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 来禁止修改,这个命令是与最外层的命令是同级的。
相关推荐
Code哈哈笑9 分钟前
【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活
java·开发语言·学习
年薪丰厚39 分钟前
如何在K8S集群中查看和操作Pod内的文件?
docker·云原生·容器·kubernetes·k8s·container
zhangj112540 分钟前
K8S Ingress 服务配置步骤说明
云原生·容器·kubernetes
岁月变迁呀42 分钟前
kubeadm搭建k8s集群
云原生·容器·kubernetes
墨水\\42 分钟前
二进制部署k8s
云原生·容器·kubernetes
Source、44 分钟前
k8s-metrics-server
云原生·容器·kubernetes
上海运维Q先生1 小时前
面试题整理15----K8s常见的网络插件有哪些
运维·网络·kubernetes
颜淡慕潇1 小时前
【K8S问题系列 |19 】如何解决 Pod 无法挂载 PVC问题
后端·云原生·容器·kubernetes
QQ同步助手1 小时前
如何正确使用人工智能:开启智慧学习与创新之旅
人工智能·学习·百度
流浪的小新1 小时前
【AI】人工智能、LLM学习资源汇总
人工智能·学习