投射数据卷 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
相关推荐
花晓木6 小时前
k8s etcd 数据损坏处理方式
容器·kubernetes·etcd
运维&陈同学6 小时前
【模块一】kubernetes容器编排进阶实战之基于velero及minio实现etcd数据备份与恢复
数据库·后端·云原生·容器·kubernetes·etcd·minio·velero
花晓木7 小时前
k8s备份 ETCD , 使用velero工具进行备份
容器·kubernetes·etcd
liuxuzxx9 小时前
Istio-2:流量治理之简单负载均衡
云原生·kubernetes·istio
上海运维Q先生9 小时前
面试题整理14----kube-proxy有什么作用
运维·面试·kubernetes
怡雪~10 小时前
Kubernetes使用Ceph存储
ceph·容器·kubernetes
aherhuo1 天前
kubevirt网络
linux·云原生·容器·kubernetes
catoop1 天前
K8s 无头服务(Headless Service)
云原生·容器·kubernetes
liuxuzxx1 天前
1.24.1-Istio安装
kubernetes·istio·service mesh
道一云黑板报1 天前
Flink集群批作业实践:七析BI批作业执行
大数据·分布式·数据分析·flink·kubernetes