K8s学习八(配置与存储_配置)

配置与存储

配置管理

ConfigMap
ConfigMap的创建
  • 一般用于去存储 Pod 中应用所需的一些配置信息,或者环境变量,将配置于 Pod 分开,避免应为修改配置导致还需要重新构建 镜像与容器。
  • configmap缩写为cm
  • kubectl create cm -h来查看创建命令
  1. 指定目录去创建
  • 比如我在config目录中创建test目录,在里面简单配置两个配置文件,db.properties , redis.properties
  • 在config目录执行命令kubectl create configmap test-dir-config --from-file=test/
  1. 基于指定的文件去创建(用的最多)
  • 在test目录下面创建application.yaml,然后下面进行操作
  • 执行kubectl create cm spring-test-yaml --from-file=/root/k8s/config/test/application.yaml
  • 这样描述cm之后里面信息的文件名就是application.yaml,要是想改变文件名可以执行kubectl create cm spring-test-yaml --from-file=app.yaml=/root/k8s/config/test/application.yaml,就变成了app.yaml
  • 参数比较少时,可以自己指定参数,执行kubectl create cm spring-test-yaml --from-literal=username=root --from-literal=password=admin
cm环境变量加载与配置文件加载
cm环境变量加载
  • 配置文件如下所示:
bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: test-env-cm
spec:
  containers:
  - name: env-test
    image: alpine
    command: ["/bin/bash", "-c", "env;sleep 3600"]
    imagePullPolicy: IfNotPresent
    env:
    - name: JAVA_VM_OPTS
      valueFrom:
        configMapKeyRef:
          name: test-env-config # config的名字
          key: JAVA_OPTS_TEST # 表示从上面name的cm中获取名字为key的value,将其赋值给本地环境变
量 JAVA_VM_OPTS,也就是name为JAVA_VM_OPTS的值是从test-env-config这个cm的JAVA_OPTS_TEST这个key取
到的值给他
    - name: APP
      valueFrom:
        configMapKeyRef:
          name: test-env-config # config的名字
          key: APP_NAME
  restartPolicy: Never

# 下面是用到的config:
root@master:~/k8s/config# kubectl describe cm test-env-config
Name:         test-env-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
APP_NAME:
----
springboot_env-test
JAVA_OPTS_TEST:
----
-Xms512m -Xmx512m

BinaryData
====

Events:  <none>
cm配置文件加载
  • 配置文件如下所示:
bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: test-configfile-pod
spec:
  containers:
  - name: config-test
    image: alpine
    command: ["/bin/sh", "-c", "env;sleep 3600"]
    imagePullPolicy: IfNotPresent
    env:
    - name: JAVA_VM_OPTS
      valueFrom:
        configMapKeyRef:
          name: test-env-config # config的名字
          key: JAVA_OPTS_TEST # 表示从上面name的cm中获取名字为key的value,将其赋值给本地环境变
量 JAVA_VM_OPTS,也就是name为JAVA_VM_OPTS的值是从test-env-config这个cm的JAVA_OPTS_TEST这个key取
到的值给他
    - name: APP
      valueFrom:
        configMapKeyRef:
          name: test-env-config # config的名字
          key: APP_NAME
    volumeMounts: # 加载数据卷
    - name: db-config # 表示加载volume属性中的哪个数据卷
      mountPath: "/usr/local/mysql/conf" # 将想要的数据卷中的文件加载到哪个目录下
      readOnly: true # 是否只读
  volumes: # 数据卷挂载,可以是configmap和secret
    - name: db-config # 数据卷的名字,随意设置
      configMap: # 数据卷的类型为configmap
        name: test-dir-config  # configmap的名字,必须跟想要加载的cm名字相同
        items: # 对configmap中的key进行映射,如果不指定的话,会默认将configmap中所有的key全部>转换为一个个同名的文件,这里指定的话可以将path的命名和key不一样
        - key: "db.properties" # configmap中的key
          path: "db.properties" # 将该key的值转换为文件
  restartPolicy: Never

#  对configmap中的key进行映射,如果不指定的话,会默认将configmap中所有的key全部>转换为一个个同名的文件,这里指定的话可以将path的命名和key不一样
# 也就是原来的key为db.xxx,可以将path写为db.properties

# 上面就实现了cm的配置文件加载
  • 进入容器之后查看

  • 发现只有db.properties,也就是定义了items之后只会加载path上的那个文件,如果不定义则会有所有文件。

加密数据配置Secret
  • Secret 的应用,kubectl create secret -h查看命令,有三种形式如下。用第一种比较多

  • 有一个问题是,如果有特殊字符的话,创建后的可能和创建时输入的不一样:

  • 比如kubectl create secret generic orig-secret --from-literal=username=admin --from-literal=password=ds@!30,这里password有特殊字符,所以创建后的可能不一样

  • 当创建好之后,可以直接输入名称来查看,发现显示的是字节数

Docker仓库Secret配置
  • 这里听了个大概,没有实操

  • 可以看帮助,了解一下大概使用方法kubectl create secret docker-registry -h

  • 常用场景就是配置一个secret,里面有用户名和密码,然后配置文件,里面用到刚才这个secret,如果拉取镜像没有登陆的话,会使用配置文件给出的这个secret里的信息去登陆然后拉取镜像

  • 这里直接上配置文件

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: private-image-pull-pod
spec:
  imagePullSecrets:
  - name: harbor-secret # 意思就是当拉取镜像的时候,如果没有登陆,则会去找到harbor-secret这个Secret配置文件的用户名和密码去登陆。
  containers:
  - name: nginx
    image: 192.168.113.122:8858/opensource/nginx:1.9.1
    command: ["/bin/sh", "-c", "env;sleep 3600"]
    imagePullPolicy: IfNotPresent
    env:
    - name: JAVA_VM_OPTS
      valueFrom:
        configMapKeyRef:
          name: test-env-config # config的名字
          key: JAVA_OPTS_TEST # 表示从上面name的cm中获取名字为key的value,将其赋值给本地环境变
量 JAVA_VM_OPTS,也就是name为JAVA_VM_OPTS的值是从test-env-config这个cm的JAVA_OPTS_TEST这个key取
到的值给他
    - name: APP
      valueFrom:
        configMapKeyRef:
          name: test-env-config # config的名字
          key: APP_NAME
    volumeMounts: # 加载数据卷
    - name: db-config # 表示加载volume属性中的哪个数据卷
      mountPath: "/usr/local/mysql/conf" # 将想要的数据卷中的文件加载到哪个目录下
      readOnly: true # 是否只读
  volumes: # 数据卷挂载,可以是configmap和secret
    - name: db-config # 数据卷的名字,随意设置
      configMap: # 数据卷的类型为configmap
        name: test-dir-config  # configmap的名字,必须跟想要加载的cm名字相同
        items: # 对configmap中的key进行映射,如果不指定的话,会默认将configmap中所有的key全部>转换为一个个同名的文件,这里指定的话可以将path的命名和key不一样
        - key: "db.properties" # configmap中的key
          path: "db.properties" # 将该key的值转换为文件
  restartPolicy: Never
SubPath的使用
bash 复制代码
使用 ConfigMap 或 Secret 挂载到目录的时候,会将容器中源目录给覆盖掉,此时我们可能只想覆盖目录中的某一个文件,但是这样的操作会覆盖整个文件,因此需要使用到 SubPath

配置方式:
定义 volumes 时需要增加 items 属性,配置 key 和 path,且 path 的值不能从 / 开始
在容器内的 volumeMounts 中增加 subPath 属性,该值与 volumes 中 items.path 的值相同
containers:
  ......
  volumeMounts:
  - mountPath: /etc/nginx/nginx.conf # 挂载到容器哪里
    name: config-volume # 使用哪个 configmap 或 secret
    subPath: etc/nginx/nginx.conf # 与 volumes.[0].items.path 相同
volumes:
- configMap:
  name: nginx-conf # configMap 名字
  items: # subPath 配置
    key: nginx.conf # configMap 中的文件名
    path: etc/nginx/nginx.conf # subPath 路径


subpath后面跟的是volume的路径,这个路径是相对于 Volume 的根路径的,而不是绝对路径。
这样也就是将volume中的etc/nginx/nginx.conf文件挂载到容器里的/etc/nginx/nginx.conf下
ComfigMap的热更新
  • 我们通常会将项目的配置文件作为 configmap 然后挂载到 pod,那么如果更新 configmap 中的配置,会不会更新到 pod 中呢?

  • 这得分成几种情况:

    • 默认方式:会更新,更新周期是更新时间 + 缓存时间
    • subPath:不会更新
    • 变量形式:如果 pod 中的一个变量是从 configmap 或 secret 中得到,同样也是不会更新的(这里说的是pod将cm里的值当作变量,而不是当作volume挂载到pod中,后者容器中的应用程序可以直接读取这些文件来获取配置信息。)
  • 对于 subPath 的方式,我们可以取消 subPath 的使用,将配置文件挂载到一个不存在的目录,避免目录的覆盖,然后再利用软连接的形式,将该文件链接到目标位置,

  • 如下图,新创建一个文件夹目录之后,将subpath指到新目录,然后新目录创建一个软连接指到开始的那个目录,也能实现更改。

  • 但是如果目标位置原本就有文件,可能无法创建软链接,此时可以基于前面讲过的 postStart 操作执行删除命令,将默认的文件删除即可

第一种可以直接通过edit命令直接修改configmap

第二种通过replace替换

  • 由于 configmap 我们创建通常都是基于文件创建,并不会编写 yaml 配置文件,因此修改时我们也是直接修改配置文件,而 replace 是没有 --from-file参数的,因此无法实现基于源配置文件的替换,此时我们可以利用下方的命令实现

  • 该命令的重点在于 --dry-run参数,该参数的意思打印 yaml 文件,但不会将该文件发送给 apiserver,再结合 -o yaml输出 yaml 文件就可以得到一个配置好但是没有发给 apiserver 的文件,然后再结合 replace 监听控制台输出得到 yaml 数据即可实现替换.kubectl create cm test-dir-config --from-file=./test/ --dry-run -o yaml | kubectl replace -f-,输出的yaml文件作为输出当作后面管道符后面命令-f的输入。 也就是更改test文件夹里面的东西之后,然后管道符之前的是将修改后的保存成一个yaml文件,传到后面去进行修改

  • 这里不传给apiserver也就是不会生效,由于 --dry-run 参数,这个更新操作也是模拟的,不会真正应用到集群中的资源。

配置文件不可变
  • 跟上面的有出入,上面是更新,这里是不能改变。
  • 对于一些敏感服务的配置文件,在线上有时是不允许修改的,此时在pod中配置 configmap 时可以设置 immutable: true 来禁止修改,这个命令是与最外层的命令是同级的。
相关推荐
jerry6096 分钟前
LLM笔记(六)线性代数
笔记·学习·线性代数·自然语言处理
ghost14310 分钟前
C#学习第23天:面向对象设计模式
开发语言·学习·设计模式·c#
Yan_ks37 分钟前
计算机组成原理——数据的表示
学习
freellf1 小时前
go语言学习进阶
后端·学习·golang
真的想上岸啊1 小时前
学习51单片机02
嵌入式硬件·学习·51单片机
小刘要努力呀!1 小时前
嵌入式开发学习(第二阶段 C语言基础)
c语言·学习·算法
圈圈编码2 小时前
MVVM框架
android·学习·kotlin
川石教育3 小时前
测试工程师如何学会Kubernetes(k8s)容器知识
云原生·容器·kubernetes·kubernetes容器·kubernetes教程
iRayCheung4 小时前
Kind方式部署k8s单节点集群并创建nginx服务对外访问
nginx·kubernetes·kind
关于不上作者榜就原神启动那件事4 小时前
Java基础学习
java·开发语言·学习