Gateway 介绍

Istio Gateway 描述在网格边缘运行的负载均衡器,用于接收传入或传出的 HTTP/TCP 连接。Istio Gateway 网关跟 sidecar 代理都是使用的 envoy 程序,其配置也可以用 istioctl 命令来查看。

Istio Gateway 分为 Ingress 和 Egress 网关,分别描述集群的入口和出口。在安装 Istio 时,可以指定是否安装网关,比如指定安装出口网关:

1
2
3
4
istioctl install <flags-you-used-to-install-Istio> \
                   --set components.egressGateways[0].name=istio-egressgateway \
                   --set components.egressGateways[0].enabled=true

Ingress 网关

集群入口介绍

istio 支持三种方式暴露服务网格集群内的服务:

  • Kubernetes Ingress:Kubernets 1.19 版本引入的,Ingress 仅支持 HTTP 协议路由。
  • Istio Gateway:Gateway 提供了更广泛的自定义和灵活性,并允许将 Istio 功能应用于进入集群的流量。
  • Kubernetes Gateway API:2022 年 7 月正式进入 beta 阶段,目前 Istio 提供了 Gateway API 的 beta 支持,Gateway API 是一种规范,并不提供实现。

Istio 中推荐使用 Gateway 暴露服务,因 Gateway API 还没发布正式版,这里主要讨论 Istio Gateway 的使用和原理。

部署测试

本地使用的 k3s 安装的 kubernetes 集群,使用 istioctl 安装的 istio:

1
2
istioctl install --set profile=demo -y
kubectl label namespace default istio-injection=enabled

部署 httpbin:

1
2
3
// 下载的 istio release 包
cd istio-1.16.1
kubectl apply -f samples/httpbin/httpbin.yaml

Ingress Gateway 描述在网格边缘运行的负载均衡器,用于接收传入的 HTTP/TCP 连接。它会配置暴露的端口、协议等,但与 Kubernetes Ingress 资源不同,不会包括任何流量路由配置。 转而使用路由规则来配置入口流量的流量路由,这与内部服务请求所用的方式相同。创建如下的 Istio Gateway:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "httpbin.example.com"
EOF

设置流量路由配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - "httpbin.example.com"
  gateways:
  - httpbin-gateway
  http:
  - match:
    - uri:
        prefix: /status
    - uri:
        prefix: /delay
    route:
    - destination:
        port:
          number: 8000
        host: httpbin
EOF

每一个网关都由一个 LoadBalancer 类型的服务支持,该服务的外部负载均衡器 IP 和端口用于访问 Gateway,大多数云平台上运行的集群默认支持类型为 LoadBalancer 的 Kubernetes 服务。如果 k3s 的节点设置了 lb 标签,“svccontroller.k3s.cattle.io/enablelb: “true””,则直接如下访问即可:

1
2
3
4
export INGRESS_HOST=$(kubectl -n "$INGRESS_NS" get service "$INGRESS_NAME" -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export INGRESS_PORT=$(kubectl -n "$INGRESS_NS" get service "$INGRESS_NAME" -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
// 示例:curl -vs -I -HHost:httpbin.example.com "http://172.19.52.50:80/status/200"
curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST:$INGRESS_PORT/status/200"

如果 k3s 的节点没有设置 lb 标签,需要通过 nodePort 方式访问:

1
2
3
4
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n "${INGRESS_NS}" -o jsonpath='{.items[0].status.hostIP}')
export INGRESS_PORT=$(kubectl -n "${INGRESS_NS}" get service "${INGRESS_NAME}" -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
// 示例:curl -s -I -HHost:httpbin.example.com "http://172.19.52.50:31532/status/200"
curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST:$INGRESS_PORT/status/200"

流量分析

上面通过LoadBalancer和nodePort方式暴露Gateway,来访问集群内部服务,其流量走向如下图所示: istio_ingress_gateway

即从集群外面通过 LoadBalancer 或者 nodePort 返回请求到 ingressgateway svc,然后根据 Gateway 的配置,将请求转发到对应的 VirtualService,再根据 VirtualService 的配置,将请求转发到对应的 DestinationRule,最后将请求转发到对应的服务:

1
2
3
root@cluster1:~# kubectl get svc -nistio-system istio-ingressgateway
NAME                   TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)
istio-ingressgateway   LoadBalancer   10.45.36.89   xxx  15021:31942/TCP,80:31532/TCP,443:31936/TCP,31400:32353/TCP,15443:31263/TCP

可以看到,istio-ingressgateway 服务中 80 端口对应的是 http2 协议,其 targetPort 为 8080,即转发到 istio-ingressgateway pod 监听的端口:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
root@cluster1:~# kubectl get pods -nistio-system
NAME                                    READY   STATUS    RESTARTS   AGE
istiod-6cd994fc86-gf8jn                 1/1     Running   0          5d23h
istio-ingressgateway-85c59bdcd9-bbsj4   1/1     Running   0          5d23h
istio-egressgateway-5985746885-rscdw    1/1     Running   0          5d23h

// 查看 listener
root@cluster1:~# istioctl pc listener istio-ingressgateway-85c59bdcd9-bbsj4.istio-system
ADDRESS PORT  MATCH DESTINATION
0.0.0.0 8080  ALL   Route: http.8080
0.0.0.0 15021 ALL   Inline Route: /healthz/ready*
0.0.0.0 15090 ALL   Inline Route: /stats/prometheus*

// 查看路由,设置了匹配的 host 和目的服务
root@cluster1:~# istioctl pc route istio-ingressgateway-85c59bdcd9-bbsj4.istio-system
NAME          DOMAINS                 MATCH                  VIRTUAL SERVICE
http.8080     httpbin.example.com     /status*               httpbin.default
http.8080     httpbin.example.com     /delay*                httpbin.default
              *                       /healthz/ready*
              *                       /stats/prometheus*

// 查看 cluster
root@cluster1:~# istioctl pc cluster istio-ingressgateway-85c59bdcd9-bbsj4.istio-system | grep httpbin
SERVICE FQDN                                            PORT      SUBSET     DIRECTION     TYPE           DESTINATION RULE
httpbin.default.svc.cluster.local                       8000      -          outbound      EDS

// 查看 endpoints
root@cluster1:~# istioctl pc endpoint istio-ingressgateway-85c59bdcd9-bbsj4.istio-system | grep httpbin
10.44.0.12:80                                           HEALTHY     OK                outbound|8000||httpbin.default.svc.cluster.local

Egress 访问外部服务

istio 中访问外部服务的流量都会到代理 sidecar 中,根据 istio 的安装选项“meshConfig.outboundTrafficPolicy.mode”值不同,sidecar 有不同的处理方式:

  • ALLOW_ANY:允许访问所有未知服务
  • REGISTRY_ONLY:只允许访问在 ServiceEntry 中注册的服务

通过这种方式访问外部服务,其流量走向如下图所示: istio_egress_direct

直接访问

本地使用的 k3s 安装的 kubernetes 集群,使用 istioctl 安装的 istio:

1
2
istioctl install --set profile=demo -y
kubectl label namespace default istio-injection=enabled

部署 sleep:

1
2
3
// 下载的 istio release 包
cd istio-1.16.1
kubectl apply -f samples/sleep/sleep.yaml

istio 中配置“meshConfig.outboundTrafficPolicy.mode”设置 sidecar 对外部服务的处理方式,默认为 ALLOW_ANY,允许调用未知的服务。此时测试:

1
2
3
4
root@cluster1:~# export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
root@cluster1:~# kubectl exec "$SOURCE_POD" -c sleep -- curl -sSI https://www.baidu.com | grep  "HTTP/"; kubectl exec "$SOURCE_POD" -c sleep -- curl -sI https://edition.cnn.com | grep "HTTP/"
HTTP/1.1 200 OK
HTTP/2 200

通过 ServiceEntry 访问

重新安装 istio,设置 “meshConfig.outboundTrafficPolicy.mode”选项为 REGISTRY_ONLY,只允许访问 ServiceEntry 中配置的服务:

1
2
3
4
5
root@cluster1:~# istioctl install --set profile=demo -y --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY

// 等待生效后
root@cluster1:~# kubectl exec "$SOURCE_POD" -c sleep -- curl -sSI https://www.baidu.com | grep  "HTTP/"; kubectl exec "$SOURCE_POD" -c sleep -- curl -sI https://edition.cnn.com | grep "HTTP/"
command terminated with exit code 35

配置 ServiceEntry 来允许访问“httpbin.org”这个 host。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: httpbin-ext
spec:
  hosts: # 匹配的 hosts
  - httpbin.org
  ports: # 外部服务的端口
  - number: 80
    name: http
    protocol: HTTP # 协议,可以为 HTTP|HTTPS|GRPC|HTTP2|MONGO|TCP|TLS
  resolution: DNS # 通过环境中的 dns 异步解析地址,可以为 NONE|STATIC|DNS|DNS_ROUND_ROBIN
  location: MESH_EXTERNAL # 标识服务位于网格内还是网格外,可以为,MESH_INTERNAL|MESH_EXTERNAL

查看 pods 的 sidecar 配置如下,显示 cluster 中的 httpbin.org 服务已经配置了 DNS 解析,并且 endpoints 配置中已经获取到了两个 ip 地址:

1
2
3
4
5
6
7
8
9
root@cluster1:~# istioctl pc listener sleep-bc9998558-s6rcm | grep "80"
0.0.0.0       80    Trans: raw_buffer; App: http/1.1,h2c                                                          Route: 80
root@cluster1:~# istioctl pc route sleep-bc9998558-s6rcm | grep "httpbin.org"
80                                                            httpbin.org                                          /*
root@cluster1:~# istioctl pc cluster sleep-bc9998558-s6rcm | grep httpbin.org
httpbin.org                                             80        -          outbound      STRICT_DNS
root@cluster1:~# istioctl pc endpoints sleep-bc9998558-s6rcm | grep httpbin.org
3.230.204.70:80                                         HEALTHY     OK                outbound|80||httpbin.org
34.193.132.77:80                                        HEALTHY     OK                outbound|80||httpbin.org

绕过代理

如果想在 istio 集群中,针对特定的 IP 范围绕过 sidecar 直接访问,可以使用“global.proxy.includeIPRanges”或“global.proxy.excludeIPRanges”配置项。

集群在创建时,都会设置 pods 和 service 的可用 ip 范围,因此推荐使用“global.proxy.includeIPRanges”。通过以下命令,查看 apiserver 配置的 service ip 范围:

1
2
[root@node-1 ~]# kubectl describe pod kube-apiserver -n kube-system | grep 'service-cluster-ip-range'
      --service-cluster-ip-range=10.222.0.0/16

因为这里测试用的是 k3s,没有 kube-apiserver 这个 pod,但是 k3s 可以在安装时通过参数“INSTALL_K3S_EXEC="–cluster-cidr 10.44.0.0/16 –service-cidr 10.45.0.0/16"”来设置,直接根据这个值重新安装 istio:

1
istioctl install --set profile=demo -y --set values.global.proxy.includeIPRanges="10.45.0.0/16"

Egress 出口网关

上面的例子是通过 sidecar 直接调用的外部服务,而这里展示通过专用的 egress gateway 服务间接调用外部服务。有两种场景会使用出口网关:

  • 对安全有严格要求,要求网格所有出站流量必须经过专用节点。这些专用节点用于实施 egress 流量的策略,并且受到比其余节点更严密地监控。
  • 应用节点没有公网 IP,无法访问互联网,但是 egress gateway 节点分配了公有 IP ,可以用它引导所有的出站流量,访问外部服务。

直接访问

同样的,先部署测试 pods:

1
2
kubectl apply -f samples/sleep/sleep.yaml
export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})

为 edition.cnn.com 定义一个 ServiceEntry:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
kubectl apply -f - <<EOF
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
EOF

此时测试发送 http 请求,可以看到能返回成功,验证 ServiceEntry 是否已正确应用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
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
...

通过查看 envoy 配置,可以看到 http 流量的走向如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// 获取 http 的 listener,会路由到名称为 80 的路由
root@cluster1:~# istioctl pc listener sleep-bc9998558-xkzlp | grep 80
0.0.0.0       80    Trans: raw_buffer; App: http/1.1,h2c                                                          Route: 80
// 80 路由中,根据 host 匹配到 edition.cnn.com,根据此路由的 json 输出,可以看到路由到 cluster "outbound|80||edition.cnn.com"
root@cluster1:~# istioctl pc route sleep-bc9998558-xkzlp --name 80
NAME     DOMAINS                                              MATCH     VIRTUAL SERVICE
80       edition.cnn.com                                      /*
// cluster 中指定了 dns 解析方式
root@cluster1:~# istioctl pc cluster sleep-bc9998558-xkzlp --fqdn "outbound|80||edition.cnn.com"
SERVICE FQDN        PORT     SUBSET     DIRECTION     TYPE           DESTINATION RULE
edition.cnn.com     80       -          outbound      STRICT_DNS
// 查看 endpoints
root@cluster1:~# istioctl pc endpoints sleep-bc9998558-xkzlp --cluster "outbound|80||edition.cnn.com"
ENDPOINT             STATUS      OUTLIER CHECK     CLUSTER
151.101.131.5:80     HEALTHY     OK                outbound|80||edition.cnn.com
151.101.195.5:80     HEALTHY     OK                outbound|80||edition.cnn.com

因为这个 host 会返回 301 重定向到 https 地址,继续查看 https 流量的走向如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// listener 通过 SNI(服务名称指示)匹配 host
root@cluster1:~# istioctl pc listener sleep-bc9998558-xkzlp | grep 443
0.0.0.0       443   SNI: edition.cnn.com              Cluster: outbound|443||edition.cnn.com
// cluster 中指定了 dns 解析方式
root@cluster1:~# istioctl pc cluster sleep-bc9998558-xkzlp --fqdn "outbound|443||edition.cnn.com"
SERVICE FQDN        PORT     SUBSET     DIRECTION     TYPE           DESTINATION RULE
edition.cnn.com     443      -          outbound      STRICT_DNS
// 查看 endpoints
root@cluster1:~# istioctl pc endpoints sleep-bc9998558-xkzlp --cluster "outbound|443||edition.cnn.com"
ENDPOINT              STATUS      OUTLIER CHECK     CLUSTER
151.101.131.5:443     HEALTHY     OK                outbound|443||edition.cnn.com
151.101.195.5:443     HEALTHY     OK                outbound|443||edition.cnn.com

通过 gateway 访问

为 edition.cnn.com 端口 80 创建 egress Gateway。并为指向 egress gateway 的流量创建一个 destination rule。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: egressgateway
  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
  subsets:
  - name: cnn

定义一个 VirtualService,将流量从 sidecar 引导至 Egress Gateway,再从 Egress Gateway 引导至外部服务:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: direct-cnn-through-egress-gateway
spec:
  hosts:
  - edition.cnn.com
  gateways: # 应用这些 route 的 gateway 和 sidecar 的名称,其他命名空间的网关可以用<网关命名空间>/<网关名称>来指代,“mesh”表示网格中的所有 sidecar
  - istio-egressgateway
  - 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: 80
      weight: 100

再次发送 HTTP 请求测试:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
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_egress_gateway

查看此时流量走向如下,可以看到对外部域名的 dns 解析工作,由应用容器的 sidecar 中转移到了 egressgateway 的 pods 中:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 通过 json 输出看到流量转发到 cluster "outbound|80|cnn|istio-egressgateway.istio-system.svc.cluster.local"
root@cluster1:~# istioctl pc route sleep-bc9998558-xkzlp --name 80
NAME     DOMAINS                                              MATCH     VIRTUAL SERVICE
80       edition.cnn.com                                      /*        direct-cnn-through-egress-gateway.default

// 查看 cluster 对应的 endpoint 地址和端口
root@cluster1:~# istioctl pc endpoint sleep-bc9998558-xkzlp --cluster "outbound|80|cnn|istio-egressgateway.istio-system.svc.cluster.local"
ENDPOINT            STATUS      OUTLIER CHECK     CLUSTER
10.44.0.25:8080     HEALTHY     OK                outbound|80|cnn|istio-egressgateway.istio-system.svc.cluster.local

// 查看 egressgateway pods ip
root@cluster1:~# kubectl get pods -nistio-system -owide
NAME                                    READY   STATUS    RESTARTS   AGE     IP           NODE       NOMINATED NODE   READINESS GATES
istio-egressgateway-5985746885-25rqt    1/1     Running   0          2d4h    10.44.0.25   cluster1   <none>           <none>

// 查看 egress 的 listener
root@cluster1:~# istioctl pc listener istio-egressgateway-5985746885-25rqt.istio-system --port 8080
ADDRESS PORT MATCH DESTINATION
0.0.0.0 8080 ALL   Route: http.8080

// 查看 egress 的 route,会转发到 cluster "outbound|80||edition.cnn.com"
root@cluster1:~# istioctl pc route istio-egressgateway-5985746885-25rqt.istio-system
NAME          DOMAINS             MATCH                  VIRTUAL SERVICE
http.8080     edition.cnn.com     /*                     direct-cnn-through-egress-gateway.default

// 查看 cluster
root@cluster1:~# istioctl pc cluster istio-egressgateway-5985746885-25rqt.istio-system --fqdn "outbound|80||edition.cnn.com"
SERVICE FQDN        PORT     SUBSET     DIRECTION     TYPE           DESTINATION RULE
edition.cnn.com     80       -          outbound      STRICT_DNS

// 查看 endpoints
root@cluster1:~# istioctl pc endpoint istio-egressgateway-5985746885-25rqt.istio-system --cluster "outbound|80||edition.cnn.com"
ENDPOINT             STATUS      OUTLIER CHECK     CLUSTER
151.101.131.5:80     HEALTHY     OK                outbound|80||edition.cnn.com
151.101.195.5:80     HEALTHY     OK                outbound|80||edition.cnn.com

Gateway 字段说明

Gateway 中字段为:

字段 类型 说明 必填
servers Server[] 服务器列表
selector map<string, string> 一个或多个标签,指示应在其上应用此网关配置的特定pod、vm集

Server 结构中字段为:

字段 类型 说明 必填
port Port 监听入口流量的端口
bind string listener 应该被绑定到的 ip 或 Unix 域套接字。格式:x.x.x.x 或 unix://path/to/uds 或 unix://@foobar(Linux 抽象命名空间)。当使用 Unix 域套接字时,端口号应该是 0。 这可以用来限制该服务器的可达性,使其仅为网关内部访问。这通常是在网关需要与另一个网格服务通信时使用,例如发布度量指标。在这种情况下,用指定的绑定方式创建的服务器,将不能被外部网关客户端使用。
hosts string[] 要通过此 gateway 暴露的 hosts,通常用于 http 服务,也可用于带 SNI 的 TCP 服务。一个主机被指定为一个 dnsName,并有一个可选的命名空间/前缀。dnsName 应该使用 FQDN 格式指定,可以在最左边包括一个通配符(例如 prod/.example.com)。将 dnsName 设置为,以选择指定命名空间中的所有 VirtualService 主机
tls ServerTLSSettings 一组与 TLS 相关的选项,管理服务器的行为。使用这些选项来控制是否所有的 http 请求都应该被重定向到 https,以及使用何种 TLS 模式
name string 一个可选的服务器名称,当设置时必须在所有的服务器中是唯一的。这将被用于各种目的,比如用这个名字生成的统计信息的前缀等。

Port 结构中字段为:

字段 类型 说明 必填
number uint32 端口
protocol string 协议,可以为 HTTP/HTTPS/GRPC/HTTP2/MONGO/TCP/TLS
name string 名称

ServerTLSSettings 结构中字段为:

字段 类型 说明 必填
httpsRedirect bool 如果为 true,负载均衡器将为 http 连接发送 301 重定向,要求客户使用 HTTPS
mode TLSmode 表示该端口的连接是否使用 TLS 来保护,决定了 TLS 的执行方式
serverCertificate string 如果 mode 为 SIMPLE 或者 MUTUAL 需要填写,持有的服务器端 TLS 证书文件路径
privateKey string 如果 mode 为 SIMPLE 或者 MUTUAL 需要填写,持有的服务器端私钥文件路径
caCertificates string 如果 mode 为 MUTUAL 需要填写,持有的 CA 证书文件路径,用来验证客户端证书
credentialName string 凭据名称,对于运行在 Kubernetes 上的网关,表示持有 TLS 证书的 secret 的名称,仅适用于 Kubernetes 上。该 secret 应包含以下 key 和 value:key: 和 cert: 。对于双向 TLS,可以在此 secret 中提供 cacert: ,也可以是一个单独的 secret,命名为-cacert。只能指定 serverCertificate、caCertificates、credentialName 中的一个。
subjectAltNames string[] 用于验证客户端证书中主体身份的备用名称列表
verifyCertificateSpki string[] 认证客户端证书的基于 SPKI 的 base64 编码的 SHA-256 哈希列表,当 verifyCertificateSpki 和 verifyCertificateHash 都指定了,任意一个哈希匹配了将会导致证书被接受
verifyCertificateHash string[] 认证客户端证书的 hex 编码的 SHA-25 哈希列表
minProtocolVersion TLSProtocol 最低的 TLS 协议版本,默认为 TLSV1_2
maxProtocolVersion string[] 最高的 TLS 协议版本
cipherSuites string[] 指定后将只支持指定的密码列表

ServerTLSSettings.TLSmode 是由代理执行的,字段有以下这些值:

  • PASSTHROUGH:直通,不进行 TLS 终止,即不将 https 解密为 http。客户端给定的 SNI 字符将被用作 VirtualService TLS 路由中的匹配标准,以确定服务注册表中的目标服务。
  • SIMPLE:用标准的 TLS 语义进行安全连接,入口 gateway 会将 https 解密为 http 进行访问。
  • MUTUAL:通过出示服务器证书进行验证,使用双向 TLS 与下游的安全连接。
  • AUTO_PASSTHROUGH:与 PASSTHROUGH 类似,只是不需要相关的 VirtualService 来从 SNI 值映射到注册表中的服务。目的地的详细信息,如服务/子集/端口被编码在 SNI 值中。代理将转发到 SNI 值所指定的上游(Envoy)集群(一组端点)。这种 server 通常用于在不同的 L3 网络中的服务之间提供连接,否则它们各自的端点之间没有直接连接。使用这种模式的前提是,源和目的地都使用 Istio mTLS 来保证流量安全。
  • ISTIO_MUTUAL:通过出示服务器证书进行认证,从 downstream 使用双向 TLS 进行安全连接。与 MUTUAL 模式相比,该模式使用证书代表网关工作负载身份,由 Istio 自动生成,用于 mTLS 认证。当使用这种模式时,TLSOptions 中的所有其他字段应该为空。

参考