配景和概念
容器中的文件在磁盘上是临时存放的,这给在容器中运行较重要的应用带来一些问题: 当容器崩溃或停止时,此时容器状态未生存, 因此在容器生命周期内创建或修改的全部文件都将丢失。别的 在崩溃期间,kubelet 会以干净的状态重新启动容器。 当多个容器在一个 Pod 中运行并且必要共享文件时, 跨全部容器设置和访问共享文件体系也有肯定的挑衅性;
有docker使用经历的人应该知道,docker内有一个数据卷的概念,可以持久化容器内的文件数据;同样,在k8s体系内,使用的也是卷的概念;
Kubernetes 支持许多类型的卷。 Pod 可以同时使用任意数量的卷类型。 临时卷类型的生命周期与 Pod 雷同, 但持久卷可以比 Pod 的存活期长。 当 Pod 不再存在时,Kubernetes 也会销毁临时卷;不外 Kubernetes 不会销毁持久卷。 对于给定 Pod 中任何类型的卷,在容器重启期间数据都不会丢失。
卷的核心是一个目录,其中大概存有数据,Pod 中的容器可以访问该目录中的数据。 所接纳的特定的卷类型将决定该目录如何形成的、使用何种介质生存数据以及目录中存放的内容。
使用卷时, 在 .spec.volumes 字段中设置为 Pod 提供的卷,并在 .spec.containers.volumeMounts 字段中声明卷在容器中的挂载位置。 容器中的历程看到的文件体系视图是由它们容器镜像的初始内容以及挂载在容器中的卷所构成的。 其中根文件体系同容器镜像的内容相符合。 任何在该文件体系下的写入操纵,如果被允许的话,都会影响接下来容器中历程访问文件体系时所看到的内容。
卷挂载在镜像中的指定路径下。 Pod 配置中的每个容器必须独立指定各个卷的挂载位置;
常见的卷类型
常见的卷有如下几种类型:
- configMap :configMap 卷提供了向 Pod 注入配置数据的方法。 ConfigMap 对象中存储的数据可以被 configMap 类型的卷引用,然后被 Pod 中运行的容器化应用使用(注意环境变量也可以使用configMap)。
- hostPath:将主机节点文件体系上的文件或目录挂载到你的 Pod 中,但是官网现在不推荐使用这个了;
- nfs:将 NFS (网络文件体系) 挂载到你的 Pod 中。nfs 卷的内容在删除 Pod 时会被生存,卷只是被卸载;使用nfs可以可以在 Pod 之间做到数据共享。
- persistentVolumeClaim: 简称PVC,是用户在不知道特定云环境细节的环境下申领持久存储(例如 iSCSI 卷)的一种方法。
- secret:用来给 Pod 通报敏感信息,例如密码。你可以将 Secret 存储在 Kubernetes API 服务器上,然后以文件的形式挂载到 Pod 中,无需直接与 Kubernetes 耦合
固然也有其他类型的卷,具体的可查阅k8s官网;
案例
一、nfs原生方式挂载卷
企业级生产环境一样寻常会由基础设施部门提供一个nfs地址和目录。受限于我当地测试环境的资源,我只能在虚拟机上随意找一台节点,来模拟nfs文件体系;这里我使用了k8s集群的master节点模拟搭建一个nfs;
(这里解释一下nfs,他的全称就是网络共享文件体系,他可以挂载到任何机器的磁盘目录下,做到几台机器间的文件数据同步共享;)
步骤:
1、在全部机器上安装nfs工具
- #所有机器安装
- yum install -y nfs-utils
复制代码 2、master主节点模拟配置为nfs服务端
- #nfs主节点
- echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports
-
- mkdir -p /nfs/data
- systemctl enable rpcbind --now
- systemctl enable nfs-server --now
- #配置生效
- exportfs -r
复制代码 3、worker节点查询nfs服务
可以看到我上一个步骤创建的目录可以查到了
4、挂载到worker节点指定的目录下
- # 创建/nfs/data目录,执行以下命令挂载 nfs 服务器上的共享目录到本机路径 /nfs/data
- mkdir -p /nfs/data
-
- mount -t nfs 192.168.xxx.xxx:/nfs/data /nfs/data
- # 写入一个测试文件
- echo "hello nfs server" > /nfs/data/test2.txt
复制代码 查看同步的test2.txt文件
5、pod挂载nfs
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- labels:
- app: nginx-pv-demo
- name: nginx-pv-demo
- spec:
- replicas: 2
- selector:
- matchLabels:
- app: nginx-pv-demo
- template:
- metadata:
- labels:
- app: nginx-pv-demo
- spec:
- containers:
- - image: nginx
- name: nginx
- volumeMounts:
- - name: html
- mountPath: /usr/share/nginx/html
- volumes:
- - name: html
- nfs:
- server: 192.168.xxx.xxx
- path: /nfs/data/nginx-pv
复制代码 这里的意思就是将nfs的/nfs/data/nginx-pv目录挂载到容器内的/usr/share/nginx/html目录,这样两边的目录文件就可以做到实时同步了;无论任何一个地方的文件有变动,对方的目录也会跟着一起变动,并且数据始终一致;
可以看到上边两个图片中,两边目录中的文件已经同步了;
二、PV&VC的使用
持久卷(PersistentVolume,PV) 是集群中的一块存储,可以由管理员事先制备, 或者使用存储类(Storage Class)来动态制备。 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样, 也是使用卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 生命周期。 此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储体系;
持久卷申领(PersistentVolumeClaim,PVC) 表达的是用户对存储的哀求。概念上与 Pod 雷同。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以哀求特定命量的资源(CPU 和内存)。同样 PVC 申领也可以哀求特定的大小和访问模式 (例如,可以挂载为 ReadWriteOnce、ReadOnlyMany、ReadWriteMany 或 ReadWriteOncePod)
PV 卷的制备有两种方式:静态制备或动态制备。静态制备是事先已经创建好的pv,动态制备则是基于 StorageClass 来实现,为 PVC 申领动态制备一个存储卷;
本案例使用静态制备的方式
1、在模拟的nfs服务端,创建几个静态的资源空间
- #主节点
- mkdir -p /nfs/data/01
- mkdir -p /nfs/data/02
- mkdir -p /nfs/data/03
复制代码 2、创建PV,分别使用上述的几个目录;
- apiVersion: v1
- kind: PersistentVolume
- metadata:
- name: pv01-10m
- spec:
- capacity:
- storage: 10M
- accessModes:
- - ReadWriteMany
- storageClassName: nfs
- nfs:
- path: /nfs/data/01
- server: 192.168.xxx.xxx
- ---
- apiVersion: v1
- kind: PersistentVolume
- metadata:
- name: pv02-1gi
- spec:
- capacity:
- storage: 1Gi
- accessModes:
- - ReadWriteMany
- storageClassName: nfs
- nfs:
- path: /nfs/data/02
- server: 192.168.xxx.xxx
- ---
- apiVersion: v1
- kind: PersistentVolume
- metadata:
- name: pv03-3gi
- spec:
- capacity:
- storage: 3Gi
- accessModes:
- - ReadWriteMany
- storageClassName: nfs
- nfs:
- path: /nfs/data/03
- server: 192.168.xxx.xxx
复制代码
3、创建PVC
- kind: PersistentVolumeClaim
- apiVersion: v1
- metadata:
- name: nginx-pvc1
- spec:
- accessModes:
- - ReadWriteMany
- resources:
- requests:
- storage: 200Mi
- storageClassName: nfs
复制代码 pvc会找到和所需容量相符的PV资源举行绑定,并且这种绑定也是一对一的关系;
可以看到,我们申领的是200M的存储,那最接近这个要求的就是pv02-1gi这个资源,那此次申领就使用了这个pv卷;
4、pod绑定pvc
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- labels:
- app: nginx-deploy-pvc
- name: nginx-deploy-pvc
- spec:
- replicas: 2
- selector:
- matchLabels:
- app: nginx-deploy-pvc
- template:
- metadata:
- labels:
- app: nginx-deploy-pvc
- spec:
- containers:
- - image: nginx
- name: nginx
- volumeMounts:
- - name: html
- mountPath: /usr/share/nginx/html
- volumes:
- - name: html
- persistentVolumeClaim:
- claimName: nginx-pvc
复制代码 这里pod是将容器内的/usr/share/nginx/html目录挂载到name=html的卷内,html卷使用的是我创建的nginx-pvc;也就是/usr/share/nginx/html目录内的文件会同步到/nfs/data/02目录;
从上述截图中可以看到,容器内的目录下的文件在nfs中也有了;
三、ConfigMap
ConfigMap 是一种 API 对象,用来将非机密性的数据生存到键值对中。使用时, Pod 可以将其用作环境变量、下令行参数或者存储卷中的配置文件。
ConfigMap 可以将你的环境配置信息和容器镜像解耦,便于应用配置的修改。
ConfigMap 并不提供保密或者加密功能。 如果你想存储的数据是机密的,请使用 Secret, 或者使用其他第三方工具来包管你的数据的私密性;
ConfigMap 在计划上不是用来生存大量数据的。在 ConfigMap 中生存的数据不可超过 1 MiB。如果你必要生存超出此尺寸限制的数据,你可考虑挂载存储卷或者使用独立的数据库或者文件服务。
本案例使用configMap抽离容器的配置信息;
1、创建一个配置文件,名称为edis.conf;查看该配置文件内的信息:
2、基于此文件创建CM;
- kubectl create cm redis-conf --from-file=redis.conf
复制代码 3、创建pod,使用上述已经建好的configMap
- apiVersion: v1
- kind: Pod
- metadata:
- name: redis
- spec:
- containers:
- - name: redis
- image: redis
- command:
- - redis-server
- - "/redis-master/redis.conf" #指的是redis容器内部的位置
- ports:
- - containerPort: 6379
- volumeMounts:
- - mountPath: /data
- name: data
- - mountPath: /redis-master
- name: config
- volumes:
- - name: data
- emptyDir: {}
- - name: config
- configMap:
- name: redis-conf
- items:
- - key: redis.conf
- path: redis.conf
复制代码 4、查看配置信息
- # 登录redis,查看配置同步信息
- kubectl exec -it redis -- redis-cli -a yes
复制代码
可以看到我CM中的配置已同步到了redis容器内;并且登录redis也能看到配置的信息;
四、secret
Secret 是一种包罗少量敏感信息例如密码、令牌或密钥的对象。 这样的信息大概会被放在 Pod 规约中或者镜像中。 使用 Secret 意味着你不必要在应用程序代码中包罗机密数据。
由于创建的Secret 可以独立于使用它们的Pod,因此在创建、查看和编辑 Pod 的工作流程中暴露 Secret(及其数据)的风险较小。Kubernetes 和在集群中运行的应用程序也可以对 Secret 采取额外的预防步伐,例如制止将敏感数据写入非易失性存储。
Secret雷同于ConfigMap,但是前者专门用于生存机密数据;
本案例使用阿里云作为镜像仓库,来通过设置的secret登录阿里云,并拉取镜像仓库的私有镜像;
1、起首在阿里云服务中要先上传镜像文件,并确保镜像文件是私有状态;
2、拉取镜像时,必要docker login下令登录阿里云服务,涉及到账号和密码,这里将登录账号信息存储在secret中;
- kubectl create secret docker-registry my-secret ----docker-server=registry.cn-hangzhou.aliyuncs.com --docker-username=aliyun88000000 --docker-password=123456
复制代码 这里我创建了一个my-secret的对象,在管理端查看效果如下:
3、创建pod应用
- apiVersion: v1
- kind: Pod
- metadata:
- name: my-pod
- spec:
- containers:
- - name: my-container
- image: registry.cn-hangzhou.aliyuncs.com/wtl-test/test-nginx:1.0
- imagePullPolicy: Always
- imagePullSecrets:
- - name: my-secret #登录密码从my-secret获取
复制代码 pod创建时指定了镜像的仓库地址和密码;
4、查抄pod启动环境
可以看到镜像已成功获取,并启动了pod应用;
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |