返回文章列表

Ansible 自動化佈署 Docker 與容器應用

本文介紹如何使用 Ansible 自動化佈署 Docker 和容器應用程式,涵蓋 RPM、Debian 和 Windows 系統上的 Docker 安裝,以及使用 Flatpak 和 Snap 管理 Linux 應用程式,並以佈署 Apache Web 伺服器為例,示範在容器中佈署應用程式的最佳實務。

DevOps 容器化

Ansible 提供了跨平台的自動化能力,簡化了 Docker 和容器化應用程式的佈署流程。本文詳細說明如何在不同作業系統上安裝 Docker,並利用 Ansible 管理 Flatpak 和 Snap 等套件格式,有效提升應用程式佈署效率。同時,以 Apache Web 伺服器為例,展示如何在容器中佈署應用程式,實作應用程式與資料分離,降低攻擊面並簡化更新流程。透過 Ansible 的自動化組態,可以確保佈署過程的一致性和可靠性,減少人工錯誤並提高工作效率。

在不同作業系統上使用 Ansible 自動安裝 Docker

本章節將介紹如何使用 Ansible 自動化安裝 Docker 的過程,涵蓋在 RPM 系統(如 Red Hat Enterprise Linux)、Debian 系統以及 Windows 系統上的安裝步驟。

在 RPM 系統上安裝 Docker

在 RPM 系統上安裝 Docker 需要經歷三個主要步驟:下載 GPG 簽名金鑰、新增 Docker 儲存函式庫以及更新 yum 快取並安裝 Docker。

第一步:下載 GPG 簽名金鑰

首先,您需要使用 ansible.builtin.rpm_key 模組下載 Docker 儲存函式庫的 GPG 簽名金鑰。此金鑰用於驗證下載的 Docker 套件未被竄改。

- name: Add signing key
  ansible.builtin.rpm_key:
    key: "https://download.docker.com/linux/{{ mydistribution }}/gpg"
    state: present

內容解密:

  • ansible.builtin.rpm_key 是用於管理 RPM 金鑰的 Ansible 模組。
  • key 引數指定了 GPG 金鑰的 URL。
  • state: present 確保金鑰存在於系統中。

第二步:新增 Docker 儲存函式庫

接下來,使用 ansible.builtin.yum_repository 模組將 Docker 儲存函式庫新增至系統中。

- name: Add repository into repo.d list
  ansible.builtin.yum_repository:
    name: docker
    description: docker repository
    baseurl: "https://download.docker.com/linux/{{ mydistribution }}/$releasever/$basearch/stable"
    enabled: true
    gpgcheck: true
    gpgkey: "https://download.docker.com/linux/{{ mydistribution }}/gpg"

內容解密:

  • namedescription 定義了儲存函式庫的名稱和描述。
  • baseurl 指定了 Docker 儲存函式庫的 URL。
  • gpgcheck: truegpgkey 用於啟用 GPG 驗證。

第三步:更新 yum 快取並安裝 Docker

最後,使用 ansible.builtin.yum 模組更新 yum 快取並安裝 Docker。

- name: Install Docker
  ansible.builtin.yum:
    name:
      - docker-ce
      - docker-ce-cli
      - containerd.io
    state: latest
    update_cache: true

內容解密:

  • name 指定了要安裝的套件名稱。
  • state: latest 確保安裝最新版本的 Docker。
  • update_cache: true 在安裝前更新 yum 快取。

在 Debian 系統上安裝 Docker

雖然本章節主要關注 RPM 系統,但同樣的概念可以應用於 Debian 系統。您需要使用不同的 Ansible 模組,如 ansible.builtin.apt_keyansible.builtin.apt

在 Windows 系統上安裝 Docker

在 Windows 系統上,您可以使用 Chocolatey 套件管理器和 chocolatey.chocolatey.win_chocolatey Ansible 模組來安裝 Docker Desktop。

- name: Install Docker
  chocolatey.chocolatey.win_chocolatey:
    name: "docker-desktop"
    state: present

內容解密:

  • name 指定了要安裝的套件名稱(Docker Desktop)。
  • state: present 確保 Docker Desktop 被安裝。

使用 Ansible 管理 Linux 應用程式:Flatpak 與 Snap

在現代 Linux 環境中,容器化和套件管理已成為佈署和管理應用程式的重要工具。Ansible 作為一種自動化工具,能夠有效地管理和佈署各種 Linux 應用程式。本文將探討如何使用 Ansible 管理 Flatpak 和 Snap 兩種流行的 Linux 套件格式。

使用 Ansible 管理 Flatpak

Flatpak 是一種用於在 Linux 上分發應用程式的系統,它允許應用程式在沙箱環境中執行,從而提高安全性。要使用 Ansible 管理 Flatpak,首先需要確保目標系統上已安裝 Flatpak。

步驟一:安裝 Flatpak

使用 ansible.builtin.package 模組安裝 Flatpak:

- name: flatpak present
  ansible.builtin.package:
    name: flatpak
    state: present

步驟二:組態 Flathub 倉函式庫

Flathub 是 Flatpak 應用程式的主要來源。使用 community.general.flatpak_remote 模組組態 Flathub 倉函式庫:

- name: flathub repo
  community.general.flatpak_remote:
    name: flathub
    state: present
    flatpakrepo_url: https://flathub.org/repo/flathub.flatpakrepo
    method: system

步驟三:安裝 Podman Desktop

使用 community.general.flatpak 模組安裝 Podman Desktop:

- name: install Podman Desktop via flatpak
  community.general.flatpak:
    name: io.podman_desktop.PodmanDesktop
    state: present
    method: system

#### 內容解密:

  1. ansible.builtin.package模組用於安裝Flatpak,確保目標系統具備管理Flatpak的能力。
  2. community.general.flatpak_remote模組組態Flathub倉函式庫,這是取得Flatpak應用程式的來源。
  3. community.general.flatpak模組安裝Podman Desktop,這是一個具體的Flatpak應用程式範例。

完整的 Ansible Playbook 如 Listing 3-4 所示。

更新 Flatpak 應用程式

Flatpak 預設不會自動更新,但可以使用 Ansible 的 ansible.builtin.command 模組來自動化更新過程:

- name: update flatpak(s)
  ansible.builtin.command: "flatpak update --noninteractive"

#### 內容解密:

  1. ansible.builtin.command模組執行flatpak update命令來更新所有已安裝的Flatpak應用程式。
  2. --noninteractive選項確保更新過程不會要求使用者互動。

完整的更新 Playbook 如 Listing 3-5 所示。

使用 Ansible 管理 Snap

Snap 是另一種流行的 Linux 套件格式,由 Canonical 開發並推廣。要使用 Ansible 管理 Snap,首先需要確保目標系統上已安裝 Snapd。

步驟一:安裝 Snapd

在 Ubuntu 系統上,使用 ansible.builtin.apt 模組安裝 Snapd:

- name: snapd present
  ansible.builtin.apt:
    name: snapd
    state: present

步驟二:安裝 microk8s

使用 community.general.snap 模組安裝 microk8s:

- name: install microk8s via snap
  community.general.snap:
    name: microk8s
    state: present
    classic: true

#### 內容解密:

  1. ansible.builtin.apt模組用於在Ubuntu系統上安裝Snapd。
  2. community.general.snap模組安裝microk8s,一個輕量級的Kubernetes發行版。
  3. classic: true選項允許Snap應用程式以經典模式執行,擁有更多的系統資源存取許可權。

完整的 Ansible Playbook 如 Listing 3-6 所示。

在Fedora類別Linux作業系統中安裝snap

在Fedora類別Linux作業系統中安裝snap需要額外的努力,因為你需要處理SquashFS相依性並為/snap目錄建立符號連結。其他部分的程式碼與清單3-7中所示的Ubuntu Ansible Playbook完全相同。

清單3-7. snap_fedora.yml

---
- name: snap module demo
  hosts: all
  become: true
  tasks:
  - name: snapd present
    ansible.builtin.yum:
      name:
        - snapd
        - fuse
        - squashfs-tools
        - squashfuse
        - kernel-modules
      state: present
  - name: symlink /snap
    ansible.builtin.file:
      src: "/var/lib/snapd/snap"
      dest: "/snap"
      state: link
  - name: load squashfs module
    community.general.modprobe:
      name: "squashfs"
      state: present
  - name: install microk8s via snap
    community.general.snap:
      name: microk8s
      state: present

內容解密:

  1. ansible.builtin.yum模組用於安裝必要的軟體包,包括snapdfusesquashfs-toolssquashfusekernel-modules
  2. 使用ansible.builtin.file模組建立/var/lib/snapd/snap/snap的符號連結。
  3. community.general.modprobe模組用於載入squashfs核心模組。
  4. 最後,使用community.general.snap模組透過snap安裝microk8s

執行結果是在你的Fedora機器上準備好完整的microk8s(見圖3-3)。

在容器中佈署Web伺服器

容器最優秀的特性之一是能夠將應用程式與資料分離。讓我們將這個隔離原則應用到你的服務中。例如,在容器中執行你的Web伺服器可以降低攻擊面並使服務平滑更新,同時保持檔案系統中的資料不變。

Apache在最著名的容器註冊中心中以名為httpd的容器形式提供。它支援所有架構,包括amd64、arm32v5、arm32v6、arm32v7、arm64v8、i386、mips64le、ppc64le和s390x。在撰寫本文時,標準映像檔根據Debian Linux 11 “bullseye”(最新或bullseye標籤)或Alpine Linux(alpine標籤)。

使用Docker在Debian類別系統上執行Apache

執行Apache Web伺服器容器需要六個步驟,你可以使用不同的Ansible模組自動化這些步驟:

  1. 首先,使用ansible.builtin.apt Ansible模組安裝一些Python軟體包和相依性。
  2. 然後,使用ansible.builtin.pip Ansible模組安裝Python的Docker模組。
  3. 接著,使用community.docker.docker_image Ansible模組從Docker Hub註冊中心提取映像檔。
  4. 現在,使用ansible.builtin.file模組建立檔案根目錄並設定正確的許可權。
  5. 然後,使用ansible.builtin.copy Ansible模組建立自訂的index.html檔案。你可以使用範本模組升級此步驟。
  6. 最後,使用community.docker.docker_container Ansible模組執行Web伺服器容器,設定正確的埠和卷設定。

清單3-8. httpd_debian.yml

---
- name: deploy httpd on container
  hosts: all
  become: true
  vars:
    webroot: "/webroot/"
  tasks:
  - name: system packages present
    ansible.builtin.apt:
      name:
        - python3-pip
        - virtualenv
        - python3-setuptools
      state: latest
      update_cache: true
  - name: Docker Module for Python
    ansible.builtin.pip:
      name: docker
  - name: pull image
    community.docker.docker_image:
      name: httpd
      source: pull
      tag: latest
  - name: webroot present
    ansible.builtin.file:
      path: "{{ webroot }}"
      state: directory
  - name: custom index.html
    ansible.builtin.copy:
      dest: "{{ webroot }}index.html"
      content: |
        Custom Web Page
  - name: run httpd container
    community.docker.docker_container:
      name: webserver
      image: httpd
      state: started
      detach: true
      exposed_ports:
        - 80
      ports:
        - "8080:80"
      volumes: "{{ webroot }}:/usr/local/apache2/htdocs/"

內容解密:

  1. 使用ansible.builtin.apt更新快取並安裝必要的Python軟體包。
  2. 使用ansible.builtin.pip安裝Python的Docker模組。
  3. 使用community.docker.docker_image從Docker Hub提取最新的httpd映像檔。
  4. 使用ansible.builtin.file建立Web根目錄。
  5. 使用ansible.builtin.copy建立自訂的index.html檔案。
  6. 使用community.docker.docker_container執行名為webserver的容器,將主機的8080埠對映到容器的80埠,並掛載Web根目錄到容器內的/usr/local/apache2/htdocs/

在Red Hat類別系統上使用Podman執行Apache

你可以在Red Hat系統上使用Podman容器引擎獲得與前一種情況相同的結果。整個過程需要四個步驟,你可以使用不同的Ansible模組自動化這些步驟:

  1. 首先,使用ansible.builtin.yum Ansible模組驗證Podman及其相依性是否已成功安裝在目標系統上。
  2. 其次,使用ansible.builtin.copy Ansible模組建立自訂的index.html檔案。請注意,現代Red Hat系統預設啟用SELinux,因此你需要設定container_share_t SELinux上下文;否則,檔案無法在主機和容器之間分享。
  3. 第三,使用containers.podman.podman_image Ansible模組從容器Hub註冊中心提取映像檔。
  4. 最後,使用containers.podman.podman_container Ansible模組執行Web伺服器容器,設定正確的埠和設定。

清單3-9. httpd_redhat.yml

---
- name: deploy httpd container
  hosts: all
  become: true
  gather_facts: false
  vars:
    webroot: "/webroot"
  tasks:
  - name: podman installed
    ansible.builtin.yum:
      name: podman
      state: latest
  - name: pull image
    containers.podman.podman_image:
      name: docker.io/library/httpd
      pull: true
      tag: latest
  - name: webroot present
    ansible.builtin.file:
      path: "{{ webroot }}"
      state: directory
      owner: "root"
      group: "root"
      mode: '0777'
      setype: "container_share_t"
  - name: custom index.html
    ansible.builtin.copy:
      dest: "{{ webroot }}/index.html"
      content: |
        Custom Web Page
      setype: "container_share_t"
  - name: run httpd container
    containers.podman.podman_container:
      name: webserver
      image: httpd
      state: started
      detach: true
      expose:
        - 80

內容解密:

  1. 使用 ansible.builtin.yum`` 安裝或更新 podman``。
  2. docker.io/library/httpd`` 提取最新的 httpd`` 映像檔。
  3. 建立 Web 根目錄並設定正確的許可權和 SELinux 上下文。
  4. 建立自訂的 `index.html`` 檔案並設定正確的 SELinux 上下文。
  5. 使用 containers.podman.podman_container`` 以 httpd 映像檔執行名為 `webserver 的容器。