一、ConfigMap
. 1. ConfigMap简介
在我们部署一些应用服务时,通常都会有一些配置文件,而在k8s中,我们如果在将这些配置文件写到代码应用程序中,需要修改配置的话,我们还得重新去修改代码,重新制作一个镜像,这样操作起来很麻烦。
还好kubernetes为我们提供了一个ConfigMap资源对象,它的主要作用就是为了让镜像和配置文件解耦,以便实现镜像的可移植性和可复用性,提供了向容器中注入配置信息的能力,不仅可以用来保存单个属性,还可以用来保存整个配置文件,我们只需要将配置文件以ConfigMap的方式挂载到应用Pod中,这样我们在更新配置信息的时候只需要更新这个ConfigMap对象即可。
ConfigMap使用场景:
通过环境变量的方式,直接传递给pod
通过在pod的命令行下运行的方式(启动命令中)
作为volume的方式挂载到pod内
. 2. 创建ConfigMap
2.1 通过目录创建
1$ ls /app/web/configmap/kubectl/
2ftp.properties
3jdbc.properties
4
5$ cat /app/web/configmap/kubectl/ftp.properties
6FTP_ADDRESS=192.168.133.11
7FTP_PORT=21
8FTP_USERNAME=ftpuser
9FTP_PASSWORD=ftpuser
10FTP_BASEPATH=/
11IMAGE_BASE_URL=http://test.test.com/image
12
13$ cat /app/web/configmap/kubectl/jdbc.properties
14#database configuration
15connection.url=jdbc:mysql://10.1.133.111:3306/web
16connection.username=testdata
17#connection.password=abcde
18connection.password=SN9+koFJWHmf
创建Configmap对象
1$ kubectl create configmap web-config --from-file=/app/web/configmap/kubectl
--from-file
:指定目录路径,该目录下的所有文件都会被用在ConfigMap里面创建一个键值对,键的名字就是文件名,值就是文件的内容。
查看Configmap信息
1$ kubectl describe configmaps web-config
2Name: web-config
3Namespace: default
4Labels: <none>
5Annotations: <none>
6
7Data
8====
9ftp.properties:
10----
11FTP_ADDRESS=192.168.133.11
12FTP_PORT=21
13FTP_USERNAME=ftpuser
14FTP_PASSWORD=ftpuser
15FTP_BASEPATH=/
16IMAGE_BASE_URL=http://test.test.com/image
17
18jdbc.properties:
19----
20#database configuration
21connection.url=jdbc:mysql://10.1.133.111:3306/web
22connection.username=testdata
23#connection.password=abcde
24connection.password=SN9+koFJWHmf
25
26Events: <none>
如果配置文件信息较多的话,describe的输出信息会显示不全,我们可以使用以下命令来查看完整内容:
1$ kubectl get configmaps web-config -o yaml
2apiVersion: v1
3data:
4 ftp.properties: |
5 FTP_ADDRESS=192.168.133.11
6 FTP_PORT=21
7 FTP_USERNAME=ftpuser
8 FTP_PASSWORD=ftpuser
9 FTP_BASEPATH=/
10 IMAGE_BASE_URL=http://test.test.com/image
11 jdbc.properties: |
12 #database configuration
13 connection.url=jdbc:mysql://10.1.133.111:3306/web
14 connection.username=testdata
15 #connection.password=abcde
16 connection.password=SN9+koFJWHmf
17kind: ConfigMap
18metadata:
19 creationTimestamp: 2020-02-18T18:34:05Z
20 name: web-config
21 namespace: default
22 resourceVersion: "407"
23 selfLink: /api/v1/namespaces/default/configmaps/web-config
24 uid: 680944725-d62e-10e5-8cd0-68f123db1985
2.2 使用文件创建
1$ kubectl create configmap web-config-2 --from-file=/app/web/configmap/kubectl/ftp.properties
2$ kubectl get configmaps web-config-2 -o yaml
3apiVersion: v1
4data:
5 ftp.properties: |+
6 FTP_ADDRESS=192.168.133.11
7 FTP_PORT=21
8 FTP_USERNAME=ftpuser
9 FTP_PASSWORD=ftpuser
10 FTP_BASEPATH=/
11 IMAGE_BASE_URL=http://test.test.com/image
12
13kind: ConfigMap
14metadata:
15 creationTimestamp: "2020-05-22T16:36:39Z"
16 name: web-config-2
17 namespace: default
18 resourceVersion: "33386795"
19 selfLink: /api/v1/namespaces/default/configmaps/web-config-2
20 uid: cffef22c-be55-4de3-8835-79195de8ec7e
--from-file
:可以多次使用,指定多个文件
2.3 使用命令行创建
1$ kubectl create configmap web-config-3 --from-literal=FTP_ADDRESS=192.168.133.11 --from-literal=FTP_PORT=21 --from-literal=FTP_USERNAME=ftpuser --from-literal=FTP_PASSWORD=ftpuser --from-literal=FTP_BASEPATH=/ --from-literal=IMAGE_BASE_URL=http://test.test.com/image
2configmap/web-config-3 created
3$ kubectl get configmap web-config-3 -o yaml
4apiVersion: v1
5data:
6 FTP_ADDRESS: 192.168.133.11
7 FTP_BASEPATH: /
8 FTP_PASSWORD: ftpuser
9 FTP_PORT: "21"
10 FTP_USERNAME: ftpuser
11 IMAGE_BASE_URL: http://test.test.com/image
12kind: ConfigMap
13metadata:
14 creationTimestamp: "2020-05-22T16:46:50Z"
15 name: web-config-3
16 namespace: default
17 resourceVersion: "33387937"
18 selfLink: /api/v1/namespaces/default/configmaps/web-config-3
19 uid: d69afbaf-0ac4-4405-a4ea-351ad613bdb4
--from-literal
:可以多次使用,指定多个值
. 3. 使用Configmp
3.1 使用ConfigMap来填充环境变量
编写Pod资源文件,使用上面名为web-config-3的configmap
1apiVersion: v1
2kind: Pod
3metadata:
4 name: testweb-pod
5spec:
6 containers:
7 - name: testweb
8 image: busybox
9 command: [ "/bin/sh", "-c", "env" ]
10 env:
11 - name: FTP_ADDRESS
12 valueFrom:
13 configMapKeyRef:
14 name: web-config-3
15 key: FTP_ADDRESS #configmap的key值
16 - name: FTP_PORT
17 valueFrom:
18 configMapKeyRef:
19 name: web-config-3
20 key: FTP_PORT
21 envFrom:
22 - configMapRef:
23 name: web-config-3 #使用名为web-config-3的configmap对象
创建Pod并查看日志
1$ kubectl logs -f testweb-pod
2--------
3FTP_ADDRESS=192.168.133.11
4IDLE_LLAMA_NGINX_INGRESS_DEFAULT_BACKEND_PORT_80_TCP=tcp://10.98.12.71:80
5PLUNDERING_MARMOT_NGINX_INGRESS_CONTROLLER_PORT_80_TCP_ADDR=10.108.129.64
6FTP_PORT=21
7MY_RELEASE_TOMCAT_PORT_80_TCP_ADDR=10.101.28.152
8KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
9
10FTP_USERNAME=ftpuser
11EXACERBATED_HEDGEHOG_NGINX_INGRESS_DEFAULT_BACKEND_SERVICE_PORT=80
12PLUNDERING_MARMOT_NGINX_INGRESS_CONTROLLER_PORT_80_TCP=tcp://10.108.129.64:80
13PLUNDERING_MARMOT_NGINX_INGRESS_CONTROLLER_PORT_443_TCP_ADDR=10.108.129.64
14MYDB_MYSQL_SERVICE_PORT_MYSQL=3306
15--------
3.2 使用ConfigMap设置命令行参数
1apiVersion: v1
2kind: Pod
3metadata:
4 name: testweb2-pod
5spec:
6 containers:
7 - name: testweb2
8 image: busybox
9 command: [ "/bin/sh", "-c", "echo $(FTP_ADDRESS) $(FTP_PORT)" ]
10 env:
11 - name: FTP_ADDRESS
12 valueFrom:
13 configMapKeyRef:
14 name: web-config-3
15 key: FTP_ADDRESS
16 - name: FTP_PORT
17 valueFrom:
18 configMapKeyRef:
19 name: web-config-3
20 key: FTP_PORT
查看Pod的输出信息
1kubectl logs -f testweb2-pod
2192.168.133.11 21
3.3 通过数据卷使用ConfigMap
1apiVersion: v1
2kind: Pod
3metadata:
4 name: testweb3-pod
5spec:
6 volumes:
7 - name: config-volume
8 configMap:
9 name: web-config-2
10 containers:
11 - name: testweb3
12 image: busybox
13 command: [ "/bin/sh", "-c", "cat /etc/config/ftp.properties" ]
14 volumeMounts:
15 - name: config-volume
16 mountPath: /etc/config
查看pod输出日志
1$ kubectl logs -f testweb3-pod
2FTP_ADDRESS=192.168.133.11
3FTP_PORT=21
4FTP_USERNAME=ftpuser
5FTP_PASSWORD=ftpuser
6FTP_BASEPATH=/
7IMAGE_BASE_URL=http://test.test.com/image
注意,当 ConfigMap 以数据卷的形式挂载进 Pod 的时,这时更新 ConfigMap(或删掉重建ConfigMap),Pod 内挂载的配置信息会热更新。这时可以增加一些监测配置文件变更的脚本,然后重新加载对应服务就可以实现应用的热更新。
二、Secret
. 1. Secret简介
一般情况下ConfigMap 是用来存储一些非安全的配置信息,因为ConfigMap是明文存储的,面对敏感信息时,我们就需要使用k8s的另一个对象Secret。
Secret用来保存敏感信息,例如密码、OAuth 令牌和 ssh key 等等,将这些信息放在 Secret 中比放在 Pod 的定义中或者 Docker 镜像中要更加安全和灵活。
Secret 主要使用的有以下三种类型:
Opaque:base64 编码格式的 Secret,用来存储密码、密钥等;但数据也可以通过base64 –decode解码得到原始数据,所有加密性很弱。
kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。
kubernetes.io/service-account-token:用于被 ServiceAccount ServiceAccount 创建时 Kubernetes 会默认创建一个对应的 Secret 对象。Pod 如果使用了 ServiceAccount,对应的 Secret 会自动挂载到 Pod 目录 /run/secrets/kubernetes.io/serviceaccount 中。
bootstrap.kubernetes.io/token:用于节点接入集群的校验的 Secret
Secret对比ConfigMap
相同点
key/value的形式
属于某个特定的命名空间
可以导出到环境变量
可以通过目录/文件形式挂载
通过 volume 挂载的配置信息均可热更新
不同点
Secret 可以被 ServerAccount 关联
Secret 可以存储 docker register 的鉴权信息,用在 ImagePullSecret 参数中,用于拉取私有仓库的镜像
Secret 支持 Base64 加密
Secret分为kubernetes.io/service-account-token、kubernetes.io/dockerconfigjson、Opaque 三种类型,而 Configmap 不区分类型
. 2. Opaque Secret
2.1 手动创建Secret
1$ echo -n "admin" | base64
2YWRtaW4=
3$ echo -n "adminpass" | base64
4YWRtaW5wYXNz
Opaque 类型的数据是一个 map 类型,要求 value 必须是 base64 编码格式。
使用上面加密的编码编写Yaml
1apiVersion: v1
2kind: Secret
3metadata:
4 name: mysecret
5type: Opaque
6data:
7 username: YWRtaW4=
8 password: YWRtaW5wYXNz
创建Secret
1$ kubectl create -f secret-demo.yaml
2secret/mysecret created
3$ kubectl get secret
4NAME TYPE DATA AGE
5default-token-g7sqf kubernetes.io/service-account-token 3 219d
6exacerbated-hedgehog-nginx-ingress-token-zrwpn kubernetes.io/service-account-token 3 174d
7idle-llama-nginx-ingress-token-r2j5k kubernetes.io/service-account-token 3 174d
8istio.default istio.io/key-and-cert 3 185d
9mydb-mysql Opaque 2 181d
10mysecret Opaque 2 6m13s
查看Secret信息
1kubectl describe secret mysecret
2Name: mysecret
3Namespace: default
4Labels: <none>
5Annotations: <none>
6
7Type: Opaque
8
9Data
10====
11password: 9 bytes
12username: 5 bytes
查看Secret详细信息
1apiVersion: v1
2data:
3 password: YWRtaW5wYXNz
4 username: YWRtaW4=
5kind: Secret
6metadata:
7 creationTimestamp: "2020-05-25T14:50:01Z"
8 name: mysecret
9 namespace: default
10 resourceVersion: "33864313"
11 selfLink: /api/v1/namespaces/default/secrets/mysecret
12 uid: cf560ef9-eb67-4b3d-ac17-ed930e6799ce
13type: Opaque
2.2 使用Secret作为环境变量
编写Pod的资源文件
1apiVersion: v1
2kind: Pod
3metadata:
4 name: secret1-pod
5spec:
6 containers:
7 - name: secret1
8 image: busybox
9 command: [ "/bin/sh", "-c", "env" ]
10 env:
11 - name: USERNAME
12 valueFrom:
13 secretKeyRef:
14 name: mysecret
15 key: username
16 - name: PASSWORD
17 valueFrom:
18 secretKeyRef:
19 name: mysecret
20 key: password
secretKeyRef
:和前面Configmap定义相同,获取Secret的key值
创建Pod后查看日志输出
1$ kubectl create -f testpod.yaml
2pod/secret1-pod created
3$ kubectl logs -f secret1-pod | grep USERNAME
4USERNAME=admin
5$ kubectl logs -f secret1-pod | grep PASSWORD
6PASSWORD=adminpass
2.3 通过数据卷使用Secret
将Sercret挂载到Pod的/etc/secret路径下
1apiVersion: v1
2kind: Pod
3metadata:
4 name: secret2-pod
5spec:
6 containers:
7 - name: secret2
8 image: busybox
9 command: ["/bin/sh", "-c", "ls /etc/secrets"]
10 volumeMounts:
11 - name: secrets
12 mountPath: /etc/secrets
13 volumes:
14 - name: secrets
15 secret:
16 secretName: mysecret
创建Pod并查看日志输出
1$ kubectl create -f testpod2.yaml
2 pod/secret2-pod created
3$ kubectl logs -f secret2-pod
4password
5username
可以看到 Secret 把两个 key 以两个对应的文件挂载到了Pod中/etc/secret路径下,如果挂载到指定的文件上面,可以使用上面Configmap的数据卷挂载方式。
. 3. kubernetes.io/dockerconfigjson
3.1 创建Secret对象
这个类型的Secret对象用来创建建镜像仓库认证信息,如下:
1$ kubectl create secret docker-registry harbor --docker-server=http://192.168.166.229 --docker-username=admin --docker-password=harbor123 --docker-email=test@163.com
2secret/harbor created
查看创建的secret,注意Sercret对应的TYPE类型
1$ kubectl get secret
2NAME TYPE DATA AGE
3default-token-g7sqf kubernetes.io/service-account-token 3 233d
4exacerbated-hedgehog-nginx-ingress-token-zrwpn kubernetes.io/service-account-token 3 188d
5harbor kubernetes.io/dockerconfigjson 1 66s
3.2 查看Secret信息
1$ kubectl get secret harbor -o yaml
2apiVersion: v1
3data:
4 .dockerconfigjson: eyJhdXRocyI6eyJodHRwOi8vMTkyLjE2OC4xNjYuMjI5Ijp7InVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6IkhhcmJvckAxYW4iLCJlbWFpbCI6InRlc3RAMTYzLmNvbSIsImF1dGgiOiJZV1J0YVc0NlNHRnlZbTl5UURGaGJnPT0ifX19
5kind: Secret
6metadata:
7 creationTimestamp: "2020-06-08T14:20:41Z"
8 name: harbor
9 namespace: default
10 resourceVersion: "36160653"
11 selfLink: /api/v1/namespaces/default/secrets/harbor
12 uid: 69f79c70-245a-4a91-b846-878a026e7ba6
13type: kubernetes.io/dockerconfigjson
可以看到dockerconfigjson信息已经被加密了,我们可以使用base64解码查看
1$ echo eyJhdXRocyI6eyJodHRwOi8vMTkyLjE2OC4xNjYuMjI5Ijp7InVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6IkhhcmJvckAxYW4iLCJlbWFpbCI6InRlc3RAMTYzLmNvbSIsImF1dGgiOiJZV1J0YVc0NlNHRnlZbTl5UURGaGJnPT0ifX19 | base64 -d
2{"auths":{"http://192.168.166.229":{"username":"admin","password":"harbor123 ","email":"test@163.com","auth":"YWRtaW46SGFyYm9yQDFhbg=="}}}
3.3 Pod使用Secret对象
使用名为harbor的Secret拉取镜像:
1apiVersion: v1
2kind: Pod
3metadata:
4 name: harbortest
5spec:
6 containers:
7 - name: harbor
8 image: 192.168.166.229/test/node-exporter:latest
9 imagePullSecrets:
10 - name: harbor
查看Pod状态
1$ kubectl get pod
2NAME READY STATUS RESTARTS AGE
3harbortest 1/1 Running 0 2m26s
查看Pod创建过程,镜像是否符合定义
1$ kubectl describe pod harbortest
2Events:
3 Type Reason Age From Message
4 ---- ------ ---- ---- -------
5 Normal Scheduled 3m2s default-scheduler Successfully assigned default/harbortest to kubesphere
6 Normal Pulling 2m57s kubelet, kubesphere Pulling image "192.168.166.229/test/node-exporter:latest"
7 Normal Pulled 2m57s kubelet, kubesphere Successfully pulled image "192.168.166.229/test/node-exporter:latest"
8 Normal Created 2m51s kubelet, kubesphere Created container harbor
9 Normal Started 2m51s kubelet, kubesphere Started container harbor
. 4.kubernetes.io/service-account-token
kubernetes.io/service-account-token
类型的Secret用于被 ServiceAccount (服务账户)引用。
Service Account:为Pod中的进程和外部用户提供身份信息。ServiceAccout 创建时 Kubernetes 会默认创建对应的 Secret。
集群创建时会创建一个默认的Service Account
1$ kubectl get sa
2NAME SECRETS AGE
3default 1 233d
4$ kubectl describe sa default
5Name: default
6Namespace: default
7Labels: <none>
8Annotations: <none>
9Image pull secrets: <none>
10Mountable secrets: default-token-g7sqf
11Tokens: default-token-g7sqf
12Events: <none>
可以看到名为“default”的Service Account对应的service-account-token为“default-token-g7sqf”,这是因为ServiceAccout 创建时 Kubernetes 会默认创建对应的 Secret。
然后我们查看之前创建pod的详细信息
1$ kubectl describe pod web-0
2.........................
3 Environment: <none>
4 Mounts:
5 /var/run/secrets/kubernetes.io/serviceaccount from default-token-g7sqf (ro)
6Conditions:
7 Type Status
8 Initialized True
9 Ready True
10 ContainersReady True
11 PodScheduled True
12Volumes:
13 default-token-g7sqf:
14 Type: Secret (a volume populated by a Secret)
15 SecretName: default-token-g7sqf
16 Optional: false
17QoS Class: BestEffort
18Node-Selectors: <none>
19Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
20 node.kubernetes.io/unreachable:NoExecute for 300s
21Events: <none>
可以看到pod使用了名为“default-token-g7sqf”对应的service-account-token,这是因为我们使用kubectl
指令请求apiserver创建的时候,使用的Service Account服务账户为default
,而名为”default“ 的Service Account对应的service-account-token就是“default-token-g7sqf”。对应的 Secret 对象信息会通过 Volume 挂载到容器的/var/run/secrets/kubernetes.io/serviceaccount目录中。
关于Service Account 对象我会在下篇文章中详细解析,欢迎关注。
参考资料:从Docker到Kubernetes进阶-阳明
关注公众号回复【k8s】获取视频教程及更多资料:





