欢迎访问我的博客,你的支持,是我最大的动力!

马哥_K8s进阶实战(6)ConfigMap/Secret

Docker 马从东 147℃ 评论
目录:
[显示]

容器化应用配置方式

通过命令行参数进行配置

ENTRYPOINT 和 CMD 均可以指定容器运行的程序和参数,若二者同时存在时,ENTRYPOINT指定程序,CMD提供参数
其中CMD是列表

在Pod中,则是 pods.spec.containers.command和args

将配置文件嵌入镜像文件

通过环境变量向容器注入配置信息

docker 启动时,通过 -e 注入配置信息,后由ENTRYPOINT启动脚本抓取环境变量,通过sed、echo等命令将变量替换到配置文件中
也可以让启动脚本通过网络中KV存储,如Consul或etcd等处获取配置参数
confd还可以根据KV中的数据,动态生成配置文件

在Pod中,通过spec.containers.env注入环境变量

通过存储卷向容器注入配置信息

借助Docker config进行容器配置

在docker swarm service环境中,可以使用docker swarm serivce secret 或 config
在K8s中,则是Secret和ConfigMap

通过命令行参数配置容器应用

Pod中,使用command指定要运行的程序,args字段用于指定传统给程序的选项和参数
在配置文件中定义command和args会覆盖镜像文件中的默认设定

busybox镜像中默认运行的命令是 ["/bin/sh","-c"]

若只配置args字段,则向默认运行的程序提供额外的参数,如 /bin/sh -c httpd -f

K8s中的command对应于Dockerfile中的ENTRYPOINT;args对应于CMD
只给出command时,会覆盖ENTRYPOINT和CMD;只给出args时,会覆盖CMD;同时给出时,分别覆盖
容器创建完成后,修改command和args不会直接生效,除非重建Pod对象

利用环境变量配置容器应用

对于不支持从环境变量获取配置的应用,可以通过 ENTRYPOINT 启动脚本进行转换。

使用 env 字段,其值为由环境变量构建的列表
name,必须,环境变量名称
value,环境变量的值,通过 $(VAR_NAME) 引用,逃逸格式为 $$(VAR_NAME),默认值为空
valueFrom,引用Pod资源信息,如名称、标签、容器相关的系统资源配置、ConfigMap对象及Secret对象中的Key
# kubectl explain pods.spec.containers.env.valueFrom
-fieldRef 当前Pod资源的指定字段,包括
== metadata.name metadata.namespace metadata.labels metadata.annotations
== spec.nodeName spec.serviceAccountName status.hostIP status.podIP
-configMapKeyRef 从ConfigMap中获取特定Key
-secretKeyRef 从Secret中获取特定Key
-resourceFieldRef 获取当前容器的特定系统资源配额和限额,包括
== limits.cpu limits.memory limits.ephemeral-storage requests.cpu requests.memory requests.ephemeral-storage

kubectl exec env-demo -- env

ConfigMap

将配置内容从代码中分离出来
# 分布式配置中心开源项目 Diamond(阿里)、Apollo(携程)、Qconf(360)、disconf(百度)

一个 ConfigMap 对象就是一系列配置数据的集合,注入Pod的方式有挂载为存储卷或传递为环境变量
ConfigMap 将配置数据以键值对形式进行存储

创建 ConfigMap 对象

kubectl create configmap <map-name> <data-source>
其中 map-name 是ConfigMap对象名称;data-source 是数据源,可以是值、文件或目录

1、利用直接值创建
kubectl create configmap configmap_name --from-literal=key=value
# 示例
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
kubectl get configmaps special-config -o yaml --export

2、基于文件创建
kubectl create configmap configmap_name --from-file=path-to-file
kubectl create configmap <configmap_name> --from-file=<key_name>=<path-to-file>   #自定义键名 而不使用原文件名
# 示例
kubectl create configmap nginx-config --from-file=b.txt --from-file=/root/a.yaml
kubectl get configmaps nginx-config -o yaml
键为文件名(不含路径),值为文件内容

基于直接值和基于文件两种方式可以混编使用

3、基于目录创建
kubectl create configmap <configmap_name> --from-file=<path-to-dir>
注,包含以.开始的隐藏文件,但不会包含子目录
# 示例
kubectl create configmap metrics --from-file=/root/metrics-server-0.3.1

4、使用清单创建

Pod环境变量中使用ConfigMap

kubectl explain pods.spec.containers.env.valueFrom.configMapKeyRef
参数:
key,必须,要引用的键名
name,ConfigMap对象名称
optional,boolean,引用是否可选

kubectl exec configmap-env-demo -- ps aux

ConfigMap是基于名称空间的,被引用的资源必须事先存在,否则容器将无法启动
envFrom字段的值是列表,为防止从多个ConfigMap引用时产生的键名冲突,可以添加一个前缀,如HH_,这样 http_port 将变成 HH_http_port
若键名中有连接线 - 在转换为变量名时会替换为下划线 _
下面是导入ConfigMap导入所有键的语法:
kubectl explain pods.spec.containers.envFrom

ConfigMap 存储卷

挂载整个存储卷

每个键对应一个文件,键名就是文件名,键值就是文件内容

kubectl exec configmap-volume-demo -- ls -la /opt

挂载部分键值

独立挂载文件

对于前两种挂载方式,若挂载点目录下有文件,则会被隐藏
若需单独挂载文件,补充到挂载点目录下,则可使用独立挂载,使用subPath

容器应用重载新配置

支持容器应用动态更新配置
直接更新ConfigMap中的内容,会立即返回到容器器中挂载的文件(方件由两级符号链接构成,支持动态更新)
此时,文件已经更新,应该程序要支持重载配置,才会生效
注意,因为新的配置信息并非同步推送进所有容器中,且重载操作也不一定能同时进行,在短时间内,会存在配置不一致的现象

注意,独立挂载方式挂载的文件,因为不是两级链接的形式,所以不支持动态更新

使用 ConfigMap 资源的注意事项:
1、以存储卷方式引用ConfigMap必须先于Pod存在,除非全部标记为optional,否则会导致Pod无法启动
2、存在ConfigMap,但引用的键不存在时,除非标记为optional,否则会导致Pod无法启动
3、以环境变量方式注入ConfigMap中的键不存在时,会忽略,Pod可正常启动,但错误的引用会以 InvalidVariableNames 记录于日志中
4、ConfigMap是名称空间级的资源

Secret

类似于ConfigMap,但专用于存储敏感数据,如密码、证书、私钥、令牌等

Secret对象仅会被分发至调用了些对象的Pod所在的节点,且只能由节点将其存储于内存中。Secret数据的存储及打印是Base64编码的,在容器中以环境变量或存储卷方式访问时,会被自动解码为明文。Secret是以非加密格式存储于etcd中的。
所有拥有创建Pod资源的用户都可以使用Secret资源并能通过Pod中容器访问其数据

Secret主要两种用途:注入容器供容器使用;存储私有仓库认证信息
用ServiceAccount资源自建的Secret对象是更安全的方式

Secret资源四种类型
Opaque,自定义数据内容,base64编码,存储密码、密钥、信息、证书等,类型标识符为 generic
kubernetes.io/service-account-token,Service Account的认证信息,可在创建ServiceAccount时由K8s自动创建
kubernetes.io/dockerconfigjson,存储镜像仓库认证信息,类型标识符为 docker-registry
kubernetes.io/tls,SSL通信的证书和私钥文件,类型标识符为 tls

创建 Secret 资源

命令式创建

generic

kubectl create secret generic <secret_name> --from-literal=key=value
kubectl create secret generic <secret_name> --from-file[=key]=<path_to_file>
# 作为认证用户时,键名通常使用 username password
kubectl create secret generic mysql-auth --from-literal=username=root --from-literal=password=mypasswd
kubectl get secrets mysql-auth -o yaml
## base64解码: echo bXlwYXNzd2Q= | base64 -d
kubectl create secret generic file --from-file=a.yml

tls

kubectl create secret tls <secret_name> --cert= --key=
# 自签证书
(umask 077; openssl genrsa -out nginx.key 2048)
openssl req -new -x509 -key nginx.key -out nginx.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=www.ilinux.io
# 创建secret对象 无论用户提供的证书和私钥名称是什么,会一律转换为 tls.key 和 tls.crt
kubectl create secret tls nginx-ssl --key=nginx.key --cert=nginx.crt

清单式创建

kubectl explain secret
参数:
data <map[string]string>,key:value格式数据,value需是base64格式
stringDate <map[string]string>,明文格式,创建时自动用base64编码,并存储于data字段;明文不会被API Server输出,但若使用kubectl apply则会存在注解中
type,类型 Opaque等

Secret 存储卷

Secret可注入为环境变量或存储卷,但容器应用通常会在发生错误时,将所有环境变量保存于日志信息中,或在启动时就将环境打印到日志中,所以不推荐使用环境变量引用Secret

kubectl exec secret-volume-demo -- ls /etc/nginx/ssl

imagePullSecret

方式一:创建docker-registry类型Secret,在定义Pod时通过imagePullSecrets字段给出
方式二:创建docker-registry类型Secret,将其添加到某ServiceAccount对象中,则使用该ServiceAccount创建的Pod对象,默认会直接使用imagePullSecrets中的认证信息

kubectl create secret docker-registry <secret_name> --docker-username=<username> --docker-password=<pass> --docker-email=<email>
# 示例
kubectl create secret docker-registry local-registry --docker-username=aaa --docker-password=bbb --docker-email=ccc@ddd.ee

 

转载请注明:轻风博客 » 马哥_K8s进阶实战(6)ConfigMap/Secret

喜欢 (0)or分享 (0)