Kubernetes 的安全是一個至關普遍的主題,涉及不少高度相關的內容。和探討大部分安全性相關的問題同樣,首先須要考慮威脅模型——誰可能攻擊你的系統,以及他們如何作到這一點。這能夠幫你肯定安全工做的優先級。對於大多數 Kubernetes 應用有三類主要的攻擊者:php
圍繞雲原生基礎概念構建的模型能夠幫你創建對 Kubernetes 安全的整體認識。下圖將安全劃分爲四個層級,被稱爲雲原生安全的4C模型。管理員將在不一樣的層次上應對三類攻擊者。node
4C 指的是雲(Cloud)、集羣(Cluster),容器(Containers)和代碼(Code)
正如你在圖中所看見的,4C 模型中每部分的安全性都是相互包含的。只依靠加強代碼層次安全來預防雲、集羣和容器中安全漏洞是幾乎不可能的。適當提升其餘層的安全能力,就已經爲你的代碼提供強大的基礎安全保障。下面將詳細介紹這四部份內容。nginx
大多數狀況下,云爲 Kubernetes 集羣提供可信的計算資源。若是雲的基礎設置是不可靠的(或以易受到攻擊的方式配置),那就沒有辦法保證在這個基礎上構建的 Kubernetes 集羣的安全性。每個雲服務提供商都向他們的客戶提供大量如何在其環境安全運行負載的建議。下面提供經常使用雲服務廠商的安全文檔連接,而且提供了構建安全 Kubernetes 集羣的建議。程序員
雲服務廠商 | 連接 |
---|---|
阿里雲 | https://www.alibabacloud.com/... |
AWS | https://aws.amazon.com/security/ |
Google Cloud Platform | https://cloud.google.com/secu... |
Microsoft Azure | https://docs.microsoft.com/en... |
若是你運行在本身的硬件上或者其餘雲服務提供商,請查閱文檔獲取最佳安全實踐。docker
Kubernetes 是一個複雜的系統,下圖展現了一個集羣不一樣的組成部分,爲了保證集羣總體的安全,須要仔細保護每個組件。shell
將須要注意保護的集羣組件劃分紅兩個部分:數據庫
使用 TLS 進行安全通信。Kubernetes 指望默認狀況下使用 TLS 對集羣中全部 API 通訊進行加密,大多數安裝方式都會建立必要的證書並分發給集羣組件。後端
API 認證。在安裝集羣時,爲API服務器選擇與通用訪問模式匹配的身份驗證機制。例如,小型單用戶集羣可能但願使用簡單的證書或靜態Bearer令牌方法。較大的羣集可能但願集成現有的OIDC或LDAP服務器,以將用戶細分爲多個組。更多有信息請參考認證。api
API 受權。一旦經過身份驗證,每一個API調用也都有望經過受權檢查。Kubernetes 附帶了一個集成的基於角色的訪問控制(RBAC)組件,該組件將傳入的用戶或組與捆綁到角色中的一組權限進行匹配。這些權限將動詞(get,create,delete)與資源(pods,service,nodes)結合在一塊兒,而且能夠是命名空間或集羣做用域。提供了一組現成的角色,這些角色根據客戶端可能要執行的操做提供合理的默認責任分離。更多有關信息請參考受權安全
Kubelet 在端口10250和10255上提供小型 REST API。端口10250是讀/寫端口,而10255是具備API端點子集的只讀端口。這些端點授予對節點和容器的強大控制權。默認狀況下,Kubelets容許未經身份驗證對此API進行訪問。生產集羣應啓用 Kubelet 身份驗證和受權,能夠經過設置 --read-only-port=0
來禁用只讀端口,可是10250 端口用於系統指標收集和其餘重要功能,因此開發者必須仔細控制對此端口的訪問。更多有關信息請參考Kubelet身份驗證/受權
保護集羣組件不受損壞
根據應用程序受到的攻擊,關注安全的特定方面。例如,運行中的服務 A 對於其餘應用很是重要,而服務 B 容易受到資源耗盡攻擊,若是不設置服務 B 的資源限制,就會由於服務 B 耗盡資源致使服務 A 不可用。因此須要注意下面幾個常見安全措施:
定義資源限制
默認狀況下,Kubernetes 集羣中對全部資源沒有對 CPU 、內存和磁盤的使用限制。能夠經過建立資源配額策略,並附加到 namespace 中來限制資源的使用。
下面的例子將限制命名空間中Pod 的數量爲4個,CPU使用在1和2之間,內存使用在1GB 和 2GB 之間。
# compute-resources.yaml apiVersion: v1 kind: ResourceQuota metadata: name: compute-resources spec: hard: pods: "4" requests.cpu: "1" requests.memory: 1Gi limits.cpu: "2" limits.memory: 2Gi requests.nvidia.com/gpu: 4
分配資源配額到命名空間:
kubectl create -f ./compute-resources.yaml --namespace=myspace
查看 namespace 資源使用狀況:
[root@localhost ~]# kubectl describe quota compute-resources --namespace=myspace Name: compute-resources Namespace: myspace Resource Used Hard -------- ---- ---- limits.cpu 0 2 limits.memory 0 2Gi pods 0 4 requests.cpu 0 1 requests.memory 0 1Gi requests.nvidia.com/gpu 0 4
也能夠爲 Pod 添加資源限制,設置內存請求爲 256MiB,內存限制爲512MiB
apiVersion: v1 kind: Pod metadata: name: default-mem-demo spec: containers: - name: default-mem-demo-ctr image: nginx resources: limits: memory: 512Mi requests:
- Pod 安全策略 做爲 Pod 的組成部分,容器一般配置有很是實用的安全默認值,這些默認值適用於大多數狀況。可是,有時 Pod 可能須要其餘權限才能執行其預期任務,在這種狀況下,咱們須要加強 Pod 的默認權限。安全上下文定義了 Pod 或容器的特權和訪問控制,安全上下文設置有: 1. 委託訪問:基於用戶ID 和用戶組ID 權限去訪問資源對象(如文件)。 2. SELinux:爲對象分配安全標籤 3. 以特權或非特權用戶運行 4. Linux 功能:爲進程提供一些特權,而不去賦予它root用戶的全部特權 5. AppArmor:使用程序配置文件來限制單個程序的功能。 6. Seccomp:過濾進程的系統調用 7. 容許提高權限(AllowPrivilegeEscalation):子進程可否得到父進程更多的權限。這個布爾值直接控制是否在容器進程上設置了 no_new_privs 標誌。在如下狀況下 AllowPrivilegeEscalation 始終爲 true——一是,以特權OR運行;二是,具備 `CAP_SYS_ADMIN`。 在 `securityContext` 字段下配置安全策略,在 Pod 中指定的安全策略將被應用於全部容器,容器中指定的安全策略應用於單個容器,當它們重複時,容器級會覆蓋 Pod 級的的安全策略。
apiVersion: v1 kind: Pod metadata: name: security-context-demo spec: securityContext: runAsUser: 1000 runAsGroup: 3000 fsGroup: 2000 volumes: - name: sec-ctx-vol emptyDir: {} containers: - name: sec-ctx-demo image: busybox command: [ "sh", "-c", "sleep 1h" ] volumeMounts: - name: sec-ctx-vol mountPath: /data/demo securityContext: runAsUser: 2000 allowPrivilegeEscalation: false ``` 更多有關信息請參考[Pod 安全策略](https://kubernetes.io/docs/concepts/policy/pod-security-policy/)
Kubernetes容許來自集羣中任何容器的全部網絡流量發送到集羣中的任何其餘容器並由其接收。當嘗試隔離工做負載時,這種開放式方法沒有幫助,所以須要應用網絡策略來幫助開發者實現所需的隔離。Kubernetes NetworkPolicy API使開發者可以將入口和出口規則應用於選定的Pod,用於第3層和第4層流量,並依賴於實現容器網絡接口(CNI)的兼容網絡插件的部署。
網絡策略是 namespace 做用域,並根據匹配標籤(例如,tier:backend)的選擇應用於Pod。當NetworkPolicy對象的Pod選擇器與Pod匹配時,根據策略中定義的入口和出口規則來管理進出Pod的流量。 全部來自或發往該Pod的流量都會被拒絕,除非有容許它的規則。
要在Kubernetes集羣中正確隔離網絡和傳輸層的應用程序,網絡策略應以「拒絕全部」的默認前提開始。而後,應將每一個應用程序組件及其所需源和目標的規則逐個列入白名單,並進行測試以確保流量模式按預期工做。
Kubernetes 使用 Secrets 保護應用程序須要訪問敏感信息——密碼、X.509證書、SSH密鑰或OAuth令牌等。它經過卷裝入,對它的訪問嚴格限於那些須要使用它的實體(用戶和Pod),且當存儲在磁盤上時(靜止狀態)它是不可訪問或只讀的。
須要考慮的所有安全問題以下:
須要關注的安全領域 | 建議 |
---|---|
RBAC 受權 | https://kubernetes.io/docs/re... |
認證方式 | https://kubernetes.io/docs/re... |
密鑰管理 | https://kubernetes.io/docs/co... |
Pod 安全規則 | https://kubernetes.io/docs/co... |
服務質量 | https://kubernetes.io/docs/ta... |
網絡規則 | https://kubernetes.io/docs/co... |
ingress 的 TLS | https://kubernetes.io/docs/co... |
爲了在 Kunernetes 中運行軟件,必須將它打包成容器。須要考慮下面的注意事項,來保證容器符合 Kubernetes 安全配置。
理想狀況下,使用應用程序二進制文件和二進制文件所依賴的的任何相關項來建立鏡像。事實上,沒有什麼阻止開發者將 scratch
做爲基礎鏡像,並將靜態連接的二進制文件複製到鏡像中。它沒有其餘依賴,鏡像中包含單個文件,以及一些描述容器如何運行的元數據。最小化鏡像加快鏡像的分發速度,而且顯著減小容器內部的受攻擊面。
可是這並不老是可行的,所以須要慎重選擇基礎鏡像。最佳的方法是使用操做系統供應商支持的鏡像,或者是 docker hub 上官方支持的鏡像。不要盲目使用以前未通過審查的不受信任來源的鏡像,尤爲是在生產環境中。
鏡像掃描對於保障容器應用的安全相當重要,確保您的鏡像按期經過信譽良好的工具進行掃描,可使用 CoreOS 的 Clair 之類的工具掃描容器中的已知漏洞,它是容器鏡像的靜態漏洞分析器。
使用 CNCF 項目的的 TUF 和 Notary 對容器進行簽名,在執行前驗證簽名,確保鏡像的正確沒有被篡改。
在構建鏡像時,建立最低操做系統權限的用戶完成容器的運行。
最後是代碼級別,這是程序員能掌控的被攻擊面,但不在 Kubernetes 的安全保護範圍,提供以下建議:
若是您的代碼須要經過TCP進行通訊,則理想狀況下,它將提早與客戶端執行TLS握手。除少數狀況外,默認行爲應是對傳輸中的全部內容進行加密。
不管什麼狀況下,程序只應該公開必要的端口。
確保第三方依賴是安全的。
大多數語言都提供了靜態代碼分析,能夠分析代碼中是否存在潛在的不安全編碼實踐。
自動化工具能夠針對您的服務嘗試會破壞服務的攻擊。這些包括SQL注入,CSRF和XSS。最受歡迎的動態分析工具之一是OWASP Zed Attack代理。
本篇文章出自 Choerodon豬齒魚社區易大強。