科普文:kubernets原理

kubernetes 已经成为容器编排领域的王者,它是基于容器的集群编排引擎,具备扩展集群、滚动升级回滚、弹性伸缩、自动治愈、服务发现等多种特性能力。

本文将带着大家快速了解 kubernetes ,了解我们谈论 kubernetes 都是在谈论什么。
 

一、背景

1、部署方式的变迁

  • 传统部署时代:
    • 在物理服务器上运行应用程序
    • 无法为应用程序定义资源边界
    • 导致资源分配问题

例如,如果在物理服务器上运行多个应用程序,则可能会出现一个应用程序占用大部分资源的情况, 结果可能导致其他应用程序的性能下降。 一种解决方案是在不同的物理服务器上运行每个应用程序,但是由于资源利用不足而无法扩展, 并且维护许多物理服务器的成本很高。

  • 虚拟化部署时代:
    • 作为解决方案,引入了虚拟化
    • 虚拟化技术允许你在单个物理服务器的 CPU 上运行多个虚拟机(VM)
    • 虚拟化允许应用程序在 VM 之间隔离,并提供一定程度的安全
    • 一个应用程序的信息 不能被另一应用程序随意访问。
    • 虚拟化技术能够更好地利用物理服务器上的资源
    • 因为可轻松地添加或更新应用程序 ,所以可以实现更好的可伸缩性,降低硬件成本等等。
    • 每个 VM 是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。

缺点:虚拟层冗余导致的资源浪费与性能下降

  • 容器部署时代:
    • 容器类似于 VM,但可以在应用程序之间共享操作系统(OS)。
    • 容器被认为是轻量级的。
    • 容器与 VM 类似,具有自己的文件系统、CPU、内存、进程空间等。
    • 由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。

容器优势:

  • 敏捷性:敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
  • 及时性:持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性),支持可靠且频繁的 容器镜像构建和部署。
  • 解耦性:关注开发与运维的分离:在构建/发布时创建应用程序容器镜像,而不是在部署时。 从而将应用程序与基础架构分离。
  • 可观测性:可观察性不仅可以显示操作系统级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
  • 跨平台:跨开发、测试和生产的环境一致性:在便携式计算机上与在云中相同地运行。
  • 可移植:跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
  • 简易性:以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
  • 大分布式:松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
  • 隔离性:资源隔离:可预测的应用程序性能。
  • 高效性:资源利用:高效率和高密度

2、容器化问题

  • 弹性的容器化应用管理
  • 强大的故障转移能力
  • 高性能的负载均衡访问机制
  • 便捷的扩展
  • 自动化的资源监测

3、为什么用 Kubernetes

容器是打包和运行应用程序的好方式。在生产环境中,你需要管理运行应用程序的容器,并确保不会停机。 例如,如果一个容器发生故障,则需要启动另一个容器。如果系统处理此行为,会不会更容易?

这就是 Kubernetes 来解决这些问题的方法! Kubernetes 为你提供了一个可弹性运行分布式系统的框架。linux之上的一个服务编排框架;

Kubernetes 会满足你的扩展要求、故障转移、部署模式等。 例如,Kubernetes 可以轻松管理系统的 Canary 部署。

Kubernetes 为你提供:

  • 服务发现和负载均衡 Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器,如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。
  • 存储编排 Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。
  • 自动部署和回滚 你可以使用 Kubernetes 描述已部署容器的所需状态,它可以以受控的速率将实际状态 更改为期望状态。例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。
  • 自动完成装箱计算 Kubernetes 允许你指定每个容器所需 CPU 和内存(RAM)。 当容器指定了资源请求时,Kubernetes 可以做出更好的决策来管理容器的资源。
  • 自我修复 Kubernetes 重新启动失败的容器、替换容器、杀死不响应用户定义的 运行状况检查的容器,并且在准备好服务之前不将其通告给客户端。
  • 密钥与配置管理 Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥

为了生产环境的容器化大规模应用编排,必须有一个自动化的框架。

kubernetes 架构

ba01b6cc16a20b46d266860c08c4a925.png

从宏观上来看 kubernetes 的整体架构,包括 Master、Node 以及 Etcd。

Master 即主节点,负责控制整个 kubernetes 集群。它包括 Api Server、Scheduler、Controller 等组成部分。它们都需要和 Etcd 进行交互以存储数据。

    Api Server:主要提供资源操作的统一入口,这样就屏蔽了与 Etcd 的直接交互。功能包括安全、注册与发现等。

    Scheduler:负责按照一定的调度规则将 Pod 调度到 Node 上。

    Controller:资源控制中心,确保资源处于预期的工作状态。

Node 即工作节点,为整个集群提供计算力,是容器真正运行的地方,包括运行容器、kubelet、kube-proxy。

    kubelet:主要工作包括管理容器的生命周期、结合 cAdvisor 进行监控、健康检查以及定期上报节点状态。

    kube-proxy: 主要利用 service 提供集群内部的服务发现和负载均衡,同时监听 service/endpoints 变化并刷新负载均衡。

从创建 deployment 开始

为了更好地解决服务编排的问题,k8s在V1.2版本开始,引入了deployment控制器,值得一提的是,这种控制器并不直接管理pod,

而是通过管理replicaset来间接管理pod,即:deployment管理replicaset,replicaset管理pod。所以deployment比replicaset的功能更强大。

deployment的主要功能有下面几个:

  • 支持replicaset的所有功能
  • 支持发布的停止、继续
  • 支持版本的滚动更新和版本回退

deployment 是用于编排 pod 的一种控制器资源,我们会在后面做介绍。这里以 deployment 为例,来看看架构中的各组件在创建 deployment 资源的过程中都干了什么。

    1. 首先是 kubectl 发起一个创建 deployment 的请求

    2. apiserver 接收到创建 deployment 请求,将相关资源写入 etcd;之后所有组件与 apiserver/etcd 的交互都是类似的

    3. deployment controller list/watch 资源变化并发起创建 replicaSet 请求

    4. replicaSet controller list/watch 资源变化并发起创建 pod 请求

    5. scheduler 检测到未绑定的 pod 资源,通过一系列匹配以及过滤选择合适的 node 进行绑定

    6. kubelet 发现自己 node 上需创建新 pod,负责 pod 的创建及后续生命周期管理

    7. kube-proxy 负责初始化 service 相关的资源,包括服务发现、负载均衡等网络规则

deployment的资源清单文件

apiVersion: apps/v1  #版本号
kind: Deployment  #类型
metadata:    #元数据name:    #rs名称namespace:   #所属命名空间labels:   #标签controller: deploy
spec:   #详情描述replicas:  #副本数量revisionHistoryLimit: #保留历史版本,默认是10paused: #暂停部署,默认是falseprogressDeadlineSeconds: #部署超时时间(s),默认是600strategy: #策略type: RollingUpdates  #滚动更新策略rollingUpdate:  #滚动更新maxSurge: #最大额外可以存在的副本数,可以为百分比,也可以为整数maxUnavaliable: #最大不可用状态的pod的最大值,可以为百分比,也可以为整数selector:  #选择器,通过它指定该控制器管理哪些podmatchLabels:   #Labels匹配规则app: nginx-podmatchExpressions:   #Expression匹配规则- {key: app, operator: In, values: [nginx-pod]}template:  #模板,当副本数量不足时,会根据下面的模板创建pod副本metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1ports:- containerPort: 80

创建deployment

apiVersion: apps/v1
kind: Deployment
metadata:name: pc-deploymentnamespace: dev
spec:replicas: 3selector:matchLabels:app: nginx-podtemplate:metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1

deployment功能

扩缩容

方式一:命令行

格式

kubectl scale deploy deploy名称 --replicas=pod数量 -n 命名空间

通过命令行变更pod数量为5个

[root@master ~]# kubectl scale deploy pc-deployment --replicas=5 -n dev
deployment.apps/pc-deployment scaled
[root@master ~]# kubectl get pod -n dev
NAME                             READY   STATUS    RESTARTS   AGE
pc-deployment-5d89bdfbf9-bhcns   1/1     Running   0          83s
pc-deployment-5d89bdfbf9-cfls7   1/1     Running   0          83s
pc-deployment-5d89bdfbf9-k8j9n   1/1     Running   0          8m54s
pc-deployment-5d89bdfbf9-vw87k   1/1     Running   0          8m54s
pc-deployment-5d89bdfbf9-x7nsm   1/1     Running   0          8m54s

方式二:编辑deploy文件

格式

kubectl edit deploy deploy名字 -n 命名空间

通过编辑deploy文件编辑pod数量为3个

[root@master ~]# kubectl edit deploy pc-deployment -n dev
找到replicas,将其数量改为3
spec:progressDeadlineSeconds: 600replicas: 3
[root@master ~]# kubectl get pod -n dev
NAME                             READY   STATUS    RESTARTS   AGE
pc-deployment-5d89bdfbf9-k8j9n   1/1     Running   0          15m
pc-deployment-5d89bdfbf9-vw87k   1/1     Running   0          15m
pc-deployment-5d89bdfbf9-x7nsm   1/1     Running   0          15m

镜像更新

deployment支持两种镜像更新策略:重建更新滚动更新(默认),可以通过strategy选项进行配置

strategy:指定新的pod替换旧的pod的策略,支持两个属性:type:指定策略类型,支持两种策略Recreate:在创建出新的pod之前会先杀掉所有已存在的podRollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本podrollingUpdate:当type为RollingUpdate时生效,用于为RollingUpdate设置参数,支持两个属性maxUnavailable:用来指定在升级过程中不可用pod的最大数量,默认为25%maxSurge:用来指定在升级过程中可以超过期望的pod的最大数量,默认为25%

重建更新

编辑pc-deployment.yaml,在spec节点下添加更新策略

spec:strategy:  #策略type: Recreate  #重建更新策略
[root@master ~]# vim pc-deployment.yaml 
[root@master ~]# kubectl apply -f pc-deployment.yaml 
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
deployment.apps/pc-deployment configured

创建deploy进行验证

#首先记录原本的pod名
[root@master ~]# kubectl get pod -n dev
NAME                             READY   STATUS    RESTARTS   AGE
pc-deployment-5d89bdfbf9-bqf86   1/1     Running   0          8s
pc-deployment-5d89bdfbf9-kz6jt   1/1     Running   0          8s
pc-deployment-5d89bdfbf9-z7d9z   1/1     Running   0          8s#更改pod镜像
[root@master ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.2 -n dev
deployment.apps/pc-deployment image updated#再次查看镜像
[root@master ~]# kubectl get pod -n dev
NAME                             READY   STATUS    RESTARTS   AGE
pc-deployment-675d469f8b-b9rwd   1/1     Running   0          27s
pc-deployment-675d469f8b-kc7rr   1/1     Running   0          27s
pc-deployment-675d469f8b-kxgkq   1/1     Running   0          27s

发现pod镜像已经改变了

滚动更新

编辑pc-deployment.yaml,在spec节点下添加滚动更新策略(也可以把strategy去掉,因为默认滚动更新策略)

strategy:type: RollingUpdate #滚动更新策略rollingUpdate:maxUnavailable: 25%maxSurge: 25%
[root@master ~]# vim pc-deployment.yaml 
[root@master ~]# kubectl apply -f pc-deployment.yaml 
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
deployment.apps/pc-deployment configured

创建deploy进行验证

#记录以前的pod
[root@master ~]# kubectl get pod -n dev
NAME                             READY   STATUS    RESTARTS   AGE
pc-deployment-5d89bdfbf9-526wf   1/1     Running   0          61s
pc-deployment-5d89bdfbf9-b5x5v   1/1     Running   0          64s
pc-deployment-5d89bdfbf9-kc7hb   1/1     Running   0          59s
#更新镜像
[root@master ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.2 -n dev
deployment.apps/pc-deployment image updated
#查看pod状态
[root@master ~]# kubectl get pod -n dev
NAME                             READY   STATUS              RESTARTS   AGE
pc-deployment-5d89bdfbf9-526wf   0/1     Terminating         0          2m2s
pc-deployment-5d89bdfbf9-b5x5v   1/1     Running             0          2m5s
pc-deployment-5d89bdfbf9-kc7hb   0/1     Terminating         0          2m
pc-deployment-675d469f8b-7vw6x   1/1     Running             0          3s
pc-deployment-675d469f8b-rzq82   0/1     ContainerCreating   0          2s
pc-deployment-675d469f8b-zk4fs   1/1     Running             0          5s
[root@master ~]# kubectl get pod -n dev
NAME                             READY   STATUS    RESTARTS   AGE
pc-deployment-675d469f8b-7vw6x   1/1     Running   0          38s
pc-deployment-675d469f8b-rzq82   1/1     Running   0          37s
pc-deployment-675d469f8b-zk4fs   1/1     Running   0          40s

发现pod是旧的一遍停止新的一边创建,最后全变成了新的

滚动更新的过程

镜像更新中rs的变化

前期准备:

#重建deployment
[root@master ~]# kubectl delete -f pc-deployment.yaml 
deployment.apps "pc-deployment" deleted
#添加record参数,表明创建时记录
[root@master ~]# kubectl create -f pc-deployment.yaml --record
deployment.apps/pc-deployment created
[root@master ~]# kubectl get deploy,rs,pod -n dev
NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/pc-deployment   3/3     3            3           81sNAME                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/pc-deployment-5d89bdfbf9   3         3         3       81sNAME                                 READY   STATUS    RESTARTS   AGE
pod/pc-deployment-5d89bdfbf9-4bg2j   1/1     Running   0          81s
pod/pc-deployment-5d89bdfbf9-gbt95   1/1     Running   0          81s
pod/pc-deployment-5d89bdfbf9-tstlh   1/1     Running   0          81s

新建两个xshell窗口,用于监听rs和pod

 在2窗口中监听rs,3窗口中监听pod

#在2窗口中输入
[root@master ~]# kubectl get rs -n dev -w
NAME                       DESIRED   CURRENT   READY   AGE
pc-deployment-5d89bdfbf9   3         3         3       6m18s
#在3窗口中输入
[root@master ~]# kubectl get pod -n dev -w
NAME                             READY   STATUS    RESTARTS   AGE
pc-deployment-5d89bdfbf9-4bg2j   1/1     Running   0          6m56s
pc-deployment-5d89bdfbf9-gbt95   1/1     Running   0          6m56s
pc-deployment-5d89bdfbf9-tstlh   1/1     Running   0          6m56s

在1窗口中改变pod镜像

[root@master ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.2 -n dev
deployment.apps/pc-deployment image updated

查看3窗口中pod的变化,发现序号5开头的pod在逐渐暂停,序号6开头的pod在逐渐创建

查看2窗口中rs的变化,可以看见序号5开头的rs的pod数在减少,序号6开头的rs的pod数在增加

 在1窗口中查看最终rs变化,发现原来的rs依旧存在,只是pod数量变为了0,而后又新产生了一个rs,pod数量为3,其实这就是deployment能够进行版本回退的奥妙所在,后面会详细解释

[root@master ~]# kubectl get rs -n dev
NAME                       DESIRED   CURRENT   READY   AGE
pc-deployment-5d89bdfbf9   0         0         0       11m
pc-deployment-675d469f8b   3         3         3       3m12s
版本回退

deployment支持版本升级过程中的暂停,继续功能以及版本回退等诸多功能,下面具体来看

kubectl rollout:版本升级相关功能,支持下面的选项:

  • status:显示当前升级状态
  • history:显示升级历史记录
  • pause:暂停版本升级过程
  • resume:继续已经暂停的版本升级过程
  • restart:重启版本升级过程
  • undo:回滚到上一级版本(可以使用--to-revision回滚到指定版本)
#查看升级状态
[root@master ~]# kubectl rollout status deploy pc-deployment -n dev
deployment "pc-deployment" successfully rolled out#查看升级历史(注意:如果只显示版本号说明一开始使用yaml创建文件的时候没有加上--record命令)
[root@master ~]# kubectl rollout history deploy pc-deployment -n dev
deployment.apps/pc-deployment 
REVISION  CHANGE-CAUSE
1         kubectl create --filename=pc-deployment.yaml --record=true
2         kubectl create --filename=pc-deployment.yaml --record=true#版本回滚
#这里使用--to-revision=1回滚到1版本,如果省略这个选项,则会回退到上个版本
[root@master ~]# kubectl rollout undo deploy pc-deployment --to-revision=1 -n dev
deployment.apps/pc-deployment rolled back#查看是否回滚成功,发现5序号开头的rs被启动了
[root@master ~]# kubectl get rs -n dev
NAME                       DESIRED   CURRENT   READY   AGE
pc-deployment-5d89bdfbf9   3         3         3       31m
pc-deployment-675d469f8b   0         0         0       22m
金丝雀发布

deployment支持更新过程中的控制,如"暂停(pause)"或"继续(resume)"更新操作

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

#更新deployment版本,并配置暂停deployment
[root@master ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.2 -n dev && kubectl rollout pause deploy pc-deployment -n dev
deployment.apps/pc-deployment image updated
deployment.apps/pc-deployment paused#查看rs,发现老版本rs没有减少,新版本rs增加一个
[root@master ~]# kubectl get rs -n dev
NAME                       DESIRED   CURRENT   READY   AGE
pc-deployment-5d89bdfbf9   3         3         3       44m
pc-deployment-675d469f8b   1         1         1       35m#在窗口2中查看deploy状态,发现deploy正在等待更新且已经有1个更新好了
[root@master ~]# kubectl rollout status deploy pc-deployment -n dev
Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated...#在窗口1中继续deploy的更新
[root@master ~]# kubectl rollout resume deploy pc-deployment -n dev
deployment.apps/pc-deployment resumed#查看窗口2的状态
Waiting for deployment spec update to be observed...
Waiting for deployment spec update to be observed...
Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "pc-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "pc-deployment" successfully rolled out#在窗口1查看rs更新结果,发现老版本均停止,新版本已经创建好
[root@master ~]# kubectl get rs -n dev
NAME                       DESIRED   CURRENT   READY   AGE
pc-deployment-5d89bdfbf9   0         0         0       49m
pc-deployment-675d469f8b   3         3         3       40m

至此,经过 kubenetes 各组件的分工协调,完成了从创建一个 deployment 请求开始到具体各 pod 正常运行的全过程。

Pod

在 kubernetes 众多的 api 资源中,pod 是最重要和基础的,是最小的部署单元。

首先我们要考虑的问题是,我们为什么需要 pod?pod 可以说是一种容器设计模式,它为那些”超亲密”关系的容器而设计,我们可以想象 servelet 容器部署 war 包、日志收集等场景,这些容器之间往往需要共享网络、共享存储、共享配置,因此我们有了 pod 这个概念。

33a11ee8a026b8afd0320efd48e5479f.png

对于 pod 来说,不同 container 之间通过 infra container 的方式统一识别外部网络空间,而通过挂载同一份 volume 就自然可以共享存储了,比如它对应宿主机上的一个目录。

容器编排

容器编排是 kubernetes 的看家本领了,所以我们有必要了解一下。kubernetes 中有诸多编排相关的控制资源,例如编排无状态应用的 deployment,编排有状态应用的 statefulset,编排守护进程 daemonset 以及编排离线业务的 job/cronjob 等等。

我们还是以应用最广泛的 deployment 为例。deployment、replicatset、pod 之间的关系是一种层层控制的关系。简单来说,replicaset 控制 pod 的数量,而 deployment 控制 replicaset 的版本属性。这种设计模式也为两种最基本的编排动作实现了基础,即数量控制的水平扩缩容、版本属性控制的更新/回滚。

水平扩缩容

ad19d164f8ecb1ecf2d5c978cde052e9.png

水平扩缩容非常好理解,我们只需修改 replicaset 控制的 pod 副本数量即可,比如从 2 改到 3,那么就完成了水平扩容这个动作,反之即水平收缩。

更新/回滚

8620aeec3a056d292677dcae53d58310.png

更新/回滚则体现了 replicaset 这个对象的存在必要性。例如我们需要应用 2 个实例的版本从 v1 改到 v2,那么 v1 版本 replicaset 控制的 pod 副本数会逐渐从 2 变到 0,而 v2 版本 replicaset 控制的 pod 数会注解从 0 变到 2,当 deployment 下只存在 v2 版本的 replicaset 时变完成了更新。回滚的动作与之相反。

滚动更新

可以发现,在上述例子中,我们更新应用,pod 总是一个一个升级,并且最小有 2 个 pod 处于可用状态,最多有 4 个 pod 提供服务。这种”滚动更新”的好处是显而易见的,一旦新的版本有了 bug,那么剩下的 2 个 pod 仍然能够提供服务,同时方便快速回滚。

在实际应用中我们可以通过配置 RollingUpdateStrategy 来控制滚动更新策略,maxSurge 表示 deployment 控制器还可以创建多少个新 Pod;而 maxUnavailable 指的是,deployment 控制器可以删除多少个旧 Pod。

kubernetes 中的网络

我们了解了容器编排是怎么完成的,那么容器间的又是怎么通信的呢?

讲到网络通信,kubernetes 首先得有”三通”基础:

    1. node 到 pod 之间可以通

    2. node 的 pod 之间可以通

    3. 不同 node 之间的 pod 可以通

简单来说,不同 pod 之间通过 cni0/docker0 网桥实现了通信,node 访问 pod 也是通过 cni0/docker0 网桥通信即可。

而不同 node 之间的 pod 通信有很多种实现方案,包括现在比较普遍的 flannel 的 vxlan/hostgw 模式等。flannel 通过 etcd 获知其他 node 的网络信息,并会为本 node 创建路由表,最终使得不同 node 间可以实现跨主机通信。

微服务—service

在了解接下来的内容之前,我们得先了解一个很重要的资源对象:service。

我们为什么需要 service 呢?在微服务中,pod 可以对应实例,那么 service 对应的就是一个微服务。而在服务调用过程中,service 的出现解决了两个问题:

    1. pod 的 ip 不是固定的,利用非固定 ip 进行网络调用不现实

    2. 服务调用需要对不同 pod 进行负载均衡

service 通过 label 选择器选取合适的 pod,构建出一个 endpoints,即 pod 负载均衡列表。实际运用中,一般我们会为同一个微服务的 pod 实例都打上类似app=xxx的标签,同时为该微服务创建一个标签选择器为app=xxx的 service。

kubernetes 中的服务发现与网络调用

在有了上述”三通”的网络基础后,我们可以开始微服务架构中的网络调用在 kubernetes 中是怎么实现的了。

这部分内容其实在说说 Kubernetes 是怎么实现服务发现的已经讲得比较清楚了,比较细节的地方可以参考上述文章,这里做一个简单的介绍。

服务间调用

首先是东西向的流量调用,即服务间调用。这部分主要包括两种调用方式,即 clusterIp 模式以及 dns 模式。

clusterIp 是 service 的一种类型,在这种类型模式下,kube-proxy 通过 iptables/ipvs 为 service 实现了一种 VIP(虚拟 ip)的形式。只需要访问该 VIP,即可负载均衡地访问到 service 背后的 pod。

29567003e1c246e299b59b3c5177c8f2.png

上图是 clusterIp 的一种实现方式,此外还包括 userSpace 代理模式(基本不用),以及 ipvs 模式(性能更好)。

dns 模式很好理解,对 clusterIp 模式的 service 来说,它有一个 A 记录是 service-name.namespace-name.svc.cluster.local,指向 clusterIp 地址。所以一般使用过程中,我们直接调用 service-name 即可。

服务外访问

b0af3cebd07d406e2d7a6e42569c6bd3.png

南北向的流量,即外部请求访问 kubernetes 集群,主要包括三种方式:nodePort、loadbalancer、ingress。

nodePort 同样是 service 的一种类型,通过 iptables 赋予了调用宿主机上的特定 port 就能访问到背后 service 的能力。

loadbalancer 则是另一种 service 类型,通过公有云提供的负载均衡器实现。

我们访问 100 个服务可能需要创建 100 个 nodePort/loadbalancer。我们希望通过一个统一的外部接入层访问内部 kubernetes 集群,这就是 ingress 的功能。ingress 提供了统一接入层,通过路由规则的不同匹配到后端不同的 service 上。ingress 可以看做是”service 的 service”。ingress 在实现上往往结合 nodePort 以及 loadbalancer 完成功能。

到现在为止,我们简单了解了 kubernetes 的相关概念,它大致是怎么运作的,以及微服务是怎么运行在 kubernetes 中的。于是当我们听到别人讨论 kubernetes 时,我们可以知道他们在讨论什么。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/51167.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详细介绍BIO、NIO、IO多路复用(select、poll、epoll)

BIO、NIO、IO多路复用 BIO(Blocking IO)NIO(Non-blocking IO) 同步非阻塞IOIO多路复用selectpollepoll Redis的IO多路复用 BIO(Blocking IO) 最基础的IO模型,当进行IO操作时,线程会被阻塞,直到操作完成。 比如read和write,通常IO…

Python的输入规则

Python的输入特别有意思,它和C的输入不一样,它的输入的原型是类似于C的string类型,但是对于一些有意思的算法题来说,光是读入string型的内容并不容易解题,于是我们可以从两个方面来将输入给转化。 1. 先使用函数input…

SGLang 大模型推理框架 qwen2部署使用案例;openai接口调用、requests调用

参考: https://github.com/sgl-project/sglang 纯python写,号称比vllm、tensorRT还快 暂时支持模型 安装 可以pip、源码、docker安装,这里用的pip 注意flashinfer安装最新版,不然会可能出错误ImportError: cannot import name ‘top_k_top_p_sampling_from_probs’ fr…

EtherNet/IP转Profinet协议网关(经典配置案例)

怎么样才能把EtherNet/IP和Profinet网络连接起来呢?这几天有几个朋友问到了这个问题,作者在这里统一为大家详细说明一下。其实有一个设备可以很轻松地解决这个问题,名为JM-PN-EIP,下面是详细介绍。 一,设备主要功能 1、捷米特J…

nodepad++已打开的文件怎么按照字母/文字顺序排列?

nodepad已打开的文件怎么按照字母/文字顺序排列? 点击菜单栏 “窗口” -> “排序方式” (可选择升序或降序)

加密货币赋能跨境电商:PayPal供应链金融服务如何引领行业新趋势

跨境电商行业近年来呈现出爆发式增长,随着全球化贸易壁垒的降低和数字经济的快速发展,越来越多的商家和消费者跨越国界进行交易。根据eMarketer的数据,全球跨境电商交易额在2023年已超过4万亿美元,并预计在未来几年内仍将保持两位…

centos7 xtrabackup mysql(8)增量备份(1)

centos7 xtrabackup mysql(8)增量备份(1) 参考 xtrabackup-8.0的安装、备份以及恢复(innoxtrabackup有待测试) https://blog.csdn.net/DWJRIVER/article/details/117792271 https://blog.csdn.net/qq_28…

开发环境搭建——Tomcat安装配置

一、Tomcat安装 1、解压下载好的安装包,将解压后的文件放到任意一个盘中,注意,尽量不要有中文 2、运行Tomcat,测试Tomcat是否正常连接使用 双击bin目录下的startup.bat文件,启动Tomcat 出现下面的界面标识Tomcat启动…

顺序栈和链栈的操作实现

目录 一. 前言 二.顺序栈 三. 链栈 一. 前言 简而言之,顺序栈就是栈的顺序存储,链栈就是栈的链式存储。 二.顺序栈 下面我们来看下顺序栈的结构定义: typedef char SElemType; #define MAXSIZE 100 typedef struct{SElemType * base; //…

使用git命令行的方式,将本地项目上传到远程仓库

在国内的开发环境中,git的使用是必不可少的。Git 是一款分布式版本控制系统,用于有效管理和追踪文件的变更历史及协作开发。本片文章就来介绍一下怎样使用git命令行的方式,将本地项目上传到远程仓库,虽然现在的IDE中基本都配置了g…

SPI 通信协议

文章目录 一 简介二 特点三 接口四 时钟极性和时钟相位五 优缺点 一 简介 ​ SPI (Serial Perripheral Interface),是由 Motorola 公司推出的一种高速、全双工的总线协议。SPI 采用主从方式工作,一般由 SCLK、CS、MOSI、MISO 四根线组成,主机…

DNS劫持实验

实验背景 利用ettercap进行DNS欺骗,攻击者冒充域名服务器,也就是把查询的IP地址设为攻击者 的IP地址,这样用户上网就只能看到攻击者设计的网页。 实验设备 一个网络 net:cloud0 一台模拟黑客主机 kali 一台靶机 windows 主机 实验拓扑 …

机器学习之人脸识别-使用 scikit-learn 和人工神经网络进行高效人脸识别

文章摘要 本文将介绍如何使用 Python 的 scikit-learn 库和人工神经网络(ANN)来识别人脸。我们将使用 LFW 数据集(Labeled Faces in the Wild),这是一个广泛用于人脸识别基准测试的大型人脸数据库。我们将展示如何准备…

【微软蓝屏】构建更加稳固和安全的网络环境:从“微软蓝屏”事件谈起

最近,那个让全球都头疼的“微软蓝屏”事件,简直就像是科技界的一场大地震。你说这背后的原因,竟然是一个软件更新的小失误?哎呀,这可真是让人哭笑不得。不过,笑归笑,这事儿也给我们提了个醒&…

nodejs - express 学习笔记

express 是一个基于 Node.js 平台的极简、灵活的 WEB 应用开发框架,官方网址:https://www.expressjs. com.cn/ 简单来说,express 是一个封装好的工具包,封装了很多功能,便于我们开发 WEB 应用(HTTP 服务&am…

TiDB-从0到1-sync-diff-inspector数据校验工具

TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCCTiDB-从0到1-部署篇TiDB-从0到1-配置篇TiDB-从0到1-集群扩缩容TiDB-从0到1-数据导出导入TiDB-从0到1-BR工具 一、sync-diff-inspector工具 sync-diff-inspector是TiDB原生…

3.仓颉编程_没有switch_case需使用match_case

仓颉编程_没有switch_case需使用match_case 支持两种 match 表达式,一种是包含待匹配值的 match 表达式,另一种是不含待匹配值的 match 表达式。 含有匹配值的 match 表达式 main() {let a Hello World!//不可变量var a2 var b 77 //可变变量match(b…

指针!!C语言(第三篇)

目录 一. 二维数组传参的本质 二. 函数指针变量和函数指针数组 三. typedef关键字 四. 转移表 五. 回调函数以及qsort使用举例 一. 二维数组传参的本质 🍟首先我们先回顾一下二维数组是怎样传参的?我们需要传入数组名以及行数和列数,这…

Dhtmlx Gantt教程:创建交互式甘特图的完整指南

在现代的项目管理中,时间是一种宝贵的资源,而甘特图则是一把解锁项目进度的魔法钥匙,想象一下,您可以在一个直观而动态的时间轴上,清晰地看到项目的每一个任务如何交织在一起,如何随着时间的推移展开&#…

LangChain4j-RAG高级-检索增强器

Retrieval Augmentor 检索增强器 RetrievalAugmentor 是 RAG 管道的入口点。它负责使用从各种来源检索的相关 Content 来扩充 ChatMessage 。 可以在创建 AiService 期间指定 RetrievalAugmentor 的实例: Assistant assistant AiServices.builder(Assistant.cla…