Kubernetes Pod的配置管理 ConfigMap和Secret

目录

前言

一、为什么需要配置管理

二、使用ConfigMap管理Pod的配置信息

[2.1 创建ConfigMap(4种方式)](#2.1 创建ConfigMap(4种方式))

[2.1.1 指定ConfigMap的参数创建](#2.1.1 指定ConfigMap的参数创建)

[2.1.2 指定配置文件创建ConfigMap](#2.1.2 指定配置文件创建ConfigMap)

[2.1.3 通过一个文件内的多个键值对创建ConfigMap](#2.1.3 通过一个文件内的多个键值对创建ConfigMap)

[2.1.4 yaml文件创建ConfigMap](#2.1.4 yaml文件创建ConfigMap)

[2.2 使用ConfigMap(2种方式)](#2.2 使用ConfigMap(2种方式))

[2.2.1 环境变量evn](#2.2.1 环境变量evn)

[2.2.2 数据卷volume](#2.2.2 数据卷volume)

[2.3 ConfigMap的动态更新(数据卷volume方式才支持动态更新)](#2.3 ConfigMap的动态更新(数据卷volume方式才支持动态更新))

三、使用Secret管理Pod的配置信息

[3.1 创建Secret](#3.1 创建Secret)

[3.1.1 账号密码文件创建](#3.1.1 账号密码文件创建)

[3.1.2 yaml文件创建](#3.1.2 yaml文件创建)

[3.2 使用Secret](#3.2 使用Secret)

[3.2.1 环境变量env使用](#3.2.1 环境变量env使用)

[3.2.2 数据卷volume使用](#3.2.2 数据卷volume使用)


前言

当镜像制作完成后被用来创建Pod时,如果需要修改镜像中的一些参数值则比较麻烦------需要重新制作镜像。能否让镜像根据实际的需要,自动读取响应的配置信息呢?这时就需要使用Kubernetes的配置管理。

一、为什么需要配置管理

在实际的应用开发过程中会遇到这样的情况:在开发Web应用时,在开发环境需要链接M有SQL数据库;而在生产环境中需要链接Redis数据库,这两套相互独立的环境。就需要为应用指定不同的参数来满足实际的要求。如果不能很好的管理这些配置信息,则运维工作将变得无比烦恼。

为了解决这样的问题,Kubernetes提供了自己的解决方案,它将配置信息作为一种独立的资源存入配置中心,并将其以注入的方式提供给Pod使用。如果更新了配置中心的配置信息,则Pod会自动加载更新后的配置信息。Kubernetes主要通过ConfigMap和Secret两种方式来实现配置信息的管理。

二、使用ConfigMap管理Pod的配置信息

ConfigMap是用来存储配置信息的Kubernetes资源对象。ConfigMap采用明文的方式将所有的配置信息都存储在ETCD中。在ConfigMap创建成功后,就可以在Pod中使用ConfigMap了。

2.1 创建ConfigMap(4种方式)

2.1.1 指定ConfigMap的参数创建

创建

kubectl create cm demo-configmap1 \
> --from-literal=db.host=localhost \
> --from-literal=db.port=3306 \
> --from-literal=user=admin \
> --from-literal=password=123456

configmap/demo-configmap1 created

查看

[root@master activemq-cluster]# kubectl get cm

NAME DATA AGE

demo-configmap1 4 115s
[root@master activemq-cluster]# kubectl describe cm demo-configmap1

Name: demo-configmap1

Namespace: default

Labels: <none>

Annotations: <none>

Data

====

db.host:


localhost

db.port:


3306

password:


123456

user:


admin

BinaryData

====

Events: <none>

2.1.2 指定配置文件创建ConfigMap

[root@master ~]# tree configmap-demo/

configmap-demo/

├── mysql.properties

└── redis.properties

[root@master ~]# cat configmap-demo/redis.properties

redis.host=127.0.0.1

redis.port=6379

redis.password=123456

[root@master ~]# cat configmap-demo/mysql.properties

mysql.host=127.0.0.1

mysql.port=3306

mysql.password=123456

创建configmap

[root@master ~]# kubectl create cm demo-configmap2 --from-file=./configmap-demo /

configmap/demo-configmap2 created

查看

[root@master ~]# kubectl describe cm demo-configmap2

Name: demo-configmap2

Namespace: default

Labels: <none>

Annotations: <none>

Data

====

mysql.properties:


mysql.host=127.0.0.1

mysql.port=3306

mysql.password=123456

redis.properties:


redis.host=127.0.0.1

redis.port=6379

redis.password=123456

BinaryData

====

Events: <none>

2.1.3 通过一个文件内的多个键值对创建ConfigMap

[root@master configmap-demo3]# cat << EOF > env-config.txt

> db.host=localhost

> db.port=3306

> user=admin

> password=123456

> EOF

[root@master configmap-demo3]# kubectl create cm demo-configmap3 --from-env-file=env-config.txt

configmap/demo-configmap3 created

[root@master configmap-demo3]# kubectl describe cm demo-configmap3

Name: demo-configmap3

Namespace: default

Labels: <none>

Annotations: <none>

Data

====

user:


admin

db.host:


localhost

db.port:


3306

password:


123456

BinaryData

====

Events: <none>

2.1.4 yaml文件创建ConfigMap

这里展示了2种写法

[root@master configmap-demo4]# cat config.yaml

apiVersion: v1

kind: ConfigMap

metadata:

name: demo-configmap4

data:

db.host: localhost

db.port: "3306"

user: |

admin

password: |

"123456"

[root@master configmap-demo4]# kubectl apply -f config.yaml

configmap/demo-configmap4 created

查看

[root@master configmap-demo4]# kubectl describe cm demo-configmap4

Name: demo-configmap4

Namespace: default

Labels: <none>

Annotations: <none>

Data

====

db.host:


localhost

db.port:


3306

password:


"123456"

user:


admin

BinaryData

====

Events: <none>

2.2 使用ConfigMap(2种方式)

2.2.1 环境变量evn

[root@master configmap]# cat configmap-usage01.yaml

apiVersion: v1

kind: Pod

metadata:

name: configmap-usage01

spec:

containers:

  • name: busybox

image: busybox

imagePullPolicy: IfNotPresent

command: [ "/bin/sh", "-c", "echo $(HOST) $(PORT)" ]

env:

  • name: HOST

valueFrom:
configMapKeyRef:
name: demo-configmap4 # configmap的name
key: db.host # configmap中的key值

  • name: PORT
    valueFrom:
    configMapKeyRef:
    name: demo-configmap4
    key: db.port

restartPolicy: Never

[root@master configmap]# kubectl apply -f configmap-usage01.yaml

pod/configmap-usage01 created

查看日志 (host 和ip均读入容器内)

[root@master configmap]# kubectl logs -f configmap-usage01

localhost 3306

2.2.2 数据卷volume

[root@master configmap]# cat configmap-usage02.yaml

apiVersion: v1

kind: Pod

metadata:

name: configmap-usage02

spec:

containers:

  • name: busybox

image: busybox

imagePullPolicy: IfNotPresent

command: [ "/bin/sh", "-c", "cat /etc/config/redis.properties && sleep 200000" ]

volumeMounts:

  • name: config-volume
    mountPath:/etc/config

#不写subPath 挂在的时候会把/etc/config文件清空,下边配置会只挂在redis.properties文件到该目录下

#mountPath: /etc/config/redis.properties
#subPath: redis.properties

volumes:
- name: config-volume
configMap:
name: demo-configmap2

# items配置要挂在到卷的文件,不配置表示全部挂在

#items:

# - key: redis.properties # configMap对应的key

# path: redis.properties # 重新映射的文件名

restartPolicy: Never

Kubernetes中安装部署ActiveMQ集群(手把手式记录)-CSDN博客 可参照第三点的案例配置

2.3 ConfigMap的动态更新(数据卷volume方式才支持动态更新)

案例演示

bash 复制代码
[root@master share]# vim configmap-usage.yaml
i

apiVersion: v1
kind: Pod
metadata:
  name: configmap-usage
spec:
  containers:
  - name: busybox
    image: busybox
    command: ['sh', '-c', 'watch -n 2 "cat /etc/config/redis.properties"']
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap: 
        name: demo-configmap2

         
  restartPolicy: Never

查看日志输出,标识成功使用configMap

bash 复制代码
[root@master share]# kubectl get cm demo-configmap -o yaml > demo-configmap.yaml # 这里每次修改都要重新执行,基于版本修改
[root@master share]# vi demo-configmap.yaml

apiVersion: v1
data:
  mysql.properties: |
    mysql.host=127.0.0.1
    mysql.port=3306
    mysql.password=123456
  redis.properties: |
    redis.host=localhost  # 这里修改了
    redis.port=6379
    redis.password=123456
kind: ConfigMap
metadata:
  creationTimestamp: "2023-04-18T01:55:07Z"
  name: demo-configmap
  namespace: default
  resourceVersion: "2544156"
  uid: adfd480b-d926-4c77-bba2-73b291c6e0b3
~       

   #执行命令修改   
[root@master share]# kubectl apply -f demo-configmap.yaml 
# 查看修改成功
[root@master share]# kubectl describe cm demo-configmap
                                                                 

查看pod打印日志

bash 复制代码
[root@master share]# kubectl logs configmap-usage
# 前面文件设置每2秒钟查看一次,这里过几秒中后会查看到配置信息已经被修改,这也实现了动态配置功能
Every 2.0s: cat /etc/config/redis.properties                2023-04-18 04:02:27

redis.host=127.0.0.11
redis.port=6379
redis.password=123456

三、使用Secret管理Pod的配置信息

Secret也是Kubernetes配置管理管理的一种方式,它采用Base64编码机制保存配置信息。与ConfigMap不同的是,Secret中包含敏感的信息,例如用户的登录密码、Token等。这些敏感信息使用Secret来保存,可以更好的控制他们的用途,并降低意外暴露的风险。在成功创建Secret后,可以通过环境变量或数据卷的方式在Pod中使用它。

3.1 创建Secret

3.1.1 账号密码文件创建

[root@master secret]# echo dolphinchen > username.txt

[root@master secret]# echo password123 > password.txt

[root@master secret]# ls

password.txt username.txt

[root@master secret]# kubectl create secret generic demo-secret1 --from-file=username.txt --from-file=password.txt

secret/demo-secret1 created

[root@master secret]# kubectl get secret

NAME TYPE DATA AGE

default-token-bdv4x kubernetes.io/service-account-token 3 19d

demo-secret1 Opaque 2 6s

[root@master secret]# kubectl describe secret demo-secret1

Name: demo-secret1

Namespace: default

Labels: <none>

Annotations: <none>

Type: Opaque

Data

====

password.txt: 12 bytes

username.txt: 12 bytes

3.1.2 yaml文件创建

由于Secret是采用Base64编码机制来保存配置信息的,因此在创建yaml文件前,需要先得到配置信息的Base 64编码。

  • 得到账号"admin"和密码"hello123"的Base64编码。

[root@master secret]# echo 'admin' | base64

YWRtaW4K

[root@master secret]# echo 'hello123' | base64

aGVsbG8xMjMK

  • 创建demo-secret2.yaml文件

[root@master secret]# cat demo-secret2.yaml

apiVersion: v1

kind: Secret

metadata:

name: demo-secret2

type: Opaque

data:

username: YWRtaW4K

password: aGVsbG8xMjMK

  • 执行命令创建Secret

[root@master secret]# kubectl apply -f demo-secret2.yaml

secret/demo-secret2 created

[root@master secret]# kubectl get secret

NAME TYPE DATA AGE

default-token-bdv4x kubernetes.io/service-account-token 3 19d

demo-secret1 Opaque 2 7m56s

demo-secret2 Opaque

3.2 使用Secret

3.2.1 环境变量env使用

  • secret-usage01.yaml创建

[root@master secret]# cat secret-usage01.yaml

apiVersion: v1

kind: Pod

metadata:

name: secret-usage01

spec:

containers:

  • name: secret-usage01

image: nginx

imagePullPolicy: IfNotPresent

env:

  • name: USERNAME
    valueFrom:
    secretKeyRef:
    name: demo-secret2
    key: username

  • name: PASSWORD

valueFrom:

secretKeyRef:

name: demo-secret2

key: password

restartPolicy: Never

  • 创建Pod

[root@master secret]# kubectl apply -f secret-usage01.yaml

pod/secret-usage01 created

  • 进入容器查看变量信息

[root@master secret]# kubectl exec -it secret-usage01 /bin/bash

kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.

root@secret-usage01:/# echo $USERNAME
admin

root@secret-usage01:/# echo $PASSWORD
hello123

3.2.2 数据卷volume使用

  • 创建secret-usage02.yaml

[root@master secret]# cat secret-usage02.yaml

apiVersion: v1

kind: Pod

metadata:

name: secret-usage02

spec:

containers:

  • name: secret-usage02

image: redis

imagePullPolicy: IfNotPresent
**volumeMounts:

  • name: foo
    mountPath: /etc/foo
    readOnly: true
    volumes:
  • name: foo
    secret:
    secretName: demo-secret2**
  • 执行命令创建pod

[root@master secret]# kubectl apply -f secret-usage02.yaml

pod/secret-usage02 created

  • kubectl exec 命令进入容器查看

[root@master secret]# kubectl exec -it secret-usage02 bash

kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.

root@secret-usage02:/data# cd /etc/foo/

root@secret-usage02:/etc/foo# ls

password username

root@secret-usage02:/etc/foo# cat username
admin

root@secret-usage02:/etc/foo# cat password
hello123

四、secret类型之私有镜像仓库使用

创建Docker harbor的secret信息:

因为,k8s拉取镜像与Docker拉取镜像是不同方式,所以k8s需要创建一个属于自己的拉取镜像的方式。

k8s拉取公开项目可以直接拉取,拉取私有项目需要配置secret密码

docker-registry: 创建一个给Docker registry容器镜像仓库使用的secret

generic: 从本地file,directory或者literal value创建一个secret(这是大多数情况使用的),也就是资源清单中的type:Opaque是一个意思

tls: 创建一个TLS secret

4.1 响应式创建secret资源

[K8S@k8s-master ~]$ kubectl create secret docker-registry dolphin-harbor --docker-username=admin --docker-password=Harbor12345 --docker-email=123@admin.com --docker-server=core.harbor.eastcom.com:30710

secret/dolphin-harbor created

[K8S@k8s-master ~]$ kubectl get secret

NAME TYPE DATA AGE

default-token-l2nz8 kubernetes.io/service-account-token 3 422d

dolphin-harbor kubernetes.io/dockerconfigjson 1 13s

4.2 拉取harbor私有仓库测试

4.2.1 私有仓库镜像

4.2.2 创建pod测试文件(不配置secret docker-registry)

镜像拉取失败

[K8S@k8s-master ~]$ cat pod.yaml

apiVersion: v1

kind: Pod

metadata:

name: pod-secret-02

spec:

containers:

  • name: c1

image: core.harbor.eastcom.com:30710/nginx:latest

[K8S@k8s-master ~]$ kubectl apply -f pod.yaml

pod/pod-secret-02 created

[K8S@k8s-master ~]$ kubectl get pod

NAME READY STATUS RESTARTS AGE

mysql-0 1/1 Running 0 10d

nfs-client-provisioner-76b5dc7886-scf79 1/1 Running 7 (10d ago) 36d

nfs-devops-provisioner-866787c4d7-k52rq 1/1 Running 7 (10d ago) 35d

pod-secret-02 0/1 ErrImagePull 0 4s

ubuntu 1/1 Running 0 27h

4.2.3 imagePullSecret 指定secret docker-registry拉取镜像

[K8S@k8s-master ~]$ cat pod.yaml

apiVersion: v1

kind: Pod

metadata:

name: pod-secret-02

spec:
**imagePullSecrets:

  • name: dolphin-harbor**

containers:

  • name: c1

image: core.harbor.eastcom.com:30710/dolphintest/nginx:latest

镜像拉取成功

相关推荐
wusam1 小时前
螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习03(网络及IP规划)
运维·服务器·网络·docker·容器
一直在进步的派大星1 小时前
Docker 从安装到实战
java·运维·docker·微服务·容器
Zl1597531597535 小时前
k8s基础环境部署
云原生·容器·kubernetes
花酒锄作田5 小时前
[kubernetes]二进制方式部署单机k8s-v1.30.5
kubernetes
陌殇殇殇7 小时前
使用GitLab CI构建持续集成案例
运维·ci/cd·云原生·容器·kubernetes·gitlab
技术钱7 小时前
docker简介
运维·docker·容器
roman_日积跬步-终至千里7 小时前
【docker】docker常见命令
运维·docker·容器
Gogeof8 小时前
云原生化 - 基础镜像(简约版)
微服务·云原生·基础镜像
daxian_am4619 小时前
k8s image error
java·数据库·kubernetes
Gogeof10 小时前
云原生化 - 旅程(简约版)
微服务·云原生