-
全球顶级开源组织云原生计算基金会(Cloud Native Computing Foundation,简称 CNCF)正式宣布其2024年技术监督委员会(Technical Oversight Committee,简称CNCF TOC)席位,华为云云原生开源负责人王泽锋,凭借其在CNCF领域长期卓越的贡献成功当选,成为本届 CNCF TOC 11位技术领军人物之一。CNCF致力于云原生技术的普及和可持续发展,汇集世界顶级厂商,发展至今会员单位已超过750+。CNCF技术监督委员会是CNCF的核心决策团队,为云原生社区提供技术领导,决定CNCF社区的技术走向,由董事会、Maintainer以及End User等多个选区投票产生。一直以来,CNCF TOC主要以欧美专家为主,本届选举中,华为云开源专家王泽锋获得CNCF Maintainer广泛支持,凭借Maintainer选区最高票当选新一届CNCF TOC委员(2024-2026任期)。这也标志着其个人及华为在云原生领域的持续贡献获得产业界的高度认可,代表了整个中国本土贡献者在国际舞台上开源影响力的新高度。云原生产业规模和前景巨大,不少技术领域仍然处于窗口期,可谓机遇与挑战并存。王泽锋表示:“中国在全球云原生产业发展中拥有非常明显的优势:巨大的数字经济规模、丰富的应用场景,不断推动技术层面的创新;不少本土科技公司凭借技术实力已在云原生的核心赛道中占据了重要位置。作为CNCF TOC的新任成员,我将致力于更好地联接国内以及国际开源社区,借助CNCF、华为等平台及资源,携手更多企业、开源组织、学术机构及广大开发者一起,共同推动云原生技术发展与产业标准化,赋能千行万业的数字化转型。”王泽锋:协作创新,共建更有生命力的开源社区作为最早来自中国的Kubernetes维护者之一,王泽锋早在2014年基于 Upstream first 的理念,参与 Kubernetes 上游社区贡献,并于2015年成为了国内最早的 Kubernetes maintainer 之一,其主导的 Kubernetes 社区的多个关键特性和子项目的设计研发工作在社区完成开发后被大量企业用户在生产环境中广泛使用;与此同时,他指导了超过30名开发人员成为Kubernetes和其他CNCF项目的业务骨干、核心开发者。2018 年,王泽锋与同事联合创立了业界首个云原生边缘计算项目KubeEdge 开源项目,并捐赠到 CNCF 基金会,通过开放社区的治理模式与业界开发者协作共享。KubeEdge 也因此成为 CNCF 第一个将云原生技术应用到边缘计算的开源项目。时至今日,KubeEdge 在交通、能源、通信、金融、工业制造、CDN、智慧园区等各行各业已经有了更加深广的应用和普惠价值。此外,他还发起了 Volcano云原生批量计算 、Karmada云原生多集群管理 等多个云原生开源项目,填补了云原生技术在相关领域的技术空白。作为CNCF中国大使,王泽锋在KubeCon + CloudNativeCon 程序委员会任职多年,并于 2023 年担任 KubeCon + CloudNativeCon China 联合主席。作为公认的演讲者,王泽锋多次在 KubeCon Europe 和 KubeCon China 上发表Keynote和分论坛议题演讲。此外,王泽锋一直是Kubernetes贡献者峰会的长期支持者,联合规划和组织多场KCS China、KCD,并从2018年开始,联合策划了 “Cloud Native Days China”系列 Meetup、“Cloud Native Lives”等一系列业内活动;与此同时,由他发起的系列云原生技术公共课程,帮助超过百万的中国开发者构筑云原生技术交流平台,学习和采用云原生技术。技术先驱,引领全球云原生生态圈作为CNCF亚洲唯一创始成员、白金成员,华为对 Kubernetes、Istio 等社区核心项目的贡献一直位居全球前列,社区影响力持续多年亚洲第一,加速了云原生技术从起步到成熟的过程;华为拥有10余位CNCF项目核心Maintainer,出版多部云原生领域技术书籍,是全球云原生开源技术的领导者之一。近年来,华为持续开源创新,先后向CNCF捐献业界首个云原生边缘计算项目KubeEdge、首个云原生算力调度引擎Volcano、首个多云容器编排引擎Karmada等重量级云原生项目,在网络、边缘、调度、多云等技术领域形成了相对成熟生态圈,并开源了Kurator、Kappital、Kuasar、Kmesh等创新项目,加速了云原生与边缘计算、AI、大数据等产业的融合。共享开源价值,为行业发展注入源生动力在数字经济快速演进的大背景下,开源作为数智化转型的创新驱动力,不断催生技术突破和业务创新,发挥出愈加凸显的价值。华为与业界分享生产实践经验及创新成果,与国际云原生社区共发展。未来,面向全球的云原生社区工作有何创新?王泽锋提出了他对CNCF TOC的愿景和其独特的价值:促进跨区域新贡献者和现有贡献者之间的经验分享和沟通。建立公共的维护者地图,帮助新加入的贡献者找到周围的维护者以获得支持和帮助,以新一代的维护者增进社区活力,促进项目的可持续性。建立项目导师和项目冠军机制,帮助加快新开源项目向CNCF的申请/引导过程,以及项目在CNCF沙盒和孵化器中的成长。更清晰的项目推进过程和相应的自动化工具,以减少项目维护者和TOC/TAG成员在观察和评估项目健康和项目成熟度方面所花费的时间。云原生+AI,开源加速构建AI基础设施面对AI时代迎面而来的挑战,华为云在云原生领域持续引领,打造多云场景下的AI云原生基础设施,加速构建AI时代最佳云底座。作为全球最早参与CNCF重点项目产品化的企业之一,华为云早在2015年基于Kubernetes、Istio等上游社区,推出了国内最早的商用容器产品,并于2016年发布国内首个公有云容器服务CCE(云容器引擎)。伴随华为云近年来的高速发展,目前华为云已经陆续发布Serverless容器CCI、应用服务网格ASM、智能边缘平台IEF、分布式云原生UCS等多个创新产品,连续七次登顶IDC发布的中国容器市场份额报告,这也是业界对华为云在容器领域一路领先给与的充分肯定。智能浪潮新形势下,华为云结合在云原生领域的领先优势,打造云原生多云融合基础设施,云原生AI基础设施,云原生Serverless基础设施等系列解决方案,陆续升级发布华为云CCE Turbo,华为云CCE Autopilot,Serverless云耀云容器等创新产品。由华为云开源并捐赠至CNCF的孵化级开源项目也在AI云边协同、AI混部调度、多集群算力分配等技术领域加速行业产品应用升级,为行业智能升级攻坚克难,注入源生动力。未来,华为云云原生将持续与全球开发者紧密合作,共同推进云原生技术的创新与发展,积极推动云原生技术在产业领域的深度融合应用,为促进全球数智化经济的繁荣发展贡献力量。更多云原生技术动向关注容器魔方添加小助手k8s2222进入技术群
-
前面我们了解了位于服务网格内部的应用应如何访问网格外部的 HTTP 和 HTTPS 服务,知道如何通过 ServiceEntry 对象配置 Istio 以受控的方式访问外部服务,这种方式实际上是通过 Sidecar 直接调用的外部服务,但是有时候我们可能需要通过专用的 Egress Gateway 服务来调用外部服务,这种方式可以更好的控制对外部服务的访问。Istio 使用 Ingress 和 Egress Gateway 配置运行在服务网格边缘的负载均衡,Ingress Gateway 允许定义网格所有入站流量的入口。Egress Gateway 是一个与 Ingress Gateway 对称的概念,它定义了网格的出口。Egress Gateway 允许我们将 Istio 的功能(例如,监视和路由规则)应用于网格的出站流量。使用场景比如有一个对安全要求非常严格的团队,要求服务网格所有的出站流量必须经过一组专用节点。专用节点运行在专门的机器上,与集群中运行应用程序的其他节点隔离,这些专用节点用于实施 Egress 流量的策略,并且受到比其余节点更严密地监控。另一个使用场景是集群中的应用节点没有公有 IP,所以在该节点上运行的网格服务都无法访问互联网,那么我们就可以通过定义 Egress gateway,将公有 IP 分配给 Egress Gateway 节点,用它引导所有的出站流量,可以使应用节点以受控的方式访问外部服务。接下来我们就来学习下在 Istio 中如何配置使用 Egress Gateway。准备工作如果你使用的 demo 这个配置文件安装 Istio,那么 Egress Gateway 已经默认安装了,可以通过下面的命令来查看:$ kubectl get pod -l istio=egressgateway -n istio-system NAME READY STATUS RESTARTS AGE istio-egressgateway-556f6f58f4-hkzdd 1/1 Running 0 14d如果没有 Pod 返回,可以通过下面的步骤来部署 Istio Egress Gateway。如果你使用 IstioOperator 安装 Istio,请在配置中添加以下字段:spec: components: egressGateways: - name: istio-egressgateway enabled: true否则使用如下的 istioctl install 命令来安装:$ istioctl install <flags-you-used-to-install-Istio> \ --set components.egressGateways[0].name=istio-egressgateway \ --set components.egressGateways[0].enabled=true同样我们还是使用 sleep 示例做为发送请求的测试源,如果启用了自动 Sidecar 注入,运行以下命令部署示例应用程序:kubectl apply -f samples/sleep/sleep.yaml否则,在使用以下命令部署 sleep 应用程序之前,手动注入 Sidecar:kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml)为了发送请求,您需要创建 SOURCE_POD 环境变量来存储源 Pod 的名称:export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})用 Egress gateway 发起 HTTP 请求首先创建一个 ServiceEntry 对象来允许流量直接访问外部的 edition.cnn.com 服务。apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: cnn spec: hosts: - edition.cnn.com ports: - number: 80 name: http-port protocol: HTTP - number: 443 name: https protocol: HTTPS resolution: DNS发送 HTTPS 请求到 https://edition.cnn.com/politics 验证 ServiceEntry 是否已正确应用。$ kubectl exec "$SOURCE_POD" -c sleep -- curl -sSL -o /dev/null -D - http://edition.cnn.com/politics # 输出如下内 HTTP/1.1 301 Moved Permanently # ...... location: https://edition.cnn.com/politics # ...... HTTP/2 200 Content-Type: text/html; charset=utf-8 # ......然后为 edition.cnn.com 的 80 端口创建一个 egress Gateway,并为指向 Egress Gateway 的流量创建一个 DestinationRule 规则,如下所示:apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: istio-egressgateway spec: selector: istio: egressgateway # 匹配 Egress Gateway Pod 的标签 servers: - port: number: 80 name: http protocol: HTTP hosts: - edition.cnn.com # 也支持通配符 * 的形式 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: egressgateway-for-cnn spec: host: istio-egressgateway.istio-system.svc.cluster.local # 目标规则为 Egress Gateway subsets: - name: cnn # 定义一个子集 cnn,没有指定 labels,则 subset 会包含所有符合 host 字段指定的服务的 Pod在上面的对象中我们首先定义了一个 Gateway 对象,不过这里我们定义的是一个 Egress Gateway,通过 istio: egressgateway 匹配 Egress Gateway Pod 的标签,并在 servers 中定义了 edition.cnn.com 服务的 80 端口。然后定义了一个 DestinationRule 对象,指定了目标规则为 istio-egressgateway.istio-system.svc.cluster.local,并定义了一个子集 cnn。这里的子集名称是 cnn,但没有指定 labels。这意味着,这个 subset 会涵盖所有属于 istio-egressgateway.istio-system.svc.cluster.local 服务的 Pod。这种情况下,subset 的作用主要是为了在其他 Istio 配置中提供一个方便的引用名称,而不是为了区分不同的 Pod 子集。如何再定义一个 VirtualService 对象将流量从 Sidecar 引导至 Egress Gateway,再从 Egress Gateway 引导至外部服务,如下所示:apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: direct-cnn-through-egress-gateway spec: hosts: - edition.cnn.com gateways: - istio-egressgateway # Egress Gateway - mesh # 网格内部的流量 http: - match: - gateways: - mesh # 这条规则适用于从服务网格内发出的流量 port: 80 route: - destination: host: istio-egressgateway.istio-system.svc.cluster.local # 流量将被路由到 egress gateway subset: cnn port: number: 80 weight: 100 - match: - gateways: - istio-egressgateway # 这条规则适用于通过 istio-egressgateway 的流量 port: 80 route: - destination: host: edition.cnn.com # 流量将被路由到外部服务 port: number: 80 weight: 100在上面的 VirtualService 对象中通过 hosts 指定 edition.cnn.com,表示该虚拟服务用于该服务的请求,gateways 字段中定义了 istio-egressgateway 和 mesh 两个值,istio-egressgateway 是上面我们定义的 Egress Gateway,mesh 表示该虚拟服务用于网格内部的流量,也就是说这个虚拟服务指定了如何处理来自服务网格内部以及通过 istio-egressgateway 的流量。mesh 是一个特殊的关键字,在 Istio 中表示服务网格内的所有 Sidecar 代理。当使用 mesh 作为网关时,这意味着 VirtualService 中定义的路由规则适用于服务网格内的所有服务,即所有装有 Istio sidecar 代理的服务。http 字段中定义了两个 match,第一个 match 用于匹配 mesh 网关,第二个 match 用于匹配 istio-egressgateway 网关,然后在 route 中定义了两个 destination,第一个 destination 用于将流量引导至 Egress Gateway 的 cnn 子集,第二个 destination 用于将流量引导至外部服务。总结来说,这个 VirtualService 的作用是控制服务网格内部到 edition.cnn.com 的流量。当流量起始于服务网格内时,它首先被路由到 istio-egressgateway,然后再路由到 edition.cnn.com,这种配置有助于统一和控制从服务网格内部到外部服务的流量,可以用于流量监控、安全控制或实施特定的流量策略。应用上面的资源对象后,我们再次向 edition.cnn.com 的 /politics 端点发出 curl 请求:$ kubectl exec "$SOURCE_POD" -c sleep -- curl -sSL -o /dev/null -D - http://edition.cnn.com/politics # ...... HTTP/1.1 301 Moved Permanently location: https://edition.cnn.com/politics # ...... HTTP/2 200 Content-Type: text/html; charset=utf-8 # ......正常和前面的一次测试输出结果是一致的,但是这次在请求是经过 istio-egressgateway Pod 发出的,我们可以查看日志来验证:kubectl logs -l istio=egressgateway -c istio-proxy -n istio-system | tail正常会看到一行类似于下面这样的内容:[2023-11-15T08:48:38.683Z] "GET /politics HTTP/2" 301 - via_upstream - "-" 0 0 204 203 "10.244.1.73" "curl/7.81.0-DEV" "6c2c4550-92d4-955c-b6cb-83bf2b0e06f4" "edition.cnn.com" "151.101.3.5:80" outbound|80||edition.cnn.com 10.244.2.184:46620 10.244.2.184:8080 10.244.1.73:49924 - -因为我们这里只是将 80 端口的流量重定向到 Egress Gateway 了,所以重定向后 443 端口的 HTTPS 流量将直接进入 edition.cnn.com,所以没有看到 443 端口的日志,但是我们可以通过 SOURCE_POD 的 Sidecar 代理的日志来查看到:$ kubectl logs "$SOURCE_POD" -c istio-proxy | tail # ...... [2023-11-15T08:55:55.513Z] "GET /politics HTTP/1.1" 301 - via_upstream - "-" 0 0 191 191 "-" "curl/7.81.0-DEV" "12ce15aa-1247-9b7e-8185-4224f96f5ea0" "edition.cnn.com" "10.244.2.184:8080" outbound|80|cnn|istio-egressgateway.istio-system.svc.cluster.local 10.244.1.73:49926 151.101.195.5:80 10.244.1.73:41576 - - [2023-11-15T08:55:55.753Z] "- - -" 0 - - - "-" 839 2487786 1750 - "-" "-" "-" "-" "151.101.195.5:443" outbound|443||edition.cnn.com 10.244.1.73:45246 151.101.67.5:443 10.244.1.73:42998 edition.cnn.com -用 Egress gateway 发起 HTTPS 请求上面我们已经学习了如何通过 Egress Gateway 发起 HTTP 请求,接下来我们再来学习下如何通过 Egress Gateway 发起 HTTPS 请求。原理都是一样的,只是我们需要在相应的 ServiceEntry、Egress Gateway 和 VirtualService 中指定 TLS 协议的端口 443。首先为 edition.cnn.com 定义 ServiceEntry 服务:apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: cnn spec: hosts: - edition.cnn.com ports: - number: 443 name: tls protocol: TLS resolution: DNS应用该资源对象后,发送 HTTPS 请求到 https://edition.cnn.com/politics,验证该 ServiceEntry 是否已正确生效。$ kubectl exec "$SOURCE_POD" -c sleep -- curl -sSL -o /dev/null -D - https://edition.cnn.com/politics ... HTTP/2 200 Content-Type: text/html; charset=utf-8 ...接下来同样的方式为 edition.cnn.com 创建一个 Egress Gateway。除此之外还需要创建一个目标规则和一个虚拟服务,用来引导流量通过 Egress Gateway,并通过 Egress Gateway 与外部服务通信。apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: istio-egressgateway spec: selector: istio: egressgateway servers: - port: number: 443 name: tls protocol: TLS hosts: - edition.cnn.com tls: mode: PASSTHROUGH # 透传 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: egressgateway-for-cnn spec: host: istio-egressgateway.istio-system.svc.cluster.local subsets: - name: cnn --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: direct-cnn-through-egress-gateway spec: hosts: - edition.cnn.com gateways: - mesh - istio-egressgateway tls: - match: - gateways: - mesh port: 443 sniHosts: - edition.cnn.com route: - destination: host: istio-egressgateway.istio-system.svc.cluster.local subset: cnn port: number: 443 - match: - gateways: - istio-egressgateway port: 443 sniHosts: - edition.cnn.com route: - destination: host: edition.cnn.com port: number: 443 weight: 100上面对象中定义的 Gateway 对象和前面的一样,只是将端口改为了 443,然后在 tls 中指定了 mode: PASSTHROUGH,表示该 Gateway 对象用于 TLS 协议的请求。然后在后面的 VirtualService 对象中就是配置 spec.tls 属性,用于指定 TLS 协议的请求的路由规则,配置方法和前面 HTTP 方式类似,只是注意要将端口改为 443,并且在 match 中指定 sniHosts 为 edition.cnn.com,表示该虚拟服务用于处理 edition.cnn.com 的 TLS 请求。应用上面的资源对象后,我们现在发送 HTTPS 请求到 https://edition.cnn.com/politics,输出结果应该和之前一样。$ kubectl exec "$SOURCE_POD" -c sleep -- curl -sSL -o /dev/null -D - https://edition.cnn.com/politics ... HTTP/2 200 Content-Type: text/html; charset=utf-8 ...检查 Egress Gateway 代理的日志,则打印日志的命令是:kubectl logs -l istio=egressgateway -n istio-system应该会看到类似于下面的内容:[2023-11-15T08:59:55.513Z] "- - -" 0 - 627 1879689 44 - "-" "-" "-" "-" "151.101.129.67:443" outbound|443||edition.cnn.com 172.30.109.80:41122 172.30.109.80:443 172.30.109.112:59970 edition.cnn.com到这里我们就实现了通过 Egress Gateway 发起 HTTPS 请求。最后记得清理上面创建的资源对象:$ kubectl delete serviceentry cnn $ kubectl delete gateway istio-egressgateway $ kubectl delete virtualservice direct-cnn-through-egress-gateway $ kubectl delete destinationrule egressgateway-for-cnn需要注意的是,Istio 无法强制让所有出站流量都经过 Egress Gateway, Istio 只是通过 Sidecar 代理实现了这种流向。攻击者只要绕过 Sidecar 代理, 就可以不经 Egress Gateway 直接与网格外的服务进行通信,从而避开了 Istio 的控制和监控。出于安全考虑,集群管理员和云供应商必须确保网格所有的出站流量都要经过 Egress Gateway。这需要通过 Istio 之外的机制来满足这一要求。例如,集群管理员可以配置防火墙,拒绝 Egress Gateway 以外的所有流量。Kubernetes NetworkPolicy 也能禁止所有不是从 Egress Gateway 发起的出站流量,但是这个需要 CNI 插件的支持。此外,集群管理员和云供应商还可以对网络进行限制,让运行应用的节点只能通过 gateway 来访问外部网络。要实现这一限制,可以只给 Gateway Pod 分配公网 IP,并且可以配置 NAT 设备, 丢弃来自 Egress Gateway Pod 之外的所有流量。Egress TLS Origination接下来我们将学习如何通过配置 Istio 去实现对发往外部服务的流量的 TLS Origination(TLS 发起)。若此时原始的流量为 HTTP,则 Istio 会将其转换为 HTTPS 连接。TLS Origination 的概念前面我们也已经介绍过了。TLS Origination假设有一个传统应用正在使用 HTTP 和外部服务进行通信,如果有一天突然有一个新的需求,要求必须对所有外部的流量进行加密。此时,使用 Istio 便可通过修改配置实现此需求,而无需更改应用中的任何代码。该应用可以发送未加密的 HTTP 请求,由 Istio 为请求进行加密。从应用源头发起未加密的 HTTP 请求,并让 Istio 执行 TLS 升级的另一个好处是可以产生更好的遥测并为未加密的请求提供更多的路由控制。下面我们就来学习下如何配置 Istio 实现 TLS Origination。同样我们这里使用 sleep 示例应用来作为测试源,如果启用了自动注入 Sidecar,那么可以直接部署 sleep 应用:kubectl apply -f samples/sleep/sleep.yaml否则在部署 sleep 应用之前,必须手动注入 Sidecar:kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml)创建一个环境变量来保存用于将请求发送到外部服务 Pod 的名称:export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})▍配置对外部服务的访问首先使用 ServiceEntry 对象来配置对外部服务 edition.cnn.com 的访问。这里我们将使用单个 ServiceEntry 来启用对服务的 HTTP 和 HTTPS 访问。创建一个如下所示的 ServiceEntry 对象:apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: edition-cnn-com spec: hosts: - edition.cnn.com ports: - number: 80 name: http-port protocol: HTTP - number: 443 name: https-port protocol: HTTPS resolution: DNS上面的 ServiceEntry 对象中我们指定了 edition.cnn.com 服务的主机名,然后在 ports 中指定了需要暴露的端口及其属性,表示该 ServiceEntry 对象代表对 edition.cnn.com 的访问,这里我们定义了 80 和 443 两个端口,分别对应 http 和 https 服务,resolution: DNS 定义了如何解析指定的 hosts,这里我们使用 DNS 来解析。直接应用该资源对象,然后向外部的 HTTP 服务发送请求:$ kubectl exec "${SOURCE_POD}" -c sleep -- curl -sSL -o /dev/null -D - http://edition.cnn.com/politics # 输出如下结果 HTTP/1.1 301 Moved Permanently # ...... location: https://edition.cnn.com/politics HTTP/2 200 content-type: text/html; charset=utf-8 # ......上面我们在使用 curl 命令的时候添加了一个 -L 标志,该标志指示 curl 将遵循重定向。在这种情况下,服务器将对到 http://edition.cnn.com/politics 的 HTTP 请求进行重定向响应,而重定向响应将指示客户端使用 HTTPS 向 https://edition.cnn.com/politics 重新发送请求,对于第二个请求,服务器则返回了请求的内容和 200 状态码。尽管 curl 命令简明地处理了重定向,但是这里有两个问题。第一个问题是请求冗余,它使获取 http://edition.cnn.com/politics 内容的延迟加倍,第二个问题是 URL 中的路径(在本例中为 politics)被以明文的形式发送。如果有人嗅探你的应用与 edition.cnn.com 之间的通信,他将会知晓该应用获取了此网站中哪些特定的内容。出于隐私的原因,我们可能希望阻止这些内容被嗅探到。通过配置 Istio 执行 TLS 发起,则可以解决这两个问题。▍用于 egress 流量的 TLS 发起为 edition.cnn.com 创建一个出口网关,端口为 80,接收 HTTP 流量,如下所示:apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: istio-egressgateway spec: selector: istio: egressgateway servers: - port: number: 80 name: tls-origination-port protocol: HTTP hosts: - edition.cnn.com然后为 istio-egressgateway 创建一个 DestinationRule 对象,如下所示:apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: egressgateway-for-cnn spec: host: istio-egressgateway.istio-system.svc.cluster.local subsets: - name: cnn接着我们只需要创建一个 VirtualService 对象,将流量从 Sidecar 引导至 Egress Gateway,再从 Egress Gateway 引导至外部服务,如下所示:apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: direct-cnn-through-egress-gateway spec: hosts: - edition.cnn.com gateways: - istio-egressgateway # Egress Gateway - mesh # 网格内部的流量 http: - match: - gateways: - mesh port: 80 route: - destination: host: istio-egressgateway.istio-system.svc.cluster.local subset: cnn port: number: 80 weight: 100 - match: - gateways: - istio-egressgateway port: 80 route: - destination: host: edition.cnn.com port: number: 443 # 443 端口 weight: 100 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: originate-tls-for-edition-cnn-com spec: host: edition.cnn.com trafficPolicy: loadBalancer: simple: ROUND_ROBIN portLevelSettings: - port: number: 443 tls: mode: SIMPLE # initiates HTTPS for connections to edition.cnn.com需要注意的是上面最后针对 edition.cnn.com 的 DestinationRule 对象,在 trafficPolicy 中指定了 portLevelSettings 用于对不同的端口定义不同的流量策略,这里我们定义了 443 端口的 tls 模式为 SIMPLE,表示当访问 edition.cnn.com 的 HTTP 请求时执行 TLS 发起。应用上面的资源对象,然后再次向 http://edition.cnn.com/politics 发送 HTTP 请求:$ kubectl exec "${SOURCE_POD}" -c sleep -- curl -sSL -o /dev/null -D - http://edition.cnn.com/politics # 直接输出200状态码 HTTP/1.1 200 OK content-length: 2474958 content-type: text/html; charset=utf-8 # ......这次将会收到唯一的 200 OK 响应,因为 Istio 为 curl 执行了 TLS 发起,原始的 HTTP 被升级为 HTTPS 并转发到 edition.cnn.com。服务器直接返回内容而无需重定向,这消除了客户端与服务器之间的请求冗余,使网格保持加密状态,隐藏了你的应用获取 edition.cnn.com 中 politics 端点的信息。如果我们在代码中有去访问外部服务,那么我们就可以不用修改代码了,只需要通过配置 Istio 来获得 TLS 发起即可,而无需更改一行代码。到这里我们就学习了如何通过配置 Istio 实现对外部服务的 TLS 发起。▍TLS 与 mTLS 基本概念前面我们学习了如何通过配置 Istio 实现对外部服务的 TLS 发起,这里其实还有一个 mTLS 的概念呢,由于 TLS 本身就比较复杂,对于双向 TLS(mTLS)就更复杂了。TLS 是一个连接层协议,旨在为 TCP 连接提供安全保障。TLS 在连接层工作,可以与任何使用 TCP 的应用层协议结合使用。例如,HTTPS 是 HTTP 与 TLS 的结合(HTTPS 中的 S 指的是 SSL,即 TLS 的前身),TLS 认证的流程大致如下所示:首先向第三方机构 CA 提交组织信息、个人信息(域名)等信息并申请认证。CA 通过多种手段验证申请者提供信息的真实性,如组织是否存在、企业是否合法,是否拥有域名的所有权等。如信息审核通过,CA 会向申请者签发认证文件-证书。证书包含以下信息:申请者公钥、申请者的组织信息和个人信息、签发机构 CA 的信息、有效时间、证书序列号等信息的明文,同时包含一个签名。其中签名的产生算法:首先,使用散列函数计算公开的明文信息的信息摘要,然后,采用 CA 的私钥对信息摘要进行加密,密文即签名。客户端向服务端发出请求时,服务端返回证书文件。客户端读取证书中的相关的明文信息,采用相同的散列函数计算得到信息摘要,然后,利用对应 CA 的公钥解密签名数据,对比证书的信息摘要,如果一致,则可以确认证书的合法性。客户端还会验证证书相关的域名信息、有效时间等信息; 客户端会内置信任 CA 的证书信息(包含公钥),比如浏览器基本上都带有知名公共 CA 机构的证书,如 Verisign、Digicert 等,这些证书在发布时被打包在一起,当我们下载浏览器时,就经把正确的证书放进了浏览器,如果 CA 不被信任,则找不到对应 CA 的证书,证书也会被判定非法。认证过程当然 HTTPS 的工作流程和这个过程基本就一致了:1.客户端发起一个 HTTPS 请求。2.服务端把配置好的证书返回给客户端。3.客户端验证证书:比如是否在有效期内,证书的用途是不是匹配 Client 请求的站点,是不是在 CRL 吊销列表里面,它的上一级证书是否有效等。4.客户端使用伪随机数生成对称密钥,并通过证书里服务器的公钥进行加密,后续使用该对称密钥进行传输信息。5.服务端使用自己的私钥解密这个消息,得到对称密钥。至此,客户端和服务端都持有了相同的对称密钥。6.服务端使用对称密钥加密明文内容 A,发送给客户端。7.客户端使用对称密钥解密响应的密文,得到明文内容 A。8.客户端再次发起 HTTPS 的请求,使用对称密钥加密请求的明文内容 B,然后服务器使用对称密钥解密密文,得到明文内容 B。HTTPS 工作流程当然双向 TLS 就更为复杂了,Mutual TLS(双向 TLS),或称 mTLS,对于常规的 TLS,只需要服务端认证,mTLS 相对来说有一个额外的规定:客户端也要经过认证。在 mTLS 中,客户端和服务器都有一个证书,并且双方都使用它们的公钥/私钥对进行身份验证。TLS 保证了真实性,但默认情况下,这只发生在一个方向上:客户端对服务器进行认证,但服务器并不对客户端进行认证。为什么 TLS 的默认只在一个方向进行认证?因为客户端的身份往往是不相关的。例如我们在访问优点知识的时候,你的浏览器已经验证了要访问的网站服务端的身份,但服务端并没有验证你的浏览器的身份,它实际上并不关心你的浏览器的身份,这对于互联网上的 Web 项目来说足够了。但是在某些情况下,服务器确实需要验证客户端的身份,例如,当客户端需要访问某些敏感数据时,服务器可能需要验证客户端的身份,以确保客户端有权访问这些数据,这就是 mTLS 的用武之地,mTLS 是保证微服务之间跨服务通信安全的好方法。首先,你想要安全的通信。当我们把我们的应用程序拆分为多个服务时,我们最终会在这些服务之间的网络上发送敏感数据。任何能够进入网络的人都有可能读取这些敏感数据并伪造请求。其次,你关心客户端的身份。首先,你要确保你能知道调用是什么时候发生的,以便进行诊断,并正确记录指标等事项。此外,你可能想对这些身份进行授权(允许 A 调用 B 吗)。当然授权是另外的话题了。接下来我们就来测试下如何通过 egress 网关发起双向 TLS 连接。▍通过 egress 网关发起双向 TLS 连接首先使用 openssl 命令生成客户端和服务器的证书与密钥,为你的服务签名证书创建根证书和私钥:openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt # 生成 CA 证书和私钥为 my-nginx.mesh-external.svc.cluster.local 创建证书和私钥:# 为 my-nginx.mesh-external.svc.cluster.local 创建私钥和证书签名请求 $ openssl req -out my-nginx.mesh-external.svc.cluster.local.csr -newkey rsa:2048 -nodes -keyout my-nginx.mesh-external.svc.cluster.local.key -subj "/CN=my-nginx.mesh-external.svc.cluster.local/O=some organization" # 使用 CA 公钥和私钥以及证书签名请求为 my-nginx.mesh-external.svc.cluster.local 创建证书 $ openssl x509 -req -sha256 -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in my-nginx.mesh-external.svc.cluster.local.csr -out my-nginx.mesh-external.svc.cluster.local.crt然后生成客户端证书和私钥:# 为 client.example.com 创建私钥和证书签名请求 $ openssl req -out client.example.com.csr -newkey rsa:2048 -nodes -keyout client.example.com.key -subj "/CN=client.example.com/O=client organization" # 使用相同的 CA 公钥和私钥以及证书签名请求为 client.example.com 创建证书 $ openssl x509 -req -sha256 -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 1 -in client.example.com.csr -out client.example.com.crt接着我们来部署一个双向 TLS 服务器,为了模拟一个真实的支持双向 TLS 协议的外部服务,我们在 Kubernetes 集群中部署一个 NGINX 服务,该服务运行在 Istio 服务网格之外,比如运行在一个没有开启 Istio Sidecar proxy 注入的命名空间中。创建一个命名空间 mesh-external 表示 Istio 网格之外的服务,注意在这个命名空间中,Sidecar 自动注入是没有开启的,不会在 Pod 中自动注入 Sidecar proxy。kubectl create namespace mesh-external然后创建 Kubernetes Secret,保存服务器和 CA 的证书。$ kubectl create -n mesh-external secret tls nginx-server-certs --key my-nginx.mesh-external.svc.cluster.local.key --cert my-nginx.mesh-external.svc.cluster.local.crt $ kubectl create -n mesh-external secret generic nginx-ca-certs --from-file=example.com.crt生成 NGINX 服务器的配置文件:$ cat <<\EOF > ./nginx.conf events { } http { log_format main '$remote_addr - $remote_user [$time_local] $status ' '"$request" $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log; server { listen 443 ssl; root /usr/share/nginx/html; index index.html; server_name my-nginx.mesh-external.svc.cluster.local; ssl_certificate /etc/nginx-server-certs/tls.crt; ssl_certificate_key /etc/nginx-server-certs/tls.key; ssl_client_certificate /etc/nginx-ca-certs/example.com.crt; ssl_verify_client on; } } EOF生成 Kubernetes ConfigMap 保存 NGINX 服务器的配置文件:kubectl create configmap nginx-configmap -n mesh-external --from-file=nginx.conf=./nginx.conf然后就可以部署 NGINX 服务了:$ kubectl apply -f - <<EOF apiVersion: v1 kind: Service metadata: name: my-nginx namespace: mesh-external labels: run: my-nginx spec: ports: - port: 443 protocol: TCP selector: run: my-nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx namespace: mesh-external spec: selector: matchLabels: run: my-nginx template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 443 volumeMounts: - name: nginx-config mountPath: /etc/nginx readOnly: true - name: nginx-server-certs mountPath: /etc/nginx-server-certs readOnly: true - name: nginx-ca-certs mountPath: /etc/nginx-ca-certs readOnly: true volumes: - name: nginx-config configMap: name: nginx-configmap - name: nginx-server-certs secret: secretName: nginx-server-certs - name: nginx-ca-certs secret: secretName: nginx-ca-certs EOF现在如果我们在网格内部去直接访问这个 my-nginx 服务,是无法访问的,第一是没有内置 CA 证书,另外是 my-nginx 服务开启了 mTLS,需要客户端证书才能访问,现在我们的网格中是没有对应的客户端证书的,会出现 400 错误。开启了双向认证▍为 egress 流量配置双向 TLS创建 Kubernetes Secret 保存客户端证书:kubectl create secret -n istio-system generic client-credential --from-file=tls.key=client.example.com.key \ --from-file=tls.crt=client.example.com.crt --from-file=ca.crt=example.com.crtSecret 所在的命名空间必须与出口网关部署的位置一致,我们这里是 istio-system 命名空间。然后为 my-nginx.mesh-external.svc.cluster.local 创建一个端口为 443 的 Egress Gateway,以及目标规则和虚拟服务来引导流量流经 egress 网关并从 egress 网关流向外部服务。$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: istio-egressgateway spec: selector: istio: egressgateway servers: - port: number: 443 name: https protocol: HTTPS hosts: - my-nginx.mesh-external.svc.cluster.local tls: mode: ISTIO_MUTUAL --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: egressgateway-for-nginx spec: host: istio-egressgateway.istio-system.svc.cluster.local subsets: - name: nginx trafficPolicy: loadBalancer: simple: ROUND_ROBIN portLevelSettings: - port: number: 443 tls: mode: ISTIO_MUTUAL sni: my-nginx.mesh-external.svc.cluster.local EOF上面我们定义的 Gateway 对象和前面的一样,只是将端口改为了 443,然后在 tls 中指定了 mode: ISTIO_MUTUAL,表示该 Gateway 对象用于 TLS 双向认证协议的请求。然后同样在后面的 DestinationRule 对象中配置了通过 istio-egressgateway 的流量的规则,这里我们定义了 443 端口的 tls 模式为 ISTIO_MUTUAL,表示当访问 my-nginx.mesh-external.svc.clustr.local 的 TLS 请求时执行 TLS 双向认证。最后我们定义一个 VirtualService 对象来引导流量流经 egress 网关:$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: direct-nginx-through-egress-gateway spec: hosts: - my-nginx.mesh-external.svc.cluster.local gateways: - istio-egressgateway - mesh # 网格内部的流量 http: - match: - gateways: - mesh port: 80 route: - destination: host: istio-egressgateway.istio-system.svc.cluster.local subset: nginx port: number: 443 weight: 100 - match: - gateways: - istio-egressgateway port: 443 route: - destination: host: my-nginx.mesh-external.svc.cluster.local port: number: 443 weight: 100 EOF上面的 VirtualService 对象定义网格内部对 my-nginx.mesh-external.svc.cluster.local 服务的访问引导至 istio-egressgateway,然后再由 istio-egressgateway 引导流量流向外部服务。添加 DestinationRule 执行双向 TLS:$ kubectl apply -n istio-system -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: originate-mtls-for-nginx spec: host: my-nginx.mesh-external.svc.cluster.local trafficPolicy: loadBalancer: simple: ROUND_ROBIN portLevelSettings: - port: number: 443 tls: mode: MUTUAL credentialName: client-credential # 这必须与之前创建的用于保存客户端证书的 Secret 相匹配 sni: my-nginx.mesh-external.svc.cluster.local EOF发送一个 HTTP 请求至 http://my-nginx.mesh-external.svc.cluster.local:$ kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl -sS http://my-nginx.mesh-external.svc.cluster.local <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...检查 istio-egressgateway Pod 日志,有一行与请求相关的日志记录。如果 Istio 部署在命名空间 istio-system 中,打印日志的命令为:kubectl logs -l istio=egressgateway -n istio-system | grep 'my-nginx.mesh-external.svc.cluster.local' | grep HTTP将显示类似如下的一行:[2023-11-17T08:23:51.203Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 615 17 16 "10.244.1.100" "curl/7.81.0-DEV" "434b5755-54da-9924-9e2a-a204b5a2124c" "my-nginx.mesh-external.svc.cluster.local" "10.244.1.106:443" outbound|443||my-nginx.mesh-external.svc.cluster.local 10.244.2.239:35198 10.244.2.239:8443 10.244.1.100:56448 my-nginx.mesh-external.svc.cluster.local -双向认证即使我们直接在网格中访问的是 HTTP 的服务,但是通过配置 Istio,我们也可以实现对外部服务的双向 TLS 认证。参考文档:https://istio.io/latest/docs/tasks/traffic-management/egress/本文转载自k8s技术圈,原文链接添加社区小助手回复“Istio”进入技术交流群
-
作者:华为云云原生团队如果说在以Kubernetes为基础构建起的云原生世界里,哪种设计模式最为经典,Sidecar模式无疑是其中最有力的竞争者。当需要为应用提供与自身逻辑无关的辅助功能时,在应用Pod内注入对应功能的Sidecar显然是最Kubernetes Native的方式,而Istio则是这种模式的代表。Istio项目的愿景是以尽量透明的方式,解决微服务场景下,服务间的连接、安全以及可观测性问题。主要实现手段则是通过在应用旁部署一个Proxy,在Kubernetes场景下则为应用Pod注入Sidecar,拦截应用流量至Sidecar。Sidecar根据从Istio控制面获取的用户配置对应用流量进行处理,以一种对应用代码几乎无侵入的方式实现了服务治理。图1虽然Istio并不局限于仅支持Kubernetes平台,但是Istio的设计理念与Kubernetes的Sidecar模式有着天然的亲和性。基于Sidecar模式,Istio能够实现在Kubernetes平台上的快速开发、部署、验证。同时,在功能层面,Isito将服务治理功能从应用代码中剥离,作为基础设施下沉至Sidecar,抽象出了事实上的云原生应用网络层,极大地减轻了应用开发者的心智负担,这部分能力刚好也是Kubernetes生态一直以来缺失的。基于Istio对于Kubernetes生态的完美补充,随着Kubernetes的大规模普及,Istio也实现了对用户心智以及市场的快速抢占。虽然以Sidecar模式部署Istio数据面似乎是一个理所应当,让人无法拒绝的选择,但是需要强调的是,Istio完整功能的实现并不与Sidecar模式强绑定,我们还有各种各样其他的选择。另外,随着对于Istio使用程度不断加深,落地规模不断扩大,可以发现以Sidecar模式部署Istio数据面诸多挑战:1. 侵入性:Istio基本实现了对应用代码的零侵入,但是由于Sidecar的注入需要更改Pod Spec并且对应用流量进行重定向,因此应用接入网格时需要重启Pod,而应用容器与Sidecar容器的启动顺序不确定造成的冲突也可能导致应用中断;2. 生命周期绑定: Sidecar本质上是基础设施,它和应用的生命周期往往不一致,因此升级Sidecar时也需要对应用Pod进行重启,同样可能导致应用中断,而对于Job类应用,Sidecar的存在则会导致Pod无法被及时清理;3. 资源利用率低:Sidecar为单个应用Pod独占,应用的流量存在波峰波谷,而一般情况下Sidecar的内存占用与集群规模(Service数目,Pod数目)强相关,因此需要按照极端情况预留资源,导致集群整体的资源利用率低。同时由于需要为每个Pod注入Sidecar,随着集群规模的不断扩大,Sidecar占用的资源总量也会线性上涨。针对Sidecar部署模式的缺陷,Google和Solo.io联合推出了一种新的Sidecar-less部署模式 --- Ambient Mesh。架构介绍图2Ambient Mesh架构如上图所示,从设计的角度来看,它主要有以下两个特点:1. Sidecar-less:为了避免上述Sidecar模式的种种缺陷,Ambient Mesh不再为任何Pod注入Sidecar,将网格功能的实现进一步下沉到Istio自有组件中。2. L4/L7处理分层:Ambient Mesh引入了ztunnel和waypoint两个组件用于代替原来的Sidecar实现相关功能,与Sidecar既能处理L4,又能处理L7流量的实现方式不同,Ambient Mesh对两者进行了区分,ztunnel只负责L4流量的处理,L7的流量则按需交由waypoint处理。Ambient Mesh的控制面与原先Sidecar模式的Istio相比基本没有变化,数据面的组件构成以及各个组件的作用如下:1. istio-cni:必装组件,以DaemonSet的形式部署。其实istio-cni并不是Ambient Mesh的新增组件,在原先的Sidecar模式中就已经存在,当时主要用于替代istio-init这个Init Container配置流量拦截规则,同时规避istio-init引发的安全问题。Ambient Mesh对它进行了扩展,以必装组件的形式部署,负责配置流量转发规则,劫持本节点中已加入Ambient Mesh的Pods的应用流量,转发至本节点的ztunnel;2. ztunnel: 必装组件,以DaemonSet的形式部署。ztunnel对所在节点Pods的流量进行代理,主要负责L4流量的处理、L4的遥测以及服务间mTLS(双向认证)的管理。最初ztunnel基于Envoy实现,但是考虑到对ztunnel功能的有意约束以及对安全性、资源占用率的要求,社区已经用rust从零构建该组件;3. waypoint:按需配置,以Deployment的形式部署。waypoint负责处理HTTP,故障注入等L7功能。以负载或者Namespace粒度进行部署,在Kubernetes中,即一个Service Account或者一个Namespace对应生成一个waypoint的Deployment,用于处理发往对应负载的七层流量,同时waypoint实例数可以根据流量动态伸缩。图3下面以Ambient Mesh数据面实际的处理过程来展示上述各个组件在其中扮演的具体角色:1. 与Sidecar模式类似,Ambient Mesh也能以网格、Namespace以及Pod的粒度将服务加入网格;不同的是,新加入的Pod无需重启,更不需要注入Sidecar;2. istio-cni监听本节点内Pods的增删以及进出网格的情况,动态调整转发规则,网格内Pods发出的流量会被透明地转发至本节点的ztunnel,直接跳过kube-proxy的处理;3. ztunnel同样需要对本节点Pods的增删以及进出网格的情况进行监听,从控制面获取位于本节点且被网格接管的Pods的证书并进行管理;4. 源端ztunnel对拦截的流量进行处理,根据流量的源IP找到对应Pod的证书,由此和对端建立mTLS;5. 如果要访问的目标服务没有配置waypoint或者没有配置L7相关的处理策略,则源端ztunnel直接和目的端ztunnel建立连接(如上图黄线标注),对端的ztunnel终止mTLS,执行L4安全策略,将流量转发到目标Pod;6. 如果目标服务配置了waypoint(利用特殊配置的Gateway对象)以及L7的处理策略,则源端ztunnel会和对应的waypoint建立mTLS,waypoint终止mTLS后,进行L7的逻辑处理,之后再与目标Pod所在节点的ztunnel建立mTLS,最终同样由目的端的ztunnel终止mTLS并将流量发往目标Pod。▎价值分析虽然从底层实现来看,Ambient Mesh和原有的Sidecar模式的差别巨大,但是从用户面看,两者在核心Istio API(VirtualService, DestinationRules等)的使用方式、实现效果都是一致的,能够确保基本相同的用户体验。Ambient Mesh是Istio社区除Sidecar模式外,支持的第二种数据面模式,所以网格技术本身能为用户带来的价值,Ambient Mesh与先前的Sidecar模式并不二致。因此这里只对Ambient Mesh相对于原生Sidecar模式的价值进行分析,对于网格本身的价值不再赘述。Ambient Mesh主要是针对Istio的数据面架构进行调整,用于克服既有Sidecar模式的不足,因此它的价值产生必然是基于其架构特点。前文已经提到过Ambient Mesh的架构特点主要有“Sidecar-less”和“L4/L7处理分层”这两点,下面就从这两点出发进行价值分析:1. Sidecar-less的优势,其实可以看作Sidecar模式缺陷的对立面:a) 透明:网格功能下沉至基础设施,不仅对应用代码零侵入,和应用的生命周期也完全解耦,做到真正对应用透明,允许应用与网格独立演进;b) 优化资源占用:数据面占用的CPU、内存等资源不再随着实例数线性增长,随着数据面的实例数减少,与控制面的连接数也相应减少,极大地减轻控制面的资源与处理压力。2. 对于为什么要对L4/L7进行分层处理,首先要区分两者之间的区别。与L4相比,L7的处理更为复杂,需要占用更多的CPU/内存等资源,不同类型的操作之间资源占用也存在较大差别;同时操作越复杂暴露的攻击面越大。另外Envoy当前并不支持对不同租户的流量进行强隔离,“Noisy Neighbor”的问题不可避免。因此Ambient Mesh分层处理架构的优势如下:a) 资源利用率高:ztunnel仅负责L4的处理,L4处理较为简单且资源占用较为固定,所以更易对ztunnel进行资源规划,无需过量预留资源,能够将更多的节点资源供用户使用;waypoint更可以根据L7负载动态扩缩容,充分利用集群中的资源碎片;b) 租户隔离:处理复杂、安全风险高的L7处理由租户(Service Account)各自的waypoint处理,既避免了租户间的资源抢占,又限制了安全问题的爆炸半径;c) 平滑落地:允许用户逐步接入网格,当仅需网格的L4处理能力时,完全无需考虑L7的资源占用以及可能造成的潜在负面影响(例如:因为错误配置导致进入L7处理而应用并未完全遵守L7协议,导致服务中断),之后在适当时刻按需开启相关功能即可。当然Ambient Mesh作为Istio全新的数据面架构,在社区中依然以实验特性的形式存在,仍然有许多问题亟待解决,例如:1. 性能:尤其是针对L7的处理,Ambient Mesh需要经过两个ztunnel以及一个waypoint,肉眼可见地又额外增加了一跳,因此完整的L7处理需要额外经过三跳。虽然社区声称这对性能的影响很小,但是仍需待其特性稳定后进一步观察对比;2. 容器网络适配:虽然Ambient Mesh与应用基本实现了完全解耦,但是反过来也增加了网格与底层基础设施的耦合,Sidecar模式仅需在Pod的net ns实现流量的拦截处理,但是Ambient Mesh在主机网络进行流量拦截,显然需要更多考虑与底层容器网络的适配;3. 配置复杂:原本Envoy复杂的配置就被广为诟病而Ambient Mesh更需要实现一个ztunnel对节点所有Pods的代理,配置复杂度更是上升一个数量级,同时配置的复杂意味着处理流程的增加,也会对数据面的排错以及整体性能造成影响;4. 其他:ztunnel的高可用?waypoint事实上将原本双端的L7处理变为了单端,对L7监控指标正确性的影响?…▎未来展望从版本发布的角度,自从2022年9月份发布以来,Ambient Mesh一直作为实验特性存在于独立的分支之中。因此对于Ambient Mesh下一步的计划就是合入主干分支(已于2023年2月实现)并作为Alpha特性发布,最终在2023年底到达Stable,实现生产可用。从API的角度,最理想的是能在两种架构下共用同一套API。当然这是不现实的,因为已有的一部分Istio API是以Sidecar模式部署为前提条件设计的。最典型的就是Sidecar这个CRD,它用于定制化下发至不同Sidecar的配置,从而减少Sidecar不必要的资源占用。这些Sidecar-Only的API显然在Ambient Mesh下毫无意义。同时,Ambient Mesh自身也引入了ztunnel和waypoint两个独有组件,因此Ambient Mesh也需要创建新的API,用于管理这些独有组件以及实现一些Ambient Mesh Only的功能。最终Ambient Mesh会实现已有的核心Istio API(VirtualService, DestinationRules等)并创建一些其独有的API,重要的是做到三类API(Sidecar模式独有、Ambient Mesh独有、两者共有)统一的使用与交互。那么Ambient Mesh是否做到了对Sidecar模式使用场景的全覆盖,从而让Sidecar模式彻底退出历史舞台了呢?答案自然是否定的,类似于业界各种独占模式和共享模式之争,Sidecar模式本质上是应用Pod对Proxy的独占。专属的Proxy往往能保证更好的资源可用性,尽量避免其他应用的影响,确保高优先级应用的正常运行。可以预见,最终两种模式的混合部署,应用按需选择代理模式是更为理想的方式。所以构建混合部署模式,保证该模式下两种模式的良好兼容性和统一的体验也将是后续工作的重点。▎总结Sidecar模式对于Istio就像一场原型验证,以一种最Kubernetes Native的方式快速展示网格技术的价值,抢占用户认知和市场。不过随着Istio的落地逐渐进入深水区,开始在生产环境大规模部署,Sidecar模式就显得力不从心了。此时Ambient Mesh以一种更符合大规模落地要求的形态出现,克服了大多数Sidecar模式的固有缺陷,让用户无需再感知网格相关组件,真正将网格下沉为基础设施。但是显然Ambient Mesh并不是网格数据面架构演进的终点。当前还没有一种网格数据面方案能在侵入性、性能、资源占用等各个考量维度做到完美。Ambient Mesh基本做到了对应用的零侵入,但是L7的三跳处理引发的性能问题,ztunnel等常驻进程的资源占用令人无法忽视;gRPC等RPC库通过内置实现xDS,直连Istio控制面,将网格杂糅进SDK,确实能实现很好的性能和资源占用表现,只是不可避免地需要付出与应用强耦合、多语言支持复杂度高等固有代价;基于eBPF直接将全套网格数据面功能像TCP/IP协议栈一样下沉到内核貌似是理想的终局方案,只是考虑到内核安全以及与内核交互的复杂性,eBPF的执行环境其实是非常受限的,例如eBPF程序加载到内核前必须经过verifier的校验,执行路径必须完全已知,无法执行任意的循环。因此对于HTTP/2,gRPC等复杂的L7处理,基于eBPF的开发和维护都会比较困难。考虑到基础设施对性能、资源损耗的极致要求以及过往相关技术的演进规律,例如对于基础网络,绝大多数应用共享使用内核协议栈即可,部分特殊应用利用DPDK,RDMA等专用技术进行加速。同样,对于网格数据面,多种技术结合,分别优化相应场景的解决方案,可能是更具可行性的。可以预见,这类方案基本上是以类Ambient Mesh的节点级代理作为主体,随着网格以及eBPF技术的发展,将尽量多的网格数据面功能下沉至eBPF(Fast Path)实现;少部分高级功能交由用户态的Proxy(Slow Path)实现;那些对性能、隔离性等有较高要求的应用,则为其部署专属的Sidecar。这样一来,就能满足绝大多数场景下,对侵入性、性能、资源占用等各个维度的要求。综上 ,最终是一套数据面方案一统天下,还是各种方案混合部署,取各家所长,仍有待对相关技术不断探索演进,再用实践检验,最后让时间告诉我们答案。参考文献[1] Istio Ambient Mesh Explained: https://lp.solo.io/istio-ambient-mesh-explained[2] What to expect for ambient mesh in 2023: https://www.solo.io/blog/ambient-mesh-2023[3] Introducing Ambient Mesh: https://istio.io/latest/blog/2022/introducing-ambient-mesh[4] Get Started with Istio Ambient Mesh: https://istio.io/latest/blog/2022/get-started-ambient
-
由 Istio 社区指导委员会成员和华为云云原生团队联合编著的云原生服务网格书籍《 Istio 权威指南》重磅上市!《 Istio 权威指南》包含云原生服务网格原理、实践、架构、源码四大技术篇章,内容权威、系统、详实, 凝聚华为云云原生团队在 Istio 社区及产品领域耕耘多年的长期实践和宝贵经验。华为云 CTO、CNCF CTO 联合作序,Istio 社区技术委员会( TOC )资深成员强力推荐。Istio服务网格是 CNCF( Cloud-Native Computing Foundation,云原生计算基金会)定义的云原生技术的典型代表之一,向下与提供资源、运行环境结合,构建了一个懂应用、对应用更友好的基础设施,帮助下层基础设施感知上层应用,更有效地发挥资源的效能;向上以非侵入的方式提供面向应用的韧性、安全、动态路由、调用链、拓扑等应用管理和运维能力。作为服务网格技术中最具影响力的项目,Istio 从诞生之初就获得了技术圈和产业界的极大关注。CNCF 这几年的调查报告显示,Istio 一直是生产环境下最受欢迎和使用最多的服务网格。2022 年 9 月,CNCF正式接受 Istio 成为孵化项目,推动 Istio 与 Envoy 项目的紧密协作,一起构建云原生应用流量管理的技术栈,也将进一步促进 Istio 成为应用流量治理领域的事实标准。根据 Istio 官方的统计,Istio 项目已有 8800 名个人贡献者,超过 260 个版本,并有来自 15 家公司的 85 名维护者,可见Istio在技术圈和产业圈都获得了极大的关注和认可。两次年度 IstioCon活动每次都吸引了超过 4000 人参加。华为云云原生团队成员入选了每届Istio社区指导委员会,当前有 2 名指导委员会成员(全球仅 8 家公司 13 人),参与Istio社区的重大技术决策,持续引领了Istio项目和服务网格技术的发展。另外Maintainer 2 名,Member 10+ 名,Pull Request 位于全球TOP 3,中国第一,Contributions TOP 3(2.3w+)。《 Istio 权威指南》简介《 Istio 权威指南》由华为云云原生团队出品,旨在打造业界最系统权威的 Istio 图书。书籍分为上、下两册,上册包括原理篇、实践篇;下册包括架构篇和源码篇,总计 26 章。▍原理篇 1~7 章介绍 Istio 的相关概念、原理,并详解 Istio 丰富的流量治理、可观测性、安全等方面的原理、机制和用法细节。▍实践篇 8~14 章基于一个统一用例实践 Istio 的流量治理、灰度、韧性、安全、可观测性、多基础设施、网关等典型应用。▍架构篇 15~20 章从架构的视角详解 Istio 各控制面组件和数据面组件的设计思想、数据模型和核心工作流程。▍源码篇 21~26 章从代码的视角详解 Istio 各控制组件面和数据面组件的代码结构、代码流程和关键代码片段。书籍特色1. 权威详实内容获 Istio 社区和 Istio TOC Lin Sun 和 John Howard 代表 Istio 社区强力推荐《 Istio 权威指南》基于 Istio 最新版本和架构,通过 4 篇、26 章、近 1000 页的篇幅,全面、系统、详细、深入地解析 Istio 原理、用法、实践、架构和源码。能帮助读者从多个维度理解云原生、服务网格、Istio 等相关技术,掌握基于 Istio 实现应用流量管理、零信任安全、应用可观测性等能力的相关原理与实践。Istio 社区最资深权威的两位 TOC 委员 Lin Sun 和 John Howard 代表Istio 社区推荐书籍的权威、系统的内容,建议初学者、云原生技术专家或 Istio 社区的贡献者均可阅读、参考。2.450+ 详实原创图表解析关键原理、架构、模型和代码流程,归纳易错技术点全书运用 450+ 原创图表多维度洞察、归纳、总结Istio原理、架构、流程和易错技术要点。践行了作者著书的理念不是搬运知识,而是将自己的实际的经验总结和提炼出来,由浅入深地帮助广大从业者学习服务网格的机制,掌握Istio的用法,特别是帮助从业者理解其中容易出错,最难理解的技术细节。如图书第4章可观测性中详细介绍了Istio访问日志的内容,特别剖析了 6 个重要的可以帮助运维人员识别一个请求通过服务网格数据面的每个阶段的耗时细节、定位耗时的瓶颈时间段。考虑到大多数从业者很容易混淆这几个个时间段的细微的差别,特提供了图4-26展示了代理观测记录每个时间段的起始时间点和终止时间点。并通过表4-4对每个时间字段进行了解析。这种通过原创的细致入微的图、表和文字结合的立体表达详解易错核心技术点的方式,获得了Istio TOC成员, Director of Open Source at Solo.io Lin Sun的赞誉和强烈推荐。▲ 图4-26 访问日志中的重要时间字段解析▼ 表4-4 访问日志中的重要时间字段解析3.国内首本系统详细解析 Istio 和 Envoy 架构和源码的技术书籍,Istio 和Envoy 社区核心维护者周礼赞强力推荐此外当前服务网格的使用越来越普及,国内甚至业界介绍服务网格控制面的资料书籍已经慢慢丰富起来,但是详细介绍架构和源码实现的书籍,特别是网格数据面的资料一直较少。很多从业朋友反映业务进入深水区后网格数据面知识的欠缺阻碍了其日常的工作的开展和生产中问题定位定界。《 Istio 权威指南》下册着重介绍 Istio 的架构与源码,特别规划了4章系统详细地解析 Istio-proxy 和 Envoy 架构和源码。书籍的详实内容获得 Istio 和 Envoy 社区核心维护者周礼赞强力推荐。4. 大量原创实践内容覆盖典型应用和常见疑难问题,指导客户解决生产问题《 Istio 权威指南》内容源于华为云云原生团队在 Istio 社区及产品领域耕耘多年的长期工程实践、客户实际案例的宝贵经验积累。在全面系统、深入介绍 Istio 原理、架构的同时,更注重内容对读者具体工作的实用价值。本书规划了独立的实践篇涵盖 Istio 的典型的流量、安全和可观测性实践案例。另外,近些年用户深入使用 Istio 的过程中,访问日志的应答标记的含义对大部分资深使用者造成困扰,但是国内外的资料包括社区官方都很简单,只是一般性的简单描述。上册附录规划了原创的访问日志实践,涵盖了大部分 Istio 访问日志中典型应答标记的实际案例,帮助读者理解其用法。此外下册附录规划了多个华为云云原生团队生产中积累的有借鉴意义的疑难案例,帮助读者参照解决实际工作中碰到的类似问题。5. 华为云 CTO、CNCF CTO、信通院、IEEE/CCF Fellow 等顶级领域专家推荐《 Istio 权威指南》目标成为 Istio 技术的权威、系统的技术书籍,持续帮助读者朋友学习了解 Istio ,解答大家使用 Istio 中的具体问题,推动云原生技术的发展。该目标和成果得到了华为云 CTO 张宇昕、CNCF CTO Chris Aniszczyk 的大力支持,二位 CTO 为《 Istio 权威指南》联合作序,倾力推荐。中国信通院云计算与大数据研究所何宝宏所长、上海交通大学致远讲席教授IEEE/CCF Fellow 过敏意老师、CNCF 中国区总监 Keith Chan、华为云首席产品官方国伟分别结合研究所、学术界、CNCF和产业界的背景和技术趋势表达了对Istio和其所属的服务网格技术的观点,也给出了读者使用本书的建议 。6. Istio 社区和华为云产品专家联合出品《 Istio 权威指南》由 Istio 社区亚洲唯一的从首届至今的指导委员会成员、国内最早的 Istio 商用网格服务开发团队成员联合出品,内容涵盖 Istio 的原理、实践、架构与源码。内容来源于作者在 Istio 社区设计开发大颗粒功能的经验总结,结合华为云云原生团队在云服务开发、客户解决方案构建、生产环境运维等日常工作中的实践、思考和总结,打造国内最权威、系统、详实、实用的Istio书籍。图书是《云原生服务网格 Istio 原理、实践、架构与源码解析》核心作者张超盟、徐中虎又一力作 。作者简介张超盟华为云应用服务网格架构师,先后负责过华为云容器应用运维、微服务平台、云服务目录、云服务可靠性、服务网格等云原生产品的架构设计与开发工作,主导过多个重大项目的云原生和微服务化生产落地。在服务网格、Kubernetes容器服务、微服务架构、应用性能管理、大数据、DevOps工具等方面有深入的研究与实践。Istio社区成员,KubeCon、IstioCon及ServiceMeshCon等会议的演讲者,技术图书作者。早期曾在中铁一局从事路桥建设工作。徐中虎华为云云原生团队核心成员,开源技术专家,服务网格Istio核心维护者,Istio社区指导委员会成员,Kubernetes项目核心贡献者,批量计算项目Volcano的核心维护者,拥有丰富的开源工作经验。主要研究方向有微服务架构、服务网格、容器编排平台Kubernetes和未来的分布式云原生架构等。在分布式系统的性能优化、高可靠和可扩展方面研究深入、经验丰富。张伟华为云服务网格数据面资深专家,拥有18年架构设计与开发经验,先后就职于亿阳信通、加拿大北电网络(中国)、甲骨文、Polycom、阿里巴巴及华为等公司。作为核心开发人员开发过传输网管系统、Tuxedo交易中间件、ts-server多媒体转码服务、GTS高性能事务云服务、sc高性能注册中心、ASM数据面等多个产品,现主要负责华为云ASM服务网格数据面代理产品的设计与开发工作。冷雪西安电子科技大学杭州研究院菁英副教授,浙江大学工学博士。主要研究方向有云原生安全、性能优化和智能运维等,致力于解决云网环境下的关键问题。曾参与并主持多项科研项目,在国际顶级会议和期刊上发表多篇论文并获得多项授权专利。我们衷心地希望书中的内容能对您和您日常工作带来帮助,也很期待有机会就其中的内容和您进行技术交流。假如你需要更深入地学习服务网格及云原生相关技术,欢迎关注我们的容器魔方公众号(参见本书封面),一起学习并讨论服务网格及云原生领域最新的技术进展。行业权威著作,云原生服务网格从业白皮书华为云、CNCF CTO联合作序——华为云CTO 张宇昕《 Istio 权威指南》来源于华为云云原生团队在云服务开发、客户解决方案构建、Istio社区特性开发、生产环境运维等日常工作中的实践、思考和总结,旨在帮助技术圈的更多朋友由浅入深且系统地理解 Istio 的原理、实践、架构与源码。书中内容在描述 Istio 的功能和机制的同时,运用了大量的图表总结,并深入解析其中的概念和技术点,可以帮助读者从多个维度理解云原生、服务网格等相关技术,掌握基于 Istio 实现应用流量管理、零信任安全、应用可观测性等能力的相关实践。无论是初学者,还是对服务网格有一定了解的用户,都可以通过本书获取自己需要的信息。——CNCF CTO Chris Aniszczyk本书提供了全面且实用的 Istio 指南,涵盖了 Istio 的核心概念、特性和对 xDS 协议等主题的深入探讨,还包括对 Envoy 和 Istio 项目源码的深入解析,这对潜在贡献者非常有用。无论您是软件工程师、SRE 还是云原生开发人员,本书都将为您提供利用 Envoy 和 Istio 构建可扩展和安全的云原生应用所需的知识和技能。行业大咖倾力推荐——中国信通院云计算与大数据研究所所长 何宝宏服务网格作为一种管理服务间通信的核心技术,为服务间的调用带来了便捷且可靠的流量、安全和可观测性等能力。中国信通院作为ICT领域的国家智库,率先牵头制定了服务网格相关标准。华为作为云原生领域的中坚力量,在该标准的编写过程中发挥了重要作用。《Istio权威指南》作为关于服务网格的专业技术书籍,对国内云原生技术的普及和发展将起到极大的促进作用。——上海交通大学致远讲席教授、国家杰青、IEEE/CCF Fellow 过敏意云原生技术已经成为产业界和学术界共同关注的热点之一。Istio作为一种集成了流量、安全和可观测性等能力的透明服务治理平台,有效推动了服务网格在云生产环境下的应用和普及。《Istio权威指南》作为服务网格领域的权威书籍,凝聚了华为云云原生团队长期积累的丰富经验,深入浅出地对Istio相关技术进行了详尽解读,值得相关从业者、技术爱好者和学术研究者阅读、参考。——CNCF中国区总监、Linux Foundation亚太区战略总监Keith ChanIstio一直是云原生领域非常流行的开源项目,是CNCF组织的各类会议上的热门话题。华为一直是云原生开源活动的积极参与者,在Kubernetes和Istio等项目中都有着突出的贡献。《Istio权威指南》由华为云云原生团队倾力打造而成,其理论结合实践,深度剖析了Istio的原理、实践、架构与源码,对于企业面向云原生架构转型及践行服务网格落地都有很大的参考意义。——华为云首席产品官 方国伟云原生极大地提高了企业应用生产力,缩短了应用的上市时间,降低了应用上云的门槛。服务网格作为云原生技术栈中的关键技术之一,可以帮助用户打造“以应用为中心”的云原生基础设施。《Istio权威指南》作为系统介绍服务网格技术Istio的权威书籍,来源于在Istio社区及产品领域耕耘多年的华为云云原生团队的长期工程实践和宝贵经验积累,值得广大云原生技术爱好者阅读、参考。——Istio TOC Member、Director of Open Source at Solo.io Lin SunIstio是当今生产环境下非常流行、部署非常广泛的服务网格技术。如果您已经了解Istio并想从基本概念、API、架构、各组件的源码等方面深入研究Istio,那么《Istio权威指南》适合您阅读。本书是非常实用且有深度的Istio书籍,其涵盖的Istio组件工作流和图表的深度给我留下了特别深刻的印象。希望您喜欢本书,我代表Istio社区祝您学习Istio愉快!——Istio TOC Member、Istio SC Member、Google Staff Engineer John Howard加入CNCF,标志着Istio向服务网格的事实标准迈出了关键的一步。《Istio权威指南》由来自Istio指导委员会、Istio社区等的Istio资深开发人员编写而成,是非常全面、深入地讲解Istio技术的权威书籍,内容涵盖Istio的原理、实践、架构与源码。无论您是初学者、云原生技术专家,还是Istio社区的贡献者,都可以从中获益。——Envoy与Istio核心维护者、Tetrate.io前创始工程师 周礼赞《Istio权威指南(上)》讲解了Istio的原理、各种使用场景和优秀实践,《Istio权威指南(下)》讲解了Istio控制面和数据面Envoy的内部架构及源码实现。这两本书深入剖析了Istio的内部架构,可以帮助您更充分地理解Istio的工作原理和实现,从而更好地应用Istio并进行Istio调优。凝聚深厚实践 行业问鼎力作华为云应用服务网格华为云在2018年率先发布全球首个Istio商用服务:应用服务网格 ASM (Application Service Mesh,)。ASM 是一个拥有高性能、高可靠性和易用性的全托管服务网格。作为分布式云场景中面向应用的网络基础,ASM 对多云、混合云环境下的容器、虚拟机、Serverless、传统微服务、Proxyless 服务提供了应用健康、韧性、弹性、安全性等的全方位管理。华为云应用服务网格(ASM)也已服务于互联网、汽车、制造、物流、政府等多个行业的近千家客户,满足不同行业客户的业务诉求。华为云将在此过程中积累的丰富经验,转化为代码贡献给Istio社区,极大地推动了 Istio 技术的成熟和社区的快速发展。华为云 Istio 社区贡献作为最早一批投身云原生技术的厂商,华为云是 CNCF 在亚洲唯一的初创成员。华为云云原生团队从 2018 年开始积极参与 Istio 社区的活动,参与 Istio 社区的版本特性设计与开发,基于用户的共性需求开发了大量大颗粒特性。团队成员入选了每届 Istio 社区指导委员会,当前有2名指导委员会成员(全球仅 8 家公司 13 人),参与 Istio 社区的重大技术决策,持续引领了 Istio 项目和服务网格技术的发展。另外 Maintainer 2 名,Member 10+名,Pull Request 位于全球TOP 3,中国第一,Contributions TOP 3(2.3w+)。华为云云原生团队华为云云原生团队创建于2013年,是国内较早从事云原生研究的团队之一,也是CNCF的初创成员和白金会员。华为云在容器、服务网格、微服务等云原生技术领域都有着深厚的沉淀,拥有10多名CNCF项目维护者,对 Kubernetes、Istio 等核心项目的贡献一直位居全球前列,并向CNCF捐献了 KubeEdge、Volcano、Karmada 等知名项目。基于 CNCF 的开源生态,华为云还打造了云容器引擎、云容器实例、应用服务网格等一系列优质的商业化云原生服务。为进一步推广云原生技术,加速云原生在行业中落地,华为云联合CNCF、中国信通院及业界云原生技术精英们成立了全球云原生交流平台——创原会。创原会创原会是 CNCF、中国信通院、华为云及业界云原生技术精英们联合成立的全球云原生交流平台,旨在通过研究前沿云原生技术及共享产业落地实践,探索云原生与业务融合的无限可能。自 2020 年成立至今,创原会已在中国、东南亚、拉美、欧洲陆续成立分会并举办活动 50 余场,为全球技术精英们提供了一个优质、高端、开放的交流平台,并吸纳近 300 位 CTO、技术总监成为会员,极大地促进了云原生在全球各行业中的普及和落地。对本书感兴趣,可链接直达− 《Istio权威指南(上):云原生服务网格Istio原理与实践》(张超盟,徐中虎,张伟,冷雪) https://item.jd.com/13938046.html− 《Istio权威指南(上):云原生服务网格Istio架构与源码》(张超盟,徐中虎,张伟,冷雪)https://item.jd.com/13938046.html添加小助手k8s2222进入华为云云原生团队Istio技术交流群
-
3. K8S 集群安装 istio下载安装包,配置环境变量[root@master ~]#wget http://49.232.8.65/istio/istio-1.14.1-linux-amd64.tar.gz ...... [root@master ~]#mkdir /application [root@master ~]#tar zxvf istio-1.14.1-linux-amd64.tar.gz -C /application/ ...... [root@master ~]#ll /application/istio-1.14.1/ 总用量 28 drwxr-x--- 2 root root 22 6月 8 10:10 bin -rw-r--r-- 1 root root 11348 6月 8 10:10 LICENSE drwxr-xr-x 5 root root 52 6月 8 10:10 manifests -rw-r----- 1 root root 796 6月 8 10:10 manifest.yaml -rw-r--r-- 1 root root 6016 6月 8 10:10 README.md drwxr-xr-x 23 root root 4096 6月 8 10:10 samples drwxr-xr-x 3 root root 57 6月 8 10:10 tools [root@master ~]#ll /application/istio-1.14.1/bin/ 总用量 83676 -rwxr-xr-x 1 root root 85684224 6月 8 10:10 istioctl [root@master ~]#echo "export PATH=$PATH:/application/istio-1.14.1/bin" >> /etc/profile [root@master ~]#tail -n 1 /etc/profile export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/application/istio-1.14.1/bin [root@master ~]#source /etc/profile 安装 istio# 使用 demo 配置文件安装,它具有一组良好的测试默认值,但还有其他配置文件用于生产或性能测试 # 集群内存要足够 [root@master ~]# istioctl install --set profile=demo -y ✔ Istio core installed ✔ Istiod installed ✔ Ingress gateways installed ✔ Egress gateways installed ✔ Installation complete Making this installation the default for injection and validation. Thank you for installing Istio 1.14. Please take a few minutes to tell us about your install/upgrade experience! https://forms.gle/yEtCbt45FZ3VoDT5A [root@master ~]# kubectl get pods -n istio-system -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES istio-egressgateway-575d8bd99b-sqdm9 1/1 Running 0 9m22s 10.244.140.70 node02 <none> <none> istio-ingressgateway-6668f9548d-dh656 1/1 Running 0 9m22s 10.244.140.69 node02 <none> <none> istiod-8495d444bb-zxfls 1/1 Running 0 10m 10.244.140.68 node02 <none> <none> # 添加名称空间的标签,当部署应用后,告诉 istio 去自动的注入 Envoy sidecar 代理,这里是 default # istio-injection=disabled 的命名空间是不会流入 sidecar 的 [root@master ~]# kubectl get ns NAME STATUS AGE default Active 159m istio-system Active 3m31s kube-node-lease Active 159m kube-public Active 159m kube-system Active 159m [root@master ~]# kubectl label namespace default istio-injection=enabled namespace/default labeled # 如何取消注入 [root@master ~]# kubectl label namespaces default istio-injection- namespace/default labeled [root@master ~]# kubectl describe ns default Name: default Labels: istio-injection=enabled kubernetes.io/metadata.name=default Annotations: <none> Status: Active No resource quota. No LimitRange resource.卸载 istiohttps://istio.io/latest/docs/setup/install/istioctl/#uninstall-istio4. 部署示例应用程序部署 Bookinfo 示例应用程序[root@master /application/istio-1.14.1]# ls bin LICENSE manifests manifest.yaml README.md samples tools [root@master /application/istio-1.14.1]# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml service/details created serviceaccount/bookinfo-details created deployment.apps/details-v1 created service/ratings created serviceaccount/bookinfo-ratings created deployment.apps/ratings-v1 created service/reviews created serviceaccount/bookinfo-reviews created deployment.apps/reviews-v1 created deployment.apps/reviews-v2 created deployment.apps/reviews-v3 created service/productpage created serviceaccount/bookinfo-productpage created deployment.apps/productpage-v1 created查看# 应用程序将启动。随着每个 pod 准备就绪,Istio sidecar 将随之部署 # 我的 pod 启动时间非常长,等到所有 pod 都报告 READY2/2 和 STATUSRunning 后再进行下一步,耐心等待 [root@master /application/istio-1.14.1]# kubectl get pods NAME READY STATUS RESTARTS AGE details-v1-7d88846999-hrcgp 2/2 Running 0 16m productpage-v1-7795568889-92mdm 2/2 Running 0 16m ratings-v1-754f9c4975-ckf5z 2/2 Running 0 16m reviews-v1-55b668fc65-lsfjs 2/2 Running 0 16m reviews-v2-858f99c99-7nw82 2/2 Running 0 16m reviews-v3-7886dd86b9-cnjdh 2/2 Running 0 16m [root@master /application/istio-1.14.1]# kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE details ClusterIP 10.100.172.185 <none> 9080/TCP 16m kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h7m productpage ClusterIP 10.97.47.169 <none> 9080/TCP 16m ratings ClusterIP 10.102.140.67 <none> 9080/TCP 16m reviews ClusterIP 10.108.151.245 <none> 9080/TCP 16m验证到目前为止一切正常。运行以下命令,通过检查响应中的页面标题来查看应用程序是否在集群内运行并提供 HTML 页面:[root@master ~]# kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>" <title>Simple Bookstore App</title>5. 向外部流量打开应用程序Bookinfo 应用程序已部署,但无法从外部访问。为了使其可访问,您需要创建一个 Istio Ingress Gateway,它将路径映射到网格边缘的路由。将此应用程序与 Istio 网关关联[root@master ~]# kubectl apply -f /application/istio-1.14.1/samples/bookinfo/networking/bookinfo-gateway.yaml gateway.networking.istio.io/bookinfo-gateway created virtualservice.networking.istio.io/bookinfo created确保配置没有问题[root@master ~]# istioctl analyze ✔ No validation issues found when analyzing namespace: default.5.1 确定入口 IP 和端口设置访问网关的 INGRESS_HOST 和 INGRESS_PORT 变量执行以下命令来确定您的 Kubernetes 集群是否在支持外部负载均衡器的环境中运行:[root@master ~]# kubectl get svc istio-ingressgateway -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingressgateway LoadBalancer 10.98.234.126 <pending> 15021:30921/TCP,80:32314/TCP,443:31968/TCP,31400:32530/TCP,15443:31268/TCP 3h6m如果 EXTERNAL-IP 设置了 IP,则您的环境具有可用于入口网关的外部负载均衡器。如果 EXTERNAL-IP 值为 <none>(或永久 <pending>),则您的环境不为入口网关提供外部负载均衡器。在这种情况下,您可以使用服务的节点端口 访问网关。没有 EIP 解决:链接1. 安装 metallb 2. 安装 ingress-controller 3. 再次查看 istio-ingressgateway # 已经获取 EIP [root@master ~]# kubectl get svc istio-ingressgateway -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingressgateway LoadBalancer 10.98.234.126 192.168.10.170 15021:30921/TCP,80:32314/TCP,443:31968/TCP,31400:32530/TCP,15443:31268/TCP 3h19m如果您确定您的环境具有外部负载平衡器,进行下面的操作。设置入口 IP 和端口:# 可将环境变量写进 /etc/profile 中 [root@master ~]# export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') [root@master ~]# export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}') [root@master ~]# export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}') 在某些环境中,负载均衡器可能会使用主机名而不是 IP 地址。在这种情况下,入口网关的 EXTERNAL-IP 值将不是 IP 地址,而是主机名,上述命令将无法设置 INGRESS_HOST 环境变量。使用以下命令更正该 INGRESS_HOST 值:export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')确保 IP 地址和端口已成功分配给每个环境变量[root@master ~]# echo "$INGRESS_HOST" 192.168.10.170 [root@master ~]# echo "$INGRESS_PORT" 80 [root@master ~]# echo "$SECURE_INGRESS_PORT" 443设置 GATEWAY_URL# 可将环境变量写进 /etc/profile 中 [root@master ~]# export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT [root@master ~]# echo "$GATEWAY_URL" 192.168.10.170:805.2 验证外部访问通过使用浏览器查看 Bookinfo 产品页面,确认可以从外部访问 Bookinfo 应用程序。运行以下命令以检索 Bookinfo 应用程序的外部地址[root@master ~]# echo "http://$GATEWAY_URL/productpage" http://192.168.10.170:80/productpage将上一个命令的输出粘贴到您的 Web 浏览器中,并确认显示 Bookinfo 产品页面。6. 安装仪表盘Istio 集成了几个不同的监控应用程序。这些可以帮助您了解服务网格的结构、显示网格的拓扑并分析网格的健康状况。使用以下说明部署 Kiali 仪表板以及 Prometheus、Grafana 和 Jaeger。安装 kali 和其他插件[root@master ~]# kubectl apply -f /application/istio-1.14.1/samples/addons serviceaccount/grafana created configmap/grafana created service/grafana created deployment.apps/grafana created configmap/istio-grafana-dashboards created configmap/istio-services-grafana-dashboards created deployment.apps/jaeger created service/tracing created service/zipkin created service/jaeger-collector created serviceaccount/kiali created configmap/kiali created clusterrole.rbac.authorization.k8s.io/kiali-viewer created clusterrole.rbac.authorization.k8s.io/kiali created clusterrolebinding.rbac.authorization.k8s.io/kiali created role.rbac.authorization.k8s.io/kiali-controlplane created rolebinding.rbac.authorization.k8s.io/kiali-controlplane created service/kiali created deployment.apps/kiali created serviceaccount/prometheus created configmap/prometheus created clusterrole.rbac.authorization.k8s.io/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created service/prometheus created deployment.apps/prometheus created # 下面命令失败重复运行 [root@master ~]# kubectl rollout status deployment/kiali -n istio-system Waiting for deployment "kiali" rollout to finish: 0 of 1 updated replicas are available... deployment "kiali" successfully rolled out [root@master ~]# kubectl get pods,svc -n istio-system NAME READY STATUS RESTARTS AGE pod/grafana-6c5dc6df7c-zzb5q 1/1 Running 0 44s pod/istio-egressgateway-575d8bd99b-sqdm9 1/1 Running 0 8h pod/istio-ingressgateway-6668f9548d-dh656 1/1 Running 0 8h pod/istiod-8495d444bb-zxfls 1/1 Running 0 8h pod/jaeger-9dd685668-mwmqm 1/1 Running 0 44s pod/kiali-5db6985fb5-chctb 1/1 Running 0 43s pod/prometheus-699b7cc575-4lxbs 2/2 Running 0 43s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/grafana ClusterIP 10.101.225.230 <none> 3000/TCP 44s service/istio-egressgateway ClusterIP 10.107.140.240 <none> 80/TCP,443/TCP 8h service/istio-ingressgateway LoadBalancer 10.98.234.126 192.168.10.170 15021:30921/TCP,80:32314/TCP,443:31968/TCP,31400:32530/TCP,15443:31268/TCP 8h service/istiod ClusterIP 10.97.201.157 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 8h service/jaeger-collector ClusterIP 10.101.114.182 <none> 14268/TCP,14250/TCP,9411/TCP 44s service/kiali ClusterIP 10.107.178.217 <none> 20001/TCP,9090/TCP 43s service/prometheus ClusterIP 10.105.102.86 <none> 9090/TCP 43s service/tracing ClusterIP 10.98.109.173 <none> 80/TCP,16685/TCP 44s service/zipkin ClusterIP 10.111.133.26 <none> 9411/TCP 44s修改 kiali 的服务,将类型改为 LoadBalancer[root@master ~]# kubectl edit svc kiali -n istio-system ...... 46 type: ClusterIP ...... # 修改此处为 type: LoadBalancer # 在没有安装 metallb 产品的情况下,可以将该服务类型改为 NodePort [root@master ~]# kubectl edit svc kiali -n istio-system service/kiali edited访问 Kiali 仪表板配置 Service 为 LoadBalancer 类型检查一下 kiali service 的类型是不是 LoadBalancer 类型,有没有获取 EIP[root@master ~]# istioctl dashboard kiali http://localhost:20001/kiali [root@master ~]# kubectl get pods,svc -n istio-system NAME READY STATUS RESTARTS AGE pod/grafana-6c5dc6df7c-wt9wq 1/1 Running 0 4m7s pod/istio-egressgateway-575d8bd99b-wq5fv 1/1 Running 0 20m pod/istio-ingressgateway-6668f9548d-2nt77 1/1 Running 0 20m pod/istiod-8495d444bb-xm6lw 1/1 Running 0 21m pod/jaeger-9dd685668-9hp2t 1/1 Running 0 4m7s pod/kiali-5db6985fb5-pnkvw 1/1 Running 0 4m7s pod/prometheus-699b7cc575-nc86z 2/2 Running 0 4m7s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/grafana ClusterIP 10.99.147.179 <none> 3000/TCP 4m7s service/istio-egressgateway ClusterIP 10.101.226.2 <none> 80/TCP,443/TCP 20m service/istio-ingressgateway LoadBalancer 10.106.154.219 192.168.10.170 15021:30361/TCP,80:30766/TCP,443:32089/TCP,31400:32656/TCP,15443:31882/TCP 20m service/istiod ClusterIP 10.108.100.170 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 21m service/jaeger-collector ClusterIP 10.100.230.173 <none> 14268/TCP,14250/TCP,9411/TCP 4m7s service/kiali LoadBalancer 10.99.87.90 192.168.10.171 20001:31148/TCP,9090:32497/TCP 4m7s service/prometheus ClusterIP 10.106.49.15 <none> 9090/TCP 4m7s service/tracing ClusterIP 10.101.14.242 <none> 80/TCP,16685/TCP 4m7s service/zipkin ClusterIP 10.108.155.153 <none> 9411/TCP 4m7s访问:http://192.168.10.171:20001/kiali
-
1 Istio介绍Istio-proxy是可在客户端和服务器端使用的微服务代理,并形成微服务网格。Proxy引用了微服务代理Envoy的源码,并在此基础上做了扩展,结合istio本身做处理。它支持很多功能。客户端功能:1)发现和负载平衡。代理可以使用几种标准服务发现和负载平衡API来有效地将流量分配给服务。2)凭证注入。代理可以通过连接隧道或特定于协议的机制(例如HTTP请求的JWT令牌)注入客户端身份。3)连接管理。代理管理与服务的连接,处理运行状况检查,重试,故障转移和流控制。4)监视和记录。代理可以报告客户端指标并记录到混合器。服务器端功能:1)速率限制和流量控制。代理可以防止后端系统过载,并提供客户端感知的速率限制。2)协议翻译。代理是gRPC网关,提供JSON-REST和gRPC之间的转换。3)认证和授权。代理支持多种身份验证机制,并且可以使用客户端身份通过混合器执行授权检查。4)监视和记录。代理可以报告服务器端指标并记录到混合器。2 软硬件环境要求类别子项版本硬件CPU鲲鹏920OSCentOS7.6软件GCC7.3.0Go1.13.4Clang9.0.1OpenJDK1.8.0_282Bazel3.3.1Istio-proxy/Istio1.5.0网络需连外网需连外网 3 配置编译环境3.1 安装gcc 7.3通常centos自带的版本是gcc4.8.5,在此基础上进行升级即可。执行以下命令:wget https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-7.3.0/gcc-7.3.0.tar.gztar -xvf gcc-7.3.0.tar.gzcd gcc-7.3.0./contrib/download_prerequisitesmkdir gcc-build-7.3.0cd gcc-build-7.3.0../configure --enable-checking=release --enable-language=c,c++ --disable-multilib --prefix=/usrmake -j16make install 确保依赖库存在:cd /usr/lib64ll |grep libstdc++.soll |grep libstdc++.so.6.0.24gcc --version 3.2 源码编译安装llvm+clang安装依赖软件:yum install cmake gcc g++ libffi libffi-dev -y其中cmake需要安装3.8以上版本,如果yum源中没有,执行以下命令安装:wget https://cmake.org/files/v3.9/cmake-3.9.2.tar.gztar zxvf cmake-3.9.2.tar.gzcd cmake-3.9.2./bootstrapmake -j32make install如果yum源中没有libffi,可以使用源码安装,执行以下命令即可:wget https://github.com/libffi/libffi/releases/download/v3.3/libffi-3.3.tar.gztar xf libffi-3.3.tar.gz cd libffi-3.3./configure --prefix=/usr/local/libffimake -j12make install 安装llvm+clang,下载源码:cd /optwget https://github.com/llvm/llvm-project/archive/llvmorg-9.0.1.tar.gztar -xf llvmorg-9.0.1.tar.gz执行编译安装命令:cd llvm-project-llvmorg-9.0.1rm -rf buildmkdir build && cd buildcmake -G "Unix Makefiles" ../llvm \ -DCMAKE_INSTALL_PREFIX=/opt/llvm \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_ENABLE_FFI=ON \ -DLLVM_BUILD_LLVM_DYLIB=ON \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DLLVM_TARGETS_TO_BUILD="host;AArch64" \ -DLLVM_ENABLE_PROJECTS="clang;compiler-rt;libcxx;libcxxabi;lld" \ -DLLVM_ENABLE_LIBCXX=OFF \-DLLVM_ENABLE_LLD=OFF \-DFFI_INCLUDE_PATH=/usr/local/libffi/include/ \-DFFI_LIBRARY_PATH=/usr/local/libffi/ \-Wno-devmake -j20make install配置环境变量:export PATH=/opt/llvm/bin:$PATHexport LD_LIBRARY_PATH=/opt/llvm/lib:$LD_LIBRARY_PATHexport LIBRARY_PATH=$LD_LIBRARY_PATHexport C_INCLUDE_PATH=/opt/llvm/include:$C_INCLUDE_PATHexport CXX_INCLUDE_PATH=$C_INCLUDE_PATHclang --version 3.3 源码编译安装bazel确保已经安装了jdk8,推荐使用毕昇jdk。下载毕昇jdk并且安装: wget https://mirrors.huaweicloud.com/kunpeng/archive/compiler/bisheng_jdk/bisheng-jdk-8u282-linux-aarch64.tar.gztar -zxf bisheng-jdk-8u282-linux-aarch64.tar.gzvim /etc/profile #在文件末尾添加以下内容export JAVA_HOME=/opt/bisheng-jdk1.8.0_282/export PATH=$JAVA_HOME/bin:$PATHexport CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarsource /etc/profile 确保已经设置好了JAVA_HOME环境变量。下载bazel-3.3.1源码:wget https://github.com/bazelbuild/bazel/releases/download/3.3.1/bazel-3.3.1-dist.zipunzip bazel-3.3.1-dist.zip -d bazel-3.3.1cd bazel-3.3.1执行编译安装命令:env EXTRA_BAZEL_ARGS="--host_javabase=@local_jdk//:jdk" bash ./compile.shcp output/bazel /usr/bin/bazel --version 3.4 源码编译安装gn安装依赖包:yum install ninja-build -ywget -c https://github.com/ninja-build/ninja/archive/refs/tags/v1.10.1.zip -O ninja-1.10.1.zipunzip ninja-1.10.1.zipcd ninja-1.10.1./configure.py --bootstrapcp ninja /usr/bin/编译安装gn:git clone https://github.com/timniederhausen/gn.git -b 2020.03cd gnpython build/gen.pyninja -C outcp out/gn /usr/bin/gn --version3.5 安装gowget https://dl.google.com/go/go1.13.4.linux-arm64.tar.gztar -xf go1.13.4.linux-arm64.tar.gz -C /opt/配置环境变量:export PATH=/opt/go/bin:$PATHexport GO111MODULE=onexport GOROOT="/opt/go"export GOBIN=$GOROOT/binexport GOHOME="/home/gopath"export GOARCH="arm64"go version 4 软件移植分析4.1 Istio-proxyIstio-proxy是通过bazel工具构建,主要根据WORKSPACE和BUILD文件的规则来编译。从这些文件以及Makefile/Makefile.core.mk中可以发现,istio-proxy的编译主要是build和build_envoy,而实际尝试后,build和build_envoy的区别是,build规则不仅会编译得到envoy可执行文件,还会构建istio-envoy的docker镜像,而build_envoy只会得到envoy文件。由于在istio的编译中只需要envoy文件即可,所以当前只编译build_envoy。4.2 IstioIstio的编译包括生成二进制和构建docker镜像。编译二进制时,由于Istio的编译依赖于envoy,而默认配置下会从网络下载amd64架构的envoy。这不符合要求,所以需要加USE_LOCAL_PROXY=1,指定本地已经编译好的envoy。需要注意的是envoy和istio的源码路径在同级目录。 5 Istio编译5.1 Istio-proxy1.5.0编译依赖组件安装:yum install libtool automake autoconf make virtualenv -y下载源码:git clone https://github.com/istio/proxy.git -b 1.5.0cd proxyGN=/usr/bin/gn \NINJA=/usr/bin/ninja \make build_envoy VERBOSE=1 SHELL="/bin/bash -x" BAZEL_BUILD_ARGS="-s --sandbox_debug --verbose_failures --cpu aarch64" -j20第一次编译会失败,报错如下:该报错显示proxy不支持arm64,但实际上代码已经做了arm64的兼容因为根据WORKSPACE定义的规则,会从github下载envoy-wasm.xxx.tar.gz的源码,而envoy-wasm中有个wee8.genrule_cmd的文件,完整路径是它不支持aarch64,需要打patch,patch的内容包括增加对aarch64架构的支持,以及默认使用本地的gn、ninja文件。新建一个patch文件vi wee.patch添加以下内容:diff --git a/bazel/external/wee8.genrule_cmd b/bazel/external/wee8.genrule_cmdindex 9103dfb4d..39353a02b 100644--- a/bazel/external/wee8.genrule_cmd+++ b/bazel/external/wee8.genrule_cmd@@ -2,9 +2,9 @@ set -e -# This works only on Linux-x86_64 and macOS-x86_64.-if [[ ( `uname` != "Linux" && `uname` != "Darwin" ) || `uname -m` != "x86_64" ]]; then- echo "ERROR: wee8 is currently supported only on Linux-x86_64 and macOS-x86_64."+# This works only on Linux-x86_64, Linux-aarch64 and macOS-x86_64.+if [[ ( `uname` != "Linux" && `uname` != "Darwin" ) || ( `uname -m` != "x86_64" && `uname -m` != "aarch64" ) ]]; then+ echo "ERROR: wee8 is currently supported only on Linux-x86_64, Linux-aarch64 and macOS-x86_64." exit 1 fi @@ -28,6 +28,8 @@ fi export AR=$${AR:-ar} export NM=$${NM:-nm}+export GN=$${GN-buildtools/linux64/gn}+export NINJA=$${NINJA:-third_party/depot_tools/ninja} # Hook sanitizers. if [[ $${ENVOY_ASAN-} == "1" ]]; then@@ -75,9 +77,9 @@ WEE8_BUILD_ARGS+=" v8_enable_shared_ro_heap=false" if [[ `uname` == "Darwin" ]]; then buildtools/mac/gn gen out/wee8 --args="$$WEE8_BUILD_ARGS" else- buildtools/linux64/gn gen out/wee8 --args="$$WEE8_BUILD_ARGS"+ $${GN} gen out/wee8 --args="$$WEE8_BUILD_ARGS" fi-third_party/depot_tools/ninja -C out/wee8 wee8+$${NINJA} -C out/wee8 wee8 # Move compiled library to the expected destinations. popd 执行命令:patch -p /root/.cache/bazel/_bazel_root/9b0ca638054cfa0772ed292a93825682/external/envoy/bazel/external/wee8.genrule_cmd wee.patch其中9b0ca638054cfa0772ed292a93825682需要根据实际情况进行修改:另外envoy.bazelrc文件需要添加-Wno-error:执行以下命令:cd proxyvim envoy.bazelrc在33行后面添加如下内容:build --action_env=GNbuild --action_env=NINJA并将105行修改为build:libc++ --action_env=CXXFLAGS="-stdlib=libc++ -Wno-error"再次编译。如果出现以下错误:这个报错是因为没有生成bytecodes-builtins-list.h文件。先将toolchain.ninja文件复制出来备用,执行命令:cp /root/.cache/bazel/_bazel_root/9b0ca638054cfa0772ed292a93825682/sandbox/linux-sandbox/5088/execroot/io_istio_proxy/external/com_googlesource_chromium_v8/wee8/out/wee8/toolchain.ninja /opt路径中的5088需要根据实际情况进行修改。修改wee8.genrule_cmd文件:vim /root/.cache/bazel/_bazel_root/9b0ca638054cfa0772ed292a93825682/external/envoy/bazel/external/wee8.genrule_cmd添加如下内容,并注释clang编译分支:export BAZEL_COMPILER=gccexport BAZEL_CXXOPTS='-static-libstdc++'export CXXFLAGS='-static-libstdc++ -Wno-error'export LDFLAGS='-static-libstdc++'export CC=gccexport CXX=g++编译之后会出现报错:这是因为编译过程中,后续编译链接过程中没有使用gcc,仍然是使用clang的原因导致,不过前面报错无法生成的文件这个时候已经生成了,先将生成的文件复制出来备用:cp -r /root/.cache/bazel/_bazel_root/9b0ca638054cfa0772ed292a93825682/sandbox/linux-sandbox/5089/execroot/io_istio_proxy/external/com_googlesource_chromium_v8/wee8/out/wee8/gen/ /opt注意这里的5089是编译时自动生成的沙箱编号,需要查看编译信息进行对应修改。将wee8.genrule_cmd修改回去并添加以下两行shell代码:cp /opt/toolchain.ninja out/wee8/cp -r /opt/gen out/wee8/编辑/opt/toolchain.ninja并将51、77、86行修改为command=pwd:因为这几个地方的文件都不能正常生成,所以将这几个shell命令修改成pwd,需要生成的文件wee8.genrule_cmd中配置了使用复制的方式。再次编译,成功。在proxy目录下执行:bazel-bin/src/envoy/envoy -help进行验证。5.2 Istio1.5.0编译如果需要代理访问外网,则编辑docker/Dockerfile.base文件,添加docker代理:env http_proxy " http://<USER>:<PASSWORD>@172.30.68.94:8080"env https_proxy "http:// <USER>:<PASSWORD>@172.30.68.94:8080"env ftp_proxy "http:// <USER>:<PASSWORD>@172.30.68.94:8080"还需要执行以下命令:mkdir -p /etc/systemd/system/docker.service.d/cat > /etc/systemd/system/docker.service.d/proxy.conf <<EOF[Service]Environment="http_proxy=..."Environment="https_proxy=..."Environment="no_proxy=localhost,.local,.svc,..."EOF重启docker:systemctl daemon-reloadsystemctl restart docker编辑Makefile.core.mk文件,添加对aarch64的支持:else ifeq ($(LOCAL_ARCH),aarch64) TARGET_ARCH ?= arm64编辑bin/init.sh,将所有的amd64修改为arm64。然后执行以下命令:sed -i 's/x86_64/aarch64/g' pilot/docker/Dockerfile.proxyv2sed -i 's/gcr.io\/distroless/discolix/g' $(find . -name Dockerfile.*)编辑tools/istio-docker.mk,删掉不需要的docker:docker.app docker.app_sidecar docker.test_policybackend docker.kubectl下载源码并且编译(需要先安装docker):git clone https://github.com/istio/istio.git -b 1.5.0BUILD_WITH_CONTAINER=0 USE_LOCAL_PROXY=1 make build V=1TAG=1.5.0 BUILD_WITH_CONTAINER=0 USE_LOCAL_PROXY=1 make docker.baseTAG=1.5.0 BUILD_WITH_CONTAINER=0 BASE_VERSION=1.5.0 USE_LOCAL_PROXY=1 make docker BUILD_WITH_CONTAINER=0 USE_LOCAL_PROXY=1 make build V=1执行完成后会有一个out目录。后面两个docker编译完成后可通过docker images命令查看。6 1.4.7版本编译6.1 Istio-proxy-1.4.7下载源码:git clone https://github.com/istio/proxy.git -b 1.4.7cd proxyGN=/usr/bin/gn \NINJA=/usr/bin/ninja \make build_envoy VERBOSE=1 SHELL="/bin/bash -x" BAZEL_BUILD_ARGS="-s --sandbox_debug --verbose_failures --cpu aarch64" -j20编译报错如下:提示不支持aarch64架构,查看Makefile文件,可以看到其实是支持arm64的,编辑Makefile文件,添加:else ifeq ($(LOCAL_ARCH),aarch64) TARGET_ARCH ?= arm64后续编译步骤和修改参照istio-proxy-1.5.0的即可。6.2 Istio-1.4.7下载源码并且编译(需要先安装docker):git clone https://github.com/istio/istio.git -b 1.4.7cd istio如果需要代理访问外网,则编辑docker/Dockerfile.base文件,添加docker代理:env http_proxy ""env https_proxy ""env ftp_proxy ""重启docker:systemctl daemon-reloadsystemctl restart docker编辑Makefile文件,添加对aarch64的支持:else ifeq ($(LOCAL_ARCH),aarch64) TARGET_ARCH ?= arm64编辑Makefile.core.mk文件,添加对aarch64的支持:else ifeq ($(LOCAL_ARCH),aarch64)GOARCH_LOCAL := arm64编辑bin/init.sh,将所有的amd64修改为arm64。然后执行以下命令:sed -i 's/x86_64/aarch64/g' pilot/docker/Dockerfile.proxyv2sed -i 's/gcr.io\/distroless/discolix/g' $(find . -name Dockerfile.*)编辑tools/istio-docker.mk,删掉不需要的docker:docker.app docker.app_sidecar docker.test_policybackend docker.kubectl执行编译命令:BUILD_WITH_CONTAINER=0 USE_LOCAL_PROXY=1 make build V=1TAG=1.4.7 BUILD_WITH_CONTAINER=0 USE_LOCAL_PROXY=1 make docker.baseTAG=1.4.7 BUILD_WITH_CONTAINER=0 BASE_VERSION=1.4.7 USE_LOCAL_PROXY=1 make docker执行第一个编译命令会要求输入git账号密码:编辑go.mod,删除下图所示内容:replace istio.io/operator => github.com/istio-private/operator v0.0.0-20200323204721-49487c6ada25需要注意一下第一条编译命令生成的out目录的位置:如果找不到可以尝试使用find命令进行搜索。
-
本文分享自华为云社区《[传统微服务框架接入Istio方案详解](https://bbs.huaweicloud.com/blogs/337177?utm_source=zhihu&utm_medium=bbs-ex&utm_campaign=other&utm_content=content)》,作者:香菜聊游戏 。 # 微服务的概念和原理 ## 微服务带来的问题 **微服务带来的好处:** 解耦了业务,解耦了代码和架构,业务更紧凑,逻辑更单一简单。 **微服务带来的问题:** 在早期的时候,使用单体架构,所有的业务都在一个服务内,没有跨进程和网络上的一些复杂度。 微服务化之后引入的问题包括如何做服务发现,怎么做负载均衡,包括服务间的访问保护,例如熔断,故障定位等等问题。 在故障定位时,在原来单体服务下只需要看下日志,但是微服务化之后需要借助分布式调用链工具,这无形中带来了开发和定位问题的复杂度。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648172893747136548.png) **微服务和lstio网格架构对比** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648172910258181295.png) 微服务框架我们了解比较多的Spring cloud 或者国内用的比较多的Dubbo,框架本身就不多介绍了,我想大家都有所了解。 原理就是提供了开发的SDK或者说叫框架,这些框架都是内置了一些解决微服务问题的方案,比如服务发现,负载均衡,服务的熔断和降级,以及调用链路的埋点,动态路由这些事情。 下图是一个典型的用法,也是应用非常广泛的用法 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648172924592109894.png) 基于网格的治理是近些年应用比较多的,从上图可以看出,虽然基于网格的治理提供的能力和上图的基于sdk的能力一样,但是两者的设计原理,使用场景,设计理念是不同的。 # 详细介绍 ## 服务发现和负载均衡 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648172946950218939.png) 上图是传统的微服务框架的原理 一般的流程是: • 服务启动的时候向服务中心进行注册 • 调用的时候先从服务中心获取后端服务的地址 • 选择一个实例发送请求,等待回复 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648172971697244448.png) 服务网格的工作原理: 服务网格一般和k8s结合使用,因为k8s 本身做了服务的endpoint 维护,所以lstio不需要做服务注册,只需要做服务发现。 看下详细的区别 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648172983057758844.png) **服务熔断** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173014022563261.png) 服务熔断的机制: 如果一个服务在配置的一段时间内一直不可用,可以通过熔断机制,把服务隔离开,接触不到流量,进入到半熔断状态, 如果在一定的考察时间段能够恢复正常,熔断状态就会关闭,如果还是不能正常,会继续进入到熔断状态。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173025636281188.png) # 传统微服务框架的问题和基于服务网格的解决方案 **问题1:微服务SDK的多语言问题** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173045760911718.png) 上面这张图示意了微服务的之间的关系,一些大的客户拥护大的系统,系统由多个服务组成,服务可能由多种语言开发。 比如系统中可能有go服务,C++服务,python服务以及spring cloud 服务等等,这是一种比较常见的情况。 在这些服务中想做一个通用的服务发现时,但是Spring cloud或者Dubbo开发的服务,有一套自己的服务发现机制,但是不同语言开发的服务之间发现框架是不同的,比如go服务开发的服务不可能去spring cloud的服务中心注册,这个问题没办法解决。 比较粗暴的解决办法是对其他语言的项目用Java重构,在项目不复杂的情况下是可以接受的,但是在系统业务比较复杂,需要修改的项目比较多的情况下是无法接受的,不仅需要大量的人力,还要花费大量的时间,服务的稳定性没法保证。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173056841925038.png) 服务网格的解决方案下,服务发现是业务解耦的,不管是什么语言开发的服务,因为proxy不需要参与编译,网格之间只需要开放端口,并且保持可以访问,在这种方案下,不需要修改原来代码,减少了开发量,是企业可以接受的。 **问题2:基于sdk的服务在k8s下出现延迟和数据不一致** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173073450569182.png) 在上图这种情况下,Consumer服务原来在pod1 上,后来由于调度问题,导致Consumer服务迁移到pod2 上,正常情况下pod1 需要注销,pod2 进行重新注册,但是如果pod 迁移比较频繁,导致Producer 在访问Consumer服务的时候仍然拿到老的注册地址,就会出现延迟和数据不一致的情况。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173082735445456.png) **问题3:基于SDK逻辑开发的服务升级必须重新编译** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173142036639477.png) 基于SDK开发的逻辑代码进行升级的时候,必须重新编译所有基于SDK开发的服务,这个升级会带来大量的工作量,SDK的升级过程必须要和业务团队一起升级,非常耗时。产生的需求就是如果业务代码没有改变的情况下不需要重新编译。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173153337627183.png) 使用网格的解决方案下,如果业务没有修改是不需要进行编译和修改的,对开发人员和运维来说是非常友好的,同时降低了运维的风险,毕竟任何改动都是风险。 **问题4:基于SDK开发,统一发现和治理能力,需要全部改造** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173166300440438.png) 如果对一个单体应用进行微服务化,一般是渐进微服务化,比如上图,一般先对svc1进行微服务化,然后再对svc2 进行微服务化,在开发的过程中需要仍然访问互通,但是使用SDK的微服务有时需要使用同一框架,同一版本才能进行通信交互,这就是痛点。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173174232589949.png) 在使用网格的情况下,第一步先对svc1进行微服务化,svc2不改动,在开发的期间仍然不影响原来的访问。 # 传统微服务框架在服务网格中集成的实践详情 **总体思路** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173194399917971.png) 卸载SDK的服务发现和服务治理的功能,将这些功能迁移到基础设施上,让用户从这些中解脱出来,只专注于自己的业务代码。 **解决方案** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173206617415069.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173231925154426.png) 传统微服务的发现是注册到注册中心 在使用网格之后,平台同一服务发现,使用kube-proxy进行服务发现和负载均衡,Kube-proxy 直接返回服务的ip和端口,这样的话就消除容器环境下服务发现数据不及时的问题。 在使用k8s做服务发现,再使用网格的能力,服务完全无需修改适配 **Spring cloud项目的改造** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173251864677119.png) 在原来的配置中,取消对注册中心的注册,改为直接使用服务名:端口进行访问,直连的这种方式会被k8s 进行转发,对业务代码无需修改,减少了工作量。 注意:**要和访问的服务保持协议一致。** **移除spring cloud 的项目依赖** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173273991517518.png) **微服务网关的改进** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173288079137091.png) 情况1:微服务网关有业务逻辑 写了很多自定义的逻辑,比如filter的过滤等等,这种情况下网关可以作为普通的微服务部署在网格内。 情况2:微服务只有通用逻辑能力 直接用Ingress进行替换,进行地址映射,路径映射等基础能力,移除原来的网关。 **集成微服务注册中心到网格** 由于有些项目开发架构自成体系,不太适合直接排除原来的基础能力,在这种情况下想使用网格的能力,需要把原来的注册中心导入。Istio从微服务的注册中心导入注册数据,并且转换格式存储,在这种情况下依然可以配置相同的治理规则。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648173305397667851.png) # 总结 使用k8s和lstio网格进行开发,将服务发现,服务治理留给基础设施,可以将开发人员从复杂的服务中解脱出来,专注于业务开发,是当前来说比较好的解决方案。 视频地址:https://education.huaweicloud.com/courses/course-v1:HuaweiX+CBUCNXI055+Self-paced/courseware/511f6f06d97d4aaf9b90445dca5800d1/c08eb6fa0dd14a34bd617c6beb63a923/
-
华为云大咖带你玩转Istio技术直播时间:2022/3/24 19:00-21:00直播嘉宾:叶老师 云原生培训工程师直播简介:本直播为华为云云原生入门级开发者认证人才计划活动第5场直播,本直播将由华为云云原生培训工程师叶老师给大家分享Istio的核心概念与架构、流量规则配置、流量监控和治理策略,带你玩转Istio技术!直播链接:https://bbs.huaweicloud.com/live/edu_live/202203241900.html 活动介绍:面向高校学生、个人开发者、企业开发及运维人员,华为云即将推出云原生入门级开发者认证(HCCDA - Cloud Native),从开源组件到华为云上服务的介绍,使您掌握云原生的核心理念和架构,具备基本开发实践能力。为帮助开发者学习并顺利通过认证,华为云开发者学堂上线“云原生入门级开发者认证人才计划”赋能学习活动,收获知识干货、拿到官方证书的同时还有机会赢取更多精美奖品!
-
本地启动的服务如何注册到istio中,并通过服务名调用其他微服务或者其他简单的调用方法(最好不要开放nodeport)?
-
1. istio的apiVersion的地址是 networking.istio.io/vlalpha3,请问我如何看到里面的内容。2. kind是istio自己定义,请问如何看下istio定义的kind内容。3. 请问去哪里可以看到istio的镜像初学者不好意思,麻烦各位大神了。
-
1. istio的apiVersion的地址是 networking.istio.io/vlalpha3,请问我如何看到里面的内容。2. kind是istio自己定义,请问如何看下istio定义的kind内容。3. 请问去哪里可以看到istio的镜像初学者很多不懂,不好意思,麻烦各位大神了。
-
随着云原生技术的普及,Istio近两年在中国也越来越受到开发者的广泛应用。根据CNCF 2020年调查,46%的组织在生产中使用服务网格或计划在未来12个月内使用。Istio是在生产中使用最多的网格。Istio开源四年来,已经在Github上收获了2.7万颗星,也获得了大量的社区用户。首届IstioCon也在今年的2月份成功举办,有几千人参加了线上会议。为此Istio社区联动信通院、华为云等多位合作伙伴,共同主办国内首届《Istio Meetup China》,并邀请了多位业内专家向大家分享全面的Istio技术实践。时间:7月10日13:00-17:30地点:中国信息通信研究院地址:北京市海淀区花园北路52号中国信息通信研究院科研楼二层报告厅报名方式:扫描下方海报二维码华为云容器网格数据面技术专家张伟也受邀参加此次大会,将为大家带来《Envoy 原理介绍及线上问题踩坑》主题分享,欢迎大家报名参加!
-
Istio 包含一个可远程利用的漏洞,使用Istio的k8s集群内的机器有可能越权访问到TLS证书和密钥。漏洞描述: Istio 包含一个可远程利用的漏洞,使用Istio的k8s集群内的机器有可能越权访问到TLS证书和密钥。建议受影响的用户尽快升级。lstio是一个由谷歌、IBM与Lyft共同开发的开源项目,旨在提供一种统一化的微服务连接、安全保障、管理与监控方式。漏洞编号:CVE-2021-34824漏洞等级: 高危,CVSS评分9.1漏洞详情: 该IstioGateway DestinationRule可以通过从Kubernetes秘密加载私钥和证书credentialName的配置。对于Istio 1.8 及更高版本,秘密通过 XDS API 从 Istiod 传送到网关或工作负载。在上述方法中,网关或工作负载部署应该只能访问存储在其命名空间内的Kubernetes 机密中的凭据(TLS 证书和私钥)。然而,Istiod 中的一个错误允许授权客户端访问和检索 Istiod 中缓存的任何 TLS证书和私钥。受影响的版本:Istio <=1.8Istio 1.9.0 到 1.9.5Istio 1.10.0 到 1.10.1安全版本:Istio >= 1.9.6 或更高版本,如果使用 1.9.xIstio >= 1.10.2 或更高版本,如果使用 1.10.x如果使用的是 Istio 1.8,请联系Istio 提供商以检查更新。否则,请升级到 Istio 1.9 或 1.10 的最新补丁版本。我受影响了吗?如果以下所有条件都为真,您的集群就会受到影响:使用的是 Istio 1.10.0 到 1.10.1、Istio 1.9.0 到 1.9.5 或 Istio 1.8.x。已定义Gateways或 DestinationRules具有credentialName指定的字段。没有指定 Istiod 标志PILOT_ENABLE_XDS_CACHE=false。漏洞修复建议:建议受影响的用户尽快升级到安全版本。如果升级不可行,则可以通过禁用 Istiod 缓存来缓解此漏洞。通过设置 Istiod 环境变量来禁用缓存PILOT_ENABLE_XDS_CACHE=false。修改后,系统和 Istiod 性能可能会受到影响,因为这会禁用 XDS 缓存。参考链接:https://istio.io/latest/news/security/istio-security-2021-007/
-
云原生改造遵循两阶段原则: 第一阶段:进行容器化改造,使用K8S+容器基础设施承载应用; 第二阶段:启用Istio,进行灰度发布和服务治理。改造实践可分别参考如下系列文章:01.虚机应用部署至华为云CCE03. 迁移第三方云厂商集群应用到华为云CCE 04. 容器化应用迁移至ASM平台05. SpringCloud微服务至Istio迁移指导09.我的应用当前阶段是否适合进行云原生改造?
上滑加载中
推荐直播
-
华为AI技术发展与挑战:集成需求分析的实战指南
2024/11/26 周二 18:20-20:20
Alex 华为云学堂技术讲师
本期直播将综合讨论华为AI技术的发展现状,技术挑战,并深入探讨华为AI应用开发过程中的需求分析过程,从理论到实践帮助开发者快速掌握华为AI应用集成需求的框架和方法。
去报名 -
华为云DataArts+DWS助力企业数据治理一站式解决方案及应用实践
2024/11/27 周三 16:30-18:00
Walter.chi 华为云数据治理DTSE技术布道师
想知道数据治理项目中,数据主题域如何合理划分?数据标准及主数据标准如何制定?数仓分层模型如何合理规划?华为云DataArts+DWS助力企业数据治理项目一站式解决方案和应用实践告诉您答案!本期将从数据趋势、数据治理方案、数据治理规划及落地,案例分享四个方面来助力企业数据治理项目合理咨询规划及顺利实施。
去报名
热门标签