Kubernetes 的 GitOps 實踐與叢集安全是密不可分的兩個議題。透過 GitOps,可以將 Kubernetes 的組態和應用程式碼儲存在 Git 倉函式庫中,並使用自動化工具將這些變更佈署到叢集。這不僅簡化了佈署流程,也提高了安全性,因為所有變更都可追蹤和審核。本文首先介紹如何使用 Flux 工具引導 GitOps 流程,包含建立 Git 倉函式庫、組態 Flux 元件,以及佈署應用程式。接著,文章探討 Kubernetes 叢集安全的重要性和實踐,涵蓋多層次防禦策略、叢集安全設定、程式碼安全最佳實踐等。最後,文章討論了安全工具的應用和最佳實踐建議,以確保 Kubernetes 叢集和應用程式的安全。
使用 Flux 實作 GitOps
檢查並安裝 Flux
首先,檢查您的叢集是否能夠安裝 Flux:
flux check --pre
引導 Flux
接下來,使用以下命令引導 Flux:
flux bootstrap github \
--owner=$GITHUB_USER \
--repository=kbp-flux \
--branch=main \
--path=./clusters/prod \
--personal
上述命令將在您的 GitHub 帳戶中建立一個名為 kbp-flux 的 Git 倉函式庫,並建立一個 main 分支和一個 clusters/prod 目錄。clusters/prod 目錄將包含將被佈署到叢集的 Flux 元件。
內容解密:
--owner=$GITHUB_USER指定 GitHub 使用者名稱。--repository=kbp-flux指定要建立的倉函式庫名稱。--branch=main指定要使用的分支。--path=./clusters/prod指定 Flux 元件的儲存路徑。--personal表示這是一個個人倉函式庫。
驗證 Flux 安裝
檢查 flux-system 名稱空間以確認 Flux 元件是否已佈署:
kubectl get pods -n flux-system
您應該會看到類別似以下的輸出:
NAME READY STATUS RESTARTS AGE
helm-controller-8664d9dcfc-4gd2h 1/1 Running 0 6m30s
kustomize-controller-9888f965-ld5g6 1/1 Running 0 6m30s
notification-controller-b6d8458c7-vjb86 1/1 Running 0 6m30s
source-controller-5b68b64c65-pj2tn 1/1 Running 0 6m30s
內容解密:
kubectl get pods -n flux-system命令用於取得flux-system名稱空間中的 Pod 狀態。- 輸出顯示了各個 Flux 控制器的執行狀態。
複製倉函式庫並組態 Flux
將剛才建立的倉函式庫複製到本地機器:
git clone https://github.com/$GITHUB_USER/kbp-flux
接下來,在倉函式庫中新增一個 Flux 組態,並使用一個公開的 GitHub 倉函式庫。我們將使用由 Weaveworks 的 Stefan Prodan 建立的一個示例應用程式。
首先,建立一個指向 apps 倉函式庫 main 分支的 Git 倉函式庫清單:
flux create source git podinfo \
--url=https://github.com/stefanprodan/podinfo \
--branch=master \
--interval=30s \
--export > ./clusters/prod/podinfo-source.yaml
然後,組態 Flux 以佈署應用程式並套用 Kustomize 組態:
flux create kustomization podinfo \
--target-namespace=default \
--source=podinfo \
--path="./kustomize" \
--prune=true \
--interval=5m \
--export > ./clusters/prod/podinfo-kustomization.yaml
內容解密:
flux create source git podinfo命令用於建立一個 Git 源,指向podinfo倉函式庫。--url=https://github.com/stefanprodan/podinfo指定了podinfo倉函式庫的 URL。--branch=master指定了要使用的分支。flux create kustomization podinfo命令用於建立一個 Kustomization 物件,以佈署podinfo應用程式。--target-namespace=default指定了佈署目標的名稱空間。
提交變更並驗證
將變更提交到倉函式庫:
git add -A && git commit -m "Add podinfo Kustomization"
git push
使用 Flux CLI 檢視變更是否已套用:
flux get kustomizations --watch
您應該會看到類別似以下的輸出:
NAME REVISION SUSPENDED READY MESSAGE
flux-system main@sha1:9c3fb6f1 False True Applied revision: main@sh...
podinfo master@sha1:1abc44f0 False True Applied revision: master@...
內容解密:
flux get kustomizations --watch命令用於監視 Kustomization 的狀態。- 輸出顯示了各個 Kustomization 的修訂版本和狀態。
GitOps 工具
許多不同的工具可以用於在叢集中實施 GitOps。以下是一些最流行的工具:
Flux
Flux 是一個 Kubernetes 操作器,能夠監控您的 Git 倉函式庫並自動將變更套用到叢集。
ArgoCD
Argo CD 是一個開源的 GitOps 連續交付工具,能夠監控叢集和 Git 倉函式庫,並解決兩者之間的差異。
Codefresh
Codefresh 是一個 CI/CD 平台,能夠用於在叢集中實施 GitOps,並提供 ArgoCD 作為服務。
Harness
Harness 是一個 CI/CD 平台,能夠用於在叢集中實施 GitOps,並提供完整的連續交付功能。
GitOps 最佳實踐
在使用 GitOps 管理 Kubernetes 叢集時,請考慮以下最佳實踐:
- 從小規模應用程式開始,然後逐步擴充套件到管理所有資源。
- 評估符合您需求的工具,或從成熟的開源工具如 Flux 或 ArgoCD 開始。
- 避免使用分支來管理倉函式庫結構,因為這是最複雜且容易出錯的方式。
- 從每個環境一個資料夾開始,這樣可以提供靈活性並允許使用 Kustomize 或 Helm 等工具進行範本化。
- 使用 Sealed Secrets 或外部金鑰提供者來管理叢集中的金鑰。
Kubernetes 安全性的重要性與實踐
Kubernetes 是一個強大的容器協調平台,但其背後卻是一個複雜的分散式系統,需要特定的知識來確保其安全性。未正確組態 Kubernetes 的安全性,可能會使資料和資源暴露於駭客、惡意軟體和未經授權的存取之下。本章將概述 Kubernetes 安全性的關鍵層面,並提供最佳實踐建議。
多層次防禦策略
確保 Kubernetes 安全性的有效方法是採用「多層次防禦」策略。這需要在每個層級上使用多種安全措施,以保護 Kubernetes 和工作負載。此外,還應遵循「最小許可權原則」,即使用者和工作負載僅能存取執行其功能所絕對必要的資源。
叢集安全性
確保叢集安全性的第一步是規範和限制誰可以存取叢集以及可以執行哪些操作。以下是幾個關鍵的安全層面:
etcd 存取控制
Kubernetes 的預設儲存系統是 etcd。必須確保只有 Kubernetes API 伺服器能夠存取 etcd,並使用強大的憑證且不分享。同時,也要確保只有 API 伺服器具有對 etcd 的網路存取許可權,使用網路防火牆進行隔離。
身份驗證
Kubernetes 提供了多種身份驗證方法,包括 bearer tokens、憑證、OpenID Connect(OIDC)和輕量級目錄存取協定(LDAP)整合。選擇適合業務需求的身份驗證模型至關重要。使用身份驗證提供者可以檢索臨時動態令牌,而不是使用容易被惡意行為者檢索的靜態令牌或憑證。
授權管理
授權是強制執行使用者對資源的操作許可權的重要工具。主要工具是根據角色的存取控制(RBAC)。Kubernetes 預設提供了合理的設定,但仍需要考慮將團隊成員資格和名稱空間等屬性納入 RBAC 資源的擴充套件中,以支援日益增長的工作負載和使用者數量。
TLS 組態
Kubernetes 預設啟用了 TLS 安全的 API 端點。然而,不同的工具和平台可能會啟用 HTTP 明文通訊,這會使流量不安全。安全地儲存和控制對憑證和金鑰的存取許可權,並制定在憑證遺失或洩露時的輪換計劃,對於降低安全風險至關重要。
Kubelet 和雲端後設資料存取控制
Kubelet 是執行在每個節點上的元件,負責管理節點和在其上執行的 Pod。預設情況下,Kubelet 啟用了未經身份驗證的 API,因此需要啟用身份驗證和授權。如果在雲端提供者上執行,還需要鎖定對雲端後設資料 API 的存取,以防止 Kubernetes 組態憑證的洩露。
秘密管理
Kubernetes 的 Secret 預設未加密,這意味著惡意行為者可能能夠從其他管道讀取這些 Secret。有幾種解決方案可以幫助解決這個問題,包括使用加密提供者和 CSI Secret Store。
日誌記錄與稽核
Kubernetes 提供了豐富的日誌功能。此外,啟用 API 伺服器的稽核日誌功能,可以記錄所有與安全相關的事件,並可透過稽核策略進行組態。啟用稽核日誌後,還需要將稽核日誌傳送到匯總點,並組態觸發器,以便在檢測到可疑事件時向安全團隊發出警示。
程式碼安全性最佳實踐
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
containers:
- name: secure-container
image: secure-image
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
內容解密:
apiVersion和kind定義了 Kubernetes 資源的版本和型別,在此範例中為 Pod。metadata部分定義了 Pod 的中繼資料,如名稱。spec部分定義了 Pod 的詳細規格,包括容器列表。securityContext定義了容器的安全設定,例如以非 root 使用者身份執行,並指定了使用者和群組 ID,以提高容器的安全性。
Kubernetes 安全性的實踐與工具
Kubernetes 的安全性實作可能相當具有挑戰性,但幸運的是,有許多開源工具可以掃描 Kubernetes 叢集、檢測安全風險,並標記常見的錯誤組態。此外,這些工具還可以掃描叢集中的所有資源,並提供最佳實踐建議。像 Kubescape 這樣的工具執行速度快,並根據嚴重程度提供輸出結果。建議定期在所有叢集上執行這些工具,以評估叢集及其佈署資源的安全狀況。
叢集安全最佳實踐
在介紹了叢集層面的主要安全領域後,以下是一些方便您核對的安全最佳實踐:
- 鎖定 etcd 存取許可權,並將存取憑證和證書儲存在安全的位置。
- 停用不安全且未經身份驗證的 API 端點。
- 使用提供臨時動態令牌的身份驗證提供者,而不是在 Kubeconfig 中組態靜態令牌。
- 確保使用者和服務遵循最小許可權原則。
- 定期輪換基礎設施憑證。
- 使用金鑰和證書加密靜止和傳輸中的敏感資料。
- 在將容器映像佈署到叢集之前掃描其漏洞和惡意軟體。
- 啟用稽核日誌和監控,以檢測和回應可疑活動。
- 使用 Kubescape 等安全掃描工具來基準測試 Kubernetes 叢集和工作負載的安全狀況。
工作負載容器安全
在介紹了叢集安全性的核心元件後,我們將探討工作負載層面的安全機制。Kubernetes 提供了許多以安全性為重點的 API,使得透過相同的工具進行組態變得簡單。
Pod Security Admission
Pod Security Admission 是您工作負載安全性故事中的關鍵部分,它允許您組態和管理 Pod 組態中的所有安全性敏感元件,並在名稱空間或叢集層級套用開箱即用的最佳實踐。第 10 章專門介紹了容器和 Pod 安全性,強烈建議您檢視該章以瞭解更多細節。
Seccomp、AppArmor 和 SELinux
Linux 提供了多種不同的安全機制,可以與 Kubernetes 結合使用,以提高在 Kubernetes 上執行的工作負載的安全性。Seccomp 允許建立系統呼叫過濾設定檔,用於限制來自容器的系統呼叫。可惜的是,Seccomp 設定檔在 Kubernetes 社群中沒有被足夠討論,而且經常未被組態或組態錯誤,從而允許容器存取可能被用於惡意目地的系統呼叫。Kubernetes 社群建立了一個很好的工具,稱為 Security Profile Operator,它簡化了 Seccomp 設定檔組態的管理開銷。從安全形度來看,Seccomp 是容易組態的,因此強烈建議至少啟用預設的 Seccomp 設定檔。
AppArmor 和 SELinux 是 Linux 核心安全模組,允許對每個容器進行強制存取控制的細粒度組態。這使得叢集管理員能夠對容器可以執行的操作進行細粒度控制。結合使用 Pod Security Admission 和這些 Linux 安全機制,您可以控制容器對作業系統的存取層級。
Admission Controllers
Admission Controllers 是保護工作負載安全的關鍵元件。Kubernetes 內建了一組 Admission Controllers,所有與安全性相關的 Admission Controllers 都預設啟用。例如,NodeRestriction Admission Controller 限制了 Kubelet 的許可權,使其只能修改分配給該特定節點的 Pod。Admission Controllers 是一個很大的話題,建議您檢視第 17 章以瞭解更多細節。
Operators
Operators 是使用 Kubernetes API 提供自定義資源的控制器,以支援需要應用程式特定知識的特定工作負載。如果您想了解更多關於 Operator 模式的資訊,請參閱第 21 章,其中詳細介紹瞭如何實作 Operator。在安全性方面,不幸的是,許多 Operators 都附帶非常寬鬆的 RBAC 組態,以方便使用。許多 Operators 授予 cluster-admin 或等效的許可權,這可能成為攻擊向量。此外,儘管較少見,但這些 Operators 可能會直接暴露其他 API,這可能會提供提權的途徑。
網路策略
Kubernetes 附帶了一個網路策略資源;但是,您需要仔細檢查您的網路提供者是否在執行時實作了該資源。有關網路安全的更多細節,請參閱第 9 章。Kubernetes 網路策略提供了對允許進入或離開服務或名稱空間的網路流量的細粒度控制,無論是內部還是外部資源。網路策略還允許叢集管理員建立叢集範圍或名稱空間特定的策略,並將應用程式特定的網路策略委派給應用程式開發人員。網路策略僅涵蓋 IP 位址和 TCP/UDP 連線埠,而不涵蓋特定的 HTTP 流量或端點路由存取控制。如果您需要應用程式特定的存取策略,服務網格包括更高層級的存取策略,這些策略不是 Kubernetes 整合 API 的一部分。
Runtime Security
大多數 Kubernetes 叢集預設使用 containerd 或 CRI-O 等容器執行時,它們利用 Linux cgroups 提供輕量級的沙箱供容器執行時使用。對於某些安全性敏感的工作負載,這些安全保證可能不夠。有一個不同的容器執行時生態系統,包括 Kata containers 和 gvisor,它們提供了不同的安全設定檔,以滿足工作負載的需求。Kubernetes 支援在同一叢集中使用多個容器執行時,使用 Pod 設定檔中的 RuntimeClass 欄位。有關 RuntimeClass 的更多細節,請參閱第 10 章。如果您仍然需要更高層級的安全性,那麼 Confidential Containers 也值得考慮。Confidential Containers 利用可信執行環境,這是 CPU 上執行工作負載的安全區域。
與 Kubernetes 控制平面上的稽核日誌一樣,您也應該投資於容器執行時的稽核日誌記錄。像 Falco 這樣的工具提供了一種方法,可以在容器執行時內啟用稽核日誌記錄和策略,從而監控和捕捉惡意行為。
工作負載容器安全最佳實踐
Kubernetes 提供了一套豐富的安全工具供您使用,這可能會讓人感到不知所措。以下是您可以專注的最佳實踐簡要清單,以快速改善在叢集上執行的負載的安全性:
程式碼範例:使用 Kubescape 掃描叢集
kubescape scan --verbose
內容解密:
此命令會使用 Kubescape 掃描叢集,並輸出詳細的掃描結果。Kubescape 可以幫助檢測叢集中的安全風險和錯誤組態。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-traffic
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress: []
egress: []
內容解密:
此網路策略定義了一個名為 deny-all-traffic 的網路策略,它會拒絕所有進入和流出的流量。此策略可以幫助提高叢集的安全性。