返回文章列表

Ansible自動化管理Kubernetes資源

本文介紹如何使用 Ansible 自動化管理 Kubernetes 資源,涵蓋 Deployment 列表、Pod 和 Secret 建立、服務暴露、網路組態以及擴充套件佈署等核心操作。文章提供詳細的 Playbook 範例和 YAML 組態檔案,並輔以流程圖和程式碼片段,幫助讀者快速上手 Ansible 管理

DevOps 容器化

Ansible 提供了便捷的模組和 Playbook,讓開發者能以程式化方式管理 Kubernetes 資源,從而提升效率和可靠性。本文涵蓋了從基礎操作到進階組態的完整流程,包含 Deployment 的查詢、Pod 和 Secret 的建立、服務型別的選擇與組態、以及如何使用 Ansible 和 kubectl 進行佈署擴充套件。透過這些實務操作,可以有效降低人為錯誤,並確保 Kubernetes 叢集的穩定執行。

使用Ansible管理Kubernetes資源

概述

本文介紹如何使用Ansible自動化管理Kubernetes資源,包括列出Deployment、建立Pod和Secret等操作。

列出Kubernetes中的Deployment

要列出Kubernetes叢集中的Deployment,可以使用kubernetes.core.k8s查詢外掛。該外掛傳回從Kubernetes叢集接收到的完整JSON輸出。為了提取單個元素(例如Deployment名稱),可以使用community.general.json_query過濾外掛。

安裝必要的集合和函式庫

在使用json_query過濾外掛之前,需要安裝community.general Ansible集合和Python jmespath函式庫。

$ ansible-galaxy collection install community.general
$ pip3 install jmespath

示例Playbook:列出Deployment

---
- name: k8s deployments
  hosts: all
  tasks:
    - name: list all deployments
      ansible.builtin.set_fact:
        deployments: "{{ query('kubernetes.core.k8s', kind='Deployment', namespace='ansible-examples') | community.general.json_query('[*].metadata.name') }}"
    - name: display the result
      ansible.builtin.debug:
        msg: "{{ deployments }}"

執行Playbook

使用ansible-playbook命令執行Playbook,並指定inventory檔案。

$ ansible-playbook -i inventory deployment_list.yml

建立Pod

Pod是Kubernetes中的基本執行單元。要建立Pod,可以使用kubernetes.core.k8s模組。

示例Playbook:建立Pod

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

Pod的YAML定義檔案(pod.yaml)

---
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
    - name: nginx
      image: nginx:latest
      ports:
        - containerPort: 80

建立Secret

Secret用於儲存敏感資訊,如密碼、令牌等。可以使用kubernetes.core.k8s模組建立Secret。

示例Playbook:建立Secret

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

Secret的YAML定義檔案(secret.yaml)

---
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
  namespace: ansible-examples
type: Opaque
data:
  username: YWRtaW4=
  password: bXlzdXBlcnNlY3JldHBhc3N3b3Jk

base64編碼的值計算方法:

import base64

# 編碼username和password為base64格式。
username = 'admin'
password = 'mysupersecretpassword'

encoded_username = base64.b64encode(username.encode()).decode()
encoded_password = base64.b64encode(password.encode()).decode()

print(f"username的base64編碼為:{encoded_username}")
print(f"password的base64編碼為:{encoded_password}")
Ansible管理Kubernetes資源流程圖

圖表翻譯: 此圖示描述了使用Ansible管理Kubernetes資源的基本流程。首先,需要安裝必要的Ansible集合和Python函式庫。接著,編寫Ansible Playbook以定義所需的操作。然後,執行該Playbook。最後,檢查執行結果以確保操作成功。

使用Ansible自動化管理Kubernetes資源是一種高效且可靠的方法,可以簡化叢集管理任務,提高維運效率。透過掌握相關的Ansible模組和Playbook編寫技巧,可以更好地利用Kubernetes進行應用佈署和管理。

Kubernetes 資源管理與網路組態詳解

在 Kubernetes 環境中,管理和暴露應用程式至外部存取是一個重要的任務。本文將探討如何使用 Kubernetes Service 來暴露應用程式,以及 Kubernetes 網路組態的相關技術。

使用 Secret 管理敏感資訊

在 Kubernetes 中,Secret 用於儲存敏感資訊,如密碼、OAuth 權杖和 SSH 金鑰。以下是一個建立 Secret 的範例:

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  # base64 編碼的資料
  username: dXNlcm5hbWU=
  password: cGFzc3dvcmQ=

內容解密:

  • apiVersionkind 定義了資源的型別和版本。
  • metadata 包含了資源的名稱和其他元資料。
  • type 指定了 Secret 的型別,Opaque 表示這是一個通用的 Secret。
  • data 欄位包含了 base64 編碼的敏感資訊。

使用 Service 暴露應用程式

Kubernetes Service 提供了一個穩定的網路介面,用於存取一組 Pod。以下是一個簡單的 Service 組態範例:

apiVersion: v1
kind: Service
metadata:
  name: nginx-example
spec:
  selector:
    app: nginx-example
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000

內容解密:

  • spec.selector 指定了 Service 將流量轉發到哪些 Pod。
  • ports.protocolports.portports.targetPort 定義了 Service 的連線埠組態,將外部的 TCP 80 連線埠對映到 Pod 的 TCP 3000 連線埠。

使用 Ansible 管理 Kubernetes 資源

可以使用 Ansible 的 kubernetes.core.k8s 模組來管理 Kubernetes 資源。以下是一個範例 Playbook,用於建立上述 Service:

---
- name: k8s service
  hosts: all
  vars:
    myproject: "ansible-examples"
  tasks:
  - name: k8s service
    kubernetes.core.k8s:
      src: service.yaml
      namespace: "{{ myproject }}"
      state: present

內容解密:

  • hosts 指定了 Playbook 將執行的主機。
  • vars 定義了變數 myproject,用於指定名稱空間。
  • tasks 列出了要執行的任務,使用 kubernetes.core.k8s 模組來應用 service.yaml 組態檔案。

Kubernetes 網路組態技術

Kubernetes 提供了多種網路組態技術,用於管理和暴露服務:

  1. ClusterIP:預設型別,只能在叢集內部存取。
  2. NodePort:在每個節點上開放一個靜態連線埠,可以從叢集外部存取。
  3. LoadBalancer:暴露一個外部負載平衡器。
  4. Ingress:提供 HTTP 和 HTTPS 路由規則,減少負載平衡器的數量。
  5. ExternalName:將 Service 對映到一個 DNS 名稱。

ClusterIP 組態範例

apiVersion: v1
kind: Service
metadata:
  name: "nginx-example"
  namespace: "mynamespace"
spec:
  type: ClusterIP
  selector:
    app: "nginx"
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 9376

內容解密:

  • type: ClusterIP 指定了 Service 的型別。
  • selectorports 的組態與前述相同,用於將流量轉發到對應的 Pod。

Kubernetes 服務型別與應用擴充套件

Kubernetes 提供多種服務型別以滿足不同的應用需求,包括 ClusterIP、NodePort、LoadBalancer、Ingress 和 ExternalName。這些服務型別使得應用能夠在叢集中被有效暴露和存取。

ClusterIP 服務型別

ClusterIP 是 Kubernetes 中的預設服務型別。它為服務提供一個內部的 IP 地址,使得該服務可以在叢集內被其他 Pod 存取。

NodePort 服務型別

NodePort 服務型別在每個節點上開放一個隨機埠(除非指定特定埠),允許外部流量透過該埠存取服務。kube-proxy 元件負責將流量從 NodePort 轉發到服務的 ClusterIP,然後再到後端的 Pod。

apiVersion: v1
kind: Service
metadata:
  name: "nginx-example"
  namespace: "mynamespace"
spec:
  type: NodePort
  selector:
    app: "nginx"
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 9376
    nodePort: 25000

內容解密:

  • type: NodePort 指定了服務型別為 NodePort。
  • nodePort: 25000 指定了節點上開放的埠號為 25000。
  • targetPort: 9376 指定了流量應轉發到的 Pod 的埠號。

LoadBalancer 服務型別

LoadBalancer 服務型別擴充套件了 NodePort,透過在所有節點前新增一個負載平衡器,使得外部流量可以透過負載平衡器存取服務。

apiVersion: v1
kind: Service
metadata:
  name: "nginx-example"
  namespace: "mynamespace"
spec:
  type: LoadBalancer
  selector:
    app: "nginx"
  ports:
  - name: http
    port: 80
    targetPort: 9376

內容解密:

  • type: LoadBalancer 指定了服務型別為 LoadBalancer。
  • 負載平衡器會將外部流量路由到節點上的特定埠。

Ingress 資源

Ingress 資源提供了一種方式來暴露 HTTP 和 HTTPS 路由到叢集外部,並根據定義的流量規則將流量路由到內部的服務。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: "nginx-example"
  namespace: "mynamespace"
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx-example
  rules:
  - http:
      paths:
      - path: /webapp
        backend:
          service:
            serviceName: webapp
            servicePort: 9376

內容解密:

  • ingressClassName: nginx-example 指定了使用的 Ingress 控制器的類別。
  • path: /webapp 定義了路徑為 /webapp 的流量應被路由到 webapp 服務的 9376 埠。

ExternalName 服務型別

ExternalName 服務型別用於將叢集內的服務對映到外部資源,如資料函式庫或檔案系統。

apiVersion: v1
kind: Service
metadata:
  name: "nginx-example"
  namespace: "mynamespace"
spec:
  type: ExternalName
  externalName: mydb.example.com

內容解密:

  • type: ExternalName 指定了服務型別為 ExternalName。
  • externalName: mydb.example.com 指定了外部資源的網域名稱。

應用擴充套件

為了實作高用性和容錯性,Kubernetes 允許執行多個 Pod 複本,並提供了 PodDisruptionBudget(PDB)來限制並發中斷的數量,從而確保應用的高用性。

圖表說明

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Ansible自動化管理Kubernetes資源

package "Kubernetes Cluster" {
    package "Control Plane" {
        component [API Server] as api
        component [Controller Manager] as cm
        component [Scheduler] as sched
        database [etcd] as etcd
    }

    package "Worker Nodes" {
        component [Kubelet] as kubelet
        component [Kube-proxy] as proxy
        package "Pods" {
            component [Container 1] as c1
            component [Container 2] as c2
        }
    }
}

api --> etcd : 儲存狀態
api --> cm : 控制迴圈
api --> sched : 調度決策
api --> kubelet : 指令下達
kubelet --> c1
kubelet --> c2
proxy --> c1 : 網路代理
proxy --> c2

note right of api
  核心 API 入口
  所有操作經由此處
end note

@enduml

圖表翻譯: 此圖示描述了客戶端請求透過負載平衡器到達 NodePort,然後被轉發到服務,最後由服務將請求分配到後端的 Pod 的流程。

Kubernetes 擴充套件功能與 Ansible 自動化

Kubernetes 平台最強大的功能之一便是其擴充套件能力,能夠根據客戶需求動態調整資源。在本章中,我們將探討如何使用 kubectl 命令和 Ansible 的 kubernetes.core.k8s_scale 模組來擴充套件佈署(Deployment)。

使用 Kubectl 命令擴充套件佈署

使用 kubectl scale 命令可以輕鬆地增加或減少佈署的副本數量。以下範例將 nginx 佈署的副本數量擴充套件到 3:

$ kubectl scale deployment nginx --replicas=3

執行後,輸出確認 nginx 佈署已成功擴充套件:

deployment.apps/nginx scaled

檢查佈署狀態:

$ kubectl get deployments

輸出顯示 nginx 現在執行在 3 個副本上:

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

同樣地,可以縮減佈署的副本數量:

$ kubectl scale deployment nginx --replicas=1

使用 Ansible 擴充套件佈署

Ansible 的 kubernetes.core.k8s_scale 模組提供了與 kubectl 命令類別似的功能,能夠擴充套件佈署、ReplicaSet、Replication Controller 和 Job。以下是一個範例 Playbook,用於將 nginx 佈署的副本數量擴充套件到 10:

scale_up.yml

---
- name: k8s scale
  hosts: all
  vars:
    myproject: "ansible-examples"
    mydeployment: "nginx"
    myreplica: 10
    mytimeout: 120
  tasks:
    - name: scale Deployment
      kubernetes.core.k8s_scale:
        api_version: v1
        kind: Deployment
        name: "{{ mydeployment }}"
        namespace: "{{ myproject }}"
        replicas: "{{ myreplica }}"
        wait_timeout: "{{ mytimeout }}"

執行該 Playbook:

$ ansible-playbook -i localhost scale_up.yml

內容解密:

  1. api_versionkind:指定 Kubernetes 資源的 API 版本和型別。
  2. namenamespace:指定要擴充套件的佈署名稱和名稱空間。
  3. replicas:指定要擴充套件到的副本數量。
  4. wait_timeout:指定等待操作完成的超時時間。

自動擴充套件

Kubernetes 提供了自動擴充套件功能,可以根據指標自動調整叢集資源。

  • 水平擴充套件(Horizontal Pod Autoscaler, HPA):根據需求動態增加或減少相同大小的 Pod。
  • 垂直擴充套件(Vertical Pod Autoscaler, VPA):保持 Pod 數量不變,但調整其資源大小。

Kubernetes Cluster Autoscaler (CA)

CA 能夠根據應用需求動態調整叢集資源。要佈署 CA,需要建立一個 Service Account 並授予相應許可權。

組態引數
KeyValue
k8s.io/cluster-autoscaler/my-clusterowned
k8s.io/cluster-autoscaler/enabledtrue

下載並應用 Cluster Autoscaler 的 YAML 清單檔案:

$ kubectl apply -f cluster-autoscaler-autodiscover.yaml

圖表翻譯:

此圖示展示了 Kubernetes Pod 資源利用率的變化。在擴充套件操作後,Pod 數量從 2 增加到 10,同時其他資源也相應增加。