当前位置: 首页 > news >正文

西部数码网站管理助手 v3.0百度网站建设在哪

西部数码网站管理助手 v3.0,百度网站建设在哪,弄美团网站的一般一个做赚多少钱,全网品牌推广企业k8s 资源控制系统k8s 中大部分概念如#xff1a;Node、Pod、Replication Controller、RS、Deployment、Service 等都可以被看作一种资源对象#xff0c;激活所有的资源对象都可以通过 k8s 提供 kubectl 工具#xff08;或者 API 编程调用#xff09;执行 CRUD 等操作并将其…k8s 资源控制系统k8s 中大部分概念如Node、Pod、Replication Controller、RS、Deployment、Service 等都可以被看作一种资源对象激活所有的资源对象都可以通过 k8s 提供 kubectl 工具或者 API 编程调用执行 CRUD 等操作并将其保存在 etcd 中持久化存储。从这个角度来看k8s 其实是一个高度自动化的资源控制系统它通过跟踪对比 etcd 库里保存的 “资源期望状态” 与当前环境中的 “实际资源状态” 的差异来实现 自动控制 和 自动纠错 的高级功能。在声明 k8s 资源对象的时候需要注意一个关键属性apiVersion 。以 Pod 声明为例可以看到 Pod 这种资源对象归属 v1 这个核心 API。apiVersion: v1 kind: Pod metadata:name: nginxlabels: name: nginx spec:containers:- name: nginximage: nginx:1.14.2ports:- containerPort: 80k8s 平台 API Groupsk8s 平台采用了 “核心外围扩展” 的设计思路在保持平台核心稳定的同时具备持续演进升级的优势。k8s 大部分常见的核心资源对象都归属 v1 这个 core核心API比如 Node、Pod、Service、Endpoints、Namespace、RC、PersistentVolume 等。在版本迭代过程中k8s 先后扩展了 extensions/v1beta1、apps/v1beta1、apps/v1beta2 等 API 组而在 v1.9 版本之后引入了 apps/v1 这个正式的扩展 API 组正式 淘汰deprecated) 了 extensions/v1beta1、apps/v1beta1、 apps/v1beta2 这三个 API 组。我们可以采用 YAML 或 JSON 格式声明定义或创建一个 k8s 资源对象每个资源对象都有自己的特定语法格式可以理解为数据库中一个特定的表)但 随着 k8s 版本的持续升级一些资源对象会不断引入新的属性。为了在不影响当前功能的情况下引入对新特性的支持我们通常会采用下面 两种典型方法。方法1在设计数据库表的时候在每个表中都增加一个很长的备注字段之后扩展的数据以某种格式如 XML、JSON、简单字符串拼接等放入备注字段。因为数据库表的结构没有发生变化所以此时程序的改动范围是最小的风险也更小但看起来不太美观优雅。方法2直接修改数据库表增加一个或多个新的列此时程序的改动范围较大风险更大但看起来比较美观。显然两种方法都不完美。更加优雅的做法是先采用方法1实现这个新特性经选几个版本的迭代等新特性变得稳定成熟了以后可以在后续版本中采用方法2升级到正式版。为此 k8s 为每个资源对象都增加了类似数据库表里备注字段的通用属性 Annotations注解以实现方法1的升级。以 k8s v1.3 版本引入的 Pod 的 Init Container 新特性为例参照对比如下在 k8s v1.8 版本中资源对象中的很多 Alpha、Beta 版本的 Annotaions注解 被取消升级成了常规定义方式在学习 k8s 的过程中需要特别注意。更多的 API Groups 请查看https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#-strong-api-groups-strong-k8s 资源对象在 k8s 中一切皆可被抽象定义为资源对象接下来我们了解下 k8s 中有哪些常用的资源对象比如Master、Node、Label、RC、RS、Deployment、DaemonSet、HPA、StatefulSet、Service、Job CronJob、Volume、PV PVC、Namespace、Annotation、ConfigMap、Secret 等。Master在 k8s 里 Master 指的是集群控制节点负责整个 k8s 集群环境的管理和控制基本上 k8s 的所有命令都发给它并负责具体的执行过程我们后面所有执行的命令基本上是在 Master 上运行的。Master 通常会占据一个独立的服务器生产环境为了保障高可用性通常建议奇数台服务器组成 Master 集群比如357... 台服务器它对于整个 k8s 的集群环境非常重要是 整个集群的 “大脑” 如果 Master 宕机或者不可用那么整个集群内的容器应用的管理都将全部失效。在 Master 节点运行着以下关键进程kube-apiserver提供了基于 http 协议的 RESTful API 的关键进程是 k8s 里面所有资源的 CRUD增、删、改、查等操作的唯一入口也是集群控制的入口进程。kube-controller-manager是 k8s 里所有资源对象的自动化控制中心可以将其理解为资源对象的 “大总管”。kube-scheduler负责资源调度Pod 调度的进程相当于交通道路的指挥中心和公交公司的 “调度室”。另外在 Master 上面通常还需部署 etcd 数据库服务因为 k8s 里的所有资源对象的数据都被保存在 etcd 中持久化存储。【注意】etcd 数据库服务可以独立物理机环境部署为了保障在生产环境中的高可用性通常建议采用奇数节点组成 eetcd 集群环境比如357... 台服务器环境。Node除了 Master k8s 集群中其他机器还存在另一角色 Node在早期的版本中叫 Minion。与 Master 一样Node 也可以是一台物理机或者虚拟机。Node 是 k8s 集群中的工作负载节点每个 Node 都会被 Master 分配一些工作负载比如Docker 容器当某个 Node 宕机时其上面的工作负载会被 Master 自动转移到其他的 Node 节点上继续运行自动化的故障处理。在每个 Node 上面都运行着以下关键进程kubelet等同于 Node 上面的 Agent负责 Pod 对应的容器的创建、启动、停止等任务同时与 Master 密切协作实现 k8s 集群管理的基本功能。kube-proxy实现 k8s Service 的通信与 软件负载均衡LAN-4 机制的重要组件。Container Runtime容器运行负责本机的容器创建和管理工作从 k8s v1.24 版本以后正式剔除 Docker 采用 Containerd 作为默认的 Container Runtime提供标准的 CRI 接口实现更多的容器运行时产品。Node 可以在运行期间动态的在 k8s 集群中增加前提是在这个节点上已经正确安装、配置和配置了上述关键的进程服务在 默认情况下 kubelet 会向 Master 注册自己这也是 k8s 推荐的 Node 管理方式。一旦 Node 被纳入 k8s 集群管理范围kubelet 进程就会定时向 Master 汇报自身的情况例如操作系统、容器版本、集群的CPU和 Mamory 内存情况以及当前 Node 有哪些 Pod 在运行等这样 Master 就可以获知每个 Node 的资源使用情况并实现高效的资源调度策略。而 某个 Node 在超过指定时间不上报信息时会被 Master 判定为 “失联” 此时 Node 的状态被标记为不可用Not Ready随后 Master 会触发 “ Worker 工作负载大转移” 的自动流程。向 API 服务器添加节点的方式主要有两种节点上的 kubelet 向控制面Master 上面的 kube-controller-manager执行自注册。人工手动添加一个 Node 对象。在你创建了 Node 对象或者该节点上的 kubelet 执行了自注册操作之后控制面Master会检查新的 Node 对象是否合法。例如如果你尝试使用下面的 JSON 对象来创建 Node 对象{kind: Node,apiVersion: v1,metadata: {name: 10.240.79.157,labels: {name: my-first-k8s-node}} }k8s 会在内部创建一个 Node 对象作为节点的 label标签。k8s 检查 kubelet 向 API 服务器注册节点时使用的 metadata.name 字段是否匹配。如果节点是健康的即所有必要的服务都在运行中则该节点可以用来运行 Pod。否则直到该节点变为健康之前所有的集群活动都会忽略该节点。查看集群中 Node 的数量和状态kubectl get nodes查看某一个 Node 的详细信息kubectl describe node k8s-node-01说明K8s 会一直保存着非法节点对应的对象并持续检查该节点是否已经变得健康。你或者某个控制器必须显式地删除该 Node 对象以停止健康检查操作。关于更多 Node 信息请查看https://kubernetes.io/zh-cn/docs/concepts/architecture/nodes/PodPod 是什么Pod 是 k8s 中最重要的基本概念是可以在 k8s 中创建和管理的、最小的可部署的计算单元。Pod就像在鲸鱼荚或者豌豆荚中是一组一个或多个 容器这些容器共享存储、网络、以及怎样运行这些容器的声明。Pod 中的内容总是并置colocated的并且一同调度在共享的上下文中运行。Pod 所建模的是特定于应用的 “逻辑主机”其中包含一个或多个应用容器 这些容器相对紧密地耦合在一起。在非云环境中在相同的物理机或虚拟机上运行的应用类似于在同一逻辑主机上运行的云应用。除了应用容器Pod 还可以包含在 Pod 启动期间运行的 Init-Container。你也可以在集群中支持  ephemeral containers临时性容器的情况下为调试的目的注入临时性容器。Pod 的共享上下文包括一组 Linux 名字空间namespace、控制组cgroup和可能一些其他的隔离方面 即用来隔离比如Docker容器的技术。在 Pod 的上下文中每个独立的应用可能会进一步实施隔离。上图展示了 Pod 的组成示意图在每一个 Pod 中都有一个特殊的 “根容器” Pause 容器。Pause 容器对应的镜像属于 k8s 平台的一部分在 Pod 中除了 Pause 容器还包含一个或多个紧密相关的的用户业务容器。为什么 k8s 会设计出一个全新的 Pod 的概念并且 Pod 有这样特殊的组成结构原因之一在一组容器作为一个单元的情况下我们难以简单地对 “整体” 进行判断及有效地行动。比如一个容器死亡了此时算是整体死亡还是算 n/m 的死亡率呢?引入业务无关并且不易死亡的 Pause 容器作为 Pod 的根容器以它的状态代表整个容器组的状态就简单、巧妙地解决了这个难题。原因之二Pod 里的多个业务容器共享 Pause 容器的 IP共享Pause 容器挂接的Volume。这样既简化了密切关联的业务容器之间的通信问题也很好地解决了它们之间的文件共享问题。k8s 为每个 Pod 都分配了唯一的 IP 地址称之为 Pod IP一个 Pod 里的 多容器共享 Pod IP 地址。K8s 要求底层网络支持集群内任意两个 Pod 之间的 TCP/IP 直接通信这通常采用 虚拟二层网络技术 来实现例如 Flannel、Open vSwitch 等因此我们需要牢记一点在 k8s 里一个 Pod 里的容器与另外主机上的 Pod 容器能够直接通信在 k8s 中网络环境要求 “扁平化” 管理即 Pod 间可以相互网络通信也可以跨主机网络通信。Pod 分类按运行方式Pod 其实有两种类型**自主式 Pod也叫静态 Pod/ Static Pod**这种 Pod 比较特殊它并没被存放在 k8s 的 etcd 中存储持久化而是被存放在某个具体的 Node 上的一个具体文件中并且只在此 Node 上启动、运行。并且该 Pod 本身是不能自我修复的当 Pod 被创建后不论是由你直接创建还是被其他 Controller都会被 k8s 调度到集群的 Node 上。直到 Pod 的进程终止、被删掉、因为缺少资源而被驱逐、或者 Node 故障之前这个 Pod 都会一直保持在那个 Node 上。Pod 不会自愈。如果 Pod 运行的 Node 故障或者是调度器本身故障这个 Pod 就会被删除。同样的如果 Pod 所在 Node 缺少资源或者 Pod 处于维护状态Pod 也会被驱逐。**控制器管理的 Pod也叫普通 Pod**K8s 使用更高级的称为 Controller 的抽象层来管理 Pod 实例。Controller 可以创建和管理多个 Pod提供副本管理、滚动升级和集群级别的自愈能力。该 Pod 一旦被创建就会被存入 etcd 中存储持久化随后被 k8s Master 调度到某个具体的 Node 上并进行绑定Binding随后该 Pod 被对应的 Node 上的 kubelet 进程实例化成―组相关的 Docker 容器并启动。在默认情况下当 Pod 里的某个容器停止时k8s 会自动检测到这个问题并重新启动这个 Pod重启 Pod 里的所有容器如果 Pod 所在的 Node 宕机就会将这个 Node 上的所有 Pod 重新调度到其他健康的 Node 上。虽然可以直接创建和使用 Pod但是在 k8s 中通常是使用 Controller 来管理 Pod 的。Pod 资源对象的 YAML 定义文件k8s 里所有的资源对象都可以采用 YAML 或者 JSON 格式的文件来定义或描述下面我们来看一个 Pod 运行单个容器 的资源定义文件apiVersion: v1                     # API 版本号 kind: Pod                          # 资源类型 metadata:                          # meta 信息name: myweblabels:                          # 标签 name: myweb spec:containers:- name: myweb-aspnetcore           # 容器名称image: aspnetcore-6.0:v1.0.0     # 镜像:版本imagePullPolicy: IfNotPresent    # 如果镜像不存在则拉取ports:- containerPort: 5001            # 容器暴露端口env:                             # 环境变量- name: ASPNETCORE_ENVIRONMENT   # asp.net core 运行时环境value: Development             # 开发环境- name: ASPNETCORE_URLS          # 设置 asp.net core 启动端口value: http://localhost:5001/  # 本地主机 5001 端口上面 Pod 的 yaml 文件定义中Pod 的 IP 加上容器端口containerPort就组成了一个新的概念 —— Endpoint它代表此 Pod 里的一个服务进程的对外通信地址。一个 Pod 也存在具有多个 Endpoint 的情况比如当我们把一个 RabbitMQimage rabbitmq:3.10.7-management 定义为一个 Pod 时可以对外暴露管理端口和服务端口这两个 Endpoint 。接下来我们再看一个 Pod 运行多容器 的资源定义文件apiVersion: v1 kind: Pod metadata:name: kucc4 spec:containers:- name: nginximage: nginx:1.23.1- name: redisimage: redis:7.0.4- name: memcachedimage: memcached:1.6.16上面 Pod 的 yaml 文件定义中创建了一个名称为 kucc4 的 Pod在该 Pod 里面分别为镜像 images nginx redis memcache单独运行一个 app container应用程序容器。Pod Volume大家熟悉的 Docker Volume 在 k8s 里面也有对应的概念 —— Pod Volume后者有一些扩展比如可以使用分布式文件系统 GlusterFS 实现后端存储功能Pod Pod Volume 是被定义在 Pod 上然后被各个容器挂载到自己的文件系统中的。k8s 中的 EventEvent 是一个事件的记录记录了事件的最早生产时间、最后重现时间、重复次数、发起者、类型以及导致此事件的原因等信息。它通常会被关联到某个具体的资源对象上是排查故障的重要参考信息。例如当我们发现某个资源对象迟迟无法创建时可以查看某个资源对象的描述信息方便定位问题成因执行命令如下kubectl describe 资源对象类型 资源对象名称kubectl describe pod xxxx  # 查看 Pod 资源信息 kubectl describe node aaaa # 查看 Node 资源信息Pod 中的资源配额每个 Pod 都可以对其使用的服务器上的计算资源设置限额常用的限额的计算资源有 CPU 和 Memory 两种CPU 资源单位为 CPUCore的数量是一个绝对值最小单位m1 个 CPUCore 核等于 1000m。一个 CPU 等于1 个物理 CPU 核 或者 一个虚拟核 取决于节点是一台物理主机还是运行在某物理主机上的虚拟机。Memory 资源配额也是一个绝对值单位是内存字节数。可以使用普通的整数或者带有以下 数量后缀 的定点数字来表示内存E、P、T、G、M、k。你也可以使用对应的 2 的幂数Ei、Pi、Ti、Gi、Mi、Ki。例如以下表达式所代表的是大致相同的值128974848、129e6、129M、128974848000m、123Mi说明K8s 不允许设置精度小于 1m 的 CPU 资源。因此当 CPU 单位小于 1 或 1000m 时使用毫核的形式是有用的例如 5m 而不是 0.005。在 k8s 里一个计算资源进行配额限定时需要设定以下两个参数Request该资源的最小申请量系统必须满足要求。Limits该资源的最大允许使用量不能被突破当容器尝试使用超过这个量的资源时可能会被 k8s “杀掉/ kill” 进程服务并重启。以 Pod 为例你可以配置为该 Pod 的资源请求为 0.5 CPU 和 128 MiB 内存资源限制为 1 CPU 和 256MiB 内存。apiVersion: v1 kind: Pod metadata:name: frontendlabels: name: myweb spec:containers:- name: appimage: images.my-company.example/app:v4resources:requests:memory: 128Micpu: 500m      # 或者 0.5limits:memory: 256Micpu: 1         # 或者 1000mPod 重启策略Pod 的 spec 中包含一个 restartPolicy 字段其可能取值包括 Always、OnFailure 和 Never。默认值是 Always。restartPolicy 适用于 Pod 中的所有容器。restartPolicy 仅针对同一节点上 kubelet 的容器重启动作。当 Pod 中的容器退出时kubelet 会按指数回退 方式计算重启的延迟10s、20s、40s、...其最长延迟为 5 分钟。一旦某容器执行了 10 分钟并且没有出现问题kubelet 对该容器的重启回退计时器执行 重置操作。Pod 阶段PhasePod 的 status 字段是一个 PodStatus 对象其中包含一个 phase 字段。Pod 的阶段Phase是 Pod 在其生命周期中所处位置的简单宏观概述。该阶段并不是对容器或 Pod 状态的综合汇总也不是为了成为完整的状态机。我们可以把它理解为 Pod 创建的一个总体阶段过程。Pod 阶段的数量和含义是严格定义的。除了本文档中列举的内容外不应该再假定 Pod 有其他的 phase 值。下面是 phase 可能的值取值描述Pending悬决Pod 已被 k8s 系统接受但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。Running运行中Pod 已经绑定到了某个节点Pod 中所有的容器都已被创建。至少有一个容器仍在运行或者正处于启动或重启状态。Succeeded成功Pod 中的所有容器都已成功终止并且不会再重启。Failed失败Pod 中的所有容器都已终止并且至少有一个容器是因为失败终止。也就是说容器以非 0 状态退出或者被系统终止。Unknown未知因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。如果某节点 “死掉” 或者与集群中其他节点 “失联”k8s 会实施一种策略将失去的节点上运行的所有 Pod 的 phase 设置为 Failed。Pod 状态Pod 有一个 PodStatus 对象其中包含一个 PodConditions 数组。Pod 可能通过也可能未通过其中的一些状况测试。PodScheduledPod 已经被调度到某节点ContainersReadyPod 中所有容器都已就绪Initialized所有的 Init 容器 都已成功完成ReadyPod 可以为请求提供服务并且应该被添加到对应服务的负载均衡池中。字段名称描述typePod 状况的名称status表明该状况是否适用可能的取值有 True, False 或 UnknownlastProbeTime上次探测 Pod 状况时的时间戳lastTransitionTimePod 上次从一种状态转换到另一种状态时的时间戳reason机器可读的、驼峰编码UpperCamelCase的文字表述上次状况变化的原因message人类可读的消息给出上次状态转换的详细信息Container 状态k8s 会跟踪 Pod 中每个容器的状态就像它跟踪 Pod 总体上的阶段一样。你可以使用 容器生命周期回调 来在容器生命周期中的特定时间点触发事件。一旦调度器将 Pod 分派给某个节点kubelet 就通过 容器运行时 开始为 Pod 创建容器。容器的状态有三种Waiting等待、Running运行中和 Terminated已终止。要检查 Pod 中容器的状态你可以使用 kubectl describe pod pod 名称。其输出中包含 Pod 中每个容器的状态。Container 每种状态都有特定的含义字段名称描述Waiting 等待如果容器并不处在 Running 或 Terminated 状态之一它就处在 Waiting 状态。处于 Waiting 状态的容器仍在运行它完成启动所需要的操作例如从某个容器镜像 仓库拉取容器镜像或者向容器应用 Secret 数据等等。当你使用 kubectl 来查询包含 Waiting 状态的容器的 Pod 时你也会看到一个 Reason 字段其中给出了容器处于等待状态的原因。Running运行中Running 状态表明容器正在执行状态并且没有问题发生。如果配置了 postStart 回调那么该回调已经执行且已完成。如果你使用 kubectl 来查询包含 Running 状态的容器的 Pod 时你也会看到 关于容器进入 Running 状态的信息。Terminated已终止处于 Terminated 状态的容器已经开始执行并且或者正常结束或者因为某些原因失败。如果你使用 kubectl 来查询包含 Terminated 状态的容器的 Pod 时你会看到 容器进入此状态的原因、退出代码以及容器执行期间的起止时间。说明如果容器配置了 preStop 回调则该回调会在容器进入 Terminated 状态之前执行。Container 探针probe 是由 kubelet 对容器执行的定期诊断。要执行诊断kubelet 既可以在容器内执行代码也可以发出一个网络请求。1、检查机制使用探针来检查容器有四种不同的方法。每个探针都必须准确定义为这四种机制中的一种字段名称描述exec在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。grpc使用 gRPC 执行一个远程过程调用。目标应该实现 gRPC健康检查。如果响应的状态是 SERVING则认为诊断成功。gRPC探针是一个 alpha 特性只有在你启用了 GRPCContainerProbe 特性门控时才能使用。httpGet对容器的 IP 地址上指定端口和路径执行 HTTP GET 请求。如果响应的状态码大于等于 200 且小于 400则诊断被认为是成功的。tcpSocket对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开则诊断被认为是成功的。如果远程系统容器在打开连接后立即将其关闭这算作是健康的。2、探测结果每次探测都将获得以下三种结果之一字段名称描述Success成功容器通过了诊断。Failure失败容器未通过诊断。Unknown未知诊断失败因此不会采取任何行动。3、探测类型针对运行中的容器kubelet 可以选择是否执行以下三种探针以及如何针对探测结果作出反应字段名称描述livenessProbe存活探针指示容器是否正在运行。如果存活态探测失败则 kubelet 会杀死容器 并且容器将根据其重启策略决定未来。如果容器不提供存活探针 则默认状态为 Success。readinessProbe就绪探针指示容器是否准备好为请求提供服务。如果就绪态探测失败 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。初始延迟之前的就绪态的状态值默认为 Failure。如果容器不提供就绪态探针则默认状态为 Success。startupProbe启动探针指示容器中的应用是否已经启动。如果提供了启动探针则所有其他探针都会被 禁用直到此探针成功为止。如果启动探测失败kubelet 将杀死容器而容器依其 重启策略进行重启。如果容器没有提供启动探测则默认状态为 Success。如果想了解如何设置存活态、就绪态和启动探针的进一步细节可以参阅 配置存活态、就绪态和启动探针。何时该使用存活态探针?特性状态Kubernetes v1.0 [stable]如果容器中的进程能够在遇到问题或不健康的情况下自行崩溃则不一定需要存活态探针; kubelet 将根据 Pod 的 restartPolicy 自动执行修复操作。如果你希望容器在探测失败时被杀死并重新启动那么请指定一个存活态探针 并指定 restartPolicy 为 Always 或 OnFailure。何时该使用就绪态探针?特性状态Kubernetes v1.0 [stable]如果要仅在探测成功时才开始向 Pod 发送请求流量请指定就绪态探针。在这种情况下就绪态探针可能与存活态探针相同但是规约中的就绪态探针的存在意味着 Pod 将在启动阶段不接收任何数据并且只有在探针探测成功后才开始接收数据。如果你希望容器能够自行进入维护状态也可以指定一个就绪态探针检查某个特定于 就绪态的因此不同于存活态探测的端点。如果你的应用程序对后端服务有严格的依赖性你可以同时实现存活态和就绪态探针。当应用程序本身是健康的存活态探针检测通过后就绪态探针会额外检查每个所需的后端服务是否可用。这可以帮助你避免将流量导向只能返回错误信息的 Pod。如果你的容器需要在启动期间加载大型数据、配置文件或执行迁移你可以使用 启动探针。然而如果你想区分已经失败的应用和仍在处理其启动数据的应用你可能更倾向于使用就绪探针。Pod 优雅终止由于 Pod 所代表的是在集群中节点上运行的进程当不再需要这些进程时 “允许其体面地终止” 是很重要的。一般不应武断地使用 KILL 信号终止它们导致这些进程没有机会完成清理操作。设计的目标 是让你能够请求删除进程并且知道进程何时被终止同时也能够确保删除 操作终将完成。当你请求删除某个 Pod 时集群会记录并跟踪 Pod 的体面终止周期 而不是直接强制地杀死 Pod。在存在强制关闭设施的前提下 kubelet 会尝试体面地终止 Pod。通常情况下容器运行时container runtime会发送一个 TERM 信号到每个容器中的主进程。很多容器运行时都能够注意到容器镜像中 STOPSIGNAL 的值并发送该信号而不是 TERM。一旦超出了体面终止限期超出所计算时间点则认为 Pod 已死dead容器运行时会向所有剩余进程发送 KILL 信号之后 Pod 就会被从 API 服务器 上移除。如果 kubelet 或者容器运行时的管理服务在等待进程终止期间被重启 集群会从头开始重试赋予 Pod 完整的体面终止限期。强制终止 Pod注意对于某些工作负载及其 Pod 而言强制删除很可能会带来某种破坏。默认情况下所有的删除操作都会附有 30 秒钟的宽限期限。kubectl delete 命令支持 --grace-periodseconds 选项允许你重载默认值 设定自己希望的期限值。将宽限期限强制设置为 0 意味着立即从 API 服务器删除 Pod。如果 Pod 仍然运行于某节点上强制删除操作会触发 kubelet 立即执行清理操作。说明你必须在设置 --grace-period0 的同时额外设置 --force 参数才能发起强制删除请求。执行强制删除操作时API 服务器不再等待来自 kubelet 的、关于 Pod 已经在原来运行的节点上终止执行的确认消息。API 服务器直接删除 Pod 对象这样新的与之同名的 Pod 即可以被创建。在 Node 节点侧被设置为立即终止的 Pod 仍然会在被强行杀死之前获得一点点的宽限时间。已终止 Pod 的垃圾收集对于 已失败的 Pod 而言对应的 API 对象仍然会保留在集群的 API 服务器上直到 用户或者控制器进程显式地 将其删除。控制面组件会在 Pod 个数超出所配置的阈值 根据 kube-controller-manager 的 terminated-pod-gc-threshold 设置时 删除已终止的 Pod阶段值为 Succeeded 或 Failed。这一行为会避免随着时间演进不断创建和终止 Pod 而引起的 资源泄露问题。Pod 容器资源管理https://kubernetes.io/zh-cn/docs/concepts/configuration/manage-resources-containers/ Pod 的生命周期 https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/pod-lifecycle/ 关于 Pod 更多信息请查看https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/LabelLabel Label SelectorLable标签 是 k8s 系统中另外一个核心概念。一个标签是一个 keyvalue 的键值对其中 key 和 vaule 由用户自己指定。Label 可以被附加到各种资源对象上例如 Node、Pod、Service、RC、RS、Deployment、DaemonSet 和 Job 等一个资源对象可以定义任意数量的 Label同一个 Label 也可以被添加到任意数量的资源对象上。Label 通常在资源对象定义时确定也可以在对象创建后动态添加或删除。我们可以通过给指定的资源对象捆绑一个或多个不同的 Label 来实现多维度的资源分组管理功能以便灵活、方便地进行资源分配、调度、配置、部署等管理工作。例如部署不同版本的应用到不同的环境中监控和分析应用日志记录、监控、告警等。一些常用的 Label 示例如下版本标签release: stable、release: canary。环境标签environment: dev、environment: qa、environment: production。架构标签tier: frontend、tier: backend、tier: middleware。分区标签partition: customerA、partition: customerB、partition: customerC。质量管控标签track: daily、track: weekly 。给某个资源对象定义一个 Label随后即可通过 Label Selector标签选择器 查询和筛选拥有某些 Label 的资源对象k8s 通过这种方式实现了类似 SQL 的简单又通用的对象查询机制。举例给 Pod 资源对象添加一个 Label nameredis-slave然后  Label Selector 作用于 Poid等效如下的 sql 语句select * from pod where pods name  redis-slave当前 Label Selector标签选择器有两种类型**基于等式的Equality-based**使用等式类表达式匹配标签例如name redis-slave、env ! production 。**基于集合的Set-based**使用集合操作类表达式匹配标签例如name in (redis-master, name-slave)、name notin(frontend) 。可以通过多个 Label Selector 表达式的组合实现复杂的条件选择多个表达式之间用 “,” 进行分隔几个条件之间是 “AND” 的关系即同时满足多个条件比如下面的例子name  redis-slave,env ! production name notin(frontend),env ! productionmatchLabels matchExpressionsselector: matchLabels: app: mywebmatchExpressions: - {key: tier, operator: In, values: [frontend]}- {key: environment, operator: NotIn, values: [dev]}matchLabels 用于定义一组 Label与直接写在 Selector 中的作用相同matchExpressions 用于定义一组集合的筛选条件**可用的条件运算符包括In、NotIn、Exists 和 DoesNotExist**。如果同时设置了 matchLabels 和 matchExpressions 则两组条件为 AND 关系即需要同时满足所有条件的才能完成 Selector 的筛选。Label Selector 在 k8s 中的 重要使用场景 如下kube-controller 进程通过在资源对象 RC上定义的 Label Selector 来筛选要监控 Pod 的副本数量使 Pod 副本数量始终符合预期设定的全自动控制流程。kube-proxy 进程通过 Service 的 Label Selector 来选择对应的 Pod自动建立每个 Service 到对应 Pod 的请求转发路由表从而实现 Service 的智能负载均衡机制。通过对某些 Node 定义特定的 Label并且在 Pod 定义文件中使用 NodeSelector 这种标签调度策略kube-scheduler 进程可以实现 Pod 定向调度的特性。总之使用 Label 可以给对象创建多组标签Label 和 Label Selector 共同构成了 k8s 系统中核心的应用模型使得被管理对象能够被精细地分组管理同时实现了整个集群的高可用性。关于 Label 和 Label Selector 更多信息请查看https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/labels/RC RSReplicationControllerReplicationController简称 RC 是 k8s 系统中的核心概念之一简单来说它的作用是 确保在任何时候都有特定数量的 Pod 副本处于运行状态 。换句话说RC 确保一个 Pod 或一组同类的 Pod 总是可用的。所以 RC 的定义包括如下几个部分Pod 期待的副本数量。用于筛选目标 Pod 的 Label Selector 。当 Pod 的副本数量小于预期数量时用于创建新 Pod 的 Pod 模板template。下面是一个完整的 RC 例子这个示例 ReplicationController 配置运行 nginx Web 服务器的三个副本。apiVersion: v1 kind: ReplicationController metadata:name: nginx spec:replicas: 3   # 目标 Pod 的副本数量selector:app: nginxtemplate:metadata:name: nginxlabels:app: nginxspec:containers:- name: nginximage: nginxports:- containerPort: 80可以使用以下命令检查 RC 的状态kubectl describe replicationcontrollers/nginx如果当前目标 Pod 副本数为 2则将其扩展至 3。kubectl scale --current-replicas2 --replicas3 deployment/myweb设置多个 RC 中 Pod 副本数量。kubectl scale --replicas5 rc/foo rc/bar rc/baz关于 RC 的更多信息请查看https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/replicationcontroller/RC 的替代方案 —— ReplicaSetRC 由于与 k8s 代码中的模块 ReplicationController 同名同时 “ReplicationController ” 无法准确的表达它的本意所以在 k8s v1.2 版本中升级为另一个新的概念 —— **ReplicaSet简称 RS**官方解释为 RS 是 “下一代的 RC”RS 是 RC 的超集RC 只支持基于等式的 Label Selector equality-based selectorRS 同时还支持新的基于集合的 Label SelectorSet-based selector这使得 RS 的功能更强。RS 的工作原理RS 是通过一组字段来定义的包括一个用来识别可获得的 Pod 的集合的选择算符、一个用来标明应该维护的副本个数的数值、一个用来指定应该创建新 Pod 以满足副本个数条件时要使用的 Pod 模板等等。每个 ReplicaSet 都通过根据需要创建和删除 Pod 以使得副本个数达到期望值 进而实现其存在价值。当 ReplicaSet 需要创建新的 Pod 时会使用所提供的 Pod 模板。RS 通过 Pod 上的 metadata.ownerReferences 字段连接到附属 Pod该字段给出当前对象的属主资源。ReplicaSet 所获得的 Pod 都在其 ownerReferences 字段中包含了属主 ReplicaSet 的标识信息。正是通过这一连接ReplicaSet 知道它所维护的 Pod 集合的状态并据此计划其操作行为。RS 使用其选择算符来辨识要获得的 Pod 集合。如果某个 Pod 没有 OwnerReference 或者其 OwnerReference 不是一个控制器 且其匹配到某 ReplicaSet 的选择算符则该 Pod 立即被此 ReplicaSet 获得。何时使用 RSRS 确保任何时间都有指定数量的 Pod 副本在运行。然而Deployment 是一个更高级的概念它管理 RS 并向 Pod 提供声明式的更新以及许多其他有用的功能。因此我们建议使用 Deployment 而不是直接使用 RS 除非你需要自定义更新业务流程或根本不需要更新。这实际上意味着你可能永远不需要操作 ReplicaSet 对象而是使用 Deployment并在 spec 部分定义你的应用。RS  的 yaml 文件定义式例apiVersion: apps/v1 kind: ReplicaSet metadata:name: frontendlabels:app: guestbooktier: frontend spec:# 按你的实际情况修改副本数replicas: 3selector:matchLabels:tier: frontendtemplate:metadata:labels:tier: frontendspec:containers:- name: php-redisimage: gcr.io/google_samples/gb-frontend:v3RS 主要被 Deployment 用来作为一种编排 Pod 创建、删除及更新的机制。推荐使用 Deployment 而不是直接使用 ReplicaSet除非你需要自定义更新编排或根本不需要更新。RS 与 Deployment 这两个重要的资源对象逐步替代了之前的 RC 的作用是 k8s v1.3 版本里 Pod 自动扩容伸缩这个告警功能实现的基础也将继续在 k8s 未来版本中发挥重要作用。RC或 RS 的一些特性与作用在大多数情况下通过定义一个 RC 实现 Pod 的创建及副本数量的自动控制。在 RC 里包括完整的 Pod 定义模板。RC 通过 Label Selector 机制实现对 Pod 副本的自动控制。通过改变 RC 里 Pod 的副本数量可以实现 Pod 的扩容和缩容。通过改变 RC 里 Pod 模板中的镜像版本可以实现 Pod 的滚动升级Rolling Update。关于 RS 的更多信息请查看https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/replicaset/DeploymentDeployment 推荐是 K8s 在 v1.2 版本中引人的新概念是一种更高级别的 API 对象**用于更新其底层 ReplicaSet 及其 Pod更好地解决 Pod 的编排问题** 。为此Deployment 在内部使用了 Replica Set 来实现目的无论从 Deployment 的作用与目的、YAML定义还是从它的具体命令行操作来看我们都可以把它看作 RC 的一次升级两者的相似度超过90%。如果你想要这种 滚动更新 功能那么推荐使用 Deployment因为它们是 声明式的、服务端的并且具有其它特性。我们看下官方的定义一个 Deployment 为 Pod 和 ReplicaSet 提供声明式的更新能力。你负责描述 Deployment 中的 目标状态而 Deployment 控制器Controller 以受控速率更改实际状态 使其变为期望状态。你可以定义 Deployment 以创建新的 ReplicaSet或删除现有 Deployment 并通过新的 Deployment 回收其资源。以下是 Deployments 的典型用例创建 Deployment 以将 ReplicaSet 上线。ReplicaSet 在后台创建 Pods。检查 ReplicaSet 的上线状态查看其是否成功。通过更新 Deployment 的 PodTemplateSpec声明 Pod 的新状态 。新的 ReplicaSet 会被创建Deployment 以受控速率将 Pod 从旧 ReplicaSet 迁移到新 ReplicaSet。每个新的 ReplicaSet 都会更新 Deployment 的修订版本。如果 Deployment 的当前状态不稳定回滚到较早的 Deployment 版本。每次回滚都会更新 Deployment 的修订版本。扩大 Deployment 规模以承担更多负载。暂停 Deployment 以应用对 PodTemplateSpec 所作的多项修改 然后恢复其执行以启动新的上线版本。使用 Deployment 状态来判定上线过程是否出现停滞。清理较旧的不再需要的 ReplicaSet 。下面是一个创建 Deployment 的示例。其中 创建了一个 ReplicaSet负责启动三个 nginx PodapiVersion: apps/v1 kind: Deployment metadata:name: nginx-deploymentlabels:app: nginx spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.14.2ports:- containerPort: 80按照以下步骤创建上述 Deployment 通过运行以下命令创建 Deployment kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml运行 kubectl get deployments 检查 Deployment 是否已创建。如果仍在创建 Deployment则输出类似于NAME               READY   UP-TO-DATE   AVAILABLE   AGE nginx-deployment   0/3     0            0           1s在检查集群中的 Deployment 时所显示的字段有NAME 列出了集群中 Deployment 的名称。READY 显示应用程序的可用的“副本”数。显示的模式是“就绪个数/期望个数”。UP-TO-DATE 显示为了达到期望状态已经更新的副本数。AVAILABLE 显示应用可供用户使用的副本数。AGE 显示应用程序运行的时间。请注意期望副本数是根据 .spec.replicas 字段设置 3。要查看 Deployment 上线状态运行 kubectl rollout status deployment/nginx-deployment。输出类似于Waiting for rollout to finish: 2 out of 3 new replicas have been updated... deployment nginx-deployment successfully rolled out几秒钟后再次运行 kubectl get deployments。输出类似于NAME               READY   UP-TO-DATE   AVAILABLE   AGE nginx-deployment   3/3     3            3           18s注意 Deployment 已创建全部三个副本并且所有副本都是最新的它们包含最新的 Pod 模板 并且可用。要查看 Deployment 创建的 ReplicaSetRS运行 kubectl get rs。输出类似于NAME                          DESIRED   CURRENT   READY   AGE nginx-deployment-75675f5897   3         3         3       18sReplicaSet 输出中包含以下字段NAME 列出名字空间中 ReplicaSet 的名称DESIRED 显示应用的期望副本个数即在创建 Deployment 时所定义的值。此为期望状态CURRENT 显示当前运行状态中的副本个数READY 显示应用中有多少副本可以为用户提供服务AGE 显示应用已经运行的时间长度。【注意】ReplicaSet 的名称始终被格式化为[Deployment名称]-[随机字符串]。其中的随机字符串是使用 pod-template-hash 作为种子随机生成的。要查看每个 Pod 自动生成的标签运行 kubectl get pods --show-labels。返回以下输出NAME                                READY     STATUS    RESTARTS   AGE       LABELS nginx-deployment-75675f5897-7ci7o   1/1       Running   0          18s       appnginx,pod-template-hash3123191453 nginx-deployment-75675f5897-kzszj   1/1       Running   0          18s       appnginx,pod-template-hash3123191453 nginx-deployment-75675f5897-qqcnn   1/1       Running   0          18s       appnginx,pod-template-hash3123191453所创建的 ReplicaSet 确保总是存在三个 nginx Pod。说明你必须在 Deployment 中指定适当的选择算符和 Pod 模板标签在本例中为 app: nginx。标签或者选择算符不要与其他控制器包括其他 Deployment 和 StatefulSet重叠。Kubernetes 不会阻止你这样做但是如果多个控制器具有重叠的选择算符 它们可能会发生冲突执行难以预料的操作。关于 Deployment 的更多信息请查看https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/Horizontal Pod Autoscaler(HPA)上面我们讲解过 RC、RS、Deployment 可以扩容或缩容 Pod 的副本数量也可以手工执行 kubectl scale 命令实现 Pod 的扩容或缩容。如果 k8s 的功能仅仅到此为止很显然不符合谷歌对 k8s 的定位目标 —— **自动化、智能化**。在谷歌看来分布式系统要能够根据当前负载的变化自动触发水平扩容或缩容因此这一过程可能是频繁发生的不可预测的所以手动触发控制的方式是不实际的。因此在 k8s v1.0 版本实现后就有人在默默研究 Pod 智能化的扩容特性了并在 k8s v1.1 版本中首次发布了重量级新特性 —— HorizontalPodAutoscaler简称 HPAPod 水平自动扩缩。在 k8s 中HPA 自动更新工作负载资源 例如 Deployment 或者 StatefulSet目的是自动扩缩工作负载以满足需求。水平扩缩意味着对增加的负载的响应是部署更多的 Pods。这与 “垂直Vertical/ VPA” 扩缩不同对于 k8s VPA 垂直扩缩意味着将更多资源例如内存或 CPU分配给已经为工作负载运行的 Pod。如果负载减少并且 Pod 的数量高于配置的最小值 HPA 会指示工作负载资源 Deployment、StatefulSet 或其他类似资源缩减。水平 Pod 自动扩缩不适用于无法扩/缩容的对象例如DaemonSet 。HPA 与之前的 RC、RS、Deployment 一样也属于一种 k8s 资源对象HPA 被实现为 k8s API 资源Resources和控制器Controller。资源决定了 Controller 控制器的行为。在 k8s 控制平面kube-controller-manager内运行的水平 Pod 自动扩 / 缩控制器会定期调整其目标例如Deployment的所需规模以匹配观察到的指标 例如平均 CPU 利用率、平均内存利用率或你指定的任何其他自定义指标。HPA 工作原理HPA 通过追踪分析指定 RC目前 k8s 新版本已经使用 RS 替换 RC 控制器的所有目标 Pod 的负载变化情况来确定是否需要有针对性地调整目标 Pod 的副本数量这是 HPA 的实现原理。HPA 的常见用途是将其配置为从聚合 API metrics.k8s.io、custom.metrics.k8s.io 或 external.metrics.k8s.io获取指标。metrics.k8s.io API 通常由名为 Metrics Server 的插件提供需要单独启动。HPA 控制器访问支持扩缩的相应工作负载资源例如Deployments 和 StatefulSet。这些资源每个都有一个名为 scale 的子资源该接口允许你动态设置副本的数量并检查它们的每个当前状态。大概的控制流程如下HPA Deployment内置 Scale RS内置 Scale Podk8s 将 HPA 实现为一个间歇运行的控制回路它不是一个连续的过程。间隔由 kube-controller-manager 的 --horizontal-pod-autoscaler-sync-period 参数设置默认间隔为 15 秒。在每个时间段内kube-controller-manager 都会根据每个 HPA 定义中指定的指标查询资源利用率。控制器管理器找到由 scaleTargetRef 定义的目标资源然后根据目标资源的 .spec.selector 标签选择 Pod 并从 资源指标 API针对每个 Pod 的资源指标 或 自定义指标适用于所有其他指标 获取指标 API。当前 HPA 有以下两种方式作为 Pod 负载的度量指标CPUUtilizationPercentage它是一个算术平均值即目标 Pod 所有副本自身的 CPU 利用率的平均值。应用程序自定义的度量指标比如服务在每秒内的相应请求数TPS 或 QPS。HPA 算法细节从最基本的角度来看HPA 控制器根据 当前指标currentMetricValue 和 期望指标desiredMetricValue 来计算扩缩比例。desiredReplicas  ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )] 期望副本数  ceil[当前副本数 * (当前指标 / 期望指标)]CPUUtilizationPercentage一个 Pod 自身 CPU 的利用率是该 Pod 当前 CPU 的使用量除以它的 Pod Request 的值。举个 “栗子”比如定义一个 Pod 的 Pod Request 的值为 0.4而当前 Pod 的 CPU 使用量为 0.2 则它的 CPU 使用率为 50%【》(0.2 / 0.4 ) * 100%】这样就可以推算出一个 RC/RS/Deployment 控制的所有 Pod 副本的 CPU 利用率的算术平均值了。如果某一时刻 CPUUtilizationPercentage 的值超过 80%则意味着当前 Pod 副本数量很可能不足以支撑下来更多的请求需要进行动态扩容而在请求高峰时段过去后Pod 的 CPU 利用率又会下降此时对应的 Pod 副本数量应该自动缩减到一个合理的水平。如果目标 Pod 没有定义 Pod Request 的值则无法使用 CPUUtilizationPercentage 实现 Pod 的水平自动扩缩容。HPA 资源监控指标 —— Metrics Serverk8s 中为了更好的支持 HAP 和其他需要用到基础性能数据的功能模块在 k8s v1.7 版本开始自身孵化了一个 基础性能数据采集监控框架 —— k8s Monitoring Architecture在这其中 k8s 定义了一套 标准化的 API 接口 Resource Metrics API更佳方便了客户端应用程序HPA从 Metrics Server 中获取目标资源对象的性能数据例如容器的 CPU 和 Memory 内存的使用数据。【度量资源用量】1、CPU 报告为以 cpu 为单位测量的平均核心使用率。在 k8s 中 一个 cpu 相当于云提供商的 1 个 vCPU/Core以及裸机 Intel 处理器上的 1 个超线程。该值是通过对内核提供的累积 CPU 计数器在 Linux 和 Windows 内核中取一个速率得出的。用于计算 CPU 的时间窗口显示在 Metrics API 的窗口字段下。要了解更多关于 Kubernetes 如何分配和测量 CPU 资源的信息请参阅 CPU 的含义。2、内存memory报告为在收集度量标准的那一刻的工作集大小以字节为单位。在理想情况下“工作集”是在内存压力下无法释放的正在使用的内存量。然而工作集的计算因主机操作系统而异并且通常大量使用启发式算法来产生估计。Kubernetes 模型中容器工作集是由容器运行时计算的与相关容器关联的匿名内存。工作集指标通常还包括一些缓存文件支持内存因为主机操作系统不能总是回收页面。要了解有关 Kubernetes 如何分配和测量内存资源的更多信息 请参阅 内存的含义。在 CPUUtilizationPercentage 计算过程中使用到的 Pod 的 CPU 使用量通常是 1min 内的平均值通过查询 Metrics Server 监控指标来得到该值在 k8s 早期版本中使用 Heapster 来获取监控值。metrics-server 从 kubelet 中获取资源指标并通过 Metrics API 在 k8s API 服务器中公开它们以供 HPA 和 VPA 使用。你还可以使用 kubectl top 命令查看这些指标。metrics-server 使用 k8s API 来跟踪集群中的 Node 和 Pod。metrics-server 服务器通过 HTTP 查询每个 Node 以获取指标。metrics-server 还构建了 Pod 元数据metadata 的内部视图并维护 Pod 健康状况的缓存。缓存的 Pod 健康信息可通过 metrics-server 提供的扩展 API 获得。例如对于 HPA 查询metrics-server 需要确定哪些 Pod 满足 Deployment 中的 标签选择器Label Selector。metrics-server 调用 kubelet API 从每个节点收集指标。根据它使用的度量服务器版本版本 v0.6.0 中使用指标资源端点 /metrics/resource旧版本中使用 Summary API 端点 /stats/summary关于 metrics-server 的更多信息请查看https://kubernetes.io/zh-cn/docs/tasks/debug/debug-cluster/resource-metrics-pipeline/#metrics-serverHPA 演练示例基于多项度量指标和自定义度量指标自动扩缩利用 autoscaling/v2 API 版本你可以在自动扩缩 myweb-aspnetcore 这个 Deployment 时使用其他度量指标。下面的 yaml 文件定义示例中演示了三种度量指标resource metric资源度量指标它表示容器上指定资源的百分比目前支持的资源有 CPU 和 Memory 。custom metrics自定义度量指标即 Pod 度量指标 和 Object 度量指标 这些度量指标可能具有特定于集群的名称并且需要更高级的集群监控设置。如果 yaml 文件中指定了多个上述类型的度量指标HPA 将会依次考量各个指标并计算每一个指标所提议的副本数量然后最终选择一个最高值。需要注意的是targetCPUUtilizationPercentage 字段已经被名为 metrics 的数组所取代。apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata:name: myweb-aspnetcore spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: myweb-aspnetcoreminReplicas: 1maxReplicas: 10metrics:- type: Resourceresource:name: cputarget:type: UtilizationaverageUtilization: 50- type: Podspods:metric:name: packets-per-secondtarget:type: AverageValueaverageValue: 1k- type: Objectobject:metric:name: requests-per-seconddescribedObject:apiVersion: networking.k8s.io/v1kind: Ingressname: main-routetarget:type: Valuevalue: 10k status:observedGeneration: 1lastScaleTime: some-timecurrentReplicas: 1desiredReplicas: 1currentMetrics:- type: Resourceresource:name: cpucurrent:averageUtilization: 0averageValue: 0- type: Objectobject:metric:name: requests-per-seconddescribedObject:apiVersion: networking.k8s.io/v1kind: Ingressname: main-routecurrent:value: 10k上的 yaml 文件定义中HPA 将会尝试确保每个 Pod 的 CPU 利用率在 50% 以内每秒能够服务 1000 个数据包请求并确保所有在 Ingress 后的 Pod 每秒能够服务的请求总数达到 10000 个。除了上面的定义 yaml 文件并且调用 kubectl create 命令来创建一个 HPA 资源对象的方式还可以通过下面的简单命令行直接创建等价的 HPA 对象kubectl autoscale deployment myweb-aspnetcore --help关于 HPA 更多的示例请查看https://kubernetes.io/zh-cn/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/VerticalPodAutoscaler (VPA)VPA 简介与 HPA 不同Vertical Pod Autoscaler(VPA) / Pod 垂直自动扩缩使用户无需为其 Pod 中的容器设置最新的资源限制和请求。配置后它将根据使用情况自动设置请求从而允许对节点进行适当的调度以便为每个 Pod 提供适当的资源量。它还将保持初始容器配置中指定的限制和请求之间的比率。VPA 既可以缩小过度请求资源的 Pod也可以根据资源随时间推移的使用情况对资源请求不足的升级 Pod。自动缩放配置了一个名为 VerticalPodAutoscaler 的 自定义资源定义对象。它允许指定哪些 Pod 应垂直自动缩放以及是否/如何应用资源建议。VPA 版本介绍VPA 当前默认版本是 v0.11.0各版本兼容性如下VPA 版本Kubernetes version0.111.220.101.220.91.160.81.130.4 至 0.71.110.3.X 及更低1.7VPA 资源对象的 yaml 文件示例关于 VPA 的安装步骤此处不再说明请自行查阅相关资料文献接下来我们看下 VPA 资源的 yaml 文件定义apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler metadata:name: nginx-vpa spec:targetRef:apiVersion: apps/v1kind: Deploymentname: nginx updatePolicy:updateMode: Off resourcePolicy:containerPolicies:- containerName: *minAllowed:cpu: 20mmemory: 50MimaxAllowed:cpu: 1memory: 500MicontrolledResources: [cpu, memory] --- apiVersion: apps/v1 kind: Deployment metadata:name: nginxlabels:app: nginx spec:replicas: 2selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.7.8ports:- containerPort: 80resources:requests:cpu: 100mmemory: 250Mi关于 VPA 的更多信息请查看https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler#readme https://discuss.kubernetes.io/t/vertical-pod-autoscaler-vpa-not-updating-request-limits/18603DaemonSetDaemonSet 的功效与应用DaemonSet简称 DS 确保全部或者某些Node 上运行一个 Pod Container 容器的副本。当有 Node 加入集群时 也会为他们新增一个 Pod 。当有 Node 从集群移除时这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。DaemonSet 的一些典型用法日志收集在每个节点上运行日志收集守护进程比如 fluentdlogstash 等。系统监控在每个节点上运行监控守护进程比如 Prometheus Node ExportercollectdNew Relic agentGanglia gmond 等。系统程序在每个节点上运行集群守护进程比如 kube-proxy, kube-dns, glusterd, ceph 等。一种简单的用法是 为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。一个稍微复杂的用法是 为同一种守护进程部署多个 DaemonSet每个具有不同的标志并且对不同硬件类型具有不同的 Memory内存、CPU 要求。DaemonSet 的 yaml 定义文件示例例如使用 Fluentd 收集日志的 YAML 文件定义apiVersion: apps/v1 kind: DaemonSet metadata:name: fluentd-elasticsearchnamespace: kube-systemlabels:k8s-app: fluentd-logging spec:selector:matchLabels:name: fluentd-elasticsearchtemplate:metadata:labels:name: fluentd-elasticsearchspec:tolerations:# 这些容忍度设置是为了让该守护进程集在控制平面节点上运行# 如果你不希望自己的控制平面节点运行 Pod可以删除它们- key: node-role.kubernetes.io/control-planeoperator: Existseffect: NoSchedule- key: node-role.kubernetes.io/masteroperator: Existseffect: NoSchedulecontainers:- name: fluentd-elasticsearchimage: quay.io/fluentd_elasticsearch/fluentd:v2.5.2resources:limits:cpu: 300mmemory: 500Mirequests:cpu: 100mmemory: 200MivolumeMounts:- name: varlogmountPath: /var/log- name: varlibdockercontainersmountPath: /var/lib/docker/containersreadOnly: trueterminationGracePeriodSeconds: 30volumes:- name: varloghostPath:path: /var/log- name: varlibdockercontainershostPath:path: /var/lib/docker/containersDaemonSet 与 Deployments 的区别DaemonSet 与 Deployments 非常类似 它们都能创建 Pod并且 Pod 中的进程都不希望被终止例如Web 服务器、存储服务器。建议为无状态的服务使用 Deployments比如前端服务。对这些服务而言对副本的数量进行扩缩容、平滑升级比精确控制 Pod 运行在某个主机上要重要得多。当需要 Pod 副本总是运行在全部或特定主机上并且当该 DaemonSet 提供了节点级别的功能允许其他 Pod 在该特定节点上正确运行时 应该使用 DaemonSet。例如网络插件 通常包含一个以 DaemonSet 运行的组件。这个 DaemonSet 组件确保它所在的节点的集群网络正常工作。关于 DaemonSet  的更多信息请查看https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/daemonset/#running-pods-on-only-some-nodes除了 DaemonSet 外以下这些特性也可以做到类似 DaemonSet 的功效接下来我们会逐个介绍。将 Pod 分配给指定 Node DS 的等效替换方案DaemonSet 会忽略 Node 的 unschedulable 状态有两种方式来指定 Pod 只运行在指定的 Node节点上nodeSelector只调度到匹配指定 label 的 Node 上。nodeAffinity功能更丰富的 Node 选择器比如支持集合操作。podAffinity调度到满足条件的 Pod 所在的 Node 上。nodeSelectornodeSelector 提供了一种最简单的方法来将 Pod 约束到具有特定标签的节点上。【nodeSelector 示例】首先给 Node 打上标签 labelkubectl label nodes node-01 disktypessd然后在 daemonset 中指定 nodeSelector 为 disktypessdspec:nodeSelector:disktype: ssdnodeAffinity亲和性 podAntiAffinity反亲和性与 nodeSelector 相比亲和性和反亲和性扩展了你可以定义的约束类型。使用亲和性与反亲和性的一些好处有亲和性nodeAffinity与反亲和性podAntiAffinity语言的表达能力更强。nodeSelector 只能选择拥有所有指定标签的 Node。亲和性、反亲和性为你提供对选择逻辑的更强控制能力。你可以标明某规则是 “软需求” 或者 “偏好”这样调度器在无法找到匹配节点时仍然调度该 Pod。你可以使用节点上或其他拓扑域中运行的其他 Pod 的标签来实施调度约束 而不是只能使用 Node 本身的标签。这个能力让你能够定义规则允许哪些 Pod 可以被放置在一起。亲和性功能由两种类型的亲和性组成节点亲和性nodeAffinity 功能类似于 nodeSelector 字段但它的表达能力更强并且允许你指定软规则。Pod 间亲和性podAffinity 反亲和性podAntiAffinity 允许你根据其他 Pod 的标签来约束 Pod。说明如果你同时指定了 nodeSelector 和 nodeAffinity两者 必须都要满足才能将 Pod 调度到候选节点上。如果你指定了多个与 nodeAffinity 类型关联的 nodeSelectorTerms 只要其中一个 nodeSelectorTerms 满足的话Pod 就可以被调度到节点上。如果你指定了多个与同一 nodeSelectorTerms 关联的 matchExpressions 则只有当所有 matchExpressions 都满足时 Pod 才可以被调度到节点上。亲和性与反亲和性是 Pod 中的属性更多信息请查看https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinityweight节点亲和性权重你可以为 preferredDuringSchedulingIgnoredDuringExecution 亲和性类型的每个实例设置 weight 字段其取值范围是 1 到 100。当调度器找到能够满足 Pod 的其他调度请求的节点时调度器会遍历节点满足的所有的偏好性规则 并将对应表达式的 weight 值加和。最终的加和值会添加到该节点的其他优先级函数的评分之上。在调度器为 Pod 作出调度决定时总分最高的节点的优先级也最高。nodeAffinity节点亲和性nodeAffinity 目前支持两种requiredDuringSchedulingIgnoredDuringExecution硬性必须满足条件。调度器只有在规则被必须满足的时候才能执行调度。此功能类似于 nodeSelector 但其语法表达能力更强。preferredDuringSchedulingIgnoredDuringExecution软性可选尝试满足条件。调度器会尝试寻找满足对应规则的节点。如果找不到匹配的 Node调度器仍然会调度该 Pod。【nodeAffinity 示例】比如下面的例子代表调度到包含 label 标签 kubernetes.io/e2e-az-name 并且 values 值为 e2e-az1 或 e2e-az2 的 Node上并且优选还带有标签 another-node-label-keyanother-node-label-value 的 Node。apiVersion: v1 kind: Pod metadata:name: with-node-affinity spec:affinity:nodeAffinity:# 必须满足条件requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/e2e-az-nameoperator: Invalues:- e2e-az1- e2e-az2# 优先满足条件preferredDuringSchedulingIgnoredDuringExecution:# 节点亲和性权重- weight: 1preference:matchExpressions:- key: another-node-label-keyoperator: Invalues:- another-node-label-valuecontainers:- name: with-node-affinityimage: gcr.io/google_containers/pause:2.0podAffinity Pod 间亲和性podAffinity 基于 Pod 的标签来选择 Node仅调度到满足条件 Pod 所在的 Node 上支持 podAffinityPod 亲和性 和 podAntiAffinityPod 反亲和性。这个功能比较绕举个 “栗子”【podAffinity 示例】如果一个 “ Node 所在 Zone 中包含至少一个带有 securityS1 标签且运行中的 Pod ”那么可以调度到该 Node 。不调度到 “包含至少一个带有 securityS2 标签且运行中 Pod” 的 Node 上。apiVersion: v1 kind: Pod metadata:name: with-pod-affinity spec:affinity:# pod 亲和性podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: securityoperator: Invalues:- S1topologyKey: failure-domain.beta.kubernetes.io/zone# pod 反亲和性podAntiAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 100podAffinityTerm:labelSelector:matchExpressions:- key: securityoperator: Invalues:- S2topologyKey: kubernetes.io/hostnamecontainers:- name: with-pod-affinityimage: gcr.io/google_containers/pause:2.0Taint污点和 Toleration容忍度nodeAffinity节点亲和性 是 Pod 的一种属性它使 Pod 被吸引到一类特定的节点 这可能出于一种偏好也可能是硬性要求。污点Taint 则相反——它使节点能够排斥一类特定的 Pod。容忍度Toleration 是应用于 Pod 上的。容忍度允许调度器调度带有对应污点的 Pod。容忍度允许调度但并不保证调度作为其功能的一部分 调度器也会评估其他参数。污点和容忍度Toleration相互配合可以用来避免 Pod 被分配到不合适的节点上。每个节点上都可以应用一个或多个污点这表示对于那些不能容忍这些污点的 Pod 是不会被该节点接受的。Static Pod静态Pod除了 DaemonSet还可以使用 静态 Pod 来在每台机器上运行指定的 Pod这需要 kubelet 在启动的时候指定 manifest 目录kubelet --pod-manifest-path/etc/kubernetes/manifests然后将所需要的 Pod 定义文件放到指定的 manifest 目录中。【注意】静态 Pod 不能通过 API Server 来删除但可以通过删除 manifest 文件来自动删除对应的 Pod。未完待续先分享到这里想了解更多 k8s 中常用的资源对象敬请期待 下一篇文章 继续讲解。
http://www.zqtcl.cn/news/346119/

相关文章:

  • 天津网站建设班模拟网站建设软件有哪些
  • 服务类的网站怎么做做软件的网站担保网站
  • 最新电子产品网站模板海口网站排名提升
  • 北京社保网站减员怎么做phpcms v9 实现网站搜索
  • 视频运营管理网站济南网站建设 济南货梯
  • html电影网站模板下载工具阿里云网站建设 部署与发布笔记
  • 建设跨境网站微信seo是什么意思
  • 我做彩票网站开发彩票网站搭建织梦如何仿手机网站源码下载
  • 东仓建设网站手机便宜的网站建设
  • 吕梁市住房与城乡建设厅网站wordpress 乐趣公园
  • 沈阳正规制作网站公司吗德成建设集团有限公司网站
  • 做网站标准步骤大学两学一做专题网站
  • 如何在手机上做网站Windows怎么建设网站
  • 专门做稀有产品的网站海口网站制作设计
  • 怎么查看自己的网站是否被百度收录网站的设计制作流程
  • 视觉设计网站芜湖做网站找哪家好
  • flash网站源码带asp后台电子商务有限公司网站
  • 一个网站有多少网页简单的logo设计
  • 重庆专业网站营销长春建站免费模板
  • 企业建设网站多少钱爱的网站歌曲
  • 宁波网站优化如何欣宝儿在什么网站做直播
  • 东营网签查询系统官方网站超炫的网站模板
  • 请人做网站谁来维护南宁营销型网站设计
  • 汕头做网站的公司西安建筑科技大学华清学院教务网
  • 免费行情网站在线石家庄正规制作网站公司
  • 站长工具网凡科网商城
  • 网站开发工程师需要会写什么区别沈阳网站建设建设公司哪家好
  • 营销型网站建设的优缺点利用海康威视做直播网站
  • 阿里手机网站开发框架怎么看网站被降权
  • 电视台做网站还是APP网络推广是什么意思