{"msg":"操作成功","code":200,"data":{"createBy":"admin","createTime":"2021-08-15 17:49:01","updateBy":"admin","updateTime":"2021-08-15 17:49:01","remark":null,"id":68,"articleTitle":"Kubernetes（六）ConfigMap配置管理","articleUrl":"k8s_configmap","articleThumbnail":"https://www.asumimoe.com/imgfiles/20220906/f93daad129a04b8db74eed70cd45263b.png","articleFlag":"0","draftStatus":"1","reprintStatement":"1","articleSummary":"应用部署的一个最佳实践是将应用所需的配置信息与程序进行分离，这样可以使得应用程序被更好地复用，通过不同的配置也能实现更灵活的功能。从Kubernetes v1.2开始提供了一种统一的应用配置管理方案——ConfigMap。","articleContent":"## ConfigMap介绍\n\n应用部署的一个最佳实践是将应用所需的配置信息与程序进行分离，这样可以使得应用程序被更好地复用，通过不同的配置也能实现更灵活的功能。\n 将应用打包为容器镜像后，可以通过环境变量或者外挂文件的方式在创建容器时进行配置注入，但在大规模容器集群的环境中，对多个容器进行不同的配置将变得非常复杂。\n 从Kubernetes v1.2开始提供了一种统一的应用配置管理方案——ConfigMap。\n\nConfigMap供容器使用的典型用法如下。\n （1）生成为容器内的环境变量。\n （2）设置容器启动命令的启动参数（需设置为环境变量）。\n （3）以Volume的形式挂载为容器内部的文件或目录。\n\nConfigMap以一个或多个key:value的形式保存在Kubernetes系统中供应用使用，既可以用于表示一个变量的值（例如apploglevel=info），也可以用于表示一个完整配置文件的内容（例如server.xml=<?xml...>...）。可以通过YAML配置文件或者直接使用kubectl create configmap命令行的方式来创建ConfigMap。\n\n## 创建ConfigMap资源对象\n\n### 1.命令行方式\n\n1）通过`--from-file`参数从文件中进行创建，可以指定key的名称，也可以在一个命令行中创建包含多个key的ConfigMap，语法为：\n\n```vbnet\nkubectl create configmap NAME --from-file=[key=]source --from-file=[key=]source \n```\n\n2）通过`--from-file`参数从目录中进行创建，该目录下的每个配置文件名都被设置为key，文件的内容被设置为value，语法为：\n\n```delphi\nkubectl create configmap NAME --from-file=config-file-dir\n```\n\n3）使用--from-literal时会从文本中进行创建，直接将指定的`key#=value#`创建为ConfigMap的内容，语法为：\n\n```csharp\nkubectl create configmap NAME --from-literal=key1=value1 --from-literal=key2=value2 \n```\n\n### 2.yaml文件方式\n\n1）将应用所需变量定义为ConfigMap\n\n```yaml\n# cm-appvars.yml\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cm-appvars\ndata:\n  apploglevel: info\n  appdatadir: /var/data\n```\n\n```shell\n[root@master ~]# kubectl apply -f cm-appvars.yml \nconfigmap/cm-appvars created\n\n[root@master ~]# kubectl get cm\nNAME               DATA   AGE\ncm-appvars         2      19s\n\n[root@master ~]# kubectl describe cm cm-appvars\nName:         cm-appvars\nNamespace:    default\nLabels:       <none>\nAnnotations:  <none>\n\nData\n====\nappdatadir:\n----\n/var/data\napploglevel:\n----\ninfo\nEvents:  <none>\n```\n\n\n\n2）将应用配置文件定义为ConfigMap，key为配置文件的别名，value为配置文件的全部内容。如将server.xml和logging.properties定义为ConfigMap。\n\n```yaml\n# cm-appconfigfiles.yml\n\napiVersion: v1\nkind: ConfigMap\nmetedata:\n  name: cm-appconfigfiles\ndata:\n  key-serverxml: |\n    <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n    <Server port=\"8005\" shutdown=\"SHUTDOWN\">\n      <Listener className=\"org.apache.catalina.startup.VersionLoggerListener\" />\n    ......\n    </Server>\n  key-loggingproperties: |\n    handlers =1catalina.org.apache.juli.AsyncFileHandler,2localhost.org.apache.juli.AsyncFileHandler, 3manager.org.apache.juli.AsyncFileHandler, 4host-manager.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler\n    ......\n```\n\n## ConfigMap使用\n\n容器中对ConfigMap的使用有以下两种方式：\n\n1）通过环境变量获取ConfigMap中的内容；\n\n2）通过Volume挂载的方式将ConfigMap中的内容挂载为容器内部的文件或目录。\n\n### 1.环境变量方式\n\n以上一步生成的cm-appvars为例。\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: cm-pod\nspec:\n  containers:\n  - name: cm-pod\n    image: busybox\n    env:\n    - name: APPLOGLEVEL # 定义环境变量的名称\n      valueFrom: # 环境变量\"apploglevel\"对应的值\n        configMapKeyRef:      \n          name: cm-appvars # 环境变量的值取自名为cm-appvars的ConfigMap\n          key: apploglevel # 在该ConfigMap中的key为apploglevel\n    - name: APPDTATDIR\n      valueFrom:\n        configMapKeyRef:\n          name: cm-appvars\n          key: appdatadir\n    args:\n    - /bin/sh\n    - -c\n    - env | grep APP\n  restartPolicy: Never\n```\n\n```shell\n[root@master ~]# kubectl create -f cm-pod.yml \npod/cm-pod created\n[root@master ~]# kubectl logs cm-pod\nAPPLOGLEVEL=info\nAPPDTATDIR=/var/data\n```\n\nKubernetes从1.6版本开始，引入了一个新字段envFrom，实现了再Pod环境中将ConfigMap中所有定义的key=value自动生成为环境变量。\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: cm-pod\nspec:\n  containers:\n  - name: cm-pod\n    image: busybox\n    envFrom:\n    - configMapRef:\n      name: cm-appvars\n# 通过这个定义，容器中会自动生成如下环境变量\napploglevel=info\nappdatadir=/var/data\n```\n\n### 2.通过volumeMount方式\n\n以之前生成的cm-appconfigfiles为例。将该ConfigMap中的内容以文件的形式Mount到容器内部的/configfiles目录下。\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: cm-pod\nspec:\n  containers:\n  - name: cm-pod\n    image: tomcat\n    ports:\n    - containerPort: 8080\n    volumeMounts:\n    - name: config # 引用的volume的名称\n      mountPath: /configfiles # 挂载到容器的目录\n  volumes:\n  - name: config # 定义volume的名称\n    configMap:\n      name: cm-appconfigfiles\n      items:\n      - key: key-serverxml # key=key-serverxml\n        path: server.xml # value将以server.xml文件名进行挂载\n      - key: key-loggingproperties\n        path: logging.properties\n```\n\n创建容器后就可在容器/configfiles目录下看到server.xml和logging.properties两个文件。\n\n如果在yml文件中不指定items，则使用volumeMount方式在容器内的目录下挂载两个名为key的文件。\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: cm-pod\nspec:\n  containers:\n    volumeMounts:\n    - name: config\n      mountPath: /configfiles\n  volumes:\n  - name: config\n    configMap:\n      name: cm-appconfigfiles\n# 最终会在/configfiles目录下生成两个名为key-serverxml和key-loggingproperties的文件，内容为value的内容。\n```\n\n### 3.使用ConfigMap的限制条件\n\n1. ConfigMap必须在Pod之前创建。\n2. ConfigMap受namespace显示，只有处于相同namespace下的Pod才可使用。\n3. kubelet只支持可以被API Server管理的Pod使用ConfigMap，静态Pod无法使用。\n4. Pod对ConfigMap进行挂载时，容器内部只能挂载为目录，不能挂载为文件。如果在容器内原目录下还有其他文件，则其他文件将消失。\n\n## Secret加密信息管理\n\nConfigMap适用于容器的配置，这种配置一般是明文的，如果我们需要将用户名和密码等一些比较私密的数据在容器中引用就需要Secret来管理。Secret 会以密文的方式存储数据，避免了直接在配置文件中保存敏感信息。Secret 会以 Volume 的形式被 mount 到 Pod，容器可通过文件的方式使用 Secret 中的敏感数据；此外，容器也可以环境变量的方式使用这些数据\n\n### 1.创建\n\nyaml文件方式创建：\n\n```yaml\n# secret.yml\napiVersion: v1\nkind: Secret\nmetadata:\n  name: mysecret\ntype: Opaque\ndata:\n  username: a2VuCg== # 编码方式必须为BASE64格式\n  password: MTIzCg==\n```\n\n命令行方式：\n\n```shell\n# 通过 –from-literal：每个 –from-literal 对应一个信息条目。\nkubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123456\n\n# 通过 –from-file：每个文件内容对应一个信息条目。\necho -n admin > ./username\necho -n 123456 > ./password\nkubectl create secret generic mysecret --from-file=./username --from-file=./password\n\n# 通过 –from-env-file：文件 env.txt 中每行 Key=Value 对应一个信息条目。\ncat << EOF > env.txt\nusername=admin\npassword=123456\nEOF\nkubectl create secret generic mysecret --from-env-file=env.txt\n```\n\n### 2.引用\n\nvolume挂载方式：\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: pod-secret\nspec:\n  containers:\n  - name: pod-secret\n\timage: busybox\n\tvolumeMounts:\n\t- name: foo\n\t  mountPath: /foo\n\t  readOnly: true\n  volumes:\n  - name: foo\n    secret:\n\t  secretName: mysecret\n# 会在/foo目录下生成两个文件，文件名即为mysecret中的data下的key值，文件内容为value值。\n```\n\n环境变量方式：\n\n```yml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: pod-secret2\nspec:\n  containers:\n  - name: busybox\n    image: busybox\n    env:\n    - name: MYSQL_ROOT_PASSWORD\n      valueFrom:\n        secretKeyRef:\n          name: mysecret\n          key: password\n    - name: MY_NAME\n      valueFrom:\n        secretKeyRef:\n          name: mysecret\n          key: username\n```","categoryId":10,"viewCount":1108,"categoryName":"Kubernetes","author":"球接子","authorAvatar":null,"tagIds":[16],"tagNames":["Kubernetes"]}}