在Docker中构建Ansible的实时环境
我想使用Docker来构建Ansible的实践环境。
构建的配置如下所示:
-
- コントロールノード(Ansible) x 1
- ターゲットノード x 3
目标节点是可调整的,您可以将其替换为合适的数量进行执行。
如果不需要解释,请参考以下链接:
https://github.com/Shoma-progr-0210/ansible-training
前提
-
- Docker on Desktopがインストールされている
-
- Dockerの基礎知識がある
- Linuxコマンドの基礎知識がある
目录结构
ansible-training
│ docker-compose.yml
│
├─ansible
│ ansible.cfg
│ Dockerfile
│
├─node
│ Dockerfile
│
└─work
hosts
playbook.yml
构建控制节点
ansible-training
├─ansible
│ ansible.cfg
│ Dockerfile
创建控制节点的Dockerfile。
本次使用CentOS7镜像。
作为最低限必要的东西,我们需要安装openssh-clients以进行sudo和SSH连接。
因为CentOS7镜像中没有ansible,所以我们需要先安装eptl-release,然后再进行ansible的安装。
# CentOS7
FROM centos:7
# system update
RUN yum -y update && yum clean all
# install sudo
RUN yum -y install sudo
# install ssh clients
RUN yum -y install openssh-clients
# install ansible
RUN yum -y install epel-release && \
yum -y install ansible && \
yum clean all
# setttings
ADD ansible.cfg /etc/ansible
为了实施实际操作,将进行Ansible配置的更改。
因此,在相同的层级中创建ansible.cfg文件,并通过Dockerfile的ADD指令进行覆盖。
内容如下。 .)
-
- デフォルトのインベントリファイルを/root/work/hostsに変更
- ssh接続の設定変更
[defaults]
inventory = /root/work/hosts
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
添加目标节点
ansible-training
├─node
│ Dockerfile
创建目标节点的Dockerfile。
同样使用CentOS7的镜像。
为了进行SSH连接,安装openssh-server。
另外,我们还会执行以下操作。
-
- SSHの公開鍵作成
-
- rootのパスワード設定
-
- 22番ポートの公開
- SSHデーモンの起動
# CentOS7
FROM centos:7
# install ssh server
RUN yum -y install openssh-server && yum clean all
# create Public key
RUN ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa
RUN ssh-keygen -f /etc/ssh/ssh_host_ecdsa_key -N '' -t ecdsa
# set to login as root
RUN sed -ri 's/^#PermitEmptyPasswords no/PermitEmptyPasswords yes/' /etc/ssh/sshd_config
# set a password for root
RUN echo "root:" | chpasswd
# expose 22 port
EXPOSE 22
# start up sshd
CMD ["/usr/sbin/sshd", "-D"]
创建服务定义(docker-compose.yml)
ansible-training
│ docker-compose.yml
创建一个docker-compose.yml文件来描述服务的定义。
控制节点是ansible。将主机的./work作为卷共享给控制节点的/root/work。
目标节点是node0x(例如,x是1-3)。
使用自3.4版本起支持的Extension Field,我们可以像定义变量一样使用x-node: &node 来定义目标节点。调用方应为*node。
目标节点的端口信息并不是必需的,但为了确认实践结果,我们还是定义了这些信息。
version: '3.8'
x-node: &node
build: ./node
privileged: true
command: /sbin/init
tty: true
services:
ansible:
container_name: 'ansible'
build: ./ansible
tty: true
working_dir: '/root/work'
volumes:
- ./work:/root/work
node01:
container_name: node01
<<: *node
ports:
- '8081:80'
node02:
container_name: node02
<<: *node
ports:
- '8082:80'
node03:
container_name: node03
<<: *node
ports:
- '8083:80'
建立工作目录。
ansible-training
└─work
hosts
playbook.yml
在控制节点上创建工作目录。
由于该目录在主机端和Docker端之间共享,因此即使删除Docker,工作内容也将得以保存。
创建库存文件
hosts是用于配置Ansible的清单文件。
它在先前创建的ansible.cfg中被指定为默认清单,并将目标节点设置为一个名为node的组。
[node]
node01
node02
node03
制定Playbook
使用Ansible,通过Playbook来定义目标节点的状态进行管理。
定义文件使用YAML格式。文件名可以是任意的,但为了方便理解,我们将其命名为playbook.yml。
以下的Playbook定义了安装和启动Apache (httpd) 的状态。
主机:在节点上执行,针对先前在清单中定义的节点组。
---
- name: deploy httpd server
hosts: node
become: yes
gather_facts: no
tasks:
- name: install httpd
yum:
name: httpd
state: latest
- name: start & enabled httpd
service:
name: httpd
state: started
enabled: yes
Ansible实操培训
构建和启动容器
请首先进入ansible-training子目录。
(请将替换为ansible-training的文件夹路径。)
$ cd <BASE_DIR>/ansible-training
构建每个节点。
$ docker-compose build --no-cache
启动所有节点。
$ docker-compose up -d
控制节点的功能验证 de
当启动完成后,请进入控制节点(Ansible容器)。
$ docker-compose exec ansible bash
我将测试已安装的Ansible的运行情况。通过使用ping模块,将对localhost(控制节点本身)进行连通性测试。
$ ansible localhost -m ping
如果按照以下方式显示结果,则表示Ansible已成功安装。
localhost | SUCCESS => {
"changed": false,
"ping": "pong"
}
操作目标节点
对于每个目标节点,我们将通过SSH进行连接确认。通过这个操作,我们会事先将目标节点注册到SSH的known_hosts中。
$ ssh node0x
$ exit
使用ping模块来检查与目标节点的连通性。
$ ansible node -m ping
如果显示出每个目标节点的结果,那么连接就成功了。
node01 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
node03 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
node02 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
在目标节点上启动Apache(httpd)。
Ansible使用Playbook作为单位,通过定义目标节点的状态来进行操作。
这次我们创建了一个Playbook来安装和启动httpd,现在让我们执行它吧。
执行 playbook.yml,在目标节点上安装 httpd。
$ ansible-playbook playbook.yml
PLAY [deploy httpd server] *********************************************************************************************
TASK [install httpd] ***************************************************************************************************
fatal: [node01]: FAILED! => {"changed": false, "msg": ["Could not detect which major revision of yum is in use, which is required to determine module backend.", "You can manually specify use_backend to tell the module whether to use the yum (yum3) or dnf (yum4) backend})"]}
fatal: [node02]: FAILED! => {"changed": false, "msg": ["Could not detect which major revision of yum is in use, which is required to determine module backend.", "You can manually specify use_backend to tell the module whether to use the yum (yum3) or dnf (yum4) backend})"]}
fatal: [node03]: FAILED! => {"changed": false, "msg": ["Could not detect which major revision of yum is in use, which is required to determine module backend.", "You can manually specify use_backend to tell the module whether to use the yum (yum3) or dnf (yum4) backend})"]}
PLAY RECAP *************************************************************************************************************
node01 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
node02 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
node03 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
在每个目标节点上,应该会出现failed=1的错误。
虽然错误信息有很多,但由于未安装sudo,导致httpd安装时出现权限问题。
我们将在目标节点上安装sudo。您可以准备一个Playbook,但在这里,我们将直接使用shell模块执行sudo的安装。
ansible node -m shell -a 'yum -y install sudo'
当您完成安装后,请再次执行Playbook。
$ ansible-playbook playbook.yml
PLAY [deploy httpd server] *********************************************************************************************
TASK [install httpd] ***************************************************************************************************
changed: [node02]
changed: [node03]
changed: [node01]
TASK [start & enabled httpd] *******************************************************************************************
changed: [node03]
changed: [node01]
changed: [node02]
PLAY RECAP *************************************************************************************************************
node01 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node02 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node03 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
只要各目标节点对应的ok=2和changed=2,则表示成功。
只需这样,在所有目标节点上都完成了httpd的安装。
让我们在浏览器中检查目标节点上httpd是否正常工作。
节点0x: http://本地主机:808x
最后
我已经整理了如何使用Docker在本地环境搭建 Ansible,以便您可以轻松地入门。您可以更改目标节点数,创建除了设置httpd之外的Playbook,以帮助您理解 Ansible。