pod资源规范总结
资源类型获取:
kubectl aip-resources
资源群组获取:
kubectl aip-versions
特定资源的规范获取:
kubectl explain <Kind>.
pod运行
自主式pod,非受控于工作负载型控制器
直接由kubelet管理
apiVersion: v1
kind: Pod
metadata:
name:
namespace:
lables:
key1: value1:
spec:
containers: (唯一的必选字段,对象列表)
- name:
image:
- name:
image:
- name:
image:
securityContext: {}(安全上下文)用在容器里
startProbe:{}(初始化探针)
livenessProbe:{}(就 绪状态探针,会重启)
readinessProbe:{}(探测service会不会把pod作为端点)
command:[]string (自定义要运行的命令,字串列表)
args: []string(自定义传参数)
resources:{}(需求,预留资源)
cpu: 100m
memory: 512Mi
limits:{}(上限,最大资源的边界)
env: {}(环境变量)
- name:
value:
imagePullPolicy:{}(镜像下载策略) ----明细
restartPolicy: (重启策略) ----明细
securityContext: {}(安全上下文)用在pod里
编写声明式资源配置,生成yaml文件模板:
kubectl run POD_NAME --image=<image> --dry-run=client -o yaml
或者使用Web UI:资源配置生成向导
华为云CCE
阿里云ACK
超亲密关系
关于容器设计模式
单节点多容器模式:
Sidecar模式:辅助容器用于为主容器提供辅助服务以增强主容器的功能
Ambassador模式:大使模式
Adapter模式:将自己的业务读取并转换为外部能识别的业务
Init Container模式:初始化容器,在主容器运行之前
存储卷
卷类型及插件
In-Tree存储卷插件
◼ 临时存储卷
◆emptyDir
◼ 节点本地存储卷
◆hostPath, local
◼ 网络存储卷
◆文件系统:NFS、GlusterFS、CephFS和Cinder
◆块设备:iSCSI、FC、RBD和vSphereVolume
◆存储平台:Quobyte、PortworxVolume、StorageOS和ScaleIO
◆云存储:awsElasticBlockStore、gcePersistentDisk、azureDisk和azureFile
◼ 特殊存储卷
◆Secret、ConfigMap、DownwardAPI和Projected
◼ 扩展接口
◆CSI和FlexVolume
Out-of-Tree存储卷插件
◼ 经由CSI或FlexVolume接口扩展出的存储系统称为Out-of-Tree类的存储插件
存储卷资源规范
定义存储卷
◼ 存储卷对象并非Kubernetes系统一等公民,它需要定义在
Pod上
◼ 卷本身的生命周期同Pod,但其后端的存储及相关数据的
生命周期通常要取决于存储介质
存储卷的配置由两部分组成
◼ 通过.spec.volumes字段定义在Pod之上的存储卷列表,它经
由特定的存储卷插件并结合特定的存储供给方的访问接口
进行定义
◼ 嵌套定义在容器的volumeMounts字段上的存储卷挂载列表,
它只能挂载当前Pod对象中定义的存储卷
spec:
volumes:
- name <string>
# 卷名称标识,仅可使用DNS标签格式的字符,在当前Pod中必须惟一;
VOL_TYPE <Object>
# 存储卷插件及具体的目标存储供给方的相关配置;
containers:
- name: …
image: …
volumeMounts:
- name <string>
# 要挂载的存储卷的名称,必须匹配存储卷列表中某项的定义;
mountPath <string>
# 容器文件系统上的挂载点路径;
readOnly <boolean>
# 是否挂载为只读模式,默认为否;
subPath <string>
# 挂载存储卷上的一个子目录至指定的挂载点;
subPathExpr <string>
# 挂载由指定的模式匹配到的存储卷的文件或目录至挂载点;
mountPropagation <string>
# 挂载卷的传播模式;
获取内置的卷插件类型:
kubectl explain pods.spec.volumes
emptyDir存储卷
emptyDir存储卷
◼ Pod对象上的一个临时目录
◼ 在Pod对象启动时即被创建,而在Pod对象被移
除时一并被删除
◼ 通常只能用于某些特殊场景中
◆同一Pod内的多个容器间文件共享
◆作为容器数据的临时存储目录用于数据缓存系统
配置参数
◼ medium:此目录所在的存储介质的类型,可用
值为“default”或“Memory”
◼ sizeLimit:当前存储卷的空间限额,默认值为nil,
表示不限制
emptyDir存储卷示例
生成配置模板:
[root@k8s-master02 ~]#kubectl run pods-with-emptyDir-vol --image=ikubernetes/admin-box:v1.2 --dry-run=client -o yaml > pods-with-emptyDir-vol.yaml
修改完善配置文件:
[root@k8s-master02 ~]#vim pods-with-emptyDir-vol.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
name: pods-with-emptyDir-vol
spec:
containers:
- image: ikubernetes/admin-box:v1.2
name: admin
command: ["/bin/sh", "-c"]
args: ["sleep 99999"]
resources: {}
volumeMounts:
- name: data
mountPath: /data
- image: ikubernetes/demoapp:v1.0
name: demoapp
resources: {}
volumeMounts:
- name: data
mountPath: /var/www/html
volumes:
- name: data
emptydir:
medium: Memory
sizelimit: 16Mi
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
[root@k8s-master02 ~]#kubectl apply -f pods-with-emptyDir-vol.yaml
pod/pods-with-emptydir-vol created
进入admin的交互式接口,进入挂载目录创建一个文件:
[root@k8s-master02 ~]#kubectl exec -it pods-with-emptydir-vol -c admin -- /bin/sh
root@pods-with-emptydir-vol # cd /data
root@pods-with-emptydir-vol data# ls
root@pods-with-emptydir-vol data# touch test.txt
root@pods-with-emptydir-vol data# vi test.txt
root@pods-with-emptydir-vol data# exit
进入demoapp的交互式接口,查看挂载目录已经有admin创建的文件:
[root@k8s-master02 ~]#kubectl exec -it pods-with-emptydir-vol -c demoapp -- /bin/sh
[root@pods-with-emptydir-vol /]# cd /var/www/html/
[root@pods-with-emptydir-vol /var/www/html]# ls
test.txt
[root@pods-with-emptydir-vol /var/www/html]# cat test.txt
Hi demoapp
追加数据进去:
[root@pods-with-emptydir-vol /var/www/html]# echo "Hi admin" >> test.txt
[root@pods-with-emptydir-vol /var/www/html]# exit
在admin里面能看到追加的数据:
[root@k8s-master02 ~]#kubectl exec -it pods-with-emptydir-vol -c admin -- /bin/sh
root@pods-with-emptydir-vol # cd data/
root@pods-with-emptydir-vol data# cat test.txt
Hi demoapp
Hi admin
root@pods-with-emptydir-vol data#
实现了两个pod共同挂载一个存储卷,挂载到各自不同的目录,实现数据共享
卷的生命周期跟pod一样,pod删除,卷的数据也就没了
hostPath存储卷
hostPath卷
◼ 将Pod所在节点上的文件系统的某目录用作存储卷
◼ 数据的生命周期与节点相同
配置参数
◼ path:指定工作节点上的目录路径,必选字段
◼ type:指定节点之上存储类型
hostpath存储卷示例
[root@k8s-master02 ~]#vim pod-with-hostpath-vol.yaml
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis:6
imagePullPolicy: IfNotPresent
volumeMounts:
- name: redisdata
mountPath: /data
volumes:
- name: redisdata
hostPath:
type: DirectoryOrCreate
path: /data/redis
[root@k8s-master02 ~]#kubectl apply -f pod-with-hostpath-vol.yaml
pod/redis created
查询redis运行的节点:在node02上
[root@k8s-master02 ~]#kubectl get pods -o wide
redis 1/1 Running 0 84s 10.244.4.10 k8s-node02 <none>
在主服务器进入redis交互式:并写入数据
[root@k8s-master02 ~]#kubectl exec -it redis -- /bin/sh
# redis-cli
127.0.0.1:6379> SET mykey magedu.com
OK
127.0.0.1:6379> BGSAVE
Background saving started
127.0.0.1:6379> exit
# ls /data
dump.rdb
到运行redis的node02节点上查看挂载目录下:
[root@k8s-node02 ~]#cd /data/redis/
[root@k8s-node02 redis]#ls
dump.rdb
说明redis的存储数据实在node02节点上的
此时,pod删除,利用相同的yaml文件重建redis,如果刚好重载在同一个节点,那么redis下的数据会依然在,得到数据保持
NFS存储卷
nfs存储卷
◼ 将nfs服务器上导出(export)的文件系统用作存储卷
◼ nfs是文件系统级共享服务,它支持多路挂载请求,可由多
个Pod对象同时用作存储卷后端
配置参数
◼ server <string>:NFS服务器的IP地址或主机名,必选字段
◼ path <string>:NFS服务器导出(共享)的文件系统路径,
必选字段
◼ readOnly <boolean>:是否以只读方式挂载,默认为false
NFS存储卷示例
新的服务器下载nfs-kernel-server,作为nfs服务端:ip:10.0.0.106
apt -y install nfs-kernel-server
创建目录:
mkdir /data/redis00{1,2,3} -pv
将此目录共享出去:
vim /etc/exports
/data/redis001 10.0.0.0/24(rw,no_subtree_check,no_root_squash)
启动服务:
systemctl start nfs-server
检查:
exports -ar
查看2049端口是否开启:
ss -ntl
应kubernetes客户端节点,下载nfs客户端
apt install nfs-common
mkdir /data
将nfs服务器共享的目录挂载到本节点/data下:
mount -t nfs 10.0.0.106:/data/redis001 /data
在客户节点data下创建文件:
cd /data
touch a.txt
再查看服务节点:所有节点写的数据实际存在了nfs-server上
cd /data/redis001
ls
a.txt
基于pod实现nfs
所有节点下载nfs客户端:
apt install nfs-common
写yaml配置文件:
[root@k8s-master02 ~]#vim pod-with-nfs-vol.yaml
apiVersion: v1
kind: Pod
metadata:
name: redis-nfs
spec:
containers:
- name: redis
image: redis:6
imagePullPolicy: IfNotPresent
volumeMounts:
- name: redisdata
mountPath: /data
volumes:
- name: redisdata
nfs:
server: 10.0.0.106
path: /data/redis001
进入交互式页面创建数据:
Kubectl exec -it redis-nfs -- /bin/sh
#redis-cli
#SET testkey www.magedu.com
ok
#BGSAVE
#exit
#ls /data
dump.rdb
此时在NFS-server上查看:
cd /data/redis001
ls
dump.rdb
此时,如果重建redis或再建一个新的redis,不管被分配到哪个节点上,都能加载到nfs下的数据,删除redis,也不会删除nfs的数据
持久卷
PV如何满足PVC期望?
1、管理员事先创建多种规格的PV;
2、管理流程:提交工单;
PV静态置备(Static Provisioning)
3、管理员不去创建PV,取而代之,创建StorageClass(PV模板)
管理员创建SC资源对象:配置了远程存储服务管理接口的API调用操作
远程存储服务:有管理API,而且还要支持远程访问
PV动态置备(Dynamic Provisioning)
PV和PVC示例:
基于NFS的静态PV和PVC示例
access modes支持的模块:
RWO - ReadWriteOnce 单路可写
ROX - ReadOnlyMany 多路只读
RWX - ReadWriteMany 多路可写
RWOP - ReadWriteOncePod 单路单pod可写
NFS PV 资源定义示例
[root@k8s-master02 chapter5]#vim pv-nfs-demo.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs-demo
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
- ReadWriteOnce
- ReadOnlyMany
persistentVolumeReclaimPolicy: Retain
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: "/data/redis002"
server: 10.0.0.106
kubectl apply -f pv-nfs-demo.yaml
kubectl get pv
在NFS-server上共享/data/redis002出目录:
[root@NFS]#vim /etc/exports
/data/redis002 10.0.0.0/24(rw,no_subtree_check,no_root_squash)
[root@NFS]#exportfs -ar
[root@NFS]#showmount -e 10.0.0.106
PVC 资源定义示例
[root@k8s-master02 chapter5]#vim pvc-demo-0001.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-demo-0001
namespace: default
spec:
accessModes: ["ReadWriteMany"]
volumeMode: Filesystem
resources:
requests:
storage: 3Gi
limits:
storage: 10Gi
kubectl apply -f pvc-demo-0001.yaml
kubectl get pvc -n default
此时再看Pv属于bind状态
[root@ubuntu2004 chapter5]#kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs-demo 5Gi RWO,ROX,RWX Retain Bound default/pvc-demo-0001 24s
在Pod上使用PVC卷
[root@k8s-master02 chapter5]#vim volumes-pvc-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-pvc-demo
namespace: default
spec:
containers:
- name: redis
image: redis:6
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
name: redisport
volumeMounts:
- mountPath: /data
name: redis-pvc-vol
volumes:
- name: redis-pvc-vol
persistentVolumeClaim:
claimName: pvc-demo-0001
kubectl apply -f volumes-pvc-demo.yaml
此时redis基于NFS的PV已创建好
进入pod-pvc-demo的交互式接口:
kubectl exec -it pod-pvc-demo -- /bin/sh
#redis-cli
172.20.0.1:6379> SET hikey www.mm.com
ok
172.20.0.1:6379> BGSAVE
172.20.0.1:6379> exit
#ls /data
dump.rdb
到后端NFS-server上验证
ls /data/redis002
dump.rdb
即使删除pod,PV和PVC还在,只删除PVC那么PV会处于pending状态,新建的PVC不会再绑定在上面
PVC需要单独删除:kubectl delete pvc pvc-demo-001
动态pv
storageclass
StorageClass资源
◼ Kubernetes支持的标准资源类型之一
◼ 为管理PV资源之便而按需创建的存储资源类别(逻辑组)
◼ 是PVC筛选PV时的过滤条件之一
◼ 为动态创建PV提供“模板”
◆需要存储服务提供管理API
◆StorageClass资源上配置接入API的各种参数
⚫ 定义在parameters字段中
⚫ 还需要使用provisioner字段指明存储服务类型
◼ 一般由集群管理员定义,隶属集群级别
StorageClass资源示例
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-csi
provisioner: nfs.csi.k8s.io #后端存储服务器
parameters:
server: nfs-server.default.svc.cluster.local #IP或名字
share: / #共享挂载的目录
reclaimPolicy: Delete #回收策略
volumeBindingMode: Immediate #绑定模式
mountOptions:
- hard
- nfsvers=4.1
PVC和动态PV示例
PVC向StorageClass申请绑定PV
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nfs-dynamic
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: nfs-csi
Out-of-Tree存储
◼容器存储接口规范,与平台无关
◼驱动程序组件
CSI Controller:负责与存储服务的API通信从而完成后端存储的管理操作
node plugin:node插件,每个节点都要部署,也称为CSI Node,负责在节点级别完成存储卷的管理,用于扩展卷插件类型以及卷管理器所能支持的卷插件管理类型
CSI存储组件和部署架构
CSI Controller:由StatefulSet控制器对象编排运行,副本量需要设置为1,以保证只会该存储服务运行单
个CSI Controller实例;
Node Plugin:由DaemonSet控制器对象编排运行,以确保每个节点上精确运行一个相关的Pod副本
部署NFS CSI
1.部署nfs server;
2.部署nfs csi driver;
3.创建storageclass,配置CSI Driver引用前面部署的nfs server为存储后端;
4.测试:在storageclass内部,创建一个PVC,验证PVC的动态置备功能
1.部署nfs server
默认部署在default名称空间下,我们可以自己创建名称空间
[root@k8s-master02 ~]#kubectl create namespace nfs
namespace/nfs created
[root@k8s-master02 ~]#kubectl get ns
NAME STATUS AGE
default Active 2d10h
demo Active 2d10h
kube-flannel Active 2d10h
kube-node-lease Active 2d10h
kube-public Active 2d10h
kube-system Active 2d10h
nfs Active 34s
下载镜像并生成pod:
[root@k8s-master02 ~]#kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/deploy/example/nfs-provisioner/nfs-server.yaml --namespace nfs
service/nfs-server created
deployment.apps/nfs-server created
查看生成的pod:
[root@k8s-master02 ~]#kubectl get pods -n nfs
NAME READY STATUS RESTARTS AGE
nfs-server-5847b99d99-lqbp8 0/1 Pending 0 96s
并且还创建了一个server:
[root@k8s-master02 ~]#kubectl get svc -n nfs -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
nfs-server ClusterIP 10.100.177.177 <none> 2049/TCP,111/UDP 3m47s app=nfs-server
2.部署nfs csi driver
在线部署NFS CSI driver v3.1.0:会自动部署到所有节点
[root@k8s-master02 ~]#curl -skSL https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/v3.1.0/deploy/install-driver.sh | bash -s v3.1.0 --
Installing NFS CSI driver, version: v3.1.0 ...
serviceaccount/csi-nfs-controller-sa created
clusterrole.rbac.authorization.k8s.io/nfs-external-provisioner-role created
clusterrolebinding.rbac.authorization.k8s.io/nfs-csi-provisioner-binding created
csidriver.storage.k8s.io/nfs.csi.k8s.io created
deployment.apps/csi-nfs-controller created
daemonset.apps/csi-nfs-node created
NFS CSI driver installed successfully.
检查pod执行状态:
kubectl -n kube-system get pod -o wide -l app=csi-nfs-controller
kubectl -n kube-system get pod -o wide -l app=csi-nfs-node
确保状态为running即可:
NAME READY STATUS RESTARTS AGE IP NODE
csi-nfs-controller-56bfddd689-dh5tk 4/4 Running 0 35s 10.240.0.19 k8s-agentpool-22533604-0
csi-nfs-controller-56bfddd689-8pgr4 4/4 Running 0 35s 10.240.0.35 k8s-agentpool-22533604-1
csi-nfs-node-cvgbs 3/3 Running 0 35s 10.240.0.35 k8s-agentpool-22533604-1
csi-nfs-node-dr4s4 3/3 Running 0 35s 10.240.0.4 k8s-agentpool-22533604-0
3.创建storageclass,配置CSI Driver引用前面部署的nfs server为存储后端
[root@k8s-master02 ~]#vim storageclass-nfs.yaml
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-csi
provisioner: nfs.csi.k8s.io
parameters:
#server: nfs-server.default.svc.cluster.local
server: nfs-server.nfs.svc.cluster.local
share: /
#reclaimPolicy: Delete
reclaimPolicy: Retain
volumeBindingMode: Immediate
mountOptions:
- hard
- nfsvers=4.1
创建pod:storageclass是集群级别的资源,不需要指定名称空间
[root@k8s-master02 ~]#kubectl apply -f storageclass-nfs.yaml
storageclass.storage.k8s.io/nfs-csi created
查看可以看到有一个nfs-csi的sc:
[root@k8s-master02 ~]#kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-csi nfs.csi.k8s.io Retain Immediate false 74s
4.测试:在storageclass内部,创建一个PVC,验证PVC的动态置备功能
请求创建PVC,里面指定了sc指向刚才创建的nfs-csi:
(1)在线创建:
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/release-3.1/deploy/example/pvc-nfs-csi-dynamic.yaml
(2)本地创建:
[root@k8s-master02 ~]#vim dynamic-pvc.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nfs-dynamic
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: nfs-csi
[root@k8s-master02 ~]#kubectl apply -f dynamic-pvc.yaml
persistentvolumeclaim/pvc-nfs-dynamic created
[root@k8s-master02 ~]#kubectl get pvc
会看见处于bound状态,自动创建了一个PV
结果验证:
创建pod,测试动态置备的PVC卷是否可用
[root@k8s-master02 chapter5]#vim volumes-pvc-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: redis-dyn-pvc
namespace: default
spec:
containers:
- name: redis
image: redis:6
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
name: redisport
volumeMounts:
- mountPath: /data
name: redis-pvc-vol
volumes:
- name: redis-pvc-vol
persistentVolumeClaim:
claimName: pvc-nfs-dynamic
[root@k8s-master02 chapter5]#kubectl apply -f volumes-pvc-demo.yaml
pod/redis-dyn-pvc created
进入交互式接口:
[root@k8s-master02 chapter5]#kubectl exec -it redis-dyn-pvc -- /bin/sh
创建数据,退出后删除pod,重新创建pod,再进入交互式接口查看之前的数据,会发现之前的数据还在
标签:存储,pv,name,kubernetes,示例,redis,nfs,k8s,root
From: https://blog.51cto.com/lmm01/6910428