歡迎訪問博客原文
Secret 是對敏感信息的抽象,例如:密碼、token、SSH key,其他對象可引用Secret。
Pod 使用 Secret 有兩種場景:
- 作爲 volume 中的文件被掛載到 Pod 中一個或多個容器中
- 拉取鏡像時需要使用 secret 作爲安全憑證
Secret 分類
Secret 可分爲三類:
- docker-registry: 創建一個給 Docker Registry 使用的 secret,實際是保存了賬戶密碼。
- generic:從本地 file, directory 或者 literal value 創建一個 secret。
- tls:創建一個 TLS secret。
創建 generic secret
通過 literal(字面量)創建
創建一個order數據庫的secret,包含賬戶密碼兩個字段。
kubectl create secret generic db-order-secret --from-literal=username=admin --from-literal=password=123456
literal 中若包含特殊字符則需要進行轉義,如"123456!" 需設置爲 “123456\!”
查看secret,describe secret db-order-secret
,查看時隱藏了字段值,僅展示了字節數。
對應的API對象爲 Opaque([oʊˈpeɪk]),譯爲"不透明物",等同於"敏感數據"。
Name: db-order-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 6 bytes
username: 5 bytes
再看看其yaml形態:
kubectl get secret db-order-secret -o yaml
其中字段是base64編碼後的值。
apiVersion: v1
data:
password: MTIzNDU2
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2020-03-14T04:21:29Z"
name: db-order-secret
namespace: default
resourceVersion: "28023453"
selfLink: /api/v1/namespaces/default/secrets/db-order-secret
uid: 5c60f906-ec8e-4277-8b96-caa75ef6589a
type: Opaque
解碼password字段,值爲123456
。
$ echo MTIzNDU2 | base64 --decode
123456
通過文件創建
在當前目錄創建一個RSA 公私鑰對作爲例子。
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): ./id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ./id_rsa.
Your public key has been saved in ./id_rsa.pub.
將私鑰創建爲secret,公鑰可分發給另一方。
kubectl create secret generic rsa-key-secret --from-file=./id_rsa
通過yaml創建
通過yaml提供元數據以創建secret,字段需用base64先編碼,如: echo -n admin | base64
。
apiVersion: v1
kind: Secret
metadata:
name: db-user-secret
type: Opaque
data:
username: YWRtaW4=
password: MTIzNDU2
然後創建Secret即可。
kubectl apply -f ./secret.yaml
Pod 中應用Secret
下面的例子演示了Secret 的三種應用方式。
- 作爲volume直接掛載,在容器中可直接使用
- 在環境變量中使用secret
- 向特定目錄映射secret
下面是Pod yaml。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx-container
image: nginx
env:
- name: SECRET_USERNAME
# 使用secret 做環境變量
valueFrom:
secretKeyRef:
name: db-user-secret
key: username
volumeMounts:
# 將secret作爲volume掛載
- name: volume1
mountPath: "/etc/foo1"
readOnly: true
# 向特定目錄映射secret
- name: volume2
mountPath: "/etc/foo2"
readOnly: true
volumes:
- name: volume1
secret:
secretName: db-user-secret
- name: volume2
secret:
secretName: db-user-secret
items:
- key: username
path: usernameFile
創建Pod,然後進入Pod驗證效果。
- 做環境變量
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: db-user-secret
key: username
結果如下:
$ env | grep SECRET_USERNAME
SECRET_USERNAME=admin
- 掛載到容器
volumeMounts:
- name: volume1
mountPath: "/etc/foo1"
readOnly: true
效果如下:
$ ls -l /etc/foo1
total 0
lrwxrwxrwx 1 root root 15 Mar 14 07:49 password -> ..data/password
lrwxrwxrwx 1 root root 15 Mar 14 07:49 username -> ..data/username
- 向特定目錄映射secret
spec:
volumeMounts:
- name: volume2
mountPath: "/etc/foo2"
readOnly: true
volumes:
- name: volume2
secret:
secretName: db-user-secret
items:
- key: username
path: usernameFile
將 username 字段映射到了 /etc/foo2/usernameFile
中
$ cat /etc/foo2/usernameFile
admin
創建 docker-registry secret 拉取鏡像
構建、部署時需要拉取鏡像,可以向Pod提供一個secret專門用於拉取鏡像。
以騰訊雲鏡像倉庫爲例,ccr.ccs.tencentyun.com/easyk8s/nginx
是一個私有的demo鏡像。
利用下面yaml跑一個簡單Pod:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx-container
image: ccr.ccs.tencentyun.com/easyk8s/nginx:1.17
運行後Pod Event如下,出現 Error: ErrImagePull
。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-aCIiPd6t-1584194450616)(https://imgcdn.chenyongjun.vip/2020/03/14/2.png)]
接下來創建一個secret專門用於拉取鏡像。
kubectl create secret docker-registry registry-tecent-secret \
--docker-server=ccr.ccs.tencentyun.com \
--docker-username=name \
--docker-password=password
在 Pod 中使用 secret。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx-container
image: ccr.ccs.tencentyun.com/easyk8s/nginx:1.17
imagePullSecrets:
- name: registry-tecent-secret
應用yaml後Pod成功創建。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-F28N8FX3-1584194450617)(https://imgcdn.chenyongjun.vip/2020/03/14/3.png)]
通過kubectl get secret registry-tecent-secret -o yaml
拿到的 registry-tecent-secret
的yaml結構如下:
apiVersion: v1
data:
.dockerconfigjson: eyJhdXR...
kind: Secret
metadata:
creationTimestamp: "2020-03-14T05:01:04Z"
name: registry-tecent-secret
namespace: default
resourceVersion: "28027921"
selfLink: /api/v1/namespaces/default/secrets/registry-tecent-secret
uid: a05ae3c0-b504-448b-bc78-8c540b2dda6c
type: kubernetes.io/dockerconfigjson
其中 .dockerconfigjson 通過base64解碼後可以拿到docker-registry的賬戶密碼。
創建tls secret
存儲用於SSL通訊的私鑰文件和證書文件,下面以nginx爲例子。
預先準備好nginx ssl 通訊所需的key和crt文件.
kubectl create secret tls nginx-ssl-secret \
--key=nginx.key \
--cert=nginx.crt
下面是 secret 的數據,其類型爲:kubernetes.io/tls
$ kubectl describe secret/nginx-ssl-secret
Name: nginx-ssl-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/tls
Data
====
tls.crt: 4241 bytes
tls.key: 1679 bytes
在nginx pod 中應用該secret,作爲volume映射到容器中。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx-container
image: nginx
volumeMounts:
- name: nginx-crt
mountPath: /etc/nginx/ssl
readOnly: true
volumes:
- name: nginx-crt
secret:
secretName: nginx-ssl-secret
運行Pod後進入Pod查看 /etc/nginx/ssl
目錄,可看到映射的證書、私鑰文件,不過名字從 nginx.crt, nginx.key
變爲了 tls.crt, tls.key
。
$ ls -l /etc/nginx/ssl/
total 0
lrwxrwxrwx 1 root root 14 Mar 14 08:42 tls.crt -> ..data/tls.crt
lrwxrwxrwx 1 root root 14 Mar 14 08:42 tls.key -> ..data/tls.key
接着可以在nginx配置中使用這兩個文件完成ssl通訊配置。
常用 Secret 示意圖
歡迎關注公衆號 [陳一樂],一起學習,一起成長