Kubernetes 叢集的監控和日誌管理對於系統穩定性和效能至關重要。Prometheus Operator 提供了 Kubernetes 原生的監控解決方案,而 Ansible 則可以自動化佈署和管理流程。本文將介紹如何結合 Prometheus Operator 和 Ansible,實作 Kubernetes 監控和日誌管理的自動化,並探討節點管理的 Taint、Drain、Cordon 和 Uncordon 等操作,讓讀者能更有效地管理 Kubernetes 叢集。此方法能有效提升維運效率,確保系統穩定執行。透過 Ansible 的自動化能力,可以簡化佈署和管理流程,降低人為錯誤的風險。
Kubernetes 監控與日誌管理:Prometheus 與 Ansible 的整合應用
在現代化的 Kubernetes 環境中,監控和日誌管理是確保系統穩定性和效能的關鍵。本篇文章將探討如何使用 Prometheus Operator 和 Ansible 來佈署和管理 Kubernetes 叢集的監控與日誌收集。
使用 Prometheus Operator 進行 Kubernetes 監控
Prometheus Operator 是 Kubernetes 原生的解決方案,允許使用者佈署和管理 Prometheus 及其相關元件,如 Alertmanager 和 Grafana。它提供了宣告式的組態方式,讓使用者可以指定監控堆積疊的期望狀態,並由 Operator 確保其始終保持最新狀態。
佈署 Prometheus Operator
佈署 Prometheus Operator 的最簡單方法是使用 kube-prometheus 專案。kube-prometheus 專案透過佈署 Prometheus Operator 來實作端對端的 Kubernetes 叢集監控。
下載 kube-prometheus 專案:
$ git clone https://github.com/prometheus-operator/kube-prometheus.git佈署 kube-prometheus:
$ kubectl create -f manifests/setup $ kubectl create -f manifests/轉發 Prometheus、Alertmanager 和 Grafana 的埠:
$ kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090 $ kubectl --namespace monitoring port-forward svc/alertmanager-main 9093 $ kubectl --namespace monitoring port-forward svc/grafana 3000
使用 Ansible 自動化佈署 Prometheus
Ansible 是另一種佈署和管理 Prometheus 的有效工具。你可以使用 Ansible Galaxy 中的 prometheus.prometheus Collection 來自動化安裝 Prometheus。
安裝 prometheus.prometheus Collection:
$ ansible-galaxy collection install prometheus.prometheus建立 Playbook(例如
prometheus.yml):
- name: install prometheus
hosts: all
roles:
- prometheus.prometheus.prometheus
vars:
prometheus_targets:
node:
- targets:
- k8s.ansiblepilot.com:9100 labels: env: ansible-examples
- targets:
- prometheus.prometheus.prometheus
vars:
prometheus_targets:
node:
3. **執行 Playbook**:
```bash
$ ansible-playbook -i inventory prometheus.yml
使用 Helm Chart 佈署 Prometheus Operator
另一個佈署 Prometheus Operator 的方法是使用 Helm Chart。你可以重用之前的 Ansible Playbook,並透過命令列指定額外的變數來啟用 Helm 倉函式庫並安裝 kube-prometheus-stack。
啟用 Helm 倉函式庫:
$ ansible-playbook -i inventory -e "helm_chart_name=prometheus-community" -e "helm_chart_url=https://prometheus-community.github.io/helm-charts" helm_repo_present.yml安裝 kube-prometheus-stack:
$ ansible-playbook -i inventory -e "chart_name=kube-prometheus-stack" -e "chart_ref=prometheus-community/kube-prometheus-stack" helm_present.yml
從 Kubernetes 資源中取得日誌
要手動從 Kubernetes 資源中取得日誌,可以使用 kubectl logs 命令。這個命令允許你檢視 Pod 中容器的日誌,或者檢索 Deployment、StatefulSet 或 CronJob 等資源的日誌。
使用 Ansible Playbook 取得日誌
你也可以編寫 Ansible Playbook 來自動化日誌收集的過程。以下是一個範例 Playbook,用於從指定的 Pod 或其他資源中取得日誌:
---
- name: k8s log
hosts: all
vars:
myproject: "ansible-examples"
myname: "nginx-server"
mykind: "Deployment"
tasks:
- name: get log from resource
kubernetes.core.k8s_log:
api_version: apps/v1
kind: "{{ mykind }}"
namespace: "{{ myproject }}"
name: "{{ myname }}"
register: log
- name: display log
ansible.builtin.debug:
var: log
執行這個 Playbook:
$ ansible-playbook -i inventory log_resource.yml
使用Ansible管理Kubernetes資源
套用JSON Patch操作
JSON Patch是一種描述JSON檔案變更的格式。要手動將JSON patch操作套用到現有的Kubernetes物件,可以使用kubectl patch命令。此命令需要兩個引數:物件名稱和JSON patch檔案。
patch檔案應包含一個或多個操作,以JSON或YAML格式表示,您希望將這些操作套用到物件上。例如,要為現有的pod新增一個新的標籤,可以建立一個包含以下YAML的patch檔案,如清單6-23所示。
清單6-23. patch-file.yaml檔案
- op: add
path: /metadata/labels/new-label
value: new-value
然後,可以使用以下命令將此patch套用到nginx-server pod物件:
$ kubectl patch pod nginx-server --patch "$(cat patch-file.yaml)"
這將為pod新增新的標籤。您可以使用相同的命令和不同的patch檔案對叢集中的其他物件進行更改。
也可以使用如清單6-24所示的Ansible Playbook自動執行上述操作。
清單6-24. patch.yml檔案
---
- name: k8s patch
hosts: all
vars:
mypod: "nginx-server"
myproject: "ansible-examples"
tasks:
- name: patch a Pod
kubernetes.core.k8s_json_patch:
kind: Pod
namespace: "{{ myproject }}"
name: "{{ mypod }}"
patch:
- op: add
path: /metadata/labels/new-label
value: new-value
程式碼解析:
此Ansible Playbook定義了一個名為k8s patch的遊戲,目標主機為all。在vars段中定義了兩個變數:mypod和myproject,分別代表pod的名稱和專案的名稱。在tasks段中,定義了一個名為patch a Pod的任務,使用kubernetes.core.k8s_json_patch模組對指定的pod進行patch操作。
使用localhost inventory執行此程式碼,如清單6-25所示。
清單6-25. Inventory檔案
localhost ansible_connection=local
執行patch.yml Ansible Playbook:
$ ansible-playbook -i inventory patch.yml
成功執行的輸出包括:
- Play recap狀態:ok=2 changed=1
- Task狀態:TASK [patch a Pod] changed: [localhost]
複製檔案和目錄到和從Pod
在Kubernetes中,將檔案和目錄複製到和從pod中是非常有用的,尤其是在開發的早期階段或進行一些調查時。對於手動操作,可以使用kubectl cp命令。此命令允許您在pod和本地檔案系統之間複製檔案和目錄。命令的語法是kubectl cp <source> <destination>,其中source可以是pod或本地檔案系統,destination可以是pod或本地檔案系統。
例如,要將檔案從pod複製到本地檔案系統,可以使用以下命令:
$ kubectl cp <pod-name>:/path/to/file /local/destination/path
同樣地,要將檔案從本地檔案系統複製到pod,可以使用以下命令:
$ kubectl cp /local/source/path <pod-name>:/path/to/destination
您可以使用kubernetes.core.k8s_cp Ansible模組自動執行此操作。引數state定義了您想要的預設操作是將資料從本地複製到pod(to_pod選項)還是從pod複製到本地(from_pod選項)。
清單6-26中的Ansible Playbook將資料從名為nginx-server的pod中的/data目錄複製到名為/tmp/data的本地資料夾。
清單6-26. cp.yml檔案
---
- name: k8s copy
hosts: all
vars:
mypod: "nginx-server"
myproject: "ansible-examples"
remote_path: "/data"
local_path: "/tmp/data"
direction: "from_pod"
tasks:
- name: copy data
kubernetes.core.k8s_cp:
namespace: "{{ myproject }}"
pod: "{{ mypod }}"
remote_path: "{{ remote_path }}"
local_path: "{{ local_path }}"
state: "{{ direction }}"
程式碼解析:
此Ansible Playbook定義了一個名為k8s copy的遊戲,目標主機為all。在vars段中定義了五個變數:mypod、myproject、remote_path、local_path和direction,分別代表pod的名稱、專案的名稱、遠端路徑、本地路徑和複製方向。在tasks段中,定義了一個名為copy data的任務,使用kubernetes.core.k8s_cp模組進行檔案複製。
使用如清單6-27所示的localhost inventory執行此程式碼。
清單6-27. Inventory檔案
localhost ansible_connection=local
執行您的cp.yml Ansible Playbook:
$ ansible-playbook -i inventory cp.yml
成功執行的輸出包括:
- Play recap狀態:ok=2 changed=1
- Task狀態:TASK [copy data] changed: [localhost]
管理Kubernetes上的服務
要管理Kubernetes上的服務,可以使用kubectl命令列工具。此工具允許您在Kubernetes叢集中建立、編輯、刪除和檢視服務。
要建立服務,可以使用kubectl expose命令,該命令將佈署或pod作為引數。
要編輯服務,可以使用將在編輯器中開啟服務定義的 kubectl edit 命令。
要刪除服務,可以使用 kubectl delete 命令,該命令將服務名稱和名稱空間作為引數。
要檢視服務,可以使用 kubectl get 命令,該命令將服務名稱和名稱空間作為引數。
您還可以使用 kubectl describe 命令來檢視有關服務的詳細資訊。
您可以使用如清單6-28所示的Ansible Playbook自動管理Kubernetes叢集上的服務。
清單6-28. service.yml檔案
---
- name: k8s service
hosts: all
tasks:
- name: expose https port with ClusterIP
kubernetes.core.k8s_service:
state: present
name: port-https
namespace: default
ports:
- port: 443
protocol: TCP
selector:
key: special
程式碼解析:
此Ansible Playbook定義了一個名為 k8s service 的遊戲,目標主機為 all. 在 tasks. 中定義了一個名為 expose https port with ClusterIP. 的任務. 使用 kubernetes.core.k8s_service. 對指定的服務進行操作.
透過指定 localhost. 在inventory中執行此程式碼,如 清單6-29. 所示。
清單6-29. Inventory檔案
localhost ansible_connection=local
執行您的service.yml Ansible Playbook:
$ ansible-playbook -i inventory service.yml
Kubernetes 節點管理:Taint、Drain、Cordon 與 Uncordon 操作詳解
在 Kubernetes 叢集管理中,維護節點的狀態對於確保系統的穩定性和可靠性至關重要。為了達到這一目的,Kubernetes 提供了多種工具和操作,包括 Taint、Drain、Cordon 和 Uncordon。本文將探討這些操作的原理、應用場景以及如何使用 Ansible Playbook 來自動化這些操作。
Taint Nodes:節點汙染
Taint 是 Kubernetes 中用於標記節點的一種機制,目的是避免不符合特定條件的 Pod 被排程到這些節點上。典型的應用場景包括將具有特殊硬體(如 GPU)的節點保留給需要這些資源的 Pod,或者在進行節點維護時避免新的 Pod 被排程到該節點。
使用 Ansible Taint 節點
以下是一個使用 Ansible Playbook 對節點進行 Taint 操作的範例(taint.yml 檔案):
---
- name: k8s taint
hosts: all
vars:
mynode: "k8s.ansiblepilot.com"
tasks:
- name: taint node
kubernetes.core.k8s_taint:
state: present
name: "{{ mynode }}"
taints:
- effect: NoExecute
key: "key1"
value: "value1"
- effect: NoSchedule
key: "key1"
value: "value1"
內容解密:
state: present表示如果 Taint 不存在,則建立它。name: "{{ mynode }}"指定要進行 Taint 操作的節點。taints部分定義了 Taint 的詳細資訊,包括effect(影響)、key(鍵)和value(值)。effect可以是NoSchedule或NoExecute,前者阻止新的 Pod 被排程到節點上,後者除了阻止排程,還會驅逐現有的 Pod。key和value用於標識 Taint 的具體內容。
執行該 Playbook 的命令如下:
$ ansible-playbook -i inventory taint.yml
Drain、Cordon 和 Uncordon Nodes:節點維護操作
Drain:安全驅逐 Pod
Drain 操作用於在維護節點之前安全地驅逐其上的 Pod。它會嘗試刪除節點上的所有 Pod,除了由 ReplicationController、Job 或 DaemonSet 管理的映象 Pod。
Cordon:標記節點為不可排程
Cordon 操作將節點標記為不可排程,防止新的 Pod 被排程到該節點上,但不會影響現有的 Pod。
Uncordon:還原節點的可排程狀態
Uncordon 操作與 Cordon 相反,它將節點還原為可排程狀態,允許新的 Pod 被排程到該節點上。
使用 Ansible Playbook 執行 Drain、Cordon 和 Uncordon 操作
以下是使用 Ansible Playbook 執行這些操作的範例:
- Drain 操作(
drain.yml檔案):
---
- name: k8s drain
hosts: all
vars:
mynode: "k8s.ansiblepilot.com"
grace_period: 600
tasks:
- name: drain node
kubernetes.core.k8s_drain:
state: drain
name: "{{ mynode }}"
delete_options:
terminate_grace_period: "{{ grace_period }}"
內容解密:
state: drain表示要執行 Drain 操作。name: "{{ mynode }}"指定目標節點。delete_options中的terminate_grace_period設定了刪除 Pod 時的優雅終止週期。
- Cordon 操作(
cordon.yml檔案):
---
- name: k8s cordon
hosts: all
vars:
mynode: "k8s.ansiblepilot.com"
tasks:
- name: cordon node
kubernetes.core.k8s_drain:
state: cordon
name: "{{ mynode }}"
內容解密:
state: cordon表示將節點標記為不可排程。
- Uncordon 操作(
uncordon.yml檔案):
---
- name: k8s uncordon
hosts: all
vars:
mynode: "k8s.ansiblepilot.com"
tasks:
- name: uncordon node
kubernetes.core.k8s_drain:
state: uncordon
name: "{{ mynode }}"
內容解密:
state: uncordon表示還原節點的可排程狀態。
執行這些 Playbook 的命令與 Taint 操作類別似,只需替換相應的 Playbook 檔名即可。