如何保護K8S中的Deployment資源物件

語言: CN / TW / HK

對於在共享基礎架構上執行的容器化應用程式,安全性至關重要。隨著越來越多的組織將其容器流量負載轉移到 Kubernetes,K8s 已成為容器編排的首選平臺。隨著這一趨勢的出現,越來越多的威脅和新的攻擊方式層出不窮。

在 Kubernetes 中,安全性有兩個方面:叢集安全性和應用程式安全性。在這篇文章中,我們將探討如何保護Kubernetes Deployment資源型別和應用程式的安全。

基礎知識

在這裡快速回顧一下基礎知識:Pod 是在 叢集中執行一個或多個容器的邏輯原子單元;它由其他資源包裝,例如 ReplicaSet、Deployment、StatefulSets 等。有多種方法可以改善在 Kubernetes 中執行的應用程式的安全狀況。

在 Kubernetes 部署中, 模板 部分包含 pod 規範,這些規範定義了此部署必須執行的工作負載。在下面的模板中,幾個與安全相關的部分以粗體突出顯示:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx
spec:
 selector:
   matchLabels:
     app: nginx
 template:
   metadata:
     labels:
       app: nginx
   spec:
     serviceAccountName: nginx-sa
     securityContext:
       runAsUser: 1000
       runAsGroup: 3000
       fsGroup: 2000
     containers:
     - name: nginx
       image: my-private-registry.io/nginx:1.34
       resources:
         limits:
           memory: "128Mi"
           cpu: "500m"
       ports:
       - containerPort: 80
       securityContext:
         allowPrivilegeEscalation: false
         seccompProfile:
           type: RuntimeDefault
         capabilities:
           add: ["NET_ADMIN", "SYS_TIME"]
         seLinuxOptions:
           level: "s0:c123,c456"

現在讓我們仔細看看 pod 規範中宣告的這些部分。

Service Account

當容器內的程序與 API 伺服器通訊時,您應該使用服務帳戶進行身份驗證。如果您沒有為 pod 定義服務帳戶,則將使用預設帳戶。建議使用執行該功能所需的最低許可權建立一個特定於應用程式的服務帳戶。如果您選擇將角色授予預設服務帳戶,則這些許可權將可用於未在規範中定義服務帳戶的每個 pod。這可能會無意中允許對其他應用程式的過度許可,因此不建議這樣做。在 Kubernetes 1.6 及更高版本中,您可以通過設定來選擇不為容器中的服務帳戶自動掛載 API 令牌。

automountServiceAccountToken: false. 
For example:
apiVersion: v1
kind: ServiceAccount
metadata:
 name: nginx-sa
automountServiceAccountToken: false

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
 name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
 resources: ["pods"]
 verbs: ["get", "watch", "list"]

---

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
 name: read-pods
 namespace: default
subjects:
- kind: ServiceAccount
 name: nginx-sa # "name" is case sensitive
 namespace: default
roleRef:
 kind: Role
 name: pod-reader
 apiGroup: rbac.authorization.k8s.io

安全上下文

安全上下文定義和容器中的許可權和訪問控制設定。以下是一些重要的列表:

  • seLinuxOptions (Security-Enhanced Linux):應用提供更精細訪問和控制策略的機制

  • runAsUser和runAsGroup:特定的UserID或GroupID(UID和GID)執行容器程序的入口點;如果未指定,則預設為使用者在影象元資料中指定的(在 Windows 容器中均無效)。

  • privileged:以特權模式執行容器,預設為 false;與主機上的 root(具有所有功能)相同

  • runAsNonRoot:容器必須以非 root 使用者身份執行(如果 Kubelet 在執行時驗證時 UID 為 0,則容器將無法啟動)。

  • capabilities:在執行容器時新增或刪除能力;容器執行時授予功能,這是預設設定。

  • procMount:指定容器的 proc 掛載型別,預設為 DefaultProcMount;這將容器執行時預設值用於只讀和掩碼路徑。

  • AppArmor:與 SELinux 類似,可以通過配置檔案限制單個程式的功能。

  • seccompProfile:容器使用的 secomp 選項;過濾程序的系統呼叫

  • readOnlyRootFilesystem:將容器中的根檔案系統掛載為只讀;預設為false

  • AllowPrivilegeEscalation:決定一個程序是否可以獲得比其父程序更多的許可權;如果容器以 Privileged 或具有 CAP_SYS_ADMIN 功能執行,則始終為 true。該欄位必須顯式設定為 false,因為它的預設行為可能會在 PSP 中更改。

映象

源映象通常取自各種公共儲存庫;開發人員將他們的應用程式程式碼放在這些基礎映象之上。您還可以直接從流行的公共註冊中心部署 OOTB 應用程式。

關於影象,需要牢記三件事,我們將在下面討論。

映象來源

確保您從受信任的登錄檔中獲取映象。攻擊者可以將惡意圖映象放置在公共登錄檔中,這反過來又會導致資料洩露或攻擊者獲得對叢集的訪問權等問題。許多公共映象也被發現被加密礦工機感染。

作為一個組織,您可以建立基本映象並與開發人員共享它們,然後開發人員可以從他們的內部儲存庫中安全地使用它們。

Distroless 和容器優化映象

這些映象安全且經過優化,可在容器中執行,從而減少了潛在攻擊的表面積。它們僅包含您的應用程式和依賴庫,而 Linux 作業系統上通常可用的包管理器、shell 和程式已被刪除。

持續漏洞掃描

強烈建議實施連續映象掃描,以檢測容器映象中的漏洞、惡意軟體和其他安全威脅(例如,與不受信任的網路的未經授權的連線)。有許多可用的安全解決方案,包括 Kubescape。

Pod 准入控制

您可能聽說過 PodSecurityPolicies,它現在已被棄用,將在 Kubernetes 1.25 中刪除。Pod S安全准入 (PSA) 將取代它,處理安全和其他與安全相關的要求。它為 pod 定義了不同的隔離級別,例如 privileged、  baseline和 restricted。截至 1.23,PSA 目前處於測試階段。

這些級別在 Kubernetes 的 Pod 安全標準中有詳細描述,但下面是 Kubernetes 自己的文件的摘要:

  • Privileged 該政策不受限制,並授予儘可能廣泛的許可權;它允許已知的特權升級。

  • Baseline 此策略具有最低限度的限制,防止已知的特權升級並允許預設(最低限度指定)pod 配置。

  • Restricted 此策略受到極大限制,並以當前的 pod 強化最佳實踐為指導。

Pod Security 准入與內建的 Pod Security 准入控制器配合使用;您需要在叢集中使用 –feature-gates=”...,PodSecurity=true” 或使用 pod admission webhook啟用此功能。它應用於名稱空間級別,帶有以下標籤:

  • Enforce 如果違反政策,該 pod 將被拒絕。

  • Audit 允許違反策略,但它們會觸發對審計日誌中記錄的事件的註釋。

  • Warn 違反政策將提示面向使用者的警告,但仍然允許。在名稱空間中,使用以下註解啟用 Pod 安全准入:

# MODE can be one of enforce, audit or warn
# LEVEL can be one of privileged, baseline or restricted
# VERSION must be valid Kubernetes minor version or latest.
pod-security.kubernetes.io/<MODE>: <LEVEL>
pod-security.kubernetes.io/<MODE>-version: <VERSION>

使用Securit

如果您在應用程式中有可用的敏感資訊(如憑證、令牌、加密金鑰和證書),請使用 Kubernetes Secrets。您可以使用文字值或檔案建立 Secret,然後將它們掛載到 pod 中。不要將此類資訊儲存在容器映像和 Git 儲存庫中。

使用 Secrets 時,最好不要使用環境變數將憑據投影到容器中,而是使用檔案。

請記住,Secrets 是 base64 編碼的值。它們未加密,因此必須限制對安全物件的訪問,並且您應該  在 API 伺服器的寫入時啟用加密。

總結

Kubernetes 提供了多種方法來改善您組織的安全狀況。開發人員需要考慮這些結構以使他們的應用程式更安全。

回顧一下:

  • 每個應用程式使用服務帳戶,並將服務帳戶與最低角色和許可權要求繫結,以實現您的目標。

  • 如果您的應用程式不需要服務帳戶令牌,請不要自動掛載它。

  • 使用安全上下文來實現各種技術,例如防止容器在特權模式下以 root 使用者身份執行,使用 SELinux 或 AppArmor 配置檔案等等。

  • 確保你的容器映象的來源是可信的,如果可能的話,將它們儲存在私有登錄檔中。

  • 嘗試使用優化映象來減少表面積以最大程度地減少威脅。

  • 部署持續的漏洞掃描解決方案,不僅在 CI/CD 中,而且在叢集中,可以實時監控和採取行動。

  • 使用 Pod 安全准入配置檔案和模型為您的工作負載提供不同的隔離級別。

  • 使用 Secrets 儲存敏感資訊,並應用最低許可權 RBAC 來限制使用者/SA 祕密訪問。

  • 對於應用程式開發人員來說,這一切似乎都是壓倒性的。Kubescape等工具  可以幫助進行風險分析、CI/CD 中安全標準的實施、易於理解的 RBAC 視覺化、自動漏洞掃描等等。Kubescape 幫助開發人員實現其應用程式的安全部署。

推薦

如何在雲原生中監控JVM指標

Kubernetes入門培訓(內含PPT)

原創不易,隨手關注或者”在看“,誠摯感謝!