杨梅冲
每天在想什么呢?

一、Configmap概述

1.1 什么是configmap

  Configmap 是 k8s 中的资源对象,用于保存非机密性的配置的,数据可以用 key/value 键值对的形式保存,也可通过文件的形式保存。

1.2 Configmap能解决哪些问题?

        我们在部署服务的时候,每个服务都有自己的配置文件,如果一台服务器上部署多个 服务:nginx、tomcat、apache 等,那么这些配置都存在这个节点上,假如一台服务 器不能满足线上高并发的要求,需要对服务器扩容,扩容之后的服务器还是需要部署 多个服务:nginx、tomcat、apache,新增加的服务器上还是要管理这些服务的配置, 如果有一个服务出现问题,需要修改配置文件,每台物理节点上的配置都需要修改, 这种方式肯定满足不了线上大批量的配置变更要求。 所以,k8s 中引入了 Configmap 资源对象,可以当成 volume 挂载到 pod 中,实现统一的配置管理

 

1、Configmap 是 k8s 中的资源, 相当于配置文件,可以有一个或者多个 Configmap;
2、Configmap 可以做成 Volume,k8s pod 启动之后,通过 volume 形式映射到容器内 部指定目录上;
3、容器中应用程序按照原有方式读取容器特定目录上的配置文件。
4、在容器看来,配置文件就像是打包在容器内部特定目录,整个过程对应用没有任何侵入。 

1.3 configmap应用场景

  1、使用 k8s 部署应用,当你将应用配置写进代码中,更新配置时也需要打包镜像, configmap 可以将配置信息和 docker 镜像解耦,以便实现镜像的可移植性和可复用 性,因为一个 configMap 其实就是一系列配置信息的集合,可直接注入到 Pod 中给容 器使用。configmap 注入方式有两种,一种将 configMap 做为存储卷,一种是将 configMap 通过 env 中 configMapKeyRef 注入到容器中

  2、使用微服务架构的话,存在多个服务共用配置的情况,如果每个服务中单独一份配 置的话,那么更新配置就很麻烦,使用 configmap 可以友好的进行配置共享

1.4 configmap局限性

  ConfigMap 在设计上不是用来保存大量数据的。在 ConfigMap 中保存的数据不可超过 1 MiB。如果你需要保存超出此尺寸限制的数据,可以考虑挂载存储卷或者使用独立的数 据库或者文件服务

1.5 configmap创建方法

# 1.命令行直接创建
# 直接在命令行中指定 configmap 参数创建,通过--from-literal 指定参数
kubectl create configmap --help

[root@master ds]# kubectl create configmap tomcat-config --from-literal=tomcat_port=8080 --from-literal=server_name=myapp.tomcat.com
configmap/tomcat-config created

# kubectl get configmap
[root@master ds]# kubectl get cs
NAME                                 DATA   AGE
calico-config                        4      16d
coredns                              1      25d
extension-apiserver-authentication   6      25d
kube-proxy                           2      25d
kube-root-ca.crt                     1      25d
kubeadm-config                       2      25d
kubelet-config-1.20                  1      25d
metrics-server-config                1      16d
tomcat-config                        2      50s

[root@master ds]# kubectl describe cm tomcat-config
Name:         tomcat-config
Namespace:    kube-system
Labels:       <none>
Annotations:  <none>

Data
====
server_name:
----
myapp.tomcat.com
tomcat_port:
----
8080
Events:  <none>
#2.通过文件创建
通过指定文件创建一个 configmap,--from-file=<文件>

[root@master configmap]# kubectl create configmap www-nginx --from-file=www=./nginx.conf
configmap/www-nginx created

[root@master configmap]# kubectl describe cm www-nginx
Name:         www-nginx
Namespace:    kube-system
Labels:       <none>
Annotations:  <none>

Data
====
www:
----
nginx.conf的内容

Events:  <none>

# 指定文件创建configmap
[root@master configmap]# kubectl create configmap www-nginx-1 --from-file=./nginx.conf
configmap/www-nginx-1 created
# 3.指定目录创建configmap
mkdir /root/test-a
cd /root/test-a
[root@master test-a]# cat my-server.cnf 
server-id=1
[root@master test-a]# cat my-slave.cnf 
server-id=2
[root@master ~]# kubectl create configmap mysql-config --from-file=/root/test-a/
configmap/mysql-config created
[root@master ~]# kubectl describe cm mysql-config
Name:         mysql-config
Namespace:    kube-system
Labels:       <none>
Annotations:  <none>

Data
====
my-server.cnf:
----
server-id=1

my-slave.cnf:
----
server-id=2

Events:  <none>

1.6 configmap资源清单编写技巧

[root@master ds]# kubectl explain configmap
KIND:     ConfigMap
VERSION:  v1

FIELDS:
apiVersion    <string>
binaryData    <map[string]string>
data    <map[string]string>
immutable    <boolean>
kind    <string>
metadata    <Object>


[root@master configmap]# cat mysql-configmap.yaml 
apiVersion: v1 
kind: ConfigMap 
metadata: 
  name: mysql 
  labels: 
    app: mysql 
data: 
  master.cnf: |   # |表示有多行,下面按行分离
   [mysqld] 
   log-bin
   log_bin_trust_function_creators=1 
   lower_case_table_names=1 
 slave.cnf: | 
   [mysqld] 
   super-read-only 
   log_bin_trust_function_creators=1 

1.7 使用configmap

# 1.通过环境变量引入:使用 configMapKeyRef
#创建一个存储 mysql 配置的 configmap
[root@master configmap]# cat configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
data:
  log: "1"
  lower: "1"
[root@master configmap]# kubectl apply -f configmap.yaml 
configmap/mysql created
[root@master configmap]# kubectl get cm
NAME                                 DATA   AGE
mysql                                2      11s

# 创建pod,引入mysql
[root@master configmap]# cat mysql-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod
  namespace: default
spec:
  containers:
  - name: mysql
    image: busybox
    imagePullPolicy: IfNotPresent
    command: [ "/bin/sh", "-c", "sleep 3600" ]
    env:
    - name: log_bin  # 定义环境变量log_bin
      valueFrom:
        configMapKeyRef:
          name: mysql   # 指定configmap名字
          key: log          # 指定configmap的key
    - name: lower
      valueFrom:
        configMapKeyRef:
          name: mysql
          key: lower
  restartPolicy: Never

[root@master configmap]# kubectl apply -f mysql-pod.yaml 
pod/mysql-pod created
[root@master configmap]# kubectl get pods
NAME                                       READY   STATUS             RESTARTS   AGE
mysql-pod                                  1/1     Running            0          7s
[root@master configmap]# kubectl exec -it mysql-pod -c mysql -- /bin/sh
/ # printenv
log_bin=1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
METRICS_SERVER_PORT_443_TCP_ADDR=10.105.85.228
KUBE_DNS_SERVICE_PORT_DNS_TCP=53
HOSTNAME=mysql-pod
METRICS_SERVER_PORT_443_TCP_PORT=443
SHLVL=1
METRICS_SERVER_PORT_443_TCP_PROTO=tcp
HOME=/root
SPRINGBOOT_SERVICE_PORT_SERVER=8080
KUBE_DNS_SERVICE_HOST=10.96.0.10
KUBE_DNS_PORT_9153_TCP_ADDR=10.96.0.10
KUBE_DNS_PORT_9153_TCP_PORT=9153
METRICS_SERVER_PORT_443_TCP=tcp://10.105.85.228:443
KUBE_DNS_PORT_9153_TCP_PROTO=tcp
KUBE_DNS_PORT=udp://10.96.0.10:53
METRICS_SERVER_SERVICE_HOST=10.105.85.228
KUBE_DNS_SERVICE_PORT=53
TERM=xterm
lower=1
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
SPRINGBOOT_SERVICE_HOST=10.105.225.164
SPRINGBOOT_PORT_8080_TCP_ADDR=10.105.225.164
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
SPRINGBOOT_PORT_8081_TCP_ADDR=10.105.225.164
KUBE_DNS_PORT_53_TCP_ADDR=10.96.0.10
KUBERNETES_PORT_443_TCP_PORT=443
KUBE_DNS_SERVICE_PORT_METRICS=9153
SPRINGBOOT_PORT_8080_TCP_PORT=8080
METRICS_SERVER_SERVICE_PORT=443
METRICS_SERVER_PORT=tcp://10.105.85.228:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBE_DNS_PORT_9153_TCP=tcp://10.96.0.10:9153
KUBE_DNS_PORT_53_UDP_ADDR=10.96.0.10
SPRINGBOOT_PORT_8081_TCP_PORT=8081
SPRINGBOOT_PORT_8080_TCP_PROTO=tcp
SPRINGBOOT_PORT_8081_TCP_PROTO=tcp
KUBE_DNS_PORT_53_TCP_PORT=53
KUBE_DNS_PORT_53_TCP_PROTO=tcp
KUBE_DNS_PORT_53_UDP_PORT=53
SPRINGBOOT_PORT=tcp://10.105.225.164:8080
SPRINGBOOT_SERVICE_PORT=8080
KUBE_DNS_SERVICE_PORT_DNS=53
KUBE_DNS_PORT_53_UDP_PROTO=udp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
SPRINGBOOT_PORT_8080_TCP=tcp://10.105.225.164:8080
KUBERNETES_SERVICE_HOST=10.96.0.1
SPRINGBOOT_PORT_8081_TCP=tcp://10.105.225.164:8081
PWD=/
KUBE_DNS_PORT_53_TCP=tcp://10.96.0.10:53
KUBE_DNS_PORT_53_UDP=udp://10.96.0.10:53
SPRINGBOOT_SERVICE_PORT_MANAGEMENT=8081
# 2. 通过环境变量引入:使用envfrom
[root@master configmap]# cat mysql-pod-envFrom.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod-envfrom
spec:
  containers:
  - name: mysql
    image: busybox
    imagePullPolicy: IfNotPresent
    command: [ "/bin/sh", "-c", "sleep 3600" ]
    envFrom:
    - configMapRef:
        name: mysql
  restartPolicy: Never

[root@master configmap]# kubectl exec -it mysql-pod-envfrom -- /bin/sh
/ # printenv
lower=1
log=1
# 常用方式:把 configmap 做成 volume,挂载到 pod
[root@master configmap]# cat configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
data:
  log: "1"
  lower: "1"
  my.cnf: |
    [mysqld]
    Welcome=cxiong

[root@master configmap]# kubectl apply -f configmap.yaml 
configmap/mysql configured
[root@master configmap]# kubectl describe cm mysql
Name:         mysql
Namespace:    kube-system
Labels:       app=mysql
Annotations:  <none>

Data
====
log:
----
1
lower:
----
1
my.cnf:
----
[mysqld]
Welcome=cxiong

Events:  <none>

[root@master configmap]# cat mysql-pod-volume.yaml 
apiVersion: v1
kind: Pod
metadata:
 name: mysql-pod-volume
spec:
  containers:
  - name: mysql
    image: busybox
    imagePullPolicy: IfNotPresent
    command: [ "/bin/sh", "-c", "sleep 3600" ]
    volumeMounts:
    - name: mysql-config
      mountPath: /tmp/config
  volumes:
  - name: mysql-config
    configMap:
      name: mysql
  restartPolicy: Never
[root@master configmap]# kubectl apply -f mysql-pod-volume.yaml 
pod/mysql-pod-volume created

[root@master configmap]# kubectl exec -it mysql-pod-volume -c mysql -- /bin/sh
/ # cd /tmp/config
/tmp/config # ls
log     lower   my.cnf
/tmp/config # cat log
1
/tmp/config # cat lower
1
/tmp/config # cat my.cnf 
[mysqld]
Welcome=cxiong

1.8 configmap热更新

# 将log=1 改为log=2
[root@master configmap]# kubectl edit cm mysql
configmap/mysql edited
[root@master configmap]# kubectl exec -it mysql-pod-volume -c mysql -- /bin/sh
/ # cd /tmp/config
/tmp/config # cat log
1
...
/tmp/config # cat log  # 需要等一会才能生效
2

注意: 
更新 ConfigMap 后: 
使用该 ConfigMap 挂载的 Env 不会同步更新 :mysql-pod-envfrom中log还是1,也没有Welcome,不会随环境变量变化而变化,会随卷变化
 
使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概 10 秒)才能同步更新 

二、Secret概述

2.1 secret是什么?

  上面我们学习的 Configmap 一般是用来存放明文数据的,如配置文件;对于一些敏感数据,如密码、私钥等数据时,要用 secret 类型

  Secret 解决了密码、token、秘钥等敏感数据的配置问题,而不需要把这些敏感数据 暴露到镜像或者 Pod Spec 中。Secret 可以以 Volume 或者环境变量的方式使用

  要使用 secret,pod 需要引用 secret。Pod 可以用两种方式使用 secret:作为 volume 中的文件被挂载到 pod 中的一个或者多个容器里,或者当 kubelet 为 pod 拉取 镜像时使用

secret 可选参数有三种: 
    generic: 通用类型,通常用于存储密码数据。 
    tls:此类型仅用于存储私钥和证书。 
    docker-registry: 若要保存 docker 仓库的认证信息的话,就必须使用此种类型来创建。 

Secret 类型:

Service Account:用于被 serviceaccount 引用。serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。Pod 如果使用了 serviceaccount,对应的 secret 会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录 中。

Opaque:base64 编码格式的 Secret,用来存储密码、秘钥等。可以通过 base64 -- decode 解码获得原始数据,因此安全性弱

kubernetes.io/dockerconfigjson:用来存储私有 docker registry 的认证信息。

2.2 使用secret

# 1.通过环境变量引入secret
[root@master secret]# kubectl create secret generic mysql-password --from-literal=password=mysql**@123
secret/mysql-password created
[root@master secret]# kubectl get secret | grep mysql-password
mysql-password                                   Opaque                                1      19s
[root@master secret]# kubectl describe secret mysql-password
Name:         mysql-password
Namespace:    kube-system
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  11 bytes
#password 的值是加密的, 
#但 secret 的加密是一种伪加密,它仅仅是将数据做了 base64 的编码.
[root@master secret]# cat pod-secret.yaml apiVersion: v1 kind: Pod metadata: name: pod-secret labels: app: myapp spec: containers: - name: myapp image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort:
80 env: - name: MYSQL_ROOT_PASSWORD #它是 Pod 启动成功后,Pod 中容器的环境变量名. valueFrom: secretKeyRef: name: mysql-password # secret对象名 key: password # secret中的key名 [root@master secret]# kubectl apply -f pod-secret.yaml pod/pod-secret created pod-secret 1/1 Running 0 16s [root@master secret]# kubectl exec -it pod-secret -c myapp -- /bin/sh / # printenv MYSQL_ROOT_PASSWORD=mysql**@123
#2.通过 volume 挂载 Secret
#手动加密,基于 base64 加密
[root@master secret]#  echo -n "admin" | base64
YWRtaW4=
# 解密
[root@master secret]# echo YWRtaW4= | base64 -d
admin


[root@master configmap]# echo -n "mysql**@123" | base64
bXlzcWwqKkAxMjM=
[root@master configmap]# echo -n "mysql" | base64
bXlzcWw=
[root@master secret]# kubectl apply -f secret.yaml 
secret/mysecret created
[root@master secret]# kubectl get secret | grep mysecret
mysecret                                         Opaque                                2      15s
[root@master secret]# kubectl describe secret mysecret
Name:         mysecret
Namespace:    kube-system
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  11 bytes
username:  5 bytes

[root@master secret]# cat pod-secret-volume.yaml 
apiVersion: v1 
kind: Pod 
metadata: 
  name: pod-secret-volume 
spec: 
  containers: 
  - name: myapp 
    image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
    imagePullPolicy: IfNotPresent
    volumeMounts: 
    - name: secret-volume 
      mountPath: /etc/secret 
      readOnly: true 
  volumes: 
  - name: secret-volume 
    secret: 
      secretName: mysecret

[root@master secret]# kubectl apply -f pod-secret-volume.yaml 
pod/pod-secret-volume created

pod-secret-volume                          1/1     Running            0          50s

[root@master secret]# kubectl exec -it pod-secret-volume -c myapp -- /bin/sh
/ # cd /etc/secret
/etc/secret # ls
password  username
/etc/secret # cat password
mysql**@123
/etc/secret # cat username
mysql

 

posted on 2022-08-04 14:12  杨梅冲  阅读(226)  评论(0编辑  收藏  举报