kubernetes 中 Secret

ecret與ConfigMap都是用來存儲配置信息的,不同之處在于ConfigMap是明文存儲的,而Secret用來保存敏感信息,如:密碼、OAuth令牌,ssh key等等。

Secret有三種類型:

  • Service Account:用來訪問kubernetes API,由k8s自動創建,并且會自動掛載到pod的/run/secrets/kubernetes.io/serviceaccount 目錄中。
  • Opaque:base64編碼格式的Secret,用來存儲密碼,密鑰等。
  • kubernetes.io/dockerconfigjson: 用來存儲私有docker registry的認證信息。

一、前言

ConfigMap傳遞敏感數據,就需要Secret。
Secret 對象可以存儲和管理敏感信息,比如 passwords、OAuth tokens、以及 ssh keys 等。把敏感信息存儲到 Secret 對象中會比放到 Pod 的定義文件或是容器鏡像中更加安全、靈活,使用 Secret 對象可以更好的控制數據的使用方式,并且減少意外泄露的風險。

不僅用戶可以創建 Secret 對象,kubernetes 系統也會創建一些 Secret 對象。
Secret 被創建以后,可以使用 3 種方式創建它:

  • 創建 Pod 時,通過為 Pod 指定 Service Account 自動使用該 Secret
  • 通過掛載該 Secret 到 Pod 來使用它
  • 在 Docker 鏡像下載時使用,通過指定 Pod 的 spc.ImagePullSecrets 來引用它

在存儲數據的時候,如何從 ConfigMap 和 Secret 這兩者之間進行選擇呢?

  • 使用 ConfigMap 存儲非敏感的配置信息
  • 使用 Secret 存儲敏感的配置信息
  • 如果配置文件既包含敏感信息、又包含非敏感信息,依然選擇 Secret 進行存儲

Secret 和 ConfigMap 對比,既有相同點、也有不同點,列表如下:
相同點:

  • 存儲數據都屬于 key-value 鍵值對形式
  • 屬于某個特定的 namespace
  • 可以導出到環境變量
  • 可以通過目錄/文件形式掛載(支持掛載所有 key 和部分 key)

不同點:

  • Secret 可以被 ServerAccount 關聯使用
  • Secret 可以存儲 Register 的鑒權信息,用于 ImagePullSecret 參數中,用于拉取私有倉庫的鏡像
    Secret 支持 Base64 加密
  • Secret 分為 Opaque、kubernetes.io/Service Account、kubernetes.io/dockerconfigjson 三種類型,ConfigMap 不區分類型
  • Secret 文件存儲在 tmpfs 文件系統中,Pod 刪除后 Secret 文件也會對應被刪除

二、默認令牌Secret
Service Accounts使用API證書自動創建并且綁定Secret。

kubernetes 系統可以自動創建用于訪問 API 證書的 Secret,并且可以自動綁定到 Pod 中使用這種類型的 Secret。

可以根據需要禁用或覆蓋重寫這類 Secret,但是通常情況下如果考慮到安全性,更加推薦使用系統默認創建的 Secret。

查看系統默認創建的Secret: kubectl get secrets

查看Secrets詳細信息:kubectl describe secrets

新建yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-manual
spec:
  containers:
    - image: registry.cn-hangzhou.aliyuncs.com/chenshi-kubernetes/nginx:1.9.1
      name: nginx
      ports:
        - containerPort: 80
          protocol: TCP

執行創建

$ kubectl create -f nginx-manual.yaml
pod/nginx-manual created

查看詳細信息

$ kubectl describe pod nginx-manual

這里顯示了 default-token-sz72t Secret 被掛載到了容器中的 /var/run/secrets/kubernetes.io/serviceaccount 目錄下

    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-sz72t (ro)

查看容器該目錄下的文件名是否符合

$ kubectl exec nginx-manual ls /var/run/secrets/kubernetes.io/serviceaccount

ca.crt
namespace
token

**Tips: **

當pod被API Service創建時,API Service不會校驗該pod引用的Secret是否存在

一旦這個pod被調度,則kubelet將試著獲取Secret的值

如果Secret不存在或暫時無法連接到API Secret,則kubelet會按照一定的時間間隔定期重試獲取該Secret,并發送一個Event來解釋pod沒有啟動的原因。

一旦 Secret 被 Pod 獲取,則 kubelet 將創建并掛載包含 Secret 的 Volume,只有所有 Volume 都掛載成功,Pod 中的 Container 才會被啟動。

三、創建Secret
創建Secret三種方式:

  • kubectl
  • yaml配置文件
  • 生成器創建secret

(1)使用kubectl創建secret

定義帳號和密碼

echo -n 'admin' > /home/donald/username.txt
echo -n '1f2d1e2e67df' > /home/donald/password.txt

創建

shell復制代碼$ kubectl create secret generic db-user-pass --from-file=/home/donald/username.txt --from-file=/home/donald/password.txt
secret/db-user-pass created

查看Secret

kubectl get secrets

(2)yaml配置文件
文件可以是json或yaml
定義Secret有兩種字段:

data:被Base64編碼以后的數據
stringData:可以純文本

定義帳號和密碼

echo -n 'admin' | base64
YWRtaW4=
$ echo -n '123' | base64
MTIz

創建secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MTIz

執行創建
$ kubeclt create -f secre.yaml
secret/mysecret created

(3)生成器創建Secret
kubectl v1.14版本開始支持 Kustomize管理對象

創建一個kustomization.yaml, 生成器字段secretGenerator

cat <<EOF >/home/donald/kustomization.yaml

secretGenerator:
- name: db-user-pass
  files:
  - username.txt
  - password.txt

或者 key-value形式
cat <<EOF >/home/donald/kustomization.yaml

secretGenerator:
- name: db-user-pass
  literals:
  - username=admin
  - password=secret

執行創建

shell復制代碼kubectl apply -k .

查看

kubectl get secrets

K8s 的 Secrets 的安全場景

在 Kubernetes 集群上運行的應用程序可以使用 Kubernetes Secrets,這樣就無需在應用程序代碼中存儲 token 或密碼等敏感數據。

當前默認 Kubernetes 集群內 Secrets 的典型工作流程如下:

  1. Dev 階段:使用 CICD 的應用程序開發人員將 git 作為管理部署到集群的配置的真實來源。訪問控制有助于確保對該資源庫的訪問安全,但這本身并不總能確保應用程序的敏感信息不被泄露。

  2. Ops 階段:API 服務器會在集群上創建 Kubernetes Secrets 資源,你可以在這里 這里 閱讀有關 Secrets 生命周期的更多信息。 存儲在 etcd 中的 Secrets 可由應用程序 pod 以三種方式之一使用:

    1. 作為一個或多個容器的 卷掛載 中的文件。
    2. 作為容器 環境變量。
    3. 由 Pod 的 kubelet 在拉取鏡像時使用。

在這三種情況下,密文中的值在使用前都會被解碼 (decode)。

那么,既然我們知道了它的工作原理,為什么只對密文進行 base64 編碼還不夠呢?

Base64 編碼為什么不算密文?

Base64 編碼是一種二進制到文本的編碼方案,它將 24 位二進制數據表示為 6 位 base64 數字。它用于在網絡上傳輸大量數據,尤其是圖像文件等大型文件。它的主要功能是在數據通過網絡傳輸時提供數據的完整性。要明確,編碼 (encode) 并不是加密 (encrypt)。

在任何 Linux 終端上試試這個。

$ echo -n 'not encrypted' | base64
bm90IGVuY3J5cHRlZA==

$ echo -n 'bm90IGVuY3J5cHRlZA==' | base64 --decode
not encrypted

如上,無論是在將 Secrets 傳輸到群集時,還是在群集上使用時,任何可以訪問你系統的人都可以輕松解碼你的 Secrets。

問題來了

作為 DevSecOps 管理員,您顯然面臨著兩個挑戰:

  1. 如何加密和管理集群外的敏感數據,即在構建和部署階段進入集群之前?
  2. 如何在集群內運行應用程序時保護敏感數據的安全?

以下是加密 K8s Secrets 的幾種方案。

在部署到群集之前對機密進行加密

作為將代碼推送到 git 倉庫(又稱應用程序的 "真相源")的開發人員,您可以在將代碼推送到 git 倉庫之前對應用程序使用的敏感信息進行加密。下面將介紹兩種常見的方法,用于在機密提交到 git 倉庫并部署到 OpenShift 集群之前對其進行加密:

使用 Bitnami Sealed Secrets

Bitnami Sealed Secrets 簡介

Bitnami Sealed Secrets: Kubernetes 的“加密的 Secrets”.

典型使用場景:

遇到的問題:“我可以在 git 中管理我所有的 K8s 配置,除了 Secrets?!?br> 解決方案:將您的 Secret 加密到 SealedSecret 中,即使在公共存儲庫中也可以安全存儲。SealedSecret 只能由目標集群中運行的控制器解密,其他人(甚至原始作者)無法從 SealedSecret 中獲得原始 Secret。

Bitnami Sealed Secrets 使用流程

使用 Bitnami Sealed Secrets 的工作流程示例如下:

  1. 集群管理員在 K8s 集群上部署 Sealed secrets 控制器
  2. 開發者需要在本地計算機上安裝 kubeseal CLI。
  3. 開發者創建一個 Secret 資源,然后由 kubeseal CLI 在運行時從控制器中獲取密鑰,對該資源進行加密或密封。對于網絡受限的環境,公鑰也可以存儲在本地并由 kubeseal 使用。 Kubeseal 將創建一個 SealedSecret 自定義資源。
  4. 開發者將此 CR 推送到自己的 git 倉庫中
  5. 可使用 ArgoCD 等 CD 工具在集群上部署 CR。
  6. 控制器將檢測到 SealedSecret 資源,并使用集群上的私鑰對其進行解密。

使用 KSOPS/Mozilla SOPS

KSOPS/Mozilla SOPS 簡介

  • Mozilla SOPS - sops 是加密文件的編輯器,支持 YAML,JSON,ENV,INI 和 BINARY 格式,并使用 AWS KMS,GCP KMS,Azure Key Vault,age 和 PGP 進行加密。
  • KSOPS - 一個靈活的 SOPS 加密資源的 Kustomize 插件

KSOPS/Mozilla SOPS 使用流程

如果使用 Argo CD 在 Kubernetes 中部署應用程序,則可以使用 Kustomize SOPS 插件,該插件用于解密使用 SOPS 加密的資源。

在集群上,管理員將:

  1. 部署 ArgoCD
  2. 使用 age 生成密鑰
  3. 在 特定(如 GitOps) Namespace 中創建存儲公鑰和私鑰的密鑰
  4. 定制 Argo CD 以使用 Kustomize SOPS 插件
  5. 將公鑰推送到 Git 倉庫

開發人員將:

  1. 在本地控制臺創建 Secret
  2. 使用 SOPS CLI 下載公鑰并加密密文
  3. 用加密后的 Secrets 生成 KSOPS yaml 并推送到 Git 倉庫

ArgoCD 在集群上部署 Secrets 之前,會使用 KSOPS 對機密文件進行解密。

小結

上面這兩種方法都適用于使用非對稱加密技術對機密文件進行加密。兩者都提供了在敏感數據作為 Secrets 部署到集群之前對其進行解密的方法。Sealed secrets 與 Kubernetes 原生集成。SOPS / KSOPS 可以獨立工作,不需要集群上的控制器。另外,Sealed secrets 使用 AES-256-GCM 等強 crypto,而 SOPS 使用 gpg 和 age。SOPS 提供與云提供商 KMS 的集成,而 SealedSecrets 目前還沒有,但計劃在未來實現集成(參見 這里)。 SOPS 不只可以對 Secrets 的值加密,還支持 yaml、json、env var 和二進制值加密,因此也可用于加密 helm chart。

不過,正如你所看到的,加密的數據一旦進入集群,就會在使用前被解密。因此,這基本上只解決了部分問題。接下來,我們需要看看如何在群集中保護這些數據的安全。讓我們看看在集群上加密數據的不同選項。

加密 K8s 群集上的 Secrets

K8s 的 etcd 加密選項

默認情況下,K8s 容器平臺不對 etcd 數據進行加密。但是原生 K8s, 以及一些 K8s 發行版,提供了啟用基于 etcd 的加密選項。

以下是相關的一些參考文檔:

  1. 原生 K8s: 靜態加密機密數據 | Kubernetes
  2. OpenShift: Encrypting etcd data | Security and compliance | OpenShift Container Platform 4.13
  3. K3s: Secret 加密 | K3s

讀者可以進一步閱讀以了解詳情。

使用 KMS 驅動進行數據加密

除了上面 etcd 的(靜態)加密方案之外,原生 K8s 和一些 K8s 發行版也提供了基于 KMS 驅動進行(動態)數據加密的方案。

以下是相關的一些參考文檔:

  1. 原生 K8s: 使用 KMS 驅動進行數據加密 | Kubernetes
  2. GKE: 在應用層對 Secret 加密 | Google Kubernetes Engine (GKE) | Google Cloud
  3. Amazon EKS: Enabling secret encryption on an existing cluster - Amazon EKS
  4. 使用阿里云 KMS 進行 Secret 的落盤加密 (alibabacloud.com)

公有云/私有云/數據中心磁盤加密選項

在 K8s 中使用 EBS 的公有云/私有云/數據中心節點級加密可以提供額外的加密層。這里以公有云為例說明:

  1. AWS: 在 AWS 上托管 K8s 群集時,可以啟用 Amazon EBS 加密,為 EC2 實例提供加密。Amazon EBS 加密在創建加密卷和快照時使用 AWS KMS 密鑰。它使用 AES-256-XTS 進行塊密碼加密。 創建加密 EBS 卷并將其附加到支持的實例類型時,以下類型的數據將被加密:

    • 加密卷內的靜態數據
    • 卷和實例之間移動的所有數據
    • 從加密卷創建的所有快照
    • 從這些快照創建的所有卷
  2. Azure: 為連接到 Azure Key Vault 的 Azure Managed Disks 提供加密選項

  3. Google 為 Google Cloud Storage 提供加密選項。兩者默認都使用 AES 256 密鑰,但也可以使用客戶管理和提供的密鑰,并與 KMS 集成。

使用第三方 Secrets 存儲集成的 Secrets

選擇第三方 Secrets 存儲的一個重要原因是,通過集中式 Secrets 存儲解決方案,確保在集群之外管理 Secrets 的生命周期。這些 Secrets 存儲提供的身份驗證和授權策略及程序與群集上的不同,也許更適合控制應用程序數據訪問。這些解決方案大多還提供監管機構要求的信封加密和 HSM 支持。流行的解決方案包括 HashiCorp Vault、CyberArk Conjur、AWS Secret Store、Azure Key Vault、Google Secret Manager、1Password 等。

Sidecar 解決方案

Vault 等解決方案可用于注入應用程序 pod 的特定 Secrets。在這種情況下,sidecar/init 容器都負責對 Secret Provider 進行身份驗證,然后應用程序可以在必要時使用返回的 Secrets。與 Provider 的連接是通過 TLS 進行的,以確保 Secrets 檢索的安全性。Vault 通過使用 響應封裝 提供額外的安全性,這使您可以在中間人無法看到憑證的情況下傳遞憑證。選擇這些解決方案的客戶可以決定將機密存儲在集群上或集群外。通常情況下,如果客戶一直使用 Vault 來滿足其基礎架構和其他應用需求,他們會傾向于與這些解決方案集成,以便在 K8s 上獲得無縫的機密管理體驗。

Secrets 存儲 CSI(SSCSI)驅動程序和提供商解決方案

Secrets Store CSI 驅動程序允許將 Secrets 和其他敏感信息作為卷掛載到應用程序 pod 中。Secrets Store CSI 驅動程序使用 gRPC 與提供程序通信,以便從 SecretProviderClass 自定義資源中指定的外部 Secrets Store 中檢索 Secrets 內容。一旦連接了卷,其中的數據就會加載到容器的文件系統中。與上述從特定提供商引入 Secrets 內容的 sidecar 解決方案不同,SSCSI 驅動程序可以配置為從多個不同的 Secret Provider 檢索 Secrets 內容。有關驅動程序和提供商如何工作的更多信息,請參閱 此處。

不希望將秘密存儲在 etcd 中作為 Kubernetes 秘密的客戶主要會選擇 SSCSI,原因如下

  • 他們可能有嚴格的合規性要求,因此有必要僅在中央存儲區而非集群中存儲和管理機密。
  • 他們可能會在控制平面不由他們管理的環境中引入工作負載,因此他們希望完全控制工作負載的機密,而不相信平臺管理員能做到這一點。例如,客戶將工作負載引入托管服務提供商集群的租戶中,或者將工作負載引入控制平面不由其管理的云平臺中。

SSCSI 驅動程序并不直接提供保護非卷標掛載機密的方法,例如那些需要作為環境變量或鏡像拉取機密的 Secrets,或者那些你可能直接在群集上創建用于管理 Ingress 證書的 Secrets。不過,你可以使用 sync secrets 功能,它可以創建 Kubernetes Secrets,然后為作為 Env 變量的 Secret 提供支持。

External Secrets Operator (ESO)

External Secrets Operator (ESO)是一種用戶友好型解決方案,用于將外部秘密管理解決方案中的秘密同步到 Kubernetes Secrets 中。 ESO 作為部署資源運行在 Kubernetes 集群中,利用自定義資源定義(CustomResourceDefinitions,CRD)通過 SecretStore 資源配置對 Secret Provider 的訪問,并利用 ExternalSecret 資源管理 Kubernetes 秘密資源。

客戶在以下情況下會選擇 ESO:

  • 他們需要與平臺輕松集成,并便于開發人員使用
  • 他們對集群的控制平面高度信任--尤其是在如何對 etcd 進行加密配置或如何在集群上管理 RBAC 方面
  • 他們在機密管理方面有多集群用例,需要跨集群機密集成
  • 他們需要為非應用程序使用管理平臺 Secrets,例如用于 Ingress、自動化、圖像拉取的機密
  • 需要在集群上修改 Secrets,并為特定應用提供模板
  • 最后,也是最重要的一點是,他們的用例需要集群上的 Secrets

將應用程序與 HSM (硬件安全模塊) 集成

最高級別安全,將應用程序或 K8s 與 HSM (硬件安全模塊) 集成。細節略。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,250評論 6 530
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 97,923評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,041評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,475評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,253評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,801評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,882評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,023評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,530評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,494評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,639評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,177評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,890評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,289評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,552評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,242評論 3 389
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,626評論 2 370

推薦閱讀更多精彩內容