在 Kubernetes 環境中佈署應用程式需要考量多方面的安全性,包含建構、佈署和執行階段。建構階段著重於確保映像安全和主機作業系統強化,例如使用最小化基礎映像、掃描映像漏洞以及限制應用程式許可權。佈署階段則關注 Kubernetes 叢集的安全組態,例如 RBAC、網路策略和 Pod 安全策略等。執行階段則需要持續監控網路流量、實施威脅防禦機制,並確保符合企業安全規範。
在 Kubernetes 中佈署工作負載:每個階段的安全性
在前一節中,我們描述了使用 CI/CD 管道佈署應用程式時所面臨的安全挑戰。本文將描述 Kubernetes 叢集中工作負載佈署的生命週期,並闡述如何確保每個階段的安全性。工作負載佈署的三個階段分別是建構、佈署和執行階段。與傳統的客戶端-伺服器應用程式不同,Kubernetes 佈署中的應用程式是分散式的,Kubernetes 叢集網路被應用程式用作正常運作的一部分。
需要考慮的事項
由於這種組態,您需要考慮以下事項:
- 在建構工作負載和基礎設施時,需要考慮安全最佳實踐。
- 在佈署 Kubernetes 叢集和上線應用程式時,需要考慮安全最佳實踐。
- 最後,應用程式在正常運作時使用基礎設施和 Kubernetes 叢集網路,因此需要考慮應用程式執行時的安全最佳實踐。
圖示說明
圖 1-1 說明瞭在 Kubernetes 環境中保護工作負載時需要考慮的各個階段和方面。
圖 1-1. 工作負載佈署階段和每個階段的安全性
每個階段下方的方框描述了該階段需要考慮的各種安全方面:
- 建構階段:在此階段,您需要建立(建構)工作負載(應用程式)的軟體,並建構基礎設施元件(主機或虛擬機器)以託管應用程式。這是開發週期的一部分,大多數情況下由開發團隊負責。在此階段,您需要考慮 CI/CD 管道的安全性、實施映像儲存函式庫的安全措施、掃描映像以查詢漏洞,並強化主機作業系統。
- 您需要確保實施最佳實踐來保護映像登入檔,避免映像被洩露。
- 這通常透過保護對映像登入檔的存取來實作,雖然許多使用者擁有私人登入檔,不允許來自公共登入檔的映像。
- 您需要考慮秘密管理的最佳實踐;秘密就像密碼一樣,允許存取叢集中的資源。
佈署階段
在佈署階段,您需要設定執行 Kubernetes 佈署的平台,並佈署工作負載。在此階段,您需要考慮組態 Kubernetes 叢集的安全最佳實踐,並為在 Kubernetes 叢集中執行的應用程式提供外部存取。
- 您需要考慮安全控制措施,例如限制對工作負載(Pod 安全策略)的存取、控制應用程式對平台元件的存取的網路策略,以及根據角色的存取控制(RBAC)以存取資源。
執行階段
在執行階段,您的應用程式已經佈署並正在運作。在此階段,您需要考慮網路安全,包括使用網路策略進行控制、威脅防禦(使用技術檢測和防止叢集中的惡意活動),以及企業安全控制措施,如合規性、稽核和加密。
建構階段安全性:向左移動
本文將指導您瞭解建構階段安全性的各個方面,並提供範例。
映像掃描
在此階段,您需要確保應用程式沒有任何重大的未修補問題,這些問題在國家漏洞資料函式庫中被披露為常見漏洞和風險(CVE),並且應用程式碼和依賴項被掃描以查詢漏洞和脆弱的程式碼段。
- 使用的工具包括 Whitesource、Snyk、Trivy、Anchor 等,甚至雲端供應商如 Google 也提供容器映像掃描。
主機作業系統強化
您需要確保被佈署的應用程式在主機上被限制為僅具有必要的許可權。
- 這可以透過使用強化主機作業系統來實作,該作業系統支援控制措施,以限制應用程式僅具有必要的許可權,如系統呼叫和檔案系統存取。
程式碼範例與詳細說明
以下是一個簡單的 Dockerfile 範例,用於建構一個安全的容器映像:
# 使用官方的 Python 映像作為基礎映像
FROM python:3.9-slim
# 設定工作目錄
WORKDIR /app
# 複製 requirements.txt 檔案到工作目錄
COPY requirements.txt .
# 安裝 Python 依賴項
RUN pip install --no-cache-dir -r requirements.txt
# 複製應用程式碼到工作目錄
COPY . .
# 暴露應用程式的連線埠
EXPOSE 8000
# 使用非 root 使用者執行應用程式
RUN useradd -ms /bin/bash appuser
USER appuser
# 執行應用程式
CMD ["python", "app.py"]
內容解密:
- 使用官方 Python 映像:這減少了維護自定義基礎映像的工作量,並利用了官方映像的安全更新。
- 設定工作目錄:明確工作目錄可以避免在容器中執行命令時出現路徑混淆。
- 安裝依賴項:透過在單獨的步驟中複製
requirements.txt並安裝依賴項,可以利用 Docker 的快取機制,避免每次建構都重新安裝依賴項。 - 使用非 root 使用者執行應用程式:這減少了應用程式被攻陷時對容器和主機的風險。
- 暴露連線埠和執行應用程式:明確宣告應用程式使用的連線埠,並設定預設的執行命令,便於容器管理和使用。
這個 Dockerfile 範例展示瞭如何透過選擇合適的基礎映像、管理依賴項和使用非 root 使用者執行應用程式來提高容器映像的安全性。
Kubernetes 工作負載佈署的安全策略:建構、佈署與執行時安全
在 Kubernetes 環境中佈署工作負載時,安全性是至關重要的考量因素。為了確保工作負載的安全,需要在建構、佈署和執行時三個階段實施全面的安全策略。
建構時安全:最小化攻擊面
為了提高安全性,建議檢視容器映像的組成,並最小化基礎映像中的軟體套件,只包含應用程式執行所必需的套件。在根據 Dockerfile 的容器映像中,可以從父映像開始,然後將應用程式新增至映像中以建立容器映像。例如,可以使用 FROM scratch 指令建立最小的映像,然後新增應用程式和所需的套件。這樣可以完全控制容器映像的組成,並且有助於 CVE 管理。
程式碼範例:建立最小的 Docker 映像
FROM scratch
COPY myapp /
CMD ["./myapp"]
內容解密:
FROM scratch:使用scratch作為基礎映像,建立一個最小的 Linux 映像。COPY myapp /:將本地的myapp檔案複製到映像中的根目錄。CMD ["./myapp"]:設定容器啟動時執行的預設命令。
除了使用 scratch 映像外,也可以考慮使用 distroless 映像或 Alpine 最小映像作為基礎映像。這些技術將有助於設計和實施建構時安全策略。
佈署時安全:強化 Kubernetes 叢集
佈署時安全的重點是強化 Kubernetes 叢集的組態。首先,需要建立信任模型,以定義叢集中各元件之間的信任關係。可以使用角色型存取控制(RBAC)、標籤分類別、標籤治理和准入控制等機制來設計和實施信任模型。
Kubernetes 叢集信任模型
@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
此圖示說明瞭 Kubernetes 叢集信任模型的組成要素,包括 RBAC、標籤分類別、標籤治理和准入控制等機制。
此外,還需要關注 Kubernetes 資料儲存和 API 伺服器的安全,使用強大的憑證、公開金鑰基礎設施(PKI)和傳輸層安全性(TLS)來保護資料。
執行時安全:保護 Kubernetes 叢集網路
執行時安全的重點是保護 Kubernetes 叢集網路的安全。Kubernetes 是一個跨主機網路的工作負載和應用程式協調器,需要考慮網路安全作為執行時安全的重要導向。
網路安全最佳實踐
- 使用網路政策來控制 Pod 之間的流量。
- 使用加密技術來保護資料在傳輸中的安全。
- 監控網路流量,以偵測和回應潛在的安全威脅。
Kubernetes 安全與可觀測性策略
Kubernetes 網路安全挑戰
Kubernetes 的網路模型與傳統企業網路有著根本性的差異。在 Kubernetes 中,Pod 的 IP 位址是動態且短暫的,當 Pod 被重新排程到其他節點時,通常會獲得不同的 IP 位址。這使得傳統根據 IP 位址或網路拓撲的安全裝置(如防火牆和路由器)難以提供有效的工作負載感知網路安全。
傳統網路安全方法主要依賴於實體拓撲和 IP 位址範圍的劃分,但在 Kubernetes 平坦的網路架構下,這些方法顯得力不從心。特別是在同一節點上的 Pod 之間的東西向流量,甚至不會經過底層網路,使得傳統安全裝置無法監控這些流量。
Kubernetes 網路安全的新需求
面對這些挑戰,Kubernetes 需要新的網路安全方法。這包括:
- 新的網路安全執行方式,不依賴於 IP 位址或網路拓撲,能夠處理不經過底層網路的流量。Kubernetes 網路策略正是為滿足這些需求而設計的。
- 新的工具來幫助管理網路策略,支援新的開發流程和微服務架構,提高組織的敏捷性。
- 新的方法來監控和視覺化網路流量,包括叢集範圍的全貌檢視和針對特定微服務的檢視,以幫助故障排除或診斷應用程式問題。
- 新的入侵偵測和威脅防禦實作方式,包括策略違規警示、網路異常偵測和整合威脅情報。
- 新的修復工作流程,以便在取證調查期間快速安全地隔離可能受損的工作負載。
- 新的機制來稽核組態和策略變更,以滿足合規要求。
企業級 Kubernetes 佈署例項
圖 1-2 展示了一個典型的企業級 Kubernetes 佈署案例,在混合雲環境中佈署 Kubernetes。企業通常會在多個雲端服務提供商(如 AWS、Azure、Google Cloud)上佈署 Kubernetes 叢集,並可能在自己的資料中心內佈署 Kubernetes。此外,微服務通常依賴於其他雲端服務、第三方 API 端點、SaaS 服務,以及資料中心內的資料函式庫或舊式應用程式。
可觀測性在 Kubernetes 中的重要性
Kubernetes 中的可觀測性是指從收集的指標中取得有關 Kubernetes 狀態的可行洞察力。可觀測性概念與其他 Kubernetes 中繼資料(Pod 標籤、策略、名稱空間等)相關聯,用於監控和保護 Kubernetes 叢集內 Pod 之間的通訊,檢測惡意活動,並使用根據機器學習的技術檢測惡意活動。
Kubernetes 中的工作負載佈署安全
如圖 1-2 所示,微服務應用的足跡通常超出了虛擬私有雲(VPC)的邊界,保護這些應用需要不同於傳統週邊安全的方法。這需要結合網路安全控制、可觀測性、威脅防禦和企業安全控制等多種措施。
網路安全控制
雲端服務提供商提供的原生安全控制(如 AWS Security Groups 或 Azure Network Security Groups)或 VPC 或資料中心週邊的安全閘道(如下一代防火牆),無法理解 Kubernetes 叢集內微服務的身分。例如,您無法使用安全組規則或防火牆策略過濾到或來自 Kubernetes Pod 或服務的流量。此外,當來自 Pod 的流量到達雲端服務提供商的網路或第三方防火牆時,流量已經經過了源網路位址轉換(SNAT),使得原始 IP 位址被修改。
程式碼示例:Kubernetes 網路策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-network-policy
spec:
podSelector:
matchLabels:
app: example-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: allowed-app
- ports:
- 80
egress:
- to:
- podSelector:
matchLabels:
app: external-service
- ports:
- 443
內容解密:
此網路策略範例定義了一個名為 example-network-policy 的網路策略,適用於標籤 app: example-app 的 Pod。此策略允許來自標籤 app: allowed-app 的 Pod 對其進行存取,且僅允許透過 80 連線埠。同時,它允許此 Pod 存取標籤 app: external-service 的 Pod,透過 443 連線埠。
此範例體現了 Kubernetes 網路策略如何實作細粒度的流量控制,與傳統的安全組或防火牆規則不同,它根據 Kubernetes 的原生概念(如 Pod 標籤)進行策略定義。
Kubernetes 安全架構與網路政策的重要性
在多雲或混合雲環境中,Kubernetes 工作負載的安全性面臨著巨大的挑戰。由於 Kubernetes 的高度動態性和短暫性,傳統的網路安全控制方法難以跟上工作負載的快速變化。因此,需要一種新的安全架構來確保 Kubernetes 工作負載的安全。
網路政策與細粒度存取控制
Kubernetes 提供了原生網路政策解決方案,可以實作細粒度的存取控制。有多種網路政策實作方案可供選擇,如 Calico、Weave Net、Kube-router 和 Antrea。除了在第三層/第四層(TCP/IP)實施政策外,還建議選擇支援應用層政策(如 HTTP/HTTPS)的解決方案。同時,建議選擇根據 Envoy 代理的解決方案,因為它在應用層政策方面被廣泛佈署。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-network-policy
spec:
podSelector:
matchLabels:
app: example-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: allowed-app
- ports:
- 80
egress:
- to:
- podSelector:
matchLabels:
app: external-service
- ports:
- 443
內容解密:
此網路政策範例定義了一個名為 example-network-policy 的網路政策。它允許來自標籤為 app: allowed-app 的 Pod 的流量進入標籤為 app: example-app 的 Pod 的 80 連線埠。同時,它允許標籤為 app: example-app 的 Pod 向標籤為 app: external-service 的 Pod 的 443 連線埠傳送流量。
企業級安全控制
除了網路存取控制和可觀察性外,還需要考慮企業級的其他安全控制措施。傳輸中的資料加密是安全和合規性的關鍵要求。可以考慮使用 TLS-based 加密、相互 TLS 或根據 VPN 的方法(如 Wireguard)來實作加密。
合規性和持續合規
應該利用可觀察性策略中的資料收集功能來建立所需的報告,以幫助滿足 PCI、HIPAA、GDPR 和 SOC 2 等標準的合規要求。同時,還應該考慮確保持續合規的能力。可以利用 Kubernetes 的宣告式特性來設計和實施持續合規。例如,可以使用 Pod 的合規狀態來觸發必要的操作來糾正情況(觸發映像更新)。
處理威脅防禦
Kubernetes 叢集中的威脅防禦是指檢測和防禦叢集中的惡意活動。惡意活動可能以多種形式出現,例如利用不安全的組態或利用應用程式流量或應用程式碼中的漏洞。在建立威脅防禦策略時,必須同時考慮入侵檢測和預防。
入侵檢測
入侵檢測的關鍵是可觀察性;需要檢視收集的資料以掃描已知威脅。在 Kubernetes 環境中,由於需要檢查的資料量龐大,資料收集非常具有挑戰性。建議將可觀察性策略與入侵檢測相結合,並利用智慧匯總來收集和檢查資料。
kubectl logs -f <pod-name>
內容解密:
此命令用於檢視指定 Pod 的日誌輸出。-f 選項表示跟隨日誌輸出,即持續輸出最新的日誌內容。
Kubernetes 安全與可觀測性策略
在 Kubernetes 環境中,安全與可觀測性是確保系統穩健運作的關鍵要素。為了有效監控和保護分散式系統,需要採取多層面的安全措施和可觀測性策略。
威脅防禦技術
威脅防禦技術不斷演進,組織需要與安全研究團隊合作,深入瞭解應用程式並建立威脅模型,以實施有效的威脅防禦策略。簡單來說,可以從以下幾點著手:
- 蒐集來自知名威脅情報源的 IP 地址和網域
- 記錄未經匯總的網路流量,以監控被策略拒絕的流量
這些基礎技術有助於建立健全的安全策略。
可觀測性
Kubernetes 抽象化了許多細節,使得監控系統變得複雜。可觀測性提供了一種方法,可以在 Kubernetes 的上下文中監控指標,例如:
- 與服務相關聯的 Pod 重啟並執行不同的二進位制檔案
- Pod 活動(網路、檔案系統、核心系統呼叫)與其他 Pod 不同
可觀測性在 Kubernetes 中的工作負載安全監控和故障排除非常有用。例如,它可以:
- 將 Kubernetes 叢集視覺化為服務圖,顯示 Pod 如何與服務相關聯以及服務之間的通訊流程
- 在服務圖上疊加應用層(第 7 層)和網路流量(第 3/4 層),以便輕鬆確定應用程式和底層網路的流量模式和負載
- 檢視與 Pod 運作相關的指標,例如流量負載、應用延遲、網路延遲或 Pod 運作(例如 RBAC 策略、服務帳戶或容器重啟)
- 檢視特定服務的 DNS 活動(DNS 回應碼、延遲、負載)
- 跟蹤需要跨多個服務通訊的使用者交易,也稱為分散式追蹤
- 檢視特定服務與外部實體的網路通訊
- 檢視與特定服務相關聯的 Kubernetes 活動日誌(例如稽核日誌)
網路流量可視性
具備在服務層級匯總的網路流量資訊,且包含名稱空間、標籤、服務帳戶或網路策略等上下文的解決方案,對於充分監控叢集活動和存取控制至關重要。例如,報告「標籤為“frontend”的 Pod 與標籤為“backend”的 Pod 在特定埠上通訊」比僅報告「IP1 與 IP2 在埠 8080 上通訊」更有意義。這種報告方式使您能夠檢視來自外部實體的通訊,並應用根據 IP 地址的威脅情報,以偵測來自已知惡意 IP 地址或意外地理位置的活動。
DNS 活動日誌
DNS(網域名稱系統)用於將網域名稱轉換為 IP 地址。在 Kubernetes 叢集中,檢視 DNS 活動日誌以偵測意外活動至關重要,例如查詢已知惡意網域、DNS 回應碼(如 NXDOMAIN),以及 DNS 查詢中的位元組和封包意外增加。
應用程式流量可視性
建議檢視應用程式流量中的可疑活動,例如意外回應碼和罕見或已知惡意的 HTTP 標頭(User-Agent、查詢引數)。由於 HTTP 是 Kubernetes 佈署中最常用的協定,因此與安全研究團隊合作監控 HTTP 流量以偵測惡意流量至關重要。如果使用其他應用程式協定(如 Kafka、MySQL),也需要進行相同的監控。
Kubernetes 活動日誌
除了網路活動日誌外,還必須監控 Kubernetes 活動日誌以偵測惡意活動。例如,檢視資源存取被拒絕的日誌、服務帳戶建立/修改日誌,以及名稱空間建立/修改日誌。同時,也需要檢視記錄對 Kubernetes API 請求的稽核日誌。