Secret的三種形式


Secret

ConfigMap這個資源對象是Kubernetes當中非常重要的一個對象,一般情況下ConfigMap是用來存儲一些非安全的配置信息,如果涉及到一些安全相關的數據的話用ConfigMap就非常不妥了,因為ConfigMap是名為存儲的,我們說這個時候我們就需要用到另外一個資源對象了:SecretSecret用來保存敏感信息,例如密碼、OAuth 令牌和 ssh key等等,將這些信息放在Secret中比放在Pod的定義中或者docker鏡像中來說更加安全和靈活。

Secret有三種類型:

  • Opaque:base64 編碼格式的 Secret,用來存儲密碼、密鑰等;但數據也可以通過base64 –decode解碼得到原始數據,所有加密性很弱。
  • kubernetes.io/dockerconfigjson:用來存儲私有docker registry的認證信息。
  • kubernetes.io/service-account-token:用於被serviceaccount引用,serviceaccout 創建時Kubernetes會默認創建對應的secret。Pod如果使用了serviceaccount,對應的secret會自動掛載到Pod目錄/run/secrets/kubernetes.io/serviceaccount中。

Opaque Secret

Opaque 類型的數據是一個 map 類型,要求value是base64編碼格式,比如我們來創建一個用戶名為 admin,密碼為 admin321 的 Secret 對象,首先我們先把這用戶名和密碼做 base64 編碼,

$ echo -n "admin" | base64 YWRtaW4= $ echo -n "admin321" | base64 YWRtaW4zMjE= 

然后我們就可以利用上面編碼過后的數據來編寫一個YAML文件:(secret-demo.yaml)

apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4= password: YWRtaW4zMjE= 

然后同樣的我們就可以使用kubectl命令來創建了:

$ kubectl create -f secret-demo.yaml
secret "mysecret" created 

利用get secret命令查看:

$ kubectl get secret
NAME                  TYPE                                  DATA      AGE
default-token-n9w2d   kubernetes.io/service-account-token   3         33d
mysecret              Opaque                                2         40s

其中default-token-cty7pdefault-token-n9w2d為創建集群時默認創建的 secret,被serviceacount/default 引用。

使用describe命令,查看詳情:

$ kubectl describe secret mysecret
Name:         mysecret
Namespace:    default
Labels:       <none> Annotations: <none> Type: Opaque Data ==== password: 8 bytes username: 5 bytes 

我們可以看到利用describe命令查看到的Data沒有直接顯示出來,如果想看到Data里面的詳細信息,同樣我們可以輸出成YAML文件進行查看:

$ kubectl get secret mysecret -o yaml
apiVersion: v1
data:
  password: YWRtaW4zMjE= username: YWRtaW4= kind: Secret metadata: creationTimestamp: 2018-06-19T15:27:06Z name: mysecret namespace: default resourceVersion: "3694084" selfLink: /api/v1/namespaces/default/secrets/mysecret uid: 39c139f5-73d5-11e8-a101-525400db4df7 type: Opaque 

創建好Secret對象后,有兩種方式來使用它:

  • 以環境變量的形式
  • 以Volume的形式掛載

環境變量

首先我們來測試下環境變量的方式,同樣的,我們來使用一個簡單的busybox鏡像來測試下:(secret1-pod.yaml)

apiVersion: v1 kind: Pod metadata: name: secret1-pod spec: containers: - name: secret1 image: busybox command: [ "/bin/sh", "-c", "env" ] env: - name: USERNAME valueFrom: secretKeyRef: name: mysecret key: username - name: PASSWORD valueFrom: secretKeyRef: name: mysecret key: password 

主要上面環境變量中定義的secretKeyRef關鍵字,和我們上節課的configMapKeyRef是不是比較類似,一個是從Secret對象中獲取,一個是從ConfigMap對象中獲取,創建上面的Pod

$ kubectl create -f secret1-pod.yaml
pod "secret1-pod" created 

然后我們查看Pod的日志輸出:

$ kubectl logs secret1-pod
... USERNAME=admin PASSWORD=admin321 ... 

可以看到有 USERNAME 和 PASSWORD 兩個環境變量輸出出來。

Volume 掛載

同樣的我們用一個Pod來驗證下Volume掛載,創建一個Pod文件:(secret2-pod.yaml)

apiVersion: v1 kind: Pod metadata: name: secret2-pod spec: containers: - name: secret2 image: busybox command: ["/bin/sh", "-c", "ls /etc/secrets"] volumeMounts: - name: secrets mountPath: /etc/secrets volumes: - name: secrets secret: secretName: mysecret 

創建Pod:

$ kubectl create -f secret-pod2.yaml
pod "secret2-pod" created 

然后我們查看輸出日志:

$ kubectl logs secret2-pod
password
username

可以看到secret把兩個key掛載成了兩個對應的文件。當然如果想要掛載到指定的文件上面,是不是也可以使用上一節課的方法:在secretName下面添加items指定 key 和 path,這個大家可以參考上節課ConfigMap中的方法去測試下。

kubernetes.io/dockerconfigjson

除了上面的Opaque這種類型外,我們還可以來創建用戶docker registry認證的Secret,直接使用kubectl create命令創建即可,如下:

$ kubectl create secret docker-registry myregistry --docker-server=DOCKER_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL secret "myregistry" created 

然后查看Secret列表:

$ kubectl get secret
NAME                  TYPE                                  DATA      AGE
default-token-n9w2d   kubernetes.io/service-account-token   3         33d
myregistry            kubernetes.io/dockerconfigjson        1         15s
mysecret              Opaque                                2         34m

注意看上面的TYPE類型,myregistry是不是對應的kubernetes.io/dockerconfigjson,同樣的可以使用describe命令來查看詳細信息:

$ kubectl describe secret myregistry
Name:         myregistry
Namespace:    default
Labels:       <none> Annotations: <none> Type: kubernetes.io/dockerconfigjson Data ==== .dockerconfigjson: 152 bytes 

同樣的可以看到Data區域沒有直接展示出來,如果想查看的話可以使用-o yaml來輸出展示出來:

$ kubectl get secret myregistry -o yaml
apiVersion: v1
data:
  .dockerconfigjson: eyJhdXRocyI6eyJET0NLRVJfU0VSVkVSIjp7InVzZXJuYW1lIjoiRE9DS0VSX1VTRVIiLCJwYXNzd29yZCI6IkRPQ0tFUl9QQVNTV09SRCIsImVtYWlsIjoiRE9DS0VSX0VNQUlMIiwiYXV0aCI6IlJFOURTMFZTWDFWVFJWSTZSRTlEUzBWU1gxQkJVMU5YVDFKRSJ9fX0= kind: Secret metadata: creationTimestamp: 2018-06-19T16:01:05Z name: myregistry namespace: default resourceVersion: "3696966" selfLink: /api/v1/namespaces/default/secrets/myregistry uid: f91db707-73d9-11e8-a101-525400db4df7 type: kubernetes.io/dockerconfigjson 

可以把上面的data.dockerconfigjson下面的數據做一個base64解碼,看看里面的數據是怎樣的呢?

$ echo eyJhdXRocyI6eyJET0NLRVJfU0VSVkVSIjp7InVzZXJuYW1lIjoiRE9DS0VSX1VTRVIiLCJwYXNzd29yZCI6IkRPQ0tFUl9QQVNTV09SRCIsImVtYWlsIjoiRE9DS0VSX0VNQUlMIiwiYXV0aCI6IlJFOURTMFZTWDFWVFJWSTZSRTlEUzBWU1gxQkJVMU5YVDFKRSJ9fX0= | base64 -d {"auths":{"DOCKER_SERVER":{"username":"DOCKER_USER","password":"DOCKER_PASSWORD","email":"DOCKER_EMAIL","auth":"RE9DS0VSX1VTRVI6RE9DS0VSX1BBU1NXT1JE"}}} 

如果我們需要拉取私有倉庫中的docker鏡像的話就需要使用到上面的myregistry這個Secret

apiVersion: v1 kind: Pod metadata: name: foo spec: containers: - name: foo image: 192.168.1.100:5000/test:v1 imagePullSecrets: - name: myregistrykey 

我們需要拉取私有倉庫鏡像192.168.1.100:5000/test:v1,我們就需要針對該私有倉庫來創建一個如上的Secret,然后在Pod的 YAML 文件中指定imagePullSecrets,我們會在后面的私有倉庫搭建的課程中跟大家詳細說明的。

kubernetes.io/service-account-token

另外一種Secret類型就是kubernetes.io/service-account-token,用於被serviceaccount引用。serviceaccout 創建時 Kubernetes 會默認創建對應的 secret。Pod 如果使用了 serviceaccount,對應的secret會自動掛載到Pod的/run/secrets/kubernetes.io/serviceaccount目錄中。

這里我們使用一個nginx鏡像來驗證一下,大家想一想為什么不是呀busybox鏡像來驗證?當然也是可以的,但是我們就不能在command里面來驗證了,因為token是需要Pod運行起來過后才會被掛載上去的,直接在command命令中去查看肯定是還沒有 token 文件的。

$ kubectl run secret-pod3 --image nginx:1.7.9
deployment.apps "secret-pod3" created $ kubectl get pods NAME READY STATUS RESTARTS AGE ... secret-pod3-78c8c76db8-7zmqm 1/1 Running 0 13s ... $ kubectl exec secret-pod3-78c8c76db8-7zmqm ls /run/secrets/kubernetes.io/serviceaccount ca.crt namespace token $ kubectl exec secret-pod3-78c8c76db8-7zmqm cat /run/secrets/kubernetes.io/serviceaccount/token eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tbjl3MmQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjMzY2FkOWQxLTU5MmYtMTFlOC1hMTAxLTUyNTQwMGRiNGRmNyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.0FpzPD8WO_fwnMjwpGIOphdVu4K9wUINwpXpBOJAQ-Tawd0RTbAUHcgYy3sEHSk9uvgnl1FJRQpbQN3yVR_DWSIlAtbmd4dIPxK4O7ZVdd4UnmC467cNXEBqL1sDWLfS5f03d7D1dw1ljFJ_pJw2P65Fjd13reKJvvTQnpu5U0SDcfxj675-Z3z-iOO3XSalZmkFIw2MfYMzf_WpxW0yMFCVkUZ8tBSTegA9-NJZededceA_VCOdKcUjDPrDo-CNti3wZqax5WPw95Ou8RJDMAIS5EcVym7M2_zjGiqHEL3VTvcwXbdFKxsNX-1VW6nr_KKuMGKOyx-5vgxebl71QQ 

Secret 與 ConfigMap 對比

最后我們來對比下SecretConfigMap這兩種資源對象的異同點:

相同點:

  • key/value的形式
  • 屬於某個特定的namespace
  • 可以導出到環境變量
  • 可以通過目錄/文件形式掛載
  • 通過 volume 掛載的配置信息均可熱更新

不同點:

  • Secret 可以被 ServerAccount 關聯
  • Secret 可以存儲 docker register 的鑒權信息,用在 ImagePullSecret 參數中,用於拉取私有倉庫的鏡像
  • Secret 支持 Base64 加密
  • Secret 分為 kubernetes.io/service-account-token、kubernetes.io/dockerconfigjson、Opaque 三種類型,而 Configmap 不區分類型


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM