secret

Secret 存在意义

Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec中。

Secret 可以以 Volume 或者环境变量的方式使用.

(环境变量无法感知 secretconfigmap 的更新 )

Secret 有三种类型

  1. Service Account:用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod/run/secrets/kubernetes.io/serviceaccount 目录中
  2. Opaquebase64 编码格式的 Secret,用来存储密码、密钥等 # 也可用别的加密方式
  3. kubernetes.io/dockerconfigjson:用来存储私有 docker registry 的认证信息 (也是用 base64 加密)

secret 可选参数有三种:

  1. generic: 通用类型,通常用于存储密码数据。
  2. tls:此类型仅用于存储私钥和证书。
  3. 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 类型,要求 valuebase64 编码格式:

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

使用方式

  1. 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
  1. 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/
  1. 使用 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.
  2. 在创建 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. 查看信息
    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