kubernetes部署的最佳安全實踐
本文闡述了作者在部署一個安全的kubernetes應用時的最佳實踐,包括:鏡像無漏洞,使用授權鏡像,限制節點訪問,限制資源訪問,定義資源配額,實現網絡分割,運用安全上下文,處處記錄日志,等等,并建議讀者將這些措施無縫集成到持續集成流水線中。
kubernetes提供了許多能有效提升你的應用安全性的規則。配置這些規則需要你精通kubernetes,并且明確部署的安全需求。此處我們強調的最佳實踐指的是容器的生命周期管理:構建,打包和運行,并且特指kubernetes的部署。我們在 我們自己的SaaS部署 中采用了這些最佳實踐,它是運行在谷歌云平臺上的kubernetes。
以下就是我們關于部署一個安全的kubernetes應用的建議。
確保鏡像沒有漏洞
用有漏洞的鏡像來跑容器會使你的環境面臨更容易被攻破的風險。確保你的所有軟件都沒有已知漏洞,就能減少很多攻擊。
- 進行持續的安全漏洞掃描 -- 容器可能包含那些過期的攜帶已知漏洞的包。漏洞掃描不能只是個一次性過程,因為新的漏洞每天都在發布。一個持續評估鏡像安全性的過程,對確保一個必要的安全態勢是至關重要的。
- 定期對環境進行安全更新 -- 一旦運行中的容器發現了漏洞,你必須更新源鏡像并重新部署容器。盡量避免直接更新運行中的容器(如使用 apt-update),因為這會破壞鏡像和容器的關系。使用 kubernetes 的 rolling update 特性來升級容器是相當簡單的,它允許逐步更新運行中的應用,通過更新鏡像到最新版本。
確保環境中只使用授權的鏡像
如果不能確保只允許附帶組織策略的鏡像運行,那么該組織將冒著運行有漏洞甚至是惡意容器的風險。從未知源下載并運行鏡像是危險的。這相當于在生產環境服務器上運行未知供應商提供的軟件。千萬不要這么做。
使用私有倉庫來存儲你的認證過的鏡像,并確保只上傳認證過的鏡像到這些私有倉庫。單單這條就已經縮小范圍了,它從成千上萬的公開可用的鏡像中減少到只剩一部分潛在的鏡像可以進入到你的流水線。構建一條 CI 流水線來集成安全評估(比如漏洞掃描),使它成為構建過程的一部分。
CI 流水線必須確保只有評審過的代碼(允許上生產環境)才能用來構建鏡像。一旦鏡像構建好,它必須掃描安全漏洞,并且只有當沒發現問題時,這個鏡像才能被上傳到私有倉庫,從該倉庫中部署到生產環境就完成了。安全評估中的失敗應該在流水線中創建一個失敗,從而阻止差的安全質量的鏡像上傳到鏡像倉庫。
kubernetes 的鏡像認證插件正在完工中(期望在 kubernetes 1.4 中完工),它將允許阻止未認證的鏡像打包。詳情請看這個 pull request 。
限制對 Kubernetes 節點的直接訪問。
你應該限制對 kubernetes 節點的 SSH 訪問,減少主機資源未認證就被訪問的風險。相應的,你應該要求用戶使用 kubectl exex 命令來訪問,它將提供對容器環境的直接訪問,而不涉及對主機的訪問。
你可以使用 kubernetes 的 授權插件 來進一步控制用戶的資源訪問權限。它允許對特定的命名空間,容器和操作定義細粒度訪問的控制規則。
資源之間創建管理邊界
限制用戶權限的范圍可以減少誤操作或者惡意操作的影響。kubernetes 的命令空間允許你將已創建的資源劃分成邏輯命名組。一個命名空間內創建的資源可以和其它命名空間隔離開。默認情況下,用戶在kubernetes集群中創建的每個資源都在default命名空間下。你可以創建額外的命名空間并將資源和用戶掛到該空間下。你可以通過kubernetes的授權插件(Authorization plugins)創建策略,隔離不同用戶對空間下的資源的訪問權限。
例如,以下策略允許“alice”讀取命名空間“fronto”下的 pods。
{ "apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": { "user": "alice", "namespace": "fronto", "resource": "pods", "readonly": true }
}
定義資源配額
運行資源不受限的容器會使你的系統面臨DoS或者“吵鬧的鄰居(noisy neighbor)”的風險。為了阻止或者最小化這些風險,你應該定義資源配額。默認情況下,kubernetes集群中創建的所有資源都不限制CPU和內存。你可以創建資源配額策略并關聯到命名空間下,以限制pod對CPU和內存的消耗。
以下是命名空間下資源配額定義的例子,它限制了該命令空間下,pod數量為4,總的CPU使用為1到2個,總的內存為1到2G。
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
將資源配額關聯到命名空間方法如下:
kubectl create -f ./compute-resources.yaml --namespace=myspace
實現網絡分割
不同的應用都運行在同一個kubernetes集群中,會面臨一個缺乏抵抗力的應用攻擊它的鄰居應用的風險。網絡分割對確保容器只能和那些它們允許訪問的容器交流來說就很重要。
kubernetes部署中的其中一個挑戰就是在pod,服務和容器間創建網絡分割。說它是挑戰,是因為容器網絡標識(IPs)的“動態”本質,以及另一個事實,即容器可以在同一節點和不同節點間通信。
谷歌云平臺的用戶受益于平臺的自動防火墻規則,可以阻止跨集群的通信。使用網絡防火墻或者SDN方案,我們也可以在本地部署一個相似的實現。kubernetes的 網絡SIG 正在該領域做相關工作,它能明顯改善pod和pod間通信的策略。一個新的網絡策略API應該滿足用戶的需求,在pod間創建防火墻規則,以限制容器間的網絡訪問。
以下是個網絡策略的例子,它控制"backend"pod的網絡,只允許“frontend”pod 的網絡訪問。
POST /apis/net.alpha.kubernetes.io/v1alpha1/namespaces/tenant-a/networkpolicys { "kind": "NetworkPolicy", "metadata": { "name": "pol1" }, "spec": { "allowIncoming": { "from": [{ "pods": { "segment": "frontend" } }], "toPorts": [{ "port": 80, "protocol": "TCP" }] }, "podSelector": { "segment": "backend" } }
}
給pod和容器使用安全上下文
在設計容器和pod的時候,請確保為你的pod,容器和volumes配置了安全的上下文。一個安全的上下文是部署yaml中定義的一個屬性。它控制了將賦給pod/容器/volume的安全參數。某些重要參數如下:
Security Context Setting Description
SecurityContext->runAsNonRoot Indicates that containers should run as non-root user
SecurityContext->Capabilities Controls the Linux capabilities assigned to the container.
SecurityContext->readOnlyRootFilesystem Controls whether a container will be able to write into the root filesystem.
PodSecurityContext->runAsNonRoot Prevents running a container with ‘root’ user as part of the pod
以下是一個帶安全上下文參數的pod定義例子:
apiVersion: v1 kind: Pod metadata: name: hello-world spec: containers: # specification of the pod’s containers # ... securityContext: readOnlyRootFilesystem: true runAsNonRoot: true
當你要用提升的權限(--privileged)來運行容器的時候,你應該考慮使用“DenyEscalatingExec”接入控制。這個控制拒絕 exec 和 attach 命令發到 pod ,那些pod用提升權限在運行,允許主機訪問。這些pod包括以特權運行的,對主機IPC命名空間有訪問權限的,以及對主機PID命名空間有訪問權限的。
每個地方都記錄日志
kubernetes提供基于集群的日志,允許記錄容器活動到一個中央日志倉庫。當一個集群創建的時候,每個容器的標準輸出和標準錯誤輸出都可以通過一個運行在每個節點上的Fluentd代理獲取到,這些輸出被輸入到谷歌Stackdriver日志系統或者Elasticsearch,并通過Kibana來查看。
總結
kubernetes應用了許多選項來創建安全的部署。不存在一刀切的解決方案,適用于任何地方。因此對這些選項要有一定的熟悉度,以及理解它們如何增強你的應用的安全性。
我們建議使用本文強調的那些最佳實踐,使用kubernetes的靈活配置能力將安全過程并入到持續集成流水線中,使得整個過程能自動化得無縫接入。
來自:http://dockone.io/article/1904