Ansible 執行環境的建立,能有效隔離 Ansible 執行環境的依賴關係,避免與系統環境衝突。透過 Ansible Builder 建立執行環境映像,並結合 Ansible Runner 執行 Playbook,可以簡化 Kubernetes 叢集的管理流程。kubernetes.core.k8s 模組提供與 Kubernetes API 互動的功能,方便進行名稱空間的建立、佈署的管理等操作。此外,文章也說明瞭如何使用 Ansible 查詢外掛列出指定名稱空間中的所有佈署,以及如何處理 Kubernetes 佈署過程中可能遇到的錯誤狀態,例如 ImagePullBackOffCrashLoopBackOff

組態 Ansible 執行環境

Ansible 執行環境是由 Red Hat 發明的用於容器化 Ansible 執行的技術。它能夠維護作業系統依賴、Python 依賴和 Ansible 集合的隔離存檔,而不會干擾 Linux 系統。這是 Python 虛擬環境的進化版本,可以在 Kubernetes 叢集中原生執行。它取代了手動的 Python 虛擬環境、Ansible 模組依賴和 Ansible Tower bubblewrap。

建立 Ansible 執行環境

Ansible 執行環境依賴於 Ansible Builder(ansible-builder 命令)來建立。Ansible Builder 會產生一個包含容器映像構建上下文的目錄,其中包含 Containerfile 以及需要新增到映像中的其他檔案。

執行 Ansible Playbook

Ansible Runner(ansible-runner 命令工具)用於在 Ansible 執行環境中執行 Ansible Playbook。Ansible Runner 能夠讓你在當前機器上以容器的形式執行 Ansible 執行環境。

你可以使用 DNF 套件管理器(Fedora、CentOS 和 Red Hat Enterprise Linux)或 pip 套件管理器來安裝 ansible-builderansible-runner 命令列工具:

$ pip3 install ansible-builder
$ pip3 install ansible-runner

建立自訂的 Ansible 執行環境

清單 4-4 建立了一個名為 my_kube 的自訂 Ansible 執行環境,用於 Kubernetes。execution-environment.yml 檔案包含了最新執行環境的藍圖,指定了要自訂的作業系統套件(system: bindep.txt)、Python 函式庫(python: requirements.txt)和 Ansible 集合(galaxy: requirements.yml)。

execution-environment.yml 檔案

---
version: 1
dependencies:
  galaxy: requirements.yml
  python: requirements.txt
  system: bindep.txt
additional_build_steps:
  prepend: |
    RUN pip3 install --upgrade pip setuptools
  append:
    - RUN ls -al /

「#### 內容解密:」

  • version: 指定了執行環境的版本。
  • dependencies: 定義了執行環境的依賴,包括 Ansible 集合、Python 函式庫和作業系統套件。
  • additional_build_steps: 定義了額外的構建步驟,包括升級 pip 和 setuptools,以及列出根目錄下的檔案。

指定 Ansible 集合

清單 4-5 中的 requirements.yml 檔案指定了要下載的 Ansible 集合列表。在本例中,包括 cloud.commonkubernetes.core

requirements.yml 檔案

---
collections:
  - name: cloud.common
  - name: kubernetes.core

「#### 內容解密:」

  • collections: 定義了要下載的 Ansible 集合列表。
  • name: 指定了集合的名稱。

指定 Python 函式庫依賴

清單 4-6 中的 requirements.txt 檔案指定了 Python 函式庫依賴,包括 kubernetesPyYAMLjsonpatch

requirements.txt 檔案

kubernetes>=12.0.0
PyYAML>=3.11
jsonpatch

「#### 內容解密:」

  • 指定了 Python 函式庫的版本要求。

指定作業系統套件

清單 4-7 中的 bindep.txt 檔案指定了作業系統套件,包括 git

bindep.txt 檔案

git [platform:rpm]
git [platform:dpkg]

「#### 內容解密:」

  • 指定了根據不同平台(RPM 或 DEB)安裝 git 套件。

建構 Ansible 執行環境

使用 ansible-builder 命令建構 my_kube Ansible 執行環境:

$ ansible-builder build -t my_kube -v 3

建構完成後,使用以下命令建立映像:

$ podman build -f context/Containerfile -t my_kube context

使用 Ansible Runner 執行 Ansible Playbook

使用 ansible-runner 命令以容器的形式執行 Ansible Playbook:

$ ansible-runner run -p ping.yml --inventory inventory --container-image=my_kube .

這裡使用了一個簡單的 Ansible INI 清單檔案,針對本地主機使用本地連線:

localhost ansible_connection=local

Ping 測試

清單 4-8 中的 Ansible Playbook 使用了 ansible.builtin.ping 模組來測試與目標節點的連線。

ping.yml Playbook

---
- name: Ping test
  hosts: localhost
  tasks:
    - name: Ping test
      ping:

「#### 內容解密:」

  • 使用 ping 模組測試與目標節點的連線。

這樣,你就成功地組態了一個用於 Kubernetes 的自訂 Ansible 執行環境,並使用 Ansible Runner 在容器中執行了 Ansible Playbook。

使用Ansible管理Kubernetes名稱空間

在現代的DevOps與自動化維運中,Ansible已成為廣泛使用的工具之一,特別是在管理Kubernetes叢集時。本篇文章將探討如何使用Ansible來管理Kubernetes名稱空間,包括建立、列出以及相關的最佳實踐。

為何使用Ansible管理Kubernetes名稱空間?

Kubernetes作為一個強大的容器協調平台,提供了豐富的API和管理功能。然而,手動管理Kubernetes資源(如名稱空間)可能會變得繁瑣且容易出錯。Ansible透過其豐富的模組和Playbook功能,可以簡化這些任務,實作自動化和可重複性。

建立Kubernetes名稱空間

要建立一個Kubernetes名稱空間,可以使用kubernetes.core.k8s Ansible模組。以下是一個簡單的Playbook範例(ns_create.yml):

---
- name: 建立Kubernetes名稱空間
  hosts: localhost
  vars:
    myproject: "ansible-examples"
  tasks:
    - name: 確保名稱空間存在
      kubernetes.core.k8s:
        api_version: v1
        kind: Namespace
        name: "{{ myproject }}"
        state: present

內容解密:

  1. hosts: localhost:指定該Playbook執行在本地主機上。
  2. vars: 定義變數myproject,這裡的值為"ansible-examples",表示要建立的名稱空間名稱。
  3. kubernetes.core.k8s模組: 用於與Kubernetes API互動。
    • api_version: v1: 指定Kubernetes API版本。
    • kind: Namespace: 表示要操作的資源型別是名稱空間。
    • name: "{{ myproject }}": 使用變數myproject的值作為名稱空間的名稱。
    • state: present: 確保名稱空間存在,如果不存在則建立。

執行該Playbook的命令如下:

$ ansible-playbook -i inventory ns_create.yml

認證與安全性

在實際操作中,與Kubernetes叢集的互動需要認證。可以使用kubernetes.core.k8s_auth模組來處理認證。以下是一個包含認證步驟的Playbook範例(ns_create_auth.yml):

---
- name: 建立Kubernetes名稱空間並認證
  hosts: localhost
  vars:
    myproject: "ansible-examples"
    k8s_username: "kubeadmin"
    k8s_password: "password"
    k8s_host: "https://api.k8s:6443"
    k8s_validate: true
  tasks:
    - name: 取得存取令牌
      kubernetes.core.k8s_auth:
        username: "{{ k8s_username }}"
        password: "{{ k8s_password }}"
        host: "{{ k8s_host }}"
        validate_certs: "{{ k8s_validate }}"
      register: k8s_auth_results
    - name: 確保名稱空間存在
      kubernetes.core.k8s:
        api_key: "{{ k8s_auth_results.k8s_auth.api_key }}"
        api_version: v1
        kind: Namespace
        name: "{{ myproject }}"
        state: present

內容解密:

  1. k8s_auth模組: 用於取得存取Kubernetes叢集的令牌。
    • username, password, host: 分別指定使用者名稱、密碼和叢集地址。
    • validate_certs: 是否驗證SSL證書。
  2. register: k8s_auth_results: 將認證結果儲存到變數k8s_auth_results中。
  3. 在後續的任務中,使用取得的令牌進行認證。

列出所有名稱空間

管理員經常需要列出叢集中的所有名稱空間。以下是一個簡單的Playbook(ns_list.yml),用於列出所有名稱空間:

---
- name: 列出所有Kubernetes名稱空間
  hosts: localhost
  tasks:
    - name: 取得所有名稱空間列表
      ansible.builtin.set_fact:
        projects: "{{ query('kubernetes.core.k8s', api_version='v1', kind='Namespace') }}"
    - name: 顯示結果
      ansible.builtin.debug:
        msg: "{{ projects }}"

內容解密:

  1. query('kubernetes.core.k8s', ...): 使用查詢外掛呼叫kubernetes.core.k8s模組,取得指定資源(這裡是Namespace)的列表。
  2. set_fact: 將查詢結果儲存到變數projects中。
  3. debug模組: 列印出變數projects的值。

在Kubernetes中報告名稱空間內的佈署狀態

報告名稱空間內的佈署狀態是Kubernetes使用者或管理員常見且實用的任務。首先,您需要建立一個佈署,以便在Kubernetes/OpenShift叢集中列出它們。

建立Kubernetes佈署

Kubernetes佈署是一個核心物件,允許您指定Pod的副本數量。Pod定義包含在佈署的YAML清單檔案中。以下範例中的deployment.yaml檔案是一個簡單的佈署YAML檔案,它在ansible-examples名稱空間中佈署名為nginx的容器最新版本,具有兩個副本,監聽TCP 3000埠,如清單4-14所示。

清單4-14:deployment.yaml Kubernetes檔案

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: ansible-examples
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.22
        imagePullPolicy: Always
        ports:
        - containerPort: 3000

使用kubectl命令列工具或kubernetes.core.k8s Ansible模組套用佈署

您可以手動使用kubectl命令列工具或透過kubernetes.core.k8sAnsible模組將您的佈署套用到Kubernetes叢集:

$ kubectl apply -f deployment.yaml

成功執行kubectl命令後,會傳回以下訊息:

deployment.apps/nginx created

您可以使用以下命令檢查nginx佈署的狀態:

$ kubectl get deployment nginx

輸出確認您的nginx佈署已經執行了三分鐘(在AGE列下):

NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   2/2     1            1           3m

您還可以使用此命令檢查由您的佈署分配的Pod等Kubernetes資源:

$ kubectl get pods

如果您未指定kubectl名稱空間,請嘗試列出預設名稱空間的資源。您應該始終指定名稱空間(-n ansible-examples引數),以取得完整的Pod列表。如果您在螢幕上看到以下訊息,則意味著您忘記指定名稱空間:

No resources found in default namespace.

使用以下命令指定名稱空間:

$ kubectl get pods -n ansible-examples

輸出確認您的nginx Pod,以及ansible-examples名稱空間內的隨機識別碼:

NAME                     READY   STATUS    RESTARTS   AGE
nginx-98fabf9-pvw89      2/2     Running   0          5m

如您所見,Pod具有2個副本,狀態為Running,已執行5分鐘。

注意事項

當Kubernetes無法從容器登入檔中下載容器映像時,它會報告ImagePullBackOffCrashLoopBackOff狀態。這兩個狀態是相關的,表示Kubernetes叢集嘗試從登入檔下載映像但未成功。整個工作流程從ErrImagePull開始,然後是ImagePullBackOff,並持續嘗試。根本原因可能是映像名稱或標籤拼寫錯誤、登入檔問題、登入檔的速率限制(參見Docker Hub中的免費與專業帳戶)、未指定Pod的私密登入檔,或者只是連線性方面的運氣不好。

使用Ansible Playbook自動化佈署

您可以使用以下Ansible Playbook和k8s模組自動化您的Kubernetes deployment.yaml檔案的套用,如清單4-15所示。

清單4-15:deployment.yml Ansible Playbook檔案

---
- name: k8s deployment
  hosts: all
  vars:
    myproject: "ansible-examples"
  tasks:
  - name: namespace present
    kubernetes.core.k8s:
      api_version: v1
      kind: Namespace
      name: "{{ myproject }}"
      state: present
  - name: deployment present
    kubernetes.core.k8s:
      src: deployment.yaml
      namespace: "{{ myproject }}"
      state: present

在Ansible控制器機器中執行程式碼

現在,使用清單4-16所示的庫存,在Ansible控制器機器中執行您的程式碼。

清單4-16:庫存檔案

localhost ansible_connection=local

使用ansible-playbook命令成功執行的輸出包括以下內容:

  • 受管理的host:localhost
  • Play recap狀態:ok=3 changed=2
  • Task狀態:
    • TASK [namespace ansible-examples present] changed: [localhost]
    • TASK [deployment present] changed: [localhost]

您會收到兩個任務的changed狀態,這意味著佈署請求已成功傳送到Kubernetes叢集API並執行。兩個changed狀態表示名稱空間和佈署已建立。如果其中之一已經存在,您將收到ok狀態。

TASK [deployment present]
ok: [localhost]

注意事項

當名稱空間不存在時,您將收到Kubernetes傳回碼404錯誤;當名稱空間被終止時,您將收到403錯誤。

列出指定名稱空間中的所有佈署

以下程式碼列出了指定名稱空間中的所有佈署。如您在上一節中所探索的,Ansible查詢查詢外掛呼叫kubernetes.core.k8s模組與Kubernetes API互動,並傳回叢集中所有佈署的列表。查詢查詢外掛(有時簡稱為q)呼叫kubernetes.core.k8s模組,將佈署指定為kind引數,將ansible-examples指定為名稱空間引數。您可以列出其他型別的Kubernetes資源。

內容解密:

此段落描述瞭如何使用Ansible Playbook和k8s模組自動化Kubernetes佈署的過程。首先,建立了一個簡單的佈署YAML檔案,用於在指定的名稱空間中佈署一個名為nginx的容器。然後,透過kubectl命令列工具或Ansible Playbook將該佈署套用到Kubernetes叢集。最後,演示瞭如何使用Ansible查詢查詢外掛列出指定名稱空間中的所有佈署。