提示:本文原创作品,良心制作,干货为主,简洁清晰,一看就会
文章目录
- 前言
- 一、Secret介绍
- 二、Secret创建
-
- [2.1 命令方式创建](#2.1 命令方式创建)
- [2.2 yaml方式创建](#2.2 yaml方式创建)
- 三、Secret使用
-
- [3.1 通过环境变量注入](#3.1 通过环境变量注入)
- [3.2 数据卷挂载](#3.2 数据卷挂载)
- 四、docker私仓secret应用
前言
在 Kubernetes 集群中,敏感配置的安全管理是保障业务稳定与数据安全的关键环节。密码、令牌、密钥等信息若直接暴露在配置文件或镜像中,极易引发泄露风险。Secret 作为 K8s 原生的敏感信息存储对象,专门用于安全托管这类数据,实现加密存储与按需挂载。本文将围绕 Secret 的类型、创建方式、使用场景及安全实践展开介绍,帮助开发者规范管理集群敏感配置
我的实验环境
| 主机名 | IP |
|---|---|
| k8s-master1 | 192.168.13.136 |
| k8s-node1 | 192.168.13.139 |
| k8s-node2 | 192.168.13.140 |
一、Secret介绍
Secret 是 Kubernetes 用于 存储密码、令牌、密钥等敏感信息的资源对象 ,避免将机密数据直接写入镜像或配置文件。它默认采用 Base64 编码存储,可通过环境变量或数据卷挂载给 Pod 使用,支持通用密钥、Docker 仓库凭证、TLS 证书等多种类型。配合权限控制与加密方案,能有效降低敏感信息泄露风险,是集群安全配置的核心组件
用户可以创建自己的secret,系统也会有自己的secret
pod需要先引用才能使用某个secret
二、Secret创建
2.1 命令方式创建
yaml
root@k8s-master1:~# mkdir -p /k8s-test/secret
root@k8s-master1:~# cd /k8s-test/secret/
root@k8s-master1:/k8s-test/secret# echo -n "root" > username.txt # 存放用户名
root@k8s-master1:/k8s-test/secret# cat username.txt
rootroot@k8s-master1:/k8s-test/secret# echo -n "Abc@123" > password.txt # 存放密码
# 命令创建secret,generic是Secret的默认类型,也叫Opaque Secret
root@k8s-master1:/k8s-test/secret# kubectl create secret generic user-pass --from-file=./username.txt --from-file=./password.txt
root@k8s-master1:/k8s-test/secret# kubectl get secrets
NAME TYPE DATA AGE
user-pass Opaque 2 14s
# describe指令不会展示secret的实际内容,这是出于对数据的保护考虑
root@k8s-master1:/k8s-test/secret# kubectl describe secret user-pass # 查看secret的详细信息发现不够详细
Name: user-pass
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password.txt: 7 bytes
username.txt: 4 bytes
root@k8s-master1:/k8s-test/secret# kubectl get secret user-pass -o yaml # 查看secret详细信息方法二
apiVersion: v1
data:
password.txt: QWJjQDEyMw== # 密码被加密
username.txt: cm9vdA== # 用户被加密
kind: Secret
metadata:
creationTimestamp: "2026-04-21T06:29:53Z"
name: user-pass
namespace: default
resourceVersion: "541777"
uid: d0f0fff1-7609-4734-b464-92e0ede6e57d
type: Opaque
# base64解码就可以查看实际内容
root@k8s-master1:/k8s-test/secret# echo cm9vdA== | base64 --decode
rootroot@k8s-master1:/k8s-test/secret# echo QWJjQDEyMw== | base64 --decode
Abc@123root@k8s-master1:/k8s-test/secret#
2.2 yaml方式创建
yaml
# 1.创建secret.yaml文件,内容可以先用base64编码一下防止明文被人发现
root@k8s-master1:/k8s-test/secret# echo -n "root" | base64
cm9vdA==
root@k8s-master1:/k8s-test/secret# echo -n "Qing@123" | base64
UWluZ0AxMjM=
# 2. 创建yaml文件
root@k8s-master1:/k8s-test/secret# vim secret.yaml
---
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque # 模糊
data:
username: cm9vdA==
password: UWluZ0AxMjM=
# 3. 运行secret并查看状态
root@k8s-master1:/k8s-test/secret# kubectl apply -f secret.yaml
root@k8s-master1:/k8s-test/secret# kubectl get secret
NAME TYPE DATA AGE
mysql-secret Opaque 2 7s
user-pass Opaque 2 12m
# 4. 查看详细信息
root@k8s-master1:/k8s-test/secret# kubectl get secret mysql-secret -o yaml
apiVersion: v1
data:
password: UWluZ0AxMjM=
username: cm9vdA==
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"password":"UWluZ0AxMjM=","username":"cm9vdA=="},"kind":"Secret","metadata":{"annotations":{},"name":"mysql-secret","namespace":"default"},"type":"Opaque"}
creationTimestamp: "2026-04-21T06:42:30Z"
name: mysql-secret
namespace: default
resourceVersion: "543298"
uid: 9c9dc39c-64e5-45bb-9d49-7f1f8d233bf5
type: Opaque
三、Secret使用
3.1 通过环境变量注入
yaml
## 1. 先创建一个secret
root@k8s-master1:/k8s-test/secret# echo -n "root" | base64
cm9vdA==
root@k8s-master1:/k8s-test/secret# echo -n "Qing@2026" | base64
UWluZ0AyMDI2
root@k8s-master1:/k8s-test/secret# vim secret1.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
data:
username: cm9vdA==
password: UWluZ0AyMDI2
## 2. 运行secret并观察状态
root@k8s-master1:/k8s-test/secret# kubectl apply -f secret1.yaml
root@k8s-master1:/k8s-test/secret# kubectl get secret
NAME TYPE DATA AGE
mysql-secret Opaque 2 1m30s
root@k8s-master1:/k8s-test/secret# kubectl get secret mysql-secret -o yaml
apiVersion: v1
data:
password: UWluZ0AyMDI2
username: cm9vdA==
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"password":"UWluZ0AyMDI2","username":"cm9vdA=="},"kind":"Secret","metadata":{"annotations":{},"name":"mysql-secret","namespace":"default"},"type":"Opaque"}
creationTimestamp: "2026-04-21T07:10:56Z"
name: mysql-secret
namespace: default
resourceVersion: "546766"
uid: 6eb0f453-1ba3-4fcc-ab9e-f71695a1497b
type: Opaque
yaml
## 3. 创建pod
root@k8s-master1:/k8s-test/secret# vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD # 创建新的环境变量名称
valueFrom:
secretKeyRef: # 调用的key是什么
name: mysql-secret # 变量来自于哪个secret
key: password # 要用secret里的哪个键
## 4. 运行pod
root@k8s-master1:/k8s-test/secret# kubectl apply -f pod1.yaml
root@k8s-master1:/k8s-test/secret# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql 1/1 Running 0 2m29s 10.244.36.116 k8s-node1 <none> <none>
## 5. 进入pod,看看能否登录mysql
root@k8s-master1:/k8s-test/secret# kubectl exec -it mysql /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
bash-4.2# mysql -uroot -p'Qing@2026'
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> exit
Bye
bash-4.2# exit
exit
command terminated with exit code 126
yaml
## 6. 修改一下secret看pod中会不会自动更新
root@k8s-master1:/k8s-test/secret# echo -n "Qing@123" | base64
UWluZ0AxMjM=
root@k8s-master1:/k8s-test/secret# vim secret1.yaml
password: UWluZ0AxMjM= # 把密码改成了Qing@123
## 7. 重新运行secret
root@k8s-master1:/k8s-test/secret# kubectl apply -f secret1.yaml
root@k8s-master1:/k8s-test/secret# kubectl get secret mysql-secret -o yaml
apiVersion: v1
data:
password: UWluZ0AxMjM= # 可以看到密码已经更改
username: cm9vdA==
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"password":"UWluZ0AxMjM=","username":"cm9vdA=="},"kind":"Secret","metadata":{"annotations":{},"name":"mysql-secret","namespace":"default"},"type":"Opaque"}
creationTimestamp: "2026-04-21T07:10:56Z"
name: mysql-secret
namespace: default
resourceVersion: "549855"
uid: 6eb0f453-1ba3-4fcc-ab9e-f71695a1497b
type: Opaque
yaml
## 8. 进入pod,看新密码能不能登录mysql
root@k8s-master1:/k8s-test/secret# kubectl exec -it mysql /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
bash-4.2# mysql -uroot -p'Qing@123' # 新密码不能用
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
bash-4.2# mysql -uroot -p'Qing@2026' # 旧密码可以登录
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 5
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> exit
Bye
bash-4.2# exit
exit
root@k8s-master1:/k8s-test/secret#
通过环境变量引用的 Secret,Pod 运行后不会自动更新!
当你把 Secret 以环境变量形式注入 Pod 时:
- 环境变量的值是容器启动时一次性读取的
- Secret 后续修改、更新,已经运行的容器不会同步刷新
- 必须 删除重建 Pod 才能拿到最新的 Secret 值
3.2 数据卷挂载
bash
## 1. 创建secret
root@k8s-master1:/k8s-test/secret# echo cm9vdA== | base64 --decode
rootroot@k8s-master1:/k8s-test/secret# echo UWluZ0AxMjM= | base64 --decode
Qing@123root@k8s-master1:/k8s-test/secret# kubectl get secret
No resources found in default namespace.
root@k8s-master1:/k8s-test/secret# cat secret1.yaml
apiVersion: v1
kind: Secret
metadata:
name: nginx-secret
type: Opaque
data:
username: cm9vdA==
password: UWluZ0AxMjM=
root@k8s-master1:/k8s-test/secret# kubectl apply -f secret1.yaml
yaml
## 2. 创建pod并挂载secret
root@k8s-master1:/k8s-test/secret# vim pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.24
volumeMounts:
- name: nginx-volume
mountPath: "/etc/secret"
readOnly: true
volumes:
- name: nginx-volume
secret:
secretName: nginx-secret
root@k8s-master1:/k8s-test/secret# kubectl apply -f pod2.yaml
root@k8s-master1:/k8s-test/secret# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql 1/1 Running 0 56m
nginx 1/1 Running 0 6s
root@k8s-master1:/k8s-test/secret# kubectl exec -it nginx /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx:/# ls /etc/secret
password username
root@nginx:/# cat /etc/secret/username
rootroot@nginx:/# cat /etc/secret/password
Qing@123root@nginx:/# exit
exit
yaml
## 3. 更改secret看看pod内部会不会发生变化
root@k8s-master1:/k8s-test/secret# echo -n "qingqing" | base64
cWluZ3Fpbmc=
root@k8s-master1:/k8s-test/secret# vim secret1.yaml
password: cWluZ3Fpbmc= # 更改用户名为qingqing
root@k8s-master1:/k8s-test/secret# kubectl apply -f secret1.yaml
root@k8s-master1:/k8s-test/secret# kubectl get secret nginx-secret -o yaml
apiVersion: v1
data:
password: UWluZ0AxMjM=
username: cWluZ3Fpbmc= # 查看详细信息,可以看到secret已经更改成功
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"password":"UWluZ0AxMjM=","username":"cWluZ3Fpbmc="},"kind":"Secret","metadata":{"annotations":{},"name":"nginx-secret","namespace":"default"},"type":"Opaque"}
creationTimestamp: "2026-04-21T08:11:23Z"
name: nginx-secret
namespace: default
resourceVersion: "554423"
uid: 8bdc7fa4-6747-4a7f-acff-318a09427551
type: Opaque
## 4. 进入pod内部,发现文件更改成功
root@k8s-master1:/k8s-test/secret# kubectl exec -it nginx /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx:/# cat /etc/secret/username
qingqingroot@nginx:/# exit
exit
root@k8s-master1:/k8s-test/secret#
Secret 卷挂载 → 会自动更新!
当你把 Secret 挂载成 Volume
- K8s 会自动定期同步 Secret 的最新内容,同步时间大约是 1 分钟左右
- 你修改 Secret 后,不需要重启 Pod,容器里的挂载文件会自动变成新内容
- 你的程序只要重新读取文件,就能拿到最新值
四、docker私仓secret应用
目前,我有一个harbor仓库,ip地址:192.168.13.137
test-project仓库中里面有三个镜像:nginx:1.22 nginx:1.24 mysql:8.0

yaml
# 1. 想让哪台机器拉取harbor仓库的镜像,就在daemon.json中配置harbor的ip
# 我在k8s-node1上配置,待会就让pod运行在k8s-node1上
root@k8s-node1:~# vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://a88uijg4.mirror.aliyuncs.com",
"https://docker.lmirror.top",
"https://docker.m.daocloud.io",
"https://hub.uuuadc.top",
"https://docker.anyhub.us.kg",
"https://dockerhub.jobcher.com",
"https://dockerhub.icu",
"https://docker.ckyl.me",
"https://docker.awsl9527.cn",
"https://docker.laoex.link"
],
"insecure-registries": ["192.168.13.137"]
}
root@k8s-node1:~# systemctl daemon-reload
root@k8s-node1:~# systemctl restart docker
yaml
# 2. 创建secret存放harbor的账号密码和ip
root@k8s-master1:~# kubectl create secret docker-registry harborsecret --docker-server=192.168.13.137 --docker-username=admin --docker-password=Harbor12345
root@k8s-master1:~# kubectl get secret
NAME TYPE DATA AGE
harborsecret kubernetes.io/dockerconfigjson 1 24s
# 3. 创建pod,引用secret
root@k8s-master1:~# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-harbor
spec:
nodeName: k8s-node1
hostNetwork: true
imagePullSecrets:
- name: harborsecret # 拉取这个镜像时,要使用harborsecret这个账号密码去登录私有仓库
containers:
- name: nginx
image: 192.168.13.137/test-project/nginx:1.22 # 配置harbor镜像的地址
ports:
- containerPort: 80 # 暴露端口
root@k8s-master1:~# kubectl apply -f pod.yaml
root@k8s-master1:~# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-harbor 1/1 Running 0 4s 192.168.13.139 k8s-node1 <none> <none>
浏览器访问k8s-node1的ip

注:
文中若有疏漏,欢迎大家指正赐教。
本文为100%原创,转载请务必标注原创作者,尊重劳动成果。
求赞、求关注、求评论!你的支持是我更新的最大动力,评论区等你~