天天看點

Istio 南北向流量管理引言Istio 網關入口網關(IngressGateway)服務入口網關部署出口流量管理

Istio 南北向流量管理

  • 引言
  • Istio 網關
    • Istio網關的工作原理
    • Istio 網關負載均衡器的作用
  • 入口網關(IngressGateway)服務
  • 入口網關部署
    • 網關資源
    • 例子:使用Gateway
      • 建立一個Gateway
      • VirtualService使用Gateway
    • 使用HTTPS協定
      • 建立TLS Secret
      • 使用HTTPS
      • 為多個主機配置TLS入口網關
      • 關于基于SNI的HTTPS路由
  • 出口流量管理
    • 出口流量網關
    • Service Entry(服務入口)
    • HTTP流量強制更新為TLS

引言

之前的文章:Istio 東西向流量管理

這次講的是

南北向流量管理

,也就是

入口請求到叢集服務的流量管理

Istio 網關

網絡社群中有一個術語叫

Ingress

,是指入口請求到叢集内服務的流量管理。

Ingress

指的是

本地網絡之外

的流量

請求

本地叢集網絡

中的端口。此流量先

路由

公開的入口點

,以便通過執行一些

本地網絡

規則和政策

來确認哪些流量被

允許

進入。如果流量

未通過

這些入口點,則

無法

與叢集的任何服務

連接配接

。如果入口點

允許

流量進入,則将其

代理

到本地網絡中

合适的節點

Istio

入口流量

的管理是由

Istio網關

進行的。

Istio網關的工作原理

傳統上,

Kubernetes

使用

Ingress控制器

來處理外部進入叢集的流量。使用

Istio

時,

Istio網關

用新的

Gateway

資源和

VirtualService

資源來

控制入口流量

,它們協同工作将流量路由到網格中。在

網格内部不需要Gateway

,因為服務可以通過

叢集本地服務名稱互相通路(DNS服務發現)

  1. 用戶端

    在特定端口上

    送出請求

    ,例如:http://test.com:38081/,這是外部請求。
  2. 負載均衡器

    在這個端口上進行偵聽,并将請求

    轉發到叢集中

  3. 在叢集内部,請求被路由到

    Istio IngressGateway

    服務所偵聽的負載均衡器轉發的端口上。
  4. Istio IngressGateway

    服務将請求轉發到對應的

    pod

    上。
  5. IngressGateway pod

    上會配置

    Gateway資源

    VirtualService資源

    定義。

    Gateway

    會配置

    端口、協定及相關安全證書

    VirtualService

    路由配置資訊

    用于找到正确的服務(在東西向流量管理文章中我們已經講過路由配置了)。
  6. Istio IngressGateway pod

    會根據

    路由配置資訊

    将請求

    路由到對應的服務

    上。
  7. 應用服務

    将請求路由到對應應用

    pod

    中的執行個體上。

Istio 網關負載均衡器的作用

典型的

服務網格

具有

一個

多個負載均衡器

,也稱為

網關(Gateway)

,它們從

外部網絡

終止TLS并

允許

流量進入

網格

。然後,流量通過

邊車網關(Sidecar Gateway)

流經内部服務。

應用程式使用

外部服務

的場景也很常見,也可以直接調用外部服務,或者在某些部署中強制通過專用

出口網關(Egress Gateway)

管理離開網格的所有流量。

Istio

具有

入口網關

的概念,它扮演

網絡入口點

的角色,負責

保護和控制

來自叢集

外部的流量對叢集内的通路

此外,

Istio網關

還扮演

負載均衡

虛拟主機路由

的角色。之前提到過的

Envoy

,是一個功能強大的

服務到服務

代理

,但它也有

負載均衡

路由

的功能,可代理的流量包括從

服務網格外部到其内部運作

的服務,或者從

叢集内部服務到外部的服務

入口網關(IngressGateway)服務

IngressGateway服務

必須監聽所需的端口,以便能夠将流量轉發到IngressGateway pod上。minikube + Istio 1.7.4 部署demo項目這文章中簡單的介紹過。

這裡是看一眼

IngressGateway

常用的端口

,注意這裡隻顯示了

port

外部通路用的nodePort

白話了解

就是

IngressGateway

中的端口直接通路沒有什麼用處,因為實際上它

selector

pod

中的

container

istio-proxy

,它需要與

VirtualService

Gateway

結合起來,讓叢集内知道

從外部通路的流量

如何被路由到内部服務網格:

ports:
- name: http2
  nodePort: 30000
  port: 80
  protocol: TCP
- name: https
  nodePort: 30443
  port: 443
  protocol: TCP
- name: mysqlS
  nodePort: 30306
  port: 3306
  protocol: TCP

           

入口網關部署

當我們建立或更改一個

Gateway

VirtualService

時,

Istiod

會檢測到這些變更,并将這些變更資訊轉換為

Envoy配置

,然後将

Envoy配置資訊

發送給相關

Envoy代理

,包括

内部的Envoy

IngressGateway中的Envoy

注意:請不要混淆IngressGateway和Gateway,Gateway資源隻是用于配置IngressGateway的一種Kubernetes的自定義資源。

網關資源

網關(Gateway)資源

用來配置

Envoy端口

,前面我們看了

IngressGateway

中常用的端口,這些端口是

外部流量

通過這些

端口

流入,我們可以讓這些流量和

網格内的服務

互通,記得最早的文章說過,

服務網格

Sidecar

隻能是在

網格内的流量

才會使用到

Envoy

,是以這裡需要

IngressGateway

讓外部流量進入服務網格。

例子:使用Gateway

這裡跳過了Service和Deployment的建立,我們可知的是Service綁定了80端口,服務名是test,綁定了Deployment中的一個web。

建立一個Gateway

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: test-gateway
  namespace: istio-system
spec:
  selector: # 這裡就是使用了istio-ingressgateway
    istio: ingressgateway
  servers:
  - hosts: # 可以配置多個host,這裡使用通配符不限制host
    - "*"
    port:
      name: http
      number: 80
      protocol: HTTP
  - hosts:
    - "*"
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      mode: SIMPLE
      # 除了使用privateKey和serverCertificate指定挂載路徑也可以直接使用credentialName來指定secret名
      # credentialName: istio-ingressgateway-certs
      privateKey: /etc/istio/ingressgateway-certs/tls.key
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
           

VirtualService使用Gateway

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: test-vs
spec:
  gateways: # 可以寫很多gateway,我們隻使用剛才建立的即可。
  - test-gateway.istio-system.svc.cluster.local # 因為命名空間的關系,我們寫全了服務名,也可以簡寫,這裡為了友善萌新了解,寫全了。
  # 之前的文章host我們直接寫服務名,因為DNS服務發現可以幫助我們直接解析叢集内部服務host,這次我們講的是外部流量,這裡的host寫的是真實外網域名哦。
  hosts:
  - test.example.com
  http:
  - match:
    - uri:
      prefix: /
    route:
    - destination:
        host: test # 這裡的host是内部服務名,通過DNS服務發現即可解析
        port:
          number: 80
           
我們理一下過程
  1. 外部通過

    test.example.com:NodePort

    通路,流量先是進入

    IngressGateway

    ,被轉發到内部

    80

    端口。
  2. 通過

    test-gateway

    中的

    servers

    ,我們知道

    IngressGateway

    80

    端口對應到

    test-gateway

    http

    服務,此時流量就已經算是進入網格了。然後

    VirtualService

    根據

    test-gateway

    host

    做比對然後配合

    路由規則

    ,流量被轉發到

    test

    服務。

使用HTTPS協定

目前來說,有部分

CDN

提供

免費/收費

HTTPS

服務,對于

CDN

來說(反向代理+智能DNS解析),使用

HTTPS

分為

2種

,一種是

Flexible

,另一種是

Full

  • Flexible

    模式是這樣,僅是

    使用者←→CDN→後端(注意CDN到後端的請求會變為HTTP)

  • Full

    模式是這樣:

    使用者←→CDN←→後端

如果為了友善我們可以選擇

Flexible

模式,這樣我們後端僅使用

HTTP

即可,但是對于

使用者

來說是

HTTPS

這裡要說的是如果使用

Full

模式,我們就必須在後端也使用

HTTPS

,且将證書上傳到

CDN

這裡的情況就很像上面描述的方式,我們來說說

Istio

中如何使用

HTTPS

建立TLS Secret

建立的

secret

必須在

istio-system

namespace

,并且命名也是固定的(

istio-ingressgateway-certs

),否則無法在

Istio Gateway

中使用。

關于

tls

secret

的名稱

為什麼是固定

的,其實在

istio-ingressgateway

pod

中就能看見,我選了關鍵的幾段。

注意:看挂載路徑,再回頭看我們之前gateway中配置的私鑰路徑和證書路徑。

containers:
 - name: istio-proxy
   image: "docker.io/istio/proxyv2:1.1.0"
   imagePullPolicy: IfNotPresent
   volumeMounts:
   - name: istio-certs
     mountPath: /etc/certs
     readOnly: true
   - name: ingressgateway-certs
     mountPath: "/etc/istio/ingressgateway-certs"
     readOnly: true
   - name: ingressgateway-ca-certs
     mountPath: "/etc/istio/ingressgateway-ca-certs"
     readOnly: true
volumes:
- name: istio-certs
  secret:
    secretName: istio.istio-ingressgateway-service-account
    optional: true
- name: ingressgateway-certs
  secret:
    secretName: "istio-ingressgateway-certs"
    optional: true
- name: ingressgateway-ca-certs
  secret:
    secretName: "istio-ingressgateway-ca-certs"
    optional: true
           

Secret用來儲存證書和私鑰

kubectl create -n istio-system secret tls istio-ingressgateway-certs --key httpbin.example.com/private/httpbin.example.com.key.pem --cert httpbin.example.com/certs/httpbin.example.com.cert.pem
           

使用HTTPS

我們之前在

test-gateway

中已經配置過

443

端口的

HTTPS

,隻是當時沒有

key和證書

,現在我們建立完了

secret

,就可以使用它了。

建立Deployment和Service

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: httpbin
  labels:
    app: httpbin
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: httpbin
        version: v1
  spec:
    containers:
    - image: docker.io/citizenstig/httpbin
      imagePullPolicy: IfNotPresent
      name: httpbin
      prots:
      - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata: httpbin
spec: 
  ports:
  - name: http
    port: 8080
  selector:
    app: httpbin


# ***建立VirtualService***

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin-vs
spec:
  gateways: # gateway沒變
  - test-gateway.istio-system.svc.cluster.local 
  hosts: # 為了區分 我們建立了一個VirtualService并且HOST也不同了
  - httpbin.example.com
  http: # 網關在接收到https請求後我們會轉為http轉發到後端
  - match:
    - uri:
      prefix: /
    route:
    - destination:
        host: httpbin # 這裡的host是内部服務名,通過DNS服務發現即可解析
        port:
          number: 8080
           

為多個主機配置TLS入口網關

之前的yaml注釋中寫了

除了使用

privateKey

serverCertificate

指定挂載路徑也可以直接使用

credentialName

來指定

secret

名,這樣我們不通過修改或添加

ingress-gateway

的挂載也可以直接使用新的

tls secret

Gateway

資源清單中通過不同的

host

使用不同的證書。

但是此時

VirtualService

就需要分開建立,因為需要每個host對應一個

VirtualService

例子:

先建立一個名為

nginx-certs

tls secret

kubectl create -n istio-system secret tls nginx-certs --key nginx-certs/private/nginx.example.com.key.pem --cert nginx-certs/certs/nginx.example.com.cert.pem
           

修改gateway資源

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: test-gateway
  namespace: istio-system
spec:
  selector: # 這裡就是使用了istio-ingressgateway
    istio: ingressgateway
  servers:
  - hosts: # 可以配置多個host,這裡使用通配符不限制host
    - "*"
    port:
      name: http
      number: 80
      protocol: HTTP
  - hosts:
    # 這裡之前是* 因為我們就一個域名,是以不需要限制
    # 現在改為了固定的httpbin.example.com 使用之前的證書
    - httpbin.example.com
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      mode: SIMPLE
      # 除了使用privateKey和serverCertificate指定挂載路徑也可以直接使用credentialName來指定secret名
      # credentialName: istio-ingressgateway-certs
      privateKey: /etc/istio/ingressgateway-certs/tls.key
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
  - hosts:
    # 這裡是使用nginx的證書 域名不同哦
    - nginx.test-nginx.com
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      mode: SIMPLE
      # 除了使用privateKey和serverCertificate指定挂載路徑也可以直接使用credentialName來指定secret名
      credentialName: nginx-certs

           

建立一個nginx的VirtualService

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-vs
spec:
  gateways: # gateway沒變
  - test-gateway.istio-system.svc.cluster.local 
  hosts: # 注意我們區分了hosts
  - nginx.test-nginx.com
  http: # 網關在接收到https請求後我們會轉為http轉發到後端
  - match:
    - uri:
      prefix: /
    route:
    - destination:
        host: nginx
        port:
          number: 80
           

注意:我跳過了Nginx的Deployment和Service的建立。

關于基于SNI的HTTPS路由

SNI

的意思是

Server Name Indication

,用戶端發出

SSL

請求中的

ClientHello

階段),就送出

Host

資訊,使得伺服器能夠切換到正确的域并傳回相應的證書。

它的作用是可以在

相同的IP

使用不同的證書

,比如www.test.com和www.test2.com各使用了一個證書,如果沒有

SNI

支援,那麼無論使用哪個域名通路,隻會使用其中一個證書。

我們如果不使用

SNI路由

,那麼在建立

VirtualService

時就需要幾個

域名

就建幾個

VirtualService(因為大多數情況我們的match中的prefix是/,如果我們的hosts同時寫了這些域名,我們隻能靠match來區分了)

為了區分,我們重建一個Gateway

spec.servers[].tls.mode

我們改為了

PASSTHROUGH

,意義在于 我們

不在網關這裡使用證書

了,表示

按照原樣傳遞入口流量而不終止TLS

,也就是說進入這個網關的

HTTPS

流量,我們

原樣傳到後端

,這就需要在容器中去配置

TLS證書

,我們需要配置到

nginx

裡。

關于在nginx裡配置證書我這裡跳過了,不然yaml太多了。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: sni-gateway
  namespace: istio-system
spec:
  selector: # 這裡就是使用了istio-ingressgateway
    istio: ingressgateway
  servers:
  # 之前我們是寫了hosts,分别不同的域名用了不同的證書,現在我們寫在一起,因為我們的tls mode變了
  - hosts:
    - "nginx.test1-nginx.com"
    - "nginx.test2-nginx.com"
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      mode: PASSTHROUGH
           

VirtualService使用sni中的host轉發到後端

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata: 
  name: nginx-sni-test
spec:
  hosts:
  - nginx.test1-nginx.com
  - nginx.test2-nginx.com
  gateways:
    - sni-gateway.istio-system.svc.cluster.local
  tls: # 之前我們使用http原因是我們隻在網關層使用TLS協定
  - match:
    - sni_hosts:
      - nginx.test1-nginx.com
      port: 443
    route:
    - destination:
        host: nginx1
        port:
          number: 443
  - match:
    - sni_hosts:
      - nginx.test2-nginx.com
      port: 443
    route:
    - destination:
        host: nginx2
        port: 
          number: 443
    
      
           

出口流量管理

出口流量網關

出口網關

使用起來其實也很簡單,定義一個

VirtualService

引導

對目标的通路轉發到我們建立的egressgateway

即可,再引導

對egressgateway的通路

,我們

轉發到具體的目标位址

我們現在使用

Egress Gatway

進行HTTPS流量透傳(這是由應用程式發起的TLS)。

為了簡單一些,我們不開啟TLS雙向認證(因為雙向認證我會放在安全篇寫),直接進行透傳即可,我們配置一個出口網關。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: egressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: http
    hosts:
    - istio.io
  - port:
      number: 443
      name: https
      protocol: TLS
    hosts:
    - istio.io
    tls:
      mode: PASSTHROUGH
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
  - name: test # 因為流策預設是輪訓 ,我們可以不顯式的寫出來
           

定義一個

VirtualService

,配置對

istio.io

的通路80是HTTP協定,443為TLS協定。

如果是

網格内對外發出

的流量

(80和443)

,會被轉發到

istio-egressgateway

然後判斷如果是

istio-egressgateway

再對外發出,就會被轉發到

istio.io

本身的域名位址。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: direct-through-egress-gateway
spec:
  hosts:
  - istio.io
  gateways:
  - istio-egressgateway
  - mesh
  http:
  - match:
    - gateways:
      - mesh
      port: 80
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subset: test
        port:
          number: 80
      weight: 100
  - match:
    - gateways:
      - istio-egressgateway
      port: 80
    route:
    - destination:
        host: istio.io
        port:
          number: 80
      weight: 100
  tls:
  - match:
    - gateways:
      - mesh
      port: 443
      sni_hosts:
      - istio.io
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subset: test
        port:
          number: 443
  - match:
    - gateways:
      - istio-egressgateway
      port: 443
      sni_hosts:
      - istio.io
    route:
    - destination:
        host: istio.io
        port:
          number: 443
      weight: 100    
           

Service Entry(服務入口)

王夕甯

的書中他寫的是

服務條目

,可能是因為

ServiceEntry

允許

将其他條目

添加到

Istio

内部服務系統資料庫

中。

字段 類型 描述 必須的
hosts

string[]

與ServiceEntry關聯的主機。可以是帶有通配符字首的DNS名稱。

主機字段用于在VirtualServices和DestinationRules中選擇比對的主機。

對于HTTP通信,HTTP Host / Authority标頭将與hosts字段比對。

對于包含伺服器名稱訓示(SNI)的HTTP或TLS流量,SNI值将與主機字段比對。

注意1:當resolution設定為DNS類型且未指定端點時,主機字段将用作将流量路由到的端點的DNS名稱。

注意2:如果主機名與另一個服務系統資料庫(例如Kubernetes)中的服務名稱比對,該服務系統資料庫也提供自己的一組端點,則ServiceEntry将被視為現有Kubernetes服務的裝飾器。如果适用,服務條目中的屬性将添加到Kubernetes服務。目前,将僅考慮以下附加屬性istiod:

subjectAltNames:除了驗證與服務Pod相關聯的服務帳戶的SAN外,還将驗證此處指定的SAN。

addresses

string[]

與服務關聯的虛拟IP位址。可以是CIDR字首。HTTP通信,生成的路線的配置将包括兩個HTTP路由域addresses和hosts字段值和目的地将基于HTTP Host / Authority标頭進行辨別。如果指定了一個或多個IP位址,并且如果目标IP與位址字段中指定的IP / CIDR比對,則傳入的流量将被辨別為屬于該服務。如果“位址”字段為空,則僅根據目标端口識别流量。在這種情況下,網格中的任何其他服務都不得共享正在通路服務的端口。換句話說,Sidecar将充當簡單的TCP代理,将指定端口上的傳入流量轉發到指定的目标端點IP /主機。該字段不支援Unix域套接字位址。
ports

Port[]

與外部服務關聯的端口。如果端點是Unix域套接字位址,則必須隻有一個端口。
location

Location

指定是将服務視為網格外部還是網格的一部分。
resolution

Resolution

主機的服務發現模式。對于沒有随附IP位址的TCP端口,将resolution模式設定為NONE時必須小心。在這種情況下,将允許到該端口上任何IP的流量(即0.0.0.0:)。
endpoints

WorkloadEntry[]

與服務關聯的一個或多個端點。隻能指定endpoints或之一 workloadSelector。
workloadSelector

WorkloadSelector

僅适用于MESH_INTERNAL服務。隻能指定endpoints或之一 workloadSelector。WorkloadEntry根據标簽選擇一個或多個Kubernetes Pod或VM工作負載(使用指定 )。WorkloadEntry代表VM的對象應在與ServiceEntry相同的名稱空間中定義。
exportTo

string[]

此服務導出到的名稱空間清單。導出服務允許它被其他名稱空間中定義的邊車,網關和虛拟服務使用。此功能為服務所有者和網格管理者提供了一種機制,可以控制跨名稱空間邊界的服務的可見性。

如果未指定名稱空間,則預設情況下會将服務導出到所有名稱空間。

價值 ”。” 保留,并定義導出到聲明服務的同一名稱空間。類似地,值“ *”保留并定義到所有命名空間的導出。

對于Kubernetes服務,可以通過将注釋“ networking.istio.io/exportTo”設定為以逗号分隔的名稱空間名稱清單來實作等效效果。

注意:在目前版本中,該exportTo值限制為“.” 或“ *”(即目前名稱空間或所有名稱空間)。

subjectAltNames

string[]

如果指定,則代理将驗證伺服器證書的使用者備用名稱是否與指定值之一比對。

注意:當将工作負載條目與工作負載選擇器一起使用時,在工作條目中指定的服務帳戶也将用于派生應驗證的其他使用者備用名稱。

Location

名稱 描述

MESH_EXTERNAL

表示服務在網格外部。通常用于訓示通過API使用的外部服務。

MESH_INTERNAL

表示服務是網格的一部分。通常用于訓示在擴充服務網格以包括非托管基礎架構的過程中顯式添加的服務(例如,添加到基于Kubernetes的服務網格的VM)。

Resolution

名稱 描述

NONE

假定傳入連接配接已經解析(到特定的目标IP位址)。通常使用諸如IP表REDIRECT / eBPF之類的機制通過代理路由此類連接配接。在執行與路由相關的任何轉換之後,代理将把連接配接轉發到連接配接綁定到的IP位址。

STATIC

使用端點中指定的靜态IP位址(請參見下文)作為與服務關聯的後備執行個體。

DNS

在請求處理期間,嘗試通過查詢環境DNS來解析IP位址。如果未指定端點,則代理将解析未使用通配符的主機字段中指定的DNS位址。如果指定了端點,則将解析端點中指定的DNS位址,以确定目标IP位址。DNS解析不能與Unix域套接字端點一起使用。

舉個栗子:

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: external-svc-https
spec:
  hosts:
  - api.dropboxapi.com
  - www.googleapis.com
  - api.facebook.com
  location: MESH_EXTERNAL
  ports:
  - number: 443
    name: https
    protocol: TLS
  resolution: DNS # 如果通路上面3個host(屬于外部服務),使用dns解析
           

再來個栗子:

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: external-svc-mongocluster
spec:
  hosts:
  - mymongodb.somedomain # 因為我們不是HTTP服務,實際上hosts中的dns名稱會被忽略,這種情況下會使用endpoints中的address以及ports來甄别服務調用
  addresses:
  - 172.20.10.1/24 # 在清單範圍内的IP的通路會被認定屬于這一服務,因為hosts會被忽略,如果我們不定義address,那麼服務甄别就隻能靠下面的ports了
  ports:
  - number: 27018
    name: mongodb
    protocol: MONGO
  location: MESH_INTERNAL # 表示服務屬于網格内部
  resolution: STATIC # 靜态方式解析
  endpoints: # 一個或多個關聯到這個服務的endpoint
  - address: 2.2.2.2
  - address: 3.3.3.3
           

HTTP流量強制更新為TLS

注意看

443

端口協定,我們改為了

HTTP

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: istio-io
spec:
  hosts:
  - istio.io
  ports:
  - number: 80
    name: http
    protocol: HTTP
  - number: 443
    name: https
    protocol: HTTP # 注意這裡之前是TLS協定,我們改為了HTTP
  resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: istio-io
spec:
  hosts:
  - istio.io
  http:
  - match:
    - port: 80 # 如果對istio.io通路80端口
      route:
      - destination: # 将它轉發到443端口,但是注意,此時協定還是HTTP
          host: istio.io
          port: 443
        weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: istio-io
spec:
  host: istio.io
  trafficPolicy:
    loadBanlancer:
      simple: ROUND_ROBIN
    portLevelSettings:
    - port:
        number: 80 # 目标規則定義了80端口
        tls: SIMPLE # 發起到上遊端點的TLS連接配接,也就是說我們是通過流量政策來将對istio.io 80端口的HTTP協定更新成TLS協定。
           

解釋:我們對

http://istio.io

進行通路,

DestinationRule

将對端口

80

上的

HTTP

請求執行

TLS origination

,然後

VirtualService

将端口

80

上的請求重定向到目标端口

443

,是以我們通路

http://istio.io

直接就會傳回

200

,不會再進行重定向後跳轉,隻需要通路一次即可。

關于

DestinationRule.trafficPolicy

的東西,會在

Istio

流量治理

中細說。

Service Entry Istio官方文檔

Egress TLS Origination