一、ConfigMap
ConfigMap中包含了Map单词(Map其实就是key:value),主要是管理一些可变配置信息,如应用的配置文件、应用里面的环境变量、命令行参数。它可以让一些可变配置和容器进行解耦,保证了容器的可移植性。
kubectl命令创建ConfigMap时,可以指定文件、指定目录或直接指定键值对。
指定文件和目录的命令如下:
kubectl create configmap XXX --from-file=XXX -n kube-system
若指定的是文件,文件名就是Map中的key,文件内容就是Map中的value。
若指定的是目录,目录中的每个配置文件名都被会被设置为key。
直接指定键值对的命令如下:
kubectl create configmap XXX --from-literal=key=value --from-literal=key=value
指定的数据键值对,会直接映射到Map的key:value
被创建的ConfigMap除了apiVersion、kind、metadata外,还包括data部分
以下面的配置清单为例,可以看到它管理了两个直接指定的键值对和一个配置文件
kind: ConfigMap
apiVersion: v1
metadata:
name: five-nginx
namespace: default
data:
example.property.1: hello
example.property.2: world
example.property.file: |-
property.1=value-1
property.2=value-2
property.3=value-3
Pod里使用ConfigMap有以下几种方式:
(1)填充环境变量。
通过valueFrom进行使用:ConfigMapKeyRef字段中,name是指定ConfigMap名,key是ConfigMap.data里面的key。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: gcr.io/google_containers/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: example-config # 需使用的ConfigMap名称,必须已存在
key: example.property.1 # 对应ConfigMap data的key
restartPolicy: Never
填充的环境变量可以直接拿到cmd字段作为命令行参数使用:
如下例,Pod启动后,会打印hello world。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: gcr.io/google_containers/busybox
command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: example-config
key: example.property.1
- name: SPECIAL_TYPE_KEY
valueFrom:
configMapKeyRef:
name: example-config
key: example.property.2
restartPolicy: Never
(2)通过volume挂载的方式将ConfigMap里的内容直接挂到容器的某一个目录下面去:
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: gcr.io/google_containers/busybox
command: [ "/bin/sh","-c","ls -l /etc/config/path/" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: example-config
restartPolicy: Never
在/etc/config目录下会创建3个文件:直接指定的键值对,创建的文件名为key、文件内容就是value;配置文件则原样不变。
若ConfigMap中有多个文件::
apiVersion: v1
kind: ConfigMap
metadata:
name: test-cfgmap
data:
app.conf: file data
......
只想把app.conf文件从ConfigMap挂载到Pod,其他文件不可见,有三种方式:
(1)ConfigMap中的key、 volumeMounts.mountPath和volumeMounts.subPath名称一定要保持一致,否则会挂载不成功。
apiVersion: v1
kind: Pod
metadata:
name: test-pd-plus-cfgmap
spec:
containers:
- image: ubuntu
name: bash
volumeMounts:
- mountPath: /usr/local/app.conf
name: cfgmap
subPath: app.conf
volumes:
- name: cfgmap
configMap:
name: test-cfgmap
(2)这种方式使用ConfigMap,就不再要求ConfigMap中的key跟挂载的文件名必须一致,但需要在items指定key和path对应关系。
apiVersion: v1
kind: Pod
metadata:
name: test-pd-plus-cfgmap
spec:
containers:
- image: ubuntu
name: bash
volumeMounts:
- mountPath: /usr/local/app.conf
name: cfgmap
subPath: app.conf
volumes:
- name: cfgmap
configMap:
name: test-cfgmap
items:
- key: app.conf # 指定Configmap中的文件对应的key
path: app.conf # 指定生成的配置文件名称
(3)挂载ConfigMap到一个其它路径,然后通过软连接的方式链接到需要的文件。
ConfigMap注意要点
-
虽然ConfigMap文件没有大小限制。但是在Etcd里面数据的写入是有大小限制的,现在是限制在1MB以内;
-
ConfigMap.metadata里面是有namespace字段的。Pod只能引用相同Namespace中的ConfigMap;
-
Pod引用ConfigMap时,假如不存在,那么这个Pod无法创建成功的;
-
把ConfigMap里面所有的信息导入成环境变量时,如果ConfigMap里有些key是无效的(比如key里带有数字),那么这个环境变量会直接被忽略,不会注入容器,但是这个Pod本身是可以创建的。
-
只有通过apiserver创建的Pod才能使用ConfigMap,kubelet通过manifest创建的static pod不能使用ConfigMap。
二、Secret
Secret是一个主要用来存储敏感信息的资源对象。采用base-64编码保存。
Secret的创建:
-
系统创建:比如k8s为每一个namespace的默认用户(default ServiceAccount)创建 Secret,名称为default-token-xxxxx
-
用户手动创建:使用kubectl命令行工具时,data参数的写法与ConfigMap一致,相对ConfigMap会多一个 type 参数,不指定的话默认是Opaque类型。
kubectl create secret generic xxx —from-file=xxx —type=kubernetes.io/dockerconfigjson kubectl create secret generic xxx —from-literal=key=value —from-literal=key=value
被创建的Secret除了apiVersion、kind、metadata外,还增加了type字段,指出Secret的类型,包括:
-
Opaque:普通的Secret文件,
-
kubernetes.io/service-account-token:是用于service-account身份认证用的Secret
-
kubernetes.io/dockerconfigjson:拉取私有仓库镜像的用的Secret
-
kubernetes.io/bootstrap.token:用于节点接入集群校验用的Secret
它和ConfigMap一样也有data字段,是存储的Secret的数据,它也是key-value的形式存储的。
apiVersion: v1
kind: Secret
metadata:
name: example-secret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
Pod里使用Secret有以下几种方式:
(1)填充环境变量。
通过valueFrom进行使用:secretKeyRef字段中,name是指定Secret名,key是Secret.data里面的key。
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: example-secret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: example-secret
key: password
(2)通过volume挂载的方式直接把Secret中的内容挂到容器的某一个目录下:
apiVersion: v1
kind: Pod
metadata:
name: mypod
namespace: default
spec:
containers:
- image: redis
name: mypod
volumeMounts:
- mountPath: /etc/foo
name: foo
readOnly: true
volumes:
- name: foo
secret:
defaultMode: 420
secretName: example-secret
注意:defalutMode指定默认文件权限时,由于json文件不支持八进制,使用时应使用十进制
k8s会自动把default-token-xxxxx挂载到容器 /var/run/secrets/kubernetes.io/serviceaccount目录下。该secret包括三个文件:ca.crt、namespace(空文件)、token,它们保存了认证相关信息
(3)拉取镜像文件。
通过命令创建:
kubectl create secret docker-registry xxxxx --docker-server=reg.harbor.com --docker-username=xxxx --docker-password=xxxxxx -n xxxxx
将私有镜像仓库的信息存储在Secret里面
apiVersion: v1
kind: Secret
metadata:
name: image-test-secret
namespace: default
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: xxxxxxx
加密部分的明文为:
{
"auths": {
"xxx": {
"username": "xxxxx",
"password": "xxxxx",
"auth": "xxxxxxxxx"
}
}
}
其中auth部分的密文是username:passward的base64结果
Pod通过Pod.spec.impagePullSecrets字段使用该Secret:
apiVersion: v1
kind: Pod
metadata:
name: foo
namespace: default
spec:
containers:
- name: foo
image: janedoe/awesomeapp:v1
imagePullSecrets:
- name: image-test-secret
此外还可以配置自动注入,提前在Pod会使用的serviceaccount里配置imagePullSecrets,Pod创建时系统会自动注入此Secret。
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2020-05-21T07:52:58Z"
name: default
namespace: default
resourceVersion: "182"
selfLink: /api/v1/namespaces/default/serviceaccounts/default
uid: 517ca0ab-a675-4f3d-a2b4-6bb3d26ab8a7
secrets:
- name: default-token-848wt
imagePullSecrets:
- name: image-test-secret
Secret注意要点:
-
Secret的文件大小限制和ConfigMap一样,也是1MB;
-
Secret采用了base-64编码,安全程度不高。推荐可以使用开源的vault来解决敏感信息的加密和权限管理。
-
Secret读取不要用list/watch,否则会把namespace下的所有Secret全部拉取下来。推荐使用GET的方法,只获取需要的那个Secret。
参考资料: