Secret
Secrert

目录
[toc]
本节实战
| 实战名称 |
|---|
| 💘 实战:通过data字段来创建secret资源对象-2023.1.15(测试成功) |
| 💘 实战:通过stringData字段来创建secret资源对象-2023.1.15(测试成功) |
| 💘 实战:通过kubectl create命令来创建Opaque类型的Secret资源-2023.1.15(测试成功) |
| 💘 实战:以环境变量的形式使用secret-2023.1.15(测试成功) |
| 💘 实战:以volume挂载的形式使用secret-2023.1.15(测试成功) |
| 💘 实战:部署mysql pod并引用secret-2023.6.3(测试成功) |
| 💘 实战:通过kubectl create命令的方式来创建镜像仓库认证信息-2023.1.15(测试成功) |
| 💘 实战:通过指定文件的方式来创建镜像仓库认证信息-2023.1.15(测试成功) |
| 💘 实战:kubernetes.io/basic-auth测试-2023.1.16(测试成功) |
Secret简介
前文我们学习 ConfigMap 的时候,我们说 ConfigMap 这个资源对象是 Kubernetes 当中非常重要的一个资源对象。
一般情况下 ConfigMap 是用来存储一些非安全的配置信息,如果涉及到一些安全相关的数据的话用 ConfigMap 就非常不妥了,因为 ConfigMap 是明文存储的,这个时候我们就需要用到另外一个资源对象了:Secret。
Secret用来保存敏感信息,例如密码、OAuth 令牌和 ssh key 等等,将这些信息放在 Secret 中比放在 Pod 的定义中或者 Docker 镜像中要更加安全和灵活。
与ConfigMap类似,区别在于Secret主要存储敏感数据,所有的数据要经过base64编码。
应用场景:凭据 #secert应用场景还是挺多的;
Secret 主要使用的有以下几种类型:(主要是3种类型:Opaque、dockerconfigjson、kubernetes.io/tls–这3种用的比较多一点。)
generic:从文件、目录或者字符串创建,例如存储用户名密码Opaque:base64 编码格式的 Secret,用来存储密码、密钥等。但数据也可以通过base64 –decode解码得到原始数据,所所以加密性很弱。kubernetes.io/dockercfg:~/.dockercfg文件的序列化形式kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息,~/.docker/config.json文件的序列化形式;kubernetes.io/service-account-token:用于ServiceAccount。kubernetes.io/ssh-auth:用于 SSH 身份认证的凭据kubernetes.io/basic-auth:用于基本身份认证的凭据bootstrap.kubernetes.io/token:用于启动引导令牌数据tls:存储证书,例如HTTPS证书
上面是 Secret 对象内置支持的几种类型,通过为 Secret 对象的 type 字段设置一个非空的字符串值,也可以定义并使用自己 Secret 类型。如果 type 值为空字符串,则被视为 Opaque 类型。Kubernetes 并不对类型的名称作任何限制,不过,如果要使用内置类型之一, 则你必须满足为该类型所定义的所有要求。
⚠️ 注意:
需要注意的是默认情况下,Kubernetes Secret 未加密存储在 APIServer 的底层数据存储 etcd 中,任何拥有 API访问权限的人都可以检索或修改 Secret,任何有权访问 etcd 的人也可以。此外,任何有权限在命名空间中创建 Pod 的人都可以使用该访问权限读取该命名空间中的任何 Secret。为了更安全地使用 Secret,我们可以执行以下步骤来加强安全:
为 Secret 启用静态加密。
以最小特权访问 Secret 并启用或配置 RBAC 规则。
限制 Secret 对特定容器的访问。
考虑使用外部 Secret 存储驱动。(这个比较安全)
在后续课程中我们也会陆续接触到这些方案。
base64:这里的一个弱编码,不是加密,不具备加密的功能。只是显性地把信息隐藏起来。
Pod使用configmap数据有两种方式: • 变量注入 • 数据卷挂载
kubectl create secret 支持三种数据类型: • docker-registry:存储镜像仓库认证信息 • generic:从文件、目录或者字符串创建,例如存储用户名密码 • tls:存储证书,例如HTTPS证书
1、Opaque Secret
Secret 资源包含2个键值对: data 和 stringData,data 字段用来存储 base64 编码的任意数据。提供 stringData 字段是为了方便,它允许 Secret 使用未编码的字符串。 data 和 stringData 的键必须由字母、数字、-,_ 或 . 组成。
1.创建Secret
(1)通过data字段来创建secret资源对象
💘 实战:通过data字段来创建secret资源对象-2023.1.15(测试成功)

- 实验环境
1实验环境:
21、win10,vmwrokstation虚机;
32、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
4 k8s version:v1.25.4
5 containerd://1.6.10
实验软件(无)
比如我们来创建一个用户名为 admin,密码为 admin321 的
Secret对象,首先我们需要先把用户名和密码做base64编码:
1[root@master1 ~]#echo -n "admin"|base64
2YWRtaW4=
3[root@master1 ~]#echo -n "admin123"|base64
4YWRtaW4xMjM=
5[root@master1 ~]#
- 然后我们就可以利用上面编码过后的数据来编写一个 YAML 文件:
1#secret-demo.yaml
2apiVersion: v1
3kind: Secret
4metadata:
5 name: mysecret
6type: Opaque
7data:
8 username: YWRtaW4=
9 password: YWRtaW4zMjE=
- 然后我们就可以使用 kubectl 命令来创建了:
1[root@master1 ~]#kubectl apply -f secret-demo.yaml
2secret/mysecret created
- 利用
get secret命令查看:
1[root@master1 ~]#kubectl get secrets
2NAME TYPE DATA AGE
3mysecret Opaque 2 11s
- 我们可以使用
describe命令查看详情:
1[root@master1 ~]#kubectl describe secrets mysecret
2Name: mysecret
3Namespace: default
4Labels: <none>
5Annotations: <none>
6
7Type: Opaque
8
9Data
10====
11password: 8 bytes
12username: 5 bytes
- 我们可以看到利用 describe 命令查看到的 Data 没有直接显示出来,如果想看到 Data 里面的详细信息,同样我们可以输出成YAML 文件进行查看:
1[root@master1 ~]#kubectl get secrets mysecret -oyaml
2apiVersion: v1
3data:
4 password: YWRtaW4zMjE=
5 username: YWRtaW4=
6kind: Secret
7metadata:
8 annotations:
9 kubectl.kubernetes.io/last-applied-configuration: |
10 {"apiVersion":"v1","data":{"password":"YWRtaW4zMjE=","username":"YWRtaW4="},"kind":"Secret","metadata":{"annotations":{},"name":"mysecret","namespace":"default"},"type":"Opaque"}
11 creationTimestamp: "2023-01-15T08:22:54Z"
12 name: mysecret
13 namespace: default
14 resourceVersion: "1004608"
15 uid: 91babd64-7169-479e-b24a-2f23dbd5fb7f
16type: Opaque
符合预期,测试结束。😘
(2)通过stringData字段来创建secret资源对象
对于某些场景,你可能希望使用 stringData 字段,这字段可以将一个非 base64 编码的字符串直接放入 Secret 中, 当创建或更新该 Secret 时,此字段将被编码。
💘 实战:通过stringData字段来创建secret资源对象-2023.1.15(测试成功)

- 实验环境
1实验环境:
21、win10,vmwrokstation虚机;
32、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
4 k8s version:v1.25.4
5 containerd://1.6.10
实验软件(无)
比如当我们部署应用时,使用 Secret 存储配置文件, 你希望在部署过程中,填入部分内容到该配置文件。例如,如果你的应用程序使用以下配置文件:
1apiUrl: "https://my.api.com/api/v1"
2username: "<user>"
3password: "<password>"
- 那么我们就可以使用以下定义将其存储在 Secret 中:
1#secret-demo2.yaml
2apiVersion: v1
3kind: Secret
4metadata:
5 name: mysecret2
6type: Opaque
7stringData: #只是为了方便我们去创建Secret对象的,真正创建过后会变成编码过后的data属性
8 config.yaml: |
9 apiUrl: "https://my.api.com/api/v1"
10 username: admin
11 password: admin123
- 比如我们直接创建上面的对象后重新获取对象的话
config.yaml的值会被编码:
1[root@master1 ~]#kubectl apply -f secret-demo2.yaml
2secret/mysecret2 created
3[root@master1 ~]#kubectl get secrets
4NAME TYPE DATA AGE
5mysecret Opaque 2 3h8m
6mysecret2 Opaque 1 6s
7[root@master1 ~]#kubectl get secrets mysecret2 -oyaml
8apiVersion: v1
9data: #注意:控制器会自动帮我们把非编码的values编码成base64,然后放到data属性中去!!!
10 config.yaml: YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IGFkbWluCnBhc3N3b3JkOiBhZG1pbjEyMwo=
11kind: Secret
12metadata:
13 annotations:
14 kubectl.kubernetes.io/last-applied-configuration: |
15 {"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"mysecret2","namespace":"default"},"stringData":{"config.yaml":"apiUrl: \"https://my.api.com/api/v1\"\nusername: admin\npassword: admin123\n"},"type":"Opaque"}
16 creationTimestamp: "2023-01-15T11:31:21Z"
17 name: mysecret2
18 namespace: default
19 resourceVersion: "1022147"
20 uid: 03d4aac1-ba8e-4be1-8239-6bac0619f0e3
21type: Opaque
22
23#注意,依然可以通过base64 -d来解密
24[root@master1 ~]#echo "YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IGFkbWluCnBhc3N3b3JkOiBhZG1pbjEyMwo=" |base64 -d
25apiUrl: "https://my.api.com/api/v1"
26username: admin
27password: admin123
符合预期,测试结束。😘
(3)通过kubectl create命令来创建Opaque类型的Secret资源
- 我们可以先来查看下Secret的帮助信息:
1[root@master1 ~]#kubectl create secret --help
2Create a secret using specified subcommand.
3
4Available Commands:
5 docker-registry Create a secret for use with a Docker registry
6 generic Create a secret from a local file, directory, or literal value
7 tls Create a TLS secret
8
9Usage:
10 kubectl create secret [flags] [options]
11
12Use "kubectl <command> --help" for more information about a given command.
13Use "kubectl options" for a list of global command-line options (applies to all
14commands).
15[root@master1 ~]#kubectl create secret generic --help
16……
17# Create a new secret named my-secret with key1=supersecret and key2=topsecret
18 kubectl create secret generic my-secret --from-literal=key1=supersecret --from-literal=key2=topsecret
19……
💘 实战:通过kubectl create命令来创建Opaque类型的Secret资源-2023.1.15(测试成功)

- 实验环境
1实验环境:
21、win10,vmwrokstation虚机;
32、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
4 k8s version:v1.25.4
5 containerd://1.6.10
实验软件(无)
创建并查看:
1[root@master1 ~]#kubectl create secret generic my-secret2 --from-literal=key1=supersecret --from-literal=key2=topsecret
2secret/my-secret2 created
3#可以看到,这种命令行方式创建的secret和stringData类型的效果是一样的哦。
4
5
6[root@master1 ~]#kubectl get secrets my-secret2
7NAME TYPE DATA AGE
8my-secret2 Opaque 2 18s
9[root@master1 ~]#kubectl get secrets my-secret2 -oyaml
10apiVersion: v1
11data:
12 key1: c3VwZXJzZWNyZXQ=
13 key2: dG9wc2VjcmV0
14kind: Secret
15metadata:
16 creationTimestamp: "2023-01-15T11:37:32Z"
17 name: my-secret2
18 namespace: default
19 resourceVersion: "1022719"
20 uid: 2f3695df-b8f2-4e33-b643-0188c22e7500
21type: Opaque
22
23
24[root@master1 ~]#echo "c3VwZXJzZWNyZXQ="|base64 -d
25supersecret[root@master1 ~]#echo "dG9wc2VjcmV0"|base64 -d
26topsecret[root@master1 ~]#
符合预期,测试结束。😘
2.使用Secret
创建好 Secret 对象后,有两种方式来使用它:
- 以环境变量的形式
- 以 Volume 的形式挂载
(1)环境变量
💘 实战:以环境变量的形式使用secret-2023.1.15(测试成功)

- 实验环境
1实验环境:
21、win10,vmwrokstation虚机;
32、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
4 k8s version:v1.25.4
5 containerd://1.6.10
实验软件(无)
同样的,我们来使用一个简单的 busybox 镜像来测试下:
1#secret1-pod.yaml
2apiVersion: v1
3kind: Pod
4metadata:
5 name: secret1-pod
6spec:
7 containers:
8 - name: secret1
9 image: busybox
10 command: [ "/bin/sh", "-c", "env" ]
11 env:
12 - name: USERNAME
13 valueFrom:
14 secretKeyRef:
15 name: mysecret
16 key: username
17 - name: PASSWORD
18 valueFrom:
19 secretKeyRef:
20 name: mysecret
21 key: password
22 envFrom:
23 - secretRef:
24 name: mysecret2
主要需要注意的是上面环境变量中定义的 secretKeyRef 字段,和我们前文的 configMapKeyRef 类似,一个是从 Secret 对象中获取,一个是从 ConfigMap 对象中获取。
- 查看下之前创建的secret
1[root@master1 ~]#kubectl get secret mysecret -oyaml
2apiVersion: v1
3data:
4 password: YWRtaW4zMjE=
5 username: YWRtaW4=
6kind: Secret
7metadata:
8 annotations:
9 kubectl.kubernetes.io/last-applied-configuration: |
10 {"apiVersion":"v1","data":{"password":"YWRtaW4zMjE=","username":"YWRtaW4="},"kind":"Secret","metadata":{"annotations":{},"name":"mysecret","namespace":"default"},"type":"Opaque"}
11 creationTimestamp: "2023-01-15T08:22:54Z"
12 name: mysecret
13 namespace: default
14 resourceVersion: "1004608"
15 uid: 91babd64-7169-479e-b24a-2f23dbd5fb7f
16type: Opaque
17
18[root@master1 ~]#kubectl get secrets mysecret2 -oyaml
19apiVersion: v1
20data:
21 config.yaml: YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IGFkbWluCnBhc3N3b3JkOiBhZG1pbjEyMwo=
22kind: Secret
23metadata:
24 annotations:
25 kubectl.kubernetes.io/last-applied-configuration: |
26 {"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"mysecret2","namespace":"default"},"stringData":{"config.yaml":"apiUrl: \"https://my.api.com/api/v1\"\nusername: admin\npassword: admin123\n"},"type":"Opaque"}
27 creationTimestamp: "2023-01-15T11:31:21Z"
28 name: mysecret2
29 namespace: default
30 resourceVersion: "1022147"
31 uid: 03d4aac1-ba8e-4be1-8239-6bac0619f0e3
32type: Opaque
- 创建上面的 Pod:
1[root@master1 ~]#kubectl apply -f secret1-pod.yaml
2pod/secret1-pod created
- 然后我们查看Pod的日志输出:
1[root@master1 ~]#kubectl get po secret1-pod
2NAME READY STATUS RESTARTS AGE
3secret1-pod 0/1 CrashLoopBackOff 1 (26s ago) 61s
4
5[root@master1 ~]#kubectl logs secret1-pod
6KUBERNETES_SERVICE_PORT=443
7KUBERNETES_PORT=tcp://10.96.0.1:443
8HOSTNAME=secret1-pod
9config.yaml=apiUrl: "https://my.api.com/api/v1"
10username: admin
11password: admin123
12
13SHLVL=1
14HOME=/root
15USERNAME=admin
16KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
17PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
18KUBERNETES_PORT_443_TCP_PORT=443
19KUBERNETES_PORT_443_TCP_PROTO=tcp
20KUBERNETES_SERVICE_PORT_HTTPS=443
21KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
22KUBERNETES_SERVICE_HOST=10.96.0.1
23PWD=/
24PASSWORD=admin321
可以看到有 USERNAME 和 PASSWORD 两个环境变量输出出来,以及mysecret2里的内容也会被打印出来的。
符合预期,测试结束。😘
(2)Volume 挂载
💘 实战:以volume挂载的形式使用secret-2023.1.15(测试成功)

- 实验环境
1实验环境:
21、win10,vmwrokstation虚机;
32、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
4 k8s version:v1.25.4
5 containerd://1.6.10
实验软件(无)
同样的我们用一个 Pod 来验证下
Volume挂载,创建一个 Pod 文件:
1#secret2-pod.yaml
2apiVersion: v1
3kind: Pod
4metadata:
5 name: secret2-pod
6spec:
7 containers:
8 - name: secret2
9 image: busybox
10 command: ["/bin/sh", "-c", "ls /etc/secrets;sleep 600"]
11 volumeMounts:
12 - name: secrets
13 mountPath: /etc/secrets
14 volumes:
15 - name: secrets
16 secret:
17 secretName: mysecret
- 我们来看一下前面创建的secret
1[root@master1 ~]#kubectl get secrets mysecret -oyaml
2apiVersion: v1
3data:
4 password: YWRtaW4zMjE=
5 username: YWRtaW4=
6kind: Secret
7metadata:
8 annotations:
9 kubectl.kubernetes.io/last-applied-configuration: |
10 {"apiVersion":"v1","data":{"password":"YWRtaW4zMjE=","username":"YWRtaW4="},"kind":"Secret","metadata":{"annotations":{},"name":"mysecret","namespace":"default"},"type":"Opaque"}
11 creationTimestamp: "2023-01-15T08:22:54Z"
12 name: mysecret
13 namespace: default
14 resourceVersion: "1004608"
15 uid: 91babd64-7169-479e-b24a-2f23dbd5fb7f
16type: Opaque
- 创建 Pod,然后查看输出日志:
1[root@master1 ~]#kubectl apply -f secret2-pod.yaml
2pod/secret2-pod created
3[root@master1 ~]#kubectl get po --watch
4NAME READY STATUS RESTARTS AGE
5secret2-pod 0/1 ContainerCreating 0 6s
6secret2-pod 1/1 Running 0 23s
7^C
8
9[root@master1 ~]#kubectl logs secret2-pod
10password
11username
12[root@master1 ~]#kubectl exec secret2-pod -- cat /etc/secrets/username #进到容器里面可以看到2个文件的内容
13admin[root@master1 ~]#kubectl exec secret2-pod -- cat /etc/secrets/password
14admin123[root@master1 ~]#
可以看到 Secret 把两个 key 挂载成了两个对应的文件。
- 当然如果想要挂载到指定的文件上面,是不是也可以使用上一节课的方法:在
secretName下面添加items指定key和path,这个大家可以参考上节课ConfigMap中的方法去测试下。
这里我们来再测试下:
参考ConfigMap用例:
12.编写pod资源清单
2[root@master1 ~]#vim secret3-pod.yaml
3apiVersion: v1
4kind: Pod
5metadata:
6 name: secret3-pod
7 namespace: default
8spec:
9 containers:
10 - name: secret3
11 image: busybox
12 command: ["/bin/sh", "-c", "ls /etc/secrets/path/to/;sleep 600"]
13 volumeMounts:
14 - name: secrets
15 mountPath: /etc/secrets
16 volumes:
17 - name: secrets
18 secret:
19 secretName: mysecret
20 items:
21 - key: username
22 path: path/to/username
23 - key: password
24 path: path/to/password
25
263.部署并查看
27[root@master1 ~]#kubectl apply -f secret3-pod.yaml
28pod/secret3-pod created
29[root@master1 ~]#kubectl get po --watch
30NAME READY STATUS RESTARTS AGE
31secret3-pod 0/1 ContainerCreating 0 4s
32secret3-pod 1/1 Running 0 20s
33^C
34
35[root@master1 ~]#kubectl logs secret3-pod
36password
37username
38[root@master1 ~]#kubectl exec secret3-pod -- cat /etc/secrets/path/to/username
39admin[root@master1 ~]#kubectl exec secret3-pod -- cat /etc/secrets/path/to/password
40admin321[root@master1 ~]#
符合预期,测试结束。😘
案例:部署mysql pod并引用secret
==💘 实战:部署mysql pod并引用secret-2023.6.3(测试成功)==
- 实验环境
1实验环境:
21、win10,vmwrokstation虚机;
32、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
4 k8s version:v1.20.0
5 docker://20.10.7
- 实验软件(无)
1、编写yaml
1#获取mysql-root-password密码
2[root@k8s-master1 ~]#echo -n 123456|base64 #-n不输出尾随换行符
3MTIzNDU2
4
5[root@k8s-master1 ~]#vim mysql-pod-secret.yaml
6apiVersion: v1
7kind: Secret
8metadata:
9 name: mysql
10type: Opaque
11data:
12 mysql-root-password: "MTIzNDU2"
13---
14#mysql-pod-secret.yaml
15apiVersion: apps/v1
16kind: Deployment
17metadata:
18 name: mysql
19spec:
20 selector:
21 matchLabels:
22 app: mysql
23 template:
24 metadata:
25 labels:
26 app: mysql
27 spec:
28 containers:
29 - image: mysql:5.7.30
30 name: db
31 env:
32 - name: MYSQL_ROOT_PASSWORD
33 valueFrom:
34 secretKeyRef:
35 name: mysql
36 key: mysql-root-password
37
38#部署
39[root@k8s-master1 ~]#kubectl apply -f mysql-pod-secret.yaml
40secret/mysql created
41deployment.apps/mysql created

必须要设置这个变量,否则mysql容器是起不来的。
2、测试
1[root@k8s-master1 ~]#kubectl get secrets |grep mysql
2mysql Opaque
3[root@k8s-master1 ~]#kubectl get po
4NAME READY STATUS RESTARTS AGE
5mysql-5467bf5d7d-zgvg4 1/1 Running 0 86s
6[root@k8s-master1 ~]#kubectl exec -it mysql-5467bf5d7d-zgvg4 -- bash
7root@mysql-5467bf5d7d-zgvg4:/# mysql -uroot -p123456
8mysql: [Warning] Using a password on the command line interface can be insecure.
9Welcome to the MySQL monitor. Commands end with ; or \g.
10Your MySQL connection id is 2
11Server version: 5.7.30 MySQL Community Server (GPL)
12
13Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
14
15Oracle is a registered trademark of Oracle Corporation and/or its
16affiliates. Other names may be trademarks of their respective
17owners.
18
19Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
20
21mysql> show databases;
22+--------------------+
23| Database |
24+--------------------+
25| information_schema |
26| mysql |
27| performance_schema |
28| sys |
29+--------------------+
304 rows in set (0.00 sec)
31
32mysql>
33或者:
34root@mysql-5467bf5d7d-zgvg4:/# mysql -uroot -p$MYSQL_ROOT_PASSWORD #这里写上变量也是可以的。
35mysql: [Warning] Using a password on the command line interface can be insecure.
36Welcome to the MySQL monitor. Commands end with ; or \g.
37Your MySQL connection id is 3
38Server version: 5.7.30 MySQL Community Server (GPL)
39
40Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
41
42Oracle is a registered trademark of Oracle Corporation and/or its
43affiliates. Other names may be trademarks of their respective
44owners.
45
46Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
47
48mysql> show databases;
49+--------------------+
50| Database |
51+--------------------+
52| information_schema |
53| mysql |
54| performance_schema |
55| sys |
56+--------------------+
574 rows in set (0.00 sec)
58
59mysql>
测试结束。😘
2、kubernetes.io/dockerconfigjson
可以先来查看下帮助信息:
1[root@master1 ~]#kubectl create secret docker-registry --help
2Create a new secret for use with Docker registries.
3
4 Dockercfg secrets are used to authenticate against Docker registries.
5
6 When using the Docker command line to push images, you can authenticate to a given registry by running:
7 '$ docker login DOCKER_REGISTRY_SERVER --username=DOCKER_USER --password=DOCKER_PASSWORD --email=DOCKER_EMAIL'.
8
9 That produces a ~/.dockercfg file that is used by subsequent 'docker push' and 'docker pull' commands to authenticate
10to the registry. The email address is optional.
11
12 When creating applications, you may have a Docker registry that requires authentication. In order for the
13 nodes to pull images on your behalf, they must have the credentials. You can provide this information
14 by creating a dockercfg secret and attaching it to your service account.
15
16Examples:
17 # If you don't already have a .dockercfg file, you can create a dockercfg secret directly by using:
18 kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER
19--docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
20
21 # Create a new secret named my-secret from ~/.docker/config.json
22 kubectl create secret docker-registry my-secret --from-file=.dockerconfigjson=path/to/.docker/config.json
23
24Options:
25 --allow-missing-template-keys=true: If true, ignore any errors in templates when a field or map key is missing in
26the template. Only applies to golang and jsonpath output formats.
27 --append-hash=false: Append a hash of the secret to its name.
28 --docker-email='': Email for Docker registry
29 --docker-password='': Password for Docker registry authentication
30 --docker-server='https://index.docker.io/v1/': Server location for Docker registry
31 --docker-username='': Username for Docker registry authentication
32 --dry-run='none': Must be "none", "server", or "client". If client strategy, only print the object that would be
33sent, without sending it. If server strategy, submit server-side request without persisting the resource.
34 --field-manager='kubectl-create': Name of the manager used to track field ownership.
35 --from-file=[]: Key files can be specified using their file path, in which case a default name will be given to
36them, or optionally with a name and file path, in which case the given name will be used. Specifying a directory will
37iterate each named file in the directory that is a valid secret key.
38 -o, --output='': Output format. One of:
39json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-as-json|jsonpath-file.
40 --save-config=false: If true, the configuration of current object will be saved in its annotation. Otherwise, the
41annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
42 --show-managed-fields=false: If true, keep the managedFields when printing objects in JSON or YAML format.
43 --template='': Template string or path to template file to use when -o=go-template, -o=go-template-file. The
44template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
45 --validate=true: If true, use a schema to validate the input before sending it
46
47Usage:
48 kubectl create secret docker-registry NAME --docker-username=user --docker-password=password --docker-email=email
49[--docker-server=string] [--from-file=[key=]source] [--dry-run=server|client|none] [options]
50
51Use "kubectl options" for a list of global command-line options (applies to all commands).
1.通过kubectl create命令的方式来创建镜像仓库认证信息
💘 实战:通过kubectl create命令的方式来创建镜像仓库认证信息-2023.1.15(测试成功)
- 实验环境
1实验环境:
21、win10,vmwrokstation虚机;
32、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
4 k8s version:v1.25.4
5 containerd://1.6.10
- 实验软件(无)
除了上面的 Opaque 这种类型外,我们还可以来创建用户 docker registry 认证的 Secret,直接使用``kubectl create` 命令创建即可,如下:
1#创建
2[root@master1 ~]#kubectl create secret docker-registry myregistry --docker-server=DOCKER_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
3secret/myregistry created
4
5#查看
6[root@master1 ~]#kubectl get secret myregistry
7NAME TYPE DATA AGE
8myregistry kubernetes.io/dockerconfigjson 1 14s
9[root@master1 ~]#kubectl get secret myregistry -oyaml
10apiVersion: v1
11data:
12 .dockerconfigjson: eyJhdXRocyI6eyJET0NLRVJfU0VSVkVSIjp7InVzZXJuYW1lIjoiRE9DS0VSX1VTRVIiLCJwYXNzd29yZCI6IkRPQ0tFUl9QQVNTV09SRCIsImVtYWlsIjoiRE9DS0VSX0VNQUlMIiwiYXV0aCI6IlJFOURTMFZTWDFWVFJWSTZSRTlEUzBWU1gxQkJVMU5YVDFKRSJ9fX0=
13kind: Secret
14metadata:
15 creationTimestamp: "2023-01-15T13:50:01Z"
16 name: myregistry
17 namespace: default
18 resourceVersion: "1035322"
19 uid: 481ddb22-c793-4899-971f-96e64e1d933e
20type: kubernetes.io/dockerconfigjson
测试结束。😘
2.通过指定文件的方式来创建镜像仓库认证信息
💘 实战:通过指定文件的方式来创建镜像仓库认证信息-2023.1.15(测试成功)
- 实验环境
1实验环境:
21、win10,vmwrokstation虚机;
32、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
4 k8s version:v1.25.4
5 containerd://1.6.10
实验软件(无)
除了上面这种方法之外,我们也可以通过指定文件的方式来创建镜像仓库认证信息,需要注意对应的
KEY和TYPE:
1kubectl create secret generic myregistry --from-file=.dockerconfigjson=/root/.docker/config.json --type=kubernetes.io/dockerconfigjson
- 我们在docker机器上查下本次我的是有仓库的
~/.docker/config.json信息:
1[root@docker ~]#cat ~/.docker/config.json
2{
3 "auths": {
4 "registry.cn-hangzhou.aliyuncs.com": {
5 "auth": "5omn5qyh5LiA55Sf5L……nQGNyMjAyMSE=" #哈哈,我这里略去了,懂的都懂。
6 }
7 }
8}[root@docker ~]#
注意:本次我们使用第一种方法来验证我们的实验结果
- 通过
kubecrate craete命令来创建kubernetes.io/dockerconfigjson类型的secret
1[root@master1 ~]#kubectl create secret docker-registry myregistry --docker-server=DOCKER_SERVER --docker-username=DOCKER_USE --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
2secret/myregistry created
- 然后查看 Secret 列表:
1[root@master1 ~]#kubectl get secrets
2NAME TYPE DATA AGE
3default-token-mb5fw kubernetes.io/service-account-token 3 27d
4my-secret Opaque 2 27m
5myregistry kubernetes.io/dockerconfigjson 1 26s
6mysecret Opaque 2 11h
注意看上面的 TYPE 类型,myregistry 对应的是 kubernetes.io/dockerconfigjson。
- 同样的可以使用 describe 命令来查看详细信息:
1[root@master1 ~]#kubectl describe secrets myregistry
2Name: myregistry
3Namespace: default
4Labels: <none>
5Annotations: <none>
6
7Type: kubernetes.io/dockerconfigjson
8
9Data
10====
11.dockerconfigjson: 151 bytes
- 同样的可以看到 Data 区域没有直接展示出来,如果想查看的话可以使用
-o yaml来输出展示出来:
1[root@master1 ~]#kubectl get secrets myregistry -oyaml
2apiVersion: v1
3data:
4 .dockerconfigjson: eyJhdXRocyI6eyJET0NLRVJfU0VSVkVSIjp7InVzZXJuYW1lIjoiRE9DS0VSX1VTRSIsInBhc3N3b3JkIjoiRE9DS0VSX1BBU1NXT1JEIiwiZW1haWwiOiJET0NLRVJfRU1BSUwiLCJhdXRoIjoiUkU5RFMwVlNYMVZUUlRwRVQwTkxSVkpmVUVGVFUxZFBVa1E9In19fQ==
5kind: Secret
6metadata:
7 creationTimestamp: "2021-11-27T02:23:04Z"
8 name: myregistry
9 namespace: default
10 resourceVersion: "623316"
11 uid: c26d27e4-5a88-4db7-aa43-f3295e178ed4
12type: kubernetes.io/dockerconfigjson
- 可以把上面的
data.dockerconfigjson下面的数据做一个base64解码,看看里面的数据是怎样的呢?
1[root@master1 ~]#echo "eyJhdXRocyI6eyJET0NLRVJfU0VSVkVSIjp7InVzZXJuYW1lIjoiRE9DS0VSX1VTRSIsInBhc3N3b3JkIjoiRE9DS0VSX1BBU1NXT1JEIiwiZW1haWwiOiJET0NLRVJfRU1BSUwiLCJhdXRoIjoiUkU5RFMwVlNYMVZUUlRwRVQwTkxSVkpmVUVGVFUxZFBVa1E9In19fQ==" |base64 -d
2{"auths":{"DOCKER_SERVER":{"username":"DOCKER_USE","password":"DOCKER_PASSWORD","email":"DOCKER_EMAIL","auth":"RE9DS0VSX1VTRTpET0NLRVJfUEFTU1dPUkQ="}}}[root@master1 ~]#
- 如果我们需要拉取私有仓库中的 Docker 镜像的话就需要使用到上面的 myregistry 这个
Secret:
我们需要拉取私有仓库镜像 172.29.9.100:5000/test:v1,我们就需要针对该私有仓库来创建一个如上的 Secret,然后在 Pod 中指定 imagePullSecrets。
1#private-image.yaml
2apiVersion: v1
3kind: Pod
4metadata:
5 name: private-image
6 namespace: default
7spec:
8 imagePullSecrets:
9 - name: myregistry #这个secrets只属于namespaces级别
10 containers:
11 - name: foo
12 image: 172.29.9.100:5000/test:v1
注意:
ImagePullSecrets与Secrets不同,因为Secrets可以挂载到 Pod 中,但是ImagePullSecrets只能由 Kubelet 访问。
- 除了设置
Pod.spec.imagePullSecrets这种方式来获取私有镜像之外,我们还可以通过在ServiceAccount中设置imagePullSecrets,然后就会自动为使用该 SA 的 Pod 注入imagePullSecrets信息:
1apiVersion: v1
2kind: ServiceAccount
3metadata:
4 name: default
5 namespace: default
6secrets:
7 - name: default-token-5tsh4
8imagePullSecrets:
9 - name: myregistry
实验结束。
3、kubernetes.io/basic-auth
该类型用来存放用于基本身份认证所需的凭据信息,使用这种 Secret 类型时,Secret 的 data 字段或者stringData(不一定)必须包含以下两个键(相当于是一个约定速成的一个规定):
username: 用于身份认证的用户名password: 用于身份认证的密码或令牌
以上两个键的键值都是 base64 编码的字符串。 然你也可以在创建 Secret 时使用 stringData 字段来提供明文形式的内容。
💘 实战:kubernetes.io/basic-auth测试-2023.1.16(测试成功)
- 实验环境
1实验环境:
21、win10,vmwrokstation虚机;
32、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
4 k8s version:v1.25.4
5 containerd://1.6.10
- 实验软件(无)
下面的 YAML 是基本身份认证 Secret 的一个示例清单:
- 创建资源清单文件并部署测试
1#secret-basic-auth.yaml
2apiVersion: v1
3kind: Secret
4metadata:
5 name: secret-basic-auth
6type: kubernetes.io/basic-auth
7stringData:
8 username: admin
9 password: admin321
10
11[root@master1 ~]#kubectl apply -f secret-basic-auth.yaml
12secret/secret-basic-auth created
13[root@master1 ~]#kubectl get secrets secret-basic-auth
14NAME TYPE DATA AGE
15secret-basic-auth kubernetes.io/basic-auth 2 21s
16[root@master1 ~]#kubectl get secrets secret-basic-auth -oyaml
17apiVersion: v1
18data:
19 password: YWRtaW4zMjE= #这里的效果相当于Opaque类型的stringData功能。
20 username: YWRtaW4=
21kind: Secret
22metadata:
23 annotations:
24 kubectl.kubernetes.io/last-applied-configuration: |
25 {"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"secret-basic-auth","namespace":"default"},"stringData":{"password":"admin321","username":"admin"},"type":"kubernetes.io/basic-auth"}
26 creationTimestamp: "2021-11-27T06:54:59Z"
27 name: secret-basic-auth
28 namespace: default
29 resourceVersion: "646214"
30 uid: b39573a4-8ef2-42db-8206-84e0d68a9602
31type: kubernetes.io/basic-auth
提供基本身份认证类型的 Secret 仅仅是出于用户方便性考虑,我们也可以使用 Opaque 类型来保存用于基本身份认证的凭据,不过使用内置的 Secret 类型的有助于对凭据格式进行统一处理。
- 创建资源清单文件并部署测试(本次修改下key的值为
username0,我们看下效果)
1[root@master1 ~]#cp secret-basic-auth.yaml secret-basic-auth2.yaml
2[root@master1 ~]#vim secret-basic-auth2.yaml
3apiVersion: v1
4kind: Secret
5metadata:
6 name: secret-basic-auth2
7type: kubernetes.io/basic-auth
8stringData:
9 username0: admin
10 password: admin321
11
12[root@master1 ~]#kubectl apply -f secret-basic-auth2.yaml
13secret/secret-basic-auth2 created
14[root@master1 ~]#kubectl get secrets secret-basic-auth2
15NAME TYPE DATA AGE
16secret-basic-auth2 kubernetes.io/basic-auth 2 8s
17[root@master1 ~]#kubectl get secrets secret-basic-auth2 -oyaml
18apiVersion: v1
19data:
20 password: YWRtaW4zMjE=
21 username0: YWRtaW4= #符合前面描述的,这里不一定必须是`username`和`password`
22kind: Secret
23metadata:
24 annotations:
25 kubectl.kubernetes.io/last-applied-configuration: |
26 {"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"secret-basic-auth2","namespace":"default"},"stringData":{"password":"admin321","username0":"admin"},"type":"kubernetes.io/basic-auth"}
27 creationTimestamp: "2021-11-27T06:58:16Z"
28 name: secret-basic-auth2
29 namespace: default
30 resourceVersion: "646489"
31 uid: 516392cb-92ba-4111-a3dc-532f38855f5a
32type: kubernetes.io/basic-auth
33[root@master1 ~]#
实验结束。😘
4、kubernetes.io/ssh-auth
该类型用来存放 SSH 身份认证中所需要的凭据,使用这种 Secret 类型时,你就(不一定)必须在其 data(或 stringData)字段中提供一个ssh-privatekey 键值对,作为要使用的 SSH 凭据。
如下所示是一个 SSH 身份认证 Secret 的配置示例:
1apiVersion: v1
2kind: Secret
3metadata:
4 name: secret-ssh-auth
5type: kubernetes.io/ssh-auth
6data:
7 ssh-privatekey: |
8 MIIEpQIBAAKCAQEAulqb/Y ...
同样提供 SSH 身份认证类型的 Secret 也仅仅是出于用户方便性考虑,我们也可以使用 Opaque 类型来保存用于 SSH 身份认证的凭据,只是使用内置的 Secret 类型的有助于对凭据格式进行统一处理。
5、kubernetes.io/tls
该类型用来存放证书及其相关密钥(通常用在 TLS 场合),一般是https证书。此类数据主要提供给 Ingress 资源,用以校验 TLS 链接,当使用此类型的 Secret 时,Secret 配置中的 data (或 stringData)字段必须包含 tls.key 和 tls.crt主键。下面的 YAML 包含一个 TLS Secret 的配置示例:
1apiVersion: v1
2kind: Secret
3metadata:
4 name: secret-tls
5type: kubernetes.io/tls
6data:
7 tls.crt: |
8 MIIC2DCCAcCgAwIBAgIBATANBgkqh ...
9 tls.key: |
10 MIIEpgIBAAKCAQEA7yn3bRHQ5FHMQ ...
提供 TLS 类型的 Secret 仅仅是出于用户方便性考虑,我们也可以使用 Opaque 类型来保存用于 TLS 服务器与/或客户端的凭据。不过,使用内置的 Secret 类型的有助于对凭据格式进行统一化处理。当使用 kubectl 来创建 TLS Secret 时,我们可以像下面的例子一样使用 tls 子命令:
1➜ ~ kubectl create secret tls my-tls-secret \
2 --cert=path/to/cert/file \
3 --key=path/to/key/file
需要注意的是用于
--cert的公钥证书必须是.PEM编码的 (Base64 编码的 DER 格式),且与--key所给定的私钥匹配,私钥必须是通常所说的 PEM 私钥格式,且未加密。对这两个文件而言,PEM 格式数据的第一行和最后一行(例如,证书所对应的--------BEGIN CERTIFICATE-----和-------END CERTIFICATE----)都不会包含在其中。
- 案例




6、kubernetes.io/service-account-token
老版本
另外一种 Secret 类型就是 kubernetes.io/service-account-token,用于被 ServiceAccount 引用。ServiceAccout 创建时 Kubernetes 会默认创建对应的 Secret,如下所示我们随意创建一个 Pod:
1[root@master1 ~]#kubectl run secret-pod3 --image=nginx:1.7.9
2pod/secret-pod3 created
3[root@master1 ~]#kubectl get po
4NAME READY STATUS RESTARTS AGE
5secret-pod3 1/1 Running 0 16s
6……
7[root@master1 ~]#
我们可以直接查看这个 Pod 的详细信息:
1[root@master1 ~]#kubectl get po secret-pod3 -oyaml
2……
3 serviceAccount: default
4 serviceAccountName: default
5
6spec:
7 containers:
8 - image: nginx:1.7.9
9 imagePullPolicy: IfNotPresent
10 name: secret-pod3
11 resources: {}
12 terminationMessagePath: /dev/termination-log
13 terminationMessagePolicy: File
14 volumeMounts:
15 - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
16 name: kube-api-access-6h78t
17 readOnly: true
18……
19 volumes:
20 - name: kube-api-access-6h78t
21 projected:
22 defaultMode: 420
23 sources:
24 - serviceAccountToken:
25 expirationSeconds: 3607
26 path: token
27 - configMap:
28 items:
29 - key: ca.crt
30 path: ca.crt
31 name: kube-root-ca.crt
32 - downwardAPI:
33 items:
34 - fieldRef:
35 apiVersion: v1
36 fieldPath: metadata.namespace
37 path: namespace
当创建 Pod 的时候,如果没有指定 ServiceAccount,Pod 则会使用命名空间中名为 default 的 ServiceAccount,上面我们可以看到 spec.serviceAccountName 字段已经被自动设置了。
我们再来查看下信息:
1我们进入到这个容器中:
2[root@master1 ~]#kubectl exec -it secret-pod3 -- bash
3root@secret-pod3:/# cd /var/run/secrets/kubernetes.io/serviceaccount/
4root@secret-pod3:/var/run/secrets/kubernetes.io/serviceaccount# ls
5ca.crt namespace token
6root@secret-pod3:/var/run/secrets/kubernetes.io/serviceaccount# cat namespace
7defaultroot@secret-pod3:/var/run/secrets/kubernetes.io/serviceaccount#
8root@secret-pod3:/var/run/secrets/kubernetes.io/serviceaccount# cat ca.crt
9-----BEGIN CERTIFICATE-----
10MIIC/jCCAeagAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl
11cm5ldGVzMB4XDTIxMTAzMDIzNTY1MFoXDTMxMTAyODIzNTY1MFowFTETMBEGA1UE
12AxMKa3ViZXJuZXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMP0
13xMRZPSPAGKvSECShcwwaUFJmht6F1MGV8cG27mor8+JdmYLLO64Kkblcwnxflcj/
146UzdFuOW+pxe/9a+7M4tHKrpQgiydLu5peGj8FJHsjzGnOigNss978+714RGRhIN
15JAp9JWX9tpgaOaupY367nQ3aBLt2nl+9t2FELzxAQ99w4COt95/Rv8B4E0UgGP/V
16/q9N447VjkDzZr2AF9gfv2RvGq1307KDy7UHxkDG86WAvd1qigkTsIYkPEAaTllZ
17u7/xnhJt+CBCD7C1oHtAD5fcJT6hQS+qYPchP9x3voP/UaHtg4rUP8QDc88/FBDh
18yiB7L6jfRvQrn7bR+98CAwEAAaNZMFcwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB
19/wQFMAMBAf8wHQYDVR0OBBYEFD0FWPf+WxR7twmDA9lmAjspE/YJMBUGA1UdEQQO
20MAyCCmt1YmVybmV0ZXMwDQYJKoZIhvcNAQELBQADggEBAEoI7y1Qj8ALqXWwaTJw
21id9wReTJPF860GP4C1Ktxt3SEJEqB6He8zkZSrTYUIoYT0K+IYMapWf1GaftToiJ
22LjOR5UXIsfZrsl042lbnLKSOoxhhY8qEziz7iLK9VSINCbz+Qeuo0SgqEibwGW+K
23SPHEbeajOf8Q7rHv/k41koZWz6qQGvaLQ1ob8ilDNcO41AAAGM6jFL2HYmVJIGCL
248G61+/cMShAim0EFkJS9M4Hw3JR2AzpzvprzoX0zhzbvo5+r5jdXyAUUcWz194Is
25RclaCGlyRrdJnceZ4E2wEHdx2BCcrs76Qo6SkpxPcRMIcd9lpjiJRE97oZP1Jm/I
263/4=
27-----END CERTIFICATE-----
28root@secret-pod3:/var/run/secrets/kubernetes.io/serviceaccount#
29[root@master1 ~]#kubectl get cm
30NAME DATA AGE
31cm-demo1 2 3d15h
32cm-demo2 1 3d14h
33cm-demo3 2 3d14h
34kube-root-ca.crt 1 27d
35[root@master1 ~]#kubectl describe cm kube-root-ca.crt
36Name: kube-root-ca.crt
37Namespace: default
38Labels: <none>
39Annotations: kubernetes.io/description:
40 Contains a CA bundle that can be used to verify the kube-apiserver when using internal endpoints such as the internal service IP or kubern...
41
42Data
43====
44ca.crt:
45----
46-----BEGIN CERTIFICATE-----
47MIIC/jCCAeagAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl
48cm5ldGVzMB4XDTIxMTAzMDIzNTY1MFoXDTMxMTAyODIzNTY1MFowFTETMBEGA1UE
49AxMKa3ViZXJuZXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMP0
50xMRZPSPAGKvSECShcwwaUFJmht6F1MGV8cG27mor8+JdmYLLO64Kkblcwnxflcj/
516UzdFuOW+pxe/9a+7M4tHKrpQgiydLu5peGj8FJHsjzGnOigNss978+714RGRhIN
52JAp9JWX9tpgaOaupY367nQ3aBLt2nl+9t2FELzxAQ99w4COt95/Rv8B4E0UgGP/V
53/q9N447VjkDzZr2AF9gfv2RvGq1307KDy7UHxkDG86WAvd1qigkTsIYkPEAaTllZ
54u7/xnhJt+CBCD7C1oHtAD5fcJT6hQS+qYPchP9x3voP/UaHtg4rUP8QDc88/FBDh
55yiB7L6jfRvQrn7bR+98CAwEAAaNZMFcwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB
56/wQFMAMBAf8wHQYDVR0OBBYEFD0FWPf+WxR7twmDA9lmAjspE/YJMBUGA1UdEQQO
57MAyCCmt1YmVybmV0ZXMwDQYJKoZIhvcNAQELBQADggEBAEoI7y1Qj8ALqXWwaTJw
58id9wReTJPF860GP4C1Ktxt3SEJEqB6He8zkZSrTYUIoYT0K+IYMapWf1GaftToiJ
59LjOR5UXIsfZrsl042lbnLKSOoxhhY8qEziz7iLK9VSINCbz+Qeuo0SgqEibwGW+K
60SPHEbeajOf8Q7rHv/k41koZWz6qQGvaLQ1ob8ilDNcO41AAAGM6jFL2HYmVJIGCL
618G61+/cMShAim0EFkJS9M4Hw3JR2AzpzvprzoX0zhzbvo5+r5jdXyAUUcWz194Is
62RclaCGlyRrdJnceZ4E2wEHdx2BCcrs76Qo6SkpxPcRMIcd9lpjiJRE97oZP1Jm/I
633/4=
64-----END CERTIFICATE-----
65
66
67BinaryData
68====
69
70Events: <none>
71[root@master1 ~]#
72
73
74
75root@secret-pod3:/var/run/secrets/kubernetes.io/serviceaccount# cat token
76eyJhbGciOiJSUzI1NiIsImtpZCI6Im9hOERROHhuWTRSeVFweG1kdnpXSTRNNXg3bDZ0ZkRDVWNzN0l5Z0haT1UifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjY5NTI0MzEyLCJpYXQiOjE2Mzc5ODgzMTIsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0IiwicG9kIjp7Im5hbWUiOiJzZWNyZXQtcG9kMyIsInVpZCI6ImQzYTg4N2M3LWRmNmItNGZhZi05N2Y0LWFhNDAwNTJhMzU3ZSJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVmYXVsdCIsInVpZCI6IjRhNDY3NGJlLTQwZGItNDFhMC04NGVhLTgzMmM0YTI5YjAyZSJ9LCJ3YXJuYWZ0ZXIiOjE2Mzc5OTE5MTl9LCJuYmYiOjE2Mzc5ODgzMTIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.Ki_cUUrExymQKqLBeKl_CkubgyG-NYPycDHWODPNG942FWhGdQrrMrkg2z_v4tpwr3DpGgIQDGYlPUwiM_c7Ey4lbRfCQ7c7nW96a0zkfDHAwdLx4Yf6TeRRaBNrfetiF9taUExDuLGfgt8Fx1Av7QR38uiFzdOCPnfa65NZgxV91sE49bKWrRY4mkjku1DxorKW-UqK94cKl7s9yJUqElwzb64PL90SGhS5ipLg5M0Rd_0gGFp49T7ZYJgBLbIWb3085M5njtgf-LKXqrDUlzh14Kb1Bpzzq835ksdJnM2vLIDoZhMdtkNZOBKvXu85ZvleNIA2LcYEZecdY0ulFwroot@secret-pod3:/var/run/secrets/kubernetes.io/serviceaccount#
77root@secret-pod3:/var/run/secrets/kubernetes.io/serviceaccount#
78
79
80[root@master1 ~]#kubectl describe secrets default-token-mb5fw #这个token值好像不一样。。。。
81Name: default-token-mb5fw
82Namespace: default
83Labels: <none>
84Annotations: kubernetes.io/service-account.name: default
85 kubernetes.io/service-account.uid: 4a4674be-40db-41a0-84ea-832c4a29b02e
86
87Type: kubernetes.io/service-account-token
88
89Data
90====
91ca.crt: 1099 bytes
92namespace: 7 bytes
93token: eyJhbGciOiJSUzI1NiIsImtpZCI6Im9hOERROHhuWTRSeVFweG1kdnpXSTRNNXg3bDZ0ZkRDVWNzN0l5Z0haT1UifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tbWI1ZnciLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjRhNDY3NGJlLTQwZGItNDFhMC04NGVhLTgzMmM0YTI5YjAyZSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.q55oyF7sYFX_1EsVHPSzu-fvLuFWvb4aqfXjThZ-ix0hMuNtTfOitZ5tCeIsRRVcmMu274VTrXhDACYQDuVI5eVryJAFBUD7tf_uI2gBnIk2uLZCOsEfSCSEw0_KvHdiOTk0d83DXyZRIsq0xlx6en5flye5TgEsW3SWgbM3O5FAKsKYr-I8sjGRhg0VCaNOhc1tnMGhHdzaPIY3Iirs-b5Wws8Sf6PUe5YKK5wwiUlVoJkwzZmquX33OQvhZZCN06bLFd963DGEb5yGQr6MilmhsrYUskEBWJQZH-tDEeI6zO4jJxW4aWb1ZsGaDNb82dksEeLYPQcGVo97CWoL2Q
94[root@master1 ~]#
可以看到这里通过一个 projected 类型(你可以认为它是一个聚合)的 Volume 挂载到了容器的 /var/run/secrets/kubernetes.io/serviceaccount 的目录中,projected 类型的 Volume 可以同时挂载多个来源的数据,这里我们挂载了一个 downwardAPI 来获取 namespace,通过 ConfigMap 来获取 ca.crt 证书,然后还有一个 serviceAccountToken 类型的数据源。
在之前的版本(v1.20)中,是直接将 default(自动创建的)的 ServiceAccount 对应的 Secret 对象通过 Volume 挂载到了容器的 /var/run/secrets/kubernetes.io/serviceaccount 的目录中的,现在的版本提供了更多的配置选项,比如上面我们配置了 expirationSeconds 和 path 两个属性。
前面我们也提到了默认情况下当前 namespace 下面的 Pod 会默认使用 default 这个 ServiceAccount,对应的 Secret 会自动挂载到 Pod 的 /var/run/secrets/kubernetes.io/serviceaccount/ 目录中,这样我们就可以在 Pod 里面获取到用于身份认证的信息了。
我们可以使用自动挂载给 Pod 的 ServiceAccount 凭据访问 API,我们也可以通过在 ServiceAccount 上设置 automountServiceAccountToken: false 来实现不给 ServiceAccount 自动挂载 API 凭据:
1apiVersion: v1
2kind: ServiceAccount
3metadata:
4 name: build-robot
5automountServiceAccountToken: false
6...
此外也可以选择不给特定 Pod 自动挂载 API 凭据:
1apiVersion: v1
2kind: Pod
3metadata:
4 name: my-pod
5spec:
6 serviceAccountName: build-robot
7 automountServiceAccountToken: false
8 ...
如果 Pod 和 ServiceAccount 都指定了 automountServiceAccountToken 值,则 Pod 的 spec 优先于 ServiceAccount。
==ServiceAccount Token 投影==
注意:这个部分的知识点比较不太容易理解🤣。研发可能会比较容易理解些。但是安全性更好,对我们使用起来没什么影响。
ServiceAccount 是 Pod 和集群 apiserver 通讯的访问凭证,传统方式下,在 Pod 中使用 ServiceAccount 可能会遇到如下的安全挑战:
ServiceAccount中的JSON Web Token (JWT)没有绑定 audience 身份,因此所有 ServiceAccount 的使用者都可以彼此扮演,存在伪装攻击的可能;- 传统方式下每一个 ServiceAccount 都需要存储在一个对应的 Secret 中,并且会以文件形式存储在对应的应用节点上,而集群的系统组件在运行过程中也会使用到一些权限很高的 ServiceAccount,其增大了集群管控平面的攻击面,攻击者可以通过获取这些管控组件使用的ServiceAccount非法提权;
- ServiceAccount 中的 JWT token 没有设置过期时间,当上述 ServiceAccount 泄露情况发生时,只能通过轮转 ServiceAccount 的签发私钥来进行防范;
- 每一个 ServiceAccount 都需要创建一个与之对应的 Secret,在大规模的应用部署下存在弹性和容量风险
为解决这个问题 Kubernetes 提供了 ServiceAccount Token 投影特性用于增强 ServiceAccount 的安全性,ServiceAccount 令牌卷投影可使 Pod 支持以卷投影的形式将 ServiceAccount 挂载到容器中从而避免了对 Secret 的依赖。
通过 ServiceAccount 令牌卷投影可用于工作负载的 ServiceAccount 令牌是受时间限制,受 audience 约束的,并且不与 Secret 对象关联。如果删除了Pod或删除了ServiceAccount,则这些令牌将无效,从而可以防止任何误用,Kubelet 还会在令牌即将到期时自动旋转令牌,另外,还可以配置希望此令牌可用的路径。
为了启用令牌请求投射(此功能在Kubernetes 1.12中引入,Kubernetes v1.20 已经稳定版本),你必须为 kube-apiserver 设置以下命令行参数,通过 kubeadm 安装的集群已经默认配置了:
1--service-account-issuer # serviceaccount token 中的签发身份,即token payload中的iss字段。
2--service-account-key-file # token 私钥文件路径
3--service-account-signing-key-file # token 签名私钥文件路径
4--api-audiences (可选参数) # 合法的请求token身份,用于apiserver服务端认证请求token是否合法。
配置完成后就可以指定令牌的所需属性,例如身份和有效时间,这些属性在默认 ServiceAccount 令牌上无法配置。当删除 Pod 或 ServiceAccount 时,ServiceAccount 令牌也将对 API 无效。
我们可以使用名为 ServiceAccountToken 的 ProjectedVolume 类型在 PodSpec 上配置此功能,比如要向 Pod 提供具有 “vault” 用户以及两个小时有效期的令牌,可以在 PodSpec 中配置以下内容:
例如当 Pod 中需要使用 audience 为 vault 并且有效期为2个小时的 ServiceAccount 时,我们可以使用以下模板配置 PodSpec 来使用 ServiceAccount 令牌卷投影。
1apiVersion: v1
2kind: ServiceAccount
3metadata:
4 name: build-robot
5
6---
7apiVersion: v1
8kind: Pod
9metadata:
10 name: nginx
11spec:
12 containers:
13 - image: nginx
14 name: nginx
15 volumeMounts:
16 - mountPath: /var/run/secrets/tokens
17 name: vault-token
18 serviceAccountName: build-robot
19 volumes:
20 - name: vault-token
21 projected:
22 sources:
23 - serviceAccountToken:
24 path: vault-token
25 expirationSeconds: 7200
26 audience: vault
kubelet 件会替 Pod 请求令牌并将其保存起来,通过将令牌存储到一个可配置的路径使之在 Pod 内可用,并在令牌快要到期的时候刷新它。 kubelet 会在令牌存在期达到其 TTL 的 80% 的时候或者令牌生命期超过 24 小时 的时候主动轮换它。应用程序负责在令牌被轮换时重新加载其内容。对于大多数使用场景而言,周期性地 (例如,每隔 5 分钟)重新加载就足够了。
新版本
另外一种 Secret 类型就是 kubernetes.io/service-account-token,用于被 ServiceAccount 引用。
从 v1.22 版本开始,这种类型的 Secret 不再被用来向 Pod 中加载凭据数据,现在可以通过 TokenRequest API 来获得令牌,而不是使用服务账号令牌 Secret 对象。 通过 TokenRequest API 获得的令牌比保存在 Secret 对象中的令牌更加安全,因为这些令牌有着被限定的生命期,并且不会被其他 API 客户端读取,我们可以使用 kubectl createtoken 命令调用 TokenRequest API 获得令牌。
只有在你无法使用 TokenRequest API 来获取令牌,并且你能够接受因为将永不过期的令牌凭据写入到可读取的 API 对象而带来的安全风险时,才应该创建服务账号令牌 Secret 对象。
使用这种 Secret 类型时,你需要确保对象的注解 kubernetes.io/service-account-name 被设置为某个已有的ServiceAccount 名称。如果你同时负责 ServiceAccount 和 Secret 对象的创建,应该先创建 ServiceAccount对象。
当 Secret 对象被创建之后,某个 Kubernetes 控制器会填写 Secret 的其它字段,例如kubernetes.io/service-account.uid 注解以及 data 字段中的 token 键值,使之包含实际的令牌内容。
下面的配置实例声明了一个 ServiceAccount 令牌 Secret:
1apiVersion: v1
2kind: Secret
3metadata:
4 name: secret-sa-sample
5 annotations:
6 kubernetes.io/service-account.name: "sa-name"
7type: kubernetes.io/service-account-token
8data:
9# 你可以像 Opaque Secret 一样在这里添加额外的键/值对
10 extra: YmFyCg")
创建了 Secret 之后,等待 Kubernetes 在 data 字段中填充 token 主键,关于 ServiceAccount 的工作原理将在后面的章节深入学习。
7、Secret vs ConfigMap
最后我们来对比下 Secret 和 ConfigMap这两种资源对象的异同点:
相同点:
key/value的形式
属于某个特定的命名空间
可以导出到环境变量
可以通过目录/文件形式挂载
通过 volume 挂载的配置信息均可热更新(那么环境变量的方式就不会进行热更新的哦)
不同点:
Secret 可以被 ServerAccount 关联
Secret 可以存储
docker register的鉴权信息,用在ImagePullSecret参数中,用于拉取私有仓库的镜像Secret 支持
Base64加密Secret 分为
kubernetes.io/service-account-token、kubernetes.io/dockerconfigjson、Opaque多种类型,而Configmap不区分类型
1.同样 Secret 文件大小限制为
1MB(ETCD 的要求); 2.Secret 虽然采用Base64编码,但是我们还是可以很方便解码获取到原始信息,所以对于非常重要的数据还是需要慎重考虑,可以考虑使用 Vault 来进行加密管理。

关于我
我的博客主旨:
- 排版美观,语言精炼;
- 文档即手册,步骤明细,拒绝埋坑,提供源码;
- 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!
🍀 微信二维码 x2675263825 (舍得), qq:2675263825。

🍀 微信公众号 《云原生架构师实战》

🍀 博客 www.onlyyou520.com


🍀 csdn https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

🍀 知乎 https://www.zhihu.com/people/foryouone

最后
好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!

1

