k8s阶段02 namespace,pod资源及命令, pod资源配置(应用监控,资源需求和限制), 多容器pod(初始容器), k8s卷基础
namespace
Namespace: 名称空间,命名空间 资源对象名称隔离 www.google.com, www.magedu.com 资源类型: 名称空间级别:必须属于某个名称空间 -n NAMESPACE_NAME --namespace NAMESPACE_NAME 集群级别:不属于任何名称名称 命令: kubectl get kubectl get TYPE [name, ...] -o {json|yaml|wide|jsonpath|name} #显示类型 kubectl get TYPE1,TYPE2,... #显示多种资源类型 all:代表所有类型 kubectl get TYPE name1 name2 ... kubectl get TYPE1/NAME TYPE2/NAME2 ... TYPE: #支持3种格式,单数,复数,简写(适用于get delete方法,create不支持) namespaces, namespace, ns kubectl get -f /PATH/TO/MANIFEST_FILE #例: #获取所有名称空间 ~]#kubectl get namespace #获取指定名称空间 ~]#kubectl get namespace blog #以json格式展示 ~]#kubectl get namespace blog -o json #只显示json中的metadata.name字段 ~]#kubectl get namespace blog -o jsonpath={.metadata.name} #显示名字 ~]#kubectl get namespace -o name #列出多种资源对象, get all表示显示所有资源类型 ~]#kubectl get service,pods -n blog #显示指定资源类型 ~]#kubectl get service/mysql -n blog 命令: kubectl create 方法一:指令式命令 kubectl create TYPE NAME OPTIONS 方法二:指令式对象配置 kubectl create -f /PATH/TO/MANIFEST_FILE -f选项可重复使用多次; -f /PATH/TO/DIR/:加载目录下的所有以.yaml, .yml, .json结尾的文件; -f URL: 加载URL位置上的配置文件 单个配置文件,可以存在多个资源对象:#通过---进行隔开 apiVersion kind ... --- apiVersion kind .... --- #例: #创建名称空间 [root@master01 ~]#kubectl create namespace dev #存入yaml文件并做修改 ~]#kubectl get namespace dev -o yaml > prod-namespace.yaml ~]#vim prod-namespace.yaml apiVersion: v1 kind: Namespace metadata: name: prod spec: #namespace可以不用定义 finalizers: #终结器,表示删除时谁来删除 - kubernetes #创建名称空间 [root@master01 ~]#kubectl create -f prod-namespace.yaml #--dry-run=client表示以客户端形式做测试,并不真正运行 [root@master01 ~]#kubectl create namespace stage --dry-run=client -o yaml apiVersion: v1 kind: Namespace metadata: creationTimestamp: null name: stage spec: {} status: {} ~]#kubectl create namespace stage --dry-run=client -o yaml > stage-namespace.yaml [root@master01 ~]#kubectl create -f stage-namespace.yaml #可以通过配置文件查看资源类型 [root@master01 ~]#kubectl get -f stage-namespace.yaml NAME STATUS AGE stage Active 22s 命令: kubectl delete 命令格式类似于kubectl get,删除某类型下的所有资源对象时,要使用“--all”选项; #例: [root@master01 ~]#kubectl delete namespace prod stage dev ~]#kubectl delete -f stage-namespace.yaml 命令:kubectl edit kubectl edit TYPE NAME #例: [root@master01 ~]#kubectl edit service wordpress -n blog #如果修改修改有语法错误会不让保存
Kubernetes的名称空间可以划分为两种类型 系统级名称空间:由Kubernetes集群默认创建,主要用来隔离系统级的资源对象 自定义名称空间:由用户按需创建 系统级名称空间 default:默认的名称空间,为任何名称空间级别的资源提供的默认设定 kube-system:Kubernetes集群自身组件及其它系统级组件使用的名称空间,Kubernetes自身的关键组件均部署在该名称空间中 kube-public:公众开放的名称空间,所有用户(包括Anonymous)都可以读取内部的资源 kube-node-lease:节点租约资源所用的名称空间 分布式系统通常使用“租约(Lease)”机制来锁定共享资源并协调集群成员之间的活动 Kubernetes上的租约概念由API群组coordination.k8s.io群组下的Lease资源所承载,以支撑系统级别的功能需求,例如节点心跳(node heartbeats)和组件级的领导选举等 Kubernetes集群的每个节点,在该名称空间下都有一个与节点名称同名的Lease资源对象 ~# kubectl -n kube-node-lease get lease 所有的系统级名称空间均不能进行删除操作,而且除default外,其它三个也不应该用作业务应用的部署目标
什么是Pod?
一个或多个容器的集合,因而也可称为容器集,但却是Kubernetes调度、部署和运行应用的原子单元
另外封装的内容:可被该组容器共享的存储资源、网络协议栈及容器的运行控制策略等
依赖于pause容器事先创建出可被各应用容器共享的基础环境,它默认共享Network、IPC和UTS名称空间给各容器,PID名称空间也可以共享,但需要用户显式定义
Pod的组成形式有两种
单容器Pod:仅含有单个容器
多容器Pod:含有多个具有“超亲密”关系的容器
同一Pod内的所有容器都将运行于由Scheduler选定的同一个节点上
一个极简的Pod定义,仅需要为其指定一个要运行的容器即可 给出该容器的名称和使用的Image #例: ~]#vim pod-demoapp.yaml apiVersion: v1 kind: Pod metadata: name: demoapp # Pod的标识名,在名称空间中必须惟一; namespace: default # 该Pod所属的名称空间,省略时使用默认名称空间default; spec: containers: # 定义容器,它是一个列表对象,可包括多个容器的定义,至少得有一个; - name: demoapp # 容器名称,必选字段,在当前Pod中必须惟一; image: ikubernetes/demoapp:v1.0 # 创建容器时使用的镜像; #创建pod ~]#kubectl apply -f pod-demoapp.yaml #kubectl create是命令式操作,若资源已经存在会报错 #kubectl apply是声明式操作,若资源不存着就创建;若资源存在,比较现有资源配置差异,不同就更新,相同就不操作 pause容器无需定义 命令:kubectl explain TYPE NAME 显示指定资源类型的内建文档 --api-version=GROUP_NAME/VERSION #例:查看pods配置怎么写 ~]#kubectl explain pods ~]#kubectl explain pods.metadata #查看其中的metadata字段 命令:kubectl api-versions 打印k8s上的所有的资源群组及其版本号 查看一个组下所有资源 kubectl api-resources --api-group=apps
打印Pod完整的资源规范,通过status字段了解 kubectl get TYPE NAME -o yaml|json #例如 kubectl get pods demoapp -o yaml kubectl get pods demoapp -o json 打印Pod资源的详细状态 kubectl describe TYPE NAME #例如 kubectl describe pods demoapp 获取Pod中容器应用的日志 kubectl logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER] --all-containers #显示所有容器 --tail=N #显示多少行 #例如 kubectl logs demoapp -c demoapp #多容器指定哪个容器 kubectl logs demoapp #单容器,不用指定哪个容器(如果多容器,会显示第一个容器) 命令:kubectl exec kubectl exec (POD | TYPE/NAME) [-c CONTAINER] [flags] -- COMMAND [args...] [options] -it:打开交互式接口时使用 #例如 #容器内部执行netstat -tnl命令, 有多个容器加上-c [root@master01 ~]#kubectl exec demoapp -- netstat -tnl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN #进入容器内部,指定运行sh [root@master01 ~]#kubectl exec -it demoapp -- /bin/sh [root@demoapp /]# ifconfig
镜像下载策略
镜像下载策略: imagePullPolicy: Always #永远下载 IfNotPresent #如果没有就下载 Never #永远不下载,等用户手动下载 默认:IfNotPresent 例外:Image Tag为latest时,在Always或IfNotPresent策略下,都会重新下载; #例 ~]#vim pod-demoapp.yaml apiVersion: v1 kind: Pod metadata: name: demoapp # Pod的标识名,在名称空间中必须惟一; namespace: default # 该Pod所属的名称空间,省略时使用默认名称空间default; spec: containers: # 定义容器,它是一个列表对象,可包括多个容器的定义,至少得有一个; - name: demoapp # 容器名称,必选字段,在当前Pod中必须惟一; image: ikubernetes/demoapp:v1.0 # 创建容器时使用的镜像; imagePullPolicy: IfNotPresent #镜像拉取策略
Pod的相位
Pending:没有任何节点满足调度条件,或能运行该pod时,导致scheduler调度无法完成 如果是作业类应用,执行完任务会出现成功,失败两种状态 服务类应用也可能处于失败状态,所有任务都启动不起来(一直重启,但都失败了) Unknown:apiserver接收不到kubectl的报告,kubectl维护的pod信息变为未知 #kubectl有自愈能力,任何pod中的容器启动失败都会通过重启解决问题
容器的状态
Pod的重启策略:决定了容器终止后是否应该重启
◼ Always:无论何种exit code,都要重启容器 ◼ OnFailure:仅在exit code为非0值(即错误退出)时才重启容器 ◼ Never:无论何种exit code,都不重启容器 #默认是Always #例 [root@master01 ~]#vim pod-demoapp.yaml apiVersion: v1 kind: Pod metadata: name: demoapp # Pod的标识名,在名称空间中必须惟一; namespace: default # 该Pod所属的名称空间,省略时使用默认名称空间default; spec: containers: # 定义容器,它是一个列表对象,可包括多个容器的定义,至少得有一个; - name: demoapp # 容器名称,必选字段,在当前Pod中必须惟一; image: ikubernetes/demoapp:v1.0 # 创建容器时使用的镜像; imagePullPolicy: IfNotPresent #镜像拉取策略 restartPolicy: Always #注意:有些字段创建后不允许修改,有些字段创建后允许时时修改 [root@master01 ~]#kubectl apply -f pod-demoapp.yaml pod/demoapp configured
容器配置参数: 环境变量: 1、启动容器时,自定义要运行的命令及选项、参数; Dockerfile, CMD, ENTRYPOINT 2、通过环境进行配置; Dockerfile, entrypoint.sh脚本来代理预处理环境变量 3、将配置焙进Image,重制Image; 4、将配置文件放置在卷上,由容器通过卷加载; 卷:ConfigMap/Secret 命令:kubectl run 创建并运行Pod #--dry-run=client以client形式做测试,不执行,以yaml格式输出 kubectl run mydb --image=mysql:8.0 --dry-run=client -o yaml kubectl run wordpress --image=wordpress:6.4-apache -n default --dry-run=client -o yaml 主机端口: 将Pod所在的主机的某个端口与容器的端口建立映射关系#外部不能访问pod端口,通过映射就能访问 External Client --> hostIP:hostPort --> podIP:containerPort #例如:yaml格式如下 containers: - name: ... ports: - name: NAME containerPort: ... #容器端口 #映射到节点的端口(调度器scheduler找一个不占用该端口的节点) hostPort: ... #例 ]#vim pod-demo-with-cmd-and-args.yaml apiVersion: v1 kind: Pod metadata: name: pod-demo-with-cmd-and-args namespace: default spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent command: ['/bin/sh','-c'] #自定义命令 args: ['python3 /usr/local/bin/demo.py -p 8080'] #自定义传给命令的参数 ]#kubectl apply -f pod-demo-with-cmd-and-args.yaml #定义mysql容器环境变量 ]#vim pod-mydb.yaml apiVersion: v1 kind: Pod metadata: name: mydb namespace: default spec: containers: - name: mydb image: mysql:8.0 env: #把密码写在这里不安全,这里只是做演示 - name: MYSQL_RANDOM_ROOT_PASSWORD #超级用户账号 value: 1 - name: MYSQL_DATABASE value: wpdb - name: MYSQL_USER value: wpuser - name: MYSQL_PASSWORD value: magedu.com ]#kubectl apply -f pod-mydb.yaml ]#vim wordpress.yaml apiVersion: v1 kind: Pod metadata: name: wordpress namespace: default spec: containers: - name: wordpress image: wordpress:6.4-apache env: - name: WORDPRESS_DB_HOST value: '10.244.3.8' - name: WORDPRESS_DB_NAME value: wpdb - name: WORDPRESS_DB_USER value: wpuser - name: WORDPRESS_DB_PASSWORD value: magedu.com #pod地址只在集群上可达,集群外访问不到,这里通过节点和pod端口做映射 ports: #把容器的80端口映射到节点的8080端口,这样外部可以访问(正常应该通过service实现) - name: http containerPort: 80 hostPort: 8080 ]#kubectl apply -f wordpress.yaml #查找对应wordpress节点在哪 kubectl get pods -o wide #浏览器输入节点ip:8080即可访问wordpress #删除节点 ]#kubectl delete -f wordpress.yaml
Container Probe (探测): 周期性向容器发起探测请求 StartupProbe: 应对启动过程较长的应用而提供,探针成功后退出 LivenessProbe:存活状态,用于判定容器进程是否健康运行; 影响:判定为不健康的Pod,会被kubelet根据重启策略进行处理,重启; ReadinessProbe:就绪状态,用于判定容器进程是否已经初始化完成,并可向用户提供服务; 影响:判定为未就绪的Pod,以该Pod为后端端点的Service,不予调度流量给该Pod; 成功阈值:1 failure状态下,满足连续success的次数之后,即被判定为成功; 失败阈值:3 success状态下,满足连续failure的次数之后,即被判定为失败; Startup Probe和Liveness Probe ◼ Startup探针主要是为了应对启动过程较长的应用而提供 ◼ Startup探针成功后将退出,并切换为使用Liveness探针 #如果一直成功,突然失败,超过阈值将会重启容器,再次启用Startup探针
探针配置参数 #每种探针都支持下面几种参数 ◼ initialDelaySeconds:首次探测的延迟时长 ◼ periodSeconds:探测周期时长 ◼ timeoutSeconds:单次探测的超时时长 ◼ successThreshold:成功阈值 ◼ failureThreshold:失败阈值 以Liveness Probe为例来看上面几个参数的意义
探测的方式: tcpSocket httpGet exec:运行此处自定义的命令,根据命令的退出码,来判定其健康状态; #例:(了解) ]#vim startup-exec-demo.yaml apiVersion: v1 kind: Pod metadata: name: startup-exec-demo namespace: default spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent startupProbe: #启动探针(成功就退出)一个容器可以也应该同时存在多种探针(就绪和存活都有) exec: #探针类型,下面为执行的命令 command: ['/bin/sh', '-c', '[ "$(/usr/bin/curl -s http://127.0.0.1/livez)" == "OK" ]'] initialDelaySeconds: 0 #首次探测延迟0s failureThreshold: 3 #失败阈值3 periodSeconds: 5 #每隔5s探测一次 #例: 使用exec探测 ]#vim liveness-exec-demo.yaml apiVersion: v1 kind: Pod metadata: name: liveness-exec-demo namespace: default spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent livenessProbe: #一般一个容apiVersion: v1 kind: Pod metadata: name: liveness-tcpsocket-demo namespace: default spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 securityContext: capabilities: add: - NET_ADMIN livenessProbe: tcpSocket: port: http periodSeconds: 5 initialDelaySeconds: 5器同时存在多种探针 exec: #command: ['/bin/sh', '-c', '[ "$(curl -s 127.0.0.1/livez)" == "OK" ]'] command: ['/bin/sh', '-c', '[ "$(/usr/bin/curl -s http://127.0.0.1/livez)" == "OK" ]'] initialDelaySeconds: 5 #首次探测延迟5s timeoutSeconds: 1 #超时时长1s periodSeconds: 5 #每隔5s探测一次 ]#kubectl apply -f liveness-exec-demo.yaml #查看探针状态,重启计数 ]#kubectl describe pods liveness-exec-demo #查看重启计数 ]#kubectl get pods -o wide #例: 使用tcp探测 ]#vim liveness-tcpsocket-demo.yaml apiVersion: v1 kind: Pod metadata: name: liveness-tcpsocket-demo namespace: default spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent ports: - name: http #被引用 containerPort: 80 securityContext: #安全上下文,赋予容器内部特权能力(可以看iptables) capabilities: add: - NET_ADMIN livenessProbe: tcpSocket: #发tcp请求第一次,只要对方返回就算成功 port: http #应用上面的http端口80 periodSeconds: 5 initialDelaySeconds: 5 #首次探测延迟5s #例: 七层探测 ]#vim liveness-httpget-demo.yaml apiVersion: v1 kind: Pod metadata: name: liveness-httpget-demo namespace: default spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent livenessProbe: httpGet: #请求如果是200就是成功的 path: '/livez' #向本机路径 port: 80 scheme: HTTP #使用http协议 initialDelaySeconds: 5 #例: readiness探针 ]#vim readiness-httpget-demo.yaml apiVersion: v1 kind: Pod metadata: name: readiness-httpget-demo namespace: default labels: name: readiness-httpget-demo spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent readinessProbe: httpGet: path: '/readyz' port: 80 scheme: HTTP initialDelaySeconds: 5 timeoutSeconds: 2 periodSeconds: 5 failureThreshold: 5 restartPolicy: Always #启动对应service,当探针异常就不调度请求给该Pod,service会摘掉该节点 #当探针异常恢复后,service会把该节点加入
Pod及容器的安全上下文 一组用来决定容器是如何创建和运行的约束条件,这些条件代表创建和运行容器时使用的运行时参数 给了用户为Pod或容器定义特权和访问控制机制 Pod和容器的安全上下文设置主要包括以下几个方面 自主访问控制DAC 容器进程运行身份及资源访问权限 Linux Capabilities seccomp AppArmor SELinux Privileged Mode Privilege Escalation #常用 Pod级别: runAsUser #以指定用户身份 runAsGroup #以指定组运行 runAsNonRoot #以非管理员身份运行 sysctls #运行时改pod内的内核参数 容器级别: runAsUser runAsGroup runAsNonRoot readOnlyRootFilesystem #限制根文件系统为只读 privileged <boolean> #容器运行成特权模式 capabilities <Capabilities> #开放特定的内核特权给当前容器 NET_ADMIN CHOWN #改变文件属主属组的权限(默认具有CHOWN) SYS_ADMIN #仅次于管理员的身份 ... #例: ]#vim securitycontext-capabilities-demo.yaml apiVersion: v1 kind: Pod metadata: name: securitycontext-capabilities-demo namespace: default spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent command: ["/bin/sh","-c"] args: ["/sbin/iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80 && /usr/bin/python3 /usr/local/bin/demo.py"] securityContext: capabilities: add: ['NET_ADMIN'] #drop: ['CHOWN'] #移除特权
资源需求和资源限制 资源需求(requests) 定义需要系统预留给该容器使用的资源最小可用值 容器运行时可能用不到这些额度的资源,但用到时必须确保有相应数量的资源可用 资源需求的定义会影响调度器的决策 资源限制(limits) 定义该容器可以申请使用的资源最大可用值,超出该额度的资源使用请求将被拒绝 该限制需要大于等于requests的值,但系统在其某项资源紧张时,会从容器那里回收其使用的超出其requests值的那部 分 #cpu可用要回来,但是被使用的内部不能要回来(会导致程序崩溃)。所以建议资源需求和资源限制保持一致 #如果什么都不设定,那么任务优先级是最低的 requests和limits定义在容器级别,主要围绕cpu、memory、hugepages和ephemeral-storage四种资源 Extended resources 所有那些不属于kubernetes.io域的资源,即为扩展资源,例如“nvidia.com/gpu” 又存在节点级别和集群级别两个不同级别的扩展资源 Pod的QoS类别: BestEffort: 最低(只要空闲就让你运行) 未定义requests和limits Burstable Garanteed:最高 cpu.requests == cpu.limits #需求等于限制 memory.ruquests == memroy.limits CPU资源单位: 1 == 1000m 100m <= 总体上单个核心的10% (可以分散到各个cpu上) 内存资源单位: Ki, Mi, Gi, ... #例: apiVersion: v1 kind: Pod metadata: name: stress-pod spec: containers: - name: stress image: ikubernetes/stress-ng #压测镜像 command: ["/usr/bin/stress-ng", "-c 1", "-m 1", "--metrics-brief"] resources: requests: #需求,要预留的 memory: "128Mi" cpu: "200m" limits: memory: "512Mi" cpu: "400m"
多容器Pod: containers: - name: ... image: ... - name: ... image: ... 运行核心业务程序的容器:主容器, main container 其它容器:辅助容器 Sidecar #其他各种类型,例流量统计,所有请求都先经过它 Ambassador#大使容器,代主容器去访问外部环境(主容器没有访问外部对应功能时,直接访问大使容器) Adpater #适配器容器,适配器不兼容外部请求,通过Adpater来接受请求,再请求主容器 Init Container模式 #初始化容器 为定义在containers字段中的容器,执行初始化任务,因此,初始化容器成功运行并退出后,常规容器才能启动、运行;而且,如果存在多个初始化容器,那么他们将以串行方式运行,且全部都成功退出,常规容器才能启动; 任何一个初始化容器启动失败,那么整个pod就失败了 #格式: initContainers: #允许多个(如果多个,串行运行),和container同一级别 - name: ... image: ... - name: ... image: ... container: #常规容器 - name: ... image: ... - name: ... image: ... #例: ]#vim init-container-demo.yaml apiVersion: v1 kind: Pod metadata: name: init-container-demo namespace: default spec: initContainers: - name: iptables-init image: ikubernetes/admin-box:latest imagePullPolicy: IfNotPresent command: ['/bin/sh','-c'] #pod内核添加规则,访问8080都跳转至80端口 args: ['iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80'] securityContext: capabilities: add: - NET_ADMIN #给予网络管理员权限 containers: #常规容器 - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 #apply -f运行后,kubectl get pods会看到init:0/1表示初始化阶段,初始化容器1个,完成后运行常规容器
终止
从概念上讲,存储卷是可供Pod中的所有容器访问的目录
Pod规范中声明的存储卷来源决定了目录的创建方式、使用的存储介质以及目录的初始内容
存储卷插件(存储驱动)决定了支持的后端存储介质或存储服务,例如hostPath插件使用宿主机文件系统,而nfs插件则对接指定的NFS存储服务等
kubelet内置支持多种存储卷插件
Pod在规范中需要指定其包含的卷以及这些卷在容器中的挂载路径
存储卷对象并非Kubernetes系统一等公民
它定义在Pod上,因而生命周期与Pod相同,这意味着
Pod中的所有卷都是在创建Pod时一并被创建
删除Pod时,其上的所有卷(定义)亦会同时被删除
另一方面,其后端的存储及相关数据的生命周期通常要取决于存储介质
In-Tree存储卷插件 临时存储卷 #删掉pod,数据也会被删掉.通常在pod所在节点的内存上或者磁盘上 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类的存储插件
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> # 挂载卷的传播模式;
#通常只能用于某些特殊场景中 同一Pod内的多个容器间文件共享 作为容器数据的临时存储目录用于数据缓存系统 配置参数 medium:此目录所在的存储介质的类型,可用值为“default”或“Memory” sizeLimit:当前存储卷的空间限额,默认值为nil,表示不限制 #例 apiVersion: v1 kind: Pod metadata: name: pods-with-emptydir-vol spec: containers: - image: ikubernetes/admin-box:v1.2 name: admin command: ["/bin/sh", "-c"] args: ["sleep 99999"] resources: {} volumeMounts:#卷挂载在/data下 - name: data mountPath: /data - image: nginx:alpine name: nginx resources: {} volumeMounts:#卷挂载在/var/www/html下 - name: data mountPath: /usr/share/nginx/html/ volumes: #卷 - name: data emptyDir: medium: Memory sizeLimit: 16Mi #创建完成后,即可在admin容器的/data目录生成测试数据,而后在nginx容器中,通过挂载点/usr/share/nginx/html/进行测试访问
hostPath卷 ◼ 将Pod所在节点上的文件系统的某目录用作存储卷 ◼ 数据的生命周期与节点相同 配置参数 ◼ path:指定工作节点上的路径,必选字段 ◼ type:指定节点之上存储类型 #例 apiVersion: v1 kind: Pod metadata: name: volumes-hostpath-demo spec: containers: - name: redis image: redis:alpine volumeMounts: - mountPath: /data name: redisdata volumes: - name: redisdata hostPath: path: /appsdata/redis/ #宿主机上的路径 type: DirectoryOrCreate #不存在就创建 #如果当前pod被删,下次还想部署到相同节点,使用同一卷,可以指定spec下追加nodename apiVersion: v1 kind: Pod metadata: name: volumes-hostpath-demo spec: nodename: 节点主机名 #追加该行 ...
type种类如下图
NFS Server的目录导出方法: /data/nfs/ 172.29.0.0/16(rw,async,no_subtree_check,no_root_squash) Server: nfs-kernel-server #安装包 Worker Nodes: nfs-common #安装包 #准备一台机器,安装nfs服务器(ubuntu上程序包叫nfs-kernel-server) [root@ubuntu ~]#apt update && apt install nfs-kernel-server -y [root@ubuntu ~]#mkdir -pv /data/nfs #把该路径作为导出目录 [root@ubuntu ~]#vim /etc/exports #NFS Server的目录导出方法:(给10.0.0.0/16地址使用) /data/nfs/ 10.0.0.0/16(rw,async,no_subtree_check,no_root_squash) #查看状态 [root@ubuntu ~]#systemctl status nfs-server.service #重新导出下,让配置生效 [root@ubuntu ~]#exportfs -arv exporting 10.0.0.0/16:/data/nfs #每个节点安装包,来挂载nfs服务 [root@node03 ~]#apt install -y nfs-common #一台机器挂载测试 [root@node03 ~]#mount 10.0.0.155:/data/nfs /mnt #不需要手动挂,卸载掉 [root@node03 /]#umount /mnt #例 [root@master01 volumes]#vim pod-with-nfs-vol.yaml apiVersion: v1 kind: Pod metadata: name: redis-nfs-vol spec: containers: - name: redis image: redis:7-alpine imagePullPolicy: IfNotPresent volumeMounts: - name: redisdata mountPath: /data volumes: - name: redisdata nfs: server: 10.0.0.155 #nfs服务器地址 path: /data/nfs #真正文件系统导出来的路径 [root@master01 volumes]#kubectl apply -f pod-with-nfs-vol.yaml #进入容器 [root@master01 volumes]#kubectl exec -it redis-nfs-vol -- /bin/sh /data # redis-cli 127.0.0.1:6379> SET hi "Hi from MageEdu" OK 127.0.0.1:6379> BGSAVE Background saving started 127.0.0.1:6379> exit /data # ls dump.rdb #nfs服务器上查看是否有对应文件 [root@ubuntu ~]#ls /data/nfs dump.rdb #删除对应pod [root@master01 volumes]#kubectl delete pods redis-nfs-vol #修改yaml文件,创建到其他节点上 [root@master01 volumes]#vim pod-with-nfs-vol.yaml ... spec: nodeName: node02 ... [root@master01 volumes]#kubectl apply -f pod-with-nfs-vol.yaml #进入容器查看redis里面数据是否和node3上创建的相同