赞
踩
摘取官网: https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/#working-with-pods
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。Pod(就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个)容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。简言之如果用 Docker 的术语来描述,Pod 类似于共享名字空间并共享文件系统卷的一组容器。
定义: Pod 就是用来管理一组(一个|多个)容器的集合 特点: 共享网络 共享存储 共享上下文环境
一般将多个紧密协作
的容器放入到一个Pod中,当一个Pod包含多个容器时,这些容器总是运行于同一个工作节点上,一个pod绝不会跨多个工作节点。
Pod 中的容器被自动安排到集群中的同一物理机或虚拟机上,并可以一起进行调度。 容器之间可以共享资源和依赖、彼此通信、协调何时以及何种方式终止自身。例如,你可能有一个容器,为共享卷中的文件提供 Web 服务器支持,以及一个单独的 “边车 (sidercar)” 容器负责从远端更新这些文件。Pod多容器的使用常见场景
pod内多个容器之间共享的部分:
由于共享端口空间,在同一pod的容器中运行的进程不能绑定到相同的端口号,而其他pod中的进程有自己的网络接口和端口空间,从而消除了不同pod之间的端口冲突。
pod内多个容器之间不共享的部分:
通常不需要直接创建 Pod,甚至单实例 Pod。 相反,一般会使用诸如 Deployment 或 Job 这类工作负载资源来创建 Pod。 如果 Pod 需要跟踪状态,可以考虑 StatefulSet 资源,将在之后学习这些资源。
Kubernetes 集群中的 Pod 主要有两种用法:
说明:
# 查看默认命名空间的 pod
$ kubectl get pods|pod|po
# 查看所有命名空间的 pod
$ kubectl get pods|pod -A
$ kubectl get pods|pod|po -n 命名空间名称
# 查看默认命名空间下 pod 的详细信息
$ kubectl get pods -o wide
# 查看所有命名空间下 pod 的详细信息
$ kubectl get pods -o wide -A
# 实时监控 pod 的状态
$ kubectl get pod -w
pod : kubectl run nginx(pod名称) --image=nginx:1.19
container: docker run --name nginx nginx:1.19
官网参考地址: https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/workload-resources/pod-v1/
# nginx-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
# 使用 kubectl apply/create -f 创建 pod
$ kubectl create -f nginx-pod.yml
$ kubectl apply -f nginx-pod.yml
注意: create 仅仅是不存在时创建,如果已经存在则报错!apply 不存在创建,存在更新配置。推荐使用 apply!
$ kubectl delete pod pod名称
$ kubectl delete -f pod.yml
# 注意: 这种方式进入容器默认只会进入 pod 中第一个容器
$ kubectl exec -it nginx(pod名称) --(固定写死) bash(执行命令)
# 注意: 进入指定 pod 中指定容器
$ kubectl exec -it pod名称 -c 容器名称 --(固定写死) bash(执行命令)
# 注意: 查看 pod 中第一个容器日志
$ kubectl logs -f(可选,实时) nginx(pod 名称)
# 注意: 查看 pod 中指定容器的日志
$ kubect logs -f pod名称 -c 容器名称
$ kubectl describe pod nginx(pod名称)
# myapp-pod.yml apiVersion: v1 kind: Pod metadata: name: myapp spec: containers: - name: nginx image: nginx:1.19 ports: - containerPort: 80 imagePullPolicy: IfNotPresent - name: redis image: redis:5.0.10 ports: - containerPort: 6379 imagePullPolicy: IfNotPresent
$ kubectl apply -f myapp-pod.yml
# 查看日志 (默认只查看第一个容器日志,这里是展示 nginx 日志)
$ kubectl logs -f myapp
# 查看 pod 中指定容器的日志
$ kubectl logs -f myapp -c nginx(容器名称)
$ kubectl logs -f myapp -c redis(容器名称)
# 进入 pod 的容器 (默认进入第一个容器内部,这里会进入 nginx 容器内部)
$ kubectl exec -it myapp -- sh
# 进入 pod 中指定容器内部
$ kubectl exec -it myapp -c nginx -- sh
$ kubectl exec -it myapp -c redis -- sh
对于微服务架构,部署的微服务数量可以超过20个,这些组件可以是副本和多个不同发布版本,如果没有有效组织这些组件的机制,将会导致产生巨大混乱,因此Kubernetes 对象可附加标签属性。
标签(Labels)
是附加到 Kubernetes 对象(比如 Pod)上的键值对。 标签旨在用于指定对用户有意义且相关的对象的标识属性。标签可以在创建时附加到对象,随后可以随时添加和修改。每个对象都可以定义一组键(key)/值(value)标签,但是每个键(key)对于给定对象必须是唯一的。
标签作用: 用来给 k8s 中对象起别名, 有了别名可以方便过滤和筛选
标签由键值对组成
,其有效标签值:
[a-z0-9A-Z]
)开头和结尾-
)、下划线(_
)、点(.
)和字母或数字apiVersion: v1 kind: Pod metadata: name: myapp labels: name: myapp #创建时添加 spec: containers: - name: nginx image: nginx:1.21 imagePullPolicy: IfNotPresent - name: redis image: redis:5.0.10 imagePullPolicy: IfNotPresent restartPolicy: Always
# 查看标签 $ kubectl get pods --show-labels # kubectl label pod pod名称 标签键值对 $ kubectl label pod myapp env=prod # 覆盖标签 --overwrite $ kubectl label --overwrite pod myapp env=test # 删除标签 -号代表删除标签 $ kubectl label pod myapp env- # 根据标签筛选 env=test/env > = < $ kubectl get po -l env=test $ kubectl get po -l env $ kubectl get po -l '!env' # 不包含的 pod $ kubectl get po -l 'env in (test,prod)' #选择含有指定值的 pod $ kubectl get po -l 'env notin (test,prod)' #选择含有指定值的 pod
摘自官网: https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/pod-lifecycle/
Pod 遵循预定义的生命周期,起始于 Pending
阶段, 如果至少其中有一个主要容器正常启动,则进入 Running
,之后取决于 Pod 中是否有容器以失败状态结束而进入 Succeeded
或者 Failed
阶段。与此同时Pod 在其生命周期中只会被调度一次。 一旦 Pod 被调度(分派)到某个节点,Pod 会一直在该节点运行,直到 Pod 停止或者被终止。
和一个个独立的应用容器一样,Pod 也被认为是相对临时性(而不是长期存在)的实体。 Pod 会被创建、赋予一个唯一的 ID(UID), 并被调度到节点,并在终止(根据重启策略)或删除之前一直运行在该节点。如果一个节点死掉了,调度到该节点的 Pod 也被计划在给定超时期限结束后删除。
Pod 自身不具有自愈能力。如果 Pod 被调度到某节点而该节点之后失效, Pod 会被删除;类似地,Pod 无法在因节点资源耗尽或者节点维护而被驱逐期间继续存活。 Kubernetes 使用一种高级抽象来管理这些相对而言可随时丢弃的 Pod 实例, 称作控制器。
任何给定的 Pod (由 UID 定义)从不会被“重新调度(rescheduled)”到不同的节点; 相反,这一 Pod 可以被一个新的、几乎完全相同的 Pod 替换掉。 如果需要,新 Pod 的名字可以不变,但是其 UID 会不同。
如果某物声称其生命期与某 Pod 相同,例如存储卷, 这就意味着该对象在此 Pod (UID 亦相同)存在期间也一直存在。 如果 Pod 因为任何原因被删除,甚至完全相同的替代 Pod 被创建时, 这个相关的对象(例如这里的卷)也会被删除并重建。
Pod 阶段的数量和含义是严格定义的。 除了本文档中列举的内容外,不应该再假定 Pod 有其他的 phase
值。
取值 | 描述 |
---|---|
Pending (悬决) | Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。 |
Running (运行中) | Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。 |
Succeeded (成功) | Pod 中的所有容器都已成功终止,并且不会再重启。 |
Failed (失败) | Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。 |
Unknown (未知) | 因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。 |
说明:
当一个 Pod 被删除时,执行一些 kubectl 命令会展示这个 Pod 的状态为
Terminating
(终止)。 这个Terminating
状态并不是 Pod 阶段之一。 Pod 被赋予一个可以体面终止的期限,默认为 30 秒。 你可以使用--force
参数来强制终止 Pod。如果某节点死掉或者与集群中其他节点失联,Kubernetes 会实施一种策略,将失去的节点上运行的所有 Pod 的
phase
设置为Failed
。
Kubernetes 会跟踪 Pod 中每个容器的状态,就像它跟踪 Pod 总体上的阶段一样。 你可以使用容器生命周期回调来在容器生命周期中的特定时间点触发事件。
一旦调度器将 Pod 分派给某个节点,kubelet
就通过容器运行时开始为 Pod 创建容器。容器的状态有三种:Waiting
(等待)、Running
(运行中)和 Terminated
(已终止)。
要检查 Pod 中容器的状态,你可以使用 kubectl describe pod <pod 名称>
。 其输出中包含 Pod 中每个容器的状态。
每种状态都有特定的含义:
Waiting
(等待)如果容器并不处在 Running
或 Terminated
状态之一,它就处在 Waiting
状态。 处于 Waiting
状态的容器仍在运行它完成启动所需要的操作:例如, 从某个容器镜像仓库拉取容器镜像,或者向容器应用 Secret 数据等等。 当你使用 kubectl
来查询包含 Waiting
状态的容器的 Pod 时,你也会看到一个 Reason 字段,其中给出了容器处于等待状态的原因。
Running
(运行中)Running
状态表明容器正在执行状态并且没有问题发生。 如果配置了 postStart
回调,那么该回调已经执行且已完成。 如果你使用 kubectl
来查询包含 Running
状态的容器的 Pod 时, 你也会看到关于容器进入 Running
状态的信息。
Terminated
(已终止)处于 Terminated
状态的容器已经开始执行并且或者正常结束或者因为某些原因失败。 如果你使用 kubectl
来查询包含 Terminated
状态的容器的 Pod 时, 你会看到容器进入此状态的原因、退出代码以及容器执行期间的起止时间。
如果容器配置了 preStop
回调,则该回调会在容器进入 Terminated
状态之前执行。
类似于许多具有生命周期回调组件的编程语言框架,例如 Angular、Vue、Kubernetes 为容器提供了生命周期回调。 回调使容器能够了解其管理生命周期中的事件,并在执行相应的生命周期回调时运行在处理程序中实现的代码。
有两个回调暴露给容器:
PostStart
这个回调在容器被创建之后立即被执行。 但是,不能保证回调会在容器入口点(ENTRYPOINT)之前执行。 没有参数传递给处理程序。
PreStop
在容器因 API 请求或者管理事件(诸如存活态探针、启动探针失败、资源抢占、资源竞争等) 而被终止之前,此回调会被调用。 如果容器已经处于已终止或者已完成状态,则对 preStop 回调的调用将失败。 在用来停止容器的 TERM 信号被发出之前,回调必须执行结束。 Pod 的终止宽限周期在 PreStop
回调被执行之前即开始计数, 所以无论回调函数的执行结果如何,容器最终都会在 Pod 的终止宽限期内被终止。 没有参数会被传递给处理程序。
使用容器生命周期回调
# nginx-pod.yml apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.19 lifecycle: postStart: #容器创建过程中执行 exec: command: ["/bin/sh","-c","echo postStart >> /start.txt"] preStop: #容器终止之前执行 exec: command: ["/bin/sh","-c","echo postStop >> /stop.txt && sleep 5"] ports: - containerPort: 80
Pod 的 spec
中包含一个 restartPolicy
字段,其可能取值包括 Always(总是重启)、OnFailure(容器异常退出状态码非 0,重启) 和 Never
。默认值是 Always
。
restartPolicy
适用于 Pod 中的所有容器。restartPolicy
仅针对同一节点上 kubelet
的容器重启动作。当 Pod 中的容器退出时,kubelet
会按指数回退方式计算重启的延迟(10s、20s、40s、…),其最长延迟为 5 分钟。 一旦某容器执行了 10 分钟并且没有出现问题,kubelet
对该容器的重启回退计时器执行重置操作。
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
imagePullPolicy: IfNotPresent
restartPolicy: Always # OnFailure Never
和 Docker 容器一样,k8s中容器也可以通过command、args 用来修改容器启动默认执行命令以及传递相关参数。但一般推荐使用 command 修改启动命令,使用 args 为启动命令传递参数。
apiVersion: v1 kind: Pod metadata: name: redis labels: app: redis spec: containers: - name: redis image: redis:5.0.10 command: ["redis-server"] #用来指定启动命令 args: ["--appendonly yes"] # 用来为启动命令传递参数 #args: ["redis-server","--appendonly yes"] # 单独使用修改启动命令并传递参数 #args: # 另一种语法格式 # - redis-server # - "--appendonly yes" imagePullPolicy: IfNotPresent restartPolicy: Always
probe 是由 kubelet对容器执行的定期诊断。 要执行诊断,kubelet 既可以在容器内执行代码,也可以发出一个网络请求。
定义: 容器探针 就是用来定期对容器进行健康检查的。
探测类型
针对运行中的容器,kubelet
可以选择是否执行以下三种探针,以及如何针对探测结果作出反应:
livenessProbe
指示容器是否正在运行。如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定未来。如果容器不提供存活探针, 则默认状态为 Success
。readinessProbe
指示容器是否准备好为请求提供服。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为 Failure
。 如果容器不提供就绪态探针,则默认状态为 Success
。startupProbe 1.7+
指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被 禁用,直到此探针成功为止。如果启动探测失败,kubelet
将杀死容器, 而容器依其重启策略进行重启。 如果容器没有提供启动探测,则默认状态为 Success
。探针机制
使用探针来检查容器有四种不同的方法。 每个探针都必须准确定义为这四种机制中的一种:
exec
在容器内执行命令并检查它终止时的退出代码。如果退出代码为零,则探测成功。非零退出代码被视为失败。
grpc
使用 gRPC 执行一个远程过程调用。 目标应该实现 gRPC健康检查。 如果响应的状态是 “SERVING”,则认为诊断成功。 gRPC 探针是一个 Alpha 特性,只有在你启用了 “GRPCContainerProbe” 特性门控时才能使用。
httpGet
对容器的 IP 地址上指定的网络端口和路径上向容器的 IP 地址发送 GET 请求。如果探测收到响应,并且响应码不代表错误(换句话说,如果 HTTP 响应码是 2xx 或 3xx),则认为探测成功。否则或者没有及时响应,则认为探测失败。
tcpSocket
对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开,则诊断被认为是成功的。 如果远程系统(容器)在打开连接后立即将其关闭,这算作是健康的。
探针结果
每次探测都将获得以下三种结果之一:
Success
(成功)容器通过了诊断。Failure
(失败)容器未通过诊断。Unknown
(未知)诊断失败,因此不会采取任何行动。探针参数
initialDelaySeconds: 5 #初始化时间5s
periodSeconds: 4 #检测间隔时间4s
timeoutSeconds: 1 #默认检测超时时间为1s
failureThreshold: 3 #默认失败次数为3次,达到3次后重启pod
successThreshold: 1 #默认成功次数为1次,1次监测成功代表成功
使用探针
apiVersion: v1 kind: Pod metadata: name: liveness-exec labels: exec: exec spec: containers: - name: nginx image: nginx:1.19 ports: - containerPort: 80 args: - /bin/sh - -c - sleep 7;nginx -g "daemon off;" #这一步会和初始化同时开始运行,也就是在初始化5s后和7秒之间,会检测出一次失败,7秒后启动后检测正常,所以pod不会重启 imagePullPolicy: IfNotPresent livenessProbe: exec: #这里使用 exec 执行 shell 命令检测容器状态 command: - ls - /var/run/nginx.pid #查看是否有pid文件 initialDelaySeconds: 5 #初始化时间5s periodSeconds: 4 #检测间隔时间4s timeoutSeconds: 1 #默认检测超时时间为1s failureThreshold: 3 #默认失败次数为3次,达到3次后重启pod successThreshold: 1 #默认成功次数为1次,1 次代表成功
说明:
- 如果 sleep 7s,第一次检测发现失败,但是第二次检测发现成功后容器就一直处于健康状态不会重启。
- 如果 sleep 30s,第一次检测失败,超过 3 次检测同样失败,k8s 就回杀死容器进行重启,反复循环这个过程。
apiVersion: v1 kind: Pod metadata: name: liveness-tcpsocket labels: tcpsocket: tcpsocket spec: containers: - name: nginx image: nginx:1.19 ports: - containerPort: 80 args: - /bin/sh - -c - sleep 7;nginx -g "daemon off;" #这一步会和初始化同时开始运行,也就是在初始化5s后和7秒之间,会检测出一次失败,7秒后启动后检测正常,所以pod不会重启 imagePullPolicy: IfNotPresent livenessProbe: tcpSocket: port: 80 initialDelaySeconds: 5 #初始化时间5s periodSeconds: 4 #检测间隔时间4s timeoutSeconds: 1 #默认检测超时时间为1s failureThreshold: 3 #默认失败次数为3次,达到3次后重启pod successThreshold: 1 #默认成功次数为1次,1 次代表成功
# probe-liveness-httget.yml apiVersion: v1 kind: Pod metadata: name: liveness-httpget labels: httpget: httpget spec: containers: - name: nginx image: nginx:1.19 ports: - containerPort: 80 args: - /bin/sh - -c - sleep 7;nginx -g "daemon off;" #这一步会和初始化同时开始运行,也就是在初始化5s后和7秒之间,会检测出一次失败,7秒后启动后检测正常,所以pod不会重启 imagePullPolicy: IfNotPresent livenessProbe: httpGet: #httpget port: 80 #访问的端口 path: /index.html #访问的路径 initialDelaySeconds: 5 #初始化时间5s periodSeconds: 4 #检测间隔时间4s timeoutSeconds: 1 #默认检测超时时间为1s failureThreshold: 3 #默认失败次数为3次,达到3次后重启pod successThreshold: 1 #默认成功次数为1次,1 次代表成功
GRPC 探针
官方参考地址: https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
在k8s中对于容器资源限制主要分为以下两类:
请求 request memory cpu :可以使用的基础资源 100M
限制 limit memory cpu :可以使用的最大资源 200M 超过最大资源之后容器会被 kill , OOM 错误
官网地址: https://github.com/kubernetes-sigs/metrics-server
Kubernetes Metrics Server (Kubernetes指标服务器),它是一个可扩展的、高效的容器资源度量源。Metrics Server 用于监控每个 Node 和 Pod 的负载(用于Kubernetes内置自动扩缩管道)。Metrics Server 从Kubelets 收集资源指标,并通过 Metrics API 在Kubernetes apiserver中公开,供 Horizontal Pod Autoscaler 和 Vertical Pod Autoscaler 使用。Metrics API 也可以通过 kubectl top 访问,使其更容易调试自动扩缩管道。
metrics.k8s.io
服务提供者)是否正在运行, 请键入以下命令:kubectl get apiservices
metrics.k8s.io
的引用。NAME
v1beta1.metrics.k8s.io
# components.yaml apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-app: metrics-server name: metrics-server namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: k8s-app: metrics-server rbac.authorization.k8s.io/aggregate-to-admin: "true" rbac.authorization.k8s.io/aggregate-to-edit: "true" rbac.authorization.k8s.io/aggregate-to-view: "true" name: system:aggregated-metrics-reader rules: - apiGroups: - metrics.k8s.io resources: - pods - nodes verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: k8s-app: metrics-server name: system:metrics-server rules: - apiGroups: - "" resources: - nodes/metrics verbs: - get - apiGroups: - "" resources: - pods - nodes verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: labels: k8s-app: metrics-server name: metrics-server-auth-reader namespace: kube-system roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: extension-apiserver-authentication-reader subjects: - kind: ServiceAccount name: metrics-server namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: k8s-app: metrics-server name: metrics-server:system:auth-delegator roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:auth-delegator subjects: - kind: ServiceAccount name: metrics-server namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: k8s-app: metrics-server name: system:metrics-server roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:metrics-server subjects: - kind: ServiceAccount name: metrics-server namespace: kube-system --- apiVersion: v1 kind: Service metadata: labels: k8s-app: metrics-server name: metrics-server namespace: kube-system spec: ports: - name: https port: 443 protocol: TCP targetPort: https selector: k8s-app: metrics-server --- apiVersion: apps/v1 kind: Deployment metadata: labels: k8s-app: metrics-server name: metrics-server namespace: kube-system spec: selector: matchLabels: k8s-app: metrics-server strategy: rollingUpdate: maxUnavailable: 0 template: metadata: labels: k8s-app: metrics-server spec: containers: - args: - --cert-dir=/tmp - --secure-port=4443 - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - --kubelet-use-node-status-port - --metric-resolution=15s - --kubelet-insecure-tls #修改去掉证书验证 image: dyrnq/metrics-server:v0.6.2 #修改官方无法下载 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: /livez port: https scheme: HTTPS periodSeconds: 10 name: metrics-server ports: - containerPort: 4443 name: https protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /readyz port: https scheme: HTTPS initialDelaySeconds: 20 periodSeconds: 10 resources: requests: cpu: 100m memory: 200Mi securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 1000 volumeMounts: - mountPath: /tmp name: tmp-dir hostNetwork: true #必须指定这个才行 nodeSelector: kubernetes.io/os: linux priorityClassName: system-cluster-critical serviceAccountName: metrics-server volumes: - emptyDir: {} name: tmp-dir --- apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata: labels: k8s-app: metrics-server name: v1beta1.metrics.k8s.io spec: group: metrics.k8s.io groupPriorityMinimum: 100 insecureSkipTLSVerify: true service: name: metrics-server namespace: kube-system version: v1beta1 versionPriority: 100
$ kubectl appply -f components.yaml
官网: https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/assign-memory-resource/
为容器指定内存请求,请在容器资源清单中包含 resources:requests
字段。 同理,要指定内存限制,请包含 resources:limits
。
# nginx-memory-demo.yaml
#内存资源的基本单位是字节(byte)。你可以使用这些后缀之一,将内存表示为 纯整数或定点整数:E、P、T、G、M、K、Ei、Pi、Ti、Gi、Mi、Ki。 例如,下面是一些近似相同的值:128974848, 129e6, 129M, 123Mi
apiVersion: v1
kind: Pod
metadata:
name: nginx-memory-demo
spec:
containers:
- name: nginx-memory-demo
image: nginx:1.19
resources:
requests:
memory: "100Mi"
limits:
memory: "200Mi"
查看容器内存使用情况
$ kubectl get pod nginx-memory-demo --output=yaml
查看容器正在使用内存情况
$ kubectl top pod nginx-memory-demo
内存请求和限制的目的
通过为集群中运行的容器配置内存请求和限制,你可以有效利用集群节点上可用的内存资源。 通过将 Pod 的内存请求保持在较低水平,你可以更好地安排 Pod 调度。 通过让内存限制大于内存请求,你可以完成两件事:
没有指定内存限制
如果你没有为一个容器指定内存限制,则自动遵循以下情况之一:
官网: https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/assign-cpu-resource/
为容器指定 CPU 请求,请在容器资源清单中包含 resources: requests
字段。 要指定 CPU 限制,请包含 resources:limits
。
# nginx-cpu-demo.yaml
#CPU 资源以 CPU 单位度量。小数值是可以使用的。一个请求 0.5 CPU 的容器保证会获得请求 1 个 CPU 的容器的 CPU 的一半。 你可以使用后缀 m 表示毫。例如 100m CPU、100 milliCPU 和 0.1 CPU 都相同。 CPU 请求只能使用绝对数量,而不是相对数量。0.1 在单核、双核或 48 核计算机上的 CPU 数量值是一样的。
apiVersion: v1
kind: Pod
metadata:
name: nginx-cpu-demo
spec:
containers:
- name: nginx-cpu-demo
image: nginx:1.19
resources:
limits:
cpu: "1"
requests:
cpu: "0.5"
$ kubectl get pod nginx-cpu-demo --output=yaml
$ kubectl top pod nginx-cpu-demo
CPU 请求和限制的初衷
通过配置你的集群中运行的容器的 CPU 请求和限制,你可以有效利用集群上可用的 CPU 资源。 通过将 Pod CPU 请求保持在较低水平,可以使 Pod 更有机会被调度。 通过使 CPU 限制大于 CPU 请求,你可以完成两件事:
如果不指定 CPU 限制
如果你没有为容器指定 CPU 限制,则会发生以下情况之一:
容器在可以使用的 CPU 资源上没有上限。因而可以使用所在节点上所有的可用 CPU 资源。
容器在具有默认 CPU 限制的名字空间中运行,系统会自动为容器设置默认限制。
如果你设置了 CPU 限制但未设置 CPU 请求
如果你为容器指定了 CPU 限制值但未为其设置 CPU 请求,Kubernetes 会自动为其 设置与 CPU 限制相同的 CPU 请求值。类似的,如果容器设置了内存限制值但未设置 内存请求值,Kubernetes 也会为其设置与内存限制值相同的内存请求。
Init 容器是一种特殊容器,在Pod 内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。
init 容器与普通的容器非常像,除了如下几点:
restartPolicy
值为 “Never”,并且 Pod 的 Init 容器失败, 则 Kubernetes 会将整个 Pod 状态设置为失败。lifecycle
、livenessProbe
、readinessProbe
和 startupProbe
, 因为它们必须在 Pod 就绪之前运行完成。官网地址: https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/
在 Pod 的规约中与用来描述应用容器的 containers
数组平行的位置指定 Init 容器。
apiVersion: v1 kind: Pod metadata: name: init-demo spec: containers: - name: myapp-container image: busybox:1.28 command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox:1.28 command: ['sh', '-c', 'echo init-myservice is running! && sleep 5'] - name: init-mydb image: busybox:1.28 command: ['sh', '-c', 'echo init-mydb is running! && sleep 10']
$ kubectl describe pod init-demo # 部分结果 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m16s default-scheduler Successfully assigned default/init-demo to k8s-node2 Normal Pulling 2m16s kubelet Pulling image "busybox:1.28" Normal Pulled 118s kubelet Successfully pulled image "busybox:1.28" in 17.370617268s (17.370620685s including waiting) Normal Created 118s kubelet Created container init-myservice Normal Started 118s kubelet Started container init-myservice Normal Pulled 112s kubelet Container image "busybox:1.28" already present on machine Normal Created 112s kubelet Created container init-mydb Normal Started 112s kubelet Started container init-mydb Normal Pulled 101s kubelet Container image "busybox:1.28" already present on machine Normal Created 101s kubelet Created container myapp-container Normal Started 101s kubelet Started container myapp-container
官方地址: http://kubernetes.p2hp.com/docs/concepts/scheduling-eviction/assign-pod-node.html
你可以约束一个 Pod 以便 限制 其只能在特定的节点上运行, 或优先在特定的节点上运行。 有几种方法可以实现这点,推荐的方法都是用 标签选择算符来进行选择。 通常这样的约束不是必须的,因为调度器将自动进行合理的放置(比如,将 Pod 分散到节点上, 而不是将 Pod 放置在可用资源不足的节点上等等)。但在某些情况下,你可能需要进一步控制 Pod 被部署到哪个节点。例如,确保 Pod 最终落在连接了 SSD 的机器上, 或者将来自两个不同的服务且有大量通信的 Pods 被放置在同一个可用区。
你可以使用下列方法中的任何一种来选择 Kubernetes 对特定 Pod 的调度:
定义: 使用节点亲和性可以把 Kubernetes Pod 分配到特定节点。
列出集群中的节点及其标签:
$ kubectl get nodes --show-labels
#输出类似于此:
NAME STATUS ROLES AGE VERSION LABELS
k8s-node1 Ready control-plane 10d v1.26.0 beta.kubernetes.io/arch=arm64,beta.kubernetes.io/os=linux...
k8s-node2 Ready <none> 10d v1.26.0 beta.kubernetes.io/arch=arm64,beta.kubernetes.io/os=linux...
k8s-node3 Ready <none> 10d v1.26.0 beta.kubernetes.io/arch=arm64,beta.kubernetes.io/os=linux...
选择一个节点,给它添加一个标签:
kubectl label nodes k8s-node1(节点名称) disktype=ssd
验证你所选节点具有 disktype=ssd
标签:
$ kubectl get nodes --show-labels
#输出类似于此:
NAME STATUS ROLES AGE VERSION LABELS
k8s-node1 Ready control-plane 10d v1.26.0 beta.kubernetes.io/arch=arm64,beta.kubernetes.io/os=linux,disktype=ssd...
k8s-node2 Ready <none> 10d v1.26.0 beta.kubernetes.io/arch=arm64,beta.kubernetes.io/os=linux...
k8s-node3 Ready <none> 10d v1.26.0 beta.kubernetes.io/arch=arm64,beta.kubernetes.io/os=linux...
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd # 选择节点为标签为 ssd 的节点
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeName: worker1 # 调度 Pod 到特定的节点
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
官网地址: http://kubernetes.p2hp.com/docs/concepts/scheduling-eviction/assign-pod-node.html
说明
nodeSelector
提供了一种最简单的方法来将 Pod 约束到具有特定标签的节点上。 亲和性和反亲和性扩展了你可以定义的约束类型。使用亲和性与反亲和性的一些好处有:
nodeSelector
只能选择拥有所有指定标签的节点。 亲和性、反亲和性为你提供对选择逻辑的更强控制能力。亲和性功能由两种类型的亲和性组成:
nodeSelector
字段,但它的表达能力更强,并且允许你指定软规则。节点亲和性概念上类似于 nodeSelector
, 它使你可以根据节点上的标签来约束 Pod 可以调度到哪些节点上。 节点亲和性有两种:
requiredDuringSchedulingIgnoredDuringExecution
: 调度器只有在规则被满足的时候才能执行调度。此功能类似于 nodeSelector
, 但其语法表达能力更强。preferredDuringSchedulingIgnoredDuringExecution
: 调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。注意:在上述类型中,IgnoredDuringExecution
意味着如果节点标签在 Kubernetes 调度 Pod 后发生了变更,Pod 仍将继续运行。
apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: affinity: nodeAffinity: #节点必须包含一个键名为 ssd 的标签, 并且该标签的取值必须为 fast 或 superfast。 requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: ssd operator: In values: - fast - superfast containers: - name: nginx image: nginx:1.19
注意: 你可以使用 In
、NotIn
、Exists
、DoesNotExist
、Gt
和 Lt
之一作为操作符。NotIn
和 DoesNotExist
可用来实现节点反亲和性行为。
你可以为 preferredDuringSchedulingIgnoredDuringExecution
亲和性类型的每个实例设置 weight
字段,其取值范围是 1 到 100。
apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: affinity: nodeAffinity: #节点最好具有一个键名为 app 且取值为 fast 的标签。 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 #取值范围是 1 到 100 preference: matchExpressions: - key: ssd operator: In values: - fast - weight: 50 preference: matchExpressions: - key: app operator: In values: - demo containers: - name: nginx image: nginx:1.19
与节点亲和性类似,Pod 的亲和性与反亲和性也有两种类型:
requiredDuringSchedulingIgnoredDuringExecution
preferredDuringSchedulingIgnoredDuringExecution
例如,你可以使用 requiredDuringSchedulingIgnoredDuringExecution
亲和性来告诉调度器, 将两个服务的 Pod 放到同一个云提供商可用区内,因为它们彼此之间通信非常频繁。 类似地,你可以使用 preferredDuringSchedulingIgnoredDuringExecution
反亲和性来将同一服务的多个 Pod 分布到多个云提供商可用区中。
要使用 Pod 间亲和性,可以使用 Pod 规约中的 spec.affinity.podAffinity
字段。 对于 Pod 间反亲和性,可以使用 Pod 规约中的 spec.affinity.podAntiAffinity
字段。
apiVersion: v1 kind: Pod metadata: name: redis labels: app: redis spec: containers: - name: redis image: redis:5.0.10 imagePullPolicy: IfNotPresent restartPolicy: Always affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: #更确切的说,调度器必须将 Pod 调度到具有 cpu 标签的节点上,并且集群中至少有一个位于该可用区的节点上运行着带有 app=nginx 标签的 Pod。 - topologyKey: cpu labelSelector: matchExpressions: - key: app operator: In values: - nginx
apiVersion: v1 kind: Pod metadata: name: redis labels: app: redis spec: containers: - name: redis image: redis:5.0.10 imagePullPolicy: IfNotPresent restartPolicy: Always affinity: podAffinity: preferredDuringSchedulingIgnoredDuringExecution: #更确切的说,调度器必须将 Pod 调度到具有 cpu 标签的节点上,并且集群中至少有一个位于该可用区的节点上运行着带有 app=nginx 标签的 Pod。 - podAffinityTerm: topologyKey: cpu labelSelector: matchExpressions: - key: app operator: In values: - nginx weight: 1 - podAffinityTerm: topologyKey: cpu labelSelector: matchExpressions: - key: app operator: In values: - web weight: 30
参考: http://kubernetes.p2hp.com/docs/concepts/scheduling-eviction/taint-and-toleration.html
参考: http://kubernetes.p2hp.com/docs/concepts/scheduling-eviction/topology-spread-constraints/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。