secret

橘子飞飞發表於2024-06-20

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;








相關文章