k8s的配置和存储(ConfigMap、Secret、Hostpath、EmptyDir以及NFS的服务使用)

时间:2024-10-24 13:24:46

ConfigMap

简介

在 Kubernetes 中,ConfigMap 是一种用于存储非敏感信息的 Kubernetes 对象。它用于存储配置数据,如键值对、整个配置文件或 JSON 数据等。ConfigMap 通常用于容器镜像中的配置文件、命令行参数和环境变量等。

ConfigMap 可以通过三种方式进行配置数据的注入:

  1. 环境变量注入:将配置数据注入到 Pod 中的容器环境变量中。

  2. 配置文件注入:将配置数据注入到 Pod 中的容器文件系统中,容器可以读取这些文件。

  3. 命令行参数注入:将配置数据注入到容器的命令行参数中。

优缺点

优点:

  1. 代码与配置分离:ConfigMap允许将应用的配置信息从容器镜像中分离出来。这种分离使得配置可以独立于应用程序进行管理和更新,从而简化了配置管理流程,并避免了因配置更改而需要重新构建和部署容器镜像的繁琐过程。
  2. 统一的集群配置管理:ConfigMap提供了一个统一的机制,用于在Kubernetes集群中存储、管理和传递配置信息。这使得配置数据可以在多个Pod、容器或服务之间共享和重用,提高了配置的灵活性和可维护性。
  3. 提高可移植性:通过将配置信息与容器镜像分离,ConfigMap使得容器镜像更加通用和可移植。同一个容器镜像可以在不同的环境中使用,只需通过ConfigMap提供不同的配置即可,从而增强了应用的适应性和灵活性。
  4. 简化配置管理:ConfigMap支持以key-value对的形式存储配置数据,可以方便地通过kubectl命令行工具或YAML文件进行创建、查询、更新和删除。此外,ConfigMap还支持存储整个配置文件或JSON二进制对象,为复杂的配置管理提供了更大的灵活性。
  5. 支持多种使用场景:ConfigMap可以用于多种使用场景,如外部配置文件的管理、环境变量的设置、应用启动参数的动态传递等。这使得ConfigMap成为Kubernetes集群中不可或缺的配置管理工具,能够满足不同应用和服务的需求。
  6. 版本控制:由于ConfigMap是Kubernetes的API资源对象,因此可以使用Kubernetes的版本控制机制对其进行版本管理。这有助于跟踪和审计配置更改,确保集群的稳定性和可维护性。当配置发生更改时,可以轻松地回滚到之前的版本,降低了因配置错误而导致的风险。

然而,需要注意的是,ConfigMap不是加密的,不适合存储敏感信息(如密码、密钥等)。对于这类敏感信息,应该使用Kubernetes的Secret对象或其他加密手段进行存储和管理。此外,ConfigMap的大小也有限制(默认为1MB),需要根据实际情况进行规划和管理。

综上所述,ConfigMap在Kubernetes集群中具有诸多优点,是配置管理的重要工具之一。通过合理利用ConfigMap,可以大大提高应用的可维护性、灵活性和安全性。

缺点:

ConfigMap是Kubernetes中用于配置管理的资源对象,它允许将配置信息从容器镜像中解耦,使得配置可以独立于应用程序进行管理和更新。然而,ConfigMap也存在一些缺点,主要包括以下几点:

  1. 数据大小限制:ConfigMap保存的数据大小不能超过1MiB(默认为1MB),这对于一些需要存储大量配置信息的场景可能会构成限制。如果配置数据超过了这个大小限制,就需要考虑其他配置管理方案。
  2. 不适用于敏感数据:ConfigMap存储的配置数据不加密,因此不适合存储敏感信息,如密码、密钥等。对于这类敏感信息,应该使用Kubernetes的Secret对象或其他加密手段进行存储和管理。
  3. 热更新限制:虽然ConfigMap支持热更新,即可以在不重启Pod的情况下更新配置数据,但需要注意的是,如果ConfigMap是通过环境变量的方式注入到容器中的,那么更新后的值不会立即生效,需要重启Pod才能使新的配置生效。这可能会在某些需要频繁更新配置的场景中造成不便。

综上所述,虽然ConfigMap为Kubernetes中的配置管理提供了很大的便利,但也存在一些需要注意的缺点和限制。在使用ConfigMap时,需要根据实际情况进行规划和管理,以确保配置的正确性和安全性。

ConfigMap基本操作

创建configmap

1:直接用命令创建

configmap的简介cm

kubectl create cm cm名称 --from-literal=key1=value1 [--from-literal=key2=value2 ...]

kubectl create cm cm-1 --from-literal=name=test --from-literal=pwd=123456
查看cm
kubectl get cm cm-1

查看详细信息

Kubectl describe cm cm-1

查看日志

kubectl logs 名称
删除
kubectl delete cm my-config(cm 的名字)

如果使用的是yml文件的话,加上-f

kubectl delete -f my-config(cm 的名字).yaml

2:用文件的方式创建

先创建两个文件:username   password    各在文件里写入内容

语法:kubectl create cm cm名称 --from-file=  

kubectl create cm cm-2 --from-file=username --from-file=password

3:用文件夹的方式创建

在当前文件夹创建两个文件,和上面的文件内容一样

kubectl create cm cm-3 --from-file=/aaa/k8s/cm

4:用yml文件的方式创建

名字为cm-4.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-4
data:
  key1: value1
  key2: value2
创建
kubectl apply -f cm-4.yaml

使用configmap

将configmap作为环境变量

创建cm

kubectl create cm cm-kv --from-literal=SERVER_PORT=9999 --from-literal=HOST=127.0.0.1

创建pod,我们在pod里使用我们刚才创建好的cm作为环境的值

apiVersion: v1
kind: Pod
metadata:
  name: pod-cm
spec:
  containers:
    - image: alpine
      name: cm-alpine
      env:
        #定义环境变量名称
        - name: ENV_SERVER_PORT
         #定义环境变量的值来源于
          valueFrom:
            #来源于ConfigMap的key引用
            configMapKeyRef:
             #来源于哪个ConfigMap
              name: cm-kv
              #来源于哪个ConfigMap的key引用
              key: SERVER_PORT
      # 容器启动后打印环境变量和睡眠3600秒
      command: ["/bin/sh","-c","env;sleep 3600"]

把我们刚创建好的cm里的SERVER_PORT作为ENV_SERVER_PORT的值

创建pod

kubectl apply -f cm-kv.yaml

可以看到值也替换成了我们自己创建的cm环境值

Secret

简介

在Kubernetes(K8s)中,Secret是一种用于存储和管理敏感信息的对象资源类型

用于安全管理敏感数据的关键组件,它可以存储如密码、OAuth令牌、TLS证书等敏感数据。这些数据在存储时通常会进行Base64编码,以避免以明文形式直接暴露。如果etcd(Kubernetes的存储后端)被配置为加密存储,Secret数据也将被加密。

作用

  1. 安全存储和分发敏感数据:Secret可以存储数据库密码、API密钥、SSH私钥等机密信息,而无需将它们暴露在代码或Docker镜像中。这有助于保护敏感数据不被未经授权的用户访问。
  2. 与镜像仓库交互时管理认证信息:Secret可用于存储从私有Docker镜像仓库拉取镜像所需的认证信息,如用户名和密码。这使得Kubernetes集群能够安全地从私有仓库中获取镜像。
  3. 提供TLS/SSL证书:Secret可以管理HTTPS通信所需的TLS/SSL证书和私钥,确保服务间通信的安全性。
  4. 环境变量和文件挂载:Secret可以以环境变量的形式注入到Pod中,或者以文件的形式挂载到Pod的文件系统中。这使得应用程序能够安全地访问所需的敏感数据。

为什么要使用Secret

  1. 提高安全性:通过将敏感数据存储在Secret中,可以避免将它们硬编码在代码或Docker镜像中,从而降低数据泄露的风险。
  2. 简化管理:Secret提供了一种集中管理敏感数据的方式,使得集群管理员能够更容易地跟踪和更新这些数据。
  3. 增强合规性:许多行业和法规要求保护敏感数据的安全性。使用Secret可以帮助组织满足这些合规性要求。
  4. 灵活性:Secret可以与特定的Namespace关联,实现细粒度的权限控制和隔离。此外,Secret还支持动态更新和自动检查更新,使得应用程序能够动态读取最新的敏感数据。

综上所述,Kubernetes中的Secret是一种非常重要的资源对象,它用于安全地存储和管理敏感数据,并提供了多种方式来访问这些数据。通过使用Secret,可以提高集群的安全性、简化管理、增强合规性,并为应用程序提供灵活的敏感数据访问方式。

创建Secret

1:使用命令创建Secret

kubectl create secret generic mysecret1 --from-literal=username=root --from-literal=password=123456
查看
kubectl get secret

查看详细情况

 kubectl describe secret mysecret1

 

可以发现看不到数据,只能看到有多少字节

kubectl get secret secret名称 -o yaml 

拿到password的明文

echo -n "MTIzNDU2" | base64 -d

 用明文查看具体信息

2:用yaml文件创建

文件名secret-my2.yaml

apiVersion: v1
kind: Secret
metadata:
  name: mysecret2
type: Opaque
data:
  username: YWRtaW4=   #base64 编码之后的用户名admin
  password: NjU0MzIx   # 编码之后的密码654321

创建

kubectl apply -f secret-my2.yaml

查看结果

kubectl get secret

3:使用文件创建secret 

创建文件

echo -n admin >./username

echo -n 123456 > ./password

创建secret 

kubectl create secret generic mysecret --from-file=./username --from-file=./password

Docker私有仓库类型的Secret使用

之前的文章里有详细的创建镜像仓库步骤

进入我们之前创建的仓库里,这里可以看到我们的username,还有一个就是我们创建仓库时自己创建的密码

我们也要获取到服务器地址

创建docker

kubectl create secret docker-registry docker-sec  --docker-server=crpi-gncut4i1n4x11ps8.cn-beijing.personal.cr.aliyuncs.com  --docker-username=aliyun3410884371 --docker-password=密码

将这三个信息替换为自己的即可

Hostpath

工作原理:HostPath卷通过Volume抽象层将宿主机的存储空间关联到容器,使容器可以直接访问宿主机上的文件系统。当Pod被调度到某个节点上时,它会将宿主机上指定的目录或文件挂载到容器内部,使得容器可以像访问本地文件系统一样访问这些资源。

简介

HostPath是Kubernetes中的一种存储卷类型,它将容器所在宿主机的文件目录挂载到容器指定的挂载点中。

HostPath的作用

HostPath类型的存储卷可以独立于Pod资源的生命周期,具有持久性。这意味着即使Pod被删除,存储在HostPath中的数据仍然会保留在宿主机上。这使得HostPath在以下场景中非常有用:

  1. 容器需要访问Docker内部结构时,可以使用HostPath映射Docker的目录到容器中。
  2. 容器工作负载程序生成的日志文件需要永久保存时,可以使用HostPath将日志文件存储到宿主机上。
  3. 需要访问宿主机上特定文件或目录的容器工作负载,可以通过HostPath实现。

创建pod

创建yaml文件

apiVersion: v1
kind: Pod
metadata:
  name: pod-vm-hostpath
spec:
  containers: 
    - image: nginx:1.22.0
      name: con-vm-hostpath
      #加载数据卷
      volumeMounts:
        #加载volumes中的哪个数据卷 
        - name: db-config
          #加载到容器中的哪个路径
          mountPath: "/usr/share/nginx/html"
  #定义容器可以用的容器卷
  volumes:
   #定义名称
    - name: db-config
      hostPath:
       #对应本机的一个文件夹路径
        path: /data1
        # 检查类型 在挂载前对目录做检查操作 DirectoryOrCreate 
        type: DirectoryOrCreate

 因为我们搭建了集群,所以我们需要查看在哪台服务器上运行

在noded3中执行

这时候我们查看pod的信息

也就是说将pod容器里面的文件夹和我们本机的data1进行了绑定

如果 Pod 被销毀了,hostPath 对应的目录还是会被保留,从这一点来看,hostPath 的持久性比emptyDir 强。不过一旦Host 崩溃,hostPath 也就无法访问了。但是这种方式也带来另外一个问题增加了 pod 与节点的耦合。

EmptyDir

用于两个容器共享文件夹

容器间共享:Pod中的所有容器都可以读写EmptyDir卷,这使得它适合用作共享存储。例如,一个容器可以将数据写入EmptyDir,然后另一个容器可以从EmptyDir中读取这些数据。

简介

定义:EmptyDir是一个在Pod被分配到Node(节点)时创建的空目录。它的初始内容为空,并且无需指定宿主机上对应的目录文件,因为Kubernetes会自动为其分配一个目录。

生命周期:EmptyDir的生命周期与Pod紧密相关。当Pod被创建时,EmptyDir也会被创建;当Pod被销毁时,EmptyDir中的数据也会被永久删除。

创建pod

apiVersion: v1
kind: Pod
metadata:
  name: pod-vm-emptydir
spec:
  containers: 
    - image: busybox
      #imagePullPolicy: Never
      name: con-vm-emptydir1
      #加载数据卷
      volumeMounts:
        #加载volumes中的哪个数据卷 
        - name: db-config
          #加载到容器中的哪个路径
          mountPath: "/data3"
      command: ["/bin/sh","-c","sleep 3600"]
    - image: busybox
      imagePullPolicy: Never
      name: con-vm-emptydir2
      #加载数据卷
      volumeMounts:
        #加载volumes中的哪个数据卷 
        - name: db-config
          #加载到容器中的哪个路径
          mountPath: "/data4"
      command: ["/bin/sh","-c","sleep 3600"]
  #定义容器可以用的容器卷
  volumes:
   #定义名称
    - name: db-config
      emptyDir: {}

创建两个容器,并可以互相读取数据

分别进入两个容器

进入容器
kubectl exec -it pod-vm-emptydir -c con-vm-emptydir1 -- sh
kubectl exec -it pod-vm-emptydir -c con-vm-emptydir2 -- sh

分别进入两个data文件夹,随意操作就可以发现两个文件夹的内容时同步的

NFS

简介

NFS(Network File System)即网络文件系统,是一种允许不同计算机系统和设备之间通过网络共享文件和资源的协议

  1. 工作原理
    • NFS通过将文件系统挂载到远程服务器上,实现对文件和目录的访问和共享。
    • 客户端请求访问某个文件或目录时,NFS将该请求传递给服务器,服务器返回所需要的数据或信息。
    • 客户端和服务器之间通过RPC(Remote Procedure Call,远程过程调用)协议进行通信。

NFS作用

  1. 文件共享与协作
    • NFS允许不同操作系统和设备之间共享文件和资源,使得多台计算机可以方便地访问和操作同一份数据。
    • 这有助于提高工作效率和资源利用率,同时减少了数据冗余和管理成本。
  2. 集中化管理与维护
    • 通过NFS,可以将文件和资源集中管理在服务器上,并通过网络共享给多个客户端使用。
    • 这有助于实现集中化的管理和维护,减少了系统管理员的工作量。
  3. 高效的文件访问性能
    • NFS采用了异步I/O和数据缓存等技术,以提高文件访问效率和性能。
    • 经常访问的文件和目录可以被缓存到客户端本地,从而减少了对服务器的访问次数。
  4. 安全性与权限控制
    • NFS实现了基于权限的文件访问控制机制,只有合法用户才能访问和修改共享的文件和目录。
    • 这有助于确保数据的安全性和完整性,防止未经授权的访问和修改。

安装nfs

在我们集群的服务器上都安装上

 yum -y install  nfs-utils

启动

 systemctl start nfs-server

在主机上创建/opt/nfs/data文件夹

设置访问权限

# insecure:通过 1024 以上端口发送 rw: 读写 sync:请求时写入共享 no_root_squash:root用户有完全根目录访问权限

echo  "/opt/nfs/data *(insecure,rw,sync,no_root_squash)" >> /etc/exports

让共享生效:

#重新挂载 使 /etc/exports生效

exportfs -r

查看共享文件

 exportfs 

重启nfs-server服务

systemctl restart nfs-server

在其余两台服务器上创建/root/nfs/data目录

挂载远程nfs目录到本地

 mount -t nfs 192.168.227.100:/root/nfs/data /root/nfs/data

创建一个测试文件

 echo "hello nfs server" > /root/nfs/data/test.txt

查看主机上的文件

cat /root/nfs/data/test.txt

就可以发现文件共享了,主机的文件夹里也出现了这个test文件

取消挂载

 umount -f -l nfs目录

在/root/nfs/data中创建index.html并写入内容

echo hello>index.html

创建pod文件nfs.yml

apiVersion: v1
kind: Pod
metadata:
  name: pod-nfs
spec:
  containers: 
    - image: nginx:1.19
      name: con-nfs
      #加载数据卷
      volumeMounts:
        #加载volumes中的哪个数据卷 
        - name: nfs-volume
          #加载到容器中的哪个路径
          mountPath: "/usr/share/nginx/html"
  #定义容器可以用的容器卷
  volumes:
   #定义名称
    - name: nfs-volume
      nfs:
        #nfs网络服务的地址
        server: 192.168.227.100
        #nfs网络服务器的路径 要在服务器上存在 并且已经启用共享
        path: /root/nfs/data
        #是否只读
        readOnly: false

创建pod

kubectl apply -f nfs-pod.yaml

查看所有的pod

 kubectl get pods -o wide

 

访问我们创建的pod

curl  10.244.2.38

我们写入的信息也就显示了出来

即使pod删除,NFS服务器上的对应的文件也不会删除,能够做到持久化存储。

总结

Emptydir  容器之间可以数据共享

Hostpath : 把容器内部的路径挂载到对应的节点的主机上面,操作主机上面的文件夹对应的容器就可以同步

Nfs:把容器内部的路径挂载到主机上面,操作主机上面的文件夹对应的容器就可以同步

主机是可以跨节点(在主机上运行,挂载到另一台服务器上面 )

nfs可以跨节点 hostpath 不可以