{"id":22885023,"url":"https://github.com/mark8s/istio-in-action","last_synced_at":"2026-01-11T02:25:58.818Z","repository":{"id":112107859,"uuid":"473470813","full_name":"mark8s/istio-in-action","owner":"mark8s","description":"[istio in action] book learning  notes","archived":false,"fork":false,"pushed_at":"2022-04-19T12:36:47.000Z","size":17,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-06T22:42:24.245Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mark8s.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-24T05:37:02.000Z","updated_at":"2022-05-10T06:29:30.000Z","dependencies_parsed_at":"2023-07-31T19:15:07.436Z","dependency_job_id":null,"html_url":"https://github.com/mark8s/istio-in-action","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mark8s%2Fistio-in-action","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mark8s%2Fistio-in-action/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mark8s%2Fistio-in-action/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mark8s%2Fistio-in-action/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mark8s","download_url":"https://codeload.github.com/mark8s/istio-in-action/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246514286,"owners_count":20790016,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-13T19:30:56.541Z","updated_at":"2026-01-11T02:25:58.791Z","avatar_url":"https://github.com/mark8s.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"## Istio in Action\n\n\u003e book address : https://livebook.manning.com/book/istio-in-action/welcome/v-16/ \n\n### Understanding Istio\n\n#### Introducing Istio Service Mesh\n\n- Our cloud infrastructure is not reliable\n\n- Making service interaction resilient（使服务之间有弹性）\n\n- The application-aware service proxy（应用感知服务代理）：将这些横向关注点(horizontal concerns)转移到基础架构中的一种方法是使用代理。代理是一个中间基础设施组件，可以处理连接并将它们重定向到适当的后端。\n\n Use a proxy to push these horizontal concerns such as resilience, traffic control, security, etc. out of the application  implementation（使用代理将这些横向问题（例如弹性、流量控制、安全性等）排除在应用程序实施之外）\n\n![image-20220324144028482](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220324144028482.png)\n\n我们想要的是一个“应用程序感知”的代理，并且能够代表我们的服务执行应用程序网络。要做到这一点，这个“服务代理”需要理解消息和请求等应用程序结构，而不是理解连接和数据包的更传统的基础设施代理。换句话说，我们需要一个第 7 层代理。\n\n- ### Meet Envoy proxy（认识envoy代理）\n\nEnvoy 是 Lyft 开发的，作为其面向服务的架构基础设施的一部分，能够在应用程序之外实现应用程序弹性和其他网络问题。 Envoy 为我们提供了重试、超时、断路、客户端负载平衡、服务发现、安全性和指标收集等网络功能，而无需任何明确的语言或框架依赖。\n\n![image-20220324144638199](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220324144638199.png)\n\nEnvoy 的强大功能不仅限于这些应用层弹性方面（application layer resilience aspects）。 Envoy 还捕获许多应用程序网络指标，例如每秒请求数、故障数、断路事件等。通过使用 Envoy，我们可以自动了解我们的服务之间发生的事情，这就是我们开始看到很多意想不到的复杂性的地方。 Envoy 代理为解决服务架构的横切、横向可靠性和可观察性问题奠定了基础，并允许我们将这些问题推到应用程序之外并进入基础设施。\n\n服务代理还可以做一些事情，比如收集分布式跟踪跨度，这样我们就可以将特定请求所采取的所有步骤拼接在一起。我们可以看到每个步骤花费了多长时间，并在我们的系统中寻找潜在的瓶颈或错误。如果所有应用程序都通过自己的代理与外部世界通信，并且应用程序的所有传入流量都通过我们的代理，那么我们已经为我们的应用程序获得了一些重要的功能，而无需更改任何应用程序代码。这种代理+应用程序组合构成了称为服务网格的通信总线的基础。\n\n我们可以将像 Envoy 这样的服务代理部署在我们应用程序的每个实例中作为单个原子单元。例如，在 Kubernetes 中，我们可以将服务代理与我们的应用程序共同部署在单个 Pod 中。这种部署模式称为边车部署（**sidecar** ）。\n\n![image-20220324150023187](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220324150023187.png)\n\n##### What’s a service mesh?\n\nA *service mesh* is a distributed application infrastructure that is responsible for handling network traffic on behalf of the application in a transparent, out of process manner.（服务网格是一种分布式应用程序基础设施，负责以透明、进程外的方式代表应用程序处理网络流量。）\n\n##### Introducing Istio service mesh\n\nIstio 是由 Google、IBM 和 Lyft 创建的服务网格的开源实现。 Istio 可帮助您以透明的方式为您的服务架构添加弹性和可观察性。使用 Istio，应用程序不必知道它们是服务网格的一部分。每当他们与外界交互时，Istio 将代表应用程序处理网络。这意味着无论您是在做微服务、单体还是介于两者之间的任何东西，Istio 都可以带来很多好处。 Istio 的数据平面默认使用开箱即用的 Envoy 代理，并帮助您配置应用程序以在其旁边部署服务代理 (Envoy) 的实例。 Istio 的控制平面由几个组件组成，这些组件为最终用户/operators提供 API、代理配置 API、安全设置、策略声明等。\n\n![image-20220324151647937](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220324151647937.png)\n\n1. Traffic comes into the cluster from a client outside the mesh through the Istio ingress gateway\n2. Traffic goes to the shopping-cart service. The traffic first passes through the shopping-cart service’s sidecar proxy. The service proxy can apply timeouts, metric collection, security enforcement etc for the service.\n3. As the request makes its way through various services, Istio’s service proxy can intercept the request at various steps and make routing decisions (e.g., to route some requests intended to the Tax service to v1.1 of the Tax service which may have a fix for certain tax calculations)\n4. Istio’s control plane (`istiod`) is used to configure the Istio proxies which handle routing, security, telemetry collection, and resilience\n5. Request metrics are periodically sent back to various collection services; Distributed tracing spans (like Jaeger or Zipkin) are sent back to an tracing store which can be used to later track the path and latency of a request through the system\n\n##### What are the drawbacks to using a service mesh?\n\n首先，使用服务网格在请求路径中放置另一个中间件，特别是代理。这个代理能够提供很多价值，但对于那些不熟悉代理的人来说，这最终可能会成为一个黑匣子，并且使调试应用程序的行为变得更加困难。 Envoy 代理是专门为可调试而构建的，并且会公开很多关于网络上发生的事情的信息——比不存在时更重要——但对于不熟悉操作 Envoy 的人来说，这可能看起来非常复杂并抑制现有的调试实践。\n\n使用服务网格的另一个缺点是在租赁方面。网格与网格中运行的服务一样有价值。也就是说，网格中的服务越多，网格对于运营这些服务就越有价值。但是，如果在物理网格部署的租赁和隔离模型中没有适当的策略、自动化和深思熟虑，您最终可能会遇到错误配置网格会影响许多服务的情况。\n\n最后，服务网格成为您的服务和应用程序架构的根本重要部分，因为它位于请求路径上。服务网格可以提供很多机会来提高安全性、可观察性和路由控制状态。缺点是网格引入了另一个层和另一个复杂性的机会。了解如何在现有的组织流程和治理中以及在现有团队之间进行配置、操作和最重要的集成是很困难的。\n\n#### First steps with Istio\n\n##### Getting the Istio distribution\n\n1.下载istio\n\n```\nhttps://github.com/istio/istio/releases/tag/1.13.0\n```\n\n2.查看版本\n\n```shell\n[root@biz-master-48 bin]# istioctl version\nno running Istio pods in \"istio-system\"\n1.13.0\n```\n\n3.precheck：安装istio之前的检验\n\n```shell\n[root@biz-master-48 bin]# istioctl x precheck\n✔ No issues found when checking the cluster. Istio is safe to install or upgrade!\n  To get started, check out https://istio.io/latest/docs/setup/getting-started/\n```\n\n4.demo版本istio安装\n\n```shell\nistioctl install --set profile=demo -y\n```\n\n```shell\n[root@biz-master-48 istio-1.13.0]# istioctl install --set profile=demo -y\n✔ Istio core installed                                                                                                   \n✔ Istiod installed                                                                                                       \n✔ Egress gateways installed                                                                                              \n✔ Ingress gateways installed                                                                                             \n✔ Installation complete                                                                                                  Making this installation the default for injection and validation.\n\nThank you for installing Istio 1.13.  Please take a few minutes to tell us about your install/upgrade experience!  https://forms.gle/pzWZpAvMVBecaQ9h9\n```\n\nservice mesh由date-plane（that is service proxies）和control-plane组成。当我们安装完instio后，你可以看到一个control plane、ingress、egress。同样当我们安装application并注入service proxies后，我们就拥有了一个data plane。\n\n```shell\n[root@biz-master-48 istio-1.13.0]# kubectl get po -n istio-system\nNAME                                   READY   STATUS    RESTARTS   AGE\nistio-egressgateway-6cf5fb4756-9vrzq   1/1     Running   0          117s\nistio-ingressgateway-dc9c8f588-bd6bj   1/1     Running   0          117s\nistiod-7586c7dfd8-gffc6                1/1     Running   0          2m15s\n[root@biz-master-48 istio-1.13.0]#\n```\n\n5.安装完后，需要校验安装是否成功\n\n```shell\nistioctl verify-install\n```\n\n```shell\n[root@biz-master-48 istio-1.13.0]# istioctl verify-install\n1 Istio control planes detected, checking --revision \"default\" only\n✔ Deployment: istio-ingressgateway.istio-system checked successfully\n✔ PodDisruptionBudget: istio-ingressgateway.istio-system checked successfully\n✔ Role: istio-ingressgateway-sds.istio-system checked successfully\n✔ RoleBinding: istio-ingressgateway-sds.istio-system checked successfully\n✔ Service: istio-ingressgateway.istio-system checked successfully\n✔ ServiceAccount: istio-ingressgateway-service-account.istio-system checked successfully\n✔ Deployment: istio-egressgateway.istio-system checked successfully\n✔ PodDisruptionBudget: istio-egressgateway.istio-system checked successfully\n✔ Role: istio-egressgateway-sds.istio-system checked successfully\n✔ RoleBinding: istio-egressgateway-sds.istio-system checked successfully\n✔ Service: istio-egressgateway.istio-system checked successfully\n✔ ServiceAccount: istio-egressgateway-service-account.istio-system checked successfully\n✔ ClusterRole: istiod-istio-system.istio-system checked successfully\n✔ ClusterRole: istio-reader-istio-system.istio-system checked successfully\n✔ ClusterRoleBinding: istio-reader-istio-system.istio-system checked successfully\n✔ ClusterRoleBinding: istiod-istio-system.istio-system checked successfully\n✔ ServiceAccount: istio-reader-service-account.istio-system checked successfully\n✔ Role: istiod-istio-system.istio-system checked successfully\n✔ RoleBinding: istiod-istio-system.istio-system checked successfully\n✔ ServiceAccount: istiod-service-account.istio-system checked successfully\n✔ CustomResourceDefinition: wasmplugins.extensions.istio.io.istio-system checked successfully\n✔ CustomResourceDefinition: destinationrules.networking.istio.io.istio-system checked successfully\n✔ CustomResourceDefinition: envoyfilters.networking.istio.io.istio-system checked successfully\n✔ CustomResourceDefinition: gateways.networking.istio.io.istio-system checked successfully\n✔ CustomResourceDefinition: proxyconfigs.networking.istio.io.istio-system checked successfully\n✔ CustomResourceDefinition: serviceentries.networking.istio.io.istio-system checked successfully\n✔ CustomResourceDefinition: sidecars.networking.istio.io.istio-system checked successfully\n✔ CustomResourceDefinition: virtualservices.networking.istio.io.istio-system checked successfully\n✔ CustomResourceDefinition: workloadentries.networking.istio.io.istio-system checked successfully\n✔ CustomResourceDefinition: workloadgroups.networking.istio.io.istio-system checked successfully\n✔ CustomResourceDefinition: authorizationpolicies.security.istio.io.istio-system checked successfully\n✔ CustomResourceDefinition: peerauthentications.security.istio.io.istio-system checked successfully\n✔ CustomResourceDefinition: requestauthentications.security.istio.io.istio-system checked successfully\n✔ CustomResourceDefinition: telemetries.telemetry.istio.io.istio-system checked successfully\n✔ CustomResourceDefinition: istiooperators.install.istio.io.istio-system checked successfully\n✔ ClusterRole: istiod-clusterrole-istio-system.istio-system checked successfully\n✔ ClusterRole: istiod-gateway-controller-istio-system.istio-system checked successfully\n✔ ClusterRoleBinding: istiod-clusterrole-istio-system.istio-system checked successfully\n✔ ClusterRoleBinding: istiod-gateway-controller-istio-system.istio-system checked successfully\n✔ ConfigMap: istio.istio-system checked successfully\n✔ Deployment: istiod.istio-system checked successfully\n✔ ConfigMap: istio-sidecar-injector.istio-system checked successfully\n✔ MutatingWebhookConfiguration: istio-sidecar-injector.istio-system checked successfully\n✔ PodDisruptionBudget: istiod.istio-system checked successfully\n✔ ClusterRole: istio-reader-clusterrole-istio-system.istio-system checked successfully\n✔ ClusterRoleBinding: istio-reader-clusterrole-istio-system.istio-system checked successfully\n✔ Role: istiod.istio-system checked successfully\n✔ RoleBinding: istiod.istio-system checked successfully\n✔ Service: istiod.istio-system checked successfully\n✔ ServiceAccount: istiod.istio-system checked successfully\n✔ EnvoyFilter: stats-filter-1.11.istio-system checked successfully\n✔ EnvoyFilter: tcp-stats-filter-1.11.istio-system checked successfully\n✔ EnvoyFilter: stats-filter-1.12.istio-system checked successfully\n✔ EnvoyFilter: tcp-stats-filter-1.12.istio-system checked successfully\n✔ EnvoyFilter: stats-filter-1.13.istio-system checked successfully\n✔ EnvoyFilter: tcp-stats-filter-1.13.istio-system checked successfully\n✔ ValidatingWebhookConfiguration: istio-validator-istio-system.istio-system checked successfully\nChecked 15 custom resource definitions\nChecked 3 Istio Deployments\n✔ Istio is installed and verified successfully\n```\n\n6.安装控制层支持的组件grafana和jaeger\n\ngrafana：可视化proxies暴露的metrics\n\njaeger：分布式链路追踪系统，可视化mesh的请求流\n\n```shell\n[root@biz-master-48 istio-1.13.0]# kubectl apply -f samples/addons/\nserviceaccount/grafana created\nconfigmap/grafana created\nservice/grafana created\ndeployment.apps/grafana created\nconfigmap/istio-grafana-dashboards created\nconfigmap/istio-services-grafana-dashboards created\ndeployment.apps/jaeger created\nservice/tracing created\nservice/zipkin created\nservice/jaeger-collector created\nserviceaccount/kiali created\nconfigmap/kiali created\nclusterrole.rbac.authorization.k8s.io/kiali-viewer created\nclusterrole.rbac.authorization.k8s.io/kiali created\nclusterrolebinding.rbac.authorization.k8s.io/kiali created\nrole.rbac.authorization.k8s.io/kiali-controlplane created\nrolebinding.rbac.authorization.k8s.io/kiali-controlplane created\nservice/kiali created\ndeployment.apps/kiali created\nserviceaccount/prometheus created\nconfigmap/prometheus created\nclusterrole.rbac.authorization.k8s.io/prometheus created\nclusterrolebinding.rbac.authorization.k8s.io/prometheus created\nservice/prometheus created\ndeployment.apps/prometheus created\n```\n\n查看效果：\n\n```shell\n[root@biz-master-48 istio-1.13.0]# kubectl get po -n istio-system\nNAME                                   READY   STATUS    RESTARTS   AGE\ngrafana-6c5dc6df7c-rjrrb               1/1     Running   0          3m4s\nistio-egressgateway-6cf5fb4756-9vrzq   1/1     Running   0          13m\nistio-ingressgateway-dc9c8f588-bd6bj   1/1     Running   0          13m\nistiod-7586c7dfd8-gffc6                1/1     Running   0          13m\njaeger-9dd685668-nckfw                 1/1     Running   0          3m4s\nkiali-699f98c497-vclps                 1/1     Running   0          3m4s\nprometheus-699b7cc575-9h9hk            2/2     Running   0          3m4s\n```\n\n##### Getting to know the Istio control plane\n\n控制面组件如下：\n\n![image-20220325104314136](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220325104314136.png)\n\nistiod：负责控制面的组件。\n\n###### Istiod\n\n`Istiod`是负责控制面的组件。`Istiod`有时候被称之为`Istio Pilot`（领航员），它负责将由`user/operator`指定的高级别Istio配置下发到数据面的service proxy中。\n\n![image-20220325105222205](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220325105222205.png)\n\n`Istio`使用`Envoy`作为它的`service proxy`，所以`service-proxy-specific`配置将会被翻译为`Envoy`的配置。\n\n\u003e This data-plane API exposed by istiod implements Envoy's discovery APIS\n\nThis data-plane API exposed by istiod implements Envoy's discovery APIS（ Istiod暴露的这个数据平面API实现了Envoy的发现API），像service discovery（listener discovery service [LDS]），endpoints（endpoint discovery service [EDS]），和routing rules（路由规则）（route discovery service [RDS]）被称为`xDS APIs`。\n\n###### Ingress and egress gateway\n\n我们可能需要与集群外的服务打交道，那么就需要配置`istio`去指定什么流量可以允许进入集群，什么流量可以被允许从集群中出去。这里就涉及到`ingressgateway`和`istio-egressgateway`。\n\n![image-20220325113351446](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220325113351446.png)\n\n###### Deploying your first application\n\n下载示例：\n\n```shell\ngit clone https://github.com/istioinaction/book-source-code\n```\n\n创建命名空间\n\n```shell\nkubectl create namespace istioinaction\n```\n\n设置上下文，设置后访问这个`namespace`不需要指定`-n` \n\n```shell\nkubectl config set-context $(kubectl config current-context) --namespace=istioinaction\n```\n\n```shell\n[root@biz-master-48 book-source-code]# kubectl get all\nNo resources found in istioinaction namespace.\n[root@biz-master-48 book-source-code]#\n```\n\n现在不指定`-n`的时候，默认访问的命名空间由`default`变为`istioinaction`了。\n\n我们创建以下资源,部署一个`catalog`服务：\n\n```yaml\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: catalog\n---\napiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    app: catalog\n  name: catalog\nspec:\n  ports:\n  - name: http\n    port: 80\n    protocol: TCP\n    targetPort: 3000\n  selector:\n    app: catalog\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  labels:\n    app: catalog\n    version: v1\n  name: catalog\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: catalog\n      version: v1\n  template:\n    metadata:\n      labels:\n        app: catalog\n        version: v1\n    spec: \n      serviceAccountName: catalog\n      containers:\n      - env:\n        - name: KUBERNETES_NAMESPACE\n          valueFrom:\n            fieldRef:\n              fieldPath: metadata.namespace\n        image: istioinaction/catalog:latest\n        imagePullPolicy: IfNotPresent\n        name: catalog\n        ports:\n        - containerPort: 3000\n          name: http\n          protocol: TCP\n        securityContext:\n          privileged: false\n```\n\n执行以下命令,进行服务的注入：\n\n```shell\n[root@biz-master-48 ~]# kubectl label namespace istioinaction istio-injection=enabled\nnamespace/istioinaction labeled\n[root@biz-master-48 ~]# kubectl apply -f book-source-code/services/catalog/kubernetes/catalog.yaml \nserviceaccount/catalog created\nservice/catalog created\ndeployment.apps/catalog created\n[root@biz-master-48 ~]#\n```\n\n查看效果：\n\n```shell\n[root@biz-master-48 ~]# kubectl get po\nNAME                       READY   STATUS    RESTARTS   AGE\ncatalog-68666d4988-7qwd9   2/2     Running   0          2m2s\n```\n\n查看容器,会发现有一个叫`istio-proxy`容器，它就是`sidecar`：\n\n```yaml\nContainers:\n  catalog:\n    Container ID:   docker://4df217235c7b812dba4cc669643cc02cf0eb72d5ae330dc68cef5ab5973b6bda\n    Image:          istioinaction/catalog:latest\n    Image ID:       docker-pullable://istioinaction/catalog@sha256:5ebcaad0491ea6e4ab303a48b51b90856ae2aaf40ea8fc5020f943a261a7b8df\n    Port:           3000/TCP\n    Host Port:      0/TCP\n    State:          Running\n      Started:      Fri, 25 Mar 2022 04:02:00 +0000\n    Ready:          True\n    Restart Count:  0\n    Environment:\n      KUBERNETES_NAMESPACE:  istioinaction (v1:metadata.namespace)\n    Mounts:\n      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-fpxs4 (ro)\n  istio-proxy:\n    Container ID:  docker://db6bb7a0e8d0ef9993be174222cc344f1f3494bbdeddc8186f494d8719a69963\n    Image:         docker.io/istio/proxyv2:1.13.0\n    Image ID:      docker-pullable://istio/proxyv2@sha256:2919336a667e83f3a1731a21252ff2f88c74218bffa9660638e0d190071a4510\n    Port:          15090/TCP\n    Host Port:     0/TCP\n    Args:\n      proxy\n      sidecar\n      --domain\n      $(POD_NAMESPACE).svc.cluster.local\n      --proxyLogLevel=warning\n      --proxyComponentLogLevel=misc:error\n      --log_output_level=default:info\n      --concurrency\n      2\n    State:          Running\n      Started:      Fri, 25 Mar 2022 04:02:00 +0000\n    Ready:          True\n```\n\n访问这个服务：\n\n```shell\n[root@biz-master-48 ~]# kubectl get svc\nNAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE\ncatalog   ClusterIP   10.21.137.250   \u003cnone\u003e        80/TCP    108m\n[root@biz-master-48 ~]# curl 10.21.137.250:/items/1\n{\n  \"id\": 1,\n  \"color\": \"amber\",\n  \"department\": \"Eyewear\",\n  \"name\": \"Elinor Glasses\",\n  \"price\": \"282.00\"\n}[root@biz-master-48 ~]#\n```\n\n接下来，我们部署一个`webapp`服务，该服务可以聚合从其他从其他服务获取的数据，并在浏览器可视化展示。\n\n```shell\n[root@biz-master-48 ~]# kubectl apply -f book-source-code/services/webapp/kubernetes/webapp.yaml \nserviceaccount/webapp created\nservice/webapp created\ndeployment.apps/webapp created\n```\n\n查看部署\n\n```shell\n[root@biz-master-48 ~]# kubectl get po\nNAME                       READY   STATUS    RESTARTS   AGE\ncatalog-68666d4988-7qwd9   2/2     Running   0          113m\nwebapp-7f47f74b9d-tbtbf    2/2     Running   0          29s\n```\n\n访问`webapp`\n\n```shell\n[root@biz-master-48 ~]# kubectl get svc\nNAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE\ncatalog   ClusterIP   10.21.137.250   \u003cnone\u003e        80/TCP         125m\nwebapp    NodePort    10.21.222.196   \u003cnone\u003e        80:31561/TCP   12m\n```\n\n![image-20220325141133226](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220325141133226.png)\n\n###### Exploring the power of Istio with resilience,observability,and traffic control\n\n现在，我们使用`Istio ingress gateway`去暴露`webapp`服务。使用`Istio ingress gateway`，我们可以从集群外访问我们的服务，作用类似于`ingress controller`\n\n```shell\n[root@biz-master-48 ~]# kubectl apply -f book-source-code/ch2/ingress-gateway.yaml \ngateway.networking.istio.io/outfitters-gateway created\nvirtualservice.networking.istio.io/webapp-virtualservice created\n```\n\n查看具体的内容，ingress-gateway：\n\n```yaml\napiVersion: networking.istio.io/v1alpha3\nkind: Gateway\nmetadata:\n  name: outfitters-gateway\nspec:\n  selector:\n    istio: ingressgateway # use istio default controller\n  servers:\n  - port:\n      number: 80\n      name: http\n      protocol: HTTP\n    hosts:\n    - \"*\"\n---\napiVersion: networking.istio.io/v1alpha3\nkind: VirtualService\nmetadata:\n  name: webapp-virtualservice\nspec:\n  hosts:\n  - \"*\"\n  gateways:\n  - outfitters-gateway\n  http:\n  - route:\n    - destination:\n        host: webapp\n        port:\n          number: 80\n```\n\n我们已经让istio意识到kubernetes边缘的webapp服务，我们尝试一下该服务是否可达。\n\n首先，我们要获取`Istio gateway` 监听的端点：\n\n```shell\nkubectl port-forward deploy/istio-ingressgateway -n istio-system 8080:8080 --address 0.0.0.0\n```\n\n当在集群外无法访问8080端口的时候，使用`--address 0.0.0.0`\n\n访问界面，输入http://10.10.13.48:8080：\n\n![image-20220325151921072](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220325151921072.png)\n\n如果你遇到了一些错误，导致无法访问这个界面，此时需要做一些排查工作。\n\n检查`gateway`有一个路由\n\n```shell\n[root@biz-master-48 ~]# istioctl proxy-config routes deploy/istio-ingressgateway.istio-system\nNAME          DOMAINS     MATCH                  VIRTUAL SERVICE\nhttp.8080     *           /*                     webapp-virtualservice.istioinaction\n              *           /stats/prometheus*     \n              *           /healthz/ready*  \n```\n\n出现`webapp-virtualservice.istioinaction`，说明我们的路由没有问题。如果没有，那么检查gateway、virtualservice是否安装。\n\n```shell\n[root@biz-master-48 ~]# kubectl get gateway\nNAME                 AGE\noutfitters-gateway   29m\n[root@biz-master-48 ~]# kubectl get virtualservice\nNAME                    GATEWAYS                 HOSTS   AGE\nwebapp-virtualservice   [\"outfitters-gateway\"]   [\"*\"]   29m\n```\n\n-  Istio observability\n\n`Istio` 为两大类可观测性创建了遥测技术（telemetry）：top-line metrics、distributed tracing\n\n**top-line metrics**\n\n包含：request per second、number of failures、tail-latency percentiles\n\n为了获取metrics，我们需要使用`prometheus`和`grafana`\n\n访问我们之前部署的`grafana`,执行以下\n\n```shell\nistioctl dashboard grafana --address 0.0.0.0\n```\n\n```shell\n[root@biz-master-48 ~]# istioctl dashboard grafana --address 0.0.0.0\nhttp://0.0.0.0:3000\nFailed to open browser; open http://0.0.0.0:3000 in your browser.\n```\n\n![image-20220325153818859](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220325153818859.png)\n\n执行以下脚本，然后查看服务对应的监控数据\n\n```shell\nwhile true; do curl http://10.21.137.250:80/api/catalog; sleep .5; done\n```\n\n![image-20220325154803709](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220325154803709.png)\n\n**distributed tracing**\n\n包含：链路追踪，查找慢请求\n\n我们使用`jaeger`处理分布式链路追踪，执行以下命令我们开启我们的`jaeger`\n\n```shell\n[root@biz-master-48 ~]# istioctl dashboard jaeger --address 0.0.0.0\nhttp://0.0.0.0:16686\nFailed to open browser; open http://0.0.0.0:16686 in your browser.\n```\n\n![image-20220325155912558](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220325155912558.png)\n\n我们多访问webapp地址，然后查看效果\n\n```shell\nhttp://10.10.13.48:8080/\n```\n\n![image-20220325160507953](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220325160507953.png)\n\n查看某个请求记录详情\n\n![image-20220325160604730](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220325160604730.png)\n\n- Istio for resiliency（弹性）\n\n一个弹性方面是在出现断断续续或瞬时的网络错误时进行请求的重试。\n\n我们执行一个`chao`脚本，使catalog服务发生一些500的错误请求。\n\n```shell\n./book-source-code/bin/chaos.sh 500 50\n```\n\n500 代表 http 500，50代表 50%的请求时 500的响应。我们查看界面：\n\n![image-20220325163937736](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220325163937736.png)\n\n刷新的时候，基本上每两次的访问，会出现一次`Catalog`服务异常的现象。\n\n让我们看看`Istio`如何使`webapp`和`catalog`之间的网络变得更有弹性：使用`VirtualService`。\n\n```yaml\napiVersion: networking.istio.io/v1alpha3\nkind: VirtualService\nmetadata:\n  name: catalog\nspec:\n  hosts:\n  - catalog\n  http:\n  - route:\n    - destination:\n        host: catalog\n    retries:\n      attempts: 3\n      retryOn: 5xx\n      perTryTimeout: 2s\n```\n\n```shell\n[root@biz-master-48 ~]# kubectl apply -f book-source-code/ch2/catalog-virtualservice.yaml \nvirtualservice.networking.istio.io/catalog created\n```\n\n- Istio for traffic routing\n\n流量路由。我们使用`Istio`中`DestinationRule`去通过version分离我们的服务。\n\n```yaml\napiVersion: networking.istio.io/v1alpha3\nkind: DestinationRule\nmetadata:\n  name: catalog\nspec:\n  host: catalog\n  subsets:\n  - name: version-v1\n    labels:\n      version: v1\n  - name: version-v2\n    labels:\n      version: v2\n```\n\n我们安装一个v2版本的`catalog`，内容如下：\n\n```yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  labels:\n    app: catalog\n    version: v2\n  name: catalog-v2\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: catalog\n      version: v2\n  template:\n    metadata:\n      labels:\n        app: catalog\n        version: v2\n    spec:\n      containers:\n      - env:\n        - name: KUBERNETES_NAMESPACE\n          valueFrom:\n            fieldRef:\n              fieldPath: metadata.namespace\n        - name: SHOW_IMAGE\n          value: \"true\"\n        image: istioinaction/catalog:latest\n        imagePullPolicy: IfNotPresent\n        name: catalog\n        ports:\n        - containerPort: 3000\n          name: http\n          protocol: TCP\n        securityContext:\n          privileged: false\n```\n\n执行安装：\n\n```shell\n[root@biz-master-48 ~]# kubectl apply -f book-source-code/services/catalog/kubernetes/catalog-deployment-v2.yaml \ndeployment.apps/catalog-v2 created\n[root@biz-master-48 ~]# kubectl get po\nNAME                         READY   STATUS    RESTARTS   AGE\ncatalog-68666d4988-7qwd9     2/2     Running   0          5h25m\ncatalog-v2-86854b8c7-v5ghx   2/2     Running   0          12s\nwebapp-7f47f74b9d-tbtbf      2/2     Running   0          3h32m\n```\n\n安装 `catalog`对应的`DestinationRule`\n\n```shell\n[root@biz-master-48 ~]# kubectl apply -f book-source-code/ch2/catalog-destinationrule.yaml \ndestinationrule.networking.istio.io/catalog created\n[root@biz-master-48 ~]#\n```\n\n如果我们访问`catalog`服务很多次，我们会发现一些请求的响应包含了一个新的`imageUrl`属性。`imageUrl`是`catalog-v2` 版本中新增加的字，如：\n\n```shell\n[root@biz-master-48 ~]# kubectl get svc\nNAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE\ncatalog   ClusterIP   10.21.137.250   \u003cnone\u003e        80/TCP         2d22h\nwebapp    NodePort    10.21.222.196   \u003cnone\u003e        80:31561/TCP   2d20h\n[root@biz-master-48 ~]# curl 10.21.137.250/items/1\n{\n  \"id\": 1,\n  \"color\": \"amber\",\n  \"department\": \"Eyewear\",\n  \"name\": \"Elinor Glasses\",\n  \"price\": \"282.00\"\n}[root@biz-master-48 ~]# curl 10.21.137.250/items/1\n{\n  \"id\": 1,\n  \"color\": \"amber\",\n  \"department\": \"Eyewear\",\n  \"name\": \"Elinor Glasses\",\n  \"price\": \"282.00\",\n  \"imageUrl\": \"http://lorempixel.com/640/480\"\n```\n\n接下来，我们创建一个`catalog` `VirtualService` 将所有访问`catalog`的流量打到`catalog`的`v1`版本，`VirtualService`的定义如下。\n\n```yaml\napiVersion: networking.istio.io/v1alpha3\nkind: VirtualService\nmetadata:\n  name: catalog\nspec:\n  hosts:\n  - catalog\n  http:\n  - route:\n    - destination:\n        host: catalog\n        subset: version-v1\n```\n\napply 这个yaml\n\n我们再次访问`catalog`，通过 `webapp`的svc ip访问，`webapp`的`svc ip`为`10.21.222.196`\n\n```shell\n[root@biz-master-48 ~]# kubectl get svc\nNAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE\ncatalog   ClusterIP   10.21.137.250   \u003cnone\u003e        80/TCP         2d22h\nwebapp    NodePort    10.21.222.196   \u003cnone\u003e        80:31561/TCP   2d20h\n```\n\n```shell\nwhile true; do curl http://10.21.222.196/api/catalog | python -m json.tool ; sleep .5 ; done \n```\n\n效果如下\n\n```shell\n[root@biz-master-48 ~]# while true; do curl http://10.21.222.196/api/catalog | python -m json.tool ; sleep .5 ; done  \n  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n                                 Dload  Upload   Total   Spent    Left  Speed\n100   357  100   357    0     0  63568      0 --:--:-- --:--:-- --:--:-- 71400\n[\n    {\n        \"color\": \"amber\",\n        \"department\": \"Eyewear\",\n        \"id\": 1,\n        \"name\": \"Elinor Glasses\",\n        \"price\": \"282.00\"\n    },\n    {\n        \"color\": \"cyan\",\n        \"department\": \"Clothing\",\n        \"id\": 2,\n        \"name\": \"Atlas Shirt\",\n        \"price\": \"127.00\"\n    },\n    {\n        \"color\": \"teal\",\n        \"department\": \"Clothing\",\n        \"id\": 3,\n        \"name\": \"Small Metal Shoes\",\n        \"price\": \"232.00\"\n    },\n    {\n        \"color\": \"red\",\n        \"department\": \"Watches\",\n        \"id\": 4,\n        \"name\": \"Red Dragon Watch\",\n        \"price\": \"232.00\"\n    }\n]\n```\n\n从上面的结果可知，所有的流量都打到`catalog v1`版本上面去了。\n\n我们再修改一下`VirtualService`，当访问`catalog`时指定了某个定义的header，那么就访问v2版本，否则访问v1版本。\n\n```yaml\napiVersion: networking.istio.io/v1alpha3\nkind: VirtualService\nmetadata:\n  name: catalog\nspec:\n  hosts:\n  - catalog\n  http:\n  - match:\n    - headers:\n        x-dark-launch:\n          exact: \"v2\"\n    route:\n    - destination:\n        host: catalog\n        subset: version-v2\n  - route:\n    - destination:\n        host: catalog\n        subset: version-v1\n```\n\napply 这个yaml\n\n我们再次访问`catalog`\n\n```shell\n[root@biz-master-48 ~]# kubectl apply -f book-source-code/ch2/catalog-virtualservice-dark-v2.yaml \nvirtualservice.networking.istio.io/catalog configured\n[root@biz-master-48 ~]# while true; do curl http://10.21.222.196/api/catalog -H \"x-dark-launch: v2\" | python -m json.tool ; sleep .5 ; done \n  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n                                 Dload  Upload   Total   Spent    Left  Speed\n100   529  100   529    0     0  10809      0 --:--:-- --:--:-- --:--:-- 11020\n[\n    {\n        \"color\": \"amber\",\n        \"department\": \"Eyewear\",\n        \"id\": 1,\n        \"imageUrl\": \"http://lorempixel.com/640/480\",\n        \"name\": \"Elinor Glasses\",\n        \"price\": \"282.00\"\n    },\n    {\n        \"color\": \"cyan\",\n        \"department\": \"Clothing\",\n        \"id\": 2,\n        \"imageUrl\": \"http://lorempixel.com/640/480\",\n        \"name\": \"Atlas Shirt\",\n        \"price\": \"127.00\"\n    },\n    {\n        \"color\": \"teal\",\n        \"department\": \"Clothing\",\n        \"id\": 3,\n        \"imageUrl\": \"http://lorempixel.com/640/480\",\n        \"name\": \"Small Metal Shoes\",\n        \"price\": \"232.00\"\n    },\n    {\n        \"color\": \"red\",\n        \"department\": \"Watches\",\n        \"id\": 4,\n        \"imageUrl\": \"http://lorempixel.com/640/480\",\n        \"name\": \"Red Dragon Watch\",\n        \"price\": \"232.00\"\n    }\n]\n```\n\nok，符合期望。\n\n至此，简单的demo已完成，我们清理一些资源\n\n```shell\n[root@biz-master-48 ~]# kubectl delete deploy,svc,gateway,vs,dr --all -n istioinaction\ndeployment.apps \"catalog\" deleted\ndeployment.apps \"catalog-v2\" deleted\ndeployment.apps \"nginx-deployment\" deleted\ndeployment.apps \"webapp\" deleted\nservice \"catalog\" deleted\nservice \"webapp\" deleted\ngateway.networking.istio.io \"outfitters-gateway\" deleted\nvirtualservice.networking.istio.io \"catalog\" deleted\nvirtualservice.networking.istio.io \"webapp-virtualservice\" deleted\ndestinationrule.networking.istio.io \"catalog\" deleted\n```\n\n#### Istio's data plane: The Envoy proxy\n\n本章节内容\n\n- 理解`Envoy` proxy\n- 了解`Envoy`在istio中有什么核心能力\n- 使用静态配置配置`Envoy`\n- 使用`Envoy` Admin API 进行debug\n\n##### What is  the Envoy proxy?\n\n`Envoy`从2016年开始开源，由2017年加入CNCF。\n\n**`Envoy`有两个重要的原则**：\n\n**（1）网络对应用来说应该是透明的**\n\n**（2）当发生网络和应用的问题时，可以很简单的找到原因**\n\n`Envoy` 是一个代理，所以在探索它之前，我们先了解一下什么是代理。我们之前提到了代理（`proxy`）在网络架构中是一个处于client和server中间的一个媒介，如下图。由于它是中间件，所以它可以提供一些额外的特性，如security、privacy和policy。\n\n![image-20220328141154042](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220328141154042.png)\n\n`Envoy`proxy具体地说是一个应用级别的代理。`Envoy`可以理解应用程序在与其他服务通信时可能使用的第7层协议。\n\n作为代理，envoy旨在通过运行应用程序之外的进程来保护开发人员免受网络问题的影响。\n\n###### Envoy's core features\n\n`Envoy`有很多的特性。当了解这些特性之前，我们先熟悉以下`Envoy`的概念：\n\n`Listeners`: 就是端口。暴露一个应用可以连接的外部端口\n\n`Routes`: 就是路由规则。路由规则用于如何处理传入`Listeners`的流量\n\n`Clusters`: 就是具体的应用服务的service。Envoy可以路由流量到的特定上游服务\n\n![image-20220328150141654](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220328150141654.png)\n\n`Downstream`：如果A服务访问B服务，那么A服务就是downstream\n\n`Upstream`：如果A服务访问B服务，那么B服务就是upstream\n\n\u003cu\u003eout of the box（开箱即用）\u003c/u\u003e\n\n###### Comparing Envoy to other proxies\n\n`Envoy`在以下方面比其他的代理表现的更加出色：\n\n- 对WebAssembly更据扩展性\n- 开源\n- 支持HTTP 2.0\n- 很深的协议指标收集\n- C++编写\n- 动态配置，不需要热加载\n\n##### Configuring Envoy\n\n`Envoy`的配置文件可以是`JSON`或者`YAML`类型格式。`Envoy`的配置文件指定`listeners`，`routes`，`clusters`以及服务端配置，比如：是否开启`Admin API`，访问日志应该放在哪里，链路追踪的配置等等。`Envoy`有好几个版本，本书中使用v3版本。\n\n`Envoy v3`配置API构建在gRPC之上。\n\n###### Static configuration\n\n我们可以指定`listeners`，`routes`，`clusters`使用配置文件。\n\n![image-20220328164139519](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220328164139519.png)\n\n###### Dynamic configuration\n\n`Envoy`可以使用一系列的APIs去做内置配置的更新。\n\n`Envoy`使用以下APIs去做动态配置：\n\n- Listener discovery service（LDS）：它是一个允许`Envoy`去查找什么`listeners`应该被暴露在这个代理的API\n- Route discovery service（RDS）：它是`listeners`配置中配置哪个`route`被使用的API\n- Cluster discovery service（CDS）：\n- Endpoint  discovery service（EDS）：\n- Secret  discovery service（EDS）：\n- Aggregate discovery service（ADS）：\n\n以上所有的APIs都是作为`xDS`服务被引用的。\n\n##### Envoy in action\n\n`Envoy`以C++编写且编译在指定环境中。所以入门`Envoy`最好的方式是启动一个docker 容器。\n\n```shell\ndocker pull envoyproxy/envoy:v1.19.0\ndocker pull curlimages/curl\ndocker pull citizenstig/httpbin\n```\n\n`httpbin`：就是用于查看我发出去的请求到底是什么样子的。地址：http://httpbin.org/\n\n一旦我们启动了httpbin服务，我们将启动envoy并配置它来代理所有的流量到httpbin服务。然后，我们将开启一个client 应用去调用这个代理。\n\n![image-20220328173004611](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220328173004611.png)\n\n启动`httpbin`\n\n```shell\n[root@biz-master-48 mark]# docker run -d --name httpbin citizenstig/httpbin\n81dbbef2009f5173e2fccbe0a2c022656d55ba4f6fd2ae77acd4d5f66c40074f\n```\n\n访问`httpbin`服务\n\n```shell\n[root@biz-master-48 ~]# docker run -it --rm --link httpbin curlimages/curl \\ curl  http://httpbin:8000/headers\ncurl: (3) URL using bad/illegal format or missing URL\n{\n  \"headers\": {\n    \"Accept\": \"*/*\", \n    \"Host\": \"httpbin:8000\", \n    \"User-Agent\": \"curl/7.82.0-DEV\"\n  }\n}\n```\n\n`docker --link`可以通过容器名互相通信，容器间共享环境变量。\n`docker --link`主要用来解决两个容器通过ip地址连接时`容器ip地址`会变的问题.\n\n启动`Envoy`\n\n```shell\n# 查看envoy支持的命令参数\ndocker run -it --rm envoyproxy/envoy:v1.19.0 envoy --help\n# 启动envoy\ndocker run -it --rm envoyproxy/envoy:v1.19.0 envoy\n```\n\n我们发现启动报错了\n\n```shell\n[2022-03-28 09:46:13.218][1][critical][main] [source/server/server.cc:112] error initializing configuration '': At least one of --config-path or --config-yaml or Options::configProto() should be non-empty\n[2022-03-28 09:46:13.218][1][info][main] [source/server/server.cc:855] exiting\nAt least one of --config-path or --config-yaml or Options::configProto() should be non-empty\n```\n\n发生了啥？我们尝试启动`proxy`，但是我们没用传递一个有效的配置文件。为了修复这个报错，我们运行的时候指定以下这个配置。\n\n```yaml\nadmin:\n  address:\n    socket_address: { address: 0.0.0.0, port_value: 15000 }\n\nstatic_resources:\n  listeners:\n  - name: httpbin-demo\n    address:\n      socket_address: { address: 0.0.0.0, port_value: 15001 }\n    filter_chains:\n    - filters:\n      - name:  envoy.filters.network.http_connection_manager\n        typed_config:\n          \"@type\": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager\n          stat_prefix: ingress_http\n          http_filters:\n          - name: envoy.filters.http.router\n          route_config:\n            name: httpbin_local_route\n            virtual_hosts:\n            - name: httpbin_local_service\n              domains: [\"*\"]\n              routes:\n              - match: { prefix: \"/\" }\n                route:\n                  auto_host_rewrite: true\n                  cluster: httpbin_service\n  clusters:\n    - name: httpbin_service\n      connect_timeout: 5s\n      type: LOGICAL_DNS\n      dns_lookup_family: V4_ONLY\n      lb_policy: ROUND_ROBIN\n      load_assignment:\n        cluster_name: httpbin\n        endpoints:\n        - lb_endpoints:\n          - endpoint:\n              address:\n                socket_address:\n                  address: httpbin\n                  port_value: 8000\n```\n\n大体上，我们暴露了一个单独的`listener`在15001端口，然后路由所有的流量到httpbin实例上。我们再次启动`Envoy`\n\n```shell\n[root@biz-master-48 ~]# docker run -d --name envoy --link httpbin envoyproxy/envoy:v1.19.0  --config-yaml \"$(cat book-source-code/ch3/simple.yaml)\"\n641837d5fa2ef391b9f590150d7fde05c6e94dfb2c431f8bf8fcc6000b21e1db\n[root@biz-master-48 ~]# docker logs -f 641837d5fa2ef391b9f590150d7fde05c6e94dfb2c431f8bf8fcc6000b21e1db\n[2022-03-28 10:24:08.919][1][info][main] [source/server/server.cc:785] all clusters initialized. initializing init manager\n[2022-03-28 10:24:08.919][1][info][config] [source/server/listener_manager_impl.cc:834] all dependencies initialized. starting workers\n[2022-03-28 10:24:08.920][1][info][main] [source/server/server.cc:804] starting main dispatch loop\n```\n\n这个`Envoy`proxy成功的监听在15001端口，让我们使用curl容器去调用这个服务：\n\n```shell\n[root@biz-master-48 ~]# docker run -it --rm --link envoy curlimages/curl \\ curl http://envoy:15001/headers\ncurl: (3) URL using bad/illegal format or missing URL\n{\n  \"headers\": {\n    \"Accept\": \"*/*\", \n    \"Host\": \"httpbin\", \n    \"User-Agent\": \"curl/7.82.0-DEV\", \n    \"X-Envoy-Expected-Rq-Timeout-Ms\": \"15000\", \n    \"X-Request-Id\": \"eaec3279-1fe9-4489-837b-d50676b694a0\"\n  }\n}\n```\n\n即使我们调用了代理，流量也被正确地发送到httpbin服务。\n\n- X-Envoy-Expected-Rq-Timeout-Ms\n- X-Request-Id\n\n它生成了一个新的X-Request-Id，该id可用于将跨集群的请求关联起来，并可能用于跨服务的多个跳转来满足请求。\n\n###### Envoy‘s Admin API\n\n为了探索`Envoy`的更多功能，让我们熟悉一下`Envoy`的管理API。 \n\n如查看clusters：\n\n```shell\ndocker run -it --rm --link envoy curlimages/curl \\ curl http://envoy:15000/clusters\n```\n\n```shell\n[root@biz-master-48 ~]# docker run -it --rm --link envoy curlimages/curl \\ curl http://envoy:15000/clusters\ncurl: (3) URL using bad/illegal format or missing URL\nhttpbin_service::observability_name::httpbin_service\nhttpbin_service::default_priority::max_connections::1024\nhttpbin_service::default_priority::max_pending_requests::1024\nhttpbin_service::default_priority::max_requests::1024\nhttpbin_service::default_priority::max_retries::3\nhttpbin_service::high_priority::max_connections::1024\nhttpbin_service::high_priority::max_pending_requests::1024\nhttpbin_service::high_priority::max_requests::1024\nhttpbin_service::high_priority::max_retries::3\nhttpbin_service::added_via_api::false\nhttpbin_service::172.18.18.2:8000::cx_active::0\nhttpbin_service::172.18.18.2:8000::cx_connect_fail::0\nhttpbin_service::172.18.18.2:8000::cx_total::1\nhttpbin_service::172.18.18.2:8000::rq_active::0\nhttpbin_service::172.18.18.2:8000::rq_error::0\nhttpbin_service::172.18.18.2:8000::rq_success::1\nhttpbin_service::172.18.18.2:8000::rq_timeout::0\nhttpbin_service::172.18.18.2:8000::rq_total::1\nhttpbin_service::172.18.18.2:8000::hostname::httpbin\nhttpbin_service::172.18.18.2:8000::health_flags::healthy\nhttpbin_service::172.18.18.2:8000::weight::1\nhttpbin_service::172.18.18.2:8000::region::\nhttpbin_service::172.18.18.2:8000::zone::\nhttpbin_service::172.18.18.2:8000::sub_zone::\nhttpbin_service::172.18.18.2:8000::canary::false\nhttpbin_service::172.18.18.2:8000::priority::0\nhttpbin_service::172.18.18.2:8000::success_rate::-1.0\nhttpbin_service::172.18.18.2:8000::local_origin_success_rate::-1.0\n```\n\n###### Envoy request retries\n\n##### How Envoy fits with Istio\n\n### Securing，observing，and controlling your service’s network traffic\n\n#### Istio gateways：Getting traffic into a cluster\n\n本章内容\n\n- 在集群中定义`entry points`\n- 在你的集群中路由ingress流量到deployment\n- 保护ingress流量\n- 路由非HTTP流量\n\n##### Traffic ingress concepts\n\n流量进入网络的时候，最开始是路由到像一个看门人一样的`ingress`端点。ingress端点加强了哪些流量可以被允许进入本地网络的规则和配置。\n\n###### Virtual IPs：Simplifying service access\n\n其实就是访问一个指定服务的时候，先访问的是一个代理，然后通过代理分发到实际的服务。好处在于高可用，然后有代理后，又可以做一些附加的操作，如LB。\n\n![image-20220329103256682](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220329103256682.png)\n\n###### Virtual hosting：Multiple services from a single access point\n\n在一个入口点托管多个不同的服务称为`virtual hosting`。一个入口托管多个不同服务，是说 多个域名使用同一个 IP 映射。然后多个client 就访问到同一个 reverse proxy了,那么 proxy怎么知道你访问的真实服务后端是哪个呢？答案是通过在请求头中加东西，让reverse proxy去识别。在不同的协议中，有不同的处理方式。\n\n总而言之，最重要的是我们在Istio中看到的边缘入口功能使用虚拟IP路由和虚拟主机将服务流量路由到集群中。\n\n![image-20220329104600457](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220329104600457.png)\n\n##### Istio ingress gateways\n\nistio入口网关(ingress gateway)充当网络的入口点，并使用`Envoy`代理(Envoy proxy)进行路由和负载均衡。\n\n![image-20220329110607736](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220329110607736.png)\n\n如果你想确认`Envoy proxy`确实是运行在`Istio ingress gateway`中，那么可以执行以下命令进行查看：\n\n```shell\n[root@biz-master-48 ~]# kubectl -n istio-system exec deploy/istio-ingressgateway -- ps\n  PID TTY          TIME CMD\n    1 ?        00:00:29 pilot-agent\n   15 ?        00:02:51 envoy\n   34 ?        00:00:00 ps\n```\n\n###### Specifying Gateway resources\n\n为了在istio中配置ingress gateway，我们使用`Gateway`资源指定想要开放的端口以及这些端口允许的虚拟主机（virtual hosts）。如下示例：\n\n```yaml\napiVersion: networking.istio.io/v1alpha3\nkind: Gateway\nmetadata:\n  name: coolstore-gateway\nspec:\n  selector:\n    istio: ingressgateway\n  servers:\n  - port:\n      number: 80\n      name: http\n      protocol: HTTP\n    hosts:\n    - \"webapp.istioinaction.io\"\n```\n\n查看我们集群的`istio-ingressgateway `service\n\n```bash\n[root@biz-master-48 ~]# kubectl get svc istio-ingressgateway -n istio-system\nNAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                 AGE\nistio-ingressgateway   LoadBalancer   10.21.154.138   \u003cpending\u003e     15021:31095/TCP,80:32619/TCP,443:32552/TCP,312699/TCP   6d\n```\n\n`istio-ingressgateway`的Service的Type是LoadBalancer, 它的`EXTERNAL-IP`处于`pending`状态， 这是因为我们目前的环境并没有可用于Istio Ingress Gateway外部的负载均衡器，为了使得可以从外部访问， 通过修改`istio-ingressgateway`这个Service的externalIps，因为当前Kubernetes集群的kube-proxy启用了ipvs，所以这个指定一个VIP `10.10.13.48`作为externalIp。\n\n```yaml\napiVersion: v1\nkind: Service\nmetadata:\n  annotations:\n    kubectl.kubernetes.io/last-applied-configuration: |\n      {\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"annotations\":{},\"labels\":{\"app\":\"istio-ingressgateway\",\"install.operator.istio.io/owning-resource\":\"unknown\",\"install.operator.istio.io/owning-resource-namespace\":\"istio-system\",\"istio\":\"ingressgateway\",\"istio.io/rev\":\"default\",\"operator.istio.io/component\":\"IngressGateways\",\"operator.istio.io/managed\":\"Reconcile\",\"operator.istio.io/version\":\"1.13.0\",\"release\":\"istio\"},\"name\":\"istio-ingressgateway\",\"namespace\":\"istio-system\"},\"spec\":{\"ports\":[{\"name\":\"status-port\",\"port\":15021,\"protocol\":\"TCP\",\"targetPort\":15021},{\"name\":\"http2\",\"port\":80,\"protocol\":\"TCP\",\"targetPort\":8080},{\"name\":\"https\",\"port\":443,\"protocol\":\"TCP\",\"targetPort\":8443},{\"name\":\"tcp\",\"port\":31400,\"protocol\":\"TCP\",\"targetPort\":31400},{\"name\":\"tls\",\"port\":15443,\"protocol\":\"TCP\",\"targetPort\":15443}],\"selector\":{\"app\":\"istio-ingressgateway\",\"istio\":\"ingressgateway\"},\"type\":\"LoadBalancer\"}}\n  creationTimestamp: \"2022-03-25T02:24:23Z\"\n  labels:\n    app: istio-ingressgateway\n    install.operator.istio.io/owning-resource: unknown\n    install.operator.istio.io/owning-resource-namespace: istio-system\n    istio: ingressgateway\n    istio.io/rev: default\n    operator.istio.io/component: IngressGateways\n    operator.istio.io/managed: Reconcile\n    operator.istio.io/version: 1.13.0\n    release: istio\n  name: istio-ingressgateway\n  namespace: istio-system\n  resourceVersion: \"1106775\"\n  uid: a4651af9-15d2-4840-9ce1-7fdc615ff9b4\nspec:\n  clusterIP: 10.21.154.138\n  clusterIPs:\n  - 10.21.154.138\n  externalIPs:\n  - 10.10.13.48\n  externalTrafficPolicy: Cluster\n  ipFamilies:\n  - IPv4\n  ipFamilyPolicy: SingleStack\n  ports:\n  - name: status-port\n    nodePort: 31095\n    port: 15021\n    protocol: TCP\n    targetPort: 15021\n  - name: http2\n    nodePort: 32619\n    port: 80\n    protocol: TCP\n    targetPort: 8080\n  - name: https\n    nodePort: 32552\n    port: 443\n    protocol: TCP\n    targetPort: 8443\n  - name: tcp\n    nodePort: 30481\n    port: 31400\n    protocol: TCP\n    targetPort: 31400\n  - name: tls\n    nodePort: 32699\n    port: 15443\n    protocol: TCP\n    targetPort: 15443\n  selector:\n    app: istio-ingressgateway\n    istio: ingressgateway\n  sessionAffinity: None\n  type: LoadBalancer\n```\n\n如上：\n\n```yaml\nexternalIPs:\n  - 10.10.13.48\n```\n\n###### Gateway routing with virtual services\n\n`virtual service`允许我们将流量从`ingress gateway`打到指定的`service`\n\n###### Istio ingress gateway vs. Kubernetes Ingress\n\n![image-20220331145315083](C:\\Users\\mark\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220331145315083.png)\n\nk8s ingress仅支持支持http，而且只支持80和443端口作为ingress端点。\n\n像kafka这种需要支持tcp直连的消息队列来说，k8s的ingress不能支持。\n\n###### Istio ingress gateway vs. API gateways\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmark8s%2Fistio-in-action","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmark8s%2Fistio-in-action","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmark8s%2Fistio-in-action/lists"}