kubernetes ConfigMap和Secret:配置应用程序
目录
7.1.配置容器化应用程序
7.2.向容器传递命令行参数
7.2.1.待Docker中定义命令与参数
7.2.2.在kubernetes中覆盖命令行和参数
7.3.为容器设置环境变量
7.3.1.在容器定义中指定环境变量
7.3.2.在环境变量值中引用其他环境变量
7.4.利用ConfigMap解耦配置
7.4.1.ConfigMap介绍
7.4.2.创建ConfigMap
7.4.3.给容器传递ConfigMap条目作为环境变量
7.4.4.一次性传递ConfigMap的所有条目作为环境变量
7.4.5.使用ConfigMap卷将条目暴露为文件
7.5.使用Secert给容器传递敏感数据
7.5.1.介绍Secert
7.5.2.默认令牌Secret
7.5.3.创建Secret
7.5.4.对比ConfigMap与Secret
7.5.5.在pod中使用Secret
正文
回到顶部
7.1.配置容器化应用程序
7.2.向容器传递命令行参数
7.2.1.待Docker中定义命令与参数
1.了解ENTRYPOINT与CMD
ENTRYPOINT定义容器启动时被调用的可以执行程序
CMD指定传递给ENTRYP的参数
dockerfile 内容如下
1
2
3
4
5
6
FROM daocloud.io/centos:latest
ADD aaa /usr/local/aaa
CMD ["-f","/var/log/aa.log"]
ENTRYPOINT ["tail"]
当启动镜像时,容器启动时执行如下命令:tail -f /var/log/aa.log
或者在docker run 中指定,arguments会覆盖CMD中内容
7.2.2.在kubernetes中覆盖命令行和参数
在k8s中定义容器时,镜像的ENTRYPOINT和CMD都可以被覆盖,仅需在容器定义中设置熟悉command和args的值
对应参数如下:
Docker kubernetes 描述
ENTRYPOINT command 容器中运行的可执行文件
CMD args 传给可执行文件的参数
相关yml代码如下:
1
2
3
4
5
6
kind: pod
spec:
containers:
- image: some/image
command: ["/bin/command"]
args: ["args1","args2","args3"]
回到顶部
7.3.为容器设置环境变量
7.3.1.在容器定义中指定环境变量
与容器的命令和参数设置相同,环境变量列表无法在pod创建后被修改。
在pod的yml文件中设置容器环境变量代码如下:
1
2
3
4
5
6
7
8
kind: pod
spec:
containers:
- image: luksa/fortune:env
env:
- name: INTERVAL
value: "30"
name: value-test-yh
7.3.2.在环境变量值中引用其他环境变量
使用$( VAR )引用环境变量,
相关ym代码如下:
1
2
3
4
5
env:
- name: FIRST_VAR
value: "foo"
- name: SECOND_VAR
value: "$(FIRST_VAR)bar" //最终变量值为foobar
回到顶部
7.4.利用ConfigMap解耦配置
7.4.1.ConfigMap介绍
kubernetes允许将配置选项分离到独立的资源对象ConfigMap中,本质上就是一个键/值对映射,值可以是短字面变量,也可以是完整的配置文件。
应用无须直接读取ConfigMap,甚至根本不需要知道其是否存在。
映射的内容通过环境变量或者卷文件的形式传递给容器,而并非直接传递给容器,命令行参数的定义中也是通过$(ENV_VAR)语法变量
7.4.2.创建ConfigMap
使用kubectl creat configmap创建ConfigMap中间不用加-f。
1.使用指令创建ConfigMap
1
#kubectl creat configmap configmap-yaohong --from-literal=foo=bar --from-literal=sleep-interval=25
2.从文件内容创建ConfigMap条目
1
#kubectl create configmap my-conf-yh --from-file=config-file.conf
使用如下命令,会将文件内容存储在自定义的条目下。与字面量使用相同
1
#kubectl create configmap my-conf-yh --from-file=customkey=config-file.conf
3.从文件夹创建ConfigMap
1
#kubectl create configmap my-conf-yh --from-file=/path/to/dir
4.合并不同选项
1
2
3
4
#kubectl create configmap my-conf-yh
--from-file=/path/to/dir/
--from-file=bar=foobar.conf
--from-literal=some=thing
5.获取ConfigMap
1
#kubectl -n get configmap
7.4.3.给容器传递ConfigMap条目作为环境变量
引用环境变量中的参数值给当前变量
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: pod
metadata:
name: fortune-env-from-configmap
spec:
containers:
- image: luksa/fortune:env
env:
- name: INTERVAL //设置环境变量
valueFrom:
configMapkeyRef:
name: fortune-configmap
key: sleep-interval //变量的值取自fortune-configmap的slee-interval对应的值
7.4.4.一次性传递ConfigMap的所有条目作为环境变量
1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: pod
metadata:
name: fortune-env-from-configmap
spec:
containers:
- image: luksa/fortune:env
envFrom:
- prefix: CONFIG_
confgMapRef:
name: my-confg-map //引用my-config-map的ConfigMap并在变量前面都加上CONFIG_
7.4.5.使用ConfigMap卷将条目暴露为文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: pod
metadata:
name: configmap-volume-yh
spec:
containers:
- image: nginx:aplin
name: web-server
volumeMounts:
...
- name: config
defaultMode: "6600" //设置文件的权限为rw-rw mountPath: /etc/nginx/con.conf
subPath: my.conf //subPath字段可以用于挂载卷中某个独立的文件或者文件夹,而且不覆盖该卷下其他文件 ... volume: ... - name: config configMap: name: fortune-config //引用fortune-config configMap的卷,然后挂载在/etc/nginx/conf.d 可以使用如下命令查看到/etc/nginx/conf.d文件下面包含fortune-config 1 #kubectl exec config-volume-yh -c web-server ls /etc/nginx/conf.d 回到顶部 7.5.使用Secert给容器传递敏感数据 7.5.1.介绍Secert Secret结构和ConfigMap类似,均是键/值对的映射。 使用方法也和ConfigMap一样,可以: 1.将Secret条目作为环境变量传递给容器, 2.将Secret条目暴露为卷中文件 ConfigMap存储非敏感的文本配置数据,采用Secret存储天生敏感的数据 7.5.2.默认令牌Secret 1.查看secret 1 2 3 # kubectl get secrets NAME TYPE DATA AGE default-token-x9cjb kubernetes.io/service-account-token 3 78d 2.描述secret 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # kubectl describe secrets default-token-x9cjb Name: default-token-x9cjb Namespace: default Labels:
Annotations: kubernetes.io/service-account.name: default
kubernetes.io/service-account.uid: 64a41a09-98ce-11e9-9fa5-fa163e6fdb6b
Type: kubernetes.io/service-account-token
Data
====
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5lduaW8vc2VydmljZTxCv6HdtP-ZW3ZC2IKKR5YBhaokFIl35mix79pU4Ia2pJ_fuPTBGNyrCHyNQYH4ex5DhND3_b2puQmn8RSErQ
ca.crt: 1298 bytes
namespace: 7 bytes
7.5.3.创建Secret
1.创建一个名为https-yh的generic secret
1
#kubectl create secret generic https-yh --from-file=https.key --from-file=https.cert --from-file=foo
2.创建一个secret.yaml文件,内容用base64编码
$ echo -n 'admin' | base64
YWRtaW4=
$ echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm
yaml文件内容:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
创建:
$ kubectl create -f ./secret.yaml
secret "mysecret" created
解析Secret中内容
$ kubectl get secret mysecret -o yaml
apiVersion: v1
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
kind: Secret
metadata:
creationTimestamp: 2016-01-22T18:41:56Z
name: mysecret
namespace: default
resourceVersion: "164619"
selfLink: /api/v1/namespaces/default/secrets/mysecret
uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque
base64解码:
$ echo 'MWYyZDFlMmU2N2Rm' | base64 --decode
1f2d1e2e67df
7.5.4.对比ConfigMap与Secret
Secret的条目内容会进行Base64格式编码,而ConfigMap直接以纯文本展示。
1.为二进制数据创建Secret
Base64可以将二进制数据转换为纯文本,并以YAML或Json格式进行展示
但要注意Secret的大小限制是1MB
2.stringDate字段介绍
Secret可以通过StringDate字段设置条目的纯文本
1
2
3
4
5
6
7
kind: Secret
apiVersion: v1
stringDate:
foo: plain txt
date:
https.cert: HGIOPUPSDF63456BJ3BBJL34563456BLKJBK634563456BLBKJBLKJ63456BLK3456LK
http.key: OHOPGPIU42342345OIVBGOI3456345OVB6O3456BIPO435B6IPU345UI
7.5.5.在pod中使用Secret
secret可以作为数据卷挂载或者作为环境变量暴露给Pod中的容器使用,也可以被系统中的其他资源使用。比如可以用secret导入与外部系统交互需要的证书文件等。
在Pod中以文件的形式使用secret
创建一个Secret,多个Pod可以引用同一个Secret
修改Pod的定义,在spec.volumes[]加一个volume,给这个volume起个名字,spec.volumes[].secret.secretName记录的是要引用的Secret名字
在每个需要使用Secret的容器中添加一项spec.containers[].volumeMounts[],指定spec.containers[].volumeMounts[].readOnly = true,spec.containers[].volumeMounts[].mountPath要指向一个未被使用的系统路径。
修改镜像或者命令行使系统可以找到上一步指定的路径。此时Secret中data字段的每一个key都是指定路径下面的一个文件名
下面是一个Pod中引用Secret的列子:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
每一个被引用的Secret都要在spec.volumes中定义
如果Pod中的多个容器都要引用这个Secret那么每一个容器定义中都要指定自己的volumeMounts,但是Pod定义中声明一次spec.volumes就好了。
映射secret key到指定的路径
可以控制secret key被映射到容器内的路径,利用spec.volumes[].secret.items来修改被映射的具体路径
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
发生了什么呢?
username被映射到了文件/etc/foo/my-group/my-username而不是/etc/foo/username
password没有变
Secret文件权限
可以指定secret文件的权限,类似linux系统文件权限,如果不指定默认权限是0644,等同于linux文件的-rw-r--r--权限
设置默认权限位
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: mysecret
defaultMode: 256
上述文件表示将secret挂载到容器的/etc/foo路径,每一个key衍生出的文件,权限位都将是0400
由于JSON不支持八进制数字,因此用十进制数256表示0400,如果用yaml格式的文件那么就很自然的使用八进制了
同理可以单独指定某个key的权限
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
mode: 511
从volume中读取secret的值
值得注意的一点是,以文件的形式挂载到容器中的secret,他们的值已经是经过base64解码的了,可以直接读出来使用。
$ ls /etc/foo/
username
password
$ cat /etc/foo/username
admin
$ cat /etc/foo/password
1f2d1e2e67df
被挂载的secret内容自动更新
也就是如果修改一个Secret的内容,那么挂载了该Secret的容器中也将会取到更新后的值,但是这个时间间隔是由kubelet的同步时间决定的。最长的时间将是一个同步周期加上缓存生命周期(period+ttl)
特例:以subPath形式挂载到容器中的secret将不会自动更新
以环境变量的形式使用Secret
创建一个Secret,多个Pod可以引用同一个Secret
修改pod的定义,定义环境变量并使用env[].valueFrom.secretKeyRef指定secret和相应的key
修改镜像或命令行,让它们可以读到环境变量
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
restartPolicy: Never
容器中读取环境变量,已经是base64解码后的值了:
$ echo $SECRET_USERNAME
admin
$ echo $SECRET_PASSWORD
1f2d1e2e67df
使用imagePullSecrets
创建一个专门用来访问镜像仓库的secret,当创建Pod的时候由kubelet访问镜像仓库并拉取镜像,具体描述文档在 这里
设置自动导入的imagePullSecrets
可以手动创建一个,然后在serviceAccount中引用它。所有经过这个serviceAccount创建的Pod都会默认使用关联的imagePullSecrets来拉取镜像,
https://www.cnblogs.com/yaohong/p/11505670.html
defaultMode: "6600" //设置文件的权限为rw-rw mountPath: /etc/nginx/con.conf
subPath: my.conf //subPath字段可以用于挂载卷中某个独立的文件或者文件夹,而且不覆盖该卷下其他文件 ... volume: ... - name: config configMap: name: fortune-config //引用fortune-config configMap的卷,然后挂载在/etc/nginx/conf.d 可以使用如下命令查看到/etc/nginx/conf.d文件下面包含fortune-config 1 #kubectl exec config-volume-yh -c web-server ls /etc/nginx/conf.d 回到顶部 7.5.使用Secert给容器传递敏感数据 7.5.1.介绍Secert Secret结构和ConfigMap类似,均是键/值对的映射。 使用方法也和ConfigMap一样,可以: 1.将Secret条目作为环境变量传递给容器, 2.将Secret条目暴露为卷中文件 ConfigMap存储非敏感的文本配置数据,采用Secret存储天生敏感的数据 7.5.2.默认令牌Secret 1.查看secret 1 2 3 # kubectl get secrets NAME TYPE DATA AGE default-token-x9cjb kubernetes.io/service-account-token 3 78d 2.描述secret 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # kubectl describe secrets default-token-x9cjb Name: default-token-x9cjb Namespace: default Labels: