系列目錄html
Secrets是Kubernetes中一種對象類型,用來保存密碼、私鑰、口令等敏感信息。與直接將敏感信息嵌入image、pod相比,Secrets更安全、更靈活,用戶對敏感信息的控制力更強。同Docker對敏感信息的管理相似,首先用戶建立Secrets將敏感信息加密後保存在集羣中,建立pod時經過volume、環境變量引用Secrets。redis
建立Secrets數據庫
假設pod須要訪問數據庫。首先將用戶名保存在文件./username.txt
,將密碼保存在./password.txt
文件:json
# Create files needed for rest of example. $ echo -n 'admin' > ./username.txt $ echo -n '1f2d1e2e67df' > ./password.txt
將兩個文件做爲參數運行以下命令建立Secret,此時敏感數據被保存在系統中:api
$ kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt secret "db-user-pass" created
用Secret名稱查看建立Secret:安全
$ kubectl get secrets NAME TYPE DATA AGE db-user-pass Opaque 2 51s $ kubectl describe secrets/db-user-pass Name: db-user-pass Namespace: default Labels: <none> Annotations: <none> Type: Opaque Data ==== password.txt: 12 bytes username.txt: 5 bytes
以上經過命令行建立Secret,須要首先將敏感內容保存在文件中,文件名做爲Secret中單條條目的key。另一種建立Secret的方法是聲明對象。敏感信息可能包含任何控制字符、不可顯示字符等,首先進行base64
編碼:bash
$ echo -n 'admin' | base64 YWRtaW4= $ echo -n '1f2d1e2e67df' | base64 MWYyZDFlMmU2N2Rm
而後像下邊這樣聲明Secret對象:ide
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4= password: MWYyZDFlMmU2N2Rm
Kubernetes用map存儲Secret中的data數據部分,合法的key由字母、數字、’-‘、’_’、’.’組成,value能夠是任何值,但要base64編碼。運行以下命令建立Secret:性能
經過以下方法查看Secret中key所對應的值,首先運行以下命令:ui
$ kubectl get secret mysecret -o yaml apiVersion: v1 data: username: YWRtaW4= password: MWYyZDFlMmU2N2Rm kind: Secret metadata: creationTimestamp: 2016-01-22T18:41:56Z name: mysecret namespace: default resourceVersion: "164619" selfLink: /api/v1/namespaces/default/secrets/mysecret uid: cfee02d6-c137-11e5-8d73-42010af00002 type: Opaque
運行以下命令base64解碼:
$ echo 'MWYyZDFlMmU2N2Rm' | base64 --decode 1f2d1e2e67df
使用Secrets
Pod使用Secret的兩種方法:volume與環境變量。
經過volume使用Secret基於流程:
建立或者使用已存Secret,同一Secret可被多個pod引用。
修改pod定義,在.spec.volumes[]下增長新volume,名稱隨意。在相應的.spec.volumes[].secret.secretName指定Secret名稱。
爲使用Secret的容器添加.spec.containers[].volumeMounts[],同時指定.spec.containers[].volumeMounts[].readOnly = true。指定.spec.containers[].volumeMounts[].mountPath爲未使用的目錄名稱。
在容器的image中,經過指定的目錄與Secret中的key訪問敏感內容。
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: mysecret
若是須要引用多個Secret,須要爲每一個Secret在.spec.volumes[]添加相應的條目。若是單個容器須要引用多個Secret,則在.spec.containers[].volumeMounts[]中爲每一個Secret添加Mount。能夠將多個文件添加到一個Secret中,或者爲每一個文件建立Secret。
默認狀況下Secret中的全部key被映射到相同目錄下,能夠經過 .spec.volumes[].secret.items爲key設定映射目錄:
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: mysecret items: - key: username path: my-group/my-username
以上配置致使的結果爲username被映射到/etc/foo/my-group/my-username,而非默認的/etc/foo/username,而且password未被映射。 若是不使用.spec.volumes[].secret.items,Secret中全部key被映射到默認目錄,若是在.spec.volumes[].secret.items指定了key與特定的映射目錄,則只映射列出的key。若是打算使用.spec.volumes[].secret.items而且映射全部Secret的key,那麼須要列出Secret中全部key。
能夠在.spec.volumes[].secret.defaultMode中爲Secret指定Permission,若是須要進一步在.spec.volumes[].secret.items[].mode爲每一個key單獨指定permission。若是沒有指定permission,默認爲0644。示例以下:
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: mypod image: redis volumeMounts: - name: foo mountPath: "/etc/foo" volumes: - name: foo secret: secretName: mysecret defaultMode: 256
上例中的256等於8進制的0400,在json\yaml配置文件中不可使用八進制表示數字。單位爲key指定permission:
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: mypod image: redis volumeMounts: - name: foo mountPath: "/etc/foo" volumes: - name: foo secret: secretName: mysecret items: - key: username path: my-group/my-username mode: 511
當經過Secret經過volume形式被使用時,其中的key若是發生變動的話,由kubelet自動週期性監控變動併爲pod更新,可是注意此特性並不是實時,存在延遲。
經過環境使用Secret流程:
建立或者使用已存在Secrets,一個Secret能夠被多個pod使用。
修改pod聲明中使用Secret的容器配置,爲其添加環境變量env[].valueFrom.secretKeyRef,每條key對應一個環境變量。
在容器的image中經過引用環境變量使用敏感數據。
示例:
apiVersion: v1 kind: Pod metadata: name: secret-env-pod spec: containers: - name: mycontainer image: redis env: - name: SECRET_USERNAME valueFrom: secretKeyRef: name: mysecret key: username - name: SECRET_PASSWORD valueFrom: secretKeyRef: name: mysecret key: password restartPolicy: Never
Secrets限制條件
建立Pod時須要對其使用的Secret進行有效性檢查,所以Secrets要先於pod建立。
Secrets寄居於namespace之下,只有處於同一namespace下的pod能夠引用
單個Secret的size不能超過1M,防止Secrets佔用太多內存引發apiServer性能惡化。但過多的Secrets仍然會佔用大量的內在,關於限制全部Secrets佔用內存的特性正在計劃中。
kubelet在不通過apiServer、控制器建立pod,如–manifest-url、–config時不能使用Secrets。
若是在建立pod時Secret不存在或者key不存在,pod不能啓動。經過環境變量引用Secret時,若是envFrom中指定的key的名稱不合法,pod仍然能啓動但會觸發相應錯誤事件,如:
$ kubectl get events LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON 0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames kubelet, 127.0.0.1 Keys [1badkey, 2alsobad] from the EnvFrom secret default/mysecret were skipped since they are considered invalid environment variable names.