Ansible/bin/sh: 1:/usr/bin/python के साथ विफल रहता है: नहीं मिला




ansible-playbook (13)

मैं उस त्रुटि में भाग रहा हूं, जिसे मैंने पहले कभी नहीं देखा। यहाँ आदेश और त्रुटि है:

$ ansible-playbook create_api.yml

PLAY [straw] ******************************************************************

GATHERING FACTS ***************************************************************
failed: [104.55.47.224] => {"failed": true, "parsed": false}
/bin/sh: 1: /usr/bin/python: not found


TASK: [typical | install required system packages] *****************************
FATAL: no hosts matched or all hosts have already failed -- aborting


PLAY RECAP ********************************************************************
           to retry, use: --limit @/Users/john/create_api.retry

104.55.47.224               : ok=0    changed=0    unreachable=0    failed=1

यहाँ create_api.yml फ़ाइल है:

---

- hosts: api
  remote_user: root
  roles:
    - api

और यहाँ मेजबान फ़ाइल है:

[api]
104.55.47.224

मैं रोल्स सेक्शन को हटा सकता हूं और यह पहले TASK को नहीं बनायेगा, यह बदले में इसे केवल लाइन /bin/sh: 1: /usr/bin/python: not found । यहां क्या हो सकता है?

नोट: यदि कोई आईपी पते को पिंग कर रहा है और प्रतिक्रिया पाने में विफल है, तो आपको पता होना चाहिए कि मैंने कोड को पेस्ट करने के बाद से आईपी पता बदल दिया है।

EDIT अजगर को स्थानीय रूप से स्थापित किया गया था, समस्या यह थी कि यह रिमोट मशीन पर स्थापित नहीं था, जो कि Ubuntu 15.04 चल रहा था


@ मिरोस्लाव, मुझे सही दिशा में इशारा करने के लिए धन्यवाद। मैंने ec2_instance मॉड्यूल में भी ec2_instance उपयोग किया था और यह एक उपचार की तरह काम करता है।

अर्थात

- name: Creating single EC2 instance 
  ec2_instance:
    region: "{{ aws_region }}"
    key_name: "{{ aws_ec2_key_pair }}"
    name: "some-cool-name"
    instance_type: t1.micro
    image_id: ami-d38a4ab1
    security_group: sg-123456
    vpc_subnet_id: sn-678901234
    network:
        assign_public_ip: no
    volumes:
      - device_name: /dev/sda1
        ebs:
          volume_type: gp2
          volume_size: 15
    user_data: |
      #!/bin/bash
      #
      apt update
      apt install -y python-simplejson              
    termination_protection: yes
    wait: yes     

Ansible 2.2 में पायथन 3 सपोर्ट का तकनीकी पूर्वावलोकन है। इसका लाभ उठाने के लिए (इसलिए आपको उबंटू 16.04 पर पायथन 2 स्थापित करने की आवश्यकता नहीं है), बस /usr/bin/python3 को ansible_python_interpreter विकल्प सेट करें। यह आपकी इन्वेंट्री फ़ाइल में प्रति-होस्ट के आधार पर किया जा सकता है:

[db]
123.123.123.123 ansible_python_interpreter=/usr/bin/python3

आप उबंटू 18.04 को इंगित कर सकते हैं कि आप python3 का उपयोग पहली प्राथमिकता के रूप में /usr/bin/python pyonon के लिए करना चाहते हैं।

- hosts: all
  become: true
  pre_tasks:
    - raw: update-alternatives --install /usr/bin/python python /usr/bin/python3 1

आप दूरस्थ मेजबानों पर पायथन को स्थापित करने के लिए कच्चे मॉड्यूल का उपयोग कर सकते हैं:

- raw: sudo apt-get install python-simplejson

जैसा कि दूसरों ने कहा, यह अजगर के लापता होने के कारण है। अन्य उत्तर यहां pre_tasks और gather_facts: no साथ वर्कअराउंड प्रदान करते हैं gather_facts: no , हालांकि यदि आप EC2 पर हैं और आप इंस्टेंस के साथ उदाहरण को स्पिन करते हैं तो आप user_data विकल्प का उपयोग कर सकते हैं:

- ec2:
    key_name: mykey
    instance_type: t2.micro
    image: ami-123456
    wait: yes
    group: webserver
    count: 3
    vpc_subnet_id: subnet-29e63245
    assign_public_ip: yes
    user_data: |
      #!/bin/bash
      apt-get update
      apt-get install -y python-simplejson
    register: ec2

तब लोग आमतौर पर ssh के इस तरह उपलब्ध होने की प्रतीक्षा करते हैं:

  - name: "Wait for the instances to boot and start ssh"
    wait_for:
      host: "{{item.public_ip}}"
      port: 22
      delay: 5
      timeout: 300
    with_items: "{{ ec2.tagged_instances }}"
    when: ec2|changed

हालाँकि मैंने पाया है, कि यह हमेशा पर्याप्त नहीं होता है क्योंकि CloudInit को बूट प्रक्रिया में काफी देर से क्रियान्वित किया जाता है इसलिए ssh उपलब्ध होने के बाद भी python2 अभी भी स्थापित नहीं हो सकता है। उदाहरण के लिए, उदाहरण के लिए, मैंने एक ठहराव जोड़ा है:

  - name: "Wait for cloud init on first boot"
    pause: minutes=2
    when: ec2|changed

यह पूरी तरह से काम करेगा और एक लाभ के रूप में आप हर रन पर python2 के लिए जाँच नहीं कर रहे हैं और आपको बाद में तथ्यों को इकट्ठा करने के लिए कोई भी वर्कअराउंड करने की आवश्यकता नहीं है।

मुझे यकीन है कि अन्य क्लाउड प्रदाता समान CloudInit कार्यक्षमता प्रदान करते हैं, इसलिए अपने उपयोग के मामले के लिए अनुकूलित करें।


डिफ़ॉल्ट रूप से, Ansible को Python 2 की आवश्यकता होती है , हालाँकि, Ansible 2.2+ पायथन 3 के साथ भी काम कर सकता है

तो या तो raw मॉड्यूल का उपयोग करके पायथन 2 स्थापित करें, जैसे

ansible localhost --sudo -m raw -a "yum install -y python2 python-simplejson"

या सूची फ़ाइल में ansible_python_interpreter चर सेट करें, जैसे:

[local]
localhost ansible_python_interpreter="env python3"

डॉकर के लिए, आप निम्नलिखित पंक्ति जोड़ सकते हैं:

RUN printf '[local]\r\nlocalhost ansible_python_interpreter="env python3"\r\n' > /etc/ansible/hosts

या इसे इस रूप में चलाएं:

ansible-playbook /ansible/provision.yml -e 'ansible_python_interpreter=/usr/bin/python3' -c local

मुझे पता चला कि वास्तव में एक ही प्लेबुक में कई नाटक होना संभव है, इसलिए मेरे सेटअप में अब एक "निर्भरता प्रावधान" नाटक शामिल है जो सभी मेजबानों पर चलता है, और विशिष्ट मेजबानों के लिए अन्य नाटक। तो कोई और अधिक pre_tasks

उदाहरण के लिए:

- name: dependency provisioning
  hosts: all
  become: yes
  become_method: sudo
  gather_facts: false
  tasks:
    - name: install python2
      raw: sudo apt-get -y install python-simplejson

- name: production
  hosts: production_host
  roles:
    - nginx
  tasks:
    - name: update apt cache
      apt: update_cache=yes cache_valid_time=3600
  # ....

- name: staging
  hosts: staging_host
  roles:
    - nginx
  tasks:
    - name: update apt cache
      apt: update_cache=yes cache_valid_time=3600
  # ....

मुझे व्यक्तिगत रूप से इस समस्या के 3 संभावित समाधान मिले हैं जो विभिन्न परिस्थितियों में अच्छी तरह से काम करते हैं:

विकल्प 1 - सेट करें ansible_python_interpreter: /usr/bin/python3 उन मेजबानों के लिए, जिनके पास डिफ़ॉल्ट रूप से python3 स्थापित है

मुझे लगता है कि समस्या को हल करने के लिए यह एक बेहतर तरीका है यदि आपके पास अपने मेजबानों को समूह बनाने का तरीका है कि क्या उनके पास डिफ़ॉल्ट रूप से python3 स्थापित है या नहीं। जहां तक ​​मुझे जानकारी है, python3 सभी Ubuntu रिलीज 16.04 और उच्चतर पर उपलब्ध है।

  • यदि आपके सभी मेजबानों के पास निश्चित रूप से python3 , तो आप चर को अपने group_vars/all.yml (या समकक्ष) में जोड़ सकते हैं:
# my-playbook.yml
- name: python2
  hosts: test
  gather_facts: no
  pre_tasks:
    - raw: sudo apt-get -y install python-simplejson

$ ansible-playbook path/to/my-playbook.yml
  • यदि आपके कुछ मेजबानों के पास python3 नहीं है और आपके पास डायनामिक इन्वेंट्री का उपयोग करते समय उन्हें टैग करने का एक तरीका है (जैसे कि AWS, ec2.py लिए टैगिंग), तो आप इस तरह से कुछ मेजबानों के लिए चर को लागू कर सकते हैं:
# group_vars/all.yml

ansible_python_interpreter: /usr/bin/python3
  • यदि आप स्थैतिक इन्वेंट्री का उपयोग करते हैं और मेजबान को इस बात पर आधारित कर सकते हैं कि उनके पास python3 , तो आप कुछ इस तरह से कर सकते हैं:
# group_vars/tag_OS_ubuntu1804.yml

ansible_python_interpreter: /usr/bin/python3

मुझे यह विकल्प सबसे अधिक पसंद है क्योंकि इसके लिए रिमोट होस्ट पर कोई बदलाव नहीं करना पड़ता है और केवल 2 और 3 के विकल्प के विपरीत, चर में मामूली बदलाव होते हैं, जिसमें हर प्लेबुक में परिवर्धन की आवश्यकता होती है।

विकल्प 2 - raw का उपयोग करके पायथन 2 स्थापित करें

इस विकल्प के लिए हर gather_facts: false के शीर्ष पर एक नाटक को gather_facts: false करना gather_facts: false जो कि python को स्थापित करने के लिए raw का उपयोग करता है:

# inventory/hosts

[python2_hosts]
centos7_server

[python3_hosts]
u1804_server

[python3_hosts:vars]
ansible_python_interpreter=/usr/bin/python3

ignore_errors: true की आवश्यकता होती है यदि आप उन होस्ट पर नाटक चलाने की योजना बनाते हैं जो apt-get नहीं हैं (उदाहरण के लिए RHEL- आधारित कुछ भी) स्थापित नहीं है, अन्यथा वे पहले नाटक में त्रुटि करेंगे।

यह समाधान काम करता है, लेकिन कुछ कारणों से मेरी सूची में सबसे कम है:

  1. हर प्लेबुक के शीर्ष पर जाने की जरूरत है (विकल्प 1 के विपरीत)
  2. सिस्टम पर मान लेता है और त्रुटियों को अनदेखा करता है (विकल्प 3 के विपरीत)
  3. apt-get कमांड धीमी हैं (विकल्प 3 के विपरीत)

विकल्प 3 - साइमलिंक /usr/bin/python -> /usr/bin/python3 यूएसआर /usr/bin/python -> /usr/bin/python3 raw /usr/bin/python -> /usr/bin/python3

मैंने किसी अन्य द्वारा प्रस्तावित इस समाधान को नहीं देखा है। यह आदर्श नहीं है, लेकिन मुझे लगता है कि विकल्प 2 से कई मायनों में बेहतर है। मेरा सुझाव सिमिलिंक /usr/bin/python -> /usr/bin/python3 लिए एक शेल कमांड चलाने के लिए raw का उपयोग करना है /usr/bin/python -> /usr/bin/python3 अगर python3 सिस्टम पर है और python नहीं है:

- name: install python2 on all instances
  hosts: "*"
  gather_facts: false
  tasks:
    - name: run apt-get update and install python
      raw: "{{ item }}"
      loop:
        - sudo apt-get update
        - sudo apt-get -y install python
      become: true
      ignore_errors: true

यह समाधान विकल्प 2 के समान है जिसमें हमें इसे हर प्लेबुक में सबसे ऊपर रखना होगा, लेकिन मुझे लगता है कि यह कुछ ही मामलों में बेहतर है:

  • केवल उस विशिष्ट मामले में सिमलिंक बनाता है जो python3 मौजूद है और python नहीं है - यह पहले से ही स्थापित होने पर Python 2 को ओवरराइड नहीं करेगा
  • नहीं लगता कि apt स्थापित है
  • किसी भी विशेष त्रुटि से निपटने के बिना सभी मेजबानों के खिलाफ चला सकते हैं
  • किसी भी चीज की तुलना में सुपर फास्ट है

जाहिर है अगर आपको /usr/bin/python Python 2 को स्थापित करने की आवश्यकता है , तो यह समाधान एक नहीं है और विकल्प 2 बेहतर है।

निष्कर्ष

  • यदि आप कर सकते हैं तो मैं सभी मामलों में विकल्प 1 का उपयोग करने का सुझाव देता हूं।
  • मैं विकल्प 3 का उपयोग करने का सुझाव देता हूं यदि आपकी इन्वेंट्री वास्तव में बड़ी / जटिल है और आपके पास python3 साथ आसानी से होस्ट करने का कोई तरीका नहीं है, तो विकल्प 1 को और अधिक कठिन और त्रुटि-प्रवण बना देता है।
  • मैं केवल विकल्प 3 पर विकल्प 2 का सुझाव देता हूं, यदि आपको Python 2 को /usr/bin/python स्थापित करने की आवश्यकता है।

सूत्रों का कहना है


मैं इस त्रुटि पर Ubuntu 15.10 सर्वर पर चल रहा है, क्योंकि यह Python 3.4.3 के साथ जहाज करता है और ansible Python 2 की आवश्यकता होती है

यह मेरा provision.yml है। अब कैसा दिखता है:

- hosts: my_app
  sudo: yes
  remote_user: root
  gather_facts: no
  pre_tasks:
    - name: 'install python2'
      raw: sudo apt-get -y install python

  tasks:
    - name: 'ensure user {{ project_name }} exists'
      user: name={{ project_name }} state=present
  • Ay-get (या कच्चे मॉड्यूल चुपचाप फंस जाएगा ) के साथ -y (सभी सवालों के लिए हाँ कहते हैं) विकल्प मत भूलना

  • gather_facts: no भी रेखा भी महत्वपूर्ण नहीं है (क्योंकि हम अजगर के बिना तथ्यों को इकट्ठा नहीं कर सकते हैं)


मैं उसी समस्या को ठीक करने में सक्षम था, जिसे टारगेट मशीन यानी कि जिस मशीन को हम SSH करना चाहते हैं, उस पर पायथन लगाकर। मैंने निम्नलिखित आदेश का उपयोग किया था:

sudo apt-get install python-minimal

हम बस इसमें भागते हैं।

हम एक योनि पर ubuntu 16.04 को तैनात करते हैं, इसलिए यदि आप योनि का उपयोग नहीं कर रहे हैं तो मेरी टिप्पणी व्यर्थ है।

हमने निम्नलिखित योनि प्लगइन्स (ट्रिगर, शेल-कमांडर) स्थापित किए हैं और हम मशीन पर 2.7.6 स्थापित करते हैं (जो थिओज़ प्लगइन्स के बिना नहीं थे) और ansible को तैनात कर सकते हैं

यह हमारा आखिरी परीक्षण था, अन्यथा हम इस इंस्टालेशन को वैगंट फाइल में शेल कमांड में शामिल करने वाले थे

आशा है कि यह किसी की मदद कर सकता है


हर किसी के जवाब को संक्षेप में बताने के लिए, यहाँ संयुक्त सेटिंग्स हैं जो मेरे लिए काम करती हैं:

 - hosts: all
   become: true
   gather_facts: false

   # Ansible requires python2, which is not installed by default on Ubuntu Xenial
   pre_tasks:
     - raw: sudo apt-get -y install python-simplejson
     # action: setup will gather facts after python2 has been installed
     - action: setup

समाधान 1:

यदि आप Ansible >2.2.0 का उपयोग कर रहे हैं, तो आप ansible_python_interpreter कॉन्फ़िगरेशन विकल्प /usr/bin/python3 सेट कर सकते हैं:

ansible my_ubuntu_host -m ping -e 'ansible_python_interpreter=/usr/bin/python3'

या अपनी इन्वेंट्री फ़ाइल में:

[ubuntu_hosts]
<xxx.xxx.xxx.xxx>

[ubuntu_hosts:vars]
ansible_python_interpreter=/usr/bin/python3

समाधान 2:

यदि आप Ansible <2.2.0 का उपयोग कर रहे हैं, तो आप अपनी प्लेबुक में इन pre_tasks को जोड़ सकते हैं:

gather_facts: False
pre_tasks:
  - name: Install python for Ansible
    raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)
    register: output
    changed_when: output.stdout != ""
    tags: always
  - setup: # aka gather_facts

अद्यतन ansible 2.8.x साथ, आपको इसके बारे में चिंता करने की ज़रूरत नहीं है, यह नियंत्रक और लक्ष्य मशीन (दोनों) के लिए अजगर> 3.5 के लिए बॉक्स से बाहर काम कर रहा है





ansible-playbook