Secret 存在意义 Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec中。
Secret 可以以 Volume 或者环境变量的方式使用.
(环境变量无法感知 secret 和 configmap 的更新 )
Secret 有三种类型
Service Account:用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中
Opaque:data 字段用 base64 编码 的通用 Secret,用来存储密码、密钥等。注意 base64 是编码不是加密——任何人 base64 -d 就还原了,也没有”别的加密方式”可选,data 的编码方式是固定的。想省掉手工编码可以改用 stringData
kubernetes.io/dockerconfigjson:用来存储私有 docker registry 的认证信息(同样是 base64 编码)
Secret 默认在 etcd 里是明文 存放的,要真正加密得配 encryption at rest(API Server 的 --encryption-provider-config),再配合 RBAC 限制谁能读。
secret 可选参数有三种:
generic: 通用类型,通常用于存储密码数据。
tls:此类型仅用于存储私钥和证书。
docker-registry: 若要保存 docker 仓库的认证信息的话,就必须使用此种类型来创建。
Service Account Service Account 用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 [root@k8s01 storage]# kubectl run nginx --image nginx:1.7.9 pod/nginx created [root@k8s01 storage]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 14s [root@k8s01 storage]# kubectl exec nginx -it -- ls /run/secrets/kubernetes.io/serviceaccount ca.crt namespace token [root@k8s01 storage]# kubectl exec nginx -it -- cat /run/secrets/kubernetes.io/serviceaccount/ca.crt -----BEGIN CERTIFICATE----- MIICyDCCAbCgAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl cm5ldGVzMB4XDTIwMDcyNzE3MzQxNFoXDTMwMDcyNTE3MzQxNFowFTETMBEGA1UE AxMKa3ViZXJuZXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOG z5wpcDPU642BeC/fj6IHUatrxJIu0xyvhXfK9NAA6qKenl0qiiKIWD2grSg6X8le d0CRJuslM+WGnq6d68G6NMZ3/MDpPwgXM0k4MttYyfo3mngBmtvEbFryoKoeulkq VSszYmNozsffjniH+tAEp7yitM5U0YrrnQFGozpiz2mQ+2RTvIBG0YOrQ1xjTnDW VSk+zqsNwpsCR18ebd1rrewatW0QZxOs1yGjNmNv+4lXodHLPKwUUewHRNnZn3vS jTf1cz77F0RHtel6bmZ8uhQ+SzpL6lT3/eykJvtGrIEpp1Vg2AfHU9Hc6IP3WYMl MG88R8kjgjRaAMz8khMCAwEAAaMjMCEwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB /wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBALi84N2GXQ6Qs3X3SKHfBumNJzb1 sK38r0+w34r+Gzlr+kRictSyv/wTc8KUHTUGXaGCRyrZOWmreDhA7ilRNN6OzRCp TgaI9bSWbgVbszroXPg12arri+ixytW1iZAZj0FIqi8v0oyIH6YIAS+U5d8npAy9 FyWBnzfg0StMjyLmh5f3pUQoxWNWRy5YOYGWZSsAhqBD3dNg+2Uor69Q0fmyJC1y rZlsUDYl4A70KWKNXfTtiRs6JfB3N9haWxmnkliC7sJ8A6bjAhgrVJYpEBThNdik hLeJhX8fCW/EyGeYNc3qPbrzza++sIZ5acSKKsX4I/vbhaqhVI/LYb9Imc4= -----END CERTIFICATE----- [root@k8s01 storage]# kubectl exec nginx -it -- cat /run/secrets/kubernetes.io/serviceaccount/token eyJhbGciOiJSUzI1NiIsImtpZCI6InZoTHNXRWwtZWU0NmswNnNvV3c0YWlyYVpZLUNaWm9sMWY5OGhzSkxveFUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tcnI3N2MiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImNjNzUwZGVjLTY4ZTYtNDcxYi1hMmVmLWZhZjFiMDYxYzFhZCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.UJYnr8KaB59ZF0wefTnh-3W3b20ftBBSw-46ghkl20aWVeK7pFxwjlcCWgp_3dG2jHn9dHtWa1DTemr05rpse0Xu_C029sJ4NlYSIwfR3lZ_K3lOuei6svAg2Aal_M5F8RdlcAvVvHn6TDEEH1VViM1-0uYQNF3p88vCKVFAkbRxQj6b-viAXeF1rlmLSgcB3qpU_xpKtFTqTJ6VvMQEw90eC2RwIxNhQgZPnNaeQsanoOlPC9DRkLPeA_ZYdys-e1_me3Gm5NeYsCBAbyfofufQ3BLMkXw0bfpiWK4VesfX-9Z7p1t3tKxYCZrsLIuSuj-O7Sc5qef89lwxYvcfKw [root@k8s01 storage]# kubectl exec nginx -it -- cat /run/secrets/kubernetes.io/serviceaccount/namespace default
Opaque Secret 创建说明 Opaque 类型的数据是一个 map 类型,要求 value 是 base64 编码格式:
1 2 3 4 5 6 [root@k8s01 storage]# echo -n "admin" | base64 # 只是编码,不是加密 YWRtaW4= [root@k8s01 storage]# echo -n "password" | base64 cGFzc3dvcmQ= [root@k8s01 storage]# echo -n "cGFzc3dvcmQ=" | base64 -d # 解密 password
secrets.yaml
1 2 3 4 5 6 7 8 apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: password: cGFzc3dvcmQ= username: YWRtaW4=
1 2 3 4 5 6 [root@k8s01 storage]# kubectl apply -f secrets.yaml secret/mysecret created [root@k8s01 storage]# kubectl get secret NAME TYPE DATA AGE default-token-rr77c kubernetes.io/service-account-token 3 32d mysecret Opaque 2 5s
补: 也可以使用 stringData, 避免 手动 使用 base64 加密
1 2 3 4 5 6 7 8 9 apiVersion: v1 kind: Secret metadata: name: mysecret namespace: default type: Opaque stringData: password: password username: admin
使用方式
将 Secret 挂载到 Volume 中
Secret-Volume.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 apiVersion: v1 kind: Pod metadata: labels: name: seret-test name: seret-test spec: volumes: - name: secrets secret: secretName: mysecret containers: - image: nginx:1.7.9 name: db volumeMounts: - name: secrets mountPath: "/etc/secrets" readOnly: true
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@k8s01 storage]# kubectl apply -f Secret-Volume.yaml pod/seret-test created [root@k8s01 storage]# kubectl get pod NAME READY STATUS RESTARTS AGE seret-test 1/1 Running 0 43s [root@k8s01 storage]# kubectl exec seret-test -it -- /bin/bash root@seret-test:/# cd /etc/secrets/ root@seret-test:/etc/secrets# ls password username root@seret-test:/etc/secrets# cat password # 已解密 password root@seret-test:/etc/secrets# cat username admin
将 Secret 导出到环境变量中 test-secert-deployment.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 apiVersion: apps/v1 kind: Deployment metadata: name: pod-deployment spec: replicas: 2 selector: matchLabels: app: pod-deployment template: metadata: labels: app: pod-deployment spec: containers: - name: pod-1 image: nginx:1.7.9 ports: - containerPort: 80 env: - name: TEST_USER valueFrom: secretKeyRef: name: mysecret key: username - name: TEST_PASSWORD valueFrom: secretKeyRef: name: mysecret key: password
1 2 3 4 5 6 7 8 9 10 [root@k8s01 storage]# kubectl apply -f test-secert-deplyment.yaml deployment.apps/pod-deployment created [root@k8s01 storage]# kubectl get pod NAME READY STATUS RESTARTS AGE pod-deployment-c97f4b999-2q4t9 1/1 Running 0 2m32s pod-deployment-c97f4b999-6nnx8 1/1 Running 0 2m32s seret-test 1/1 Running 0 6m49s [root@k8s01 storage]# kubectl exec pod-deployment-c97f4b999-2q4t9 -it -- /bin/bash root@pod-deployment-c97f4b999-2q4t9:/# echo $TEST_USER $TEST_PASSWORD # 查看环境变量 admin password
kubernetes.io/dockerconfigjson 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [root@k8s01 storage]# docker pull imwl/test:0.14 # 我自己的私有镜像 不登录 pull 失败 Error response from daemon: pull access denied for imwl/test, repository does not exist or may require 'docker login': denied: requested access to the resource is denied [root@k8s01 storage]# docker login # 登录 Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: imwl Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded [root@k8s01 storage]# docker pull imwl/test:0.14 # 登录后可 pull 成功 0.14: Pulling from imwl/test dc65f448a2e2: Pull complete Digest: sha256:97b496724012eee3df3421edb2ab6edcd6115e42b8060c24ba06b51da466e0dd Status: Downloaded newer image for imwl/test:0.14 docker.io/imwl/test:0.14 [root@k8s01 storage]# docker rmi imwl/test:0.14 # 删除镜像 Untagged: imwl/test:0.14 Untagged: imwl/test@sha256:97b496724012eee3df3421edb2ab6edcd6115e42b8060c24ba06b51da466e0dd Deleted: sha256:69c1c6c58124c56456a22c92a2e2125c9abc744f6acde379f5039779becbcc29 Deleted: sha256:ce8168f123378f7e04b085c9672717013d1d28b2aa726361bb132c1c64fe76ac [root@k8s01 storage]# docker logout # 退出登录 Removing login credentials for https://index.docker.io/v1/
使用 Kuberctl 创建 docker registry 认证的 secret
1 2 3 kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL secret "myregistrykey" created.
在创建 Pod 的时候,通过 imagePullSecrets 来引用刚创建的 myregistrykey
pod-dockerconfigjson.yaml
1 2 3 4 5 6 7 8 9 10 apiVersion: v1 kind: Pod metadata: name: foo spec: containers: - name: foo image: imwl/test:0.14 imagePullSecrets: - name: myregistrykey
查看信息
1 2 3 4 5 6 7 8 9 10 11 [root@k8s01 storage]# kubectl create secret docker-registry myregistrykey --docker-username=imwl --docker-password=********** [email protected] secret/myregistrykey created [root@k8s01 storage]# ls configMap secrets.yaml special-config.yaml test-pod02.yaml test-pod.yaml env-config.yaml Secret-Volume.yaml test04.yaml test-pod03.yaml test-secert-deplyment.yaml [root@k8s01 storage]# vi pod-dockerconfigjson.yaml [root@k8s01 storage]# kubectl apply -f pod-dockerconfigjson.yaml pod/foo created [root@k8s01 storage]# kubectl get pod # 可以看到镜像已被下载 NAME READY STATUS RESTARTS AGE foo 0/1 Completed 2 79s