隨著容器技術的普及,管理多個容器平台的需求日益增長。Ansible 作為一個強大的自動化工具,提供豐富的模組,可以有效簡化容器平台的管理流程。本文將介紹如何使用 Ansible 管理 Kubernetes、Docker 以及主流雲端供應商的容器服務,讓開發者和維運團隊能更輕鬆地掌控容器化環境。透過 Ansible 的自動化能力,可以有效提升佈署效率、降低人為錯誤,並確保容器化應用程式的可靠執行。以下將逐步說明如何使用 Ansible 管理 Kubernetes 資源、Docker 容器以及與不同雲端平台的容器服務互動。
管理多容器平台
在當今世界,僅僅能夠執行一個映像檔並不被視為生產就緒的設定。要將佈署稱為「生產就緒」,您需要能夠證明您的應用程式所提供的服務即使在單一應用程式當機或硬體故障的情況下也能合理執行。通常,您還會有來自客戶的更多可靠性約束。
幸運的是,不僅您的軟體有這些需求,因此已經開發了協調解決方案來滿足這些需求。目前最成功的協調工具是 Kubernetes,由於其各種發行版和版本,我們將主要關注它。
Kubernetes 的理念是,您通知 Kubernetes 控制平面您想要 X 個 Y 應用程式的例項,Kubernetes 將計算在 Kubernetes 節點上執行的 Y 應用程式的例項數量,以確保例項數量為 X。如果例項太少,Kubernetes 將負責啟動更多例項,而如果例項太多,則將停止超出例項。
由於安裝和管理 Kubernetes 的複雜性,多家公司已經開始銷售簡化其操作並願意支援的 Kubernetes 發行版。目前最廣泛使用的發行版是 OpenShift:Red Hat Kubernetes 發行版。
為了簡化開發人員和維運團隊的生活,Ansible 提供了一個名為 ansible-container 的工具,用於建立容器以及支援容器的整個生命週期。
使用 ansible-container 佈署到 Kubernetes
讓我們學習如何使用 ansible-container 執行我們剛剛建立的映像檔。首先,我們需要映像檔本身,這是上一節的輸出結果!我們將假設您有權存取 Kubernetes 或 OpenShift 叢集進行測試。
要將應用程式佈署到叢集,您需要修改 container.yml 檔案以新增一些額外資訊。具體來說,我們需要新增一個名為 settings 的區段和一個名為 k8s_namespace 的區段來宣告我們的佈署設定。這個區段將如下所示:
k8s_namespace:
name: http-server
description: An HTTP server
display_name: HTTP server
新增了有關 Kubernetes 佈署的必要資訊後,我們可以繼續進行佈署:
$ ansible-container --engine kubernetes deploy
Ansible 完成執行後,您將能夠在 Kubernetes 叢集上找到 http-server 佈署。
幕後發生的事情是,Ansible 有一套模組(其名稱通常以 k8s 開頭),用於驅動 Kubernetes 叢集,並使用它們自動佈署應用程式。根據我們在上一節中建立的映像檔和在本文開始時新增的額外資訊,Ansible 能夠填充佈署範本,然後使用 k8s 模組進行佈署。
使用 Ansible 管理 Kubernetes 物件
現在您已經使用 ansible-container 佈署了第一個應用程式,接下來將學習如何與 Kubernetes 叢集互動。
安裝 Ansible Kubernetes 相依性
首先,您需要安裝 Python openshift 套件(您可以透過 pip 或作業系統套件管理系統安裝它)。
使用 Ansible 列出 Kubernetes 名稱空間
Kubernetes 叢集內部有多個名稱空間,您通常可以使用 kubectl get namespaces 找到它們。您可以使用 Ansible 建立一個名為 k8s-ns-show.yaml 的檔案,內容如下:
---
- hosts: localhost
tasks:
- name: Get information from K8s
k8s_info:
api_version: v1
kind: Namespace
register: ns
- name: Print info
debug:
var: ns
現在,我們可以執行它,如下所示:
$ ansible-playbook k8s-ns-show.yaml
您現在將在輸出中看到有關名稱空間的資訊。
使用 Ansible 建立 Kubernetes 名稱空間
到目前為止,我們已經學習瞭如何顯示現有的名稱空間,但通常 Ansible 以宣告式的方式用於實作所需的狀態。因此,讓我們建立一個新的 playbook,名為 k8s-ns.yaml,內容如下:
---
- hosts: localhost
tasks:
- name: Ensure the myns namespace exists
k8s:
api_version: v1
kind: Namespace
name: myns
state: present
在執行它之前,我們可以執行 kubectl get ns 以確保 myns 不存在。現在,我們可以執行 playbook,如下所示:
$ ansible-playbook k8s-ns.yaml
輸出應該類別似於以下內容:
PLAY [localhost]
*******************************************************************
TASK [Gathering Facts]
*************************************************************
ok: [localhost]
TASK [Ensure the myns namespace exists]
********************************************
changed: [localhost]
PLAY RECAP
*************************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
內容解密:
此 Playbook 使用 k8s 模組建立了一個名為 myns 的 Kubernetes 名稱空間。state: present 表示如果名稱空間不存在,則建立它,如果已經存在,則不進行任何操作。
此範例展示瞭如何使用 Ansible 以宣告式的方式管理 Kubernetes 物件。
透過使用 Ansible 的 k8s 和 k8s_info 模組,您可以輕鬆地與 Kubernetes 叢集互動並管理其資源。
這對於自動化和簡化 Kubernetes 資源的管理非常有幫助。
這些範例程式碼和步驟提供了使用 Ansible 管理 Kubernetes 名稱空間的基本方法。
您可以根據自己的需求擴充套件和修改這些範例,以實作更複雜的管理任務。
Ansible 的宣告式語法使得描述所需的狀態變得簡單明瞭,從而使管理 Kubernetes 資源變得更加容易和直觀。
Ansible 與 Kubernetes 互動流程圖示
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 內容解密:
rectangle "k8s_info" as node1
rectangle "k8s" as node2
rectangle "取得資訊" as node3
rectangle "建立/更新資源" as node4
node1 --> node2
node2 --> node3
node3 --> node4
@enduml
此圖示展示了 Ansible 如何透過 k8s_info 和 k8s 模組與 Kubernetes API 互動,以取得資訊和建立或更新資源。
圖表內容解密:
此圖表清晰地展示了 Ansible 與 Kubernetes 之間的互動流程,包括取得資訊和建立或更新資源的動作。 這有助於更好地理解 Ansible 如何管理和與 Kubernetes 資源進行互動。 透過使用 Plantuml 圖表,我們能夠視覺化地呈現這些互動,使其更容易被理解和掌握。 這對於想要深入瞭解 Ansible 和 Kubernetes 整合的讀者來說是非常有用的。
使用 Ansible 管理 Kubernetes 與 Docker
使用 Ansible 建立 Kubernetes Namespace
在現代化的 DevOps 環境中,自動化是提升效率的關鍵。Ansible 是一種流行的自動化工具,可以用來管理 Kubernetes 資源。首先,我們將探討如何使用 Ansible 建立 Kubernetes Namespace。
建立 Namespace
要使用 Ansible 建立 Kubernetes Namespace,我們需要建立一個 playbook 檔案,例如 k8s-ns.yaml,其內容如下:
---
- hosts: localhost
tasks:
- name: 確保 myns namespace 存在
k8s:
state: present
definition:
apiVersion: v1
kind: Namespace
metadata:
name: myns
執行此 playbook 後,可以使用 kubectl get ns 指令確認 namespace 是否建立成功。
內容解密:
hosts: localhost:指定執行此 playbook 的主機為本地主機。k8s模組:用於管理 Kubernetes 資源。state: present:確保指定的資源存在,如果不存在則建立。definition:定義 Kubernetes 資源的詳細內容,在此例中為一個 Namespace。
使用 Ansible 建立 Kubernetes Service
建立好 Namespace 後,我們可以在該 Namespace 中建立 Service。
建立 Service
建立一個名為 k8s-svc.yaml 的 playbook,其內容如下:
---
- hosts: localhost
tasks:
- name: 確保 Service mysvc 存在
k8s:
state: present
definition:
apiVersion: v1
kind: Service
metadata:
name: mysvc
namespace: myns
spec:
selector:
app: myapp
service: mysvc
ports:
- protocol: TCP
targetPort: 800
name: port-80-tcp
port: 80
執行此 playbook 後,使用 kubectl get svc -n myns 檢查 Service 是否建立成功。
內容解密:
metadata中的namespace:指定 Service 所屬的 Namespace。spec.selector:定義 Service 的選擇器,用於選擇對應的 Pod。ports:定義 Service 的連線埠設定。
使用 Ansible 管理 Docker
除了管理 Kubernetes 資源外,Ansible 也可用於管理 Docker。
建立 Docker Container
首先,確保本地已安裝 Docker 並且 Docker daemon 正在執行。然後,建立一個名為 start-docker-container.yaml 的 playbook,其內容如下:
---
- hosts: localhost
tasks:
- name: 啟動一個帶有指令的容器
docker_container:
name: test-container
image: alpine
command:
- echo
- "Hello, World!"
執行此 playbook 後,可以使用 docker container list -a 檢查容器是否成功執行。
內容解密:
docker_container模組:用於管理 Docker 容器。name和image:定義容器的名稱和使用的映像檔。command:定義容器啟動時執行的指令。
使用Ansible管理容器與雲端服務
探索容器相關模組
在組織成長的過程中,不同部門可能會採用不同的技術方案。當某個供應商的解決方案被證明有效時,該部門可能會傾向於採用該供應商提供的其他新技術。這種趨勢,加上技術更新的週期,會導致同一組織內出現多種解決同一個問題的方案。
如果您的組織正面臨容器技術多樣化的挑戰,Ansible能夠提供幫助。由於Ansible具備與大多數(如果不是全部)容器平台協同工作的能力,因此可以有效地管理多種容器技術。
尋找合適的Ansible模組
在Ansible中進行模組研究的第一步是存取模組索引。通常,您可以在這裡找到與您需求相符的類別,但並非總是如此。
容器技術就是這樣一個例外,因此沒有「容器」類別。解決方案是存取「所有模組」,然後使用瀏覽器的內建搜尋功能(通常透過按Ctrl+F實作)來查詢可能的模組名稱或簡短描述。
每個Ansible模組都被歸類別到一個類別中,但很多時候,模組可能適用於多個類別,因此找到它們並不總是容易。
主要容器平台及其對應的Ansible模組
Amazon Web Services(AWS)
AWS在2014年推出了Elastic Container Service(ECS),用於在其基礎設施上佈署和協調Docker容器。隔年,AWS又推出了Elastic Container Registry(ECR),一個託管的Docker Registry服務。雖然ECS並未如AWS所期望的那樣普及,但AWS在2018年推出了Elastic Kubernetes Service(EKS),以便那些希望在AWS上執行Kubernetes的人能夠使用託管服務。
對於使用EKS的使用者,可以使用Kubernetes特定的模組進行管理。如果選擇使用ECS,則有多個模組可用於幫助管理,包括:
ecs_cluster:允許建立或終止ECS叢集ecs_ecr:允許管理ECRecs_service:允許在ECS中建立、終止、啟動或停止服務ecs_task:允許在ECS中執行、啟動或停止任務ecs_service_facts:允許Ansible列出或描述ECS中的服務
Microsoft Azure
Azure在2018年宣佈了Azure Container Service(ACS)和Azure Kubernetes Service(AKS)。這兩項服務都是託管的Kubernetes解決方案,因此可以使用Kubernetes模組進行管理。此外,Ansible提供了兩個特定的模組:
azure_rm_acs:允許建立、更新和刪除Azure Container Service例項azure_rm_aks:允許建立、更新和刪除Azure Kubernetes Service例項
Google Cloud Platform(GCP)
GCP在2015年推出了Google Kubernetes Engine(GKE),這是GCP版本的託管Kubernetes。因此,GKE與Ansible的Kubernetes模組相容。除此之外,還有多個GKE特定的模組,例如:
gcp_container_cluster:允許建立GCP叢集gcp_container_cluster_facts:允許收集GCP叢集的事實gcp_container_node_pool:允許建立GCP NodePoolgcp_container_node_pool_facts:允許收集GCP NodePool的事實
Red Hat OpenShift
Red Hat在2011年開始了OpenShift專案,最初根據自己的容器執行時。在2015年發布的第3版中,OpenShift完全根據Kubernetes重新設計。因此,所有Ansible的Kubernetes模組都適用於OpenShift。此外,還有oc模組,雖然目前仍存在,但已被標記為棄用,優先使用Kubernetes模組。
Kubernetes
Kubernetes由Google在2015年發布,很快就在其周圍形成了龐大的社群。Ansible允許多個模組來管理Kubernetes叢集:
k8s:允許管理任何型別的Kubernetes物件k8s_auth:允許對需要明確登入步驟的Kubernetes叢集進行身份驗證k8s_facts:允許檢查Kubernetes物件k8s_scale:允許為Deployment、ReplicaSet、Replication Controller或Job設定新的大小k8s_service:允許管理Kubernetes上的服務
LXC和LXD
LXC和LXD也是用於在Linux上執行容器的系統。這些系統也得到了Ansible的支援,相關模組包括:
lxc_container:允許管理LXC容器lxd_container:允許管理LXD容器lxd_profile:允許管理LXD組態檔