Kubernetes ConfigMap 与 Secret 场景应用

来自AI助手的总结
ConfigMap和Secret用于Kubernetes配置管理,前者支持热更新,后者存储敏感信息
Kubernetes ConfigMap 与 Secret 场景应用

一、ConfigMap

1.1 概述

ConfigMap是一种API对象,用来将 非加密数据 保存到 键值对 中。可以用作环境变量、命令行参数或者存储卷中的配置文件。

ConfigMap可以将环境变量配置信息和容器镜像解耦,便于应用配置的修改。如果需要存储加密信息时可以使用Secret对象。

1.2 作用

ConfigMap是Kubernetes系统上两种特殊类型的存储卷,ConfigMap对象用于为容器中的应用提供配置文件等信息。

例如:nginx、redis、mysql、coredns、jenkins、apollo等配置文件,实现统一管理, 热更新等;

1.3 创建ConfigMap的常用3种方式

1、命令行方式创建,格式:–from-literal=key=value


# 创建cm

[root@master01 1]# kubectl create configmap cm1 --from-literal=server_name=www.xxx.com --from-literal=listen=80

# 查看

[root@master01 1]# kg cm

NAME                 DATA   AGE

cm1                  2      5s

# 环境复原

[root@master01 1]# k delete cm cm1

2、通过指定文件(内设多个键值对),格式: –from-env-file=文件路径


# 定义加密文件

cat > env.txt <<EOF

server_name=www.xxx.com

listen=80

EOF

# 创建cm

[root@master01 1]# kubectl create configmap cm2 --from-env-file=env.txt

# 查看

[root@master01 1]# kg cm

NAME                 DATA   AGE

cm2                  2      6s

# 环境复原

[root@master01 1]# k delete cm cm2

3、通过YMAL文件创建


# 创建cm模板

[root@master01 1]# k create cm cm3 --from-literal=server_name=www.xxx.com  --from-literal=listen=80 --dry-run=client -oyaml > cm3.yaml

# 定义yaml文件

[root@master01 1]# vim cm3.yaml

apiVersion: v1

data:

  listen: "80"

  server_name: www.xxx.com

kind: ConfigMap

metadata:

  name: cm3

# 创建

[root@master01 1]# kaf cm3.yaml

# 环境复原

[root@master01 1]# k delete -f cm3.yaml

另外一种创建方式:

apiVersion: v1
data:
  nginx.conf: |
    server {
      server_name www.nginx.com;
      listen 80;
      root /home/nginx/www/
    }
metadata:
  name: nginx-conf
  labels:
    app: nginx-conf

1.4 ConfigMap的2种使用方式

1、通过环境变量的方式传递给pod


# 创建cm1

[root@master01 1]# kubectl create configmap cm1 --from-literal=server_name=www.xxx.com --from-literal=listen=80

# 创建pod模板

[root@master01 1]# k run pod-cm1 --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/busybox:1.28  --dry-run=client -oyaml > pod-cm1.yaml

# 定义

[root@master01 1]# vim pod-cm1.yaml

apiVersion: v1

kind: Pod

metadata:

  name: pod-cm1

spec:

  containers:

  - image: registry.cn-hangzhou.aliyuncs.com/abroad_images/busybox:1.28

    name: busybox

    args: [ "/bin/sh", "-c", "sleep 10000" ]

    envFrom: # env方式

    - configMapRef:

        name: cm1 # configmap名称

# 应用

[root@master01 1]# kaf pod-cm1.yaml

# 查看

[root@master01 1]# kgp | grep pod-cm1

pod-cm1   1/1     Running   0          5s

[root@master01 1]# kubectl exec pod-cm1 -- env|grep listen

listen=80

# 修改监听端口为99

[root@master01 1]# k edit cm cm1

apiVersion: v1

data:

  listen: "99"

  server_name: www.xxx.com

kind: ConfigMap

metadata:

  creationTimestamp: "2023-11-10T01:52:21Z"

  name: cm1

  namespace: default

  resourceVersion: "940983"

  uid: b42dd508-73c4-4286-9e66-758701ca71d3

# 再次验证,观察到端口没有更新

[root@master01 1]# kubectl exec pod-cm1 -- env|grep listen

listen=80

# 环境复原

[root@master01 1]# k delete -f pod-cm1.yaml

[root@master01 1]# k delete cm cm1

2、通过volume的方式挂载到pod内


# 定义加密文件

cat > env.txt <<EOF

server_name=www.xxx.com

listen=80

EOF

# 创建cm

[root@master01 1]# kubectl create configmap cm2 --from-env-file=env.txt

# 创建pod模板

[root@master01 1]# k run pod-cm2 --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/busybox:1.28  --dry-run=client -oyaml > pod-cm2.yaml

# 定义

[root@master01 1]# vim pod-cm2.yaml

apiVersion: v1

kind: Pod

metadata:

  name: pod-cm2

spec:

  containers:

  - image: registry.cn-hangzhou.aliyuncs.com/abroad_images/busybox:1.28

    name: busybox

    args: [ "/bin/sh", "-c", "sleep 10000" ]

    volumeMounts: # 用volume挂载方式

    - name: vol-cm # 对应下面的volume名

      mountPath: "/etc/nginx" # 挂载到容器内部的路径

      readOnly: true # 只读

  volumes:

  - name: vol-cm # 卷名称

    configMap:

      name: cm2 # configmap的名称

# 应用

[root@master01 1]# kaf pod-cm2.yaml

# 查看

[root@master01 1]# kgp | grep pod-cm2

pod-cm2                         1/1     Running   0             8s

[root@master01 1]# kubectl exec pod-cm2 -- cat /etc/nginx/listen

80

# 修改监听端口为99

[root@master01 1]# k edit cm cm2

apiVersion: v1

data:

  listen: "99"

  server_name: www.xxx.com

kind: ConfigMap

metadata:

  creationTimestamp: "2023-11-10T02:00:08Z"

  name: cm2

  namespace: default

  resourceVersion: "941120"

  uid: 4323506b-1ecc-430a-9a31-2a11983b67a1

# 再次验证,观察到端口更新(要等个1分钟左右)

[root@master01 1]# kubectl exec pod-cm2 -- cat /etc/nginx/listen

99

# 环境复原

[root@master01 1]# k delete -f pod-cm2.yaml

[root@master01 1]# k delete  cm cm2

1.5 ConfigMap的热更新

结论:

  • 通过环境变量的方式传递给pod。这种方式不会热更新;

  • 通过volume的方式挂载到pod内。这种方式会热更新;

验证第1种方式:编辑修改对应的configmap

# 编辑
kubectl edit cm cm1
# 验证
kubectl exec pod-cm1 -- env|grep listen

验证第2种方式:编辑修改对应的configmap

# 编辑
kubectl edit cm cm2
# 验证
kubectl exec pod-cm2 -- cat /etc/nginx/listen

验证对应的pod里的变化,一段时间后会改变

二、Secret

Secret与ConfigMap类似,主要的区别是Secret存储的是密文,而ConfigMap存储的是明文。

所以ConfigMap可以用配置文件管理,而而 Secret可用于密码,密钥,token等敏感数据的配置管理。

Secret有4种类型:

  • Opaque: base64编码格式的Secret,用来存储密码密钥信息证书等,类型标识符为generic

  • Service Account: 用来访问Kubernetes API,由Kubernetes自动创建,并且会 自动挂载 到Pod的/run/secrets/kubernetes.io/serviceaccount目录中

  • kubernetes.io/dockerconfigjson: 用来存储私有 docker registry的认证 信息, 类型标识为docker-registry。

  • kubernetes.io/tls: 用于为SSL通信模式存储 证书私钥 文件,命令式创建类型标识为tls。

2.1 Opaque

1、将明文密码进行base64编码


[root@master01 1]# echo -n hellomysql |base64

aGVsbG9teXNxbA==

2、编写创建secret的YAML文件


# 创建secret模板文件

[root@master01 1]# k create secret generic secret-mysql --dry-run=client -oyaml > secret-mysql.yaml

# 定义yaml文件

[root@master01 1]# vim secret-mysql.yaml

apiVersion: v1

kind: Secret

metadata:

  name: secret-mysql

data:

  password: aGVsbG9teXNxbA==

# 应用

[root@master01 1]# kaf secret-mysql.yaml

# 查看

[root@master01 1]# kg secret | grep secret-mysql

secret-mysql                       Opaque                                1      30s

2.1 Secret的2种使用方式

1、通过ENV变量的方式

创建mysql的pod示例,引用来自如上的 secret-mysql


# 定义yaml文件

[root@master01 1]# vim secret-mysql.yaml

apiVersion: v1

kind: Secret

metadata:

  name: secret-mysql

data:

  password: aGVsbG9teXNxbA==

# 应用

[root@master01 1]# kaf secret-mysql.yaml

------------

# 创建pod模板

[root@master01 1]# k run pod-mysql-secret1 --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/mysql:5.7.23  --dry-run=client -oyaml > pod-mysql-secret1.yaml

# 定义yaml文件

[root@master01 1]# vim pod-mysql-secret1.yaml

apiVersion: v1

kind: Pod

metadata:

  name: pod-mysql-secret1

spec:

  containers:

  - image: registry.cn-hangzhou.aliyuncs.com/abroad_images/mysql:5.7.23

    name: mysql

    env:

      - name: MYSQL_ROOT_PASSWORD

        valueFrom:

          secretKeyRef:

            name: secret-mysql # 对应创建的secret名字

            key: password

# 应用

[root@master01 1]# kaf pod-mysql-secret1.yaml

# 查看

[root@master01 1]# kgp | grep pod-mysql

pod-mysql-secret1               1/1     Running   0             5m39s

# 验证,其中密文会被转义成明文

[root@master01 1]# kubectl exec pod-mysql-secret1 -- env | grep MYSQL_ROOT_PASSWORD

MYSQL_ROOT_PASSWORD=hellomysql

# 提前获取加密密码

[root@master01 1]# echo -n "mysql" | base64

bXlzcWw=

# 修改密码为mysql

[root@master01 1]# k edit secret secret-mysql

apiVersion: v1

data:

  password: bXlzcWw=

kind: Secret

metadata:

  annotations:

    kubectl.kubernetes.io/last-applied-configuration: |

      {"apiVersion":"v1","data":{"password":"aGVsbG9teXNxbA=="},"kind":"Secret","metadata":{"annotations":{},"name":"secret-mysql","namespace":"default"}}

  creationTimestamp: "2023-11-10T03:09:08Z"

  name: secret-mysql

  namespace: default

  resourceVersion: "960444"

  uid: 6b5d95d5-a329-4f80-ba96-f298de3213f4

type: Opaque

# 再次验证,观察到密码未被修改

[root@master01 1]# kubectl exec pod-mysql-secret1 -- env | grep MYSQL_ROOT_PASSWORD

MYSQL_ROOT_PASSWORD=hellomysql

# 环境复原

[root@master01 1]# k delete -f pod-mysql-secret1.yaml

[root@master01 1]# k delete -f secret-mysql.yaml

2、通过volume的方式挂载


# 定义yaml文件

[root@master01 1]# vim secret-mysql.yaml

apiVersion: v1

kind: Secret

metadata:

  name: secret-mysql

data:

  password: aGVsbG9teXNxbA==

# 应用

[root@master01 1]# kaf secret-mysql.yaml

------------

# 创建pod模板

[root@master01 1]# k run pod-mysql-secret2 --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/mysql:5.7.23  --dry-run=client -oyaml > pod-mysql-secret2.yaml

# 定义yaml文件

[root@master01 1]# vim pod-mysql-secret2.yaml

apiVersion: v1

kind: Pod

metadata:

  name: pod-mysql-secret2

spec:

  containers:

  - name: busybox

    image: registry.cn-hangzhou.aliyuncs.com/abroad_images/busybox:1.28

    args:

    - /bin/sh

    - -c

    - sleep 100000

    volumeMounts:

    - name: vol-secret   #定义挂载的卷,对应下面定义的卷名

      mountPath: "/opt/passwd" #挂载目录(支持热更新),也可以使用subPath挂载文件(但不支持热更新)

      readOnly: true #只读

  volumes:

  - name: vol-secret #定义卷名

    secret:          #使用secret

      secretName: secret-mysql  #对应创建好的secret名

# 应用

[root@master01 1]# kaf  pod-mysql-secret2.yaml

# 查看

[root@master01 1]# kgp | grep pod-mysql-secret2

pod-mysql-secret2               1/1     Running   0              49s

# 验证

[root@master01 1]# kubectl exec pod-mysql-secret2 -- cat /opt/passwd/password

hellomysql

# 提前获取加密密码

[root@master01 1]# echo -n "mysql" | base64

bXlzcWw=

# 修改密码为mysql

[root@master01 1]# k edit secret secret-mysql

apiVersion: v1

data:

  password: bXlzcWw=

kind: Secret

metadata:

  annotations:

    kubectl.kubernetes.io/last-applied-configuration: |

      {"apiVersion":"v1","data":{"password":"aGVsbG9teXNxbA=="},"kind":"Secret","metadata":{"annotations":{},"name":"secret-mysql","namespace":"default"}}

  creationTimestamp: "2023-11-10T03:09:08Z"

  name: secret-mysql

  namespace: default

  resourceVersion: "960444"

  uid: 6b5d95d5-a329-4f80-ba96-f298de3213f4

type: Opaque

# 等待1分钟后再次验证,观察到密码已被修改

[root@master01 1]# kubectl exec pod-mysql-secret2 -- cat /opt/passwd/password

mysql

# 环境复原

[root@master01 1]# k delete -f pod-mysql-secret2.yaml

[root@master01 1]# k delete -f secret-mysql.yaml

2.1 小结

  • 通过env的方式 pod中参数并未发生变化;

  • 需重启pod;

  • 推荐更新configMap的name;

  • 通过挂载的方式 pod中参数发生变化;

2.2 dockerconfigjson

场景:使用jenkins自动部署容器到K8S中,其中一个步骤就是在运行容器前需要下载当前应用镜像,这时候就需要我们通过secret创建docker类型的秘钥来进行授权并拉取镜像


# 提前使用docker login登录harbor私仓,不然不会生成授权文件

docker login xxx

# 查看授权文件

[root@master01 1]# cat /root/.docker/config.json

# 通过授权文件来进行加密创建

[root@master01 1]# kubectl create secret generic harborsecret --from-file=/root/.docker/config.json --type=kubernetes.io/dockerconfigjson -n default

引用:

apiVersion: v1
kind: Pod
metadata:
  name: fooTest
spec:
  containers:
  - name: fooTest
    image: xxx/xxxxapp:v1
  imagePullSecrets:
    - name: harborsecret

2.3 kubernetes.io/tls

场景:在K8S业务场景中,很多服务通过ingress进行暴露,多数应用的核心通讯协议为 https,这就需要我们引入对应域名的证书tls;


kubectl create secret tls ingress-secret2023 -ndefault --key 7128773_xxxx.com.key --cert 7128773_xxxx.com.pem

引用:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    ingress.kubernetes.io/proxy-body-size: "0"
    ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "0"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  labels:
    app: harbor
    chart: harbor
    heritage: Tiller
    release: xxxx
  name: xxxx-harbor-ingress
  namespace: default
spec:
  rules:
  - host: core-harbor.xxxx.com
    http:
      paths:
      - backend:
          serviceName: xxxx-harbor-portal
          servicePort: 80
        path: /
      - backend:
          serviceName: xxxx-harbor-core
          servicePort: 80
        path: /api/
      - backend:
          serviceName: xxxx-harbor-core
          servicePort: 80
        path: /service/
      - backend:
          serviceName: xxxx-harbor-core
          servicePort: 80
        path: /v2/
      - backend:
          serviceName: xxxx-harbor-core
          servicePort: 80
        path: /chartrepo/
      - backend:
          serviceName: xxxx-harbor-core
          servicePort: 80
        path: /c/
  - host: core-harbor.xxxx.com
    http:
      paths:
      - backend:
          serviceName: xxxx-harbor-notary-server
          servicePort: 4443
        path: /
  tls:
  - hosts:
    - core-harbor.xxxx.com
    secretName: ingress-secret2023
© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容