Ansible 自動化

Loading

下面來看一下如何透過 Ansible 來做自動化部署,參考文章 – https://docs.ansible.com/ansible/latest/getting_started/get_started_ansible.html

測試環境 CentOS 9 Stream (虛擬機)

架構需求如下系統可以分為 Control node ( Ansible 控制端) 與 Managed nodes (被 Ansible 控制端)

  • Control node ( Ansible 控制端) IP: 192.168.31.131
  • Managed nodes (被 Ansible 控制端) IP: 192.168.31.178

Managed nodes

系統預設都安裝 Python 與 SSH-Server 就可以運作.

Control node

接下來所有設定皆是在 Control node 來設定.

  • 安裝 Ansible
    官網是用 pip 來安裝 Ansible.

    [root@localhost ~]# yum install pip
    [root@localhost ~]# pip install ansible
    [root@localhost ~]# pip install ansible-lint
    

    建議安裝 ansible-lint 該程式可以幫忙檢查 Playbook 的 ymal 檔案是否正常.

  • SSH 免密碼的登入方式
    Control node 是透過 SSH 的方式去連到 Managed node 來工作,所以要先把 Control node 的 public SSH key 加到 Managed node 的 authorized_keys 檔案 (實現 SSH 免密碼的登入方式),更多關於 SSH 基於 Key 的驗證 請參考 – https://benjr.tw/106336

    產生 ssh Public / Private Key

    [root@localhost ~]# ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (/root/.ssh/id_rsa):
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /root/.ssh/id_rsa
    Your public key has been saved in /root/.ssh/id_rsa.pub
    The key fingerprint is:
    SHA256:gDEFTV2X0g7/X3WiVNO0xYU57wUsPWwCqPzi4yMXmCo root@localhost.localdomain
    The key's randomart image is:
    +---[RSA 3072]----+
    |    +=o. ooo.= *=|
    |     +. o o.= & =|
    |    ....   = = B |
    |      o.    + . =|
    |     o .S  . o o+|
    |    o o .   . . o|
    |   . . o       ..|
    |E . . =         .|
    | .   +.o         |
    +----[SHA256]-----+
    

    把 Control node 的 public SSH key 加到 Managed node 的 authorized_keys 檔案 .

    [root@localhost ~]# ssh-copy-id root@192.168.31.178
    /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
    The authenticity of host '192.168.31.178 (192.168.31.178)' can't be established.
    ED25519 key fingerprint is SHA256:PgFJeh+W+iNzarxpeUxtVg1ewnvb3GZTAt87Oxq260E.
    This key is not known by any other names
    Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
    /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
    root@192.168.31.178's password:
    
    Number of key(s) added: 1
    
    Now try logging into the machine, with:   "ssh 'root@192.168.31.178'"
    and check to make sure that only the key(s) you wanted were added.
    

    這樣就實現了 SSH 免密碼的登入方式,測試一下連線到 Managed nodes ( IP: 192.168.31.178 )

    [root@localhost ~]# ssh root@192.168.31.178
    Activate the web console with: systemctl enable --now cockpit.socket
    
    Last failed login: Thu May 16 17:31:43 CST 2024 from 192.168.31.131 on ssh:notty
    There was 1 failed login attempt since the last successful login.
    Last login: Thu May 16 17:20:50 2024 from 192.168.31.1
    [root@localhost ~]# exit
    登出
    Connection to 192.168.31.178 closed.
    

    準備工作完成.

  • 建立一個測試用的資料夾
    [root@localhost ~]# mkdir ansible_quickstart && cd ansible_quickstart
    [root@localhost ansible_quickstart]#
    

    簡單測試一下 localhost 自己本身,並使用系統提供的 ping 模組(後面說明)

    [root@localhost ansible_quickstart]# ansible localhost -m ping
    [WARNING]: No inventory was parsed, only implicit localhost is available
    localhost | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    
  • Inventory
    建立一個 Inventory 檔案 (測試時可以指定檔名) ,內容為 Managed nodes (被 Ansible 控制端) 的 IP address 或是 fully qualified domain name (FQDN)

    [root@localhost ansible_quickstart]# vi inventory.ini
    [myhosts]
    192.168.31.178
    
    [yourhosts]
    192.168.31.179
    

    驗證 inventory 檔案的正確與否.

    [root@localhost ansible_quickstart]# ansible-inventory -i inventory.ini --list
    {
        "_meta": {
            "hostvars": {}
        },
        "all": {
            "children": [
                "ungrouped",
                "myhosts",
                "yourhosts"
            ]
        },
        "myhosts": {
            "hosts": [
                "192.168.31.178"
            ]
        },
        "yourhosts": {
            "hosts": [
                "192.168.31.179"
            ]
        }
    }
    
  • 操作模式
    模式有 Ad-Hoc , Playbook 兩種.

    • Ad-Hoc command 的 指令操作模式
      透過 Ansible 內建的 Ping 模組 來檢查 Hosts 的 python 與是否有在線上 (使用 指定的 inventory 檔案內的 myhosts 清單).

      [root@localhost ansible_quickstart]# ansible myhosts -m ping -i inventory.ini
      192.168.31.178 | SUCCESS => {
          "ansible_facts": {
              "discovered_interpreter_python": "/usr/bin/python3"
          },
          "changed": false,
          "ping": "pong"
      }
      

      因為 yourhost 指定的 IP 機器不存在,所以會顯示錯誤.

      [root@localhost ansible_quickstart]# ansible yourhosts -m ping -i inventory.ini
      192.168.31.179 | UNREACHABLE! => {
          "changed": false,
          "msg": "Failed to connect to the host via ssh: ssh: connect to host 192.168.31.179 port 22: No route to host",
          "unreachable": true
      }
      

      透過 Ansible 內建的 debug 模組

      [root@localhost ansible_quickstart]# ansible myhosts -m debug -i inventory.ini
      192.168.31.178 | SUCCESS => {
          "msg": "Hello world!"
      }
      

      指定指令來執行

      [root@localhost ansible_quickstart]# ansible myhosts -m command -a "echo Hello World" -i inventory.ini
      192.168.31.178 | CHANGED | rc=0 >>
      Hello World
      
    • Playbook 透過 劇本 (Playbooks) 來讓 Managed Nodes 進行指定的動作 (Plays) 和任務 (Tasks)
      以上 Ad-Hoc commands 一次只能做一件事情, 依序做大量工作時需使用 Playbooks 的方式,以下定義了兩個 Task.

      [root@localhost ansible_quickstart]# vi playbook.yaml
      - name: My first play
        hosts: myhosts
        tasks:
         - name: Ping my hosts
           ansible.builtin.ping:
      
         - name: Print message
           ansible.builtin.debug:
            msg: Hello world
      

      透過程式去檢測 yaml 內容是否無誤.

      [root@localhost ansible_quickstart]# ansible-lint playbook.yaml
      
      Passed: 0 failure(s), 0 warning(s) on 1 files. Last profile that met the validation criteria was 'production'.
      A new release of ansible-lint is available: 6.22.2 → 24.5.0
      

      執行.

      [root@localhost ansible_quickstart]# ansible-playbook -i inventory.ini playbook.yaml
      
      PLAY [My first play] ***************************************************************************************************
      
      TASK [Gathering Facts] *************************************************************************************************
      ok: [192.168.31.178]
      
      TASK [Ping my hosts] ***************************************************************************************************
      ok: [192.168.31.178]
      
      TASK [Print message] ***************************************************************************************************
      ok: [192.168.31.178] => {
          "msg": "Hello world"
      }
      
      PLAY RECAP *************************************************************************************************************
      192.168.31.178             : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
      

      執行結果.
      TASK [Gathering Facts] 預設 Ansible 會收集有關在 playbook 中有使用的清單的資訊.

      TASK [Ping my hosts] TASK [Print message] 顯示為 ok 表示它運行成功.

      PLAY RECAP
      這邊會總結了每個主機的 Play 中所有 Task 任務的結果.

    • 沒有解決問題,試試搜尋本站其他內容

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料