Istio入門實戰與架構原理——使用Docker Compose搭建Service Mesh

来源:https://www.cnblogs.com/skabyy/archive/2019/04/08/10668079.html
-Advertisement-
Play Games

本文將介紹如何使用Docker Compose搭建Istio。Istio號稱支持多種平臺(不僅僅Kubernetes)。然而,官網上非基於Kubernetes的教程仿佛不是親兒子,寫得非常隨便,不僅缺了一些內容,而且還有坑。本文希望能補實這些內容。我認為在學習Istio的過程中,相比於Kuberne ...


本文將介紹如何使用Docker Compose搭建Istio。Istio號稱支持多種平臺(不僅僅Kubernetes)。然而,官網上非基於Kubernetes的教程仿佛不是親兒子,寫得非常隨便,不僅缺了一些內容,而且還有坑。本文希望能補實這些內容。我認為在學習Istio的過程中,相比於Kubernetes,使用Docker Compose部署更能深刻地理解Istio各個組件的用處以及他們的交互關係。在理解了這些後,可以在其他環境,甚至直接在虛擬機上部署Istio。當然,生產環境建議使用Kubernetes等成熟的容器框架

本文使用官方的Bookinfo示例。通過搭建Istio控制平面,部署Bookinfo應用,最後配置路由規則,展示Istio基本的功能和架構原理。

本文涉及的名詞、用到的埠比較多。Don't panic.

為了防止不提供原網址的轉載,特在這裡加上原文鏈接:
https://www.cnblogs.com/skabyy/p/10668079.html

準備工作

  1. 安裝Docker和Docker Compose。
  2. 安裝kubectl(Kubernetes的客戶端)。
  3. 下載Istio release 1.1.0並解壓。註意,這裡下載的是Linux的版本。即使你用的Windows或者OSX操作系統,也應該下載Linux版本的Istio,因為我們要放到Docker容器里去運行的。

Service Mesh架構

在微服務架構中,通常除了實現業務功能的微服務外,我們還會部署一系列的基礎組件。這些基礎組件有些會入侵微服務的代碼。比如服務發現需要微服務啟動時註冊自己,鏈路跟蹤需要在HTTP請求的headers中插入數據,流量控制需要一整套控制流量的邏輯等。這些入侵的代碼需要在所有的微服務中保持一致。這導致了開發和管理上的一些難題。

為瞭解決這個問題,我們再次應用抽象和服務化的思想,將這些需要入侵的功能抽象出來,作為一個獨立的服務。這個獨立的服務被稱為sidecar,這種模式叫Sidecar模式。對每個微服務節點,都需要額外部署一個sidecar來負責業務邏輯外的公共功能。所有的出站入站的網路流量都會先經過sidecar進行各種處理或者轉發。這樣微服務的開發就不需要考慮業務邏輯外的問題。另外所有的sidecar都是一樣的,只需要部署的時候使用合適的編排工具即可方便地為所有節點註入sidecar。

Sidecar不會產生額外網路成本。Sidecar會和微服務節點部署在同一臺主機上並且共用相同的虛擬網卡。所以sidecar和微服務節點的通信實際上都只是通過記憶體拷貝實現的。

圖片來自:Pattern: Service Mesh

Sidecar只負責網路通信。還需要有個組件來統一管理所有sidecar的配置。在Service Mesh中,負責網路通信的部分叫數據平面(data plane),負責配置管理的部分叫控制平面(control plane)。數據平面和控制平面構成了Service Mesh的基本架構。

圖片來自:Pattern: Service Mesh

Istio的數據平面主要由Envoy實現,控制平面則主要由Istio的Pilot組件實現。

部署控制平面

如果你使用Linux操作系統,需要先配置DOCKER_GATEWAY環境變數。非Linux系統不要配。

$ export DOCKER_GATEWAY=172.28.0.1:

install/consul目錄下,使用istio.yaml文件啟動控制平面:

根據自己的網路情況(你懂得),可以把istio.yaml中的鏡像gcr.io/google_containers/kube-apiserver-amd64:v1.7.3換成mirrorgooglecontainers/kube-apiserver-amd64:v1.7.3

$ docker-compose -f istio.yaml up -d

用命令docker-compose -f istio.yaml ps看一下是不是所有組件正常運行。你可能(大概率)會看到pilot的狀態是Exit 255。使用命令docker-compose -f istio.yaml logs | grep pilot查看日誌發現,pilot啟動時訪問istio-apiserver失敗。這是因為Docker Compose是同時啟動所有容器的,在pilot啟動時,istio-apiserver也是處於啟動狀態,所以訪問istio-apiserver就失敗了。

istio-apiserver啟動完成後,重新運行啟動命令就能成功啟動pilot了。你也可以寫一個腳本來自動跑兩次命令:

docker-compose -f istio.yaml up -d
# 有些依賴別人的第一次啟動會掛
sec=10  # 根據你的機器性能這個時間可以修改
echo "Wait $sec seconds..."
sleep $sec
docker-compose -f istio.yaml up -d
docker-compose -f istio.yaml ps

配置kubectl,讓kubectl使用我們剛剛部署的istio-apiserver作為服務端。我們後面會使用kubectl來執行配置管理的操作。

$ kubectl config set-context istio --cluster=istio
$ kubectl config set-cluster istio --server=http://localhost:8080
$ kubectl config use-context istio

部署完成後,使用地址localhost:8500可以訪問consul,使用地址localhost:9411可以訪問zipkin

控制平面架構

在下一步之前,我們先來看一下控制平面都由哪些組件組成。下麵是istio.yaml文件的內容:

# GENERATED FILE. Use with Docker-Compose and consul
# TO UPDATE, modify files in install/consul/templates and run install/updateVersion.sh
version: '2'
services:
  etcd:
    image: quay.io/coreos/etcd:latest
    networks:
      istiomesh:
        aliases:
          - etcd
    ports:
      - "4001:4001"
      - "2380:2380"
      - "2379:2379"
    environment:
      - SERVICE_IGNORE=1
    command: ["/usr/local/bin/etcd", "-advertise-client-urls=http://0.0.0.0:2379", "-listen-client-urls=http://0.0.0.0:2379"]

  istio-apiserver:
    # 如果這個鏡像下載不了的話,可以換成下麵的地址:
    # image: mirrorgooglecontainers/kube-apiserver-amd64:v1.7.3
    image: gcr.io/google_containers/kube-apiserver-amd64:v1.7.3
    networks:
      istiomesh:
        ipv4_address: 172.28.0.13
        aliases:
          - apiserver
    ports:
      - "8080:8080"
    privileged: true
    environment:
      - SERVICE_IGNORE=1
    command: ["kube-apiserver", "--etcd-servers", "http://etcd:2379", "--service-cluster-ip-range", "10.99.0.0/16", "--insecure-port", "8080", "-v", "2", "--insecure-bind-address", "0.0.0.0"]

  consul:
    image: consul:1.3.0
    networks:
      istiomesh:
        aliases:
          - consul
    ports:
      - "8500:8500"
      - "${DOCKER_GATEWAY}53:8600/udp"
      - "8400:8400"
      - "8502:8502"
    environment:
      - SERVICE_IGNORE=1
      - DNS_RESOLVES=consul
      - DNS_PORT=8600
      - CONSUL_DATA_DIR=/consul/data
      - CONSUL_CONFIG_DIR=/consul/config
    entrypoint:
      - "docker-entrypoint.sh"
    command: ["agent", "-bootstrap", "-server", "-ui",
              "-grpc-port", "8502"
              ]
    volumes:
      - ./consul_config:/consul/config

  registrator:
    image: gliderlabs/registrator:latest
    networks:
      istiomesh:
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock
    command: ["-internal", "-retry-attempts=-1", "consul://consul:8500"]

  pilot:
    image: docker.io/istio/pilot:1.1.0
    networks:
      istiomesh:
        aliases:
          - istio-pilot
    expose:
      - "15003"
      - "15005"
      - "15007"
    ports:
      - "8081:15007"
    command: ["discovery",
              "--httpAddr", ":15007",
              "--registries", "Consul",
              "--consulserverURL", "http://consul:8500",
              "--kubeconfig", "/etc/istio/config/kubeconfig",
              "--secureGrpcAddr", "",
              ]
    volumes:
      - ./kubeconfig:/etc/istio/config/kubeconfig

  zipkin:
    image: docker.io/openzipkin/zipkin:2.7
    networks:
      istiomesh:
        aliases:
          - zipkin
    ports:
      - "9411:9411"

networks:
  istiomesh:
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16
          gateway: 172.28.0.1

控制平面部署了這幾個組件(使用istio.yaml里寫的名稱):

  • etcd:分散式key-value存儲。Istio的配置信息存在這裡。
  • istio-apiserver:實際上是一個kube-apiserver,提供了Kubernetes格式數據的讀寫介面。
  • consul:服務發現。
  • registrator:監聽Docker服務進程,自動將容器註冊到consul
  • pilot:從consulistio-apiserver收集主機信息與配置數據,並下發到所有的sidecar。
  • zipkin:鏈路跟蹤組件。與其他組件的關係相對獨立。

這些組件間的關係如下圖:

控制平面主要實現了以下兩個功能:

  • 借用Kubernetes API管理配置數據etcdkube-apiserver的組合可以看作是一個對象存儲系統,它提供了讀寫介面和變更事件,並且可以直接使用kubectl作為客戶端方便地進行操作。Istio直接使用這個組合作為控制平面的持久化層,節省了重覆開發的麻煩,另外也相容了Kubernetes容器框架。
  • 使用Pilot-discovery將主機信息與配置數據同步到Envoypilot容器中實際執行的是pilot-discovery(發現服務)。它從consul收集各個主機的功能變數名稱和IP的對應關係,從istio-apiserver獲取流量控制配置,然後按照Envoy的xDS API規範生成Envoy配置,下發到所有sidecar。

部署微服務和sidecar

接下來我們開始部署微服務。這裡我們使用Istio提供的例子,一個Bookinfo應用

Bookinfo 應用分為四個單獨的微服務:

  • productpageproductpage微服務會調用detailsreviews兩個微服務,用來生成頁面。
  • details:這個微服務包含了書籍的信息。
  • reviews:這個微服務包含了書籍相關的評論。它還會調用ratings微服務。
  • ratingsratings微服務中包含了由書籍評價組成的評級信息。

reviews微服務有3個版本:

  • v1版本不會調用ratings服務。
  • v2版本會調用ratings服務,並使用1到5個黑色星形圖標來顯示評分信息。
  • v3版本會調用ratings服務,並使用1到5個紅色星形圖標來顯示評分信息。

Bookinfo應用的架構如下圖所示:

圖片來自:Bookinfo應用

首先,我們切換到這個示例的目錄samples/bookinfo/platform/consul下。

使用bookinfo.yaml文件啟動所有微服務:

$ docker-compose -f bookinfo.yaml up -d

這裡只啟動了微服務,還需使用bookinfo.sidecar.yaml文件啟動所有sidecar:

$ docker-compose -f bookinfo.sidecars.yaml up -d

部署完畢。但是當我們訪問時……

Bookinfo暴露到外面的埠是9081,使用地址localhost:9081/productpage訪問productpage頁面。

Emmm……出錯了:

本來應該顯示reviews的部分報錯了,而details還是正常的。經過一番排查,我們發現,在所有微服務的容器上,不管你訪問的是productpagedetailsreviews還是ratings,網路請求都會跑到details

你的情況不一定是details,也有可能所有流量都跑到另外的某個服務。這是隨機的。

# 到reviews查reviews,返回404
$ docker exec -it consul_ratings-v1_1 curl reviews.service.consul:9080/reviews/0
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
  <HEAD><TITLE>Not Found</TITLE></HEAD>
  <BODY>
    <H1>Not Found</H1>
    `/reviews/0' not found.
    <HR>
    <ADDRESS>
     WEBrick/1.3.1 (Ruby/2.3.8/2018-10-18) at
     reviews.service.consul:9080
    </ADDRESS>
  </BODY>
</HTML>

# 到reviews查details,反倒能查出數據,詭異的路由……
$ docker exec -it consul_ratings-v1_1 curl reviews.service.consul:9080/details/0
{"id":0,"author":"William Shakespeare","year":1595,"type":"paperback","pages":200,"publisher":"PublisherA","language":"English","ISBN-10":"1234567890","ISBN-13":"123-1234567890"}

不用懷疑部署的時候哪裡操作失誤了,就是官方的部署文件有坑……

要解決這個問題,我們來看看sidecar的原理。

Istio Sidecar模式的原理

首先看看兩個部署用的yaml文件都做了什麼。由於每個微服務的部署都大同小異,這裡只貼出productpage相關的內容。

bookinfo.yaml

version: '2'
services:
  ……
  productpage-v1:
    image: istio/examples-bookinfo-productpage-v1:1.10.1
    networks:
      istiomesh:
        ipv4_address: 172.28.0.14
    dns:
      - 172.28.0.1
      - 8.8.8.8
    dns_search:
        - service.consul
    environment:
      - SERVICE_NAME=productpage
      - SERVICE_TAGS=version|v1
      - SERVICE_PROTOCOL=http
    ports:
      - "9081:9080"
    expose:
      - "9080"
  ……
  • dns_search: - search.consul。Docker Compose部署的這套樣例對短服務主機名的解析可能會有問題,所以這裡需要加個尾碼。
  • environment環境變數的幾個設置。registrator會以這些環境變數為配置將服務註冊到consulSERVICE_NAME是註冊的服務名,SERVICE_TAGS是註冊服務的ServiceTags,而SERVICE_PROTOCOL=http則會將protocol: http加入到ServiceMeta

bookinfo.sidecar.yaml

version: '2'
services:
  ……
  productpage-v1-init:
    image: docker.io/istio/proxy_init:0.7.1
    cap_add:
      - NET_ADMIN
    network_mode: "container:consul_productpage-v1_1"
    command:
      - -p
      - "15001"
      - -u
      - "1337"
  productpage-v1-sidecar:
    image: docker.io/istio/proxy_debug:1.1.0
    network_mode: "container:consul_productpage-v1_1"
    entrypoint:
      - su
      - istio-proxy
      - -c
      - "/usr/local/bin/pilot-agent proxy --serviceregistry Consul --serviceCluster productpage-v1 --zipkinAddress zipkin:9411 --configPath /var/lib/istio >/tmp/envoy.log"
  ……
  • sidecar由兩部分組成,一個是負責初始化的proxy_init,這個容器執行完就退出了;另一個是實際的sidecar程式proxy_debug
  • 註意這兩個容器的network_mode,值為container:consul_productpage-v1_1。這是Docker的容器網路模式,意思是這兩個容器和productpage-v1共用同一個虛擬網卡,即它們在相同網路棧上。

proxy_init

sidecar的網路代理一般是將一個埠轉發到另一個埠。所以微服務使用的埠就必須和對外暴露的埠不一樣,這樣一來sidecar就不夠透明。

為了使sidecar變得透明,以Istio使用proxy_init設置了iptables的轉發規則(proxy_initproxy_debugproductpage-v1在相同的網路棧上,所以這個配置對這三個容器都生效)。添加的規則為:

  1. 迴環網路的流量不處理。
  2. 用戶ID為1337的流量不處理。1337是Envoy進程的用戶ID,這條規則是為了防止流量轉發死迴圈。
  3. 所有出站入站的流量除了規則1和規則2外,都轉發到15001埠——這是Envoy監聽的埠。

比如productpage服務使用的9080埠,當其他服務通過9080埠訪問productpage是,請求會先被iptables轉發到15001埠,Envoy再根據路由規則轉發到9080埠。這樣訪問9080的流量實際上都在15001繞了一圈,但是對外部來說,這個過程是透明的。

proxy_debug

proxy_debug有兩個進程:pilot-agentenvoyproxy_debug啟動時,會先啟動pilot-agentpilot-agent做的事很簡單,它生成了envoy的初始配置文件/var/lib/istio/envoy-rev0.json,然後啟動envoy。後面的事就都交給envoy了。

使用下麵命令導出初始配置文件:

$ docker exec -it consul_productpage-v1-sidecar_1 cat /var/lib/istio/envoy-rev0.json > envoy-rev0.json

使用你心愛的編輯器打開初始配置文件,可以看到有這麼一段:

……
        "name": "xds-grpc",
        "type": "STRICT_DNS",
        "connect_timeout": "10s",
        "lb_policy": "ROUND_ROBIN",
        
        "hosts": [
          {
            "socket_address": {"address": "istio-pilot", "port_value": 15010}
          }
        ],
……

這一段的意思是envoy會連接到pilot(控制平面的組件,忘記了請往上翻翻)的15010埠。這倆將按照xDS的API規範,使用GRPC協議實時同步配置數據。

xDS是Envoy約定的一系列發現服務(Discovery Service)的統稱。如CDS(Cluster Discovery Service),EDS(Endpoint Discovery Service),RDS(Route Discovery Service)等。Envoy動態配置需要從實現了xDS規範的介面(比如這裡的pilot-discovery)獲取配置數據。

總結一下,Envoy配置初始化流程為:

圖片來自:Istio流量管理實現機制深度解析

那麼說envoy實際使用的路由配置並不在初始配置文件中,而是pilot生成並推送過來的。如何查看envoy的當前配置呢?還好envoy暴露了一個管理埠15000:

$ docker exec -it consul_productpage-v1-sidecar_1 curl localhost:15000/help
admin commands are:
  /: Admin home page
  /certs: print certs on machine
  /clusters: upstream cluster status
  /config_dump: dump current Envoy configs (experimental)
  /contention: dump current Envoy mutex contention stats (if enabled)
  /cpuprofiler: enable/disable the CPU profiler
  /healthcheck/fail: cause the server to fail health checks
  /healthcheck/ok: cause the server to pass health checks
  /help: print out list of admin commands
  /hot_restart_version: print the hot restart compatibility version
  /listeners: print listener addresses
  /logging: query/change logging levels
  /memory: print current allocation/heap usage
  /quitquitquit: exit the server
  /reset_counters: reset all counters to zero
  /runtime: print runtime values
  /runtime_modify: modify runtime values
  /server_info: print server version/status information
  /stats: print server stats
  /stats/prometheus: print server stats in prometheus format

我們可以通過/config_dump介面導出envoy的當前配置:

$ docker exec -it consul_productpage-v1-sidecar_1 curl localhost:15000/config_dump > envoy.json

打開這個配置,看到這麼一段:

……
     "listener": {
      "name": "0.0.0.0_9080",
      "address": {
       "socket_address": {
        "address": "0.0.0.0",
        "port_value": 9080
       }
      },
      "filter_chains": [
       {
        "filters": [
         {
          "name": "envoy.tcp_proxy",
          "typed_config": {
           "@type": "type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy",
           "stat_prefix": "outbound|9080||details.service.consul",
           "cluster": "outbound|9080||details.service.consul",
……

猜一下也能知道,這一段的意思是,訪問目標地址9080埠的出站流量,都會被路由到details。太坑了!!!

解決問題

從上面原理分析可知,這個問題的根源應該在於pilot給Envoy生成的配置不正確。

查看pilot源碼得知,pilot在生成配置時,用一個map保存Listener信息。這個map的key為<ip>:<port>。如果服務註冊的時候,沒有指明埠<port>上的協議的話,預設認為TCP協議。pilot會將這個Listener和路由寫入到這個map,並拒絕其他相同地址埠再來監聽。於是只有第一個註冊的服務的路由會生效,所有流量都會走到那個服務。如果這個埠有指定使用HTTP協議的話,Pilot-discovery這裡生成的是一個RDS的監聽,這個RDS則根據功能變數名稱路由到正確的地址。

簡單說就是所有微服務在註冊到consul時應該在ServiceMeta中說明自己9080埠的協議是http

等等,前面的bookinfo.yaml配置里,有指定9080埠的協議是了呀。我們訪問一下consul的介面看下ServiceMeta是寫入了沒有:

果然沒有……看來Registrator註冊的時候出了岔子。網上搜了下,確實有Issue提到了這個問題:gliderlabs/registrator#633istio.yaml中使用的latest版本的Registrator不支持寫入Consul的ServiceMeta。應該改為master版本

修改一下istio.yaml配置。按照部署倒敘關閉sidecar、微服務,重新啟動控制平面,等registrator啟動完畢後,重新部署微服務和sidecar。

# /samples/bookinfo/platform/consul
$ docker-compose -f bookinfo.sidecars.yaml down
$ docker-compose -f bookinfo.yaml down
# /install/consul
$ docker-compose -f istio.yaml up -d
# /samples/bookinfo/platform/consul
$ docker-compose -f bookinfo.yaml up -d
$ docker-compose -f bookinfo.sidecars.yaml up -d

再訪問consul的介面試試,有了(沒有的話可能是registrator沒啟動好導致沒註冊到consul,再新部署下微服務和sidecar):

再訪問頁面,OK了。目前沒有配置路由規則,reviews的版本是隨機的。多刷新幾次頁面,可以看到打星在“沒有星星”、“黑色星星”和“紅色星星”三種效果間隨機切換。

使用地址http://localhost:9411能訪問Zipkin鏈路跟蹤系統,查看微服務請求鏈路調用情況。

我們來看看正確的配置是什麼內容。再取出Envoy的配置,0.0.0.0_9080的Listener內容變為:

……
     "listener": {
      "name": "0.0.0.0_9080",
      "address": {
       "socket_address": {
        "address": "0.0.0.0",
        "port_value": 9080
       }
      },
      "filter_chains": [
       {
        "filters": [
         {
          "name": "envoy.http_connection_manager",
          "typed_config": {
           "@type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager",
           "stat_prefix": "0.0.0.0_9080",
           "rds": {
            "config_source": {
             "ads": {}
            },
            "route_config_name": "9080"
           },
……

9080埠的出站路由規則由一個名稱為"9080"route_config定義。找一下這個route_config

……
     "route_config": {
      "name": "9080",
      "virtual_hosts": [
       {
        "name": "details.service.consul:9080",
        "domains": [
         "details.service.consul",
         "details.service.consul:9080",
         "details",
         "details:9080",
         "details.service",
         "details.service:9080"
        ],
        "routes": [
         {
          "match": {
           "prefix": "/"
          },
          "route": {
           "cluster": "outbound|9080|v1|details.service.consul",
……
          },
……
         }
        ]
       },
       {
        "name": "productpage.service.consul:9080",
        "domains": [
         "productpage.service.consul",
         "productpage.service.consul:9080",
         "productpage",
         "productpage:9080",
         "productpage.service",
         "productpage.service:9080"
        ],
        "routes": [
         {
          "match": {
           "prefix": "/"
          },
          "route": {
           "cluster": "outbound|9080|v1|productpage.service.consul",
……
          },
……
         }
        ]
       },
……

由於內容太長,這裡只貼detailsproductpage的關鍵內容。可以看到,9080埠的出站流量會根據目標地址的功能變數名稱正確地轉發到對應的微服務。

Istio路由控制

註意:本節工作目錄為/samples/bookinfo/platform/consul

最後我們嘗試一下Istio的路由控制能力。在配置路由規則之前,我們要先使用DestinationRule定義各個微服務的版本:

$ kubectl apply -f destination-rule-all.yaml

DestinationRule:DestinationRule定義了每個服務下按照某種策略分割的子集。在本例子中按照版本來分子集,reviews分為v1、v2、v3三個版本的子集,其他微服務都只有v1一個子集。

使用命令kubectl get destinationrules -o yaml可以查看已配置的DestinationRule。

接下來我們使用VirtualService來配置路由規則。virtual-service-all-v1.yaml配置會讓所有微服務的流量都路由到v1版本。

$ kubectl apply -f virtual-service-all-v1.yaml

VirtualService:定義路由規則,按照這個規則決定每次請求服務應該將流量轉發到哪個子集。

使用命令kubectl get virtualservices -o yaml可以查看已配置的VirtualService。

再刷新頁面,現在不管刷新多少次,reviews都會使用v1版本,也就是頁面不會顯示星星。

下麵我們試一下基於用戶身份的路由規則。配置文件virtual-service-reviews-test-v2.yaml配置了reviews的路由,讓用戶jason的流量路由到v2版本,其他情況路由到v1版本。

$ kubectl apply -f virtual-service-reviews-test-v2.yaml

執行命令後刷新頁面,可以看到reviews都使用的v1版本,頁面不會顯示星星。點擊右上角的Sign in按鈕,以jason的身份登錄(密碼隨便),可以看到reviews切換到v2版本了,頁面顯示了黑色星星。

查看virtual-service-reviews-test-v2.yaml文件內容可以看到,基於身份的路由是按照匹配HTTP的headers實現的。當HTTP的headers有end-user: jason的內容時路由到v2版本,否則路由到v1版本。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews.service.consul
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews.service.consul
        subset: v2
  - route:
    - destination:
        host: reviews.service.consul
        subset: v1

幾點註意事項的總結

  1. istio.yaml引用的Registrator的latest版本不支持consul的ServiceMeta。要改為master版本。
  2. 第一次啟動istio.yaml後,因為啟動時pilot連不上istio-apiserverpilot會失敗退出。等待istio-apiserver啟動完畢後再跑一次istio.yaml
  3. 配置kubectlcontext,讓kubectl使用istio-apiserver提供的Kubernetes API介面。
  4. 使用bookinfo.yaml啟動各個微服務後,還要運行bookinfo.sidecar.yaml以初始化和啟動sidecar。

整體架構圖

參考資料


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 接手項目之後,在安裝依賴後,再npm start的過程中報錯./node_modules/history/esm/history.js Module not found: Can't resolve '@babel/runtime/helpers/esm/extends' ...
  • 最近一個星期準備學習一下angular前端框架,因為之前在學習abp框架的時候,都要求前端要掌握angular,所以不得不回來惡補一下了,學習的過程有時間的話會記錄在這裡,方便以後複習。 閑言少敘,下麵來介紹開發環境搭建的步驟: 開發環境搭建 1.安裝node和npm(其實只需要安裝node,因為n ...
  • 前言: 相信大家都打開過層級很多很多的文件夾。如果把第一個文件夾看作是樹的根節點的話,下麵的子文件夾就可以看作一個子節點。不過最終我們尋找的還是文件夾中的文件,文件可以看做是葉子節點。下麵我們介紹一種模式,與這種樹級結構息息相關。當然,今天的主角是HashMap。接下來我們一起來看HashMap中到 ...
  • 一、引言 我們都知道,資料庫連接是很珍貴的資源,頻繁的開關資料庫連接是非常浪費伺服器的CPU資源以及記憶體的,所以我們一般都是使用資料庫連接池來解決這一問題,即創造一堆等待被使用的連接,等到用的時候就從池裡取一個,不用了再放回去,資料庫連接在整個應用啟動期間,幾乎是不關閉的,除非是超過了最大閑置時間。 ...
  • 歡迎大家的不嫌棄,繼續和我一起學習設計模式。上一篇已經把裝飾者模式的類圖有了一個整體的出來,末尾說的去想想實現的代碼,你實踐了嗎?是什麼原因讓你實踐了呢?又是什麼原因讓你沒有動手呢?沒動手,可能是思路還不夠明確是嗎? 接下來,我們繼續學習。通過代碼實現的方式,來搞定裝飾者模式。 寫下代碼 動手的時候 ...
  • JAVA的主要優勢:跨平臺性,可以在Linux,windows,mac三個系統上運行。 跨平臺的核心:JAVA虛擬機--JVM 原理就是將Java語言在這個系統上翻譯。JAVA在jvm上運行,jvm進行翻譯。 JRE:java的運行環境,包括JVM和所需要的核心類。 JDK:java程式的開發包,包 ...
  • 背景 《SRE Google運維解密》里提到SRE自動化系統的一個bug導致幾乎所有的數據中心機器被成功下線併進行硬碟擦除。當然這本書出版之後又業界也進行了很多的演進。在我們團隊現在很難發生這樣的事情。因為團隊內人人要遵循的一個設計原則是:原則上禁止批量操作。如需批量,需要有審核流程。批量設置上限。 ...
  • 前言 說到分散式緩存,可能大多數人腦海浮現的就是redis了,為什麼redis能夠在競爭激烈的緩存大戰中脫穎而出呢?原因無非有一下幾點:性能好,豐富的特性跟數據結構,api操作簡單。但是用的人多了,就會出現很多不規範或者疏忽的地方,嚴重的時候甚至會導致生產事故,所以我們有必要來聊聊在Redis使用過 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...