投射数据卷 Projected Volume

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

  1. 创建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 编码
  1. 应用Secret
bash 复制代码
[root@master01 ~]# kubectl apply -f tty.yml
  1. 在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 生命周期内存储临时数据
  1. 登录容器查看
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

  1. 创建了一个名为 nginx-secret 的 Secret
bash 复制代码
kubectl create secret generic nginx-secret --from-literal=username=myUser --from-literal=password=myPass
  1. 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 名称
  1. 登录查看
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 文件中

  1. 简单的 ConfigMap
bash 复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-config
data:
  # MySQL 数据库密码,配置 MySQL root 用户的密码(需要用引号包围)
  MYSQL_ROOT_PASSWORD: "123456"  
  # 要创建的数据库名称
  MYSQL_DATABASE: your_database_name
  1. 多行配置,适用于配置文件等。
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
相关推荐
戮戮34 分钟前
一次深入排查:Spring Cloud Gateway TCP 连接复用导致 K8s 负载均衡失效
tcp/ip·spring cloud·kubernetes·gateway·负载均衡·netty
能不能别报错2 小时前
K8s学习笔记(二十四) ingress
笔记·学习·kubernetes
能不能别报错3 小时前
K8s学习笔记(二十三) 网络策略 NetworkPolicy
笔记·学习·kubernetes
suknna3 小时前
记一次 Kubebuilder Operator 开发中的 CRD 注解超限问题
kubernetes
victory04316 小时前
K8S 安装 部署 文档
算法·贪心算法·kubernetes
能不能别报错1 天前
K8s学习笔记(二十二) 网络组件 Flannel与Calico
笔记·学习·kubernetes
lijun_xiao20091 天前
DevOps(devops/k8s/docker/Linux)学习笔记
docker·kubernetes·devops
k3s中文社区1 天前
K3s + Sysbox:让容器拥有“虚拟机的灵魂”
kubernetes·rancher·k3s
Mr.小海1 天前
Kubernetes GPU 运维组件介绍
运维·容器·kubernetes
RancherLabs1 天前
告别卡顿与等待,Rancher Vai 让集群操作“秒响应”
kubernetes·rancher