Istio 自定义 Ingress(入口)网关

背景

Istio 默认只创建了一个位于 istio-system 命名空间下的 LoadBalancer 类型入口网关 istio-ingressgateway

$ kubectl get service -n istio-system
NAME                        TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                                                                                                                                                                    AGE
istio-ingressgateway        LoadBalancer   10.0.7.232     123.456.789.1   15020:32724/TCP,80:30201/TCP,443:32136/TCP,15029:32507/TCP,15030:31957/TCP,15031:30514/TCP,15032:32306/TCP,15443:30343/TCP,31400:31383/TCP,                  166d
istio-pilot                 ClusterIP      10.0.176.110   <none>         15010/TCP,15011/TCP,15012/TCP,8080/TCP,15014/TCP,443/
......

在 Kubernetes 集群中,一般会部署许多服务,如果所有的流量都通过一个 LoadBalancer 进来,不仅容易造成单点故障,并且 Gateway 的配置(比如域名、端口、HTTPS 证书等)也会杂糅在一起,不便管理。

Istio Gateway 支持自定义多个入口网关,通过开放一系列端口用于承载网格边缘的进入连接,同时可以使用不同 LoadBalancer 来隔离不同的入口流量

增加自定义入口网关

Istio 1.5.0 以上版本,可以使用 Istioctl 部署自定义入口网关。

准备部署文件

下面以 1.5.4 版本为例。

# Istio-1.5.4-yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  profile: default
  
  components:
    # ingressGateways 是个数组
    ingressGateways:
      # Istio 默认创建的入口网关,可保留
      - name: istio-ingressgateway
        enabled: true
      # 增加自定义入口网关 xxx-ingressgateway
      - name: xxx-ingressgateway
        enabled: true
        label:
          app: xxx-ingressgateway
          istio: xxx-ingressgateway
        k8s:
          service:
            # 可以设置 IP,这样重新部署 IP 不会改变
            loadBalancerIP: "234.567.89.1"
            # 自定义暴露的端口
            ports:
            - port: 15020
              targetPort: 15020
              name: status-port
            - port: 80
              targetPort: 80
              name: http2
            - port: 443
              name: https
            - port: 15029
              targetPort: 15029
              name: kiali
            - port: 15030
              targetPort: 15030
              name: prometheus
            - port: 15031
              targetPort: 15031
              name: grafana
            - port: 15032
              targetPort: 15032
              name: tracing
            - port: 15443
              targetPort: 15443
              name: tls
            - port: 31400
              name: tcp
            - port: 1883
              targetPort: 1883
              name: mqtt
            # 以上端口是 istio 默认的端口,8000 端口是增加的自定义端口
            - port: 8000
              targetPort: 8000
              name: grpc
......

注:可以通过 istioctl profile dump default > default.yaml 获取默认的配置项作为参考。比如,Istio-1.5.4-yaml 中的默认端口就是从 default.yaml 获得的。

部署自定义入口网关

istioctl manifest apply -f istio-1.5.4.yaml

验证

执行以下命令,查看部署情况。

$ kubectl get service -n istio-system
NAME                        TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                                                                                                                                                                    AGE
istio-ingressgateway        LoadBalancer   10.0.7.232     123.456.789.1   15020:32724/TCP,80:30201/TCP,443:32136/TCP,15029:32507/TCP,15030:31957/TCP,15031:30514/TCP,15032:32306/TCP,15443:30343/TCP,31400:31383/TCP,                  166d
istio-pilot                 ClusterIP      10.0.176.110   <none>         15010/TCP,15011/TCP,15012/TCP,8080/TCP,15014/TCP,443/
xxx-ingressgateway        LoadBalancer   10.0.134.67    234.567.89.1   15020:32506/TCP,80:32676/TCP,443:32577/TCP,15029:30700/TCP,15030:32725/TCP,15031:32253/TCP,15032:32681/TCP,15443:31895/TCP,31400:30604/TCP,1883:31953/TCP,8000:32376/TCP   3d17h
......

可以看出,在 istio-system 命名空间下,增加了自定义的 xxx-ingressgateway,并且 IP 和端口也都对应到 Istio-1.5.4-yaml 的配置。

使用自定义入口网关

原先,我们使用 istio 默认入口网关时配置如下。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: your-gateway
  namespace: gateway
spec:
  selector:
    # 使用默认入口网关 istio-ingressgateway
    istio: ingressgateway
  servers:
  - port:
......

其中的 selector 配置为 istio: ingressgateway,表示选择默认的 istio-ingressgateway 作为入口网关。

原因是,istio-ingressgateway 中的设置了 istio: ingressgateway Label。

$ kubectl describe service istio-ingressgateway -n istio-system | grep Labels -A 5
Labels:                   app=istio-ingressgateway
                          istio=ingressgateway
                          operator.istio.io/component=IngressGateways
                          operator.istio.io/managed=Reconcile
                          operator.istio.io/version=1.5.4
                          release=istio

因为在 istio-1.5.4.yaml 中设置了 xxx-ingressgateway 其中一个 Label 为 istio: xxx-ingressgateway,因此,需要使用自定义入口网关时,只需要修改 Gateway 的 selector 即可。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: your-gateway
  namespace: gateway
spec:
  selector:
    # 使用自定义入口网关 xxx-ingressgateway
    istio: xxx-ingressgateway
  servers:
  - port:
......

参考

MakeOptim

MakeOptim

MakeOptim 是个人所学总结完再总结而形成的高质量文集。旨在通过这些文章,沉淀自己,帮助他人。