今まで本ブログでは、Ansibleを使ってLinuxやWindows Serverの操作を実施してきた。Ansibleは他にも様々なモジュールが標準で含まれている。
Ansibleに含まれるモジュールは、以下コマンドで確認することができる。
# ansible-galaxy collection list
Collection Version
----------------------------- -------
amazon.aws 3.5.0
ansible.netcommon 3.1.3
ansible.posix 1.4.0
ansible.utils 2.7.0
ansible.windows 1.12.0
arista.eos 5.0.1
~(中略)~
community.docker 2.7.1
~(中略)~
vmware.vmware_rest 2.2.0
vultr.cloud 1.3.0
vyos.vyos 3.0.1
wti.remote 1.0.4
今回は、上記に記載されているcommunity.docker
モジュールを使うことでDockerのコンテナ環境を操作することができる。今回は、Ansibleを使ってDockerのコンテナの環境を操作し、コンテナの停止、ビルド、起動を行うための手順を記載する。
環境
今回手順を確認した環境のOSは以下の通り。
- コントロールノード
- OS : AlmaLinux 8.5
- Ansible : ansible [core 2.13.1]
- DockerホストOS
- OS : CentOS Stream release 8
- Docker : docker-ce-20.10.14
Ansibleコントロールノード構築やLinuxサーバの事前準備の手順は、以下記事を参照いただきたい。
また、Docker上の操作対象のコンテナは以下3つとなる。各コンテナは、あらかじめDockerfileや必要な設定ファイルを準備しておく。必要な設定ファイルについては、それぞれ過去記事を参照いただきたい。
- メール送信用コンテナ : DockerでPostfixをコンテナ化してメールサーバを構築する
- DNS用コンテナ : DockerでUnboundをコンテナ化してDNSサーバを構築する
- プロキシ用コンテナ : DockerでSquidをコンテナ化してプロキシサーバを構築する
Dockerホストに対する事前準備
AnsibleでDockerを操作する場合、Dcokerホストに対して事前準備作業が必要となる。
1. pipをインストール
Dockerを利用する際はPythonパッケージのインストールが必要となるため、pipをインストールしておく。
# dnf install python3-pip
2. pipを用いてPythonパッケージをインストール
pipを用いて、以下の通りPythonパッケージをインストールする。
# python3 -m pip install docker docker-compose
もしこのモジュールをインストールしていない場合は、Playbook実行時に以下のようにPythonのモジュールが不足するといったエラーが発生する。
fatal: [dockerhost]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "can_talk_to_docker": false, "changed": false, "msg": "Failed to import the required Python library (Docker SDK for Python: docker above 5.0.0 (Python >= 3.6) or docker before 5.0.0 (Python 2.7) or docker-py (Python 2.6)) on t3027dock's Python /usr/libexec/platform-python. Please read the module documentation and install it in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the documentation on ansible_python_interpreter, for example via `pip install docker` (Python >= 3.6) or `pip install docker==4.4.4` (Python 2.7) or `pip install docker-py` (Python 2.6). The error was: No module named 'docker'"}
fatal: [dockerhost]: FAILED! => {"changed": false, "msg": "Unable to load docker-compose. Try `pip install docker-compose`. Error: Traceback (most recent call last):\n File \"/tmp/ansible_community.docker.docker_compose_payload_uyzpmc__/ansible_community.docker.docker_compose_payload.zip/ansible_collections/community/docker/plugins/modules/docker_compose.py\", line 497, in <module>\nModuleNotFoundError: No module named 'compose'\n"}
なお、Pythonパッケージについて、docker
またはdocker-py
のどちらかをインストールすればよいらしい。ただし、両方のインストールはNGであると明確にAnsibleのマニュアルに記載されているので注意しよう。
docker-py モジュールと docker python モジュールは、同じ名前空間を使用するため、
両方インストールすると、インストールが破損します。両方のパッケージをアンインストールし、
docker-py または docker python モジュールのいずれかを再インストールしてください。
Python 2.6 のサポートが必要でない場合は、
docker モジュールをインストールすることが推奨されます。
いずれかのモジュールをアンインストールするだけでは、
もう一方のモジュールが壊れた状態になる可能性があることに注意してください。
3. Ansible実行ユーザをdocker
グループに所属させる
Ansible実行時にAnsible実行ユーザがDockerにアクセスできる権限が必要となる。
# usermod -aG docker ansibleuser
# id ansibleuser
uid=2001(ansibleuser) gid=2001(ansibleuser) groups=2001(ansibleuser),990(docker)
以上でDockerホストに対する事前作業は完了となる。実際にPythonを実行してみよう。
Docker操作用Playbook
1. Playbook説明
今回のPlaybookの実行フローは以下の通り。
各タスクのモジュールと処理の説明を以下表に記載する。
タスク名 | モジュール | 説明 |
---|---|---|
Copy Dockerfile | copy | 各コンテナ用のDockerfile及び必要な設定ファイルをディレクトリごとコピーする。 |
Copy Dockerfile template | template | 各コンテナ用のDockerfileについて再配置する(変数で指定したベースイメージに設定したファイルを配置する)。 |
Build docker image | docker_image | Dockerfileを用いてイメージをビルドする。 |
Copy docker-compose.yml template | template | docker-compose.ymlをコピーする。 |
Down container | docker_compose | 現在稼働しているコンテナを停止&削除(Down)する。 |
Up container | docker_compose | 新しいイメージからコンテナを作成&起動(Up)する。 |
実際のPlaybookは以下となる。
---
- name: Rebuild docker container
gather_facts: false
hosts: docker_servers
vars:
ansible_user: ansibleuser
docker_config:
image: almalinux
tag: 8.7
docker_container:
- name: "{{ docker_config.image }}-postfix"
path: container-postfix
- name: "{{ docker_config.image }}-unbound"
path: container-unbound
- name: "{{ docker_config.image }}-squid"
path: container-squid
docker_file_path: /tmp/docker
tasks:
# Dockerfileコピー
- name: Copy Dockerfile
ansible.builtin.copy:
src: "templates/{{ item.path }}"
dest: "/tmp/"
mode: 0644
loop: "{{ docker_container }}"
# Dockerfileテンプレートコピー
- name: Copy Dockerfile template
ansible.builtin.template:
src: "templates/{{ item.path }}/Dockerfile"
dest: "/tmp/{{ item.path }}/"
mode: 0644
loop: "{{ docker_container }}"
# イメージ構築
- name: Build docker image
community.docker.docker_image:
build:
path: "/tmp/{{ item.path }}"
source: build
name: "{{ item.name }}"
tag: "{{ docker_config.tag }}"
state: present
loop: "{{ docker_container }}"
# docker-compose.ymlテンプレートコピー
- name: Copy docker-compose.yml template
ansible.builtin.template:
src: "templates/compose/docker-compose.yml"
dest: "/root/compose/"
mode: 0644
become: true
# コンテナ停止&削除
- name: Down container
community.docker.docker_compose:
project_src: /root/compose
build: false
# stopped: true # 停止のみ実行する場合
state: absent
become: true
# コンテナ起動
- name: Up container
community.docker.docker_compose:
project_src: /root/compose
build: false
state: present
become: true
2. Playbook実行
# ansible-playbook -i hosts -l dockerhost docker/rebuild_docker_container.yml
PLAY [Rebuild docker container] **********************************************************************************
TASK [Copy Dockerfile] *******************************************************************************************
changed: [dockerhost] => (item={'name': 'almalinux-postfix', 'path': 'container-postfix'})
changed: [dockerhost] => (item={'name': 'almalinux-unbound', 'path': 'container-unbound'})
changed: [dockerhost] => (item={'name': 'almalinux-squid', 'path': 'container-squid'})
TASK [Copy Dockerfile template] **********************************************************************************
changed: [dockerhost] => (item={'name': 'almalinux-postfix', 'path': 'container-postfix'})
changed: [dockerhost] => (item={'name': 'almalinux-unbound', 'path': 'container-unbound'})
changed: [dockerhost] => (item={'name': 'almalinux-squid', 'path': 'container-squid'})
TASK [Build docker image] ****************************************************************************************
ok: [dockerhost] => (item={'name': 'almalinux-postfix', 'path': 'container-postfix'})
ok: [dockerhost] => (item={'name': 'almalinux-unbound', 'path': 'container-unbound'})
ok: [dockerhost] => (item={'name': 'almalinux-squid', 'path': 'container-squid'})
TASK [Copy docker-compose.yml template] **************************************************************************
changed: [dockerhost]
TASK [Down container] ********************************************************************************************
ok: [dockerhost]
TASK [Up container] **********************************************************************************************
changed: [dockerhost]
PLAY RECAP *******************************************************************************************************
dockerhost : ok=6 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3. 結果確認
Playbook実行後のDcokerのコンテナイメージとコンテナの状態を比較してみよう。
まずは実行前の状態を以下に示す。イメージはAlmaLinux 8.6のみとなっており、それぞれのコンテナのタグも8.6になっていることがわかる。
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
almalinux-unbound 8.6 fd58943ebaca 2 months ago 243MB
almalinux-squid 8.6 f6e9116750e0 2 months ago 298MB
almalinux-postfix 8.6 0ca7abe54260 2 months ago 281MB
almalinux 8.6 90516e8d258d 6 months ago 189MB
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
df0976682bfe almalinux-squid:8.6 "/usr/sbin/squid -N …" 49 minutes ago Up 49 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp almalinux-squid
553c80481ac3 almalinux-unbound:8.6 "/usr/sbin/unbound -d" 49 minutes ago Up 49 minutes 0.0.0.0:10053->53/tcp, 0.0.0.0:10053->53/udp, :::10053->53/tcp, :::10053->53/udp almalinux-unbound
303103b4abe8 almalinux-postfix:8.6 "/startup.sh" 49 minutes ago Up 49 minutes 0.0.0.0:25->25/tcp, :::25->25/tcp almalinux-postfix
次に、Playbook実行後の状態を以下に示す。8.6のイメージに加えて、新たに8.7のイメージが作成されていることがわかる。また、コンテナもタグが8.7に更新されていることが確認できる。
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
almalinux-squid 8.7 7fe03e3252a7 2 seconds ago 292MB
almalinux-unbound 8.7 bed4cd545c1f 17 seconds ago 240MB
almalinux-postfix 8.7 261591afe46c 18 minutes ago 275MB
almalinux 8.7 39f63d416992 3 days ago 190MB
almalinux-unbound 8.6 fd58943ebaca 2 months ago 243MB
almalinux-squid 8.6 f6e9116750e0 2 months ago 298MB
almalinux-postfix 8.6 0ca7abe54260 2 months ago 281MB
almalinux 8.6 90516e8d258d 6 months ago 189MB
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec700661b92c almalinux-unbound:8.7 "/usr/sbin/unbound -d" 25 seconds ago Up 25 seconds 0.0.0.0:10053->53/tcp, 0.0.0.0:10053->53/udp, :::10053->53/tcp, :::10053->53/udp almalinux-unbound
1d769e4c9ee6 almalinux-squid:8.7 "/usr/sbin/squid -N …" 25 seconds ago Up 25 seconds 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp almalinux-squid
9ff38aa8b594 almalinux-postfix:8.7 "/startup.sh" 25 seconds ago Up 25 seconds 0.0.0.0:25->25/tcp, :::25->25/tcp almalinux-postfix
以上で、AnsibleにてDockerコンテナを操作する手順は完了となる。
0 件のコメント:
コメントを投稿