【k8s概念】一文搞懂k8s核心概念!!!(中)

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
应用型负载均衡 ALB,每月750个小时 15LCU
简介: 【k8s概念】一文搞懂k8s核心概念!!!(中)

4.3 Pod控制器

在介绍工作负载资源相关概念之前,先介绍一下Pod控制器(Controller)的概念,那什么是Pod控制器呢?

Pod控制器是用于实现管理pod的中间层。使用Pod控制器之后,只需要告诉Pod控制器,想要多少个什么样的Pod就可以了,它会创建出满足条件的Pod并确保每一个Pod资源处于用户期望的目标状态。如果Pod资源在运行中出现故障,它会基于指定策略重新编排Pod。


在kubernetes中,按照pod的创建方式可以将其分为两类:

自主式pod:kubernetes直接创建出来的Pod,这种pod删除后就没有了,也不会重建

控制器创建的pod:kubernetes通过控制器创建的pod,这种pod删除了之后还会自动重建


Pod和Controller关系

(1)Pod是通过Controller实现应用的运维,比如伸缩、滚动升级等等

(2)Pod和Controller之间通过label标签关系


4.3.1 ReplicationController(RC)

当我们定义了一个 ReplicationController(RC)并提交到 Kubernetes 集群中以后,Master 节点上的 Controller Manager 组件就得到通知,定期检查系统中存活的 Pod,并确保目标 Pod 实例的数量刚好等于 RC 的预期值,如果有过多或过少的 Pod 运行,系统就会停掉或创建一些 Pod。此外我们也可以通过修改 RC 的副本

数量,来实现 Pod 的动态缩放功能。RC是一种比较原始的pod控制器,已经被废弃,由ReplicaSet替代。


4.3.2 ReplicaSet(RS)

ReplicaSet(RS) 保证Pod副本数量一直维持在期望值,并支持pod的数量扩缩容,镜像版本升级等功能。

ReplicaSet 跟 ReplicationController 没有本质的不同,只是名字不一样,并且ReplicaSet 支持集合式的 selector(ReplicationController 仅支持等式)。Kubernetes 官方强烈建议避免直接使用 ReplicaSet,而应该通过 Deployment 来创建 RS 和Pod。由于 ReplicaSet 是 ReplicationController 的代替物,因此用法基本相同,唯一的区别在于 ReplicaSet 支持集合式的 selector。

RC与RS的区别:

由于 Replication Controller 与 Kubernetes 代码中的模块 Replication Controller 同名, 所以在 Kubernetes v1.2 时, 它就升级成了另外一个新的概念 Replica Set,官方解释为 下一代的 RC,它与 RC 区别是:RS 支持基于集合的 Label selector,而 RC 只支 持基于等式的 Label Selector。我们很少单独使用 ReplicaSet,它主要被 Deployment 这 个更高层面的资源对象所使用,从而形成一整套 Pod 创建、删除、更新的编排机制。最好不要越过 RS 直接创建 Pod, 因为 Replication Set 会通过 RS 管理 Pod 副本,实现自动创建、补足、替换、删除 Pod 副本,这样就能提高应用的容灾能力,减少由于节点 崩溃等意外状况造成的损失。即使应用程序只有一个 Pod 副本,也强烈建议使用 RS 来 定义 Pod。


4.3.3 Deployment

1. 概念

Deployment 为 Pod和Replica Set 提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController来方便的管理应用。

kubernetes为了更好的解决服务编排的问题,在V1.2版本开始,引入了Deployment控制器。这种控制器并不直接管理pod,而是通过管理ReplicaSet来间接管理Pod,即:Deployment管理ReplicaSet,ReplicaSet管理Pod。所以Deployment比ReplicaSet功能更加强大。

2323f68a32c847eab882aef80567bf0a.png


2. Deployment主要功能

● 支持ReplicaSet的所有功能

● 支持发布的停止、继续

● 支持滚动升级和回滚版本

● deployment支持版本升级过程中的暂停、继续功能以及版本回退等诸多功能

金丝雀发布

Deployment控制器支持控制更新过程中的控制,如“暂停(pause)”或“继续(resume)”更新操作。

比如有一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新版本的Pod应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布。

4.3.4 Horizontal Pod Autoscaler(HPA)

Horizontal Pod Autoscal(Pod 横向扩容 简称 HPA)与 RC、Deployment 一样,也属于一种Kubernetes 资源对象。通过追踪分析 RC 控制的所有目标 Pod 的负载变化情况,来确定是否需要针对性地调整目标 Pod 的副本数量,这是 HPA 的 实现原理。

Kubernetes 对 Pod 扩容与缩容提供了手动和自动两种模式,手动模式通过 kubectl scale ... 命令对一个 Deployment/RC 进行 Pod 副本数量的设置。自动模式则需要用户根据某个性能指标或者自定义业务指标,并指定 Pod 副本数量的范围,系统将自动在这个范围内根据性能指标的变化进行调整。

3b74d51c8e634b56bf5392d4b467550c.png


4.3.5 DaemonSet

1. 概念

DaemonSet类型的控制器可以保证在集群中的每一台(或指定)节点上都运行一个副本。一般适用于日志收集、节点监控等场景。也就是说,如果一个Pod提供的功能是节点级别的(每个节点都需要且只需要一个),那么这类Pod就适合使用DaemonSet类型的控制器创建。

a0b3a443b9a6444b8f8225edffb254f0.png

2. 特点

● 每当向集群中添加一个节点时,指定的 Pod 副本也将添加到该节点上

● 当节点从集群中移除时,Pod 也就被垃圾回收了


4.3.6 StatefulSet

StatefulSet 是用来管理有状态应用的工作负载 API 对象。

StatefulSet 用来管理某 Pod 集合的部署和扩缩,并为这些 Pod 提供持久存储和持久标识符

和 Deployment 类似, StatefulSet 管理基于相同容器规约的一组 Pod。但和 Deployment 不同的是, StatefulSet 为它们的每个 Pod 维护了一个有粘性的 ID。这些 Pod 是基于相同的规约来创建的, 但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。


4.3.7 Cronjob

CronJob控制器以Job控制器资源为其管控对象,并借助它管理pod资源对象,Job控制器定义的作业任务在其控制器资源创建之后便会立即执行,但CronJob可以以类似于Linux操作系统的周期性任务作业计划的方式控制其运行时间点及重复运行的方式。也就是说,CronJob可以在特定的时间点(反复的)去运行job任务。

1465d5363e644fb1b71627aa2ea44696.png

4.3.8 Job

Job,主要用于负责批量处理(一次要处理指定数量任务)短暂的一次性(每个任务仅运行一次就结束)任务。Job特点如下:

● 当Job创建的pod执行成功结束时,Job将记录成功结束的pod数量

● 当成功结束的pod达到指定的数量时,Job将完成执行


4.4 服务发现

4.4.1 Service
1. 概念

在kubernetes中,pod是应用程序的载体,我们可以通过pod的ip来访问应用程序,但是pod的ip地址不是固定的,这也就意味着不方便直接采用pod的ip对服务进行访问。

为了解决这个问题,kubernetes提供了Service资源,Service会对提供同一个服务的多个pod进行聚合,并且提供一个统一的入口地址。通过访问Service的入口地址就能访问到后面的pod服务。

Service在很多情况下只是一个概念,真正起作用的其实是kube-proxy服务进程,每个Node节点上都运行着一个kube-proxy服务进程。当创建Service的时候会通过api-server向etcd写入创建的service的信息,而kube-proxy会基于监听的机制发现这种Service的变动,然后它会将最新的Service信息转换成对应的访问规则。

0d792b23ca0345ae980df92bfd5419b7.png

2. kube-proxy三种工作模式

① userspace 模式

userspace模式下,kube-proxy会为每一个Service创建一个监听端口,发向Cluster IP的请求被Iptables规则重定向到kube-proxy监听的端口上,kube-proxy根据LB算法选择一个提供服务的Pod并和其建立链接,以将请求转发到Pod上。 该模式下,kube-proxy充当了一个四层负载均衡器的角色。由于kube-proxy运行在userspace中,在进行转发处理时会增加内核和用户空间之间的数据拷贝,虽然比较稳定,但是效率比较低。

067fd79bf24f44d7aee2790a1ece69c0.png

② iptables 模式

iptables模式下,kube-proxy为service后端的每个Pod创建对应的iptables规则,直接将发向Cluster IP的请求重定向到一个Pod IP。 该模式下kube-proxy不承担四层负载均衡器的角色,只负责创建iptables规则。该模式的优点是较userspace模式效率更高,但不能提供灵活的LB策略,当后端Pod不可用时也无法进行重试。

45fa88a2c6a846f5a6f1114a1a657e91.png

③ ipvs 模式

ipvs模式和iptables类似,kube-proxy监控Pod的变化并创建相应的ipvs规则。ipvs相对iptables转发效率更高。除此以外,ipvs支持更多的LB算法。

36d290a332f04b0ba3c9e656e1dc257f.png

3. Service常用类型

ClusterIP:默认值,它是Kubernetes系统自动分配的虚拟IP,只能在集群内部访问

NodePort:将Service通过指定的Node上的端口暴露给外部,通过此方法,就可以在集群外部访问服务

LoadBalancer:使用外接负载均衡器完成到服务的负载分发,注意此模式需要外部云环境支持

ExternalName: 把集群外部的服务引入集群内部,直接使用


1. ClusterIP类型的Service

Endpoint是kubernetes中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址,它是根据service配置文件中selector描述产生的。

一个Service由一组Pod组成,这些Pod通过Endpoints暴露出来,Endpoints是实现实际服务的端点集合。换句话说,service和pod之间的联系是通过Endpoints实现的。

7f8ca5f7e1574635a3cf1238a17e6014.png

2. NodePort类型的Service

通过ClusterIp暴露出的IP地址只有集群内部才可以访问,如果希望将Service暴露给集群外部使用,那么就要使用到NodePort类型的Service。NodePort的工作原理其实就是将service的端口映射到Node的一个端口上,然后就可以通过NodeIp:NodePort来访问service了。

56b8ef6fc79e457886592a0b9a160dc8.png

3. LoadBalancer类型的Service

LoadBalancer和NodePort很相似,目的都是向外部暴露一个端口,区别在于LoadBalancer会在集群的外部再来做一个负载均衡设备,而这个设备需要外部环境支持的,外部服务发送到这个设备上的请求,会被设备负载之后转发到集群中。

0d8324b9eea548efad650e47c55114c1.png

4. ExternalName类型的Service

ExternalName类型的Service用于引入集群外部的服务,它通过externalName属性指定外部一个服务的地址,然后在集群内部访问此service就可以访问到外部的服务了。

19c55af27e1c42b09a64c31961564f44.png

5. HeadLiness类型的Service

在某些场景中,开发人员可能不想使用Service提供的负载均衡功能,而希望自己来控制负载均衡策略,针对这种情况,kubernetes提供了HeadLiness Service,这类Service不会分配Cluster IP,如果想要访问service,只能通过service的域名进行查询。


4.4.2 Ingress

参考文章:https://blog.csdn.net/L2111533547/article/details/126248597

https://blog.csdn.net/WuDan_1112/article/details/126234642

https://blog.csdn.net/weixin_64124795/article/details/128999344

Kubernetes暴露服务的方式目前只有三种:LoadBlancer Service、NodePort Service、Ingress。

简单说,Ingress是一个代理,可以根据配置转发请求到指定的服务上。


1. 基本概念

Ingress概念:和之前提到的Service、Deployment,也是一个k8s的资源类型,ingress用于实现用域名的方式访问k8s内部应用。

Ingress为Kubernetes集群中的服务提供了入口,可以提供负载均衡、SSL终止和基于名称的虚拟主机,在生产环境中常用的Ingress有Treafik、Nginx、HAProxy、Istio等。


在Kubernetesv 1.1版中添加的Ingress用于从集群外部到集群内部Service的HTTP和HTTPS路由,流量从Internet到Ingress再到Services最后到Pod上,通常情况下,Ingress部署在所有的Node节点上。

Ingress可以配置提供服务外部访问的URL、负载均衡、终止SSL,并提供基于域名的虚拟主机。但Ingress不会暴露任意端口或协议。

b048706e895a4391b00e3e9f812b174d.png

2. 为什么需要Ingress资源

由于K8S集群拥有强大的副本控制能力,Pod随时可能从一个节点上被驱逐到另一个节点上,或者直接销毁再来一个新的。

然而伴随着Pod的销毁和重生,Pod的IP等信息不断地在改变,此时使用K8S提供的Service机制可以解决这一问题,Service通过标签选定指定的Pod作为后端服务,并监听这些Pod的变化。

在对外暴露服务时,使用Service的NodePort是一个方法,同时也有问题存在:


Q1-如何管理端口

当需要对外暴露的服务量比较多的时候,端口管理的问题变会暴露出来。

此时的一个处理方案是使用一个代理服务(例如nginx)根据请求信息将请求转发到不同的服务器上。

Q2-如何管理转发配置

每当有新服务加入,都需要对该服务的配置进行修改、升级,在服务数量逐渐变多后,该配置项目会变得越来越大,手工修改的风险也会逐渐增高。

那么需要一个工具来简化这一过程,希望可以通过简单的配置动态生成代理中复杂的配置,最好还可以顺手重新加载配置文件。

K8S刚好也提供了此类型资源。

a. Pod漂移问题

众所周知 Kubernetes 具有强大的副本控制能力,能保证在任意副本(Pod)挂掉时自动从其他机器启动一个新的,还可以动态扩容等,总之一句话,这个 Pod 可能在任何时刻出现在任何节点上,也可能在任何时刻死在任何节点上;那么自然随着 Pod 的创建和销毁,Pod IP 肯定会动态变化;那么如何把这个动态的 Pod IP 暴露出去?


这里借助于 Kubernetes 的 Service 机制,Service 可以以标签的形式选定一组带有指定标签的 Pod,并监控和自动负载他们的 Pod IP,那么我们向外暴露只暴露 Service IP 就行了;这就是 NodePort 模式:即在每个节点上开起一个端口,然后转发到内部 Pod IP 上,如下图所示

ff364390c01d4c86b9d47b25b9d60849.png

b. 端口管理问题

采用 NodePort 方式暴露服务面临一个坑爹的问题是,服务一旦多起来,NodePort 在每个节点上开启的端口会及其庞大,而且难以维护;这时候引出的思考问题是 “能不能使用 Nginx 啥的只监听一个端口,比如 80,然后按照域名向后转发?

这思路很好,简单的实现就是使用 DaemonSet 在每个 node 上监听 80,然后写好规则,因为 Nginx 外面绑定了宿主机 80 端口(就像 NodePort),本身又在集群内,那么向后直接转发到相应 Service IP 就行了,如下图所示

6451e72fc0014861a4220eff0611206d.png

c. 域名分配及动态更新问题

从上面的思路,采用 Nginx 似乎已经解决了问题,但是其实这里面有一个很大缺陷:每次有新服务加入怎么改 Nginx 配置?总不能手动改或者来个 Rolling Update 前端 Nginx Pod 吧?这时候 “伟大而又正直勇敢的” Ingress 登场,如果不算上面的 Nginx,Ingress 只有两大组件:Ingress Controller 和 Ingress。


Ingress 简单的理解就是你原来要改 Nginx 配置,然后配置各种域名对应哪个 Service,现在把这个动作抽象出来,变成一个 Ingress 对象,你可以用 yaml 创建,每次不要去改 Nginx 了,直接改 yaml 然后创建/更新就行了;那么问题来了:”Nginx 咋整?”

Ingress Controller 这东西就是解决 “Nginx 咋整” 的;Ingress Controoler 通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化,然后读取他,按照他自己模板生成一段 Nginx 配置,再写到 Nginx Pod 里,最后 reload 一下,工作流程如下图

8082bb1f582c481d85d3b4ad6dadfc2c.png

当然在实际应用中,最新版本 Kubernetes 已经将 Nginx 与 Ingress Controller 合并为一个组件,所以 Nginx 无需单独部署,只需要部署 Ingress Controller 即可。

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
Kubernetes 负载均衡 Perl
kubernetes—五个概念入门(二)
kubernetes—五个概念入门(二)
96 0
|
7天前
|
存储 Kubernetes 负载均衡
k8s原理概念基础入门
k8s原理概念基础入门
57 2
|
13天前
|
存储 Kubernetes 调度
K8S中的核心概念
【6月更文挑战第25天】k8s资源对象可以用yaml或者json格式声明。每个资源对象都有自己的特定结构定义,并统一保存在etcd这种非关系型数据库中。
|
2月前
|
存储 Kubernetes API
Kubernetes学习-核心概念篇(三) 核心概念和专业术语
Kubernetes学习-核心概念篇(三) 核心概念和专业术语
Kubernetes学习-核心概念篇(三) 核心概念和专业术语
|
2月前
|
存储 Kubernetes 负载均衡
k8s 数据流向 与 核心概念详细介绍
k8s 数据流向 与 核心概念详细介绍
|
2月前
|
Kubernetes API 调度
Kubernetes学习-核心概念篇(二) 集群架构与组件
Kubernetes学习-核心概念篇(二) 集群架构与组件
|
2月前
|
Kubernetes 调度 虚拟化
Kubernetes学习-核心概念篇(一) 初识Kubernetes
Kubernetes学习-核心概念篇(一) 初识Kubernetes
|
2月前
|
Kubernetes 测试技术 Docker
K8S中Deployment控制器的概念、原理解读以及使用技巧
K8S中Deployment控制器的概念、原理解读以及使用技巧
|
2月前
|
存储 Kubernetes Docker
Kubernetes(K8S)集群管理Docker容器(概念篇)
Kubernetes(K8S)集群管理Docker容器(概念篇)
|
2月前
|
Kubernetes 网络协议 API
玩转Kubernetes—基础概念篇
玩转Kubernetes—基础概念篇
74 1