小白學k8s(11)-k8s中Secret理解
理解Secret
什麼是Secret
Secret
物件型別用來儲存敏感資訊,例如密碼、OAuth
secret
中比放在Pod
的定義或者 容器映象中來說更加安全和靈活。
Secret
是一種包含少量敏感資訊例如密碼、令牌或金鑰的物件。 這樣的資訊可能會被放在Pod
規約中或者映象中。 使用者可以建立Secret
,同時系統也建立了一些Secret
。
要使用Secret
,Pod 需要引用Secret
。 Pod
可以用三種方式之一來使用 Secret:
-
作為掛載到一個或多個容器上的卷中的檔案。
-
作為容器的環境變數
-
由kubelet在為Pod拉取映象時使用
Secret的型別
Kubernetes
提供若干種內建的型別,用於一些常見的使用場景。 針對這些型別,Kubernetes
內建型別 | 用法 |
---|---|
Opaque | 使用者定義的任意資料 |
kubernetes.io/service-account-token | 服務賬號令牌 |
kubernetes.io/dockercfg | ~/.dockercfg 檔案的序列化形式 |
kubernetes.io/dockerconfigjson | ~/.docker/config.json 檔案的序列化形式 |
kubernetes.io/basic-auth | 用於基本身份認證的憑據 |
kubernetes.io/ssh-auth | 用於 SSH 身份認證的憑據 |
kubernetes.io/tls | 用於 TLS 客戶端或者伺服器端的資料 |
bootstrap.kubernetes.io/token | 啟動引導令牌資料 |
Opaque Secret
Opaque
型別的資料是一個map
型別,要求value
是base64
編碼格式:
建立我們需要的兩個base64
賬號資訊
$ echo -n "root" | base64
cm9vdA==
$ echo -n "123456" | base64
MTIzNDU2
secrets.yml
apiVersion: v1
kind: Secret
metadata:
name: secret-test
type: Opaque
data:
password: MTIzNDU2
username: cm9vdA==
建立 secret:kubectl create -f secrets.yml
$ kubectl get secret
NAME TYPE DATA AGE
secret-test Opaque 2 8s
可以看到我們剛剛建立的secret
Opaque Secret的使用
建立好secret
之後,有兩種方式來使用它:
-
以 Volume 方式
-
以環境變數方式
將Secret掛載到Volume中
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: secret-test
items:
- key: username
path: my-group/my-username
成功執行之後,進入到pod中
root@mypod:/etc/foo/my-group# ls
my-username
root@mypod:/etc/foo/my-group# cat my-username
root
可以看到我們之前定義的secret的username已經被當前的pod引用,併成功掛載
掛載的Secret會被自動更新
當已經儲存於卷中被使用的Secret
被更新時,被對映的鍵也將終將被更新。 元件kubelet
在週期性同步時檢查被掛載的Secret
是不是最新的。 但是,它會使用其本地快取的數值作為Secret
的當前值。
不過,使用Secret
作為子路徑卷掛載的容器 不會收到Secret
更新。
將Secret匯出到環境變數中
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: secret-test
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: secret-test
key: password
restartPolicy: Never
啟動pod,之後進入pod
root@secret-env-pod:/data# echo $SECRET_USERNAME
root
root@secret-env-pod:/data# echo $SECRET_PASSWORD
123456
可以看到secret的值已經成功寫入到環境變數中了
Secret更新之後對應的環境變數不會被更新
如果某個容器已經在通過環境變數使用某Secret
,對該Secret
的更新不會被 容器馬上看見,除非容器被重啟。有一些第三方的解決方案能夠在Secret
發生變化時觸發容器重啟。
kubernetes.io/dockerconfigjson
型別kubernetes.io/dockerconfigjson
被設計用來儲存JSON
資料的序列化形式, 該 JSON 也遵從~/.docker/config.json
檔案的格式規則,而後者是~/.dockercfg
的新版本格式。 使用此Secret
型別時,Secret
物件的 data 欄位必須包含.dockerconfigjson
鍵,其鍵值為base64
編碼的字串包含~/.docker/config.json
檔案的內容。
下面是一個kubernetes.io/dockercfg
型別Secret
的示例:
apiVersion: v1
kind: Secret
metadata:
name: secret-dockercfg
type: kubernetes.io/dockercfg
data:
.dockercfg: |
"<base64 encoded ~/.dockercfg file>"
kubernetes.io/service-account-token
kubernetes.io/service-account-token:
用於被serviceaccount
引用。serviceaccout
建立時Kubernetes
會預設建立對應的secret
。Pod如果使用了serviceaccount
,對應的 secret 會自動掛載到Pod的/run/secrets/kubernetes.io/serviceaccount
目錄中。
$ kubectl run nginx --image nginx
pod/nginx created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 0/1 ContainerCreating 0 26s
$ kubectl exec nginx ls /run/secrets/kubernetes.io/serviceaccount
ca.crt
namespace
token
Kubernetes
在建立Pod時會自動建立一個服務賬號Secret並自動修改你的Pod以使用該Secret。該服務賬號令牌Secret中包含了訪問Kubernetes API
所需要的憑據。
不可更改的Secret
Kubernetes
對於Secret
和ConfigMap
提供了一種不可變更的配置選擇,對於大量使用Secret
的叢集(至少有成千上萬各不相同的Secret
供Pod
掛載), 禁止變更它們的資料有下列好處:
-
防止意外(或非預期的)更新導致應用程式中斷
-
通過將 Secret 標記為不可變來關閉 kube-apiserver 對其的監視,從而顯著降低 kube-apiserver 的負載,提升叢集效能。
將Secret
的immutable
欄位設定為true
建立不可更改的Secret
apiVersion: v1
kind: Secret
metadata:
...
data:
...
immutable: true
1、當一個secret
設定成不可更改,如果想要更改secret
中的內容,就需要刪除並且重新建立這個secret
2、對於引用老的secret
的pod,需要刪除並且重新建立
Secret與Pod生命週期的關係
通過API建立Pod時,不會檢查引用的Secret是否存在。一旦Pod被排程,kubelet就會嘗試獲取該Secret的值。如果獲取不到該Secret,或者暫時無法與API伺服器建立連線,kubelet將會定期重試。kubelet將會報告關於 Pod 的事件,並解釋它無法啟動的原因。 一旦獲取到Secret,kubelet將建立並掛載一個包含它的卷。在Pod的所有卷被掛載之前,Pod中的容器不會啟動。
Secret與ConfigMap對比
相同點:
-
key/value 的形式
-
屬於某個特定的 namespace
-
可以匯出到環境變數
-
可以通過目錄 / 檔案形式掛載 (支援掛載所有 key 和部分 key)
不同點:
-
Secret 可以被 ServerAccount 關聯 (使用)
-
Secret 可以儲存 register 的鑑權資訊,用在 ImagePullSecret 引數中,用於拉取私有倉庫的映象
-
Secret 支援 Base64 加密
-
Secret 檔案儲存在 tmpfs 檔案系統中,Pod 刪除後 Secret 檔案也會對應的刪除。
參考
【Secret】https://feisky.gitbooks.io/kubernetes/content/concepts/secret.html
【k8s官方對Secret的描述】https://kubernetes.io/zh/docs/concepts/configuration/secret/