k8s secret
secret 存放一些敏感資料,但是不想被別人知道具體內容,如:密碼,token,金鑰等敏感資訊;
把POD想要訪問的資料加密後儲存在etcd中,然後可以透過Pod的容器掛載volume的方式或者環境變數等方式訪問secret裡的資訊;
secret 有些像ConfigMap,但是內容是加密的;
常用型別
opaque: 使用者定義的任意資料,在不指定的情況為此型別; 弱安全性,base64 加密,可以進行解密獲得原始資料;
kubernetes.io/service-account-token: 服務賬號令牌
kubernetes.io/dockercfg:~/.dockercfg檔案的序列化形式
kubernetes.io/dockerconfigjson:~/.docker/config.json檔案的序列化形式
kubernetes.io/tls:使用者TLS客戶端或服務端的資料
kubernetes.io/basic-auth: 用於基本的身份驗證
kubernetes.io/ssh-auth:用於ssh身份驗證憑據
使用
透過檔案建立secret
如:username 與password 儲存使用者名稱與密碼的兩個檔案;
echo "admin" > username # 使用者名稱不進行加密,做對比 echo "123456" | base64 > password
上面兩條命令將使用者名稱admin存放到檔案username中
密碼123456進行base64編碼後儲存到檔案password中;
透過檔案建立secret:
kuser@control195:~/learn/secret$ kubectl create secret generic -n test test-from-file --from-file=username --from-file=password -o yaml --dry-run=client
或者透過下面的yaml 檔案來建立;
apiVersion: v1 data: password: TVRJME5UWUsK username: YWRtaW4K # 從生成的檔案來看,即使不在指定的檔案中(--from-file加密),在建立的時候也會進行加密; kind: Secret metadata: creationTimestamp: null name: test-from-file namespace: test
檢視建立secret 後的情況:
kuser@control195:~/learn/secret$ kubectl describe secret -n test test-secret
kuser@control195:~/learn/secret$ kubectl describe secret -n test test-secret Name: test-secret Namespace: test Labels: <none> Annotations: <none> Type: Opaque Data ==== username: 8 bytes password: 6 bytes
透過yaml 描述檔案建立secret:
apiVersion: v1 data: password_file: MTIzNDU2Cg== # 這裡的加密資訊需要手工進行計算:echo "123456" | base64 username_file: YWRtaW4K # 這裡的加密資訊需要手工進行計算:echo "admin" | base64 kind: Secret metadata: name: test-secret namespace: test
這裡的描述檔案與透過檔案建立secret 生成的描述檔案基本完全一致,所以.....
然後建立即可,kubectl apply -f secret-from-files.yaml
檢視結果與上面的透過檔案建立完全一致;
secret 使用
透過volume 掛載進行使用
1、建立一個測試的POD
由於直接寫yaml 可能比較困難,所以有我們生成一個臨時的,而後再進行編輯;
kuser@control195:~/learn/secret$ kubectl run --image=busybox -o yaml --dry-run=client testpod -- sleep "36000" > testpod.yaml
這樣就建立出了一個testpod 的POD;
而後我們再對檔案進行修改,如:修改namespace、新增volume 資訊;
apiVersion: v1 kind: Pod metadata: labels: run: pod name: pod namespace: test spec: containers: - image: busybox name: pod command: - sleep - "36000" imagePullPolicy: IfNotPresent volumeMounts: # 這裡volume 的掛載資訊 - name: volume1 mountPath: /tmp/1 # 掛載點 readOnly: true volumes: - name: volume1 secret: secretName: test-from-file # 將secret 名稱為test-from-file 的secret 掛載進來,不寫後面items的情況,會將test-from-file中secret的所有key都掛載進來; items: # 指定將test-from-file 的username 與passwod 分別掛載到不同的檔案 - key: username path: u/usermame - key: password path: p/password dnsPolicy: ClusterFirst restartPolicy: Always
上面的volume 下的secret 資訊中,volumes中的secret,secretName 是引入的secret 的標識,當然此secret 需要與POD在相同的namespace下;
secret 名稱為test-from-file 將被載入進來,如果 test-from-file 不存在的情況,那麼也不會出現錯誤,我們需要建立即可;
載入secret的方式:
1、載入所有
指定好secretName後,後面不需要寫items即可;
2、載入指定secret 的股固定選項(key)
指定好secretName後,後面需要新增items,items下面再新增需要新增進來的Key,如:
secretName: test-from-file items: - key: username path: u/username - key: password path: p/password
上面這就是載入了usrename 與password 的key,並且指定了掛載的路徑;
如:volumeMounts中指定的volume 的path,那麼會將這裡的path 再載入到mount 的下面,如上面的例子中,最終結果為:
/tmp/1/u/username # 這裡存放了username的內容 /tmp/1/p/password #這裡存放了password 的內容
修改上面的描述檔案,新增volume相關
kuser@control195:~/learn/secret$ kubectl apply -f testpod.yaml
pod/pod created
檢視建立的POD的掛載情況,
kubectl describe pod -n test pod Mounts: /tmp/1 from volume1 (ro) /var/run/secrets/kubernetes.io/serviceaccount from default-token-ggksm (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: volume1: Type: Secret (a volume populated by a Secret) SecretName: test-from-file Optional: false default-token-ggksm: Type: Secret (a volume populated by a Secret) SecretName: default-token-ggksm
可以檢視到Mounts 下已經有新的掛載記錄,而在Volumes 資訊中,也能看到volume1 中SecretName為test-from-file 已經掛載;
此時進入POD內部,檢視具體資訊:
kuser@control195:~/learn/secret$ kubectl exec pod -n test pod -- ls -l /tmp/1/ total 0 lrwxrwxrwx 1 root root 8 Jun 19 07:51 p -> ..data/p lrwxrwxrwx 1 root root 8 Jun 19 07:51 u -> ..data/u 再次檢視掛載後的檔案具體內容: kuser@control195:~/learn/secret$ kubectl exec pod -n test pod -- cat /tmp/1/u/usermame admin kuser@control195:~/learn/secret$ kubectl exec pod -n test pod -- cat /tmp/1/p/password MTIzNDU2Cg==
2、在環境變數中使用
1、建立secret
參照前面建立即可;
2、建立POD
apiVersion: v1 kind: Pod metadata: labels: run: pod2 name: pod2 namespace: test spec: containers: - command: - sleep - "3600" image: busybox name: pod2 env: - name: SEC_USERNAME valueFrom: secretKeyRef: name: secret-from-file key: username - name: SEC_PASSWORD valueFrom: secretKeyRef: key: password name: secret-from-file resources: {} imagePullPolicy: IfNotPresent dnsPolicy: ClusterFirst restartPolicy: Always status: {}
上面這種寫法是指定載入secret 中的某些變數;
3、檢視POD的資訊中關於設定的環境變數中引用:
kuser@control195:~/learn/secret$ kubectl describe pod -n test pod2 | grep -i env -A 4 Environment: SEC_USERNAME: <set to the key 'username' in secret 'secret-from-file'> Optional: false SEC_PASSWORD: <set to the key 'password' in secret 'secret-from-file'> Optional: false Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-ggksm (ro)
4、在POD內部檢視是否真正的讀取到資訊;
kuser@control195:~/learn/secret$ kubectl exec pod2 -n test -- printenv | grep -i env kuser@control195:~/learn/secret$ kubectl exec pod2 -n test -- printenv | grep -i sec SEC_USERNAME=YWRtaW4K SEC_PASSWORD=MTIzNDU2Cg==
5、載入secret 中的全部變數
apiVersion: v1 kind: Pod metadata: labels: run: pod3 name: pod3 namespace: test spec: containers: - command: - sleep - "3600" image: busybox name: pod2 envFrom: - secretRef: name: secret-from-file resources: {} imagePullPolicy: IfNotPresent dnsPolicy: ClusterFirst restartPolicy: Always status: {}
在容器內檢視環境變數是否已經載入成功;
kuser@control195:~/learn/secret$ kubectl exec pod3 -n test -- printenv |egrep -i 'us|pass' PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin password=MTIzNDU2Cg== username=YWRtaW4K
6、更新secret 內容
設定生效後,檢視更新後的secret與pod 中的環境變數
新增加一個環境變數port
kuser@control195:~/learn/secret$ kubectl exec -n test podenv -- printenv | grep SEC
SEC_PORT=MjMK
SEC_USR=admin
SEC_PASS=MTIzNDU2Cg==
kuser@control195:~/learn/secret$ echo "24"| base64 >port
kuser@control195:~/learn/secret$ kubectl apply -f secret-from-files.yaml
secret/test-from-file configured
kuser@control195:~/learn/secret$ kubectl exec -n test podenv -- printenv | grep SEC
SEC_PORT=MjMK
SEC_USR=admin
SEC_PASS=MTIzNDU2Cg==
發現POD並沒有進行實時更新,對於已經引用了該secret的容器來說,並不會主動更新ENV,除非重啟該POD;