概述

本文的核心是:如何处理应用程序的数据配置。

配置应用程序可以使用以下几种途径:

  • 向容器传递命令行参数
  • 为每个容器配置环境变量
  • 通过特殊的卷将配置文件挂载到容器中

向容器传递命令行参数

在Kubernetes中定义容器时,镜像的ENTRYPOINT和CMD都可以被覆盖(但是在Docker中,镜像的ENTRYPOINT是不能覆盖的)。仅需在容器定义中设置command和args的值。

构建一个镜像

loopechodate.sh:接收一个时间间隔的参数,追加输出当前时间到 /tmp/a.txt

  1. #! /bin/sh
  2. trap "exit" SIGINT
  3. echo "interval is : $1"
  4. while :
  5. do
  6. echo -e "$(date)" >> /tmp/a.txt
  7. sleep $1
  8. done

Dockerfile

  1. FROM alpine
  2. COPY loopechodate.sh /bin/
  3. ENTRYPOINT ["/bin/loopechodate.sh"]
  4. CMD ["5"]

构建、推送

  1. -> [root@kube0.vm] [~] docker build -t registry.cn-hangzhou.aliyuncs.com/orzi/loopechodate .
  2. -> [root@kube0.vm] [~] docker push registry.cn-hangzhou.aliyuncs.com/orzi/loopechodate

运行Pod

  1. # cat config-cli.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: config-cli
  6. spec:
  7. containers:
  8. - name: config-cli
  9. image: registry.cn-hangzhou.aliyuncs.com/orzi/loopechodate
  10. args: ["2"] # 间隔时间2s

创建这个pod,然后查看一下logs

  1. -> [root@kube0.vm] [~] k create -f config-cli.yaml
  2. pod/config-cli created
  3. -> [root@kube0.vm] [~] k exec -it config-cli cat /tmp/a.txt
  4. Sun May 24 15:49:37 UTC 2020
  5. Sun May 24 15:49:39 UTC 2020

为容器设置环境变量

Kubernetes中通过容器的env属性定义环境变量,采用$(VAR)语法在环境变量值中引用其他变量。

定义了两个环境变量FIRST_VAR,和引用了FIRST_VAR的SECOND_VAR。

  1. # config-env.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: config-env
  6. spec:
  7. containers:
  8. - name: config-env
  9. image: nginx:alpine
  10. env:
  11. - name: FIRST_VAR
  12. value: "Hello"
  13. - name: SECOND_VAR
  14. value: "$(FIRST_VAR) World!"

创建查看

  1. -> [root@kube0.vm] [~] k create -f config-env.yaml
  2. pod/config-env created
  3. -> [root@kube0.vm] [~] k exec config-env env
  4. PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  5. HOSTNAME=config-env
  6. FIRST_VAR=Hello
  7. SECOND_VAR=Hello World!
  8. .......

ConfigMap

ConfigMap本质上是一个键值对,值可以使短字面量,也可以是文件

创建ConfigMap

kubectl create configmap NAME [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run] [options]

kubectl create命令支持从字面量(--from-literal),文件、目录(--from-file)、以及环境变量文件(--from-env-file)创建。而且不同选项可以合并,但是--from-env-file不能与--from-literal和--from-file一起指定。

下面是使用字面量、文件、目录合并创建。

  1. -> [root@kube0.vm] [~] k create configmap mycm --from-literal=interval=3 --from-file=Dockerfile --from-file=/root/configdir
  2. configmap/mycm created
  3. -> [root@kube0.vm] [~] k describe cm mycm
  4. Name: mycm
  5. Namespace: default
  6. Labels: <none>
  7. Annotations: <none>
  8. Data
  9. ====
  10. Dockerfile:
  11. ----
  12. FROM alpine
  13. COPY loopechodate.sh /bin/
  14. ENTRYPOINT ["/bin/loopechodate.sh"]
  15. CMD ["5"]
  16. a.txt:
  17. ----
  18. this is configdir/a.txt
  19. b.txt:
  20. ----
  21. this is configdir/b.txt
  22. interval:
  23. ----
  24. 3
  25. Events: <none>

使用环境变量文件创建

  1. -> [root@kube0.vm] [~] echo -e "env1=1111\nenv2=2222" | tee test.env
  2. env1=1111
  3. env2=2222
  4. -> [root@kube0.vm] [~] k create cm envcm --from-env-file=test.env
  5. configmap/envcm created
  6. -> [root@kube0.vm] [~] k describe cm envcm
  7. Name: envcm
  8. Namespace: default
  9. Labels: <none>
  10. Annotations: <none>
  11. Data
  12. ====
  13. env1:
  14. ----
  15. 1111
  16. env2:
  17. ----
  18. 2222
  19. Events: <none>

传递ConfigMap条目作为环境变量

定义一个Pod,引用了mycm中的两个key。

  1. # config-env-cm.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: config-env-cm
  6. spec:
  7. containers:
  8. - name: config-env-cm
  9. image: nginx:alpine
  10. env:
  11. - name: INTERVAL
  12. valueFrom:
  13. configMapKeyRef: # 引用configMap中的内容
  14. name: mycm # configMap的名字
  15. key: interval # 引用哪个键
  16. - name: ATXT
  17. valueFrom:
  18. configMapKeyRef:
  19. name: mycm
  20. key: a.txt

创建查看

  1. -> [root@kube0.vm] [~] k create -f config-env-cm.yaml
  2. pod/config-env-cm created
  3. -> [root@kube0.vm] [~] k exec config-env-cm env
  4. PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  5. HOSTNAME=config-env-cm
  6. INTERVAL=3
  7. ATXT=this is configdir/a.txt
  8. ....

一次性传递ConfigMap所有条目作为环境变量

  1. # config-env-cmall.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: config-env-cmall
  6. spec:
  7. containers:
  8. - name: config-env-cmall
  9. image: nginx:alpine
  10. envFrom:
  11. - prefix: CONFIG_
  12. configMapRef:
  13. name: mycm

创建查看

  1. -> [root@kube0.vm] [~] k create -f config-env-cmall.yaml
  2. pod/config-env-cmall created
  3. -> [root@kube0.vm] [~] k exec config-env-cmall env
  4. PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  5. HOSTNAME=config-env-cmall
  6. CONFIG_interval=3
  7. CONFIG_Dockerfile=FROM alpine
  8. COPY loopechodate.sh /bin/
  9. ENTRYPOINT ["/bin/loopechodate.sh"]
  10. CMD ["5"]
  11. CONFIG_a.txt=this is configdir/a.txt
  12. CONFIG_b.txt=this is configdir/b.txt
  13. ........

传递ConfigMap条目作为命令行参数

containers.args无法直接引用ConfigMap,但是可以通过$(ENV_VAR_NAME)引用环境变量,间接引用ConfigMap。

  1. # config-cli-cm.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: config-cli-cm
  6. spec:
  7. containers:
  8. - name: config-cli-cm
  9. image: registry.cn-hangzhou.aliyuncs.com/orzi/loopechodate
  10. env:
  11. - name: INTERVAL
  12. valueFrom:
  13. configMapKeyRef:
  14. name: mycm
  15. key: interval
  16. args: ["$(INTERVAL)"]

创建查看

  1. -> [root@kube0.vm] [~] k create -f config-cli-cm.yaml
  2. pod/config-cli-cm created
  3. -> [root@kube0.vm] [~] k logs config-cli-cm
  4. interval is : 3
  5. -> [root@kube0.vm] [~] k exec config-cli-cm cat /tmp/a.txt
  6. Mon May 25 05:11:14 UTC 2020
  7. Mon May 25 05:11:17 UTC 2020
  8. Mon May 25 05:11:20 UTC 2020

将ConfigMap条目暴露为卷

环境变量和命令行参数作为配置值通常适用于变量值较短的场景。如果想暴露ConfigMap中配置文件,可以将ConfigMap或者其条目通过卷的形式挂载到容器。

  1. # config-volume-cm.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: config-volume-cm
  6. spec:
  7. containers:
  8. - name: config-volume-cm
  9. image: nginx:alpine
  10. volumeMounts:
  11. - name: config
  12. mountPath: /tmp/mycm
  13. readOnly: true
  14. volumes:
  15. - name: config
  16. configMap:
  17. name: mycm

创建查看

  1. -> [root@kube0.vm] [~] k create -f config-volume-cm.yaml
  2. pod/config-volume-cm created
  3. -> [root@kube0.vm] [~] k exec config-volume-cm ls /tmp/mycm
  4. Dockerfile
  5. a.txt
  6. b.txt
  7. interval

如果只想暴露指定的条目,可以指定volumes.configMap.items

  1. volumes:
  2. - name: config
  3. configMap:
  4. name: mycm
  5. items:
  6. - key: interval
  7. path: interval2

输出结果是:

  1. -> [root@kube0.vm] [~] k exec config-volume-cm ls /tmp/mycm
  2. interval2

configMap.defaultMode设置访问权限

挂载文件夹会隐藏该文件夹中已存在的文件,挂载ConfigMap的单独条目不会隐藏其他文件

Secret

Secret与ConfigMap一样都是键值对,也可以作为环境变量传递给容器,条目也能暴露称为卷中的文件。但是为了安全起见,请始终使用Secret卷暴露Secret。Secret只会存储在内存中,永不写入物理存储。Secret条目的内容会被进行Base64编码。

默认令牌

每个pod默认都会挂载一个Secret,该Secret包含ca.crt、namespace、token,包含了从Pod内部安全访问Kubernetes Api服务器所需的全部信息。

先随便找一个pod查看。

  1. -> [root@kube0.vm] [~] k describe pod config-volume-cm
  2. Name: config-volume-cm
  3. Namespace: default
  4. ......
  5. Mounts:
  6. /tmp/mycm from config (ro)
  7. /var/run/secrets/kubernetes.io/serviceaccount from default-token-5g447 (ro)
  8. ......
  9. Volumes:
  10. ......
  11. default-token-5g447:
  12. Type: Secret (a volume populated by a Secret)
  13. SecretName: default-token-5g447
  14. Optional: false
  15. ......

再查看一下详情

  1. -> [root@kube0.vm] [~] k describe secrets default-token-5g447
  2. Name: default-token-5g447
  3. Namespace: default
  4. Labels: <none>
  5. Annotations: kubernetes.io/service-account.name: default
  6. kubernetes.io/service-account.uid: bd92a729-ed0a-491d-b600-0f86824ad588
  7. Type: kubernetes.io/service-account-token
  8. Data
  9. ====
  10. ca.crt: 1025 bytes
  11. namespace: 7 bytes
  12. token: eyJhbGciOiJSUzI1....

使nginx支持https

创建私钥和证书

  1. -> [root@kube0.vm] [~/cert] openssl genrsa -o https.key 2048
  2. -> [root@kube0.vm] [~/cert] openssl req -new -x509 -key https.key -out https.cert -days 3650 -subj /CN=www.mysecret.com

创建Secret

创建一个类型为generic的Secret,其他两个类型是docker-registry、tls。

  1. -> [root@kube0.vm] [~/cert] echo bar > foo # 后面会用到
  2. -> [root@kube0.vm] [~/cert] k create secret generic mysecret --from-file=./
  3. secret/mysecret created

将ssl.conf放入ConfigMap中

  1. # ssl.conf
  2. server {
  3. listen 80;
  4. listen 443 ssl;
  5. server_name www.mysecret.com;
  6. ssl_certificate certs/https.cert;
  7. ssl_certificate_key certs/https.key;
  8. ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  9. ssl_ciphers HIGH:!aNULL:!MD5;
  10. location / {
  11. root /usr/share/nginx/html;
  12. index index.html index.htm;
  13. }
  14. }
  1. -> [root@kube0.vm] [~] k create configmap sslcm --from-file=ssl.conf
  2. configmap/sslcm created

创建查看

先看一下描述文件

  1. # https-nginx.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: https-nginx
  6. spec:
  7. containers:
  8. - name: https-nginx
  9. image: nginx:alpine
  10. env:
  11. - name: FOO
  12. valueFrom:
  13. secretKeyRef:
  14. name: mysecret
  15. key: foo
  16. volumeMounts:
  17. - name: sslcm
  18. mountPath: /etc/nginx/conf.d/
  19. readOnly: true
  20. - name: mysecret
  21. mountPath: /etc/nginx/certs/
  22. readOnly: true
  23. ports:
  24. - containerPort: 80
  25. - containerPort: 443
  26. volumes:
  27. - name: sslcm
  28. configMap:
  29. name: sslcm
  30. items:
  31. - key: ssl.conf
  32. path: https.conf
  33. - name: mysecret
  34. secret:
  35. secretName: mysecret

创建、设置端口转发

  1. -> [root@kube0.vm] [~] k create -f https-nginx.yaml
  2. pod/https-nginx created
  3. -> [root@kube0.vm] [~] k port-forward https-nginx 443:443
  4. Forwarding from 127.0.0.1:443 -> 443

新开窗口,发送请求

  1. -> [root@kube0.vm] [~] curl -k https://localhost
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <title>Welcome to nginx!</title>
  6. .....

查看Secret通过环境变量暴露的条目

  1. -> [root@kube0.vm] [~] k exec https-nginx env
  2. PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  3. HOSTNAME=https-nginx
  4. FOO=bar
  5. .......

使用私有的镜像仓库

使用方法:创建一个docker-registry类型的secret,然后

创建一个docker-registry类型的secret。 --docker-server 用于指定仓库服务的地址。

  1. k create secret docker-registry dockerregsecret --docker-username=zhangsan --docker-password=123 --docker-email=zhangsan@163.com

在Pod中的containers.imagePullSecrets.name中引用。

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: private-pod
  5. spec:
  6. imagePullSecrets:
  7. - name: dockerregsecret
  8. containers:
  9. - image: username/private:tag
  10. name: main

StringData与二进制数据

采用Base64编码,使Secret也能存储二进制数据,而纯文本值可以在secret.StringData中定义,但StringData字段是只写的,kubectl get -o yaml查看时会被Base64编码显示在data下。

注意事项

  • 在Kubernetes中定义容器时,镜像的ENTRYPOINT和CMD都可以被覆盖。但是在Docker中,镜像的ENTRYPOINT是不能覆盖的。
  • 可以将configMapKeyRef.optional设置为true,这样即使ConfigMap不存在,容器也能启动。

小结

  • 对于环境变量:使用valueFrom.configMapKeyRef引用一个ConfigMap条目;使用envFrom.configMapRef引用全部,envFrom.prefix设置前缀。
  • 对于命令行参数:containers.args无法直接引用ConfigMap,但是可以通过$(ENV_VAR_NAME)引用环境变量,间接引用了ConfigMap。
  • 挂载文件夹会隐藏该文件夹中已存在的文件,挂载ConfigMap的单独条目不会隐藏其他文件
  • 将ConfigMap暴露为卷可以达到热更新的效果。
  • 每个pod默认都会挂载一个Secret,该Secret包含ca.crt、namespace、token,包含了从Pod内部安全访问Kubernetes Api服务器所需的全部信息。
  • 采用Base64编码,使Secret也能存储二进制数据,而纯文本值可以在secret.StringData中定义,但StringData字段是只写的,kubectl get -o yaml查看时会被Base64编码显示在data下。

Kubernetes学习笔记(六):使用ConfigMap和Secret配置应用程序的更多相关文章

  1. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  2. Learning ROS for Robotics Programming Second Edition学习笔记(六) indigo xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  3. Typescript 学习笔记六:接口

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  4. python3.4学习笔记(六) 常用快捷键使用技巧,持续更新

    python3.4学习笔记(六) 常用快捷键使用技巧,持续更新 安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器.IDLE默认不能显示行号,使 ...

  5. Go语言学习笔记六: 循环语句

    Go语言学习笔记六: 循环语句 今天学了一个格式化代码的命令:gofmt -w chapter6.go for循环 for循环有3种形式: for init; condition; increment ...

  6. 【opencv学习笔记六】图像的ROI区域选择与复制

    图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感兴趣区域ROI.今天我们来看一下如何设置图像的感兴趣区域ROI.以及对ROI区域图像 ...

  7. Linux学习笔记(六) 进程管理

    1.进程基础 当输入一个命令时,shell 会同时启动一个进程,这种任务与进程分离的方式是 Linux 系统上重要的概念 每个执行的任务都称为进程,在每个进程启动时,系统都会给它指定一个唯一的 ID, ...

  8. Kubernetes 学习笔记(一):基础概念

    个人笔记,仅本人查阅使用,不保证正确. 零.微服务 微服务架构专注于应用解耦合,通过将应用彻底地组件化和服务化,每个微服务只包含一个非常小的功能,比如权限管理.日志收集等等.由这一组微服务组合起来,提 ...

  9. # go微服务框架kratos学习笔记六(kratos 服务发现 discovery)

    目录 go微服务框架kratos学习笔记六(kratos 服务发现 discovery) http api register 服务注册 fetch 获取实例 fetchs 批量获取实例 polls 批 ...

随机推荐

  1. NLP入门之语音模型原理

    这一篇文章其实是参考了很多篇文章之后写出的一篇对于语言模型的一篇科普文,目的是希望大家可以对于语言模型有着更好地理解,从而在接下来的NLP学习中可以更顺利的学习. 1:传统的语音识别方法: 这里我们讲 ...

  2. .NET Micro Framework 4.2 beta 源码探析

    .NET Micro Framework 4.2 beta发布已经有一段时间了,一直没有腾出时间研究,昨天因为LWIP协议栈的原因(感觉上一个版本有点问题)刚 下了代码,所以抽空研究了一下.      ...

  3. CC视频CTO栗伟:CDN系统架构及CC视频应用实践

    2017 年 11 月9日,CC视频获2.08 亿元C轮融资. EGO 北京分会会员.CC视频CTO栗伟获邀作为 EGO 线上分享第三季嘉宾,与大家交流了CDN系统架构及CC 视频的应用实践. \\ ...

  4. 自动安装带nginx_upstream_check_module模块的Nginx脚本

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #!/bin/bash    useradd -s /sbin/no ...

  5. CodeForces - 1058D D. Vasya and Triangle

    D. Vasya and Triangle time limit per test1 second memory limit per test256 megabytes inputstandard i ...

  6. java权限设计思考

    1.粗粒度权限设计与细粒度权限设计             粗粒度(Coarse-graind)        表示类别级,即仅考虑对象的类别(the   type   of   object),不考 ...

  7. AIDL原理分析

    季春初始,天气返暖,新冠渐去,正值学习好时机.在Android系统中,AIDL一直在Framework和应用层上扮演着很重要的角色,今日且将其原理简单分析.(文2020.03.30) 一.开篇介绍 1 ...

  8. E - 梦幻岛宝珠 HYSBZ - 1190 变形01背包 难

    E - 梦幻岛宝珠 HYSBZ - 1190 这个题目我觉得很难,看题解都看了很久. 首先可以得到一个大概的思路就是分组,每一个数都可以分成 a*2^b  所以把b相同的数都分成一个组. 在每一组内部 ...

  9. spring学习笔记(八)webSocket

    知识储备 什么是stomp? 我们可以类比TCP与Http协议,我们知道Http协议是基于TCP协议的,Http协议解决了 web 浏览器发起请求以及 web 服务器响应请求的细节,我们在编码时候只要 ...

  10. LDheatmap | SNP连锁不平衡图(LD)可视化,自己数据实现版!

    本文首发于“生信补给站”,https://mp.weixin.qq.com/s/Gl6BChxSYbSHMo9oMpufPg 连锁不平衡图,用来可视化不同SNP之间的连锁程度,前同事间俗称“倒三角”图 ...