目录
Secret 实现
Secret
是 Kubernetes 中用于存储和管理敏感信息(例如密码、OAuth 令牌、SSH 密钥等)的对象。Secret
对象可以用来避免在 Pod 定义或容器镜像中硬编码敏感数据。
Kubernetes 的 Secret 文件(以及其他资源配置文件)不需要特定的文件扩展名,比如
.yml
或.yaml
。可以使用任何扩展名或甚至没有扩展名,只要文件内容是有效的 YAML 格式,Kubernetes 都可以解析它。
方法一:通过命令行创建
# 这将创建一个名为 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
来创建
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
username: YWRtaW4= # "admin" base64编码
password: YWRtaW4xMjM= # "admin123" base64编码
# 不使用base64编码会报错
Base64 编码是一种将二进制数据转化为 ASCII 字符串的编码方式。它常用于在需要以文本形式传输二进制数据的场景中,如在 Secret
对象中存储敏感信息时。Base64 编码可以确保数据在传输过程中不会被篡改,并能在各种环境中兼容处理。
编码和解码示例
# 编码
echo -n 'admin' | base64
# 解码
echo 'YWRtaW4=' | base64 --decode
通过环境变量使用Secret
1. 创建Secret
密码文件tty.yml
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 编码
2. 应用Secret
[root@master01 ~]# kubectl apply -f tty.yml
3. 在mysql的yml文件中使用 Secret
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 生命周期内存储临时数据
4. 登录容器查看
[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
1. 创建了一个名为 nginx-secret
的 Secret
kubectl create secret generic nginx-secret --from-literal=username=myUser --from-literal=password=myPass
2. Nginx Pod YAML 文件
通过挂载卷导入 nginx-secret
并将其内容作为文件使用的 YAML 配置示例:
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 名称
3. 登录查看
[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 文件中
1. 简单的 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
data:
# MySQL 数据库密码,配置 MySQL root 用户的密码(需要用引号包围)
MYSQL_ROOT_PASSWORD: "123456"
# 要创建的数据库名称
MYSQL_DATABASE: your_database_name
2. 多行配置,适用于配置文件等。
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。
通过命令行创建
定义个文件
[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;
}
}
使用命令行从文件导入形式创建:
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
kubectl get configmap nginx-config -o yaml
作为环境变量使用
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 终止后数据会丢失
通过挂载文件使用
# 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 的特定部分挂载到容器的指定路径
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
Downward API
Downward API 是 Kubernetes 中的一项功能,允许将关于 Pod 或者容器本身的元数据以环境变量或者文件的形式传递给运行中的容器。这在需要动态获取运行时信息的应用场景中非常有用,例如记录日志、调试或配置应用行为等。
在 Kubernetes 中,使用 Downward API 时,通过 fieldRef
引用 Pod 的 metadata.name
字段,实际上是引用了 Pod 定义中的元数据名称。这允许容器访问到 Pod 的名称,这个名称是在 Pod 的 YAML 定义中明确指定的。使用Downward API 不能直接自己定义值,而是必须通过引用 Pod 或 Container 的现有字段来获取值。Downward API 的设计目的是为了让容器能够访问到关于自身或其所在 Pod 的信息,这些信息通常是由 Kubernetes 集群管理的,而不是由容器自身定义的。
也就说 Downward API是引用pod或者容器定义的信息,ConfigMap通常是挂载引用配置文件或者不保密数据的,Secre通常是导入保密类型的变量或者其他需要保密的数据, 这是K8s中给容器内导入数据或者挂载的三种不同的机制或者称为方式。
Downward API 提供的功能
- 环境变量:将 Pod 的元数据(如名称、命名空间、UID、标签等)注入到容器的环境变量中。
- 文件:将 Pod 的元数据投射到容器的文件系统中。
可用的元数据字段
- Pod 名称:
metadata.name
- 命名空间:
metadata.namespace
- UID:
metadata.uid
- 标签:
metadata.labels
- 注解:
metadata.annotations
- 容器资源请求/限制:
spec.containers[*].resources
方式一 : 通过env环境变量的使用定义使用
apiVersion: v1 # Kubernetes API 的版本。v1 是最基本的版本,用于定义 Pod 资源。
kind: Pod # 资源类型:Pod。Pod 是 Kubernetes 中的基本执行单元。
metadata:
name: downward-api-env-demo # Pod 的名称。在 Kubernetes 中,每个 Pod 都需要一个唯一的名称。
spec:
containers:
- name: busybox # 容器的名称。可以在 Pod 中定义多个容器,每个容器需要一个名称。
image: busybox # 容器使用的 Docker 镜像。这里使用的是 busybox 镜像,它是一个轻量级的 Linux 发行版。
command: ['sh', '-c', 'echo "Pod Name: $POD_NAME"; echo "Pod Namespace: $POD_NAMESPACE"; sleep 3600']
# 容器启动时执行的命令:
# 1. 使用 sh -c 启动 shell 并执行后续命令。
# 2. 打印环境变量 POD_NAME 的值,显示 Pod 的名称。
# 3. 打印环境变量 POD_NAMESPACE 的值,显示 Pod 所在的命名空间。
# 4. 使容器保持运行 1 小时(3600 秒),以便查看输出结果。
env:
- name: POD_NAME # 环境变量的名称,这里设置为 POD_NAME。
valueFrom:
fieldRef:
fieldPath: metadata.name # 环境变量的值来源于 Pod 的元数据中的名称字段。
# fieldPath 指定了要从 Pod 的元数据中提取的字段,这里是 metadata.name,
# 它表示 Pod 的名称。该值将被设置为 POD_NAME 环境变量。
- name: POD_NAMESPACE # 环境变量的名称,这里设置为 POD_NAMESPACE。
valueFrom:
fieldRef:
fieldPath: metadata.namespace # 环境变量的值来源于 Pod 的元数据中的命名空间字段。
# fieldPath 指定了要从 Pod 的元数据中提取的字段,这里是 metadata.namespace,
# 它表示 Pod 所在的命名空间。该值将被设置为 POD_NAMESPACE 环境变量。
进行部署验证:
将上述 YAML 文件保存为 ceshi.yaml
,然后在 Kubernetes 集群中运行并创建 Pod。
[root@master01 ~]# kubectl apply -f ceshi.yaml
查看 Pod 是否启动并运行
[root@master01 ~]# kubectl get pod -n default
NAME READY STATUS RESTARTS AGE
downward-api-env-demo 1/1 Running 0 17s
进行查看日志:
[root@master01 ~]# kubectl logs downward-api-env-demo
Pod Name: downward-api-env-demo
Pod Namespace: default
方式一 : 通过 Volume 挂载定义使用
apiVersion: v1
kind: Pod
metadata:
name: downward-api-volume-demo
spec:
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'cat /etc/downward-api/pod-name; cat /etc/downward-api/pod-namespace; sleep 3600']
volumeMounts:
- name: downward-api-volume
mountPath: /etc/downward-api
volumes:
- name: downward-api-volume
downwardAPI:
items:
- path: "pod-name"
fieldRef:
fieldPath: metadata.name
- path: "pod-namespace"
fieldRef:
fieldPath: metadata.namespace
进行部署验证:
将上述 YAML 文件保存为 tty.yaml
,然后在 Kubernetes 集群中运行并创建 Pod。
[root@master01 ~]# kubectl apply -f tty.yaml
查看 Pod 是否启动并运行
[root@master01 ~]# kubectl get pod -n default
NAME READY STATUS RESTARTS AGE
downward-api-volume-demo 1/1 Running 0 93s
进入 Pod 并检查挂载的文件
[root@master01 ~]# kubectl exec -it downward-api-volume-demo -- sh
/ # ls /etc/downward-api
pod-name pod-namespace
/ # cat /etc/downward-api/pod-name
downward-api-volume-demo/
/ # cat /etc/downward-api/pod-namespace
default/
总结
Downward API:
- 作用:允许容器获取关于自身或其所在 Pod 的信息。
- 使用方式:通过环境变量或 Volume 挂载的方式将 Pod 或 Container 的字段值传递给容器。
- 适用场景:当容器需要访问 Pod 的元数据(如名称、标签、注解等)或容器的资源请求和限制时。
ConfigMap:
- 作用:用于存储和管理不包含敏感信息的配置数据。
- 使用方式:可以通过环境变量、命令行参数或文件挂载的方式将 ConfigMap 中的数据导入到容器中。
- 适用场景:当容器需要访问配置文件或配置数据时,例如应用配置、脚本、模板等。
Secret:
- 作用:用于存储和管理敏感信息,如密码、OAuth 令牌、SSH 密钥等。
- 使用方式:可以通过环境变量或文件挂载的方式将 Secret 中的数据导入到容器中。
- 适用场景:当容器需要访问敏感数据时,Kubernetes 会确保这些数据的安全存储和传输。