DevOps
CICD
K8s
Docker
Create a kubetnetes Secret
as follows:
Name: super-secret
Credential: alice or username:bob
Create a Pod
named pod-secrets-via-file using the redis image which mounts a secret named super-secret at /secrets
Create a second Pod
named pod-secrets-via-env using the redis image,which exports credential/username as TOPSECRET/CREDENTIALS
這題又來了一個新的東西,叫做Secret
,那麼Secret
是甚麼呢?
Secrets
是Kubernetes
提供開發者存放敏感資訊的方式。像是密碼、OAuth tokens及 ssh keys。將這些資訊存在放Secret
中比直接放在Pod YAML或Image中更加安全和靈活。
要使用Secret
,Pod 必須引用Secret
。Pod 有三種方式來引用Secret
:
Secret
作為容器的環境變數
Secret
製作為一個檔案,Pod以Volume
的形式將此檔案掛載 (mount)到容器上kubelet
在為Pod pull Docker Image時使用,透過指定Pod的spec.ImagePullSecrets
來參考它 (將Image存放於Private Registry中)下面介紹如何在集群中創建Secret
:
以kubeclt
創建Secret
又分為檔案形式和命令形式:
將機密資料,例如帳號密碼存在本機端的./username.txt
和./password.txt
檔案中
$ echo -n 'admin' > ./username.txt
$ echo -n '1f2d1e2e67df' > ./password.txt
以kubectl create secret generic
命令創建Secret
$ kubectl create secret generic <secret-name> --from-file=<file-name> --from-file=<file-name>
## 例如
$ kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
secret "db-user-pass" created
K8s
設置默認的key名就是檔案名稱,從上面的例子來看就是username.txt=admin (username.txt是檔名,admin是檔案內容),password.txt=1f2d1e2e67df。你也可以透過--from-file=<key>=<source>
來設置key名。
$ kubectl create secret generic db-user-pass \
--from-file=username=./username.txt \
--from-file=password=./password.txt
你可以用
kubectl get
和kubectl describe
查看創建的Secret
,但是會發現帳號密碼無法顯示,只會顯示Secret
的 bytes數,這是為了防止機密資料暴露給旁觀者或存在系統log中。
$ kubectl create secret generic <secret-name> --from-literal=<key>=<value>
## 例如
$ kubectl create secret generic test-secret --from-literal=DB_User=root \
--from-literal=DB_Password=toor
寫一個Secret
的YAML,範例如下:
$ cat secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
DB_Host: mysql
DB_User: root
DB_Password: toor
但若直接create這個 Secret
,會發現有error,這是因為Secret
是保存隱密的資料,所以Secret
會將data以 base64 的方式編碼,所以需要先把 data 轉成 base64 的格式:
$ cat secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
DB_Host: bXlzcWw=
DB_User: cm9vdA==
DB_Password: dG9vcg==
base64 編碼指令:
echo -n "<string-want-to-encode>" | base64
base64 解碼指令:
echo -n "<string-want-to-decode>" | base64 --decode
將資料編碼完成後,再將Secret
創立
kubectl apply -f secret-def.yaml
Secret
掛載是我們前面提到使用Secret
的其中兩種方式,那麼具體要如何操作呢?我們往下看~
Secret
作為容器的環境變數這種方法比較簡單,直接在Pod
中以spec.env.valueFrom.secretKeyRef
欄位參考到Secret
即可。例如:
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
創建完成後,進入該容器並輸入相關指令即可看到Secret
的設置結果
Secret
製作為一個檔案,Pod以Volume
的形式將此檔案掛載(mount)到容器上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
這邊會用到
volume
的概念,但是我們還沒介紹過,所以大家有個印象Secret
能透過這種方式使用即可,後面我們會再介紹到的~
Secret
就介紹到這裡啦~ 我們回到題目。
有了Secret
概念後這題應該就看得懂了,解題方法如下:
Secret
Pod
Pod
mount此Secret
,另一個Pod將Secret
作為環境變數使用創建Secret
$ kubectl create secret generic super-secret --from-literal=credentail=alice --from-literal=username=bob
Pod 1
$ kubectl run pod-secrets-via-file --image=redis --dry-run=client -o yaml > q5-1-pod.yaml
$ vim q5-1-pod.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod-secrets-via-file
name: pod-secrets-via-file
spec:
containers:
- image: redis
name: pod-secrets-via-file
resources: {}
volumeMounts:
- name: foo
mountPath: /secrets
volumes:
- name: foo
secret:
secretName: super-secret
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
Pod 2
$ kubectl run pod-secrets-via-env --image=redis --dry-run=client -o yaml > q5-2-pod.yaml
$ vim q5-2-pod.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod-secrets-via-env
name: pod-secrets-via-env
spec:
containers:
- image: redis
name: pod-secrets-via-env
resources: {}
env:
- name: TOPSECRET
valueFrom:
secretKeyRef:
name: super-secret
key: credential
- name: CREDENTIALS
valueFrom:
secretKeyRef:
name: super-secret
key: username
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
最後創建這兩個Pod
$ kubectl apply -f q5-1-pod.yaml q5-2-pod.yaml
這題的考點在Secret
,而且Secret
應用的兩種方式一次在這題中出現,稍微麻煩一點,需要創建兩個以上的YAML文件,但是只要能掌握Secret
的創建方式和使用方式就應該沒太大問題!好啦,今天就到這囉~ 謝謝大家~
Secrets
敏感的資料怎麼存在k8s?! - Secrets
Kubernetes — Secret
You can find me on
credentail credential 好像有寫錯
Error: couldn't find key credential in Secret default/super-secret
應該是credential