Kubernetes学习笔记(六):使用ConfigMap和Secret配置应用程序
概述
本文的核心是:如何处理应用程序的数据配置。
配置应用程序可以使用以下几种途径:
- 向容器传递命令行参数
- 为每个容器配置环境变量
- 通过特殊的卷将配置文件挂载到容器中
向容器传递命令行参数
在Kubernetes中定义容器时,镜像的ENTRYPOINT和CMD都可以被覆盖(但是在Docker中,镜像的ENTRYPOINT是不能覆盖的)。仅需在容器定义中设置command和args的值。
构建一个镜像
loopechodate.sh:接收一个时间间隔的参数,追加输出当前时间到 /tmp/a.txt
#! /bin/sh
trap "exit" SIGINT
echo "interval is : $1"
while :
do
echo -e "$(date)" >> /tmp/a.txt
sleep $1
done
Dockerfile
FROM alpine
COPY loopechodate.sh /bin/
ENTRYPOINT ["/bin/loopechodate.sh"]
CMD ["5"]
构建、推送
-> [root@kube0.vm] [~] docker build -t registry.cn-hangzhou.aliyuncs.com/orzi/loopechodate .
-> [root@kube0.vm] [~] docker push registry.cn-hangzhou.aliyuncs.com/orzi/loopechodate
运行Pod
# cat config-cli.yaml
apiVersion: v1
kind: Pod
metadata:
name: config-cli
spec:
containers:
- name: config-cli
image: registry.cn-hangzhou.aliyuncs.com/orzi/loopechodate
args: ["2"] # 间隔时间2s
创建这个pod,然后查看一下logs
-> [root@kube0.vm] [~] k create -f config-cli.yaml
pod/config-cli created
-> [root@kube0.vm] [~] k exec -it config-cli cat /tmp/a.txt
Sun May 24 15:49:37 UTC 2020
Sun May 24 15:49:39 UTC 2020
为容器设置环境变量
Kubernetes中通过容器的env属性定义环境变量,采用$(VAR)语法在环境变量值中引用其他变量。
定义了两个环境变量FIRST_VAR,和引用了FIRST_VAR的SECOND_VAR。
# config-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: config-env
spec:
containers:
- name: config-env
image: nginx:alpine
env:
- name: FIRST_VAR
value: "Hello"
- name: SECOND_VAR
value: "$(FIRST_VAR) World!"
创建查看
-> [root@kube0.vm] [~] k create -f config-env.yaml
pod/config-env created
-> [root@kube0.vm] [~] k exec config-env env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=config-env
FIRST_VAR=Hello
SECOND_VAR=Hello World!
.......
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一起指定。
下面是使用字面量、文件、目录合并创建。
-> [root@kube0.vm] [~] k create configmap mycm --from-literal=interval=3 --from-file=Dockerfile --from-file=/root/configdir
configmap/mycm created
-> [root@kube0.vm] [~] k describe cm mycm
Name: mycm
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
Dockerfile:
----
FROM alpine
COPY loopechodate.sh /bin/
ENTRYPOINT ["/bin/loopechodate.sh"]
CMD ["5"]
a.txt:
----
this is configdir/a.txt
b.txt:
----
this is configdir/b.txt
interval:
----
3
Events: <none>
使用环境变量文件创建
-> [root@kube0.vm] [~] echo -e "env1=1111\nenv2=2222" | tee test.env
env1=1111
env2=2222
-> [root@kube0.vm] [~] k create cm envcm --from-env-file=test.env
configmap/envcm created
-> [root@kube0.vm] [~] k describe cm envcm
Name: envcm
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
env1:
----
1111
env2:
----
2222
Events: <none>
传递ConfigMap条目作为环境变量
定义一个Pod,引用了mycm中的两个key。
# config-env-cm.yaml
apiVersion: v1
kind: Pod
metadata:
name: config-env-cm
spec:
containers:
- name: config-env-cm
image: nginx:alpine
env:
- name: INTERVAL
valueFrom:
configMapKeyRef: # 引用configMap中的内容
name: mycm # configMap的名字
key: interval # 引用哪个键
- name: ATXT
valueFrom:
configMapKeyRef:
name: mycm
key: a.txt
创建查看
-> [root@kube0.vm] [~] k create -f config-env-cm.yaml
pod/config-env-cm created
-> [root@kube0.vm] [~] k exec config-env-cm env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=config-env-cm
INTERVAL=3
ATXT=this is configdir/a.txt
....
一次性传递ConfigMap所有条目作为环境变量
# config-env-cmall.yaml
apiVersion: v1
kind: Pod
metadata:
name: config-env-cmall
spec:
containers:
- name: config-env-cmall
image: nginx:alpine
envFrom:
- prefix: CONFIG_
configMapRef:
name: mycm
创建查看
-> [root@kube0.vm] [~] k create -f config-env-cmall.yaml
pod/config-env-cmall created
-> [root@kube0.vm] [~] k exec config-env-cmall env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=config-env-cmall
CONFIG_interval=3
CONFIG_Dockerfile=FROM alpine
COPY loopechodate.sh /bin/
ENTRYPOINT ["/bin/loopechodate.sh"]
CMD ["5"]
CONFIG_a.txt=this is configdir/a.txt
CONFIG_b.txt=this is configdir/b.txt
........
传递ConfigMap条目作为命令行参数
containers.args
无法直接引用ConfigMap,但是可以通过$(ENV_VAR_NAME)引用环境变量,间接引用ConfigMap。
# config-cli-cm.yaml
apiVersion: v1
kind: Pod
metadata:
name: config-cli-cm
spec:
containers:
- name: config-cli-cm
image: registry.cn-hangzhou.aliyuncs.com/orzi/loopechodate
env:
- name: INTERVAL
valueFrom:
configMapKeyRef:
name: mycm
key: interval
args: ["$(INTERVAL)"]
创建查看
-> [root@kube0.vm] [~] k create -f config-cli-cm.yaml
pod/config-cli-cm created
-> [root@kube0.vm] [~] k logs config-cli-cm
interval is : 3
-> [root@kube0.vm] [~] k exec config-cli-cm cat /tmp/a.txt
Mon May 25 05:11:14 UTC 2020
Mon May 25 05:11:17 UTC 2020
Mon May 25 05:11:20 UTC 2020
将ConfigMap条目暴露为卷
环境变量和命令行参数作为配置值通常适用于变量值较短的场景。如果想暴露ConfigMap中配置文件,可以将ConfigMap或者其条目通过卷的形式挂载到容器。
# config-volume-cm.yaml
apiVersion: v1
kind: Pod
metadata:
name: config-volume-cm
spec:
containers:
- name: config-volume-cm
image: nginx:alpine
volumeMounts:
- name: config
mountPath: /tmp/mycm
readOnly: true
volumes:
- name: config
configMap:
name: mycm
创建查看
-> [root@kube0.vm] [~] k create -f config-volume-cm.yaml
pod/config-volume-cm created
-> [root@kube0.vm] [~] k exec config-volume-cm ls /tmp/mycm
Dockerfile
a.txt
b.txt
interval
如果只想暴露指定的条目,可以指定volumes.configMap.items
。
volumes:
- name: config
configMap:
name: mycm
items:
- key: interval
path: interval2
输出结果是:
-> [root@kube0.vm] [~] k exec config-volume-cm ls /tmp/mycm
interval2
configMap.defaultMode
设置访问权限
挂载文件夹会隐藏该文件夹中已存在的文件,挂载ConfigMap的单独条目不会隐藏其他文件
Secret
Secret与ConfigMap一样都是键值对,也可以作为环境变量传递给容器,条目也能暴露称为卷中的文件。但是为了安全起见,请始终使用Secret卷暴露Secret。Secret只会存储在内存中,永不写入物理存储。Secret条目的内容会被进行Base64编码。
默认令牌
每个pod默认都会挂载一个Secret,该Secret包含ca.crt、namespace、token,包含了从Pod内部安全访问Kubernetes Api服务器所需的全部信息。
先随便找一个pod查看。
-> [root@kube0.vm] [~] k describe pod config-volume-cm
Name: config-volume-cm
Namespace: default
......
Mounts:
/tmp/mycm from config (ro)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-5g447 (ro)
......
Volumes:
......
default-token-5g447:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-5g447
Optional: false
......
再查看一下详情
-> [root@kube0.vm] [~] k describe secrets default-token-5g447
Name: default-token-5g447
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: default
kubernetes.io/service-account.uid: bd92a729-ed0a-491d-b600-0f86824ad588
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1025 bytes
namespace: 7 bytes
token: eyJhbGciOiJSUzI1....
使nginx支持https
创建私钥和证书
-> [root@kube0.vm] [~/cert] openssl genrsa -o https.key 2048
-> [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。
-> [root@kube0.vm] [~/cert] echo bar > foo # 后面会用到
-> [root@kube0.vm] [~/cert] k create secret generic mysecret --from-file=./
secret/mysecret created
将ssl.conf放入ConfigMap中
# ssl.conf
server {
listen 80;
listen 443 ssl;
server_name www.mysecret.com;
ssl_certificate certs/https.cert;
ssl_certificate_key certs/https.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
-> [root@kube0.vm] [~] k create configmap sslcm --from-file=ssl.conf
configmap/sslcm created
创建查看
先看一下描述文件
# https-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: https-nginx
spec:
containers:
- name: https-nginx
image: nginx:alpine
env:
- name: FOO
valueFrom:
secretKeyRef:
name: mysecret
key: foo
volumeMounts:
- name: sslcm
mountPath: /etc/nginx/conf.d/
readOnly: true
- name: mysecret
mountPath: /etc/nginx/certs/
readOnly: true
ports:
- containerPort: 80
- containerPort: 443
volumes:
- name: sslcm
configMap:
name: sslcm
items:
- key: ssl.conf
path: https.conf
- name: mysecret
secret:
secretName: mysecret
创建、设置端口转发
-> [root@kube0.vm] [~] k create -f https-nginx.yaml
pod/https-nginx created
-> [root@kube0.vm] [~] k port-forward https-nginx 443:443
Forwarding from 127.0.0.1:443 -> 443
新开窗口,发送请求
-> [root@kube0.vm] [~] curl -k https://localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
.....
查看Secret通过环境变量暴露的条目
-> [root@kube0.vm] [~] k exec https-nginx env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=https-nginx
FOO=bar
.......
使用私有的镜像仓库
使用方法:创建一个docker-registry类型的secret,然后
创建一个docker-registry类型的secret。 --docker-server 用于指定仓库服务的地址。
k create secret docker-registry dockerregsecret --docker-username=zhangsan --docker-password=123 --docker-email=zhangsan@163.com
在Pod中的containers.imagePullSecrets.name
中引用。
apiVersion: v1
kind: Pod
metadata:
name: private-pod
spec:
imagePullSecrets:
- name: dockerregsecret
containers:
- image: username/private:tag
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配置应用程序的更多相关文章
- java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...
- Learning ROS for Robotics Programming Second Edition学习笔记(六) indigo xtion pro live
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- Typescript 学习笔记六:接口
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- python3.4学习笔记(六) 常用快捷键使用技巧,持续更新
python3.4学习笔记(六) 常用快捷键使用技巧,持续更新 安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器.IDLE默认不能显示行号,使 ...
- Go语言学习笔记六: 循环语句
Go语言学习笔记六: 循环语句 今天学了一个格式化代码的命令:gofmt -w chapter6.go for循环 for循环有3种形式: for init; condition; increment ...
- 【opencv学习笔记六】图像的ROI区域选择与复制
图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感兴趣区域ROI.今天我们来看一下如何设置图像的感兴趣区域ROI.以及对ROI区域图像 ...
- Linux学习笔记(六) 进程管理
1.进程基础 当输入一个命令时,shell 会同时启动一个进程,这种任务与进程分离的方式是 Linux 系统上重要的概念 每个执行的任务都称为进程,在每个进程启动时,系统都会给它指定一个唯一的 ID, ...
- Kubernetes 学习笔记(一):基础概念
个人笔记,仅本人查阅使用,不保证正确. 零.微服务 微服务架构专注于应用解耦合,通过将应用彻底地组件化和服务化,每个微服务只包含一个非常小的功能,比如权限管理.日志收集等等.由这一组微服务组合起来,提 ...
- # go微服务框架kratos学习笔记六(kratos 服务发现 discovery)
目录 go微服务框架kratos学习笔记六(kratos 服务发现 discovery) http api register 服务注册 fetch 获取实例 fetchs 批量获取实例 polls 批 ...
随机推荐
- Image Filter and Recover
这是CS50的第四次大作业,顺便学习了图像的入门知识. 基础 黑白图(bitmap)的每个像素点只能取值0/1,1代表白色,0代表黑色. 常见的图片格式有JPEG/PNG/BMP,这些格式都支持RGB ...
- 2019 ICPC 银川网络赛 H. Fight Against Monsters
It is my great honour to introduce myself to you here. My name is Aloysius Benjy Cobweb Dartagnan Eg ...
- Git上传本地仓库项目到gitee远程仓库(命令篇)
前言:最近整理了一下自己之前的自学代码,包括一些练习的项目.发现有些杂乱,故想使用Gitte(码云)管理.加上不少公司使用Git,所以写了这篇文章记录. 如果我们本地有了项目,那么如何上传到码云上呢? ...
- C :uthash
参考: [1] uthash | 学步园 [2] 源码 [3] 官方文档 [4] [5] 一.哈希表的概念及作用 在一般的线性表或者树中,我们所储存的值写它的存储位置的关系是随机的.因此,在查找过程中 ...
- Android原生多语言切换方案,兼容Android10
前言 一个应用若需要国际化,至少需要支持中文和英语这两种语言,而同时随着谷歌的系统的更新,安卓系统可以设置当前语言的首选语言.因此,本文立足于此,多语言的切换方案为:App固定的文字内容,跟随系统,中 ...
- 开源 一套 Blazor Server 端精致套件
Blazor 作为一种 Web 开发的新技术已经发展有一段时间了,有些人标称 无 JS 无 TS,我觉得有点误导新人的意味,也有人文章大肆宣传 Blazor 是 JavaScript 的终结者,是为了 ...
- 如何对Code Review的评论进行分级
我曾写过一篇关于Code Review的文章<Code Review 最佳实践>,在文章中建议对Code Review的评论进行分级: 建议可以对Review的评论进行分级,不同级别的结果 ...
- 一文带你深入了解 Lambda 表达式和方法引用
前言 尽管目前很多公司已经使用 Java8 作为项目开发语言,但是仍然有一部分开发者只是将其设置到 pom 文件中,并未真正开始使用.而项目中如果有8新特性的写法,例如λ表达式.也只是 Idea Al ...
- 【Kafka】实时看板案例
目录 项目需求 项目模型 实现步骤 项目需求 快速计算双十一当天的订单量和销售金额 项目模型 实现步骤 一.创建topic bin/kafka-topics.sh --create --topic i ...
- scala 隐式参数
def test(implicit name: String = "susu"): Unit ={ println(name);} 三种调用方法如下:test("dudu ...