Ansible คือเครื่องมือ orchestration ตัวนึ่งที่เราสามารถเขียน step ต่างๆ แล้วก็สั่งให้ ansible ทำงานตามที่เราเขียนไว้ ข้อดีคือเราเขียน script (ansible เค้าจะเรียกว่า playbook) เอาไว้และหากเรามีเครื่อง server ทีจำเป็นจะต้อง setup เหมือนกันสัก 100 เครื่อง เราก็ใช้ ansible ทำงานแทนเราได้เลย ข้อดีอีกอย่างคือมันเป็นเหมือน configuration management กลางได้ด้วยว่าเครื่องที่เราติดตั้งนี้มันทำอะไรไปบ้าง
Ansible นั้นมี module ให้นำไปใช้ได้เยอะแยะมากมาย สามารถเข้าไปศึกษาได้จากที่เว็บไซต์ของ ansible ได้เลยครับ แต่ในบทความนี้ผมจะแนะนำการนำ ansible ใช้ run docker container แบบคร่าวๆ นะครับ
สมมติว่าเรามีเครื่องที่ต้องการจะติดตั้งและใช้งาน docker อยู่ 5 เครื่อง (centos 7) ดังนี้
joy 192.168.100.1
fear 192.168.100.2
anger 192.168.100.3
disgust 192.168.100.4
sadnes 192.168.100.5
ติดตั้ง Ansible ที่เครื่องเรา (ubuntu16) เอง
sudo apt-get install ansible
หลังจากนั้นสร้าง folder ในรูปแบบนี้
./
|-roles/
|–|-common
|——|-tasks
|——|-files
|–|-docker
|——|-tasks
|–|-deploy
|——|-tasks
สร้าง hosts ไฟล์ทีจะใช้ ssh ไปติดตั้ง
[all] joy ansible_host=192.168.100.1 ansible_ssh_user=root fear ansible_host=192.168.100.2 ansible_ssh_user=root anger ansible_host=192.168.100.3 ansible_ssh_user=root disgust ansible_host=192.168.100.4 ansible_ssh_user=root sadnes ansible_host=192.168.100.5 ansible_ssh_user=root
ส่วนวิธีการ connect ผมไม่ขอพูดถึงนะ ใช้วิธีเดียวกันกับการใช้ ssh-key อ่ะแหล่ะ ไปหาอ่านเอาเองแล้วกัน
ติดตั้ง yum repo เพิ่มเติมให้กับ centos7
สร้างไฟล์ใน roles/common/tasks/main.yml
--- - name: Copy the EPEL repository definition copy: src=epel.repo dest=/etc/yum.repos.d/ - name: Create the GPG key for EPEL copy: src=RPM-GPG-KEY-EPEL-7 dest=/etc/pki/rpm-gpg
และภายใน roles/common/files/ ประกอบด้วยไฟล์
- epel.repo ($ wget https://raw.githubusercontent.com/ansible/ansible-examples/master/wordpress-nginx_rhel7/roles/common/files/epel.repo)
- RPM-GPG-KEY-EPEL-7 ($ wget https://raw.githubusercontent.com/ansible/ansible-examples/master/wordpress-nginx_rhel7/roles/common/files/RPM-GPG-KEY-EPEL-7)
ติดตั้ง docker
สร้างไฟล์ใน roles/docker/tasks/main.yml
--- - name: Install python setup tools yum: name=python-setuptools tags: docker - name: Install Pypi easy_install: name=pip tags: docker - name: Install docker-py pip: name=docker-py tags: docker - name: Install Docker yum: name=docker state=latest tags: docker - name: Make sure Docker is running service: name=docker state=running tags: docker
เสร็จแล้วสร้างไฟล์ที่
./site.yml
--- - name: Install Docker hosts: all remote_user: root roles: - common - docker
เสร็จแล้วให้สั่ง $ ansible-playbook -i hosts site.yml
หลังจากนั้น ansible จะทำการ ssh ไปยัง server ในไฟล์ hosts ที่เราได้ใส่เอาไว้และติดตั้ง software ตาม task ที่เราได้ใส่ไว้ในไฟล์ roles/docker/tasks/main.yml
ทดสอบ docker run
สร้างไฟล์ใน roles/deploy-docker/tasks/main.yml
--- - name: Deploy Docker image docker: name: alpine-nginx image: smebberson/alpine-nginx state: started ports: - "80:80" - "443:443"
หลังจากนี้ให้สั่ง
$ ansible-playbook -i hosts site.yml
เพื่อสั่งให้ ansible start docker ตาม task ครับ ถ้าสำเร็จลองใช้คำสั่งนี้เพื่อตรวจสอบสถานะของ docker
$ ansible -i hosts all -m command -a "docker ps -a
docker ก็จะถูก start บนเครื่องที่เราต้องการแล้ว
joy | SUCCESS | rc=0 >> CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f4f08a5ea7c3 smebberson/alpine-nginx "/init" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp alpine-nginx fear | SUCCESS | rc=0 >> CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ab3e51c0629b smebberson/alpine-nginx "/init" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp alpine-nginx anger | SUCCESS | rc=0 >> CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 79c0d72c591a smebberson/alpine-nginx "/init" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp alpine-nginx disgust | SUCCESS | rc=0 >> CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 58d8f83b00b6 smebberson/alpine-nginx "/init" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp alpine-nginx sadness | SUCCESS | rc=0 >> CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0a13e0f1db70 smebberson/alpine-nginx "/init" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp alpine-nginx หากเราเข้าไปที่ ip ของเครื่อง remote ที่เพิ่งติดตั้งไปก็จะพบว่า docker ได้ start สำเร็จ
หากเจอปัญหา
ผมลองรันตอนแรกพบปัญหาดังนี้
fatal: [joy]: FAILED! => {“changed”: false, “failed”: true, “msg”: “Docker API Error: client is newer than server (client API version: 1.22, server API version: 1.21)”}
ให้ทำการแก้ไขที่ไฟล์
roles/docker/tasks/main.yml
--- - name: Install python setup tools yum: name=python-setuptools tags: docker - name: Install Pypi easy_install: name=pip tags: docker - name: Install docker-py pip: name=docker-py version=1.2.3 tags: docker - name: Install Docker yum: name=docker state=latest tags: docker - name: Make sure Docker is running service: name=docker state=running tags: docker
และรันคำสั่ง
ansible-playbook -i hosts site.yml
ก็จะสามารถใช้งานได้ปกติแล้วครับ