• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

LinuxFoundationX LFS158x Introduction to Kubernetes

武飞扬头像
QuantumJar
帮助1

Chapter 1. From Monolith to Microservices

By the end of this chapter, you should be able to:

  • Explain what a monolith is.
  • Discuss the monolith's challenges in the cloud.
  • Explain the concept of microservices.
  • Discuss microservices advantages in the cloud.
  • Describe the transformation path from a monolith to microservices.

Chapter 2. Container Orchestration

By the end of this chapter, you should be able to:

    -   Define the concept of container orchestration.
    -   Explain the benefits of using container orchestration.
    -   Discuss different container orchestration options.
    -   Discuss different container orchestration deployment options.
    
    
  

Although we can manually maintain a couple of containers or write scripts to manage the lifecycle of dozens of containers, orchestrators make things much easier for users especially when it comes to managing hundreds and thousands of containers running on a global infrastructure.

Most container orchestrators can:

    -   Group hosts together while creating a cluster.
    -   Schedule containers to run on hosts in the cluster based on resources availability.
    -   Enable containers in a cluster to communicate with each other regardless of the host they are deployed to in the cluster.
    -   Bind containers and storage resources.
    -   Group sets of similar containers and bind them to load-balancing constructs to simplify access to containerized applications by creating an interface, a level of abstraction between the containers and the client.
    -   Manage and optimize resource usage.
    -   Allow for implementation of policies to secure access to applications running inside containers.

With all these configurable yet flexible features, container orchestrators are an obvious choice when it comes to managing containerized applications at scale. In this course, we will explore Kubernetes, one of the most in-demand container orchestration tools available today.

Chapter 8.  Kubernetes Building Blocks

学完本章节之后,你应该可以:

  • 描述什么是K8S对象模型
  • 讨论K8S的核心模块,比如Node,NameSpaces,Pods,ReplicaSets,Deployments,DaemonSets.
  • 讨论标签和标签选择器

K8S对象模型

K8S因为它先进的应用生命周期管理能力变得十分流行。通过实现一系列丰富的对象模型——它们代表着K8S集群中不同的持久实体。这些实体描述了:

  1. 正在运行的容器化应用程序。 通过定义pod对象来描述容器化应用程序,一个Pod可以运行一个或多个容器,这些容器共享网络和存储资源。

  2. 用于部署容器化应用的节点(Node) 通过定义Node对象来描述集群中的节点,每个节点可以是物理机或者虚拟机,用于运行容器的工作节点。

  3. 应用程序的资源管理 K8S提供了容器运行资源的监控和管理,可以通过在对象中定义资源请求和限制来实现对资源的控制,比如CPU,内存等。

  4. 附加到应用程序的策略(policies) 可以通过定义 Deployment、StatefulSet、DaemonSet 等对象来附加各种策略,如重启/升级策略、容错性、入口/出口、访问控制等。

    对于每个对象,我们在 SPEC中声明我们的意图,或者我们期望的对象的状态。而K8S系统则负责管理每个对象的 status ——表示了对象目前的真实状态。任何时刻,Kubernetes 控制平面都会尝试将对象的实际状态与期望状态保持一致。对象定义清单还必须包括其他字段,用于指定我们参考的 API 的版本(apiVersion)、对象类型(kind)和用于集群或用户的其他有助于帐户管理的数据(metadata)。

Kubernetes 对象类型的示例包括节点(Nodes)、命名空间(Namespaces)、Pod、ReplicaSet、Deployment、DaemonSet 等。接下来,我们将探索这些对象。

创建对象时,需要将对象配置数据部分从 spec 字段以下提交给 Kubernetes API 服务器。创建对象的 API 请求必须具有描述期望状态的 spec 部分以及其他细节。虽然 API 服务器接受 JSON 格式的对象定义,但通常我们使用 YAML 格式提供这些定义清单,kubectl 会将其转换为 JSON 负载并发送给 API 服务器。

Nodes 节点

Kubernetes 中的节点是集群中系统的虚拟身份标识,可以是虚拟机、裸金属服务器、容器等。每个节点都具有唯一的标识,并且用于集群资源的计算和监控,以帮助进行整个集群的工作负载管理。

每一个Node都是由两个节点代理来管理的(kubelet,kube-proxy),同时还需要托管一个容器运行时。容器运行时负责去运行节点上的所有容器化工作负载——包括控制平面代理和用户的工作负载。kubelet和kube-proxy节点代理负责执行所有本地工作负载管理相关的任务——和容器运行时交互来运行容器,监控容器状态和节点健康;给API Server报告问题和节点状态;管理前往容器的网络流量。

根据他们预定义功能的不同,他们被区分为两种不同的节点—— 控制平面节点和工作节点。一个典型的K8S集群必须包含一个控制平面节点,也可以为了HA(高可用)去部署多个控制平面节点。此外,集群中可以拥有一个或者多个工作节点来提供计算资源的冗余。在某些情况下,可以将单个一体化集群启动为单个节点,放置在单个虚拟机、裸金属服务器或容器中,当高可用性和资源冗余不重要时。这些是在同一系统上同时托管控制平面代理和用户工作负载的混合节点。Minikube 允许我们以专用的、独立的控制平面节点引导多节点集群,但如果我们的主机系统具有有限的物理资源,我们可以轻松地将单一个一个地体化集群引导为单个节点,放置在单个虚拟机或容器中,并且仍然能够探索本课程涵盖的大多数主题,但无法使用针对多节点集群特定的功能,如 DaemonSets、多节点网络等。 节点标识是在集群引导过程中由负责初始化集群代理的工具创建和分配的。Minikube 使用默认的 kubeadm 引导工具,在 init 阶段初始化控制平面节点,并通过 join 阶段添加工作节点或控制平面节点来扩展集群。

控制平面节点运行控制平面代理,例如 API Server、调度器、控制器管理器和 etcd,还有 kubelet 和 kube-proxy 节点代理、容器运行时和用于容器网络、监视、日志记录、DNS 等的附加组件。

工作节点运行 kubelet 和 kube-proxy 节点代理、容器运行时和用于容器网络、监视、日志记录、DNS 等的附加组件。

Namespace 名称空间

如果多个用户和团队正在使用一个K8S集群,我们可以使用namespace把集群虚拟的分割成多个子集群。同一个名称空间中,资源/对象的名字都是唯一的,但在集群的不同名称空间中不是唯一的。

查看集群中所有的名称空间 我们可以使用如下命令:

kubectl get namespaces

NAME STATUS AGE default Active 7d1h dev Active 6d9h kube-flannel Active 7d1h kube-node-lease Active 7d1h kube-public Active 7d1h kube-system Active 7d1h

通常情况下,K8S会创建4个名称空间,kube-system,kube-public,kube-node-lease,default。kube-system包含了K8S系统自身创建的对象,主要是一些控制平面管理代理。 default空间主要包括所有由用户创建的,没有明确指定名称空间的对象。 kube-public 是一个特殊的空间,它一个不安全的,任何人都可以读取的,主要用于暴露一些集群的基础信息。 最新的名称空间是 kube-node-lease,它保存用于节点心跳数据的节点租约对象。然而,最佳实践是根据需要创建额外的命名空间,以虚拟化集群并隔离用户、开发团队、应用程序或层次结构:

kubectl create namespace my-namespace

Pods

Pod是K8S中最小的工作负载对象,是K8S部署的单位,代表着一个应用的实例。一个Pod是一个或者多个容器逻辑上的集合,通过封闭隔离他们来保证以下性质:

  • 会被调度到同一个主机上
  • 公用相同的网络,名称空间。这也意味着它们公用同一个ip
  • 可以挂在相同的外部存储和其他的公共依赖

Pods的特质是短暂的,并且也不具备自我修复功能。这也是Pod都和控制器(或者操作器)一同使用的原因——通过控制器,可以实现对Pod的赋值,容错,自愈等等功能。当使用控制器来管理应用程序,Pod的规格参数都嵌入在控制器的Pod Template定义中。 下面是一个独立Pod对象的定义清单。YML格式:

**apiVersion: v1**  
**kind: Pod**  
**metadata:**  
**name: nginx-pod**  
**labels:**  
**run: nginx-pod**  
**spec:**  
**containers:**  
**- name: nginx**  
**image: nginx:1.22.1**  
**ports:**  
**- containerPort: 80**

Pod对象定义中必须指定apiVersion为v1。第二个必需字段是kind,指定Pod对象类型。第三个必需字段metadata,包含对象的名称和可选的标签和注释。第四个必需字段spec标志着定义Pod对象所需状态的块的开始,也称为PodSpec。我们的Pod创建一个单个容器,运行从容器镜像仓库中拉取的nginx:1.22.1镜像,这里使用的是Docker Hub。containerPort字段指定Kubernetes资源暴露的容器端口,用于应用程序间的访问或外部客户端访问(在服务章节中会详细探讨)。spec的内容将用于调度目的,然后所选节点的kubelet负责使用节点的容器运行时运行容器镜像。Pod的名称和标签用于工作负载统计目的。

Label 标签

标签是添加在K8S对象上的键值对。使用标签,可以根据具体的需求,组织和选择出需要的子对象。很多对象可以同时拥有相同的标签。标签不能给对象提供唯一性。控制器使用标签来逻辑上的组织解耦合的对象,而不是通过对象的名字或者ID。

学新通

在上图示中,我们创建了2个标签Key,分别是app和env。根据需求,我们把不同的值分配给了不同的pod。 当我们使用env=dev时。上面的2个pod会被选择。当使用app=frontend时,左边的两个pod会被选择。当我们想选择右上角的pod时。可以使用app=backend,env=dev;

标签选择器 Label Selector

控制器,Service,使用标签选择器来选择一个逻辑上的子对象集。K8S支持两种类型的选择器

  • 基于等式的选择器

基于等式的选择器允许根据标签键和值对对象进行筛选。通过使用=、==(等于,可互换使用)或!=(不等于)运算符来进行匹配。例如,使用env==dev或env=dev,我们选择具有env标签键设置为dev的对象。

  • 基于集合的选择器

基于集合的选择器允许根据一组值对对象进行筛选。我们可以使用in、notin运算符进行标签值的筛选,并使用exist/does not exist运算符进行标签键的筛选。例如,使用env in (dev,qa)我们选择env标签设置为dev或qa的对象;使用!app我们选择没有标签键为app的对象。

副本控制器(ReplicationController)

副本控制器即使不再是推荐使用的控制器了,但是它已然是一个复杂的控制器来保证了在任何时间点,都是指定个数的pod在运行。方式是不断的比较真实的和期望和状态。如果有超过期望个数的pod被检测到,那么RC会随机的结束多余的Pod。反之,如果没有期望个数的Pod在运行,那么RC会启动需要的Pod。

总而言之,我们不会单独的部署pod, 因为pod自身不具有自我修复,容错等功能。推荐的方式是使用不同类型的控制器来管理pod。通常使用Deployment来管理pod的副本,他有一个控制副本的属性。

ReplicaSets

ReplicaSet, 不全面的说,是下一代副本控制器,它实现了ReplicationController复制和自我修补的功能。ReplicaSets支持 等值,集合标签选择器,相比ReplicationController只支持等值选择器。

当只有应用只有一个实例在运行时,总是会有应用崩溃的可能。或者托管应用的服务器整个宕机的风险。如果只依赖单实例的应用崩溃,这里就有极大可能会影响其他应用,服务,或者客户端。为了避免这种失败,我们要同时运行应用的多个实例来提高应用的健壮性,高可用。应用Pod的生命周期可以使用RC来监管。通过RC的帮助,我们可以扩展运行的Pod。扩展功能可以通过手动或者 autoscaler来实现。

在上述描述中,我们以图形方式表示了一个ReplicaSet,并将副本数设置为3,对应一个特定的Pod模板。Pod-1、Pod-2和Pod-3是相同的,运行着相同的应用程序容器镜像,它们是从同一个Pod模板克隆而来的。当前状态与期望状态相匹配。然而,请记住,尽管这三个Pod副本被称为相同的副本 - 运行着相同的应用程序、相同的配置,但它们在身份上仍然是不同的 - Pod名称、IP地址以及Pod对象确保应用程序可以根据调度过程独立地放置在集群的任何工作节点上。

以下是ReplicaSet对象的定义清单,采用YAML格式:

学新通

apiVersion: apps/v1 
kind: ReplicaSet 
metadata: 
    name: frontend 
    labels: 
        app: guestbook 
        tier: frontend 
spec: 
    replicas: 3 
    selector: 
        matchLabels: 
            app: guestbook 
    template: 
        metadata: 
        labels: 
            app: guestbook 
        spec: 
            containers: 
            - name: php-redis
              image: gcr.io/谷歌_samples/gb-frontend:v3

Deployment

Deployment给Pod和ReplicatSets提供了声明式的更新。部署控制器是控制平面的节点一部本,作为一个控制器,它始终保证了当前应用的状态符合我们期望的状态。它允许应用无缝的更新和回滚,也就是RollingUpdate策略——通过rollouts和rollbacks.它直接管理应用的副本集。同时它还支持一个less popular的更新策略。 Recreate.

以下是一个使用YAML格式的部署对象定义示例:

apiVersion: apps/v1 
kind: Deployment 
metadata: 
    name: nginx-deployment 
    labels: 
        app: nginx-deployment 
spec: 
        replicas: 3 selector:
        matchLabels: 
        app: nginx-deployment 
        template: metadata: 
        labels: 
        app: nginx-deployment 
        spec: 
        containers: 
            - name: nginx 
            image: nginx:1.20.2 
            ports: - containerPort: 80

apiVersion字段是第一个必需的字段,它指定我们要连接的API服务器上的API端点;它必须与定义的对象类型的现有版本匹配。第二个必需的字段是kind,指定对象类型 - 在我们的示例中是Deployment,但也可以是Pod、ReplicaSet、Namespace、Service等。第三个必需的字段metadata包含对象的基本信息,如名称、注解、标签、命名空间等。我们的示例显示了两个spec字段(spec和spec.template.spec)。第四个必需的字段spec标志着定义Deployment对象期望状态的块的开始。在我们的示例中,我们要求始终同时运行3个Pod副本。Pods是使用spec.template中定义的Pod模板创建的。作为部署的一部分,嵌套对象(例如Pod)保留其元数据和规范,并且失去了自己的apiVersion和kind,这两者都由template替换。在spec.template.spec中,我们定义了Pod的期望状态。我们的Pod创建一个以来自Docker Hub的nginx:1.20.2镜像运行的单个容器。

学新通 创建Deployment对象后,Kubernetes系统将status字段附加到该对象并填充所有必要的状态字段。

在以下示例中,一个新的Deployment创建了ReplicaSet A,然后创建了3个Pods,每个Pod模板配置为运行一个nginx:1.20.2容器镜像。在这种情况下,ReplicaSet A与nginx:1.20.2相关联,表示Deployment的一种状态。这个特定状态被记录为版本1。

滚动更新是在我们更新Deployment的Pod模板的特定属性时触发的。计划更改(例如更新容器镜像、容器端口、卷和挂载)会触发新的修订版本,而其他动态性质的操作(如扩缩容或为Deployment设置标签)不会触发滚动更新,因此也不会更改修订版本号。

一旦滚动更新完成,Deployment将同时显示ReplicaSet A和B,其中A的Pod被缩容为0,B的Pod被扩展为3。这样Deployment就记录了先前的状态配置作为修订版本。

一旦ReplicaSet B和其3个版本为1.21.5的Pod准备好,Deployment就开始主动管理它们。然而,Deployment保留了其先前的配置状态作为修订版本,这在回滚功能中起着关键作用,使得Deployment可以返回到先前已知的配置状态。在我们的示例中,如果新的nginx:1.21.5的性能不理想,可以将Deployment回滚到之前的修订版本,从修订版本2返回到再次运行nginx:1.20.2的修订版本1。

学新通

DaemonSets

DaemonSet是专门设计用于管理节点代理的运算符。当管理多个Pod副本和应用程序更新时,它们与ReplicaSet和Deployment运算符类似,但DaemonSet有一个独特的特性,即强制在所有节点上每个节点只放置一个Pod副本。相比之下,默认情况下,ReplicaSet和Deployment运算符无法控制在同一节点上放置多个Pod副本的调度和位置。

当我们需要从所有节点收集监控数据或在所有节点上运行存储、网络或代理守护程序以确保始终有特定类型的Pod在所有节点上运行时,通常会使用DaemonSet运算符。它们是多节点Kubernetes集群中关键的API资源。在集群中的每个节点上作为Pod运行的kube-proxy代理,或者实现集群所有节点上的Pod网络的Calico网络节点代理,都是由DaemonSet运算符管理的应用程序的示例。

每当向集群添加节点时,给定DaemonSet的一个Pod会自动放置在该节点上。虽然它确保了自动化的过程,但是DaemonSet的Pod是由控制器本身将其放置在所有集群节点上,而不是借助默认的调度器。当任何一个节点崩溃或从集群中删除时,相应的DaemonSet Pod会被垃圾回收。如果删除了一个DaemonSet,它创建的所有Pod副本也会被删除。

DaemonSet Pod的放置仍受调度属性的管理,这可能限制其Pod只能放置在集群节点的一个子集上。可以借助Pod调度属性,如nodeSelectors、节点亲和性规则、污点和容忍度,实现这一点。这样可以确保DaemonSet的Pod只放置在特定的节点上,如所需的工作节点。然而,如果启用了相应的功能, 默认的调度器可以接管调度过程,再次接受节点亲和性规则。

Services

Kubernetes Service是一种用于将容器化应用程序暴露给集群网络的机制,它解决了容器无法直接对集群网络可见的问题。在Kubernetes中,容器不会直接将其端口暴露给集群网络,而且也无法被其他应用程序或客户端发现。为了解决这个问题,Kubernetes提供了一种称为Service的机制,通过与kube-proxy节点代理、IP表、路由规则和集群DNS服务器等组件共同工作,实现了一个微型负载均衡机制,可以将容器的端口暴露给集群网络,甚至可以使其对外部世界可见。

使用Kubernetes Service可以将任何容器化应用程序暴露给Kubernetes网络,并且在暴露多个副本的应用程序时,能够灵活处理多个容器运行相同映像的情况。相比之下,普通容器主机的简单端口映射无法处理这种复杂的要求。

Kubernetes Service资源有不同的类型和配置选项,具体的内容会在后续章节中进行详细讨论。

请注意,根据集群的配置和网络环境,Service可能会提供集群内部或集群外部的访问。为了使Service能够从集群外部访问,可能需要使用负载均衡器、Ingress控制器或NodePort类型的Service。这些细节在后续章节中还会进行进一步介绍。

总而言之,Kubernetes Service是一种强大而复杂的机制,用于将容器化应用程序暴露给集群网络。它通过负载均衡和其他组件的协同工作,提供了可靠的访问机制,并能够适应多副本应用程序的复杂需求。

Chapter 9. 认证,授权和admission Controller

在Kubernetes中,所有到达API服务器的API请求在被服务器接受并执行之前,都必须经过几个控制阶段。在本章中,我们将学习Kubernetes API访问控制的认证(Authentication)、授权(Authorization)和准入控制(Admission Control)阶段。

  1. 认证(Authentication):认证阶段用于验证用户或客户端是否具有正确的身份以及合法的访问凭据。它确保只有经过身份验证的用户可以访问Kubernetes API。Kubernetes支持多种认证方式,包括基于令牌(Token-based)、基于用户名和密码(Username/Password-based)、基于客户端证书(Client Certificate-based)等。
  2. 授权(Authorization):授权阶段确定经过认证的用户或客户端是否具有执行特定操作的权限。它基于角色、角色绑定和访问控制策略来控制用户对Kubernetes资源的操作权限。授权机制帮助管理员限制用户的权限范围,确保用户只能访问其分配的资源。
  3. 准入控制(Admission Control):准入控制是在API请求被接受之前对其进行进一步检查和处理的阶段。它允许管理员定义自定义规则和策略,以应用集群范围的访问控制和操作限制。准入控制可以阻止不符合预定义规则的请求,或者对请求进行修改,以满足特定要求。准入控制也允许在创建、更新或删除资源之前进行验证和审查。

这些控制阶段共同确保了Kubernetes集群的安全性和可靠性。通过认证、授权和准入控制,管理员可以限制用户的访问权限,并确保只有合法的操作请求被执行。这种细粒度的访问控制是Kubernetes安全性的关键组成部分,并且为集群提供了强大的保护机制,以防止未经授权的访问和恶意操作。

学习目标

  • Discuss the authentication, authorization, and access control stages of the Kubernetes API access.
  • Understand the different kinds of Kubernetes users.
  • Explore the different modules for authentication and authorization.

Chapter 10. Services

尽管微服务驱动的架构旨在解耦应用程序的组件,但微服务仍然需要代理在逻辑上将它们绑定或分组在一起,以便进行管理,或者将流量负载均衡到属于这样一个逻辑集合的微服务中。

在本章中,我们将学习用于抽象集群内部微服务之间通信或与外部世界通信的服务对象。Service为由Kubernetes集群管理的无状态容器化应用程序提供了单个DNS条目,无论副本的数量如何,都通过为一组逻辑上分组并由诸如Deployment、ReplicaSet或DaemonSet等控制器管理的Pod提供一个共同的负载均衡访问点。

我们还将学习kube-proxy守护程序,它在每个控制平面和工作节点上运行,用于实现服务的配置并提供对服务的访问。此外,我们还将讨论服务发现和服务类型,它们决定了服务的访问范围。

通过本章的学习,您将能够:

  • 讨论使用Service在逻辑上将Pod分组以访问应用程序的好处。
  • 解释在每个节点上运行的kube-proxy守护程序的作用。
  • 探索Kubernetes中可用的服务发现选项。
  • 讨论不同的Service类型。

Connecting Users or Applications to Pods

为了访问应用,用户或者其他应用需要连接到某个Pod.又因为pod本身是临时的,就造成了他们的IP不是固定的。任何的重新调度都会使得pod的ip变得不可用。

为了解决这个问题,K8S提供了一个高抽象的服务叫做Service,它逻辑上的把pod分组,然后定义一个策略来访问他们,这种分组是通过标签和选择器来实现的。

Service

标签和选择器使用键值对的格式来使用。 在下面的图示中,app就是标签key,frontend和db是标签值。使用选择器app=frontend可以把pod从逻辑上分成2个组:一组有3个pod,一组有一个pod。

这种逻辑的分组就是Service。 这个Service的名字同时也在集群内部的DNS服务中注册。在我们的例子中,我们创建了两个Service,一个frondend-svc,一个db-svc。 Service可以暴露单个pod,ReplicaSets,Deployment,DaemonSet,StatefulSets。当我们暴露被控制器管理的POD时,Service的选择器可能只用该控制器相同的标签。 学新通

Service Object Example

apiVersion: v1
kind: Service
metadata:
  name: frontend-svc
spec:
  selector:
    app: frontend
  ports:
  - protocol: TCP
    port: 80
    targetPort: 5000

在这个例子中,我们通过选择所有具有标签键key=app,值为frontend的Pod来创建一个名为frontend-svc的Service。默认情况下,每个Service都会获得一个仅在集群内可路由的IP地址,即ClusterIP。在我们的例子中,我们分别将172.17.0.4和172.17.0.5分配给了我们的frontend-svc和db-svc Services作为它们的ClusterIP。

学新通

此刻,用户/客户端可以通过clusterIp连接到这个service,它会把流量转发到其中的一个与其关联的pod。Service默认具有负载均功能。

当Service转发流量到Pods时,我们可以选择Pod中哪个端口来接收这个流量:targetPort。在这个例子中,用户把流量转发到Service监听的端口80上,然后Service再把这个流量转发到5000端口。 也就是说。port是service本身的端口,而targetPort则是需要转发的,Pod的端口。

Pod的IP地址和targetPort组成了一个Service endpoint的逻辑集合。在我们的例子中,frontend-svc Service有3个endpoints:10.0.1.3:5000、10.0.1.4:5000和10.0.1.5:5000。endpoints是由Service自动创建和管理的,而不是由Kubernetes集群管理员管理。

Kube-proxy

每个集群节点都运行一个名为kube-proxy的守护程序,它是一个节点代理,负责监视主节点上的Api Server的命令从而对Service和endpoints的添加、更新和删除进行相应操作。kube-proxy负责代表管理员或开发者实现Service配置,以便将流量路由到运行在Pod中的暴露应用程序。在下面的例子中,对于每个新的Service,在每个节点上,kube-proxy会配置iptables规则来捕获该Service的ClusterIP流量,并将其转发到其中一个Service的endpoints。因此,任何节点都可以接收外部流量,然后根据iptables规则在集群内进行内部路由。当Service被删除时,kube-proxy也会在所有节点上删除相应的iptables规则。

学新通

流量策略

kube-proxy节点代理与iptables一起实现了在流量路由到应用程序的Endpoints时Service的负载均衡机制。由于iptables的限制特性,默认情况下,这种负载均衡是随机的。这意味着从众多副本中随机选择一个接收请求的Endpoint Pod。该机制不能保证所选的接收Pod是最近的,甚至不在请求方所在的节点上,因此不是最高效的机制。由于这是iptables支持的负载均衡机制,如果我们希望获得更好的结果,就需要利用流量策略。

流量策略允许用户在流量路由的上下文中指示kube-proxy的行为方式。有两个选项可供选择:Cluster和Local。

Cluster选项允许kube-proxy在负载均衡过程中针对Service的所有就绪Endpoints进行操作。 然而,Local选项将负载均衡过程限制为仅包括与请求方Pod位于同一节点上的Service的Endpoints。虽然这听起来是一个理想的选项,但它也有一个缺点 - 如果Service在请求方Pod所在的节点上没有就绪的Endpoint,Service将不会将请求路由到其他节点上的Endpoints以满足请求。 无论是从集群内部生成的请求,还是从集群外部的应用程序和客户端生成的请求,Cluster和Local选项都适用。

服务发现

由于Services是K8S管理的容器化应用最主要的通信方式,所以及时的在运行时发现它们是很有帮助的。K8S支持两种服务发现的方式:

  • 环境变量 一旦Pod在任何工作节点上启动,运行在该节点上的kubelet守护进程会为所有活动的Service在Pod中添加一组环境变量。例如,如果我们有一个名为redis-master的活动Service,它暴露端口6379,并且其ClusterIP是172.17.0.6,在新创建的Pod中,我们可以看到以下环境变量:

REDIS_MASTER_SERVICE_HOST=172.17.0.6 REDIS_MASTER_SERVICE_PORT=6379 REDIS_MASTER_PORT=tcp://172.17.0.6:6379 REDIS_MASTER_PORT_6379_TCP=tcp://172.17.0.6:6379 REDIS_MASTER_PORT_6379_TCP_PROTO=tcp REDIS_MASTER_PORT_6379_TCP_PORT=6379 REDIS_MASTER_PORT_6379_TCP_ADDR=172.17.0.6

通过这种解决方案,我们需要注意在部署Service时的顺序,因为在Pod创建后创建的Service对应的环境变量不会被设置。

  • DNS

Kubernetes具有用于DNS的插件,为每个Service创建一个DNS记录,其格式为my-svc.my-namespace.svc.cluster.local。同一个命名空间内的Service可以通过名称直接找到其他Service。如果我们在my-ns命名空间中添加了一个名为redis-master的Service,同一命名空间中的所有Pod都可以通过名称redis-master来查找该Service。来自其他命名空间(如test-ns)的Pod可以通过添加相应的命名空间作为后缀来查找相同的Service,例如redis-master.my-ns,或者提供服务的完全限定域名(redis-master.my-ns.svc.cluster.local)。

这是最常见且强烈推荐的解决方案。例如,在上一节的图像中,我们看到配置了内部DNS,将我们的Services frontend-svc和db-svc分别映射到172.17.0.4和172.17.0.5的IP地址。

ServiceType

ClusterIP是默认的Service类型。一个Service会获得一个虚拟IP地址,也称为它的ClusterIP。这个虚拟IP地址用于与Service进行通信,只能在集群内部访问。

使用NodePort Service类型时,除了ClusterIP之外,还会为该Service从所有工作节点中动态选择一个高端口(默认范围为30000-32767),与该Service进行映射。例如,如果Service frontend-svc的映射NodePort是32233,那么如果我们连接到任何一个工作节点的32233端口,该节点会将所有流量重定向到分配的ClusterIP,即172.17.0.4。如果我们想要指定一个特定的高端口号,那么在创建Service时可以将该高端口号分配给NodePort,从默认范围中选择。

NodePort Service类型在我们希望使Service从外部世界访问时非常有用。最终用户通过指定的高端口连接到任何一个工作节点,该工作节点内部代理请求到Service的ClusterIP,然后将请求转发到集群内部运行的应用程序。值得注意的是,Service会对这些请求进行负载均衡,并且只将请求转发给运行所需应用程序的一个Pod。为了管理对外部世界的多个应用程序Service的访问,管理员可以配置一个反向代理(即Ingress),并定义针对集群内特定Service的规则。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbcbgf
系列文章
更多 icon
同类精品
更多 icon
继续加载