ansibleのlocalでの開発環境といえばvagrant+virtualboxですが、dockerでいいんじゃねぇの?と思って色々試行錯誤してみました。何度も挫けて、もう駄目かと思いましたけど、幾つもの山を越え、ついに出来ましたですよ!
1 2 3 4 5 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|
凄いknow-how詰まってます。
connection: local
とするとssh
経由じゃなく直接command叩いてくれるconnection: docker
とするとdocker exec
で叩いてくれる(のでtargetにauthorized_keys
とかsshd
とか不要)localhost
ではgather_facts: no
とする(これをしないとansible_swaptotal_mb
とかansible_memtotal_mb
といったシステムから検出される変数: Fact (ファクト)が埋められない)ansible_python_interpreter: /usr/bin/python3
はpython
binaryを探す順序があって、/usr/bin/python
を先に見つけてしまい、version 2を使ってしまうのを防ぐため。Macだと/usr/bin/python
がpython2で、python3は/usr/bin/python3
なので。ここのversionが合わないと、The error was: No module named 'requests'"
と言われて何が悪いのかさっぱりだった。基本的にはpip3 install docker
が足りなかったのだが、その他に、このようにansibleが自分で見つけて使っているpythonのversionと自分がcommand lineで使っていてpip install
したpythonのversionがずれていると、このように言われる、ことがわかった。その他にもinventoryで指定することもcommand line optionで指定することも出来る。command line optionで-e ansible_python_interpreter=/usr/bin/python3
とするのが最も柔軟だが、これはplaybooks中の値を全て上書きするので、やはり注意が必要だった。pythonってversionややこしくて...setup_mongodb_password: !vault |
はSingle Encrypted Variableでecho -n test|ansible-vault encrypt_string --vault-password-file vault_password.txt --encrypt-vault-id default --stdin setup_mongodb_password
のように使う(ansible-vaultで暗号化しよう。)docker_container:
はmodule名で、古い文献だとdocker:
になっていて今は効かないので注意。中で指定できるものはcommunity.docker.docker_container – manage docker containersに挙がっている。privileged: yes
は、container内でsysctl vm.swappiness=1
(defaultは60)をされるので。sysctl:
というoptionもあるのだけれど、そこで指定できる(whitelistにある)のはnet.*
とかkernel.*
の一部だけだそう(サポート中の sysctl)。command: sh -c 'yum -y install procps systemd-sysv file && exec /sbin/init'
は、playbook中でsystemctl
を設定するものがあるから。Restart=always
にしたいんですよね要するに。でも、そうするとdockerにsystemd
(initd
)が動いていねばならず、そういえばdockerって普通はそんなのなかったな、どうやるんだ? 調べると、systemd-sysv
をinstallする必要/sys/fs/cgroup:/sys/fs/cgroup:ro
のdevice mountが必要- macにはそんなdirectoryはないのに大丈夫なのが不思議
- 最後は
/sbin/init
- ↑これではcontainerが数秒で倒れるので更に調べると
exec /sbin/init
(これどこで見たんだっけなぁ感動したなぁStackOverflowだった気が。他では全然書いて無くて、よく見つけたもんだ) wait_for:
がないと、docker内にまだyum install
とか終わりきってないのにどんどん次に進んでしまい、service.name:mongod,service.enabled:true
の時に「mongod
というserviceはない」といって落ちてしまうので。ホントはちゃんと何かを待ちたかったんだけど、何を待ったらいいのか不明でした。processかなと思ったんですが、processのwaitってpid fileの存在有無を確認するみたいな。いゃー、systemd
というかinit
ってpid fileなんてないんですけど。network port待つ例は数多あれど。仕方ないのでただ10秒待つように。timeout:10
は不要かと思いきや、ないとずっと待ってました。- これを
ansible-playbook -vvv -i docker.ini playbooks/docker.yml
と実行するんですが、dockerでやる場合はansible/ansible-runner
使って、docker run --rm --name=ansible -v $PWD:/work -w /work -v /var/run/docker.sock:/var/run/docker.sock ansible/ansible-runner sh -c 'pip3 install docker&yum install -y yum-utils;yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo;yum install -y docker-ce docker-ce-cli containerd.io;ansible-playbook -i docker.ini playbooks/docker.yml'
と、CentOS8 baseのansible-runnerにdockerを入れねばならず、またunix socketを共有しないとなりませんでした。CentOS8にyum install docker
するとpodmanが入りやがるんですよね。podmanってMacじゃ動かねぇっつーの! podmanだとhosts:eiger-local
のgather_facts
でDocker version checkに失敗して落ちるんですよね。Podman broken on Silverblue? Podman complains kernel not supporting overlay fs (backing file system is unsupported for this graph driver)見てsed -i "s/#mount_program/mount_program/" /etc/containers/storage.conf
加えても、Error: mount /var/lib/containers/storage/overlay:/var/lib/containers/storage/overlay, flags: 0x1000: operation not permitted
。うーん。逆に、docker containerにansibleを入れる方がsimpleでした。即ち、docker run --rm --name=ansible -v $PWD:/work -w /work -v /var/run/docker.sock:/var/run/docker.sock docker sh -c 'apk add ansible py3-pip;pip3 install docker;ansible-playbook -i docker.ini playbooks/docker.yml'
ですね。
参考サイト
- ansibleを使ってDockerコンテナをプロビジョニングしたお話
- ansible-playbookでdockerコンテナをプロビジョニングしてみた
- Ansibleでdockerへプロビジョニングする
- ansibleを使ってDockerコンテナをプロビジョニングする
- community.docker.docker_container – manage docker containers
- Ansible2.8の新機能1 - Interpreter Discovery
- Docker privileged オプションについて
- Dockerコンテナ上でsysctlでカーネルパラメータを変更する方法
- サポート中の sysctl
- Dockerコンテナ内のnet.core.somaxconnをいじる方法
- Docker Compose でカーネルパラメータを設定する
- Linux Kernel 4.12以前であればhostマシンのsysctlの値がDocker container環境に引き継がれるかどうか検証した
- Ansible: ターゲットノードでpython3を使用するansible.cfg設定は、ansiblepythoninterpreterでは無くinterpreter_python
- DockerのUbuntuコンテナでsystemdを動かす
- Docker amazonlinux2 で systemctl を使いたい人生だった
- Docker for MacでAmazon Linux 2でsystemd
- Ansible wait_for module examples