配置与存储
配置管理
ConfigMap
ConfigMap的创建
- 一般用于去存储 Pod 中应用所需的一些配置信息,或者环境变量,将配置于 Pod 分开,避免应为修改配置导致还需要重新构建 镜像与容器。
- configmap缩写为cm
kubectl create cm -h
来查看创建命令
- 指定目录去创建
- 比如我在config目录中创建test目录,在里面简单配置两个配置文件,db.properties , redis.properties
- 在config目录执行命令
kubectl create configmap test-dir-config --from-file=test/
- 基于指定的文件去创建(用的最多)
- 在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 来禁止修改,这个命令是与最外层的命令是同级的。