secret介紹
1、configmap都是明文存數據的,所以我們不能用它來訪問,所以我們使用secret,但它比configmap要麻煩一點,只有敏感數據采用secrt來存放,比如你的私鑰和證書,這個時候私鑰和證書要放在secret中,其它內容應該放在configmap中,另外還有,比如我們連接mysql是我們打算把密碼寫在配置文件中,這個時候我們要把密碼寫成secret,而不能定義成configmap,所以他和configmap一樣也是鍵值存儲,只是它的值在看的時候不顯示給你,或者就算顯示給你的也是base64的編碼格式,但除此之外我們secret還有一個特定就是它有多種類型。
a、generic(通用的):保存密碼數據等用它就可以
b、tls:保存私鑰和證書
c、docker-registry:保存docker-registry的認證信息,我們每一個node運行pod之前會把pod依賴的鏡像要先檢查本地有沒有,如果沒有就回去倉庫服務器上拖,如果我們用的是私有倉庫的話,必須要輸入賬號和密碼才能訪問,賬號密碼放哪兒呢?也就意味着當前node要自動去通過認證然后去拖鏡像否則pod就會運行失敗,也就意味着拉取的時候要現在節點上使用docker login然后docker pull。因此很多時候我們k8s節點要運行pod獲取鏡像,而若鏡像若托管在在必須要認證才能獲取到的私有鏡像倉庫中時,kubelet要能自動完成,因此拖鏡像和認證是通過kubelet指揮着docker去做的,那我們怎么去提供這個私有數據呢。第一種方式是我們使用secret,使用我們pods.spec.imagePullSecrets字段,表示pod創建時,它如果要連到私有鏡像倉庫服務器,需要認證那么這里我們應該放個secret,這個secret包含了讓我們kubelet或我們docker去鏈接私有倉庫服務器時的賬號和密碼,這個賬號密碼就是由secret提供的,這個對象必須是專用的對象,就是我們這個docker-registry
創建一個generic類型的secret
kubectl create secret generic mysql-root-password --from-literal=password=MyP@ss123

獲取secret信息:
kubectl get secret mysql-root-password -o yaml

反編譯查看secret內容:
echo TXlQQHNzMTIz | base64 -d

pod應用secre兩種方式
引用到env
apiVersion: v1 kind: Pod metadata: name: pod-secret-1 namespace: default labels: #也可以在此處寫上{app:myapp,tier:frontend}代替下面兩行 app: myapp #應用層級標簽 tier: frontend #架構層級標簽,在分層架構中屬於frontend層 annotations: created-by: "cluster admin" spec: containers: #是一個列表,具體定義方式如下 - name: myapp image: ikubernetes/myapp:v1 ports: #不暴露端口其實也可以被訪問,目的是為了說明啟動的端口有哪些 - name: http #service 中可以通過名稱來引用端口 containerPort: 80 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-root-password key: password
實際效果:

方式二:掛載為存儲卷
apiVersion: v1 kind: Pod metadata: name: pod-secret-2 namespace: default labels: #也可以在此處寫上{app:myapp,tier:frontend}代替下面兩行 app: myapp #應用層級標簽 tier: frontend #架構層級標簽,在分層架構中屬於frontend層 annotations: created-by: "cluster admin" spec: containers: #是一個列表,具體定義方式如下 - name: myapp image: ikubernetes/myapp:v1 ports: #不暴露端口其實也可以被訪問,目的是為了說明啟動的端口有哪些 - name: http #service 中可以通過名稱來引用端口 containerPort: 80 volumeMounts: #在容器中使用pod定義的volumes - name: secretconfig mountPath: /tmp/ readOnly: true volumes: #在pod中定義volumes - name: secretconfig secret: secretName: mysql-root-password
效果如下:

向特性路徑映射 secret 密鑰
首先edit secret 增加一個key,value:
echo admin|base64 kubectl edit secret mysql-root-password kubectl get secret mysql-root-password -o yaml
效果如下:增加了一個username

我們還可以控制 Secret key 映射在 volume 中的路徑。您可以使用 spec.volumes[].secret.items 字段修改每個 key 的目標路徑:
apiVersion: v1 kind: Pod metadata: name: pod-secret-3 namespace: default labels: #也可以在此處寫上{app:myapp,tier:frontend}代替下面兩行 app: myapp #應用層級標簽 tier: frontend #架構層級標簽,在分層架構中屬於frontend層 annotations: created-by: "cluster admin" spec: containers: #是一個列表,具體定義方式如下 - name: myapp image: ikubernetes/myapp:v1 ports: #不暴露端口其實也可以被訪問,目的是為了說明啟動的端口有哪些 - name: http #service 中可以通過名稱來引用端口 containerPort: 80 volumeMounts: #在容器中使用pod定義的volumes - name: secretconfig mountPath: /tmp/ readOnly: true volumes: #在pod中定義volumes - name: secretconfig secret: secretName: mysql-root-password items: - key: password path: mypath/my-password
將會發生什么呢:
- password secret 存儲在 /tmp/mypath/my-password 文件中而不是 /tmp/password 中。
usernamesecret 沒有被映射

掛載的 secret 被自動更新
上面的測試,secret都是一個,現在對secret中password值進行更新,然后觀察
echo MyP@ss1234 | base64
kubectl edit secret mysql-root-password

結果:
env方式: 未進行更新,應該是需要重啟才會生效

方式二:掛載為存儲卷 : 自動更新了,圖貼錯了,實驗過,會更新

向特性路徑映射 secret 密鑰:自動更新了

重啟第一個pod,看是否生效:
kubectl delete pod pod-secret-1 kubectl get pod kubectl apply -f pod-secret-1.yaml kubectl exec -it pod-secret-1 printenv| grep PASS
更新了

使用 imagePullSecret
用於拉去鏡像時的認證
參考:https://blog.51cto.com/lvnian/2314456?source=dra
不做測試,只貼一個案例:
apiVersion: v1 kind: Pod metadata: name: foo namespace: awesomeapps spec: containers: - name: foo image: janedoe/awesomeapp:v1 imagePullSecrets: - name: myregistrykey
參考:
https://www.cnblogs.com/Presley-lpc/p/11044991.html
https://kubernetes.io/zh/docs/concepts/configuration/secret/
