Secret 实现
Secret
是 Kubernetes 中用于存储和管理敏感信息(例如密码、OAuth 令牌、SSH 密钥等)的对象。Secret
对象可以用来避免在 Pod 定义或容器镜像中硬编码敏感数据。
Kubernetes 的 Secret 文件(以及其他资源配置文件)不需要特定的文件扩展名,比如
.yml
或.yaml
。可以使用任何扩展名或甚至没有扩展名,只要文件内容是有效的 YAML 格式,Kubernetes 都可以解析它。
方法一:通过命令行创建
bash
# 这将创建一个名为 my-secret 的 Secret,包含 username 和 password 两个键值对。
kubectl create secret generic my-secret --from-literal=username=admin --from-literal=password=admin123
generic
表示通用类型,适用于大多数场景。它可以用来存储任意的键值对数据,例如用户名、密码、API 密钥等。
方法二:通过 YAML 文件创建
可以将 Secret
定义在 YAML 文件中,并使用 kubectl apply
来创建
bash
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
username: YWRtaW4= # "admin" base64编码
password: YWRtaW4xMjM= # "admin123" base64编码
# 不使用base64编码会报错
Base64 编码是一种将二进制数据转化为 ASCII 字符串的编码方式。它常用于在需要以文本形式传输二进制数据的场景中,如在 Secret
对象中存储敏感信息时。Base64 编码可以确保数据在传输过程中不会被篡改,并能在各种环境中兼容处理。
编码和解码示例
bash
# 编码
echo -n 'admin' | base64
# 解码
echo 'YWRtaW4=' | base64 --decode
通过 环境变量使用Secret
- 创建
Secret
密码文件tty.yml
bash
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret-4
namespace: default
type: Opaque
data:
mysql-root-password: MTIzNDU2 # 123456 的 Base64 编码
mysql-database: bXlkYg== # mydb 的 Base64 编码
- 应用Secret
bash
[root@master01 ~]# kubectl apply -f tty.yml
- 在mysql的yml文件中使用 Secret
bash
apiVersion: v1 # 定义 API 版本,v1 是 Kubernetes 中的稳定版本
kind: Pod # 定义资源类型为 Pod
metadata:
name: mysql-pod # Pod 的名称
namespace: default # Pod 所在的命名空间,default 是默认命名空间
spec:
containers: # 定义 Pod 中的容器列表
- name: mysql # 容器的名称
image: mysql:8.0 # 使用的镜像及其版本
env: # 定义环境变量
- name: MYSQL_ROOT_PASSWORD # MySQL root 用户的密码
valueFrom:
secretKeyRef:
name: mysql-secret-4 # 引用的 Secret 名称
key: mysql-root-password # 从 Secret 中获取的键名
- name: MYSQL_DATABASE # MySQL 数据库名称
valueFrom:
secretKeyRef:
name: mysql-secret-4 # 引用的 Secret 名称
key: mysql-database # 从 Secret 中获取的键名
ports:
- containerPort: 3306 # 暴露的端口号,MySQL 默认使用 3306 端口
volumeMounts:
- name: mysql-data # 挂载卷的名称
mountPath: /var/lib/mysql # 挂载路径,MySQL 的数据存储位置
volumes:
- name: mysql-data # 定义的卷名称
emptyDir: {} # 使用 emptyDir 卷,在 Pod 生命周期内存储临时数据
- 登录容器查看
bash
[root@master01 ~]# kubectl exec -it mysql-pod /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
bash-5.1# mysql -uroot -p123456
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 8
Server version: 8.0.39 MySQL Community Server - GPL
Copyright (c) 2000, 2024, 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> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql>
通过挂载卷导入 Secret
- 创建了一个名为
nginx-secret
的 Secret
bash
kubectl create secret generic nginx-secret --from-literal=username=myUser --from-literal=password=myPass
- Nginx Pod YAML 文件
通过挂载卷导入 nginx-secret
并将其内容作为文件使用的 YAML 配置示例:
bash
apiVersion: v1 # 定义 API 版本,v1 是 Kubernetes 中的稳定版本
kind: Pod # 定义资源类型为 Pod
metadata:
name: nginx-pod # Pod 的名称
namespace: default # Pod 所在的命名空间,default 是默认命名空间
spec:
containers: # 定义 Pod 中的容器列表
- name: nginx # 容器的名称
image: nginx:latest # 使用的 Nginx 镜像及其版本
volumeMounts: # 定义卷挂载点
- name: secret-volume # 挂载的卷名称
mountPath: "/etc/nginx-secret" # 将 Secret 挂载到容器内的 /etc/nginx-secret 路径
readOnly: true # 只读挂载,保证安全性,防止容器内应用修改 Secret
volumes: # 定义 Pod 使用的卷
- name: secret-volume # 卷的名称
secret:
secretName: nginx-secret # 指定要挂载的 Secret 名称
- 登录查看
bash
[root@master01 ~]# kubectl exec -it nginx-pod -- /bin/sh # 以交互模式进入名为 nginx-pod 的容器的 shell
# cd /etc/nginx-secret # 切换到挂载的 Secret 目录
# ls # 列出挂载在 /etc/nginx-secret 目录下的文件
password username # 显示出两个文件,分别对应 Secret 中的键名
# cat username # 查看 username 文件的内容
myUser # 输出为 Secret 中键 username 的值
# cat password # 查看 password 文件的内容
myPass# #输出为 Secret 中键 password 的值
ConfigMap详解
ConfigMap
是 Kubernetes 中用于保存非敏感配置数据的一种资源类型,它允许你将配置数据与应用程序的容器分离。使用 ConfigMap
可以使配置更加灵活,支持应用程序的配置在运行时进行更新,而不需要重建容器镜像。
ConfigMap 的作用
- 配置管理:用于存储应用程序的配置信息,如环境变量、配置文件等。
- 解耦应用和配置:应用程序的配置与代码分离,方便在不同环境中使用相同的容器镜像。
- 与 Secret 区别 :
ConfigMap
适用于非敏感数据,而敏感数据(如密码、证书等)则应使用Secret
。
直接定义在 YAML 文件中
- 简单的 ConfigMap
bash
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
data:
# MySQL 数据库密码,配置 MySQL root 用户的密码(需要用引号包围)
MYSQL_ROOT_PASSWORD: "123456"
# 要创建的数据库名称
MYSQL_DATABASE: your_database_name
- 多行配置,适用于配置文件等。
bash
apiVersion: v1 # 版本号,定义了资源的 API 版本
kind: ConfigMap # 资源类型,这里是 ConfigMap,用于存储非机密的配置数据
metadata:
name: nginx-config # ConfigMap 的名称,方便引用
data: # 配置数据部分,可以包含多个键值对
default.conf: | # 键名为 default.conf,值是一个多行字符串(表示 Nginx 配置文件)
server { # server 块定义了一个虚拟主机
listen 80; # 监听 80 端口(HTTP 默认端口)
listen [::]:80; # 为 IPv6 配置监听 80 端口
server_name localhost; # 定义服务器名称
location / { # location 块定义请求处理的路由
root /usr/share/nginx/html; # 定义根目录路径
index index.html index.htm; # 定义默认文件
}
error_page 500 502 503 504 /50x.html; # 定义错误页面
location = /50x.html { # 定义特定错误页面的处理
root /usr/share/nginx/html; # 错误页面的文件路径
}
}
创建 ConfigMap:使用kubectl create -f file-name 命令使用配置好的文件生成 ConfigMap。
通过命令行创建
定义个文件
bash
[root@master01 ~]# vim default.conf
server {
listen 8080;
listen [::]:8080;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
使用命令行从文件导入形式创建:
bash
kubectl create configmap nginx-config --from-file=default.conf
注:
1.如果想从多个文件导入,只需在后面继续加 < --from-file=file-name > 参数即可
2.如果你想从一个目录中创建 ConfigMap,也是使用 --from-file=<path-to-directory>
3.如果你需要直接在命令行中指定键值对,可以使用**
--from-literal
** 参数:--from-literal=<key>=<value>4.也可以结合使用文件和 literals , 即 --from-file=<path-to-file> --from-literal=<key>=<value>
查看ConfigMap
bash
kubectl get configmap nginx-config -o yaml
作为环境变量使用
bash
apiVersion: v1 # 版本号,定义了资源的 API 版本
kind: ConfigMap # 资源类型,这里是 ConfigMap,用于存储非机密的配置数据
metadata:
name: mysql-config # ConfigMap 的名称,用于引用此配置
data: # 配置数据部分,包含多个键值对
# MySQL 数据库密码
MYSQL_ROOT_PASSWORD: "123456" # 配置 MySQL root 用户的密码(需要用引号包围)
# 要创建的数据库名称
MYSQL_DATABASE: your_database_name # 配置要创建的数据库名称(需要用引号包围)
---
apiVersion: v1 # 版本号,定义了资源的 API 版本
kind: Pod # 资源类型,这里是 Pod,用于定义一个容器组
metadata:
name: mysql-pod # Pod 的名称
spec:
containers:
- name: mysql # 容器名称
image: mysql:8.0 # 使用的镜像,这里是 MySQL 8.0
env: # 环境变量部分,用于传递配置给容器
- name: MYSQL_ROOT_PASSWORD
valueFrom:
configMapKeyRef:
name: mysql-config # 引用的 ConfigMap 名称
key: MYSQL_ROOT_PASSWORD # ConfigMap 中的键
- name: MYSQL_DATABASE
valueFrom:
configMapKeyRef:
name: mysql-config # 引用的 ConfigMap 名称
key: MYSQL_DATABASE # ConfigMap 中的键
ports:
- containerPort: 3306 # 容器暴露的端口
volumes:
- name: mysql-data # 卷的名称
emptyDir: {} # 使用空目录卷,这是一种临时存储,Pod 终止后数据会丢失
通过挂载文件使用
bash
# ConfigMap 用于存储自定义的配置信息
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config # ConfigMap 的名称
namespace: default # ConfigMap 所在的命名空间
data:
index.html: | # ConfigMap 中存储的文件数据
<!DOCTYPE html>
<html>
<head>
<title>Welcome to My Custom Nginx Page!</title>
</head>
<body>
<h1>Hello, Kubernetes!</h1>
<p>This is a custom Nginx default page served from a ConfigMap.</p>
</body>
</html>
---
# Pod 用于运行 Nginx 容器,并将 ConfigMap 中的文件挂载到容器中
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod # Pod 的名称
namespace: default # Pod 所在的命名空间
labels:
app: nginx # 用于选择 Pod 的标签
spec:
containers:
- name: nginx # 容器的名称
image: nginx:latest # 使用的镜像
ports:
- containerPort: 80 # 容器暴露的端口
volumeMounts:
- name: nginx-config-volume # 挂载的卷名称
mountPath: /usr/share/nginx/html/index.html # 挂载到容器内的路径
subPath: index.html # ConfigMap 中的文件名
volumes:
- name: nginx-config-volume # 卷的名称
configMap:
name: nginx-config # ConfigMap 的名称
---
# Service 用于暴露 Pod 以便外部访问
apiVersion: v1
kind: Service
metadata:
name: nginx-service # Service 的名称
namespace: default # Service 所在的命名空间
spec:
selector:
app: nginx # 用于选择目标 Pod 的标签
ports:
- protocol: TCP # 使用的协议
port: 80 # Service 暴露的端口
targetPort: 80 # Pod 中的端口
type: NodePort # 服务类型为 NodePort,允许外部访问
ConfigMap 适用于挂载那些在运行时不需要修改的配置文件或数据。因为 ConfigMap 作为只读卷挂载到容器中,容器内部的应用程序只能读取这些文件,而不能对其进行修改。这使得 ConfigMap 非常适合于以下情况:
- 静态配置:例如应用程序的配置文件、环境设置、启动脚本等,容器在启动时会读取这些配置,但不会在运行时修改它们。
- 环境变量:将配置数据以环境变量的形式注入到容器中。
- 命令行参数:将配置数据传递给容器的启动命令
注意:
mountPath: 定义容器内挂载卷的路径。例如 /etc/nginx/conf.d 是容器内部的路径,Nginx 会在这个路径下查找配置文件。
subPath: 允许你指定 ConfigMap 或卷中的某个特定文件或子目录挂载到容器中的特定路径。如果没有使用 subPath,整个 ConfigMap 会被挂载到 mountPath,而不仅仅是单个文件。
将 ConfigMap 的特定部分挂载到容器的指定路径
bash
apiVersion: v1 # Kubernetes API 版本
kind: ConfigMap # 配置类型为 ConfigMap
metadata:
name: nginx-mysql-config # ConfigMap 的名称
namespace: default # ConfigMap 所在的命名空间
data:
default.conf: | # Nginx 配置文件 default.conf 的内容
server {
listen 9090; # 监听 9090 端口
location / {
root /usr/share/nginx/html; # 配置 Nginx 根目录
index index.html; # 默认首页文件
}
}
other-config.conf: | # Nginx 配置文件 other-config.conf 的内容
server {
listen 8080; # 监听 8080 端口
location /other {
root /usr/share/nginx/other; # 配置 Nginx 根目录
index index.other.html; # 默认首页文件
}
}
mysql-config.properties: | # MySQL 配置文件 mysql-config.properties 的内容
MYSQL_ROOT_PASSWORD=your-root-password # MySQL 根密码
MYSQL_DATABASE=your-database-name # MySQL 数据库名称
MYSQL_USER=your-username # MySQL 用户名
MYSQL_PASSWORD=your-password # MySQL 用户密码
---
apiVersion: v1 # Kubernetes API 版本
kind: Pod # 配置类型为 Pod
metadata:
name: nginx-pod # Pod 的名称
namespace: default # Pod 所在的命名空间
labels:
app: nginx # Pod 的标签,方便选择器匹配
spec:
containers:
- name: nginx # 容器的名称
image: nginx:latest # 使用的镜像
ports:
- containerPort: 9090 # 容器内部的端口,匹配 Nginx 配置中的端口
volumeMounts:
- name: nginx-config-volume # 挂载的卷的名称
mountPath: /etc/nginx/conf.d/default.conf # 容器内的挂载路径
subPath: default.conf # 从 ConfigMap 中选择的文件
- name: mysql-config-volume # 挂载的卷的名称
mountPath: /etc/mysql/conf.d/mysql-config.properties # 容器内的挂载路径
subPath: mysql-config.properties # 从 ConfigMap 中选择的文件
volumes:
- name: nginx-config-volume # 卷的名称
configMap:
name: nginx-mysql-config # 配置使用的 ConfigMap 名称
- name: mysql-config-volume # 卷的名称
configMap:
name: nginx-mysql-config # 配置使用的 ConfigMap 名称
---
apiVersion: v1 # Kubernetes API 版本
kind: Service # 配置类型为 Service
metadata:
name: nginx-service # Service 的名称
namespace: default # Service 所在的命名空间
spec:
selector:
app: nginx # 选择器匹配 Pod 的标签
ports:
- protocol: TCP # 协议类型
port: 9090 # Service 对外暴露的端口
targetPort: 9090 # Service 转发到 Pod 中的端口
nodePort: 30001 # NodePort 类型的端口(需要在 30000-32767 范围内)
type: NodePort # Service 类型为 NodePort