小白成长之路-k8s-Configmap、Secret资源

文章目录


一、Configmap资源

1.简介

Configmap 是 k8s 中的资源对象,用于保存非机密性的配置的,数据可以用 key/value 键值对的形式保存,也可通过文件的形式保存。

2. Configmap 能解决哪些问题?

ConfigMap 的主要作用就是为了让镜像和配置文件解耦,以便实现镜像的可移植性和可复用性。

我们在部署服务的时候,每个服务都有自己的配置文件,如果一台服务器上部署多个服务:nginx、nginx、apache 等,那么这些配置都存在这个节点上,假如一台服务 器不能满足线上高并发的要求,需要对服务器扩容,扩容之后的服务器还是需要部署 多个服务:nginx、nginx、apache,新增加的服务器上还是要管理这些服务的配置, 如果有一个服务出现问题,需要修改配置文件,每台物理节点上的配置都需要修改, 这种方式肯定满足不了线上大批量的配置变更要求。 所以,k8s 中引入了 Configmap 资源对象,可以当成 volume 挂载到 pod 中,实现统一的配置管理。

1、Configmap 是 k8s 中的资源, 相当于配置文件,可以有一个或者多个 Configmap;

2、Configmap 可以做成 Volume,k8s pod 启动之后,通过 volume 形式映射到容器内部指定目录上;

3、容器中应用程序按照原有方式读取容器特定目录上的配置文件。

4、在容器看来,配置文件就像是打包在容器内部特定目录,整个过程对应用没有任何侵入。

3. Configmap 应用场景

1、使用 k8s 部署应用,当你将应用配置写进代码中,更新配置时也需要打包镜像,configmap 可以将配置信息和 docker 镜像解耦 ,以便实现镜像的可移植性和可复用性,因为一个 configMap 其实就是一系列配置信息的集合,可直接注入到 Pod 中给容器使用。configmap 注入方式有两种,一种将 configMap 做为存储卷,一种是将configMap 通过 env 中 configMapKeyRef 注入到容器中。

2、使用微服务架构的话,存在多个服务共用配置的情况,如果每个服务中单独一份配置的话,那么更新配置就很麻烦,使用 configmap 可以友好的进行配置共享。

4.使用 ConfigMap 的限制条件

  • ConfigMap 需要在 Pod 启动前创建出来;
  • 并且只有当 ConfigMap 和 Pod 处于同一命名空间时,才可以被 Pod 引用;
  • 当 Pod 挂载 ConfigMap 绑定的目录时,目录下的目录并不会挂载到 Pod 内,只有目录下的文件会被挂载。
  • ConfigMap 在设计上不是用来保存大量数据的。在 ConfigMap 中保存的数据不可超过 1MiB。如果你需要保存超出此尺寸限制的数据,可以考虑挂载存储卷或者使用独立的数据库或者文件服务。

5.Configmap 创建方法

5.1命令创建

kubectl create configmap nginx-confs --from-literal=nginx_port=8080 --from-literal=server_name=myapp.nginx.com

查看创建的cm详细信息

kubectl describe cm nginx-conf

bash 复制代码
查看创建的configmap的yaml信息
 kubectl get cm nginx-config -o yaml


命令解析

bash 复制代码
--allow-missing-template-keys

含义:如果设置为true,当模板中的字段或映射键在数据来源中缺失时,忽略模板中的任何错误。

--append-hash

含义:将configmap的哈希值附加到它的名称后面。

--as-group

含义:指定操作时要模拟的组。这个标志可以重复使用,以指定多个组,用于在操作中进行权限模拟。

--as-uid

含义:指定操作时要模拟的用户ID(UID)。

--as

含义:指定操作时要模拟的用户名。这个用户可以是普通用户或者服务账户,用于在操作中进行权限模拟。

--cache-dir

含义:默认的缓存目录路径。

--certificate-authority

含义:指向证书颁发机构(CA)证书文件的路径,用于验证服务器证书的合法性。

--client-certificate

含义:指向用于TLS(传输层安全协议)的客户端证书文件的路径。

--client-key

含义:指向用于TLS的客户端密钥文件的路径。

--cluster

含义:指定要使用的kubeconfig中的集群名称。kubeconfig是Kubernetes用于配置客户端访问集群的文件。

--context

含义:指定要使用的kubeconfig中的上下文名称。上下文包含了集群、用户和命名空间等信息,用于确定如何与集群进行交互。

--disable-compression

含义:如果设置为true,对发送到服务器的所有请求都不使用响应压缩。

--dry-run

含义:必须是"none"、"server"或"client"之一。如果是"client"策略,仅打印出将要发送到服务器的对象,而不实际执行创建操作;"server"可能在服务器端进行一些验证但不持久化;"none"则是正常执行操作。

--field-manager

含义:用于跟踪字段所有权的管理器名称。

--from-env-file

含义:指定一个文件路径,用于读取以键值对(key=val)形式的行来创建configmap。

--from-file

含义:可以使用文件路径来指定键文件,在这种情况下,文件的基本名称(不含路径)将被用作configmap中的键,文件内容作为值。

--from-literal

含义:指定一个键和一个字面量值,用于插入到configmap中(例如mykey=somevalue)。

--help

含义:显示configmap相关的帮助信息。

--insecure-skip-tls-verify

含义:如果设置为true,将不会检查服务器证书的有效性。这会使你的连接变得不安全,但在某些测试或特殊环境下可能会用到。

--kubeconfig

含义:指向用于命令行接口(CLI)请求的kubeconfig文件的路径。

--log-flush-frequency

含义:日志刷新的最大间隔秒数,即多久将日志缓冲区中的内容刷新输出一次。

--match-server-version

含义:要求服务器版本与客户端版本匹配。

--namespace

含义:如果存在此选项,它指定了这个命令行请求的命名空间范围。命名空间用于在Kubernetes集群中对资源进行隔离和分组。

--output

含义:输出格式。可以是以下之一:(json、yaml、name、go-template、go-template-file、template等),用于指定命令执行结果的输出格式。

--password

含义:用于对API服务器进行基本身份验证的密码。

--profile

含义:要捕获的性能分析(profile)名称。可以是(none、cpu、heap、goroutine、threadcreate、block、mutex)之一,用于对Kubernetes组件的性能进行分析。

--profile-output

含义:指定要将性能分析结果写入的文件名。

--request-timeout

含义:在放弃单个服务器请求之前等待的时间长度。非零值会设置请求超时时间,避免长时间等待无响应的服务器。

--save-config

含义:如果设置为true,当前对象的配置将保存在其注释中。否则,不会保存配置。

--server

含义:Kubernetes API服务器的地址和端口,用于指定客户端连接的服务器位置。

--show-managed-fields

含义:如果设置为true,在以JSON或YAML格式打印对象时,保留managedFields字段。这些字段通常用于记录资源的管理信息。

--template

含义:当-o=go-template、-o=go-template-file等输出格式选项被使用时,指定要使用的模板字符串或模板文件路径。

--tls-server-name

含义:用于服务器证书验证的服务器名称。如果未提供,将使用主机名进行验证。

--token

含义:用于对API服务器进行身份验证的承载令牌(Bearer Token)。

--username

含义:用于对API服务器进行基本身份验证的用户名。

--user

含义:指定要使用的kubeconfig用户的名称。

--validate

含义:必须是以下之一:strict(或true)、warn、ignore(或false),用于指定对资源配置的验证级别。

--vmodule

含义:逗号分隔的pattern=N设置列表,用于基于文件过滤的日志记录(仅适用于特定的日志系统)。

--v

含义:日志级别详细程度的数字表示,用于控制日志输出的信息量。

--warnings-as-errors

含义:将从服务器接收到的警告视为错误,并以非零退出码退出命令执行。

5.2使用文件创建

通过指定文件创建一个 configmap,--from-file=<文件>,若没有定义key,则使用文件名作为key,文件内容作为value

bash 复制代码
cat nginx.conf

server {

server_name www.nginx.com;

listen 80;

root /home/nginx/www/

}

执行

kubectl create configmap nginx-conf --from-file=www.conf=./nginx.conf

6.案例-把 configmap 做成 volume,挂载到 pod

nginx

创建pod:

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-test1
  labels:
    app: nginx129
spec:
  containers:
  - name: nginx129
    ports:
    - containerPort: 81
    image: nginx:latest
    imagePullPolicy: IfNotPresent

kubectl cp pod-test1:/etc/nginx/conf.d/default.conf ./config/default.conf

创建configmap:

kubectl create cm nginx-conf --from-literal default.conf=./default.conf

创建服务:

bash 复制代码
cat svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: svc-test
spec:
  type: NodePort
  ports:
  - targetPort: 81
    port: 808
  selector:
    app: nginx129

更新pod容器:添加挂载

bash 复制代码
cat nginx-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-test1
  labels:
    app: nginx129
spec:
  containers:
  - name: nginx129
    ports:
    - containerPort: 81
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: nginx-config  # 保持与下方 volumes.name 一致
      mountPath: /etc/nginx/conf.d/
  volumes:
  - name: nginx-config    # 必须与 configMap.name 一致
    configMap:
      name: nginx-conf    # 必须与已存在的 ConfigMap 名称一致

可以删除旧的pod,重新创建

访问:

svc-test的访问端口号是30942

二、Secret资源

1.Secret概述

k8s secrets**用于存储和管理一些敏感数据,比如密码,token,密钥等敏感信息。**它把 Pod 想要访问的加密数据存放到 Etcd 中。然后用户就可以通过在 Pod 的容器里挂载 Volume 的方式或者环境变量的方式访问到这些 Secret 里保存的信息了。

Secret 类似于 ConfigMap,但专门用于保存机密数据。

2.Secret 类型

内置类型 用法
Opaque 用户定义的任意数据
kubernetes.io/service-account-tokensymotion 服务账号令牌
kubernetes.io/dockercfg ~/.dockercfg 文件的序列化形式
kubernetes.io/dockerconfigjson ~/.docker/config.json 文件的序列化形式
kubernetes.io/basic-auth 用于基本身份认证的凭据
kubernetes.io/ssh-auth 用于 SSH 身份认证的凭据
kubernetes.io/tls 用于 TLS 客户端或者服务器端的数据
bootstrap.kubernetes.io/token 启动引导令牌数据

kubectl 创建类型

shell 复制代码
[root@k8s-master01 ~]# kubectl create secret dotfile -h
Create a secret using specified subcommand.

Available Commands:
  docker-registry   创建一个给 Docker registry 使用的 secret
  generic           Create a secret from a local file, directory, or literal value
  tls               创建一个 TLS secret

Usage:
  kubectl create secret [flags] [options]

Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).
  • docker-registry: 连接私有镜像仓库的凭证(据)
  • generic: 常见 secret, 该类型 secret 与 configmap使用相同
  • tls: 提供 tls 证书, 在 service mesh 中自动挂载

3.使用

3.1使用命令创建

3.2使用yaml文件创建

注意:用户名和密码需要用密文,base64位

bash 复制代码
cat s2.yqml 
apiVersion: v1
kind: Secret
metadata:
  name: secret-volume
  namespace: wezzer1
type: Opaque
data:
  password: MTIzLmNvbQ==
  username: YWRtaW4=
immutable: true # `immutable` 字段设置为 `true` 创建不可更改的 Secret

4.案例-mysql主从复制

4.1配置文件准备

bash 复制代码
cat mysql-configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-config
data:
  # 主库配置
  master.cnf: |
    [mysqld]
    server-id=1
    log_bin=mysql-bin
    skip-host-cache
    skip-name-resolve

  # 从库配置
  slave.cnf: |
    [mysqld]
    server-id=2
    relay_log=mysql-relay-bin
    log_bin=mysql-bin
    read_only=1
    skip-host-cache
    skip-name-resolve

  # 主库初始化脚本
  init-master.sh: |
    #!/bin/bash
    set -e
    
    # 等待MySQL启动
    until mysqladmin ping -h localhost --silent; do
        echo "等待主库MySQL启动..."
        sleep 2
    done
    
    # 配置主库复制用户
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "CREATE USER IF NOT EXISTS 'repl'@'%' IDENTIFIED BY '$REPLICATION_PASSWORD';"
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';"
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "FLUSH PRIVILEGES;"
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "CREATE DATABASE IF NOT EXISTS testdb;"
    
    # 记录主库状态到文件,供从库使用
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "SHOW MASTER STATUS\G" > /var/lib/mysql/master-status.txt

  # 从库初始化脚本
  init-slave.sh: |
    #!/bin/bash
    set -e
    
    # 等待从库MySQL启动
    until mysqladmin ping -h localhost --silent; do
        echo "等待从库MySQL启动..."
        sleep 2
    done
    
    # 等待主库就绪
    until mysqladmin ping -h mysql-master --silent -u root -p"$MYSQL_ROOT_PASSWORD"; do
        echo "等待主库就绪..."
        sleep 2
    done
    
    # 从主库获取状态信息
    MASTER_STATUS=$(mysql -u root -p"$MYSQL_ROOT_PASSWORD" -h mysql-master -e "SHOW MASTER STATUS\G")
    MASTER_LOG_FILE=$(echo "$MASTER_STATUS" | grep 'File:' | awk '{print $2}')
    MASTER_LOG_POS=$(echo "$MASTER_STATUS" | grep 'Position:' | awk '{print $2}')
    
    # 配置从库复制
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "STOP SLAVE;"
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "CHANGE MASTER TO
      MASTER_HOST='mysql-master',
      MASTER_USER='repl',
      MASTER_PASSWORD='$REPLICATION_PASSWORD',
      MASTER_LOG_FILE='$MASTER_LOG_FILE',
      MASTER_LOG_POS=$MASTER_LOG_POS;"
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "START SLAVE;"
    
bash 复制代码
cat mysql-master.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mysql-master
  labels:
    app: mysql
    role: master
spec:
  containers:
  - name: mysql
    image: mysql:8.0
    ports:
    - containerPort: 3306
    env:
    - name: MYSQL_ROOT_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mysql-secrets
          key: root-password
    - name: REPLICATION_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mysql-secrets
          key: replication-password
    volumeMounts:
    - name: master-config
      mountPath: /etc/mysql/conf.d/master.cnf
      subPath: master.cnf
    - name: init-scripts
      mountPath: /docker-entrypoint-initdb.d/init-master.sh
      subPath: init-master.sh
    - name: master-data
      mountPath: /var/lib/mysql
    # 健康检查
    livenessProbe:
      exec:
        command: ["mysqladmin", "ping", "-u", "root", "-p$(MYSQL_ROOT_PASSWORD)"]
      initialDelaySeconds: 30
      periodSeconds: 10
  volumes:
  - name: master-config
    configMap:
      name: mysql-config
  - name: init-scripts
    configMap:
      name: mysql-config
      defaultMode: 0755  # 确保脚本可执行
  - name: master-data
    emptyDir: {}  # 生产环境建议使用PersistentVolume
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-master
spec:
  selector:
    app: mysql
    role: master
  ports:
  - port: 3306
    targetPort: 3306
    
bash 复制代码
cat mysql-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secrets
type: Opaque
data:
  # 密码需要base64编码,示例密码是"root123"和"repl123"
  root-password: cm9vdDEyMw==
  replication-password: cmVwbDEyMw==
bash 复制代码
 cat mysql-slave.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mysql-slave
  labels:
    app: mysql
    role: slave
spec:
  containers:
  - name: mysql
    image: mysql:8.0
    ports:
    - containerPort: 3306
    env:
    - name: MYSQL_ROOT_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mysql-secrets
          key: root-password
    - name: REPLICATION_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mysql-secrets
          key: replication-password
    volumeMounts:
    - name: slave-config
      mountPath: /etc/mysql/conf.d/slave.cnf
      subPath: slave.cnf
    - name: init-scripts
      mountPath: /docker-entrypoint-initdb.d/init-slave.sh
      subPath: init-slave.sh
    - name: slave-data
      mountPath: /var/lib/mysql
    # 健康检查
    livenessProbe:
      exec:
        command: ["mysqladmin", "ping", "-u", "root", "-p$(MYSQL_ROOT_PASSWORD)"]
      initialDelaySeconds: 30
      periodSeconds: 10
  volumes:
  - name: slave-config
    configMap:
      name: mysql-config
  - name: init-scripts
    configMap:
      name: mysql-config
      defaultMode: 0755  # 确保脚本可执行
  - name: slave-data
    emptyDir: {}  # 生产环境建议使用PersistentVolume
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-slave
spec:
  selector:
    app: mysql
    role: slave
  ports:
  - port: 3306
    targetPort: 3306

使用create -f创建后


4.2验证失败

bash 复制代码
show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Reconnecting after a failed source event read
                  Master_Host: mysql-master
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 1017
               Relay_Log_File: mysql-relay-bin.000003
                Relay_Log_Pos: 326
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Connecting
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1017
              Relay_Log_Space: 705
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 2061
                Last_IO_Error: Error reconnecting to source 'repl@mysql-master:3306'. This was attempt 3/86400, with a delay of 60 seconds between attempts. Message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 30a8cb04-7a61-11f0-a655-76a4e638e8e5
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 250816 05:41:37
     Last_SQL_Error_Timestamp: 

出现这个问题是版本不兼容导致的

4.3版本不兼容修改配置

进入主库:

从库:

验证:

进入主库:

kubectl exec -it mysql-master -- mysql -u root -proot123

进入从库:

kubectl exec -it mysql-slave -- mysql -u root -proot123

总结

希望可以帮助其他小伙伴们