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, nskubectl 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位置上的配置文件单个配置文件,可以存在多个资源对象:#通过---进行隔开 apiVersionkind ...---apiVersionkind ....--- #例: #创建名称空间 [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: nullname: 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 yamlkubectl 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, ENTRYPOINT2、通过环境进行配置;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 yamlkubectl 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: NAMEcontainerPort: ... #容器端口#映射到节点的端口(调度器scheduler找一个不占用该端口的节点) hostPort: ... #例 ]#vim pod-demo-with-cmd-and-args.yaml apiVersion: v1 kind: Pod metadata:name: pod-demo-with-cmd-and-argsnamespace: default spec:containers:- name: demoimage: ikubernetes/demoapp:v1.0imagePullPolicy: IfNotPresentcommand: ['/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: mydbnamespace: default spec:containers:- name: mydbimage: mysql:8.0env: #把密码写在这里不安全,这里只是做演示- name: MYSQL_RANDOM_ROOT_PASSWORD #超级用户账号value: 1- name: MYSQL_DATABASEvalue: wpdb- name: MYSQL_USERvalue: wpuser- name: MYSQL_PASSWORDvalue: magedu.com ]#kubectl apply -f pod-mydb.yaml ]#vim wordpress.yaml apiVersion: v1 kind: Pod metadata:name: wordpressnamespace: default spec:containers:- name: wordpressimage: wordpress:6.4-apacheenv:- name: WORDPRESS_DB_HOSTvalue: '10.244.3.8'- name: WORDPRESS_DB_NAMEvalue: wpdb- name: WORDPRESS_DB_USERvalue: wpuser- name: WORDPRESS_DB_PASSWORDvalue: magedu.com#pod地址只在集群上可达,集群外访问不到,这里通过节点和pod端口做映射ports: #把容器的80端口映射到节点的8080端口,这样外部可以访问(正常应该通过service实现)- name: httpcontainerPort: 80hostPort: 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;成功阈值:1failure状态下,满足连续success的次数之后,即被判定为成功;失败阈值:3success状态下,满足连续failure的次数之后,即被判定为失败;Startup Probe和Liveness Probe ◼ Startup探针主要是为了应对启动过程较长的应用而提供 ◼ Startup探针成功后将退出,并切换为使用Liveness探针 #如果一直成功,突然失败,超过阈值将会重启容器,再次启用Startup探针
探针配置参数 #每种探针都支持下面几种参数 ◼ initialDelaySeconds:首次探测的延迟时长 ◼ periodSeconds:探测周期时长 ◼ timeoutSeconds:单次探测的超时时长 ◼ successThreshold:成功阈值 ◼ failureThreshold:失败阈值 以Liveness Probe为例来看上面几个参数的意义
探测的方式:tcpSockethttpGetexec:运行此处自定义的命令,根据命令的退出码,来判定其健康状态;#例:(了解) ]#vim startup-exec-demo.yaml apiVersion: v1 kind: Pod metadata:name: startup-exec-demonamespace: default spec:containers:- name: demoimage: ikubernetes/demoapp:v1.0imagePullPolicy: IfNotPresentstartupProbe: #启动探针(成功就退出)一个容器可以也应该同时存在多种探针(就绪和存活都有)exec: #探针类型,下面为执行的命令command: ['/bin/sh', '-c', '[ "$(/usr/bin/curl -s http://127.0.0.1/livez)" == "OK" ]']initialDelaySeconds: 0 #首次探测延迟0sfailureThreshold: 3 #失败阈值3periodSeconds: 5 #每隔5s探测一次#例: 使用exec探测 ]#vim liveness-exec-demo.yaml apiVersion: v1 kind: Pod metadata:name: liveness-exec-demonamespace: default spec:containers:- name: demoimage: ikubernetes/demoapp:v1.0imagePullPolicy: IfNotPresentlivenessProbe: #一般一个容apiVersion: v1 kind: Pod metadata:name: liveness-tcpsocket-demonamespace: default spec:containers:- name: demoimage: ikubernetes/demoapp:v1.0imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80securityContext:capabilities:add:- NET_ADMINlivenessProbe:tcpSocket:port: httpperiodSeconds: 5initialDelaySeconds: 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 #首次探测延迟5stimeoutSeconds: 1 #超时时长1speriodSeconds: 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-demonamespace: default spec:containers:- name: demoimage: ikubernetes/demoapp:v1.0imagePullPolicy: IfNotPresentports:- name: http #被引用containerPort: 80securityContext: #安全上下文,赋予容器内部特权能力(可以看iptables) capabilities:add:- NET_ADMINlivenessProbe:tcpSocket: #发tcp请求第一次,只要对方返回就算成功port: http #应用上面的http端口80periodSeconds: 5initialDelaySeconds: 5 #首次探测延迟5s#例: 七层探测 ]#vim liveness-httpget-demo.yaml apiVersion: v1 kind: Pod metadata:name: liveness-httpget-demonamespace: default spec:containers:- name: demoimage: ikubernetes/demoapp:v1.0imagePullPolicy: IfNotPresentlivenessProbe:httpGet: #请求如果是200就是成功的path: '/livez' #向本机路径port: 80scheme: HTTP #使用http协议initialDelaySeconds: 5#例: readiness探针 ]#vim readiness-httpget-demo.yaml apiVersion: v1 kind: Pod metadata:name: readiness-httpget-demonamespace: defaultlabels:name: readiness-httpget-demo spec:containers:- name: demoimage: ikubernetes/demoapp:v1.0imagePullPolicy: IfNotPresentreadinessProbe:httpGet:path: '/readyz'port: 80scheme: HTTPinitialDelaySeconds: 5timeoutSeconds: 2periodSeconds: 5failureThreshold: 5restartPolicy: Always #启动对应service,当探针异常就不调度请求给该Pod,service会摘掉该节点 #当探针异常恢复后,service会把该节点加入
Pod及容器的安全上下文一组用来决定容器是如何创建和运行的约束条件,这些条件代表创建和运行容器时使用的运行时参数给了用户为Pod或容器定义特权和访问控制机制 Pod和容器的安全上下文设置主要包括以下几个方面自主访问控制DAC容器进程运行身份及资源访问权限Linux CapabilitiesseccompAppArmorSELinuxPrivileged ModePrivilege Escalation#常用 Pod级别:runAsUser #以指定用户身份runAsGroup #以指定组运行runAsNonRoot #以非管理员身份运行sysctls #运行时改pod内的内核参数 容器级别:runAsUserrunAsGrouprunAsNonRootreadOnlyRootFilesystem #限制根文件系统为只读privileged <boolean> #容器运行成特权模式capabilities <Capabilities> #开放特定的内核特权给当前容器 NET_ADMINCHOWN #改变文件属主属组的权限(默认具有CHOWN)SYS_ADMIN #仅次于管理员的身份 ... #例: ]#vim securitycontext-capabilities-demo.yaml apiVersion: v1 kind: Pod metadata:name: securitycontext-capabilities-demonamespace: default spec:containers:- name: demoimage: ikubernetes/demoapp:v1.0imagePullPolicy: IfNotPresentcommand: ["/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和limitsBurstableGaranteed:最高cpu.requests == cpu.limits #需求等于限制memory.ruquests == memroy.limits CPU资源单位:1 == 1000m100m <= 总体上单个核心的10% (可以分散到各个cpu上)内存资源单位:Ki, Mi, Gi, ... #例: apiVersion: v1 kind: Pod metadata:name: stress-pod spec:containers:- name: stressimage: 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-demonamespace: default spec:initContainers:- name: iptables-initimage: ikubernetes/admin-box:latestimagePullPolicy: IfNotPresentcommand: ['/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: demoimage: ikubernetes/demoapp:v1.0imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 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和FlexVolumeOut-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.2name: admincommand: ["/bin/sh", "-c"]args: ["sleep 99999"]resources: {}volumeMounts:#卷挂载在/data下- name: datamountPath: /data- image: nginx:alpinename: nginxresources: {}volumeMounts:#卷挂载在/var/www/html下- name: datamountPath: /usr/share/nginx/html/ volumes: #卷 - name: dataemptyDir:medium: MemorysizeLimit: 16Mi#创建完成后,即可在admin容器的/data目录生成测试数据,而后在nginx容器中,通过挂载点/usr/share/nginx/html/进行测试访问
hostPath卷 ◼ 将Pod所在节点上的文件系统的某目录用作存储卷 ◼ 数据的生命周期与节点相同 配置参数 ◼ path:指定工作节点上的路径,必选字段 ◼ type:指定节点之上存储类型#例 apiVersion: v1 kind: Pod metadata:name: volumes-hostpath-demo spec:containers:- name: redisimage: redis:alpinevolumeMounts:- mountPath: /dataname: redisdata volumes:- name: redisdatahostPath: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: redisimage: redis:7-alpineimagePullPolicy: IfNotPresentvolumeMounts:- name: redisdatamountPath: /datavolumes:- name: redisdatanfs: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上创建的相同