Ansible で Docker のインストール

この記事は書かれてから1年以上が経過しており、最新の情報とは異なる可能性があります

Ansible で再起動後にも playbook を継続する方法 で 再ログインに関しても一緒にまとめておこうと思ったのですが、 Docker の方が話の割合として多くなりそうだったので別記事でまとめておきます。 特に Ansible で Docker をインストールするときはこれに該当するんじゃないかと思います。

Ansible で Docker

まず話がややこしくならないように事前に触れておきますが、 Ansible & Docker の話は複数あって、

  1. Ansible の playbook の実行(の検証?)に Docker コンテナを用いる話
  2. Ansible の playbook で Docker をインストールする話

が挙げられますが、今回は 1 ではなく 2 の話です。

ちなみに 1 についてですが、 例えばローカルに用意した VirtualBox や外部に借りている VPS の環境だったり、 SSH がつながる環境であれば Ansible の実行は可能ですが、 それが Docker コンテナまで利用できるように広がってきたよという話です。 (僕も詳しくないのでここまでしか把握してません。)

詳しくは “ansible docker connection plugin” でおググりください。

Docker インストール時のグループ追加について

手動でやっててけっこうはまった箇所なのですが、 各種 docker コマンドを実行する際は、sudo をつけて実行するか、 docker グループにユーザーを追加してから docker コマンドを実行する必要があります。

Ansible 実行ユーザーを docker グループに追加し Docker 関連の操作をさせる際に、 Ansible の playbook を Ansible 実行ユーザー自身が実行中なため、 一度ログインし直してグループに追加したことを設定反映する必要があります。

つまり、Docker インストール用の playbook を実行して、 ansible ユーザーを docker グループに入れたからといって、 docker_image, docker_container モジュールを用いた playbook は動作しません。

予め手動で ansible ユーザーを docker グループに入れた直後にログアウトせず、 そのまま docker ps などを実行してみると、

$ sudo usermod -aG docker ansible
$ docker ps
Cannot connect to the Docker daemon. Is the docker daemon running on this host?

というメッセージが出て Docker 周りの操作は何もできません。 (id -a などでグループに追加されているか確認しても、自分自身はログアウトしない限り追加されてません)

Docker インストール用 playbook

Ansible 実行ユーザー(ここでは ansible)を docker グループに入れたまま docker コマンドが操作できる playbook を書いてみました。

仕組みとしては前回の Ansible で再起動後にも playbook を継続する方法 と同じで local_action を用いてログアウト後に待機します。

またまた抜粋ですみません・・・。改めてまとめなおします。

- name: Docker 用 yum リポジトリの追加
  yum_repository:
    name: dockerrepo
    description: Docker Repository
    baseurl: https://yum.dockerproject.org/repo/main/centos/$releasever/
    enabled: yes
    gpgkey: https://yum.dockerproject.org/gpg
    gpgcheck: yes
  tags: dockerhost
  become: True

- name: docker-engine のインストール
  yum: name=docker-engine enablerepo=dockerrepo state=latest
  tags: dockerhost
  become: True

- name: docker-python のインストール
  yum: name=docker-python enablerepo=dockerrepo state=latest
  tags: dockerhost
  become: True

- name: Docker 起動時の DNS 設定
  copy: src="docker" dest="/etc/sysconfig/docker" owner=ansible group=ansible mode=0400
  tags: dockerhost
  become: True

- name: Docker サービス自動起動設定
  service: name=docker state=running enabled=True
  tags: dockerhost
  become: True

- name: Docker グループにユーザー追加
  user: name=ansible groups=docker append=yes
  tags: dockerhost
  become: True

- name: Ansible 実行ユーザー自身のグループ状況の取得
  shell: id -a
  register: group_status
  changed_when: False
  tags: dockerhost

- name: Docker グループ追加後の再ログイン
  shell: "sleep 2 && pkill -u ansible sshd"
  async: 1
  poll: 0
  when: group_status.stdout.find('docker') == -1
  tags: dockerhost
  become: True

- name: Docker グループ追加後の再ログイン完了まで待機
  local_action: wait_for host={{ inventory_hostname }} port={{ ssh_port }} delay=10
  when: group_status.stdout.find('docker') == -1
  tags: dockerhost
  become: False

- name: Docker コマンドが Ansible 実行ユーザーで使えるかテスト
  shell: docker version
  changed_when: False
  tags: dockerhost
  become: False

docker-python と python-docker-py は多分同じパッケージなんじゃないかと思われます。 yum info を見てみると、どちらも docker が提供してるので、 単に yum install docker でインストールして入るであろう docker-python の方を指定しています。 (Ansible のドキュメントには docker-py が必要とありましたが、docker-python で問題なかったです)

$ yum info docker-python
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.nus.edu.sg
 * extras: mirror.vodien.com
 * updates: mirror.vastspace.net
利用可能なパッケージ
名前                : docker-python
アーキテクチャー    : x86_64
バージョン          : 1.4.0
リリース            : 115.el7
容量                : 94 k
リポジトリー        : extras/7/x86_64
要約                : An API client for docker written in Python
URL                 : http://www.docker.com
ライセンス          : ASL 2.0
説明                : An API client for docker written in Python

$ yum info python-docker-py
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.nus.edu.sg
 * extras: mirror.vodien.com
 * updates: mirror.vastspace.net
インストール済みパッケージ
名前                : python-docker-py
アーキテクチャー    : noarch
バージョン          : 1.7.2
リリース            : 1.el7
容量                : 235 k
リポジトリー        : installed
提供元リポジトリー  : extras
要約                : An API client for docker written in Python
URL                 : https://github.com/docker/docker-py/
ライセンス          : ASL 2.0
説明                : An API client for docker written in Python

前回と同様に、実行するかどうかのステータスを取得して、 必要なければスキップするようになっています。

また、local_action と wait_for モジュールの組み合わせで再度 ssh でつなぎにいくのを待機しつつ検知しています。 最後の docker version では、実際にコマンドが有効かどうかを実行して確かめています。 仕組みとしては大きく前回と違いはありません。

まとめ

まだ Docker ホストとして動作するまでしか用意してないので、 アプリケーションなどは特に動いてませんが、 開発用途であれ、サービス用途であれ、 これからはコンテナを中心とした環境にかなり移行していくと思うので、 Docker ホストとして最低限動作するところまでは playbook として共通化できる と思います。

ここまでやっておくと残りは Docker イメージや Docker コンテナの操作が中心になってきますね。

まだ、playbook は現時点でごちゃごちゃせずにすっきりしている(と個人的には思っている)ので、 docker-compose を導入せずにこのまま Ansible で Docker の構成管理してもいいんじゃないかとも思っています。

ちなみに、言うまでも無いことですが、 手動でセットアップできないのに Docker や Ansible を使えば知識なしに出来るわけはないので、 まずは空っぽの環境を用意して手動でやってみることをお勧めします。

参考URL

この記事は書かれてから1年以上が経過しており、最新の情報とは異なる可能性があります

もし記事内に誤りなどございましたら、 @girigiribauer @girigiribauer.com までご一報いただけると助かります。

Related articles