Kubernetes总结笔记
2023-03-16 21:50:40 2 举报
AI智能生成
k8s学习总结
作者其他创作
大纲/内容
Pod的资源清单
Pod生命周期起始于Pending状态,如果至少一个主要容器正常启动则进入Running状态,之后取决于Pod中是否有容器以失败状态结束而进入Succeeded或者Failed状态
如果节点死掉,Pod会在给定超时期限结束后删除
Pod在其生命周期中只会被调度一次。一旦Pod被调度到某个节点,Pod会一直在该节点运行,直到Pod停止或者被终止
Pod可以被相同的Pod替换掉,名字可以不变,但是其UID会不同
Pod是个相对临时性的实体,会被创建、赋予一个唯一的ID(UID)
控制器(通过apiserver监控集群的状态)管理Pod的创建及删除
Pod被删除或替换,期内的相关容器及对象也会被删除或重建
Pod生命期
Pod的Status字段是一个PodStatus对象,其中包含一个phase字段
Pod阶段(Phase)
三种状态:Waiting(等待)、Running(运行中)和 Terminated(已终止)
要检查 Pod 中容器的状态,你可以使用 kubectl describe pod <pod 名称>
使用 kubectl 来查询会看到一个 Reason 字段,其中给出了容器处于等待状态的原因
Waiting (等待)
表明容器正在执行状态并且没有问题发生。 如果配置了 postStart 回调,那么该回调已经执行且已完成。
Running(运行中)
如果容器配置了 preStop 回调,则该回调会在容器进入 Terminated 状态之前执行
Terminated(已终止)
容器状态
Pod 的 spec 中包含一个 restartPolicy 字段。其值为Always、OnFailure 和 Never。默认值是 Always。
restartPolicy只适用于同一节点上的容器。当容器重启,kubelet累计延时时间,最多延时5分钟。容器正常运行10分钟后重置重启延时时间。
容器重启策略
PodStatus 对象,其中包含一个 PodConditions 数组
PodScheduled: Pod 已经被调度到某节点;ContainersReady:Pod 中所有容器都已就绪;Initialized: 所有的 Init 容器 都已成功启动;Ready: Pod 可以为请求提供服务,并且应该被添加到对应服务的负载均衡池中。
Pod状况
kubelet 调用由容器实现的 Handler (处理程序)进行诊断:ExecAction: 在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。TCPSocketAction: 对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开,则诊断被认为是成功的。HTTPGetAction: 对容器的 IP 地址上指定端口和路径执行 HTTP Get 请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的。
每次探测都将获得以下三种结果之一:Success(成功):容器通过了诊断。Failure(失败):容器未通过诊断。Unknown(未知):诊断失败,因此不会采取任何行动。
livenessProbe:容器是否正在运行。如果容器未运行,则kubelet杀死容器,并根据重启策略进一步操作
readinessProbe:容器是否准备好提供服务。如果失败,控制器将从端点列表中删除该Pod的IP地址。
startupProbe:容器中的应用是否已启动。如果启动该探针,只有此探针成功后,其他探针才会被使用。如果启动探测失败,kubelet杀死容器,根据重启策略进行重启。
三种类型的探针
容器探针
使用kubectl手动删除Pod,该Pod的终止时限为30S。超过30s仍未删除,将调用kill命令强制删除
如果定义了preStop回调,超出终止时限后,kubelet会一次性增加2秒钟终止时限
Pod 中的容器会在不同时刻收到 TERM 信号,接收顺序也是不确定的。 如果关闭的顺序很重要,可以考虑使用 preStop 回调逻辑来协调。
使用 kubectl describe 来查验你正在删除的 Pod,该 Pod 会显示为 \"Terminating\" (正在终止)
kubelet启动终止逻辑后,控制面会将Pod从对应的端点列表中引出,并停止所有请求及服务
kubectl delete 命令支持 --grace-period=<seconds> 选项, 设定自定义的期限值设置 --grace-period=0 的同时额外设置 --force 参数才能发起强制删除请求。 意味着立即从 API 服务器删除 Pod
Pod的终止
Pod生命周期
Pod中可以有一个或多个先于应用容器的Init容器
它们总是运行到完成
每个都必须在下一个启动前成功完成
如果restartPolicy的值为Never,并且Init容器启动失败,则整个Pod状态设置为失败
如果Pod的Init容器启动失败,kubelet会不断的重启Init容器直到成功为止
init容器的状态在status.initContainerStatuses字段以容器状态数组的格式返回
设置Init容器需在Pod的spec中添加initContainers字段
Init容器支持应用容器的全部字段和特性,包括资源限制、数据卷和安全设置
但是对资源请求和限制的处理稍有不同
Init容器不支持lifecycle、livenessProbe、redinessProbe、startupProbe,因为Init必须在Pod就绪之前完成
如果一个pod指定多个Init容器,会按顺序逐个运行。前一个init运行成功后下一个能运行。当所有Init容器运行完成后,Pod才会初始化应用容器
与应用容器的不同之处
Init容器原理
例如:没必要为了安装sed、awk、python或dig等工具而去From一个镜像
Init容器可以包含一些安装过程中应用容器中不存在的实用工具和个性化代码
Init容器可以安全的运行相关工具,避免这些工具导致应用镜像的安全性降低
应用镜像的创建和部署可以独自执行,不必联合构建为一个独立的应用镜像
Init容器可以访问应用容器不能访问的Secret权限
Init容器可以阻塞和延迟应用容器的启动,直到满足先决条件。一旦前置条件满足,Pod内的所有应用容器会并行启动
一些使用Init容器的示例
Init容器具有与应用容器分离的单独镜像,启动相关代码具有以下优势
定义了一个具有 2 个 Init 容器的简单 Pod。 第一个等待 myservice 启动, 第二个等待 mydb 启动。 一旦这两个 Init容器 都启动完成,Pod 将启动 spec 节中的应用容器。
输出:pod/myapp-pod created
启动Pod:kubectl apply -f myapp.yaml
输出:NAME READY STATUS RESTARTS AGEmyapp-pod 0/1 Init:0/2 0 6m初始化中
检查其状态:kubectl get -f myapp.yaml
输出类似于:Name: myapp-podNamespace: default[...]Labels: app=myappStatus: Pending[...]Init Containers: init-myservice:[...] State: Running[...] init-mydb:[...] State: Waiting Reason: PodInitializing Ready: False[...]Containers: myapp-container:[...] State: Waiting Reason: PodInitializing Ready: False[...]Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 16s 16s 1 {default-scheduler } Normal Scheduled Successfully assigned myapp-pod to 172.17.4.201 16s 16s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulling pulling image \"busybox\" 13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulled Successfully pulled image \"busybox\" 13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Created Created container with docker id 5ced34a04634; Security:[seccomp=unconfined] 13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Started Started container with docker id 5ced34a04634
查看更多详细信息:kubectl describe -f myapp.yaml
发现Init容器正在等待名称为myservice和mydb的Service
查看Pod内Init容器的日志:kubectl logs myapp-pod -c init-myservice # 查看第一个 Init 容器kubectl logs myapp-pod -c init-mydb # 查看第二个 Init 容器
---apiVersion: v1kind: Servicemetadata: name: myservicespec: ports: - protocol: TCP port: 80 targetPort: 9376---apiVersion: v1kind: Servicemetadata: name: mydbspec: ports: - protocol: TCP port: 80 targetPort: 9377
创建相关的Service的配置文件
输出:service \"myservice\" createdservice \"mydb\" created
创建Service的命令:kubectl create -f services.yaml
输出:NAME READY STATUS RESTARTS AGEmyapp-pod 1/1 Running 0 9m运行状态
再查看Pod状态:kubectl get -f myapp.yaml
Init容器的使用例子
使用Init容器
Init容器会在网络和数据卷初始化之后按顺序启动。
kubelet按照Init容器在Pod规约中出现的顺序依次执行
如果某容器无法启动或以错误状态退出,kubelet会根据Pod的restartPolicy策略重试
如果Pod的restartPolicy设置为“Always”,Init容器失败时会使用“OnFailure”策略
每个Init容器成功并退出后才会启动下一个Init容器
所有Init容器没有成功前,Pod不会变为Ready状态、Init容器的端口不会在Service中进行聚集。正在初始化的Pod处于Pending状态,但会将Initializing设置为false
如果Pod重启,所有的Init容器必须重新执行
Init容器只能修改容器的image字段,修改后等同于重启Pod
因为Init容器会被重启、重试或者重新执行,所以Init容器的业务处理是要幂等的。特别是基于emptyDirs写文件操作,要做好文件已存在的处理。
Init容器具有应用容器的所有字段,但是禁止使用readlinessProbe。
在 Pod 上使用 activeDeadlineSeconds 和在容器上使用 livenessProbe 可以避免 Init 容器一直重复失败。activeDeadlineSeconds 时间包含了 Init 容器启动的时间。
在 Pod 中的每个应用容器和 Init 容器的名称必须唯一
所有Init容器定义的任何特定资源的limit或request的最大值,作为Pod的有效初始limit/request
Pod 对资源的 有效 limit/request 是如下两者的较大者:1.所有应用容器对某个资源的 limit/request 之和2.对某个资源的有效初始 limit/request
Kubernetes v1.20 及更新版本:当 Init 容器的镜像发生改变或者 Init 容器的完成记录因为垃圾收集等原因被丢失时, Pod 不会被重启
Init的在Pod中的具体启动过程
Init容器
使用 拓扑分布约束(Topology Spread Constraints) 来控制 Pods 在集群内故障域 之间的分布,例如区域(Region)、可用区(Zone)、节点和其他用户自定义拓扑域。 这样做有助于实现高可用并提升资源利用率。
可以定义一个或多个 topologySpreadConstraint 来约束每个传入的 Pod 部署到集群中。maxSkew: 必须是大于零的整数,表示能容忍不同拓扑域中 Pod 数量差异的最大值。 1 意味着只允许相差 1 个 Pod。topologyKey:节点的某个 label 的 key,能代表节点所处拓扑域,可以用 Well-Known Labels,常用的是 kubernetes.io/hostname (节点维度)、topology.kubernetes.io/zone (可用区/机房 维度)。也可以自行手动为节点打上自定义的 label 来定义拓扑域,比如 rack (机架维度)、machine (物理机维度)、switch (交换机维度)。whenUnsatisfiable: 指 Pod 不满足分布约束条件时如何处理:DoNotSchedule(默认)告诉调度器不要调度(保持 Pending),类似强反亲和;ScheduleAnyway 告诉调度器继续调度,类似弱反亲和;labelSelector 用于查找匹配的 pod。匹配此标签的 Pod 将被统计,以确定相应 拓扑域中 Pod 的数量。 你可以执行 kubectl explain Pod.spec.topologySpreadConstraints 命令以 了解关于 topologySpreadConstraints 的更多信息。
需要部署label为app=foo的pod到可用区,Zone1中有两个相同标签的Pod,Zone2中没有,根据maxSkew=1的条件,两个可用区相同标签的Pod数量相差最大为1,因此新Pod将被部署到Zone2上
高级用法
多重拓扑扩展约束
将 Pod 打散调度到不同地方,可避免因软硬件故障、光纤故障、断电或自然灾害等因素导致服务不可用,以实现服务的高可用部署。https://imroc.cc/k8s/ha/pod-split-up-scheduling/
使用 podAntiAffinity
使用 topologySpreadConstraints
Kubernetes 支持两种方式将 Pod 打散调度:Pod 反亲和 (Pod Anti-Affinity)Pod 拓扑分布约束 (Pod Topology Spread Constraints)
Pod 打散调度
Pod拓扑分布约束
节点下层物理机的硬件故障集群管理员错误地删除虚拟机(实例)云提供商或虚拟机管理程序中的故障导致的虚拟机消失内核错误节点由于集群网络隔离从集群中消失由于节点资源不足导致 pod 被驱逐。
非自愿干扰(Involuntary Disruptions)
应用程序所有者的操 作包括:删除 Deployment 或其他管理 Pod 的控制器更新了 Deployment 的 Pod 模板导致 Pod 重启直接删除 Pod(例如,因为误操作)集群管理员操作包括:排空(drain)节点进行修复或升级。从集群中排空节点以缩小集群(了解集群自动扩缩)。从节点中移除一个 Pod,以允许其他 Pod 使用该节点。
自愿干扰(Voluntary Disruptions)
自愿干扰和非自愿干扰
应用程序所有者可以为每个应用程序创建 PodDisruptionBudget 对象(PDB)。 PDB 将限制在同一时间因自愿干扰导致的复制应用程序中宕机的 pod 数量。 例如,基于票选机制的应用程序希望确保运行的副本数永远不会低于仲裁所需的数量。 Web 前端可能希望确保提供负载的副本数量永远不会低于总数的某个百分比。
https://kubernetes.io/zh/docs/concepts/workloads/pods/disruptions/
干扰预算(Kubernetes v1.21 [stable])
处理干扰
干扰(Disruptions)
Pods
定义 Deployment 以创建新的 ReplicaSet、删除现有 Deployment, 并通过新的 Deployment 接收其资源。
Deployment 非常适合使用在多个副本上挂载的 ReadOnlyMany 或 ReadWriteMany 卷的无状态应用,但不适合使用 ReadWriteOnce 卷的工作负载。如果是使用 ReadWriteOnce 卷的有状态应用,请使用 StatefulSet。StatefulSet 旨在用于部署有状态应用和将数据保存到永久性存储空间(例如 Compute Engine 永久性磁盘)的聚簇应用。StatefulSet 适合部署 Kafka、MySQL、Redis、ZooKeeper 以及其他需要唯一持久身份和稳定主机名的应用。
创建名为 nginx-deployment的 Deployment。(由 .metadata.name 字段标明)该 Deployment 创建三个Pod 副本。(由 replicas 字段标明)selector 字段定义 如何查找要管理的 Pods。 template 字段包含以下子字段:Pod 使用 labels 字段打上 app: nginx 标签。Pod 模板规约(即 .template.spec 字段)指示 Pods 运行一个 nginx 容器, 该容器运行版本为 1.14.2 的 nginx Docker Hub镜像。创建一个容器并使用 name 字段将其命名为 nginx。
创建命令:kubectl apply -f nginx-deployment.yaml
输出
查看命令:kubectl get deployments
查看上线状态:kubectl rollout status deployment/nginx-deployment
查看创建的ReplicaSet:kubectl get rs
Pod-template-hash 标签说明: 不要更改此标签。Deployment 控制器将 pod-template-hash 标签添加到 Deployment 所创建或接收的 每个 ReplicaSet 。此标签可确保 Deployment 的子 ReplicaSets 不重叠。 标签是通过对 ReplicaSet 的 PodTemplate 进行哈希处理。 所生成的哈希值被添加到 ReplicaSet 选择算符、Pod 模板标签,并存在于在 ReplicaSet 可能拥有的任何现有 Pod 中。
查看Pod自动生成的Label:kubectl get pods --show-labels
创建Deployment
仅当 .spec.template发生改变时,例如模板的标签或容器镜像被更新, 才会触发 Deployment 更新。 其他更新(如对 Deployment 执行扩缩容的操作)不会触发更新动作。
修改nginx-deployments.yaml中的.spec.template.spec.containers.image 从 nginx:1.14.2 更改至 nginx:1.16.1执行:kubectl apply -f nginx-deployments.yaml
更新 Deployment 时,它创建了一个新的 ReplicaSet ,并将其扩容为 1,然后将旧 ReplicaSet 缩容到 2, 最多时 4 个 Pod在线。 然后继续对新的 ReplicaSet 扩容并对旧的 ReplicaSet 缩容。 最后, 3 个可用的副本在新的 ReplicaSet 中,旧 ReplicaSet 将缩容到 0。
更新中
查看Deployment的信息:kubectl describe deployments
在创建一个 Deployment 以生成 nginx:1.14.2 的 5 个副本,但接下来 更新 Deployment 以创建 5 个 nginx:1.16.1 的副本,而此时有 3 个nginx:1.14.2 副本已创建。在这种情况下,Deployment 会立即开始杀死 3 个 nginx:1.14.2 Pods, 并开始创建 nginx:1.16.1 Pods。它不会等待 nginx:1.14.2 的 5 个副本都创建完成 后才开始执行变更动作。
动态更新
更新Deployment
修改nginx-deployments.yaml中的.spec.template.spec.containers.image 更改至 nginx:1.161(版本好写错了)执行:kubectl apply -f nginx-deployments.yaml
卡住了
检查上线状态:kubectl rollout status deployment/nginx-deployment
deployment.apps/nginx-deployment REVISION CHANGE-CAUSE1 <none>3 <none>4 <none>
deployment.apps/nginx-deployment with revision #4Pod Template: Labels: app=nginx pod-template-hash=559d658b74 Containers: nginx: Image: nginx:1.16.1 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none>
查看历史详细信息:kubectl rollout history deployment/nginx-deployment --revision=4
检查Deployment修订历史:kubectl rollout history deployment/nginx-deployment
输出deployment.apps/nginx-deployment rolled back
查看结果
回滚之前的版本:kubectl rollout undo deployment/nginx-deployment --to-revision=4
回滚Deployment
输出:NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEnginx-deployment 10 10 10 10 50s
扩缩指令:kubectl scale deployment/nginx-deployment --replicas=10
查看自动缩放策略:kubectl get hpa
删除自动缩放策略:kubectl delete hpa NAME-OF-HPA
自动缩放:kubectl autoscale deployment/nginx-deployment --min=10 --max=15 --cpu-percent=80
根据业务场景调节HPA扩缩容灵敏度
扩缩容Deployment
在暂停和恢复执行之间应用多个修补程序,而不会触发不必要的发布操作
暂停状态的deployment,不会触发更新
暂停指令:kubectl rollout pause deployment.v1.apps/nginx-deployment
恢复指令:kubectl rollout resume deployment.v1.apps/nginx-deployment
不可以回滚处于暂停状态的 Deployment,需要先恢复其执行状态。
暂停、恢复Deployment
三种状态:Progressing(进行中)、Complete(完成)、Failed(失败)
查看Deploy的状态输出
kubectl get deployment nginx-deployment -o yaml
Deployment 创建新的 ReplicaSetDeployment 正在为其最新的 ReplicaSet 扩容Deployment 正在为其旧有的 ReplicaSet(s) 缩容新的 Pods 已经就绪或者可用(就绪至少持续了 MinReadySeconds 秒)。
Progressing状态
与 Deployment 关联的所有副本都已更新到指定的最新版本,这意味着之前请求的所有更新都已完成。与 Deployment 关联的所有副本都可用。未运行 Deployment 的旧副本。
Complete状态
设置规约中的 progressDeadlineSeconds,从而告知控制器 在 10 分钟后报告 Deployment 没有进展kubectl patch deployment.v1.apps/nginx-deployment -p '{\"spec\":{\"progressDeadlineSeconds\":600}}'
可以对其执行扩缩容、回滚到以前的修订版本等操作,或者在需要对 Deployment 的 Pod 模板应用多项调整时,将 Deployment 暂停
配额(Quota)不足就绪探测(Readiness Probe)失败镜像拉取错误权限不足限制范围(Limit Ranges)问题应用程序运行时的配置错误
Failed状态
Deployment状态
.spec.revisionHistoryLimit字段保留多少旧的ReplicaSet,默认为10
显式将此字段设置为 0 将导致 Deployment 的所有历史记录被清空,因此 Deployment 将无法回滚。
清理策略
apiVersion,kind 和 metadata 字段必须有
.spec.selector 必须匹配 .spec.template.metadata.labels
.spec.selector 是不可变的
.spec 中只有 .spec.template 和 .spec.selector 是必需的字段。
.spec.replicas 是指定要部署的Pod 的数量,可选字段。它的默认值是1。
.spec.strategy.type==Recreate,在创建新 Pods 之前,所有现有的 Pods 会被杀死
最大不可用 .spec.strategy.rollingUpdate.maxUnavailable 是一个可选字段,用来指定 更新过程中不可用的 Pod 的个数上限。该值可以是绝对数字(例如,5),也可以是 所需 Pods 的百分比(例如,10%)。百分比值会转换成绝对数并去除小数部分。 如果 .spec.strategy.rollingUpdate.maxSurge 为 0,则此值不能为 0。 默认值为 25%。例如,当此值设置为 30% 时,滚动更新开始时会立即将旧 ReplicaSet 缩容到期望 Pod 个数的70%。 新 Pod 准备就绪后,可以继续缩容旧有的 ReplicaSet,然后对新的 ReplicaSet 扩容,确保在更新期间 可用的 Pods 总数在任何时候都至少为所需的 Pod 个数的 70%。
最大峰值 .spec.strategy.rollingUpdate.maxSurge 是一个可选字段,用来指定可以创建的超出 期望 Pod 个数的 Pod 数量。此值可以是绝对数(例如,5)或所需 Pods 的百分比(例如,10%)。 如果 MaxUnavailable 为 0,则此值不能为 0。百分比值会通过向上取整转换为绝对数。 此字段的默认值为 25%。例如,当此值为 30% 时,启动滚动更新后,会立即对新的 ReplicaSet 扩容,同时保证新旧 Pod 的总数不超过所需 Pod 总数的 130%。一旦旧 Pods 被杀死,新的 ReplicaSet 可以进一步扩容, 同时确保更新期间的任何时候运行中的 Pods 总数最多为所需 Pods 总数的 130%。
.spec.strategy.type==RollingUpdate,采取 滚动更新的方式更新 Pods。你可以指定 maxUnavailable 和 maxSurge 来控制滚动更新 过程
.spec.strategy.type 值 “Recreate” 、“RollingUpdate”(默认值)
.spec.strategy 可选字段,策略指定用于用新 Pods 替换旧 Pods 的策略
值需要大于 .spec.minReadySeconds 取值
.spec.progressDeadlineSeconds 可选字段,延时报告Deployment状态的时间
指定新创建的 Pod 在没有任意容器崩溃情况下的最小就绪时间,只有超出这个时间 Pod 才被视为可用
默认值为 0(Pod 在准备就绪后立即将被视为可用)
.spec.minReadySeconds 可选字段,最短就绪时间。
旧 ReplicaSet 会消耗 etcd 中的资源,并占用 kubectl get rs 的输出
默认情况下,系统保留 10 个旧 ReplicaSet
设置为 0 意味着将清理所有副本,将无法回滚
.spec.revisionHistoryLimit 可选字段,设定要保留的旧ReplicaSet的数量
Deployment 处于暂停状态时, PodTemplateSpec 的任何修改都不会触发新的上线。
默认:不处于暂停状态
.spec.paused 可选字段,用于暂停和恢复 Deployment
Deployment规约
Deployments
确保给定数量的、完全相同的pod副本集合
建议使用 Deployment 而不是直接使用 ReplicaSet
ReplicaSet 是 ReplicationController 的后继者。二者目的相同且行为类似。优先考虑 ReplicaSet
ReplicaSet
有状态的工作负载副本集,为每个pod维护一个永久不变的ID,拥有一个唯一的顺序索引和稳定的网络身份标识StatefulSet 适合部署 Kafka、MySQL、Redis、ZooKeeper 以及其他需要唯一持久身份和稳定主机名的应用
for i in 0 1; do kubectl exec \"web-$i\" -- sh -c 'echo \"$(hostname)\" > /usr/share/nginx/html/index.html'; done给pod中的nginx的index.html赋值 各自的hostname web-0,web-1...
映射的pv,要去所在的node上去查看,因为是local本地映射
kubectl apply -f web.yaml
NAME READY STATUS RESTARTS AGEweb-0 0/1 Pending 0 0sweb-0 0/1 Pending 0 0sweb-0 0/1 ContainerCreating 0 0sweb-0 1/1 Running 0 19sweb-1 0/1 Pending 0 0sweb-1 0/1 Pending 0 0sweb-1 0/1 ContainerCreating 0 0sweb-1 1/1 Running 0 18s
顺序创建PodPod 被部署时是按照 {0 …… N-1} 的序号顺序创建的请注意在 web-0 Pod 处于 Running和Ready 状态后 web-1 Pod 才会被启动。
查看Pods的创建情况:kubectl get pods -w -l app=nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEnginx ClusterIP None <none> 80/TCP 12s
kubectl get service nginx
NAME DESIRED CURRENT AGEweb 2 1 20s
kubectl get statefulset web
创建StatefulSet
输出:statefulset.apps/web scaled
kubectl scale sts web --replicas=5
NAME READY STATUS RESTARTS AGEweb-0 1/1 Running 0 2hweb-1 1/1 Running 0 2hNAME READY STATUS RESTARTS AGEweb-2 0/1 Pending 0 0sweb-2 0/1 Pending 0 0sweb-2 0/1 ContainerCreating 0 0sweb-2 1/1 Running 0 19sweb-3 0/1 Pending 0 0sweb-3 0/1 Pending 0 0sweb-3 0/1 ContainerCreating 0 0sweb-3 1/1 Running 0 18sweb-4 0/1 Pending 0 0sweb-4 0/1 Pending 0 0sweb-4 0/1 ContainerCreating 0 0sweb-4 1/1 Running 0 19sStatefulSet 按序号索引顺序的创建每个 Pod,并且会等待前一个 Pod 变为 Running 和 Ready 才会启动下一个 Pod
kubectl get pods -w -l app=nginx
扩容
kubectl patch sts web -p '{\"spec\":{\"replicas\":3}}'
NAME READY STATUS RESTARTS AGEweb-0 1/1 Running 0 3hweb-1 1/1 Running 0 3hweb-2 1/1 Running 0 55sweb-3 1/1 Running 0 36sweb-4 0/1 ContainerCreating 0 18sNAME READY STATUS RESTARTS AGEweb-4 1/1 Running 0 19sweb-4 1/1 Terminating 0 24sweb-4 1/1 Terminating 0 24sweb-3 1/1 Terminating 0 42sweb-3 1/1 Terminating 0 42s缩容按索引倒序的顺序关闭
缩容
Pod 序号索引相反的顺序每次删除一个 Pod。在删除下一个 Pod 前会等待上一个被完全关闭
NAME STATUS VOLUME CAPACITY ACCESSMODES AGEwww-web-0 Bound pvc-15c268c7-b507-11e6-932f-42010a800002 1Gi RWO 13hwww-web-1 Bound pvc-15c79307-b507-11e6-932f-42010a800002 1Gi RWO 13hwww-web-2 Bound pvc-e1125b27-b508-11e6-932f-42010a800002 1Gi RWO 13hwww-web-3 Bound pvc-e1176df6-b508-11e6-932f-42010a800002 1Gi RWO 13hwww-web-4 Bound pvc-e11bb5f8-b508-11e6-932f-42010a800002 1Gi RWO 13h
kubectl get pvc -l app=nginx
Pod删除,但是PVC不会被删除需要手动删除
顺序终止Pod
扩缩容StatefulSet
命令方式添加更新策略:kubectl patch statefulset web -p '{\"spec\":{\"updateStrategy\":{\"type\":\"RollingUpdate\"}}}'
更新镜像:kubectl patch statefulset web --type='json' -p='[{\"op\": \"replace\
前一个更新成功后,才会开始更新下一个pod
采用倒序更新
spec.updateStrategy更新一个 StatefulSet 中的 Pod 的 container images,resource requests,以及 limits,labels 和 annotations。 RollingUpdate滚动更新是 StatefulSets 默认策略
选择这个更新策略并修改 StatefulSet 的 .spec.template 字段时,StatefulSet 控制器将不会自动的更新 Pod
On Delete 策略
pre style=\
设置分区后进行更新,只会更新比分区号>=的pod,比如partition=2,web-0、web-1不会更新,web-2会更新
partition\":0 ,全部pod都更新
添加分区
分区更新
更新StatefulSet
kubectl delete statefulset web --cascade=false
只删除 StatefulSet 而不要删除它的任何 Pod。
非级联删除后,在删除Pod,不会重新创建
非级联删除
kubectl delete statefulset web
级联删除会按照倒序删除 StatefulSet 和它的 Pod,但它并不会删除和 StatefulSet 关联的 Headless Service。必须手动删除nginx Service。
级联删除
kubectl delete pvc XXX
kubectl delete pv XXX
PersistentVolumes不会被删除,只能手动操作
删除StatefulSet
.spec.podManagementPolicy。 仅影响扩缩操作的行为。更新不受影响。
OrderedReady pod 管理策略是 StatefulSets 的默认选项。StatefulSet 控制器遵循顺序性
并行处理,不必等待上一个pod处理完成
Parallel Pod 并行进行扩缩容
StatefulSet的管理策略
StatefulSets
集群管理员创建若干 PV 卷,供用户使用
静态供应
PVC 申领必须请求某个 存储类,集群管理员必须 已经创建并配置了该类
PVC 申领指定存储类为 \"\",则相当于为自身禁止使用动态供应的卷
通过保证 DefaultStorageClass 出现在 API 服务器组件的 --enable-admission-plugins 标志值中实现这点;该标志的值可以是逗号 分隔的有序列表。
管理员需要在 API 服务器上启用 DefaultStorageClass
动态供应
持久卷(PersistentVolume,PV)是集群中的一块存储,和普通的 Volume 一样,独立于任何使用 PV 的 Pod 的生命周期
PVC 申领与 PV 卷之间的绑定是一种一对一的映射,实现上使用 ClaimRef 来记述 PV 卷 与 PVC 申领间的双向绑定关系
如果找不到匹配的 PV 卷,PVC 申领会无限期地处于未绑定状态。 当与之匹配的 PV 卷可用时,PVC 申领会被绑定。 例如,即使某集群上供应了很多 50 Gi 大小的 PV 卷,也无法与请求 100 Gi 大小的存储的 PVC 匹配。当新的 100 Gi PV 卷被加入到集群时,该 PVC 才有可能被绑定。
绑定
持久卷申领(PersistentVolumeClaim,PVC)申领特定的大小的PV和访问模式(要求 PV 卷能够以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一来挂载)
定义
确保仍被 Pod 使用的 PersistentVolumeClaim(PVC)对象及其所绑定的 PersistentVolume(PV)对象在系统中不会被删除,防止数据丢失
在引用的情况下删除pvc:kubectl describe pvc hostpath
在引用的情况下删除pv:kubectl describe pv task-pv-volume
如果用户删除被某 Pod 使用的 PVC 对象,该 PVC 申领不会被立即移除。 PVC 对象的移除会被推迟,直至其不再被任何 Pod 使用。 此外,如果管理员删除已绑定到某 PVC 申领的 PV 卷,该 PV 卷也不会被立即移除。 PV 对象的移除也要推迟到该 PV 不再绑定到 PVC。
存储保护
创建文件:sh -c \"echo 'Hello from Kubernetes storage' > /mnt/data/index.html\"
创建一个目录:mkdir /mnt/data
生产集群中,你不会使用 hostPath,可以使用 StorageClasses 来设置动态提供存储,或者网路存储
创建:kubectl apply -f task-pv-volume.yaml
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGEtask-pv-volume 10Gi RWO Retain Available manual 4s状态(STATUS) 为 Available。 这意味着它还没有被绑定给 PersistentVolumeClaim
查看:kubectl get pv task-pv-volume
创建 PersistentVolume
访问模式有:ReadWriteOnce -- 卷可以被一个节点以读写方式挂载;ReadOnlyMany -- 卷可以被多个节点以只读方式挂载;ReadWriteMany -- 卷可以被多个节点以读写方式挂载。在命令行接口(CLI)中,访问模式也使用以下缩写形式:RWO - ReadWriteOnceROX - ReadOnlyManyRWX - ReadWriteMany
创建:kubectl apply -f task-pv-claim.yaml
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGEtask-pv-volume 10Gi RWO Retain Bound default/task-pv-claim manual 2mstatus为Bound绑定状态
查看PV:kubectl get pv task-pv-volume
NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGEtask-pv-claim Bound task-pv-volume 10Gi RWO manual 30s
查看PVC:kubectl get pvc task-pv-claim
创建 PersistentVolumeClaim
使用PersistentVolumeClaim 作为存储卷
创建:kubectl apply -f task-pv-pod.yaml
访问容器:kubectl exec -it task-pv-pod -- bash
创建Pod
kubectl delete pod task-pv-podkubectl delete pvc task-pv-claimkubectl delete pv task-pv-volume
清理
对 PersistentVolume 添加 GID 注解,Pod具有相同的GID才可写入
访问控制
使用sc来创建pvc
PVC绑定PV
使用
PersistentVolume持久卷
建议为无状态的服务使用 Deployments,比如前端服务。 对这些服务而言,对副本的数量进行扩缩容、平滑升级,比精确控制 Pod 运行在某个主机上要重要得多。 当需要 Pod 副本总是运行在全部或特定主机上,并需要它们先于其他 Pod 启动时, 应该使用 DaemonSet
DaemonSet 会尝试遵循一个节点一个 Pod 的模型
每個 Node 上都被部署了該 DaemonSet 定义的 Pod,包括master
kubectl get pods -l name=fluentd-elasticsearch -A -o wide
DaemonSet
Job会创建一个或多个Pods,直到指定数量的Pods成功终止。删除job会清除所创建的全部Pods。
π的小数点后2000位
kubectl apply -f job.yaml
查看job的详情
kubectl describe jobs/pi
查看已完成的pods
查看一个pod的标准输出
kubectl logs pod-name
kubectl get pods
Job示例
job中pod的restartPolicy只能设置Never或OnFailure
.spec.selector是可选的,一般情况下不设置
只启动一个pod
Pod成功终止,立即视job为完成状态
非并行job
.spec.completions字段为非0值,默认值为1
当成功的pod个数达到completions设定的数值时,job被视为完成
当设置.spec.completionMode=\"Indexed\"时,每个Pod都会获取一个不同的索引值,介于0~completions-1
设置完成计数的并行job
不设置spec.completions,设置spec.parallelism,默认值为1
多个Pod间相互协调,或借助外部服务确定每个Pod要处理队列内容。一个pod会处理多个队列内容
pod可以确定其他pod是否已完成,进而确定job是否完成
Pod成功完成后,不会在创建新的pod
Pod完成队列内容处理成功退出,其他Pod不会再对其处理的队列内容进行操作。
带工作队列的并行job
job并行
spec.parallelism 默认值为1。如果设置为0,job启动后便被暂停,直到此值被增加
设置完成计数的job,并行执行的pods个数不会超过剩余的完成数。比如:完成数设置为5,并行度为3,有3个pod成功完成,剩余完成数为2,这是的并行的pod个数只能是2个
工作队列job,任何pod成功结束后,不再创建新的pod,剩余的pod会继续执行,直到成功结束
job控制器因为任何原因无法创建Pods
Pod正在终止过程中,需要一定时间才会停止
实际并行数可能比设置的并行度数值略大或略小
控制并行度
Job规约
Pod保留在当前节点,容器会被重新运行
设置.spec.template.spec.restartPolicy = \"OnFailure\"
Pod中的容器因不同原因失效
即使你将 .spec.parallelism 设置为 1,且将 .spec.completions 设置为 1,并且 .spec.template.spec.restartPolicy 设置为 \"Never\",同一程序仍然有可能被启动两次。
将 .spec.parallelism 和 .spec.completions 都设置为比 1 大的值, 那就有可能同时出现多个 Pod 运行的情况。 为此,Pod 必须能够处理并发性问题
Job控制器会启动一个新的pod
整个Pod失败
Pod被删除或者成功时,回退时间还会被重置
spec.backoffLimit 默认值为6 (分钟)重试次数,重试时间将会按指数增长 (从 10 秒、20 秒到 40 秒)最多至 6 分钟也就是10s重试一次,20秒重试一次,40s重试一次,80s重试一次。。。
如果Job 的 restartPolicy 被设置为 \"OnFailure\",就要注意在 Job 到达失效回退次数上限时自动被终止
建议在调试 Job 时将 restartPolicy 设置为 \"Never\", 或者使用日志系统来确保失效 Jobs 的输出不会意外遗失。
Pod回退失效策略
处理Pod和容器失效
Job完成后不再创建新的pod,老的pod和job都不会被删除,可以手动删除
优先度高于.spec.backoffLimit
一旦 Job 运行时间达到 activeDeadlineSeconds 秒,其所有运行中的 Pod 都会被终止,并且 Job 的状态更新为 type: Failed 及 reason: DeadlineExceeded。
注意:restartPolicy 对应的是 Pod,而不是 Job 本身: 一旦 Job 状态变为 type: Failed,就不会再发生 Job 重启的动作。 换言之,由 .spec.activeDeadlineSeconds 和 .spec.backoffLimit 所触发的 Job 终结机制 都会导致 Job 永久性的失败,而这类状态都需要手工干预才能解决。
设置.spec.activeDeadlineSeconds
终止job的另一个方式
完成的job会留在系统里,占用资源
Job pi-with-ttl 在结束 100 秒之后,可以成为被自动删除的对象。如果该字段设置为 0,Job 在结束之后立即成为可被自动删除的对象。 如果该字段没有设置,Job 不会在结束之后被 TTL 控制器自动清除。
设置 Job 的 .spec.ttlSecondsAfterFinished 字段,可以让该控制器清理掉 已结束的资源。
自动清理完成的job
Job终止与清理
Jobs
子主题
kubectl get pods --output=yaml
查看没有归属的事件
kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespace
令附属成为孤立对象
kubectl delete replicaset my-repset --cascade=orphan
在前台删除附属对象
kubectl delete replicaset my-repset --cascade=foreground
在后台删除附属对象
kubectl delete replicaset my-repset --cascade=background
垃圾回收
TTL控制器
Kubernetes v1.21 [stable]
每分钟打印出当前时间和问候消息
定时调度job
在某些情况下,可能会创建两个 Job,或者不会创建任何 Job
startingDeadlineSeconds 设置为很大的数值或未设置(默认),并且 concurrencyPolicy 设置为 Allow,则作业将始终至少运行一次。
如果 startingDeadlineSeconds 的设置值低于 10 秒钟,CronJob 可能无法被调度。 这是因为 CronJob 控制器每 10 秒钟执行一次检查。
Job 应该是 幂等的
调度次数超过100次,将不会再启动job
CronJob控制器会检查失败的调度次数
CronJob
推荐使用配置 ReplicaSet 的 Deployment 来建立副本管理机制
ReplicationController
工作负载资源
基于四层的负载
Kubernetes 使用标签来将多个相关的 Pod 组合成一个逻辑单元(称为 Service)。Service 具有稳定的 IP 地址和端口,并会在一组 Pod 之间提供负载平衡
Service 在 Kubernetes 中是一个 REST 对象,和 Pod 类似
Service 能够将一个接收 port 映射到任意的 targetPort。 默认情况下,targetPort 将被设置为与 port 字段相同的值
手动添加 Endpoint 对象
没有选择算符的 Service
没有选择器的Service
定义Service
NodePort 类型是 ClusterIP 类型的扩展。因此,NodePort 类型的 Service 具有集群 IP 地址。LoadBalancer 类型是 NodePort 类型的扩展。因此,LoadBalancer 类型的 Service 具有集群 IP 地址以及一个或多个 nodePort 值。
ClusterIP(默认):内部客户端向稳定的内部 IP 地址发送请求。NodePort:客户端向使用 Service 指定的一个或多个 nodePort 值的节点的 IP 地址发送请求。LoadBalancer:客户端向网络负载平衡器的 IP 地址发送请求。ExternalName:内部客户端使用 Service 的 DNS 名称作为外部 DNS 名称的别名。Headless:如果您需要 Pod 分组,但不需要稳定的 IP 地址,则可以使用 Headless 服务。
Service 类型,默认是 ClusterIP
集群中的客户端在 TCP 端口 80 上调用地址为 10.11.247.213 的 Service。请求将转发到 TCP 端口 8080 上的其中一个成员 Pod。成员 Pod 必须有一个侦听 TCP 端口 8080 的容器。
Kubernetes 会创建一个稳定的 IP 地址,该 IP 地址可从集群中的节点访问
ClusterIP
Kubernetes 会为您提供 nodePort 值。然后,您可以使用任何节点的 IP 地址及 nodePort 值来访问 Service。
注意:您可以自行指定 nodePort 值(范围介于 30000-32767 之间)。但是,最好省略该字段,让 Kubernetes 为您分配 nodePort。这样做有助于避免 Service 之间出现冲突。
nodePort是对外使用的端口,可以使用各个节点的ip+3100访问
NodePort标志指定的范围内分配端口(默认值:30000-32767)
https://kubernetes.io/zh/docs/concepts/services-networking/service/
LoadBalancer
集群内部引用外部服务,集群内部访问service就可以访问到外部的服务
定义将 pod 名称空间中的 service 服务映射到 www.baidu.com
ExternalName
服务类型
Service
基于七层的负载
NodePort类型
通过域名加上网关的端口号,才可访问后台服务。
访问Ingress需要先配置一个网关
http
https
查看ingress
kubectl get ing
ingress
服务、负载均衡和联网
Kubernetes
收藏
0 条评论
回复 删除
下一页