Kubernetes 環境的安全性與資源管理至關重要,本篇探討如何運用 Kubernetes 內建功能與 Ansible 自動化工具強化叢集安全及管理效率。首先介紹 Kustomize 的 YAML 檔案組態與使用方法,接著說明 Pod Security Admission (PSA) 的設定方式與安全標準,並比較 AppArmor 與 SELinux 的差異與應用場景。此外,文章也提供 Seccomp 設定檔範例與 Ansible Dynamic Inventory 的使用技巧,讓讀者瞭解如何動態管理 Kubernetes 資源。最後,文章示範 Ansible Playbook 的撰寫與執行方式,並提供常見問題的解決方案,協助讀者有效運用 Ansible 管理 Kubernetes 叢集。
Kubernetes 安全性與資源管理實務
在 Kubernetes 環境中,安全性與資源管理是至關重要的議題。本章節將探討如何利用 Kubernetes 的內建功能來加強叢集的安全性,並介紹如何使用 Ansible 來自動化佈署和管理 Kubernetes 資源。
使用 Kustomize 管理 Kubernetes 資源
Kustomize 是一種 Kubernetes 組態管理工具,允許使用者自定義和管理 Kubernetes 資源的組態。以下是使用 Kustomize 管理 WordPress 和 MySQL 佈署的範例:
mysql.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: mysql
spec:
containers:
- image: mysql:5.7.41
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
wordpress.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
tier: frontend
type: LoadBalancer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:6.1.1-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wp-pv-claim
Kustomize 的使用
要套用這些資源到 Kubernetes 叢集,可以手動執行以下命令:
$ kubectl apply -k ./
或者,可以使用 Ansible 的 kubernetes.core.kustomize lookup plugin 自動化執行 Kustomization 目錄。
Pod Security Admission (PSA)
Pod Security Admission (PSA) 是 Kubernetes 的一個內建功能,用於在名稱空間層級實施 Pod 安全標準。從 Kubernetes v1.23 版本開始,PSA 已預設啟用。
設定 Pod 安全標準
可以使用以下標籤來設定 Pod 安全標準:
pod-security.kubernetes.io/<MODE>: <LEVEL>
其中,<MODE> 可以是 enforce、audit 或 warn,而 <LEVEL> 可以是 privileged、baseline 或 restricted。
例如,以下命令在 example 名稱空間上啟用 warn Pod 安全標準:
$ kubectl label --overwrite ns example pod-security.kubernetes.io/warn=baseline pod-security.kubernetes.io/warn-version=latest
這樣,每當嘗試檢索 latest 標籤時,就會收到警告訊息,提醒您違反了 Pod 安全標準。
AppArmor
AppArmor 是一種 Linux 安全工具,透過授予存取許可權來控制對系統資源的存取。它與 SELinux 不同,主要差異在於 AppArmor 是根據路徑的安全設定檔,而 SELinux 是根據檔案標籤的安全策略。
AppArmor 與 SELinux 的比較
| 功能 | AppArmor | SELinux |
|---|---|---|
| 存取控制 | 根據路徑的安全設定檔 | 根據檔案標籤的安全策略 |
| Linux 發行版 | 主要用於 SUSE 和 Ubuntu | 主要用於 RHEL/Fedora |
| 控制級別 | 中等 | 高 |
Kubernetes 安全強化:AppArmor 與 Seccomp 應用
Kubernetes 在版本 1.4 之後開始支援 AppArmor,提供了一種限制容器存取資源的方法。AppArmor 是一種 Linux 核心模組,能夠透過定義安全規則來控管容器的行為,包括檔案存取、系統呼叫以及與其他容器或行程的互動。
AppArmor 設定與應用
要使用 AppArmor,首先需要為容器建立一個設定檔,定義容器的存取許可權。這個設定檔將決定容器可以存取哪些檔案和目錄、可以進行哪些系統呼叫,以及可以與哪些其他容器或行程互動。此外,還需要設定容器執行環境,以確保在容器啟動時載入 AppArmor 設定檔。Kubernetes 支援的容器執行環境,如 Docker、CRI-O 和 containerd,都能夠支援 AppArmor。
設定 AppArmor
AppArmor 設定檔是針對每個 Pod 進行設定的,可以透過加入以下註解來指定:
container.apparmor.security.beta.kubernetes.io/<container_name>: <profile_ref>
例如,若要為名為 nginx 的容器套用名為 localhost/nginx-profile 的 AppArmor 設定檔,可以在 Pod 的設定檔中加入以下註解:
metadata:
annotations:
container.apparmor.security.beta.kubernetes.io/nginx: localhost/nginx-profile
佈署與管理
可以使用 kubectl 或 Ansible 的 kubernetes.core.k8s 模組來佈署受 AppArmor 保護的應用程式。不過,Kubernetes 並沒有原生的方法來將 AppArmor 設定檔載入到節點上,但可以透過 Ansible 作為初始化指令碼來實作。
Seccomp:限制系統呼叫
Seccomp(Secure Computing Mode)是 Linux 核心提供的一種安全機制,可以用來限制行程的系統呼叫。透過建立 Seccomp 設定檔,可以定義容器可以進行哪些系統呼叫,以及這些系統呼叫的引數和引數。
設定 Seccomp
要使用 Seccomp,需要在 Kubernetes 設定檔中指定 Seccomp 設定檔的位置。例如:
securityContext:
seccompProfile:
type: localhost
localhostProfile: profiles/audit.json
上述設定指定了使用位於 profiles/audit.json 的 Seccomp 設定檔。
Seccomp 設定檔範例
以下是一個簡單的 Seccomp 設定檔範例,內容如下:
{
"defaultAction": "SCMP_ACT_LOG"
}
這個設定檔將所有系統呼叫記錄到日誌中。
Ansible Dynamic Inventory:動態管理 Kubernetes 資源
Ansible Dynamic Inventory 能夠自動從外部來源(如雲端服務供應商、CMDB 等)產生 Ansible Inventory。這使得使用者能夠動態地佈署基礎架構和應用程式,並且快速地自動化它們。
設定 Ansible Dynamic Inventory
要使用 Ansible Dynamic Inventory,需要在 ansible.cfg 中啟用 kubernetes.core.k8s 外掛:
[inventory]
enable_plugins = kubernetes.core.k8s
然後,可以建立一個名為 inventory.k8s.yml 的檔案,內容如下:
plugin: kubernetes.core.k8s
connections:
- namespaces:
- ansible-examples
這個設定將會列出 ansible-examples 名稱空間中的所有容器。
使用 Ansible Inventory 管理 Kubernetes 資源
可以使用 ansible-inventory 命令來列出或以圖形方式顯示指定名稱空間中的 Pod。例如:
$ ansible-inventory -i inventory.k8s.yml --list
$ ansible-inventory -i inventory.k8s.yml --graph
這些命令將會顯示指定名稱空間中的 Pod 資訊。
Ansible 在 Kubernetes 管理上的應用
Ansible 在 Kubernetes 環境中扮演著自動化管理的關鍵角色,特別是在佈署和管理大規模分散式系統時。透過使用 Ansible 的 Playbook,以 YAML 格式撰寫的簡單易懂的指令碼,可以快速完成諸如節點組態、網路設定和儲存卷設定等任務。
使用 Ansible 執行 Kubernetes 資源管理
在 Kubernetes 環境中,Ansible 可以用來自動化許多手動流程,例如佈署節點、組態網路設定和設定永續性資料儲存卷等。這使得在多節點叢集環境中實作一致性和高效管理成為可能。
簡化 Kubernetes 應用佈署
透過 Ansible 的 Playbook,可以輕鬆地在 Kubernetes 叢集中佈署現代化的雲原生應用。這不僅簡化了佈署流程,也確保了不同基礎設施之間的一致性,無論這些基礎設施是本地佈署還是託管在公有雲上,如 Amazon Web Services (AWS) EC2 例項或其他執行 Linux 發行版的雲端服務提供商。
開發與維運流程
現代雲原生應用的開發和維運流程通常遵循如圖 6-1 所示的工作流程:
- DEV(開發):軟體開發團隊進行開發工作。
- SIT(系統整合測試):軟體開發人員和 QA 工程師進行系統整合測試。
- UAT(使用者驗收測試):選定的客戶進行使用者驗收測試。
- PROD(生產):公開使用者使用的生產環境。
此圖示
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title 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圖表翻譯: 此圖示呈現了現代雲原生應用的典型開發和維運流程,從開發(DEV)階段開始,經過系統整合測試(SIT)、使用者驗收測試(UAT),最終到達生產(PROD)階段。
使用 Ansible Playbook 進行 Kubernetes 資源管理
一個簡單的 Ansible Playbook,例如 ping.yml,可以用來測試 Ansible 控制器與目標節點之間的連線。
---
- name: test
hosts: all
gather_facts: false
tasks:
- name: test connection
ansible.builtin.ping:
內容解密:
- `
表示 YAML 檔案的開始。 2.- name: test定義了 Playbook 的名稱為 "test"。 3.hosts: all指定了該 Playbook 將在所有主機上執行。 4.gather_facts: false表示不收集主機的事實資訊,以加快 Playbook 的執行速度。 5.tasks:定義了要執行的任務列表。 6.- name: test connection是第一個任務的名稱,用於測試連線。 7.ansible.builtin.ping:使用內建的ping` 模組測試與目標主機的連線。
執行此 Playbook 可以使用如下命令:
$ ansible-playbook -i inventory.k8s.yml ping.yml
成功的執行將輸出包括 “Play recap status: ok=1 changed=0” 和任務狀態等資訊。
疑難排解與最佳實踐
在連線到遠端 Pod 時可能會遇到 “Failed to create temporary directory” 的錯誤,這通常是由於許可權問題。解決方案包括調整 ansible.cfg 檔案中的 remote_tmp 路徑到 /tmp 目錄下,以避免許可權問題。
調整 remote_tmp 路徑範例
[defaults]
remote_tmp = /tmp/.ansible-${USER}/tmp
內容解密:
[defaults]指定了 Ansible 組態檔案的預設部分。remote_tmp = /tmp/.ansible-${USER}/tmp定義了遠端臨時目錄的路徑,以避免許可權問題。