BUNSEN

個人的な学習ログ

ansibleでdockerインストールからdocker-compose upまで

概要

dockerとdocker-composeをインストールしてそのままdocker-compose up するplaybookを作ったが、とても詰まったポイントがあったので備忘録として残しておく。

背景

docker-composeで起動しているサービスをVM構築からサービス起動まで一貫したplaybookで構築したい状況でぶつかった。 以下のような処理をするplaybookを作成していた。

  • VM構築
  • dockerをインストール
  • ansibleユーザをdockerグループに追加
  • docker-compose.ymlを転送
  • ansibleユーザでdocker-compose upを実施

しかしなぜか初回構築時に以下のエラーで失敗

fatal: [x.x.x.x]: FAILED! => {"changed": false, "msg": "Error connecting: Error while fetching server API version: ('Connection aborted.', error(13, 'Permission denied'))"}

そして一番の謎ポイントが、もう一度実行すると成功するという点だった。

結論から言うとユーザの所属グループを作成してもそれが適用されるのは一度SSHセッションを切らないとだめだよという話。

環境

注意ポイント

  • ansible version 2.8以降からdocker_composeモジュールが追加されています
  • pipのバージョンが古いとdocker or docker-composeのインストールで失敗します
    • 詳しいバージョンは忘れましたが手元では9.0.3で成功しています

ファイル構造

.
├── hosts
├── launch_services.yml
└── roles
    ├── docker_install
    │   └── tasks
    │       ├── main.yml
    │       └── to_append_ansible_to_docker.yml
    └── launch_containers
        ├── files
        │   └── docker-compose.yml
        └── tasks
            └── main.yml

./launch_services.yml

---
- hosts: docker_hosts
  gather_facts: no
  become: yes
  roles:
    - docker_install

- hosts: docker_hosts
  gather_facts: no
  become: no
  roles:
    - launch_containers

./roles/docker_install/tasks/main.yml

- name: 関連パッケージインストール
  yum:
    name:
      - gcc
      - python2-pip

- name: dockerインストール
  yum:
    name: docker
    state: present

- name: dockerデーモンの起動
  systemd:
    name: docker
    state: started
    enabled: yes

- name: pipインストール
  yum:
    name: python2-pip
    state: present

- name: python用dockerパッケージインストール
  pip:
    name: docker
    state: present

- name: docker-composeインストール
  pip:
    name: docker-compose
    state: present

- include: to_append_ansible_to_docker.yml

./roles/docker_install/tasks/to_append_ansible_to_docker.yml

- name: ansible実行ユーザをdockerグループへ追加
  user:
    name: ansible
    state: present
    groups:
      - docker
    append: yes
  register: ansibles_group

- name: ansible実行ユーザのグループ有効化
  when: ansibles_group is changed
  block:
    - name: sshdの再起動
      systemd:
        name: sshd
        state: restarted

    - name: sshd再起動待機
      wait_for_connection:
        delay: 1
        timeout: 100

`./roles/launch_containers/tasks/main.yml``

- name: docker-composeファイル転送
  copy:
    src: docker-compose.yml
    dest: /home/ansible/docker-compose.yml

- name: コンテナ起動
  docker_compose:
    project_src: /home/ansible/
    state: present

解説

このplaybookでは以下のような処理をたどっています

  • docker, docker-composeインストール
  • ansibleユーザのdocker使用権限追加※1
  • docker-compose.yml転送
  • docker-compose up実行

※1(to_append_ansible_to_docker.yml)はdocker_composeモジュールでbecome: yesを指定する場合は必要ありません

docker, docker-compose インストール

特筆すべき点はあまりありませんがしいて言えば dockerdocker-composeパッケージをインストールできるpip の最低バージョンがあります。

今回のplaybookでは最新のpipを利用しているため問題ありませんがすでにpipがインストールされている環境ではバージョンアップタスクが必要かもしれないです。

ansibleユーザのdocker使用権限追加

ここで記事冒頭の詰まったポイントを回避しています。 docker nodeのsshdを再起動し、ansible nodeとのSSHセッションを強制的に切っています。(もっとスマートなやり方があるのかも、、、)

SSHセッションが切れるとAnsibleは再度SSH接続を仕掛けますが、sshdの再起動が終わっていない場合エラーになってしまう可能性があるため wait_for_connectionモジュールを利用して1秒待機、最大100秒間リトライし続ける処理をかませています。

docker-compose up実行

docker-composeモジュールを利用してコマンドを発行しています。 モジュールの使い方は公式を参照していただきたいのですがdockerを普段から触る方なら直感的に使えるかと思います。 ただ難点があるとすればなかなか要求が厳しいです

  • docker関連
    • Docker API >= 1.20 (docker configで確認)
    • docker-compose >= 1.7.0
  • pythonモジュール関連
    • Docker SDK
      • python2.6: docker-py
      • python2.7: docker >= 1.8.0
    • PyYAML >= 3.11
  • ansible関連
    • ansible >= 2.8

新規構築ではなくありものでこのモジュールを使う場合、アップグレード処理を入れる必要が出てくるかもしれません。