k8s基础-配置管理

1.配置分离

1.1什么是ConfigMap

ConfigMap 是 Kubernetes 中用于存储非敏感配置数据的资源对象。它允许您将配置信息与应用程序代码分离,从而提高应用程序的可移植性和可维护性。

pAvU141.md.png

配置分离的核心理念是将应用程序的配置(如数据库连接字符串、API密钥、环境变量等)与应用程序代码分开管理。这意味着开发人员和运维人员可以独立于应用程序代码来修改和管理配置,从而实现更灵活的部署和管理。

在Kubernetes中,配置分离主要通过以下资源来实现:

  1. ConfigMap:用于存储非敏感的配置信息,如配置文件、环境变量等。
  2. Secret:用于存储敏感的配置信息,如密码、API密钥、证书等。

这种做法有几个主要优点:

  1. 提高灵活性:可以在不重建容器镜像的情况下更改配置。
  2. 增强安全性:敏感信息可以与代码分开存储和管理。
  3. 简化部署:同一个容器镜像可以在不同环境中使用不同的配置。

pAvUJgK.md.png

pAvU89x.md.png

1.2创建ConfigMap的方式

1
2
3
4
5
6
7
8
kubectl create configmap -h
kubectl create cm cmfromdir --from-file=conf/
kubectl create cm cmfromfile --from-file=conf/redis.conf
kubectl create cm cmspecialname --from-file=game-conf=game.conf
kubectl create cm cmspecialname2 --from-file=game-conf=game.conf --from-file=redis-conf=redis.conf
kubectl create cm gameenvcm --from-env-file=game.conf
kubectl create cm envfromliteral --from-literal=level=INFO --from-literal=PASSWORD=redis123
kubectl create -f cm.yaml
基于目录创建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
[root@k8s-master01 pra]# mkdir -p /root/pra/configmap/conf
[root@k8s-master01 pra]# cd /root/pra/configmap/conf

#演示文件内容随便定义
[root@k8s-master01 conf]# cat game.conf
lives=3
secret.code=true
[root@k8s-master01 conf]# cat game2.conf
color.good=blue
user=tomcat

#利用/root/pra/configmap/conf目录中的文件创建configmap(假设该目录中很多配置文件,基于目录创建configmap)
#create用于创建kubernetes资源
#configmap表示创建资源的类型
#cmfromdir创建的configmap名称
#--from-file=表示从文件创建 ConfigMap
#指定路径conf/,/表示是目录,而不是文件
[root@k8s-master01 configmap]# kubectl create configmap cmfromdir --from-file=conf/
configmap/cmfromdir created

#查看创建的configmap
#configmap可以缩写为cm
[root@k8s-master01 configmap]# kubectl get cm
NAME DATA AGE
cmfromdir 2 4m26s
kube-root-ca.crt 1 35d


#查看cm的具体信息
[root@k8s-master01 configmap]# kubectl get cm cmfromdir -o yaml
apiVersion: v1
data:
game.conf: |
lives=3
secret.code=true
game2.conf: |
color.good=blue
user=tomcat
kind: ConfigMap
metadata:
creationTimestamp: "2024-07-27T15:43:41Z"
name: cmfromdir
namespace: default
resourceVersion: "3297203"
uid: 704eadb3-6ea1-480a-802a-eeb141a6f951


基于单个文件创建config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@k8s-master01 configmap]# cat conf/redis.conf
bind 127.0.0.1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
pidfile /var/run/redis/redis.pid
loglevel notice
logfile /usr/local/redis/var/redis.log
databases 16

#通过单个文件创建configmap
[root@k8s-master01 configmap]# kubectl create cm cmfromfile --from-file=conf/redis.conf
configmap/cmfromfile created

#查看创建cm
[root@k8s-master01 ~]# kubectl get cm
NAME DATA AGE
cmfromdir 2 11h
cmfromfile 1 11h
kube-root-ca.crt 1 35d
自定义key名创建cm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#--from-file=redis-conf=/root/pra/configmap/conf/game.conf使用redis-conf自定义key名称
[root@k8s-master01 ~]# kubectl create cm cmspecialname --from-file=redis-conf=/root/pra/configmap/conf/game.conf
configmap/cmspecialname created

#redis-conf是自定义的名称而不是根据创建的文件名称命名
[root@k8s-master01 ~]# kubectl get cm cmspecialname -o yaml
apiVersion: v1
data:
redis-conf: |
lives=3
secret.code=true
kind: ConfigMap
metadata:
creationTimestamp: "2024-07-28T03:42:03Z"
name: cmspecialname
namespace: default
resourceVersion: "3311656"
uid: 9076adfa-58e4-4de9-8a19-7ebfa0397a28


#一次自定义多个
[root@k8s-master01 ~]# kubectl create cm cmspecialname2 --from-file=redis-conf=/root/pra/configmap/conf/game.conf --from-file=nginx-conf=/root/pra/configmap/conf/game2.conf
configmap/cmspecialname2 created

#nginx-conf和redis-conf是自定义的名称而不是根据创建的文件名称命名
[root@k8s-master01 ~]# kubectl get cm cmspecialname2 -oyaml
apiVersion: v1
data:
nginx-conf: |
color.good=blue
user=tomcat
redis-conf: |
lives=3
secret.code=true
kind: ConfigMap
metadata:
creationTimestamp: "2024-07-28T03:44:48Z"
name: cmspecialname2
namespace: default
resourceVersion: "3312103"
uid: 2fd983c5-3f10-4871-86c3-37de6e9b0464
基于env环境变量创建cm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@k8s-master01 conf]# kubectl create cm gameenvcm --from-env-file=game.conf
configmap/gameenvcm created
[root@k8s-master01 conf]# kubectl get cm gameenvcm -oyaml
apiVersion: v1
data:
lives: "3"
secret.code: "true"
kind: ConfigMap
metadata:
creationTimestamp: "2024-07-28T04:03:06Z"
name: gameenvcm
namespace: default
resourceVersion: "3315062"
uid: f3d0507d-aaa6-413b-b03c-bec9145269a5

基于命令行直接创建configmap的键值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#--from-literal: 这个参数允许你直接在命令行中指定 ConfigMap 的键值对。
[root@k8s-master01 conf]# kubectl create cm fromenvliteral --from-literal=level=3 --from-literal=PASSWD=redis123456
configmap/fromenvliteral created
[root@k8s-master01 conf]# kubectl get cm fromenvliteral -oyaml
apiVersion: v1
data:
PASSWD: redis123456
level: "3"
kind: ConfigMap
metadata:
creationTimestamp: "2024-07-28T04:12:13Z"
name: fromenvliteral
namespace: default
resourceVersion: "3316540"
uid: 68709d37-9c2e-4f41-83d9-783bbb240b31

1.3使用ConfigMap

1.3.1使用valueFrom定义环境变量(适用少数环境变量场景)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#利用命令快速创建一个deployment,用这个deploy引用configmap
[root@k8s-master01 conf]# kubectl create deployment dp-cm --image=registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine --dry-run=client -oyaml >dp-cm.yaml

#这是创建的configmap
[root@k8s-master01 configmap]# kubectl get cm gameenvcm -oyaml
apiVersion: v1
data:
lives: "3"
secret.code: "true"
kind: ConfigMap
metadata:
creationTimestamp: "2024-07-28T04:03:06Z"
name: gameenvcm
namespace: default
resourceVersion: "3315062"
uid: f3d0507d-aaa6-413b-b03c-bec9145269a5

在pod中使用configmap中定义环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#使用valueFrom引用configmap中的环境变量
[root@k8s-master01 configmap]# cat dp-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: dp-cm
name: dp-cm
spec:
replicas: 1
selector:
matchLabels:
app: dp-cm
template:
metadata:
labels:
app: dp-cm
spec:
containers:
- image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine
name: nginx
env:
- name: TEST_ENV
value: testenv
- name: LIVES
valueFrom:
configMapKeyRef:
name: gameenvcm
key: lives
----------------------------
env中字段解释:
- name: LIVES
valueFrom:
configMapKeyRef:
name: gameenvcm
key: lives

name: LIVES: 这定义了环境变量的名称。在容器内,可以通过 $LIVES 访问这个变量。
valueFrom: 这表示值将从外部源获取,而不是直接设置。
configMapKeyRef: 这指定值将从 ConfigMap 中获取。

name: gameenvcm: 这是 ConfigMap 的名称。
key: lives: 这是要从 ConfigMap 中获取的特定键。在容器中查看LIVES的值就是configmap中lives的值,这种配置方式用于从 ConfigMap 动态获取值。根据之前显示的 ConfigMap 内容,这个环境变量 LIVES 的值将被设置为 "3"。

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


#创建这个deployment
[root@k8s-master01 configmap]# kubectl create -f dp-cm.yaml

#pod成功运行
[root@k8s-master01 configmap]# kubectl get po
NAME READY STATUS RESTARTS AGE
dp-cm-6d9d86cb4f-8jqj2 1/1 Running 0 14m

#进入pod查看配置的环境变量
[root@k8s-master01 configmap]# kubectl exec -it dp-cm-6d9d86cb4f-8jqj2 -- sh
/ # / # echo $TEST_ENV
testenv
/ # echo $LIVES
3

#不进入容器查看环境变量
[root@k8s-master01 configmap]# kubectl exec dp-cm-6d9d86cb4f-8jqj2 -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=dp-cm-6d9d86cb4f-8jqj2
NGINX_VERSION=1.27.0
PKG_RELEASE=2
NJS_VERSION=0.8.4
NJS_RELEASE=2
TEST_ENV=testenv
LIVES=3
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
SERVICE_EXTERNAL_IP_SERVICE_PORT=80
SERVICE_EXTERNAL_IP_SERVICE_PORT_HTTP=80
SERVICE_EXTERNAL_IP_PORT_80_TCP=tcp://10.96.20.32:80
SERVICE_EXTERNAL_IP_PORT_80_TCP_PROTO=tcp
SERVICE_EXTERNAL_IP_PORT_80_TCP_ADDR=10.96.20.32
KUBERNETES_SERVICE_PORT=443
SERVICE_FOR_NGINX_DEPLOYMENT_SERVICE_PORT=80
SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP_PORT=80
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
SERVICE_FOR_NGINX_DEPLOYMENT_PORT=tcp://10.96.227.196:80
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PORT=443
SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP=tcp://10.96.227.196:80
SERVICE_EXTERNAL_IP_SERVICE_HOST=10.96.20.32
SERVICE_EXTERNAL_IP_PORT=tcp://10.96.20.32:80
SERVICE_EXTERNAL_IP_PORT_80_TCP_PORT=80
SERVICE_FOR_NGINX_DEPLOYMENT_SERVICE_HOST=10.96.227.196
SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP_PROTO=tcp
SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP_ADDR=10.96.227.196
HOME=/root

1.3.2使用envFrom定义环境变量(适用多数环境变量的场景)

configmap内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@k8s-master01 configmap]# kubectl get cm gameenvcm -oyaml
apiVersion: v1
data:
game.conf: |+
lives=3
secret.code=true
color=red
user=root
password=1234

lives: "3"
secret.code: "true"
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"game.conf":"lives=3\nsecret.code=true\ncolor=red\nuser=root\npassword=1234\n\n"},"kind":"ConfigMap","metadata":{"annotations":{},"creationTimestamp":null,"name":"gameenvcm","namespace":"default"}}
creationTimestamp: "2024-07-28T04:03:06Z"
name: gameenvcm
namespace: default
resourceVersion: "3339558"
uid: f3d0507d-aaa6-413b-b03c-bec9145269a5

配置envFrom的引用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#在pod中containers.envFrom引用configmap
[root@k8s-master01 configmap]# cat dp-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: dp-cm
name: dp-cm
spec:
replicas: 1
selector:
matchLabels:
app: dp-cm
template:
metadata:
labels:
app: dp-cm
spec:
containers:
- image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine
name: nginx
envFrom: #envFrom: 该字段用于指定容器的环境变量来源。它可以从 ConfigMap、Secret 或其他来源中获取环境变量。
- configMapRef: #该字段用于指定 ConfigMap 的引用。它是一个对象,包含了 ConfigMap 的名称和其他信息。
name: gameenvcm #该字段用于指定 ConfigMap 的名称。在本例中,ConfigMap 的名称是 gameenvcm。
env:
- name: TEST_ENV
value: testenv
- name: LIVES
valueFrom:
configMapKeyRef:
name: gameenvcm
key: lives

更新deploy,并查看它管理的pod中的环境变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
[root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml
[root@k8s-master01 configmap]# kubectl exec dp-cm-7b5f78b75c-lkpvz -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=dp-cm-7b5f78b75c-lkpvz
NGINX_VERSION=1.27.0
PKG_RELEASE=2
NJS_VERSION=0.8.4
NJS_RELEASE=2
secret.code=true
TEST_ENV=testenv
LIVES=3
game.conf=lives=3
secret.code=true
color=red
user=root
password=1234


lives=3
KUBERNETES_SERVICE_HOST=10.96.0.1
SERVICE_EXTERNAL_IP_SERVICE_HOST=10.96.20.32
SERVICE_EXTERNAL_IP_SERVICE_PORT_HTTP=80
SERVICE_EXTERNAL_IP_PORT=tcp://10.96.20.32:80
SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP_ADDR=10.96.227.196
SERVICE_FOR_NGINX_DEPLOYMENT_PORT=tcp://10.96.227.196:80
SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP_PORT=80
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
SERVICE_EXTERNAL_IP_SERVICE_PORT=80
SERVICE_EXTERNAL_IP_PORT_80_TCP_PORT=80
SERVICE_FOR_NGINX_DEPLOYMENT_SERVICE_PORT=80
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
SERVICE_EXTERNAL_IP_PORT_80_TCP_PROTO=tcp
SERVICE_FOR_NGINX_DEPLOYMENT_SERVICE_HOST=10.96.227.196
KUBERNETES_SERVICE_PORT_HTTPS=443
SERVICE_EXTERNAL_IP_PORT_80_TCP=tcp://10.96.20.32:80
SERVICE_EXTERNAL_IP_PORT_80_TCP_ADDR=10.96.20.32
SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP=tcp://10.96.227.196:80
SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP_PROTO=tcp
HOME=/root

1.3.3以文件的形式挂载ConfigMap

案例:以redis.conf创建configmap,并挂载到容器中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#redis的配置文件如下:(仅供演示)
[root@k8s-master01 configmap]# cat conf/redis.conf
bind 127.0.0.1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
pidfile /var/run/redis/redis.pid
loglevel notice
logfile /usr/local/redis/var/redis.log
databases 16

#基于redis.conf创建一个名字是reids-conf的configmap
[root@k8s-master01 configmap]# kubectl create cm redis-conf --from-file=conf/redis.conf
configmap/redis-conf created


#在容器中引用这个configmap
[root@k8s-master01 configmap]# cat dp-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: dp-cm
name: dp-cm
spec:
replicas: 1
selector:
matchLabels:
app: dp-cm
template:
metadata:
labels:
app: dp-cm
spec:
containers:
- image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine
name: nginx
volumeMounts:
- name: redisconf
mountPath: /etc/config
volumes:
- name: redisconf
configMap:
name: redis-conf


#更新这个deploy
[root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml
deployment.apps/dp-cm replaced

验证是否将redis.conf文件挂载到容器中了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#查看创建的pod
[root@k8s-master01 configmap]# kubectl get po
NAME READY STATUS RESTARTS AGE
dp-cm-df468cf55-mfbfd 1/1 Running 0 10m

#进入pod(dp-cm-df468cf55-mfbfd)中
[root@k8s-master01 configmap]# kubectl exec -ti dp-cm-df468cf55-mfbfd -- sh
/ #
/ # ls -l /etc/config/ # redis.conf文件已经存在
total 0
lrwxrwxrwx 1 root root 17 Jul 28 07:27 redis.conf -> ..data/redis.conf

/etc/config # cat redis.conf
bind 127.0.0.1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
pidfile /var/run/redis/redis.pid
loglevel notice
logfile /usr/local/redis/var/redis.log
databases 16

更新configmap的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#直接使用edit编辑configmap,程序需要有热加载功能,才会同步到容器内,程序如果没有热加载就需要重启

#我们使用redis-conf configmap演示
[root@k8s-master01 configmap]# kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 35d
redis-conf 1 48m

#使用edit编辑名字是redis-conf的cm,将port 6379改为port 6380
[root@k8s-master01 configmap]# kubectl edit cm redis-conf
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
redis.conf: |
bind 127.0.0.1
protected-mode yes
port 6380
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
pidfile /var/run/redis/redis.pid
loglevel notice
logfile /usr/local/redis/var/redis.log
databases 16
kind: ConfigMap
metadata:
creationTimestamp: "2024-07-28T06:55:59Z"
name: redis-conf
namespace: default
resourceVersion: "3343543"
uid: ff3cd3a9-c6e6-4150-91be-dc523b01a099


#修改后保存退出,不重启pod的情况下,查看pod中挂载的redis.conf的内容, 是否有port 6380的参数
#进入pod中
[root@k8s-master01 configmap]# kubectl exec -ti dp-cm-df468cf55-mfbfd -- sh
/ # cat /etc/config/
..2024_07_28_07_45_52.1762584904/ ..data/ redis.conf
/ # cat /etc/config/redis.conf
bind 127.0.0.1
protected-mode yes
port 6380 #可以看到此时已经改为6380
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
pidfile /var/run/redis/redis.pid
loglevel notice
logfile /usr/local/redis/var/redis.log
databases 16

挂载多个configmap配置案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: dp-cm
name: dp-cm
spec:
replicas: 1
selector:
matchLabels:
app: dp-cm
template:
metadata:
labels:
app: dp-cm
spec:
containers:
- image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine
name: nginx
volumeMounts:# 该参数指定了容器中的卷挂载点。它是一个列表,包含了多个卷挂载点的配置。
- name: redisconf # 该参数指定了卷的名称,要和下面volumes.name一致。在本例中,卷的名称是 redisconf。
mountPath: /etc/config #该参数指定了卷挂载点的路径
- name: nginxconf # 必须与 volumes 中的 name 匹配
mountPath: /etc/config2
volumes: #该参数指定了容器中的卷。它是一个列表,包含了多个卷的配置。
- name: redisconf #该参数定义了卷的名称。在本例中,卷的名称是 redisconf。
configMap: # 该参数指定卷的类型为 ConfigMap
name: redis-conf #该参数指定了 ConfigMap 的名称。在本例中,ConfigMap 的名称是 redis-conf。
- name: nginxconf #必须与 volumeMounts 中的 name 匹配
configMap:
name: nginx-conf

1.3.4自定义挂载名称和权限

  1. 自定义挂载名称
    1. 通过 items:参数可以自定义挂载的文件名称

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      #deployment配置文件内容如下:
      [root@k8s-master01 configmap]# cat dp-cm.yaml
      apiVersion: apps/v1
      kind: Deployment
      metadata:
      labels:
      app: dp-cm
      name: dp-cm
      spec:
      replicas: 1
      selector:
      matchLabels:
      app: dp-cm
      template:
      metadata:
      labels:
      app: dp-cm
      spec:
      containers:
      - image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine
      name: nginx
      volumeMounts:
      - name: redisconf
      mountPath: /etc/config
      volumes:
      - name: redisconf
      configMap:
      name: redis-conf
      items: #定义要从 ConfigMap 中挂载的特定键值对
      - key: redis.conf #指定configmap中的键,这里是redis.conf
      path: zidingyi.conf #指定容器中的路径。将键redis.conf内容挂载到/etc/config/zidingyi.conf路径


      #创建这个deployment
      [root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml
      deployment.apps/dp-cm replaced

      #验证挂载的文件是不是自定义的zidingyi.conf名称
      [root@k8s-master01 configmap]# kubectl exec dp-cm-6b84964f55-vp6kv -- ls -l /etc/config
      total 0
      lrwxrwxrwx 1 root root 20 Jul 28 10:29 zidingyi.conf -> ..data/zidingyi.conf
  2. 自定义挂载权限

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    [root@k8s-master01 configmap]# cat dp-cm.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    labels:
    app: dp-cm
    name: dp-cm
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: dp-cm
    template:
    metadata:
    labels:
    app: dp-cm
    spec:
    containers:
    - image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine
    name: nginx
    volumeMounts:
    - name: redisconf
    mountPath: /etc/config
    volumes:
    - name: redisconf
    configMap:
    name: redis-conf
    items:
    - key: redis.conf #选择 ConfigMap 中的 redis.conf作为键。
    path: zidingyi.conf
    - key: redis.conf
    path: test.conf
    mode: 0400 #定义挂载文件的权限,优先级高于defaultMode
    defaultMode: 0755 #定义挂载文件的默认权限,如果单个key中没有配置mode,那么该值生效

    #更新这个deployment,进入pod中查看文件的权限
    [root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml
    deployment.apps/dp-cm replaced
    [root@k8s-master01 configmap]# kubectl exec -ti dp-cm-5d4b745d47-4d9t9 -- sh
    / # ls -l /etc/config/..data/
    total 8
    -r-------- 1 root root 203 Jul 28 11:59 test.conf #文件权限400
    -rwxr-xr-x 1 root root 203 Jul 28 11:59 zidingyi.conf #文件权限755


1.4Secret

在 Kubernetes 中,Secret 是一种资源对象,用于存储和管理敏感信息,如密码、令牌和密钥等。使用 Secret 可以避免将敏感数据硬编码到应用程序的代码或配置文件中,提高安全性和管理的便捷性。而 ConfigMap 用于存储应用程序的配置数据。

1.4.1Secret常用的几种类型(加粗代表常用的类型)

◆ Opaque:通用型Secret,默认类型;使用最多的类型

◆ kubernetes.io/service-account-token:作用于ServiceAccount,包含一个令牌,用于标识API服务账户;

◆ kubernetes.io/dockerconfigjson:下载私有仓库镜像使用的Secret,和宿主机的/root/.docker/config.json一致,宿主机登录后即可产生该文件;

◆ kubernetes.io/basic-auth:用于使用基本认证(账号密码)的Secret,可以使用Opaque取代;

◆ kubernetes.io/ssh-auth:用于存储ssh密钥的Secret;

◆ kubernetes.io/tls:用于存储HTTPS域名证书文件的Secret,可以被Ingress使用;

◆ bootstrap.kubernetes.io/token:一种简单的 bearer token,用于创建新集群或将新节点添加到现有集群,在集群安装时可用于自动颁发集群的证书。

参考连接:https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/

1.4.2创建Secret

参考链接:https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/#creating-a-secret

1.4.2.1使用命令创建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#准备两个演示文件,用来存储账号和密码
[root@k8s-master01 secret]# cd /root/pra/secret
[root@k8s-master01 secret]# echo -n 'admin' > ./username.txt
[root@k8s-master01 secret]# echo -n 'S!B\*d$zDsb=' > ./password.txt

#使用命令创建secret
[root@k8s-master01 secret]# kubectl create secret generic db-user-pass --from-file=username.txt --from-file=password.txt
secret/db-user-pass created

#查看创建的secret
[root@k8s-master01 secret]# kubectl get secrets
NAME TYPE DATA AGE
db-user-pass Opaque 2 18s

#以yaml格式输出 db-user-pass这个secret
[root@k8s-master01 secret]# kubectl get secrets db-user-pass -o yaml
apiVersion: v1
data:
password.txt: UyFCXCpkJHpEc2I9 #这里不是明文,进行软加密
username.txt: YWRtaW4= #这里不是明文,进行软加密
kind: Secret
metadata:
creationTimestamp: "2024-07-28T12:56:01Z"
name: db-user-pass
namespace: default
resourceVersion: "3401907"
uid: dcf18ce5-0cc6-4b56-be98-6844e688869a
type: Opaque
1.4.2.2使用–from-literal创建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#命令行中直接使用--from-literal创建
[root@k8s-master01 secret]# kubectl create secret generic dev-db-user-pass --from-literal=username=devuser --from-literal=passwd='123456' #这里不能使用双引号
secret/dev-db-user-pass created

#查看创建的secret
[root@k8s-master01 secret]# kubectl get secrets
NAME TYPE DATA AGE
db-user-pass Opaque 2 10m
dev-db-user-pass Opaque 2 43s

#以yaml格式输出dev-db-user-pass这个secret
[root@k8s-master01 secret]# kubectl get secrets dev-db-user-pass -oyaml
apiVersion: v1
data:
passwd: MTIzNDU2
username: ZGV2dXNlcg==
kind: Secret
metadata:
creationTimestamp: "2024-07-28T13:05:32Z"
name: dev-db-user-pass
namespace: default
resourceVersion: "3403451"
uid: 2025ec26-9e7b-4682-9544-e0f5fefda193
type: Opaque

1.4.2.3基于yaml文件创建secret
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#将dmin和1f2d1e2e67df进行base64编码转换
[root@k8s-master01 secret]# echo -n 'admin' | base64
YWRtaW4=
[root@k8s-master01 secret]# echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm

#创建secret的yaml文件
[root@k8s-master01 secret]# cat secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm

#利用yaml文件创建secret
[root@k8s-master01 secret]# kubectl create -f secret.yaml
secret/mysecret created

#查看刚才创建的secret
[root@k8s-master01 secret]# kubectl get secrets
NAME TYPE DATA AGE
db-user-pass Opaque 2 23m
dev-db-user-pass Opaque 2 13m
mysecret Opaque 2 24s


#以yaml格式输出mysecret
[root@k8s-master01 secret]# kubectl get secrets mysecret -oyaml
apiVersion: v1
data:
password: MWYyZDFlMmU2N2Rm
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2024-07-28T13:18:53Z"
name: mysecret
namespace: default
resourceVersion: "3405611"
uid: 3cebc767-eb57-42c5-b032-98d62e1d38d4
type: Opaque

#可以看到YWRtaW4=解码后的值是admin,和上面的步骤对应
[root@k8s-master01 secret]# echo -n 'YWRtaW4='|base64 -d
admin

上述操作是在创建secret前先对数据进行base64编码,也可以不用编码,下面是不事先对数据编码的yaml格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#不事先对数据编码需要配置stringData:参数
[root@k8s-master01 secret]# cat secret-stringdata.yaml
apiVersion: v1
kind: Secret
metadata:
name: my-springdata-secret
type: Opaque
stringData:
username: admin
password: asdqwe123@


#创建secret
[root@k8s-master01 secret]# kubectl create -f secret-stringdata.yaml
secret/my-springdata-secret created

#查看创建的secret
[root@k8s-master01 secret]# kubectl get secrets
NAME TYPE DATA AGE
db-user-pass Opaque 2 34m
dev-db-user-pass Opaque 2 24m
my-springdata-secret Opaque 2 19s
mysecret Opaque 2 11m


#可以看到创建的secret中的数据也被编码过了
[root@k8s-master01 secret]# kubectl get secrets my-springdata-secret -oyaml
apiVersion: v1
data:
password: YXNkcXdlMTIzQA==
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2024-07-28T13:29:49Z"
name: my-springdata-secret
namespace: default
resourceVersion: "3407379"
uid: 6b5baaf9-1bc6-4b56-b26a-24e483fd764a
type: Opaque

1.4.3使用secret拉取私有仓库镜像

使用阿里云私有仓库作为演示仓库

pAvUYjO.md.png
从私有仓库拉取镜像需要账号密码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[root@k8s-master01 secret]# docker pull registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx
Using default tag: latest
Error response from daemon: pull access denied for registry.cn-beijing.aliyuncs.com/java-demo-test/nginx, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

#登录镜像仓库
[root@k8s-master01 secret]# docker login --username=794940840@qq.com registry.cn-beijing.aliyuncs.com
Password: #这里输入的密码是wawxy1314@
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded #提示登录成功

#拉取镜像成功
[root@k8s-master01 secret]# docker pull registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.24.0
1.24.0: Pulling from k8s-liujunwei/nginx
04e7578caeaa: Pull complete
57a1056ea484: Pull complete
6989106bacf0: Pull complete
c00d1142b331: Pull complete
cb49393af980: Pull complete
5ac1ebd8aebe: Pull complete
Digest: sha256:47e27097c9c6a7ee3b07d44888a6c441af465cfb79bb6b9d205a1294093bb9d0
Status: Downloaded newer image for registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.24.0
registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.24.0

#可以看到镜像已经存在
[root@k8s-master01 secret]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx-lotsys v1 582eff85ec45 9 days ago 293MB
registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx 1.24.0 6c0218f16876 15 months ago 142MB

在k8s中演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#编辑deploy的yaml文件,将镜像的拉取策略改为Always(总是从仓库拉取)
[root@k8s-master01 configmap]# cat dp-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: dp-cm
name: dp-cm
spec:
replicas: 1
selector:
matchLabels:
app: dp-cm
template:
metadata:
labels:
app: dp-cm
spec:
containers:
- image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine
name: nginx
imagePullPolicy: Always
volumeMounts:
- name: redisconf
mountPath: /etc/config
# - name: redisconf
# mountPath: /etc/config2
volumes:
- name: redisconf
configMap:
name: redis-conf
items:
- key: redis.conf
path: zidingyi.conf
- key: redis.conf
path: test.conf
mode: 0400
defaultMode: 0755
#创建这个deployment
[root@k8s-master01 configmap]# kubectl delete -f dp-cm.yaml
deployment.apps "dp-cm" deleted

#查看pod的创建情况
[root@k8s-master01 configmap]# kubectl get pod
NAME READY STATUS RESTARTS AGE
dp-cm-58d5d8d9-tnw54 0/1 ImagePullBackOff 0 2m48s

#使用describe查看具体报错信息
[root@k8s-master01 configmap]# kubectl describe po dp-cm-58d5d8d9-tnw54
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3m10s default-scheduler Successfully assigned default/dp-cm-58d5d8d9-tnw54 to k8s-node01
Normal Pulling 113s (x4 over 3m10s) kubelet Pulling image "registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine"
Warning Failed 113s (x4 over 3m10s) kubelet Failed to pull image "registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine": failed to pull and unpack image "registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine": failed to resolve reference "registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine": pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
Warning Failed 113s (x4 over 3m10s) kubelet Error: ErrImagePull
Warning Failed 84s (x6 over 3m9s) kubelet Error: ImagePullBackOff
Normal BackOff 72s (x7 over 3m9s) kubelet Back-off pulling image "registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine"

#从错误信息提示中可以看出访问被拒绝,没有授权
#接下来演示创建一个docker-registry类型的secret用来存储镜像仓库的地址,用户名以及密码,用来拉取私有仓库的镜像
[root@k8s-master01 configmap]# kubectl create secret docker-registry my-aliyun-registry --docker-username=794940840@qq.com --docker-password=wawxy1314@ --docker-email=794940840@qq.com --docker-server=registry.cn-beijing.aliyuncs.com
secret/my-aliyun-registry created

#以下是对这条命令中每个参数的解释
----------------------------
kubectl: 是 Kubernetes 的命令行工具。
create: 是用于创建资源的命令。
secret: 是用于创建 Secret 资源的命令。
docker-registry: 是 Secret 资源的类型,用于存储 Docker Registry 的认证信息。
my-aliyun-registry: 是 Secret 资源的名称。
--docker-username: 是用于指定 Docker Registry 的用户名的参数,794940840@qq.com: 是 Docker Registry 的用户名。
--docker-password: 是用于指定 Docker Registry 的密码的参数,wawxy1314@: 是 Docker Registry 的密码。
--docker-email: 是用于指定 Docker Registry 的电子邮件地址的参数。794940840@qq.com: 是 Docker Registry 的电子邮件地址。邮箱信息可以为空
--docker-server: 是用于指定 Docker Registry 的服务器地址的参数。registry.cn-beijing.aliyuncs.com: 是 Docker Registry 的服务器地址。
总的来说,这条命令用于创建一个名为 my-aliyun-registry 的 Secret 资源,用于存储 Docker Registry 的认证信息,包括用户名、密码、电子邮件地址和服务器地址。

这个 Secret 资源可以被用于在 Kubernetes 中访问 Docker Registry,例如拉取镜像或推送镜像。
----------------------------

#查看创建的这个secret
#可以看到名称my-aliyun-registry 的secret的格式是kubernetes.io/dockerconfigjson格式
[root@k8s-master01 configmap]# kubectl get secrets
NAME TYPE DATA AGE
db-user-pass Opaque 2 93m
dev-db-user-pass Opaque 2 84m
my-aliyun-registry kubernetes.io/dockerconfigjson 1 2m36s
mysecret Opaque 2 70m


#如果命令忘记了可以是explain查看帮助
[root@k8s-master01 configmap]# kubectl explain po.spec.imagePullSecrets
#在pod中使用这个secret
[root@k8s-master01 configmap]# cat dp-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: dp-cm
name: dp-cm
spec:
replicas: 1
selector:
matchLabels:
app: dp-cm
template:
metadata:
labels:
app: dp-cm
spec:
imagePullSecrets: #用于指定 Docker Registry 的认证信息。它是一个列表,可以包含了多个 Secret 资源的名称。
- name: my-aliyun-registry #指定名字是my-aliyun-registry的secret
- name: my-dockerhub-registry
containers:
- image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine
name: nginx
imagePullPolicy: Always
volumeMounts:
- name: redisconf
mountPath: /etc/config
# - name: redisconf
# mountPath: /etc/config2
volumes:
- name: redisconf
configMap:
name: redis-conf
items:
- key: redis.conf
path: zidingyi.conf
- key: redis.conf
path: test.conf
mode: 0400
defaultMode: 0755


总结:在 Kubernetes 中,一个 Pod 可以包含多个容器,而每个容器可能需要从不同的 Docker Registry 中拉取镜像。如果我们将 imagePullSecrets 配置在 spec.containers 区域,那么我们需要为每个容器指定一个单独的 Secret 资源,这样会很麻烦。

更新以下之前没有拉取成功的deployment

1
2
3
4
5
6
7
[root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml
deployment.apps/dp-cm replaced

#查看pod的状态,已经成功运行
[root@k8s-master01 configmap]# kubectl get po
NAME READY STATUS RESTARTS AGE
dp-cm-bfcf596d8-85psj 1/1 Running 0 31s

1.4.4secret管理https证书

首先使用命令生产证书,生产环境应该是买的正式证书,这里使用命令生成的证书只用于测试环境:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
openssl req -x509 -nodes -days 365 \
-newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=test.com"

#该命令会生成tls.crt和tls.key两个文件
[root@k8s-master01 configmap]# openssl req -x509 -nodes -days 365 \
> -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=test.com"
Generating a 2048 bit RSA private key
..+++
.......+++
writing new private key to 'tls.key'
-----
[root@k8s-master01 configmap]# ll
total 12
drwxr-xr-x 2 root root 59 Jul 28 14:25 conf
-rw-r--r-- 1 root root 896 Jul 28 22:37 dp-cm.yaml
-rw-r--r-- 1 root root 1090 Jul 28 22:51 tls.crt
-rw-r--r-- 1 root root 1704 Jul 28 22:51 tls.key

#利用证书的tls.crt和tls.key的两个文件生成secret
[root@k8s-master01 configmap]# kubectl create secret tls nginx-test-tls --cert=tls.crt --key=tls.key
secret/nginx-test-tls created

#这条命令是用于创建一个 TLS 证书的 Secret 资源。
以下是命令的解释:
* `kubectl`: 是 Kubernetes 的命令行工具。
* `create`: 是用于创建资源的命令。
* `secret`: 是用于创建 Secret 资源的命令。
* `tls`: 是 Secret 资源的类型,用于存储 TLS 证书。
* `nginx-test-tls`: 是 Secret 资源的名称。
* `--cert`: 是用于指定 TLS 证书文件的参数。
* `tls.crt`: 是 TLS 证书文件的名称。
* `--key`: 是用于指定 TLS 私钥文件的参数。
* `tls.key`: 是 TLS 私钥文件的名称。

总的来说,这条命令用于创建一个名为 `nginx-test-tls` 的 Secret 资源,用于存储 TLS 证书和私钥。
这个 Secret 资源可以被用于在 Kubernetes 中配置 TLS 加密的服务,例如 HTTPS 服务。
注意:TLS 证书和私钥文件需要是 PEM 格式的。
在这个例子中,我们指定了一个名为 `tls.crt` 的证书文件和一个名为 `tls.key` 的私钥文件,这些文件将被用于创建 Secret 资源。

#查看创建的secret
[root@k8s-master01 configmap]# kubectl get secrets
NAME TYPE DATA AGE
nginx-test-tls kubernetes.io/tls 2 2m5s

[root@k8s-master01 configmap]# kubectl get secrets nginx-test-tls -oyaml
apiVersion: v1
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMrVENDQWVHZ0F3SUJBZ0lKQU9UWGJocTZvMlJvTUEwR0NTcUdTSWIzRFFFQkN3VUFNQk14RVRBUEJnTlYKQkFNTUNIUmxjM1F1WTI5dE1CNFhEVEkwTURjeU9ERTBOVEUwTWxvWERUSTFNRGN5T0RFME5URTBNbG93RXpFUgpNQThHQTFVRUF3d0lkR1Z6ZEM1amIyMHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCCkFRQ2d5MmNOVFFlK0NuS2d5eFEwbkhKallOZkZTUUtGSHZyZFZaZTBwZXRURXVvSEM1WDJ6NWdTQ3huYWJHRjQKSmVjMG13ZForejZtSXlYRWVMTlVsVGRqWERTay8xOVBkYnNFVkJlSVYzMjBuZ3prMTdIUEVvbmZNcWRBZ09seApabCtVSkZYTWVadklkWCthNzNxVVBEUWlRVERSaXNHN04vSlpVRG0rOVlHN3QxOWluaXdKaHBmQmZZeTM3cVovCmZlSU9WTTVSSk00WkFOTHE0ZE9OYjg5Uk41M3RzZWVaTlUrRi9LQnp3N1dhbml2QnZFdldsWkpBdFZhejB3WEcKRWFNd0lCODNVN3BCaXdPSnlOTWdFK2I1MGpBNzFvWFdkRlNIcVhwODJBcDhUeVBHT2Nna0VyZC9VdzUvQjN5awpqNlNYSHdrY0VHR0ZxUTc1QVV0S01rUHZBZ01CQUFHalVEQk9NQjBHQTFVZERnUVdCQlRuNmNQcThrTGpFTW8yCnJPNmErUXdXRGd2NVJ6QWZCZ05WSFNNRUdEQVdnQlRuNmNQcThrTGpFTW8yck82YStRd1dEZ3Y1UnpBTUJnTlYKSFJNRUJUQURBUUgvTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFCUkRKdkVFYXBZT0JOd1NBdUFOTU1OWmtmVwpoYjJrN2ZqcVhXbWhEai9ZdFp1VEhkcUhLZFJDRm9PbDB2SEpIcVEvS0pQaVRwZXJDV3V2U1Z0Z1REUS80ZVovCkJ2dEZnV2p3NTdzcExQR2xMdGNYM2lQVTEwdjhsbVQ2WWppeU1CVGFwd2ZrditDVUJ0WlpIdThvWlM2ZkJhemkKc3JEVWcva3BTa2ZqejBVSXFOT0VXNmV1TTlydUxXZU1OWnRTV2hyQW5UYTh2b2lPNnpSY0Eza1pVUVlhOGpzQgovSm1Lc3FNRm1KTFlveUFidmVOOUtvM1hxbEpYMFNBVVZlZjFqVG9CcG42STNzeUN6TDVzZXhMTEQvcFNHdTlkCkJmTUovNHlCZlJRZlB3ODRmVGp5bmgrY3ErYnl1OGZ4MFdkWkpkMktxMG1WTU9kU3NwN2cwMkVKcmpZRQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2d5MmNOVFFlK0NuS2cKeXhRMG5ISmpZTmZGU1FLRkh2cmRWWmUwcGV0VEV1b0hDNVgyejVnU0N4bmFiR0Y0SmVjMG13ZForejZtSXlYRQplTE5VbFRkalhEU2svMTlQZGJzRVZCZUlWMzIwbmd6azE3SFBFb25mTXFkQWdPbHhabCtVSkZYTWVadklkWCthCjczcVVQRFFpUVREUmlzRzdOL0paVURtKzlZRzd0MTlpbml3SmhwZkJmWXkzN3FaL2ZlSU9WTTVSSk00WkFOTHEKNGRPTmI4OVJONTN0c2VlWk5VK0YvS0J6dzdXYW5pdkJ2RXZXbFpKQXRWYXowd1hHRWFNd0lCODNVN3BCaXdPSgp5Tk1nRStiNTBqQTcxb1hXZEZTSHFYcDgyQXA4VHlQR09jZ2tFcmQvVXc1L0IzeWtqNlNYSHdrY0VHR0ZxUTc1CkFVdEtNa1B2QWdNQkFBRUNnZ0VBTzRxV1ltcC96M04yOXV1OFU2OEsvSm5Eeko0NGZLcjRJaldyczQwdEV0b1MKSndHM1NtbWMyakdhSlRPMDlCUzFCTm5UWXhLU0pGc25oUlZjOHBrK3BXQmpiaVhTV1U0ekxtc2xPNnVLTlBQQgp1b3ZVbitVeGdLRDFKZ0dXY0JPRW1RckxhcWd0YzVGdTZ5UjZzNkdIZkplL1NCaWxuSG9mRjh1SlZwajZyVk9uCmdBWDFKVUhSS3NpUGh1SHh1cFAzNURETzQwbHVMbGg1UGZWUVl1WkN5Y3Z0cDFRclcyeTR5YlY3RWRwTExKWUUKQXhnazl3dEFJdS8ralloVXBGaTVXRDM2SjMvS2MwNUZsOXNZY3l6dXdxZy9pTlVlVG9zRjROTTgwYVR0TGt5TApFM1Z6SVgwYkpwK3NNaFVxNWh3TFF5MW1HcEoyZ016d0NhcGpZWS9ob1FLQmdRRFE0Z0VKRUZYOXk4QWlKNFF1CnpYd1RFSFRSZXZmdFplOXE1YVZxK2RqVmMwdWNBVFlNeVJ2Y1ZnNGUvWE95akRyUG9pNXZEN1RJWDFmYWdEVmoKUmpJeWlvY3dnWUZqQW9mS0YzOG1TaWFLaGN6blVxbnpxNlpqSVBrUFJLcWJOL2tHTmdRQlBFY1p1djBDSDNGNwpkcjNxNE4vdlhaSkNGMjZDN1p6RU5sa0tqUUtCZ1FERkVJYjR2bmIxT1BCbi92Nm0wbnJNbGJxbmhDK2xxNTBUCjVqSUE4VEdQLzNCTDBONWxJa3VlUGtFUzlZOUxXVkNUbVQ2SXhqTmZzWU9kT1g0aVRXOVBESS9BTWZ1QXhxblkKU2p5cyt3Q2Z3bU5iak1KVThmUC90UDMvdlAyT0hyaldvZmdFaGFWc01Lb1NibGNKNFA0TzlIcFVXcHdubFFNaQpzbllSNXJVSGF3S0JnRTRPUm1qR3EvdWRLZjBaV3pIS0k3VlVEdk5BeW1qeUVKZVhuVXJ1ZG5LOUZPSUZLZGQ1ClIybjgxbVlLUERQYVp4ZXorVG9UV25FTi85eHMwSVo2Y3NPa05JU1J3SEhwUGlqc3d0emlGS2pxK3ZqdVVRZjMKZXNQTVRJWENHU2JMc2NqNlltQzd6NjN6ekJ3QTkvMDFFQjgzVFRjN2RpNHdaMkdSdldVdEVmVDVBb0dCQUpTUwphMUFxT1FHVTFodHg4b2ZQZEdtK0VTV3UwVVYwWjA3VFpLdTFMSXJHS09IZ0xXdk9PWGlxc3VFYVpkaUhFK3JUCnhJUFYrbkdSSWd0dGh4MVJpRFB1NG9vaXBOMW42akY1ZHRscnZBSzJ5YllDSDVsdmVXZzJDckcreU9OWFlqL2YKaVYvUGF2SndsaWlqSzlmMDIxWm5GN3QxUFBuU3JMU0NHK1pQSy9qVkFvR0FKd1k4MVR5NVlNQjZxbFJPM2hvNgpFLy9PeStiNE1Da2g5cVROcmlwZ01kUzllYUp3TjZ2K2FIejk1SEdOQUVab2JCL3JpNU1DOU0vMytxYWUzaVlJCnhKTHRvRWwrR01hMk1KemtRQUpkSkxVQzBFMFA3aGJLbm5NT2sxY000b3gyakdSZXNMekVzSzdPeHF3VVQ3TUIKRFJ1TEo3dTdCLytNbjljSDFiczh5ZFE9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
kind: Secret
metadata:
creationTimestamp: "2024-07-28T14:55:26Z"
name: nginx-test-tls
namespace: default
resourceVersion: "3421361"
uid: 2a07ae0e-4862-441e-a36f-665b518b2cb9
type: kubernetes.io/tls

在ingress中引用这个secret:使用tls参数进行配置

注意:这样配置的前提是ingress暴露在公网,如果ingress前面有slb负载,那么ssl证书应该配置在slb上

pAvUG36.md.png

1.5使用SubPath解决挂载覆盖的问题

上述configmap挂载中的演示都是把文件挂载到一个空的目录中,所以没有问题

如果挂载到一个有文件的目录中,例如把nginx.conf挂载到容器的/etc/nginx中,nginx.conf会覆盖容器的/etc/nginx,目录中只会有一个nginx.conf,这样会导致nginx无法启动,下面进行演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#准备一个nginx.conf
[root@k8s-master01 configmap]# cat nginx.conf

user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;


events {
worker_connections 512;
}


http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

include /etc/nginx/conf.d/*.conf;
}

基于nginx.conf创建一个configmap

1
2
3
4
5
[root@k8s-master01 configmap]# kubectl create configmap  nginx-conf --from-file=nginx.conf
configmap/nginx-conf created
[root@k8s-master01 configmap]# kubectl get cm
NAME DATA AGE
nginx-conf 1 9s

在pod中引用这个名字是nginx-conf的cm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
[root@k8s-master01 configmap]# cat dp-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: dp-cm
name: dp-cm
spec:
replicas: 1
selector:
matchLabels:
app: dp-cm
template:
metadata:
labels:
app: dp-cm
spec:
imagePullSecrets:
- name: my-aliyun-registry
containers:
- image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine
name: nginx
imagePullPolicy: Always
volumeMounts:
- name: nginxconf
mountPath: /etc/nginx #这样配置会覆盖/etc/nginx目录所有文件,只有一个nginx.conf的文件,容器会启动失败
volumes:
- name: nginxconf
configMap:
name: nginx-conf


#创建deployment
[root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml
deployment.apps/dp-cm replaced

#查看pod状态,状态Error
[root@k8s-master01 configmap]# kubectl get po
NAME READY STATUS RESTARTS AGE
dp-cm-6f5859f7df-dcm8q 0/1 Error 3 (40s ago) 57s

#查看日志
[root@k8s-master01 configmap]# kubectl logs -f dp-cm-6f5859f7df-dcm8q
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf is not a file or does not exist
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2024/07/28 15:28:11 [emerg] 1#1: open() "/etc/nginx/mime.types" failed (2: No such file or directory) in /etc/nginx/nginx.conf:15
nginx: [emerg] open() "/etc/nginx/mime.types" failed (2: No such file or directory) in /etc/nginx/nginx.conf:15

#日志提示无法找到文件或目录,原因是覆盖导致nginx核心文件被清理了,nginx的容器无法启动
#这种情况就可以是subpath解决文件覆盖的问题
[root@k8s-master01 configmap]# cat dp-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: dp-cm
name: dp-cm
spec:
replicas: 1
selector:
matchLabels:
app: dp-cm
template:
metadata:
labels:
app: dp-cm
spec:
imagePullSecrets:
- name: my-aliyun-registry
containers:
- image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine
name: nginx
imagePullPolicy: Always
volumeMounts:
- name: nginxconf
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf #使用这个参数解决挂载覆盖的问题
volumes:
- name: nginxconf
configMap:
name: nginx-conf

#创建deploy
[root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml
deployment.apps/dp-cm replaced

#查看pod状态
[root@k8s-master01 configmap]# kubectl get po
NAME READY STATUS RESTARTS AGE
dp-cm-85dfcf698d-fvdmz 1/1 Running 0 7m29s

#查看nginx.conf的worker_connections 是不是512,如果是证明挂载成功,并没有把其他文件覆盖
[root@k8s-master01 configmap]# kubectl exec dp-cm-85dfcf698d-fvdmz -- cat /etc/nginx/nginx.conf

user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;


events {
worker_connections 512;
}


http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

include /etc/nginx/conf.d/*.conf;
}

subPath总结:

1
`subPath` 是一个可选参数,用于指定卷挂载点的子路径。它允许你将 ConfigMap 中的单个文件挂载到容器中的特定路径。

1.6configmap&secret热更新

方式一:更新通过yaml文件方式创建的资源

1
直接对yaml文件进行修改,然后执行replace命令对configmap进行更新即可(kubectl replace -f configmap.yaml)

方式二:通过–from-file创建的configmap使用下面指令进行更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#对于使用--from-file创建的configmap资源,通过先对文件进行修改,在将文件导入configmap中
#例如需要修改名字是nginx-conf的conf
[root@k8s-master01 ~]# kubectl get cm
NAME DATA AGE
nginx-conf 1 5d23h
redis-conf 1 6d7h

#nginx-conf创建是--from-file指定的文件是nginx.conf(可以通过kubectl get cm nginx-conf -oyaml命令中的data字段获取)
#直接对nginx.conf进行修改,例如将worker_connections的值修改为2048;
[root@k8s-master01 configmap]# kubectl create cm nginx-conf --from-file=nginx.conf --dry-run=client -oyaml|kubectl replace -f -
configmap/nginx-conf replaced


#查看修改的2048是否生效
[root@k8s-master01 configmap]# kubectl get cm nginx-conf -o yaml
apiVersion: v1
data:
nginx.conf: |2

user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;


events {
worker_connections 2048; #这里修改已经生效
}


http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

include /etc/nginx/conf.d/*.conf;
}
kind: ConfigMap
metadata:
creationTimestamp: "2024-07-28T15:18:36Z"
name: nginx-conf
namespace: default
resourceVersion: "3691636"
uid: b7d278c1-2e09-46cf-8022-649d930621ef
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 命令: kubectl create cm nginx-conf --from-file=nginx.conf --dry-run=client -oyaml|kubectl replace -f -

# 第一部分: kubectl create cm nginx-conf --from-file=nginx.conf --dry-run=client -oyaml
kubectl create cm nginx-conf # 创建一个名为 nginx-conf 的 ConfigMap
--from-file=nginx.conf # 使用名为 nginx.conf 的文件内容创建 ConfigMap
--dry-run=client # 模拟创建操作,但不实际提交到集群
-oyaml # 输出 YAML 格式的结果

# 第二部分: | (管道操作符)
# 将第一部分的输出作为第二部分的输入

# 第三部分: kubectl replace -f -
kubectl replace # 替换已存在的资源
-f - # 从标准输入(stdin)读取配置文件

1.7configmap&secret使用限制

  • 使用configmap和secret需要提前创建,才能在pod中引用,否则会提示资源不存在或者pod一直处于pending状态
  • 引用的key必须存在
  • 使用envFrom和valueFrom无法热更新环境变量,此时需要重启pod
  • 使用envFrom配置环境变量,如果key是无效的,它会忽略掉无效的key
  • configmap和secret必须要和pod或者是引用它的资源在同一个命名空间
  • 使用subPath也是无法热更新的
  • configmap和secret最好不要太大(不要超过2m)

1.8配置只读的configmap和secret

1
在资源的yaml文件添加immutable: true参数即可,该配置和kind同级。