跳转至

Kubernetes 配置与密钥管理 Secret

什么是 secret

什么是 secret

  • Secret 与 ConfigMap 类似,主要的区别是 ConfigMap 存储的是明文,而 Secret 存储的是密文。
  • ConfigMap 可以用配置文件管理,而 Secret 可用于密码、密钥、token等敏感数据的配置管理。

secret 类型

Secret 有 4 种类型

类型 说明
Opaque base64 编码格式的 Secret,用来存储密码、密钥、信息、证书等,类型标识符为 generic
Service Account 用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的 /var/run/secrets/kubernetes.io/serviceaccount 目录中
kubernetes.io/dockerconfigjson 用来存储私有 docker registry 的认证信息,类型标识为 docker-registry 。
kubernetes.io/tls 用于为 SSL 通信模式存储证书和私钥文件,命令式创建类型标识为 tls。

在命令行指定参数创建

1. 查看帮助信息
[root@k8smaster001 cm]# kubectl create secret -h
Create a secret with specified type.

 A docker-registry type secret is for accessing a container registry.

 A generic type secret indicate an Opaque secret type.

 A tls type secret holds TLS certificate and its associated key.

Available Commands:
  docker-registry   创建一个给 Docker registry 使用的 Secret
  generic           Create a secret from a local file, directory, or literal value
  tls               创建一个 TLS secret

Usage:
  kubectl create secret (docker-registry | generic | tls) [options]

Use "kubectl create secret <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).

Secret 应用案例

创建 mysql 管理员密码 Secret 案例,使用 Opaque 类型来创建 mysql 密码 Secret

1. Opaque 类型密码需要进行 base64 编码
[root@k8smaster001 cm]# echo -n abc123 |base64
YWJjMTIz
假设密码为 abc123 ,得到的编码为 YWJjMTIz
2. 编写创建 secret 的 secret-mysql.yml 文件
apiVersion: v1
kind: Secret
metadata:
  name: secret-mysql
data:
  password: YWJjMTIz
3. 创建 secret 并确认
[root@k8smaster001 cm]# kubectl apply -f secret-mysql.yml 
secret/secret-mysql created

[root@k8smaster001 cm]# kubectl get secret  secret-mysql
secret-mysql   Opaque   1      12s

Secret的2种使用方式

通过环境变量的方式传递给pod

1. 编写 pod 的 pod-mysql-secret.yml 文件使用 Secret
apiVersion: v1
kind: Pod
metadata:
  name: pod-mysql-secret1
spec:
  containers:
  - name: mysql
    image: mysql:5.7
    env:
      - name: MYSQL_ROOT_PASSWORD
        valueFrom:
          secretKeyRef:
            name: secret-mysql              # 对应创建的secret名字
            key: password
2. 创建 pod
[root@k8smaster001 cm]# kubectl apply -f pod-mysql-secret.yml
pod/pod-mysql-secret1 created
3. 验证 pod
[root@k8smaster001 cm]# kubectl get pods pod-mysql-secret1
NAME                READY   STATUS    RESTARTS   AGE
pod-mysql-secret1   1/1     Running   0          102s
4. 验证传入 pod 的变量效果
[root@k8smaster001 cm]# kubectl exec -it pod-mysql-secret1 -- /bin/bash
bash-4.2# env |grep MYSQL_ROOT_PASSWORD
MYSQL_ROOT_PASSWORD=abc123
bash-4.2# mysql -pabc123
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.44 MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

通过 volume 的方式挂载到 pod 内

1. 编写 pod 的 pod-mysql-secret2.yml 文件使用 Secret
apiVersion: v1
kind: Pod
metadata:
  name: pod-mysql-secret2
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 100000
    volumeMounts:
    - name: vol-secret                  # 定义挂载的卷,对应下面定义的卷名
      mountPath: "/opt/passwd"    # 挂载目录(支持热更新),也可以使用subPath挂载文件(但不支持热更新)
      readOnly: true                    # 只读
  volumes:
  - name: vol-secret                    # 定义卷名
    secret:                             # 使用secret
      secretName: secret-mysql              # 对应创建好的secret名
2. 创建 pod
[root@k8smaster001 cm]# kubectl apply -f pod-mysql-secret2.yml
pod/pod-mysql-secret2 created
3. 验证 pod
[root@k8smaster001 cm]# kubectl get pods pod-mysql-secret2
NAME                READY   STATUS    RESTARTS   AGE
pod-mysql-secret2   1/1     Running   0          63s
4. 验证发现密码在容器内被解码
[root@k8smaster001 cm]# kubectl exec  pod-mysql-secret2 -- cat /opt/passwd/password
abc123

热更新测试

热更新测试

1. 创建新的密码
[root@k8smaster001 cm]# echo -n abc456 |base64
YWJjNDU2
2. 更新 Secret 中密码为新创建的密码
[root@k8smaster001 cm]# kubectl edit secret secret-mysql
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
  password: YWJjNDU2 # 密码改成 abc456 的 base64 编码
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"password":"YWJjMTIz"},"kind":"Secret","metadata":{"annotations":{},"name":"secret-mysql","namespace":"default"}}
  creationTimestamp: "2024-04-01T09:55:58Z"
  name: secret-mysql
  namespace: default
  resourceVersion: "4016907"
  uid: 98b76122-e4a7-4556-b31d-21800ce3ffd2
type: Opaque
3. 发现密码已经被更新了
[root@k8smaster001 cm]# kubectl exec  pod-mysql-secret2 -- cat /opt/passwd/password
abc456