我决定尝试一下现在流行的Ansible(通过EC2实践操作)
在公有云盛行的当代,使用Ansible进行操作系统层面的构建自动化和配置管理的人相当多,不是吗?
由于我之前也没有好好学习过,所以我一边在Kindle Unlimited上读这本书,一边在我手头的AWS环境中进行实操。
Ansible是什么
-
- Python製のIT自動化ツール
-
- OSSだが、Red Hat社が「Red Hat Ansible Automation Platform」としてサポートを提供している
- 自動化対象のノードにエージェントのインストールが不要。SSH接続できてPythonが利用できればOK
基本概念 (jī – Basic concept
-
- 自動化したい内容を「プレイブック」としてYAMLで定義する
- 自動化可能な処理は「モジュール」として提供されている。モジュールは日々追加開発されている
最初,我对于Ansible的印象是它类似于一个按照操作系统命令进行自动化定义的Shell脚本,所以当我看到实际的Playbook示例时,我有些惊讶。
发布形式
为了缩短发布周期,主体和附加功能被分装为不同的包装。
-
- ansible-core:本体+基本モジュール
-
- コレクション:その他のモジュールやプラグイン
Ansible Community Packageを利用すれば、本体+推奨コレクションをまとめてインストールできる
构成
-
- コントロールノード:Ansibleをインストールするノード
Python 2.7以上 or 3.5以上が入っていること
マネージドノード:自動化対象のノード
Python 2.6以上 or 3.5以上が入っていること
SSH接続ができること
SFTP or SCPでファイル転送ができること
Ansible的组件如下所述。
-
- モジュール
特定の処理が作り込まれた機能の単位のこと
パラメータを指定することで詳細を定義する
冪等性が考慮されているため、現在の状態を確認して分岐…などの考慮は不要
インベントリ
自動化対象ノードの一覧。INI or YAMLで記述する
ホストをまとめるグループも定義できる
ホストやグループ内で共用できる「インベントリ変数」を定義できる
プレイブック
マネージドノードへの処理をYAMLで記述する
いくつかのセクションに分かれている
hosts:対象ホストやグループを指定する
vars:プレイ内で利用する変数を定義する
tasks:処理内容をモジュール+パラメータで指定する
ファイル内で上から順にタスク処理される。繰り返しや条件制御も可能
ansible-playbook コマンドで実行できる
プラグイン
補完機能。いくつかの種別がある
コネクションプラグイン:マネージドノードへの接続に関するプラグイン群
コールバックプラグイン:プレイブック実行結果の出力に関するプラグイン群
設定ファイル(ansible.cfg)
INIで記述する。いくつかのセクションに分かれる
配置可能な場所がいくつかある。どこにも無ければデフォルト設定で動作する
ansible-config コマンドで設定状況を確認できる
コレクション
ansible-core に含まれないモジュール、プラグイン、プレイブックの管理単位
FQCNという名前空間で指定する
Ansible Galaxyというサイトで配布されている
ansible-galaxy コマンドでコレクション確認やインストールができる
requirements.yml を記述して一括インストールも可能
我实际上亲自触摸了一下。
我决定在AWS上搭建服务器,并尝试使用Ansible。
我参考了服务器工作室的这篇文章。
准备环境
-
- VPCを作成
マルチAZ(利用するのは片方のAZのみ)
パブリックサブネットにEC2を作成
ansible-controller:コントロールノード
プライベートサブネットにEC2を作成
ansible-managed:マネージドノード
在控制节点上安装Ansible
※在Amazon Linux 2中,通过启用Extras选项可以从yum中使用(参考文章)
$ sudo amazon-linux-extras enable ansible2
$ sudo yum install -y ansible
确认已安装
$ ansible --version
ansible 2.9.23
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/ec2-user/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.18 (default, May 25 2022, 14:30:51) [GCC 7.3.1 20180712 (Red Hat 7.3.1-15)]
似乎在etc/ansible目录中存在清单和配置文件。
$ ls /etc/ansible
ansible.cfg hosts roles
我在nano编辑器中打开hosts文件,尝试将受管节点的IP地址添加到清单中。
$ sudo nano /etc/ansible/hosts
创建播放书&SSH连接
我会尝试创建一个只需启动Apache的简单playbook。
$ nano playbook.yml
在文件中写下以下内容。请小心,使用Tab会导致错误!
---
- hosts: 10.0.141.23
tasks:
- name: start httpd
ansible.builtin.systemd:
name: httpd
state: started
让我试着执行一次这个剧本吧。
$ ansible-playbook playbook.yml
PLAY [10.0.141.23] *************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************
The authenticity of host '10.0.141.23 (10.0.141.23)' can't be established.
ECDSA key fingerprint is SHA256:Ul7RSyNiC5QWSEF0ov88qucD1OQMs303BY7oeCLjBQI.
ECDSA key fingerprint is MD5:28:57:5b:9b:89:32:3e:d6:fc:92:ed:42:94:e9:12:9e.
Are you sure you want to continue connecting (yes/no)? yes
fatal: [10.0.141.23]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added '10.0.141.23' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic).", "unreachable": true}
PLAY RECAP *********************************************************************************************************
10.0.141.23 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0
遇到了错误。
Ansible控制器似乎在与托管节点的SSH连接认证中失败了。
接下来,我们将把托管节点的SSH私钥传输到Ansible控制器上。首先使用SCP将工作用的Mac上的私钥上传到控制器EC2的主目录。
scp -i "onda-ansible.pem" "onda-ansible.pem" ec2-user@ec2-***-***-***-***.ap-east-1.compute.amazonaws.com:/home/ec2-user
首先,我们将尝试从Ansible控制器连接到受控节点的SSH。此外,在执行Playbook之前,我们还将检查Apache的运行状态。
$ ssh -i "onda-ansible.pem" ec2-user@10.0.141.23
$ systemctl status httpd
Unit httpd.service could not be found.
首先可以确认Apache未被安装。
执行播放书并进行故障排除
那么,我们将使用之前指定的密钥重新执行Playbook。
虽然没有指定用户,但由于使用的是控制器EC2上的ec2-user,所以问题不大。
$ ansible-playbook playbook.yml --private-key onda-ansible.pem
PLAY [10.0.141.23] *************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************
[WARNING]: Platform linux on host 10.0.141.23 is using the discovered Python interpreter at /usr/bin/python, but
future installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
ok: [10.0.141.23]
TASK [start httpd] *************************************************************************************************
fatal: [10.0.141.23]: FAILED! => {"changed": false, "msg": "Could not find the requested service httpd: host"}
PLAY RECAP *********************************************************************************************************
10.0.141.23 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
这次运行成功了!但是由于没有安装Apache,所以以失败告终了。毕竟它不会帮你安装,对吧?
接下来请再次通过SSH登录到托管节点,并安装Apache。
$ sudo yum install httpd
$ systemctl status httpd #起動状態の確認
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: inactive (dead)
Docs: man:httpd.service(8)
我确认已安装并且尚未启动httpd。现在让我们返回Ansible控制器并执行之前的播放簿。
$ ansible-playbook playbook.yml --private-key onda-ansible.pem
PLAY [10.0.141.23] *************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************
[WARNING]: Platform linux on host 10.0.141.23 is using the discovered Python interpreter at /usr/bin/python, but
future installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
ok: [10.0.141.23]
TASK [start httpd] *************************************************************************************************
fatal: [10.0.141.23]: FAILED! => {"changed": false, "msg": "Unable to start service httpd: Failed to start httpd.service: The name org.freedesktop.PolicyKit1 was not provided by any .service files\nSee system logs and 'systemctl status httpd.service' for details.\n"}
PLAY RECAP *********************************************************************************************************
10.0.141.23 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
这次是因为另一个错误导致Apache启动失败。
我查了一下发现可能是Python解释器的指定有问题,所以我尝试添加了-e选项。
$ sudo ansible-playbook playbook.yml --private-key onda-ansible.pem -e ansible_python_interpreter=/usr/bin/python3
PLAY [10.0.141.23] *************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************
[WARNING]: sftp transfer mechanism failed on [10.0.141.23]. Use ANSIBLE_DEBUG=1 to see detailed information
[WARNING]: scp transfer mechanism failed on [10.0.141.23]. Use ANSIBLE_DEBUG=1 to see detailed information
fatal: [10.0.141.23]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"setup": {"failed": true, "module_stderr": "Shared connection to 10.0.141.23 closed.\r\n", "module_stdout": "Please login as the user \"ec2-user\" rather than the user \"root\".\r\n\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 0}}, "msg": "The following modules failed to execute: setup\n"}
PLAY RECAP *********************************************************************************************************
10.0.141.23 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
读取消息时写着“请使用ec2-user而不是root来运行”。
那么我将尝试去掉sudo并执行。
$ ansible-playbook playbook.yml --private-key onda-ansible.pem -e ansible_python_interpreter=/usr/bin/python3
PLAY [10.0.141.23] *************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************
ok: [10.0.141.23]
TASK [start httpd] *************************************************************************************************
fatal: [10.0.141.23]: FAILED! => {"changed": false, "msg": "Unable to start service httpd: Failed to start httpd.service: The name org.freedesktop.PolicyKit1 was not provided by any .service files\nSee system logs and 'systemctl status httpd.service' for details.\n"}
PLAY RECAP *********************************************************************************************************
10.0.141.23 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
由于权限错误或类似状态,又回到了先前的状态。
很遗憾,由于Holidee工程师的周末咖啡时间即将结束,我将结束交谈。
总结
虽然无法完美解决错误,但我对Ansible的概念和实施方法有了相当清晰的印象。果然实际操作很重要!