云原生工程师-9.configmap和secret

九.configmap-配置管理

个人博客

9.1-配置管理中心基本概念

9.1.1-什么是configmap

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

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

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

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

9.2-configmap的使用(cm)

9.2.1-通过命令行-文件和目录

直接在命令行中指定configmap参数创建 --from-literal=key=value

[root@master2 ~]# kubectl create configmap tomcat-config --from-literal=tomcat_port=8080 --from-literal=servername=mytomcat
configmap/tomcat-config created
[root@master2 ~]# kubectl get configmap tomcat-config -o yaml
apiVersion: v1
data:
  servername: mytomcat
  tomcat_port: "8080"
kind: ConfigMap
metadata:
  creationTimestamp: "2023-03-16T11:30:45Z"
  name: tomcat-config
  namespace: default
  resourceVersion: "1346681"
  uid: e9d1072c-646d-4e59-bece-9e71f097511a

通过制定文件创建 --from-file=文件

[root@master2 nginx]# kubectl create configmap vip-nginx --from-file=vip-nginx=/etc/nginx/nginx.conf
[root@master2 nginx]# kubectl get cm vip-nginx -o yaml
apiVersion: v1
data:
  vip-nginx: "user nginx; \nworker_processes auto; \nerror_log /var/log/nginx/error.log;
    \npid /run/nginx.pid; \n \ninclude /usr/share/nginx/modules/*.conf; \n \nevents
    { \n worker_connections 1024; \n} \n \n# 四层负载均衡,为两台 Master apiserver 组件提供负载均衡
    \nstream { \n \n log_format main '  - []  \n'; \n \n access_log /var/log/nginx/k8s-access.log
    main; \n \n upstream k8s-apiserver { \n server 192.168.3.110:6443; # Master1 APISERVER
    IP:PORT \n server 192.168.3.111:6443; # Master2 APISERVER IP:PORT \n }\n \n server
    { \n listen 16443; # 由于 nginx 与 master 节点复用,这个监听端口不能是 6443,否则会冲突 \n proxy_pass
    k8s-apiserver; \n } \n} \n \nhttp { \n log_format main ' -  [] \"\" ' \n '  \"\"
    ' \n '\"\" \"\"'; \n \n access_log /var/log/nginx/access.log main; \n \n sendfile
    on; \n tcp_nopush on; \n tcp_nodelay on; \n keepalive_timeout 65; \n types_hash_max_size
    2048; \n \n include /etc/nginx/mime.types; \n default_type application/octet-stream;
    \n\n server { \n listen 80 default_server; \n server_name _; \n \n location /
    { \n } \n } \n}\n"
kind: ConfigMap
metadata:
  creationTimestamp: "2023-03-16T11:35:18Z"
  name: vip-nginx
  namespace: default
  resourceVersion: "1347379"
  uid: 15d261f6-bcee-4df1-9be7-4ddc27c51abb

通过指定目录创建

[root@master2 nginx]# kubectl create cm test-mysql --from-file=/etc/my.cnf.d/
configmap/test-mysql created
[root@master2 nginx]# kubectl get cm test-mysql -o yaml
apiVersion: v1
data:
  client.cnf: |+


    [client]

    [client-mariadb]

  mysql-clients.cnf: |+

    [mysql]

kind: ConfigMap
metadata:
  creationTimestamp: "2023-03-16T11:37:42Z"
  name: test-mysql
  namespace: default
  resourceVersion: "1347748"
  uid: 8039b6ef-f348-4deb-902b-7f787f1c36bf
9.2.2-通过编写yaml
#编写主从数据库的配置文件configmap
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-master-slave
  labels:
    app: mysql-master-slave
data:
  master.cnf: |
    [mysqld]
    log-bin     # 主mysql激活二进制日志
  slave.cnf: |
    [mysqld]
    super-read-only     # 从mysql上面设置为只读
#通过volumeMounts挂载,busybox测试
apiVersion: v1
kind: Pod
metadata:
  name: busybox-test-cm
spec:
  containers:
  - name: busybox-test-cm
    image: docker.io/library/busybox:latest
    command: [ "/bin/sh", "-c", "sleep 3600" ]
    volumeMounts:
    - name: mysql-config
      mountPath: /tmp/config
  volumes:
  - name: mysql-config
    configMap:
      name: mysql-master-slave
#检查结果
kubectl exec -it busybox-test-cm -- sh
/ # ls /tmp/config/
master.cnf  slave.cnf
/ # cat /tmp/config/master.cnf
[mysqld]
log-bin     # 主mysql激活二进制日志
/ # cat /tmp/config/slave.cnf
[mysqld]
super-read-only     # 从mysql上面设置为只读
#

Configmap 热更新:直接kubectl edit cm name 即可

更新后

使用该 ConfigMap 挂载的 Env 不会同步更新

使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概 10 秒)才能同 步更新

1.通过环境变量引入:configMapKeyRef

#mysql配置的configmap
apiVersion: v1 
kind: ConfigMap 
metadata: 
  name: mysql 
  labels: 
   app: mysql 
data: 
  log: "1" 
  lower: "1"
---
#pod引用上述配置文件变量
apiVersion: v1 
kind: Pod 
metadata: 
  name: mysql-pod 
spec: 
  containers: 
  - name: mysql 
    image: busybox 
    command: [ "/bin/sh", "-c", "sleep 3600" ] 
    env: 
    - name: log_bin #定义环境变量 log_bin 
      valueFrom: 
        configMapKeyRef: 
          name: mysql #指定 configmap 的名字 
          key: log #指定 configmap 中的 key 
    - name: lower #定义环境变量 lower 
      valueFrom: 
        configMapKeyRef: 
          name: mysql 
          key: lower 
  restartPolicy: Never

2.通过环境变量引入:envfrom

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 #指定 configmap 的名字 
  restartPolicy: Never
kubectl exec -it mysql-pod-envfrom -- /bin/sh 
/ # printenv 
lower=1 
log=1 
9.2.3-最佳实例主从数据库
apiVersion: v1
data:
  slave.sh: |+
    masterip=`getent hosts mysql-master-slave-0.mysql-master-slave.default.svc.cluster.local | awk '{print $1}'`
    hostip=`cat /etc/hosts | grep svc | awk '{print $1}'`
    mysql -uroot -p000000 -h mysql-master-slave-0.mysql-master-slave.default.svc.cluster.local -e "grant replication slave on *.* to 'admin'@'$hostip' identified by '000000';"
    mysql -uroot -e "CHANGE MASTER TO MASTER_HOST='$masterip', MASTER_USER='admin', MASTER_PASSWORD='000000';start slave;"
kind: ConfigMap
metadata:
  name: slave-sh
  namespace: default
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-master-slave
  labels:
    app: mysql-master-slave
data:
  master.cnf: |
    [mysqld]
    log-bin     # 主mysql激活二进制日志
  slave.cnf: |
    [mysqld]
    super-read-only     # 从mysql上面设置为只读
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-master-slave
  labels:
    app: mysql-master-slave
spec:
  ports:
  - name: mysql
    port: 3306
  clusterIP: None
  selector:
    app: mysql-master-slave
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-read
  labels:
    app: mysql-master-slave
spec:
  type: NodePort
  ports:
  - name: mysql
    port: 3306
    nodePort: 30337
  selector:
    app: mysql-master-slave
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql-master-slave
spec:
  selector:
    matchLabels:
      app: mysql-master-slave
  serviceName: mysql-master-slave
  replicas: 2
  template:
    metadata:
      labels:
        app: mysql-master-slave
    spec:
      initContainers:
      - name: init-mysql
        image: docker.io/library/mysql:5.7
        command:
        - sh
        - -c
        - |
          host_number=$(echo $HOSTNAME | sed 's/[^0-9]*//g')
          echo [mysqld] > /mnt/conf.d/server-id.cnf
          if [ "$host_number" -eq "0" ]; then
            server_id="100"
            echo "server-id=${server_id}" >> /mnt/conf.d/server-id.cnf
            cp /mnt/config-map/master.cnf /mnt/conf.d/
          else
            server_id=$((100 + host_number))
            echo "server-id=${server_id}" >> /mnt/conf.d/server-id.cnf
            cp /mnt/config-map/slave.cnf /mnt/conf.d/
          fi
        volumeMounts:
        - name: conf
          mountPath: /mnt/conf.d
        - name: config-map
          mountPath: /mnt/config-map
      containers:
      - name: mysql
        image: docker.io/library/mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "000000"
        ports:
        - name: mysql
          containerPort: 3306
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
        - name: conf
          mountPath: /etc/mysql/conf.d
        - name: slave-sh
          mountPath: /root/
        livenessProbe:
          exec:
            command: ["mysqladmin", "ping"]
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
        readinessProbe:
          exec:
            command: ["mysqladmin","ping"]
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
      volumes:
      - name: conf
        emptyDir: {}
      - name: config-map
        configMap:
          name: mysql-master-slave
      - name: slave-sh
        configMap:
          name: slave-sh
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: nfs
      resources:
        requests:
          storage: 1Gi

十.配置管理中心Secret

10.1secret基本概念

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 的认证信息。

10.2secret的使用

1.配置mysql的root的password

kubectl create secret generic mysql-password --from-literal=password=Mysql123456
#--from-literal=key=value
[root@master2 ~]# kubectl get secret
NAME             TYPE     DATA   AGE
mysql-password   Opaque   1      26s
[root@master2 ~]# kubectl get secret mysql-password -o yaml
apiVersion: v1
data:
  password: TXlzcWwxMjM0NTY=
kind: Secret
metadata:
  creationTimestamp: "2023-03-19T06:40:04Z"
  name: mysql-password
  namespace: default
  resourceVersion: "1963925"
  uid: 2bea85f9-f0cc-407b-b46b-3b41b9899f9e
type: Opaque
#password的值是加密的
#但secret 的加密是一种伪加密,它仅仅是将数据做了 base64 的编码.
#解码
[root@master2 secret]# echo TXlzcWwxMjM0NTY= | base64 -d
Mysql123456
apiVersion: v1
kind: Pod
metadata:
  name: mysql
  labels:
    test: mysql
spec:
  containers:
  - name: mysql-test
    image: docker.io/library/mysql:5.7
    ports:
      - name: mysql
        containerPort: 3306
    env:
     - name: MYSQL_ROOT_PASSWORD
       valueFrom:
         secretKeyRef:
           name: mysql-password #secret名
           key: password #secret 中key值
[root@master2 secret]# kubectl exec -it mysql -- /bin/bash
bash-4.2# printenv |grep MYSQL_ROOT_PASSWORD
MYSQL_ROOT_PASSWORD=Mysql123456

将secret挂载到volume中

apiVersion: v1
kind: Pod
metadata:
  name: busybox-test
  labels:
    test: busybox
spec:
  containers:
  - name: mysql-test
    image: docker.io/library/busybox:latest
    command: ["sh","-c","sleep 3600"]
    volumeMounts:
    - name: mysqlpassword
      mountPath: /root/
      readOnly: true
  volumes:
  - name: mysqlpassword
    secret:
      secretName: mysql-password
[root@master2 secret]# kubectl exec -it busybox-test -- sh
/ #
/ # ls /root/
password
/ # cat /root/password
Mysql123456/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

永恒布gg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值