Ansible X Docker X Packer – Another Way Provision Docker Image

背景介紹

在兩年多前曾經介紹過 Chef X Docker X Packer,在社群分享時也提到過可以把其中的 Chef 抽換成其他的 CM 工具;剛好這幾天又被 Kakashi 大大詢問我是如何整合 Ansible 的,因此這篇文章就此誕生

不過常常都會有人問我,為什麼不用 Dockerfile 就好,還需要特別使用另外兩個工具來達成,我個人的回答如下:假如你的 Application Provision 過程相當的簡單,也不需要產生除了 Docker Image 以外的其他類型 Image, e.g. AWS AMI, VMware…那使用 Dockerfile 絕對是最佳解,有效率又管理方便;但如果你的 Application Provsion 過程複雜,又需要產生各種不同類型的 Image,那使用 Packer 搭配 CM Tool 或許就是可以列入考量的一個方案


在開始之前,先用一張圖解說此篇文章打算完成的事情

  1. 利用 Packer 去 Docker Registry 抓取 Application Base Image
  2. 動用 Ansible 開始 Provision Docker Image
  3. 最後 Packer 再將完成的 Docker Image 儲存回 Docker Registry

註1:此文章所使用到的所有程式範例位於 GitHub Repository: ansibleXdockerXpacker
註2:此次的範例中簡單的使用 Packer 搭配 Ansible 把一個空空的 Ubuntu Xenial image 安裝好 Nginx
註3:Packer Template 其實也跟 Application 放在同一個 Git Repository 中,但為了解說方便,因此沒有將它放在 Repository 內

Packer 介紹

Packer 為 HashiCorp 所推出的工具,利用一個 Configuration 產生跨平台各種不同的 Machine Image,一個 Packer 的 Configuration 稱為 Template,裡面分成三大部分 Builders, Provisioners 和 Post-Processors

Ansible 介紹

Ansible 為著名的 Configuration Management 工具,被廣泛應用在 IT 產業,更詳細的介紹請參考 凍仁翔大大的現代 IT 人一定要知道的 Ansible 自動化組態技巧

Packer Template 解說

Repository 中的結構如下:

ansibleXdockerXpacker/
├── README.md
├── ansible # 存放著如何安裝 Nginx 的 Ansible role
├── ansible.yml # 引用上面的資料夾
└── packer.json # Packer template

其中的 packer.json 就是前面所提到的 Packer template, 他並沒有做太複雜的事情

  1. 他先從 docker store 拉下 image ubuntu:xenial (2:8)
  2. 透過 shell privision 把 ansible 安裝好 (11:20)
  3. 透過 ansible 把 Nginx 安裝好 (21:25)
  4. 最後把產生出來的 image 打上 tag (28:36)
{
  "builders": [{
    "type": "docker",
    "image": "ubuntu:xenial",
    "commit": true,
    "pull": true,
    "run_command": [ "-d", "-i", "-t", "-v", "/tmp:/tmp", "{{.Image}}", "/bin/bash" ]
  }],

  "provisioners": [
    {
      "type": "shell",
      "inline": [
        "apt-get update",
        "apt-get install -y software-properties-common",
        "apt-add-repository -y ppa:ansible/ansible",
        "apt-get update",
        "apt-get install -y ansible"
      ]
    },
    {
      "type": "ansible-local",
      "playbook_file": "./ansible.yml",
      "role_paths": [ "./ansible" ]
    }
  ],

  "post-processors": [
    [
      {
        "type": "docker-tag",
        "repository": "smalltown/ansiblexdockerxpacker",
        "tag": "{{user `image_tag`}}"
      }
    ]
  ]
}

看完 packer template 準備來上工

<h2>執行結果</h2>

把當前目錄切換到 ansibleXdockerXpacker,透過 Packer 的 command 開始進行 docker image 的 provision,可以把變數 image_tag 換成自己喜歡的值

~$ cd ansibleXdockerXpacker
~$ packer build -var 'image_tag=#{image_tag}' packer.json

執行下去之後會噴出一大堆的命令執行結果,仔細看一下就可以發現,就是一堆模組的安裝過程

...

==> docker: Provisioning with Ansible...
    docker: Creating Ansible staging directory...
    docker: Creating directory: /tmp/packer-provisioner-ansible-local/5a5aeeb6-d8ee-c7a1-d91d-b893c8f96860
    docker: Uploading main Playbook file...
    docker: Uploading inventory file...
    docker: Uploading role directories...
    docker: Creating directory: /tmp/packer-provisioner-ansible-local/5a5aeeb6-d8ee-c7a1-d91d-b893c8f96860/roles/ansible
    docker: Executing Ansible: cd /tmp/packer-provisioner-ansible-local/5a5aeeb6-d8ee-c7a1-d91d-b893c8f96860 && ANSIBLE_FORCE_COLOR=1 PYTHONUNBUFFERED=1 ansible-playbook /tmp/packer-provisioner-ansible-local/5a5aeeb6-d8ee-c7a1-d91d-b893c8f96860/ansible.yml --extra-vars "packer_build_name=docker packer_builder_type=docker packer_http_addr="  -c local -i /tmp/packer-provisioner-ansible-local/5a5aeeb6-d8ee-c7a1-d91d-b893c8f96860/packer-provisioner-ansible-local687885156
    docker:
    docker: PLAY [provision ansibleXdockerXpacker docker image] ****************************
    docker:
    docker: TASK [Gathering Facts] *********************************************************
    docker: ok: [127.0.0.1]
    docker:
    docker: TASK [ansible : update apt cache.] *********************************************

...

==> Builds finished. The artifacts of successful builds are:
--> docker: Imported Docker image: sha256:f7470a729d0e237fe03fc0dcf2c4d37f1a140aa9b504fbed64b6a4ff6d5bd954
--> docker: Imported Docker image: smalltown/ansiblexdockerxpacker:#{image_tag}

最後執行 Docker command 就可以看到 熱騰騰的 image 產生在本機了

~$ docker images

REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
smalltown/ansiblexdockerxpacker   #{image_tag}        f7470a729d0e        10 minutes ago      358MB
ubuntu                            xenial              00fd29ccc6f1        4 weeks ago         111MB

接下來…

當然就是把具有商業邏輯的程式碼放進來 Repository,修改 ansible task 來加入更做 provision 流程,然後跟 CI/CD Framework 整合在一起嘍

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s