如果你听说过服务网格,并尝试过 Istio ,你可能有以下问题。
本文将带大家了解 Kubernetes 和 Istio 的内部工作原理。此外,我会介绍 Kubernetes 中的负载均衡方法,并解释为什么有了 Kubernetes 后还需要 Istio。
Kubernetes 本质上是通过声明式配置来实现应用生命周期管理,而服务网格本质上是提供应用间的流量、安全管理和可观察性。如果你已经使用 Kubernetes 搭建了一个稳定的应用平台,那么如何设置服务间调用的负载均衡和流量控制?是否有这样一个通用的工具或者说平台(非 SDK),可以实现?这就需要用到服务网格了。
Envoy 引入了 xDS 协议,这个协议得到了各种开源软件的支持,比如 Istio、MOSN 等。Envoy 将 xDS 贡献给服务网格或云原生基础设施。Envoy 本质上是一个现代版的代理,可以通过 API 进行配置,在此基础上衍生出许多不同的使用场景–比如 API Gateway、服务网格中的 sidecar 代理和边缘代理。
本文包含以下内容。
下图显示了 Kubernetes 中的服务访问关系和服务网格(每个 pod 模型一个 sidecar)。

Kubernetes 集群中的每个节点都部署了一个 kube-proxy 组件,该组件与 Kubernetes API Server 进行通信,获取集群中的服务信息,然后设置 iptables 规则,将服务请求直接发送到对应的 Endpoint(属于同一组服务的 pod)。

Istio 可以跟踪 Kubernetes 中的服务注册,也可以在控制平面中通过平台适配器与其他服务发现系统对接;然后生成数据平面的配置(使用 CRD,这些配置存储在 etcd 中),数据平面的透明代理。数据平面的透明代理以 sidecar 容器的形式部署在每个应用服务的 pod 中,这些代理都需要请求控制平面同步代理配置。代理之所以 “透明”,是因为应用容器完全不知道代理的存在。过程中的 kube-proxy 组件也需要拦截流量,只不过 kube-proxy 拦截的是进出 Kubernetes 节点的流量–而 sidecar 代理拦截的是进出 pod 的流量。
由于 Kubernetes 的每个节点上都运行着很多 pod,所以在每个 pod 中放入原有的 kube-proxy 路由转发功能,会增加响应延迟–由于 sidecar 拦截流量时跳数更多,消耗更多的资源。为了对流量进行精细化管理,将增加一系列新的抽象功能。这将进一步增加用户的学习成本,但随着技术的普及,这种情况会慢慢得到缓解。
kube-proxy 的设置是全局的,无法对每个服务进行细粒度的控制,而 service mesh 通过 sidecar proxy 的方式将 Kubernetes 中的流量控制从服务层中抽离出来–可以实现更大的弹性。
首先,如果转发的 pod 不能正常服务,它不会自动尝试其他 pod。每个 pod 都有一个健康检查机制,当一个 pod 出现健康问题时,kubelet 会重启 pod,kube-proxy 会删除相应的转发规则。另外,节点 Port 类型的服务不能添加 TLS 或更复杂的消息路由机制。
Kube-proxy 实现了一个 Kubernetes 服务的多个 pod 实例之间的流量负载均衡,但如何对这些服务之间的流量进行精细化控制–比如将流量按百分比划分给不同的应用版本(这些应用版本都是同一个服务的一部分,但在不同的部署上),或者做金丝雀发布(灰度发布)和蓝绿发布?
Kubernetes 社区给出了一个使用 Deployment 做金丝雀发布 的方法,本质上是通过修改 pod 的标签来给部署的服务分配不同的 pod。
如上所述,kube-proxy 只能在 Kubernetes 集群内路由流量。Kubernetes 集群的 pod 位于 CNI 创建的网络中。Ingress 是在 Kubernetes 中创建的资源对象,用于集群外部的通信。它由位于 Kubernetes 边缘节点上的入口控制器驱动,负责管理南北向流量。Ingress 必须与各种 Ingress 控制器对接,比如 nginx ingress 控制器 和 traefik 。Ingress 只适用于 HTTP 流量,使用简单。它只能通过匹配有限的字段来路由流量——如服务、端口、HTTP 路径等。这使得它无法对 TCP 流量进行路由,如 MySQL、Redis 和各种 RPC。这就是为什么你会看到人们在 ingress 资源注释中写 Nginx 配置语言的原因(注:使用 Nginx Ingress Controller 可以通过 配置 ConfigMap 和 Service 的方式 来变通支持 TCP 和 UDP 流量转发)。直接路由南北流量的唯一通行方法是使用服务的 LoadBalancer 或 NodePort,前者需要云厂商支持,后者需要额外的端口管理。
Istio Gateway 的功能与 Kubernetes Ingress 类似,它负责进出集群的南北流量。Istio Gateway 描述了一个负载均衡器,用于承载进出服务网格边缘的连接。该规范描述了一组开放端口和这些端口所使用的协议,以及用于负载均衡的 SNI 配置等。Gateway 是一个 CRD 扩展,它也重用了 sidecar 代理的功能;详细配置请参见 Istio 网站 。
Envoy 是 Istio 中默认的 sidecar 代理。Istio 基于 Enovy 的 xDS 协议扩展了其控制平面。在讨论 Envoy 的 xDS 协议之前,我们需要先熟悉 Envoy 的基本术语。下面是 Envoy 的架构图。

以下是 Enovy 中你应该知道的基本术语。
在 Envoy 中可以设置多个监听器,每个监听器可以设置一个过滤链(过滤链表),而且过滤链是可扩展的,这样我们可以更方便地操纵流量的行为–比如设置加密、私有 RPC 等。
xDS 协议是由 Envoy 提出的,是 Istio 中默认的 sidecar 代理,但只要实现了 xDS 协议,理论上也可以作为 Istio 中的 sidecar 代理 —— 比如蚂蚁集团开源的 MOSN 。
[
Istio 是一个功能非常丰富的服务网格,包括以下功能。
Istio 中定义了以下 CRD 来帮助用户进行流量管理。
在回顾了 Kubernetes 的 kube-proxy 组件、xDS 和 Istio 对流量管理的抽象后,现在我们仅从流量管理的角度来看看这三个组件 / 协议的比较(注意,三者并不完全等同)。
| Kubernetes | xDS | Istio service mesh |
|---|---|---|
| Endpoint | Endpoint | WorkloadEntry |
| Service | Route | VirtualService |
| kube-proxy | Route | DestinationRule |
| kube-proxy | Listener | EnvoyFilter |
| Ingress | Listener | Gateway |
| Service | Cluster | ServiceEntry |
如果说 Kubernetes 管理的对象是一个 pod,那么服务网格管理的对象就是一个服务,所以用 Kubernetes 管理微服务,然后应用服务网格就可以了。如果你连服务都不想管理,那就用 Knative 这样的无服务器平台,不过这是后话
文章目录一、污点(Taint)1、污点简介2、污点的组成3、污点的设置和去除二、容忍(Tolerations)1、容忍简介2、容忍的基本用法3、示例4、多污点与多容忍配置三、警戒(cordon)和转移(drain)四、Pod启动阶段(相位phase)五、故障排除步骤一、污点(Taint)节点亲和性,是Pod的一种属性(偏好或硬性要求),它使Pod被吸引到一类特定的节点Taint则相反,它使节点能够排斥一类特定的PodTaint和Toleration相互配合,可以用来避免Pod被分配到不合适的节点上。每个节点上都可以应用一个或多个taint,这表示对于那些不能容忍这些taint的Pod,是不会被
文章目录Kubernetes(k8s)工作负载一、Workloads二、Pod三、Deployment四、RC、RS、DaemonSet、StatefulSet五、Job、CronJob1、Job2、CronJob六、GCKubernetes(k8s)工作负载一、Workloads什么是工作负载(Workloads)工作负载是运行在Kubernetes上的一个应用程序。一个应用很复杂,可能由单个组件或者多个组件共同完成。无论怎样我们可以用一组Pod来表示一个应用,也就是一个工作负载Pod又是一组容器(Containers)所以关系又像是这样工作负载(Workloads)控制一组PodPod控制
前言 前端时间PHP项目部署升级需要,需要把Laravel开发的项目部署K8s上,下面以laravel项目为例,讲解采用yaml文件方式部署项目。一、部署步骤1.创建Dockerfile文件Dockerfile是一个用来构建镜像的文本文件,在容器运行时,需要把项目文件和项目运行所必须的组件安装其中。#基础镜像FROMphp:7.4-fpm#时区ARGTZ=Asia/Shanghai#更换容器时区RUNcp"/usr/share/zoneinfo/$TZ"/etc/localtime&&echo"$TZ">/etc/timezone#替换成阿里apt-get源RUNsed-i"s@http
目录前言安装containerd解压安装配置成systemd任务安装runc编辑安装cni配置containerd镜像源containerd基本使用拓展阅读nerdctl工具安装及使用整体脚本总结写在后面前言上一篇文章,我们介绍了虚拟机的基础环境以及基础的网络配置,还有一些k8s节点要用到基础环境配置。本文将带领大家把containerd给安装了containerd的项目官方地址https://github.com/containerd/containerdcontainerd的发布版本地址如下https://github.com/containerd/containerd/releases
文章目录一.k8s集群修改config1.1备份当前k8s集群配置文件1.2删除当前k8s集群的apiserver的cert和key1.3生成新的apiserver的cert和key1.4刷新admin.conf1.5重启apiserver1.6刷新.kube/config二.安装kubectl2.1下载kubectl2.2配置kubectl三.使用kubernetes-client操作k8s集群3.1依赖3.2注意(可忽略)3.3创建StatefulSet3.4运行shell命令3.5删除StatefulSet3.6线上运行注意一.k8s集群修改config因为默认的是内网IP,复制出来后,
k8sissue: error:Readinessprobefailed:HTTPprobefailedwithstatuscode:503explanation:Kubernetes为准备和活动探测返回HTTP503错误的事实意味着到后端的连接可能有问题。有趣的是,这不是重点。这些探针不是用来执行HTTP流的端到端测试的。探测只用于验证它们所监视的服务是否响应。简单地说,好的是自己设置的readiness探针(probe)起作用了,不好的是,自己的配置文件可能有一些其他方面的问题。具体是什么方面的问题呢?就是创建出来的container里的报错信息Read-onlyfilesystem/xx
日志收集介绍日志收集的目的:分布式日志数据统一收集,实现集中式查询和管理故障排查安全信息和事件管理报表统计及展示功能日志收集的价值:日志查询、问题排查、故障恢复和故障自愈应用日志分析,错误报警性能分析,用户行为分析k8s常用的日志收集方式:在节点上进行收集,基于daemonset部署日志收集容器,实现json-file类型(标准输出/dev/stdout,错误输出/dev/stderr)日志收集使用sidecar容器收集当前Pod内一个或多个业务容器的日志,通常基于emptyDir实现业务容器与sidecar容器之间的日志共享在容器内内置日志收集进程ES集群部署使用主机如下:IP主机名角色19
文章目录概述认证认证插件基于静态token的认证服务实践基于X509证书认证实践基于webhook认证实践鉴权k8s中RBAC的使用授权实践准入场景配额管理实践插件插件开发限流APIPriorityandFairnessAPF中的排队FlowSchema与PriorityLevelConfiguration(队列权重配置)调试命令概述kube-apiserver是k8s最重要的控制组件之一,主要提供以下功能:提供集群管理的RESTAPI接口,包括认证授权、数据校验以及集群状态变更等k8s中所有模块与etcd的数据交互都需要走APIServer,禁止直接和etcd通信APIServer请求流程概
文章目录01引言02DNS服务在k8s的发展2.1SkyDNS2.2KubeDNS2.3CoreDNS03搭建CoreDNS服务3.1修改每个Node上kubelet的DNS启动参数3.2部署CoreDNS服务3.2.1ConfigMap3.2.2Deployment3.2.3Service04服务名的DNS解析05CoreDNS配置5.1示例一:设置插件5.2示例二:自定义域名5.3示例三:转发域名查询到上游DNS服务器上06引言01引言声明:本文为《Kubernetes权威指南:从Docker到Kubernetes实践全接触(第5版)》的读书笔记作为服务发现机制的基本功能,在集群内需要能够
Kubernetes声明式对象的增删改查前言一、创建对象二、更新对象三、删除对象四、查看对象总结前言我们可以通过在一个目录中存储多个对象配置文件、并使用kubectlapply来递归地创建和更新对象来创建、更新和删除Kubernetes对象。这种方法会保留对现有对象已作出的修改,而不会将这些更改写回到对象配置文件中。kubectldiff也会给你呈现apply将作出的变更的预览。一、创建对象使用kubectlapply来创建指定目录中配置文件所定义的所有对象,除非对应对象已经存在:$kubectlapply-f/此操作会在每个对象上设置kubectl.kubernetes.io/last-ap