k8s-配置与存储-配置管理

文章目录

    • 一、配置存储
    • [1.1 ConfigMap](#1.1 ConfigMap)
    • [1.2 Secret](#1.2 Secret)
      • [1.2.1Secret的应用与Docker仓库 Secret设置](#1.2.1Secret的应用与Docker仓库 Secret设置)
        • [1. Kubernetes 中的 Secrets:](#1. Kubernetes 中的 Secrets:)
        • [创建 Secret 示例:](#创建 Secret 示例:)
        • [将 Secret 挂载到 Pod 中的示例:](#将 Secret 挂载到 Pod 中的示例:)
        • [2. Docker 仓库中的 Secret:](#2. Docker 仓库中的 Secret:)
        • [在 Kubernetes 中设置 Docker 仓库的 Secret 示例:](#在 Kubernetes 中设置 Docker 仓库的 Secret 示例:)
        • [在 Pod 中使用 Docker 仓库的 Secret 示例:](#在 Pod 中使用 Docker 仓库的 Secret 示例:)
    • [1.3SubPath 的使用](#1.3SubPath 的使用)
      • [1.3.1 使用SubPath](#1.3.1 使用SubPath)
    • 1.4ConfigMap的热更新
    • [1.5不可变的 Secret 和 ConfigMap](#1.5不可变的 Secret 和 ConfigMap)

在前面已经提到,容器的生命周期可能很短,会被频繁地创建和销毁。那么容器在销毁时,保存在容器中的数据也会被清除。这种结果对用户来说,在某些情况下是不乐意看到的。为了持久化保存容器的数据,kubernetes引入了Volume的概念。
Volume是Pod中能够被多个容器访问的共享目录,它被定义在Pod上,然后被一个Pod里的多个容器挂载到具体的文件目录下,kubernetes通过Volume实现同一个Pod中不同容器之间的数据共享以及数据的持久化存储。Volume的生命容器不与Pod中单个容器的生命周期相关,当容器终止或者重启时,Volume中的数据也不会丢失。
kubernetes的Volume支持多种类型,比较常见的有下面几个:

  • 简单存储:EmptyDir、HostPath、NFS
  • 高级存储:PV、PVC
  • 配置存储:ConfigMap、Secret

一、配置存储

1.1 ConfigMap

1.1.1.基于文件夹的创建方式

ConfigMap是一种比较特殊的存储卷,它的主要作用是用来存储配置信息的。

使用 kubectl create configmap -h 查看示例,构建 configmap 对象

复制代码
[root@k8s-master ~]# mkdir config
[root@k8s-master ~]# cd config

[root@k8s-master config]# kubectl create configmap -h

创建两个配置文件

复制代码
[root@k8s-master config]# mkdir test
[root@k8s-master config]# cd test/
[root@k8s-master test]# ls
[root@k8s-master test]# touch db.properties
[root@k8s-master test]# ls
db.properties
[root@k8s-master test]# vi db.properties
yaml 复制代码
username=root
password=admin
复制代码
[root@k8s-master test]# vi redis.properties
yaml 复制代码
host:127.0.0.1
port:6379
shell 复制代码
#创建一个名为 test-dir-config 的 ConfigMap,其中包含来自指定目录的所有文件
[root@k8s-master config]# kubectl create configmap test-dir-config --from-file=test/
configmap/test-dir-config created
  • kubectl create configmap: 这是用于在 Kubernetes 中创建 ConfigMap 的命令。
  • test-dir-config: 这是您为新创建的 ConfigMap 指定的名称。
  • --from-file=test/ : 这个标志指定了 ConfigMap 的数据来自哪个目录kubectl create configmap: 这是用于在 Kubernetes 中创建 ConfigMap 的命令。
shell 复制代码
# 获取ConfigMap 列表
[root@k8s-master config]# kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      15d
test-dir-config    2      103s
  • kube-root-ca.crt: 包含了一个数据项 ,存储根证书的 ConfigMap
  • test-dir-config : 包含了两个数据项。这是在之前的操作中创建的 ConfigMap,它从 test/ 目录中获取了两个文件的内容。
shell 复制代码
#查看详细信息
[root@k8s-master config]# kubectl describe cm test-dir-config

1.1.2指定文件的创建方式

shell 复制代码
[root@k8s-master config]# vi application.yml
yaml 复制代码
spring:
  application:
    name: test app
server:
  port:8080
shell 复制代码
[root@k8s-master config]# kubectl create cm spring-boot-test-yaml --from-file=/root/config/application.yml
configmap/spring-boot-test-yaml created
# 获取ConfigMap 列表
[root@k8s-master config]# kubectl get cm
NAME                    DATA   AGE
kube-root-ca.crt        1      15d
spring-boot-test-yaml   1      20s
test-dir-config         2      12m
[root@k8s-master config]# kubectl describe cm spring-boot-test-yaml

1.1.3 配置文件创建configmap

创建configmap.yaml,内容如下:

shell 复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: configmap
  namespace: dev
data:
  info: |
    username:admin
    password:123456

接下来,使用此配置文件创建configmapp

shell 复制代码
 创建configmap
[root@k8s-master config]# kubectl create -f configmap.yaml
configmap/configmap created
# 查看configmap详情
[root@k8s-master config]# kubectl describe cm configmap -n dev
Name:         configmap
Namespace:    dev
Labels:       <none>
Annotations:  <none>

Data
====
info:
----
username:admin
password:123456


BinaryData
====

Events:  <none>

接下来创建一个pod-configmap.yaml,将上面创建的configmap挂载进去

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-configmap
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    volumeMounts: # 将configmap挂载到目录
    - name: config
      mountPath: /configmap/config
  volumes: # 引用configmap
  - name: config
    configMap:
      name: configmap
yaml 复制代码
# 创建pod
[root@k8s-master config]#  kubectl create -f pod-configmap.yaml
pod/pod-configmap created
# 查看pod
[root@k8s-master config]# kubectl get pod pod-configmap -n dev
NAME            READY   STATUS    RESTARTS   AGE
pod-configmap   1/1     Running   0          15s

#进入容器
[root@k8s-master ~]# kubectl exec -it pod-configmap -n dev -- /bin/sh
# 
# cd  /configmap/config/
# ls
info
# more info
username:admin
password:123456

# 可以看到映射已经成功,每个configmap都映射成了一个目录
# key--->文件     value---->文件中的内容
# 此时如果更新configmap的内容, 容器中的值也会动态更新

1.2 Secret

在kubernetes中,还存在一种和ConfigMap非常类似的对象,称为Secret对象。它主要用于存储敏感信息,例如密码、秘钥、证书等等。

1.2.1Secret的应用与Docker仓库 Secret设置

1. Kubernetes 中的 Secrets:

在 Kubernetes 中,Secrets 可以用于以下目的:

  • 存储敏感数据: 比如数据库密码、API 密钥等。
  • 挂载到 Pod 中: Secrets 可以通过 Volume 挂载到 Pod 中,使应用程序能够读取敏感数据。这有助于将敏感信息与应用程序的配置分离开。
  • 用于身份验证: 在某些情况下,Secrets 也可以用于身份验证,例如在 Ingress 中配置 TLS 证书。
创建 Secret 示例:

1.首先使用base64对数据进行编码

yaml 复制代码
#准备username
[root@k8s-master ~]# echo -n 'admin' | base64 
YWRtaW4=

 #准备password
[root@k8s-master ~]#  echo -n '123456' | base64
MTIzNDU2

2.接下来编写secret.yaml,并创建Secret

yaml 复制代码
apiVersion: v1
kind: Secret
metadata:
  name: secret
  namespace: dev
type: Opaque
data:
  username: YWRtaW4=
  password: MTIzNDU2
shell 复制代码
# 创建secret
[root@k8s-master config]#  kubectl create -f secret.yaml
secret/secret created
# 查看secret详情
[root@k8s-master config]#  kubectl describe secret secret -n dev
Name:         secret
Namespace:    dev
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  6 bytes
username:  5 bytes

3.创建pod-secret.yaml,将上面创建的secret挂载进去:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    volumeMounts: # 将secret挂载到目录
    - name: config
      mountPath: /secret/config
  volumes:
  - name: config
    secret:
      secretName: secret
shell 复制代码
# 创建pod
[root@k8s-master config]# kubectl create -f pod-secret.yaml
pod/pod-secret created

# 查看pod
[root@k8s-master config]# kubectl get pod pod-secret -n dev
NAME            READY   STATUS    RESTARTS   AGE
pod-secret      1/1     Running   0          2m28s

# 进入容器,查看secret信息,发现已经自动解码了
[root@k8s-master config]# kubectl exec -it pod-secret -- /bin/sh -n dev
/ # ls /secret/config/
password  username
/ # more /secret/config/username
admin
/ # more /secret/config/password
123456

另一种创建方法:

yaml 复制代码
kubectl create secret generic my-secret \
  --from-literal=username=my-username \
  --from-literal=password=my-password
将 Secret 挂载到 Pod 中的示例:
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mycontainer
    image: myimage
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/myapp
  volumes:
  - name: secret-volume
    secret:
      secretName: my-secret
2. Docker 仓库中的 Secret:

在 Docker 仓库中,Secrets 通常用于:

  • 拉取私有镜像: 如果您的 Docker 镜像存储库是私有的,您需要将 Docker 仓库的凭据存储在 Kubernetes 中的 Secret 中,以便 Pods 能够拉取镜像。
在 Kubernetes 中设置 Docker 仓库的 Secret 示例:
yaml 复制代码
kubectl create secret docker-registry my-docker-secret \
  --docker-server=my-docker-registry.com \
  --docker-username=my-username \
  --docker-password=my-password \
  --docker-email=my-email@example.com
在 Pod 中使用 Docker 仓库的 Secret 示例:
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mycontainer
    image: my-docker-registry.com/myimage:latest
  imagePullSecrets:
  - name: my-docker-secret

这将使 Kubernetes 能够使用 my-docker-secret 中的凭据拉取 my-docker-registry.com/myimage:latest 这个私有 Docker 镜像

1.3SubPath 的使用

使用 ConfigMap 或 Secret 挂载到目录的时候,会将容器中源目录给覆盖掉,此时我们可能只想覆盖目录中的某一个文件,但是这样的操作会覆盖整个文件,因此需要使用到 SubPath

配置方式:

  1. 定义 volumes 时需要增加 items 属性,配置 key 和 path,且 path 的值不能从 / 开始
  2. 在容器内的 volumeMounts 中增加 subPath 属性,该值与 volumes 中 items.path 的值相同
yaml 复制代码
containers:
......
volumeMounts:
- mountPath: /etc/nginx/nginx.conf # 挂载到哪里
name: config-volume # 使用哪个 configmap 或 secret
subPath: etc/nginx/nginx.conf # 与 volumes.[0].items.path 相同
volumes:
- configMap:
name: nginx-conf # configMap 名字
items: # subPath 配置
key: nginx.conf # configMap 中的文件名
path: etc/nginx/nginx.conf # subPath 路径
yaml 复制代码
[root@k8s-master etc]# kubectl get po
NAME                          READY   STATUS    RESTARTS       AGE
nginx-85b98978db-mkp29        1/1     Running   2 (3d3h ago)   12d
nginx-deploy-c4986b7f-8tplt   1/1     Running   2 (3d3h ago)   6d6h
nginx-deploy-c4986b7f-qltv6   1/1     Running   2 (3d3h ago)   6d6h
yaml 复制代码
[root@k8s-master etc]# kubectl exec -it  nginx-deploy-c4986b7f-8tplt -- sh
# cd /etc
# cd nginx
# ls
conf.d	fastcgi_params	koi-utf  koi-win  mime.types  nginx.conf  scgi_params  uwsgi_params  win-utf
# cat nginx.conf
user  nginx;
worker_processes  1;

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


events {
    worker_connections  1024;
}


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;
}
#复制配置信息 退出容器
# exit
yaml 复制代码
#创建nginx.conf文件
[root@k8s-master config]# vi nginx-conf
[root@k8s-master config]# ls
nginx-conf

 [root@k8s-master config]# kubectl create configmap nginx-conf-cm --from-file=./nginx-conf
configmap/nginx-conf-cm created
[root@k8s-master config]# kubectl describe cm nginx-conf-cm

Name:         nginx-conf-cm
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
nginx-conf:
----
user  nginx;
worker_processes  1;

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


events {
    worker_connections  1024;
}


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;
}


BinaryData
====

Events:  <none>

存储的内容就是nginx-conf这个文件

yaml 复制代码
[root@k8s-master config]# kubectl edit deploy nginx-deploy
yaml 复制代码
        volumeMounts: # 挂在数据卷
        - name: nginx-conf # 数据卷的名称
          mountPath: '/etc/nginx' # 挂载的路径
      volumes: # 数据卷定义
      - name: nginx-conf # 数据卷的名称
        configMap: # 数据卷类型为 configmap
          name: nginx-conf-cm #configmap名字
          items:  # 要将 configmap中哪些数据挂在尽力啊
          - key: nginx-conf # 指定挂在哪个key
            path: nginx.conf # 挂在后该key重命名什么名字
yaml 复制代码
[root@k8s-master config]# kubectl get po
NAME                           READY   STATUS             RESTARTS       AGE
nginx-85b98978db-mkp29         1/1     Running            2 (3d3h ago)   12d
nginx-deploy-7c6975968-t5w5b   0/1     CrashLoopBackOff   4 (62s ago)    2m37s
[root@k8s-master config]# kubectl edit deploy nginx-deploy
deployment.apps/nginx-deploy edited
# 在name: nginx后面加入
    command: ["/bin/sh", "-c","nginx daemon off;sleep 3600"]
yaml 复制代码
[root@k8s-master config]# kubectl get po
NAME                            READY   STATUS    RESTARTS       AGE
nginx-deploy-55f7b46d59-lp5px   1/1     Running   0              22s
nginx-deploy-55f7b46d59-wrfjm   1/1     Running   0              20s
yaml 复制代码
[root@k8s-master config]# kubectl exec -it nginx-deploy-55f7b46d59-lp5px  -- sh
# cd /etc/nginx
# ls
nginx.conf

进入容器后发现原来的一堆配置文件都不见了

得出结果:使用 ConfigMap 或 Secret 挂载到目录的时候,会将容器中源目录给覆盖掉.此时我们可能只想覆盖目录中的某一个文件,但是这样的操作会覆盖整个文件,因此需要使用到 SubPath

1.3.1 使用SubPath

yaml 复制代码
 [root@k8s-master config]# kubectl edit deploy nginx-deploy

 volumeMounts:
        - mountPath: /etc/nginx/nginx.conf
          name: nginx-conf
          subPath: etc/nginx/nginx.conf
          
 volumes:
      - configMap:
          defaultMode: 420
          items:
          - key: nginx-conf
            path: etc/nginx/nginx.conf
          name: nginx-conf-cm
        name: nginx-conf
yaml 复制代码
[root@k8s-master config]#  kubectl get po
NAME                            READY   STATUS    RESTARTS        AGE
nginx-85b98978db-mkp29          1/1     Running   2 (3d20h ago)   12d
nginx-deploy-5588c8bc86-bhj9l   1/1     Running   0               35s
nginx-deploy-5588c8bc86-ltxvs   1/1     Running   0               34s
#进入容器
[root@k8s-master config]# kubectl exec -it nginx-deploy-5588c8bc86-bhj9l -- sh
#
# cd /etc/nginx
# ls
conf.d	fastcgi_params	koi-utf  koi-win  mime.types  nginx.conf  scgi_params  uwsgi_params  win-utf

配置了subPath后进入容器后发现 原来那些文件没有被覆盖掉了,这样就解决了加载配置覆盖原目录的问题。

1.4ConfigMap的热更新

我们通常会将项目的配置文件作为 configmap 然后挂载到 pod,那么如果更新 configmap 中的配置,会不会更新到 pod 中呢?

这得分成几种情况:

默认方式:会更新,更新周期是更新时间 + 缓存时间

subPath:不会更新

变量形式:如果 pod 中的一个变量是从 configmap 或 secret 中得到,同样也是不会更新的

对于 subPath 的方式,我们可以取消 subPath 的使用,将配置文件挂载到一个不存在的目录,避免目录的覆盖,然后再利用软连接的形式,将该文件链接到目标位置

但是如果目标位置原本就有文件,可能无法创建软链接,此时可以基于前面讲过的 postStart 操作执行删除命令,将默认的文件删除即可

  1. 通过 edit 命令直接修改 configmap
  2. 通过 replace 替换

由于 configmap 我们创建通常都是基于文件创建,并不会编写 yaml 配置文件,因此修改时我们也是直接修改配置文件,而 replace 是没有 --from-file 参数的,因此无法实现基于源配置文件的替换,此时我们可以利用下方的命令实现

该命令的重点在于 --dry-run 参数,该参数的意思打印 yaml 文件,但不会将该文件发送给 apiserver,再结合 -oyaml 输出 yaml 文件就可以得到一个配置好但是没有发给 apiserver 的文件,然后再结合 replace 监听控制台输出得到 yaml 数据即可实现替换

kubectl create cm --from-file=nginx.conf --dry-run -o yaml | kubectl replace -f-

yaml 复制代码
#查看当前的 ConfigMap
[root@k8s-master config]# kubectl get cm -n dev
NAME               DATA   AGE
configmap          1      3d19h

[root@k8s-master config]# ls
application.yml  file1.txt  nginx-conf  nginx-pod-configmap.yaml  secret.yaml
configmap.yaml   file2.txt  nginx.conf  pod-secret.yaml           test
#修改 ConfigMap 数据 
[root@k8s-master config]# vi configmap.yaml
    username:AAA
    password:BBB

#更新 ConfigMap 读取 configmap.yaml 文件中的数据,
#并使用 kubectl replace 将其更新到 configmap ConfigMap 中
[root@k8s-master config]# kubectl create cm configmap    -n dev --from-file=configmap.yaml --dry-run=client -o yaml | kubectl replace -f-
configmap/configmap replaced


[root@k8s-master config]# kubectl get pod pod-configmap -n dev
NAME            READY   STATUS    RESTARTS   AGE
pod-configmap   1/1     Running   0          15s

# 验证更新是否传递到 Pod
[root@k8s-master config]#  kubectl exec -it pod-configmap -n dev -- /bin/sh
# cd  /configmap/config/
# ls
configmap.yaml
# cat configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: configmap
  namespace: dev
data:
  info: |
    username:AAA
    password:BBB

确保挂载路径与 ConfigMap 中定义的路径一致,然后查看文件内容是否更新为新的用户名和密码。

这样,就成功地使用 kubectl 命令更新了 ConfigMap 并确保更新成功地传递到相关的 Pod 中

1.5不可变的 Secret 和 ConfigMap

**对于一些敏感服务的配置文件,在线上有时是不允许修改的,此时在配置 configmap 时可以设置 immutable: true 来禁止修改.**这个配置项会锁定 ConfigMap,使其变得只读,防止运维人员或其他用户无意中修改关键配置

相关推荐
chuanauc2 小时前
Kubernets K8s 学习
java·学习·kubernetes
小张是铁粉2 小时前
docker学习二天之镜像操作与容器操作
学习·docker·容器
烟雨书信2 小时前
Docker文件操作、数据卷、挂载
运维·docker·容器
IT成长日记2 小时前
【Docker基础】Docker数据卷管理:docker volume prune及其参数详解
运维·docker·容器·volume·prune
这儿有一堆花2 小时前
Docker编译环境搭建与开发实战指南
运维·docker·容器
LuckyLay2 小时前
Compose 高级用法详解——AI教你学Docker
运维·docker·容器
Uluoyu2 小时前
redisSearch docker安装
运维·redis·docker·容器
IT成长日记6 小时前
【Docker基础】Docker数据持久化与卷(Volume)介绍
运维·docker·容器·数据持久化·volume·
疯子的模样11 小时前
Docker 安装 Neo4j 保姆级教程
docker·容器·neo4j
虚伪的空想家12 小时前
rook-ceph配置dashboard代理无法访问
ceph·云原生·k8s·存储·rook