传统上,Kubernetes应用Ingress控制器来解决从内部进入集群的流量。应用Istio时,状况不再如此。 Istio已用新的GatewayVirtualServices资源替换了相熟的Ingress资源。它们协同工作,将流量路由到网格中。在网格外部,不须要Gateway,因为服务能够通过集群本地服务名称互相拜访。

正如我之前文章介绍过的,kubernetes提供的Ingress过于简略,裸露进去的属性表白性太弱。当然社区也意识到了这个问题,从kubernetes1.19 版本,在逐渐补全性能。Istio解决方案中,本人实现了Istio gateway。在非istio场景外,gloo,ambasaador ,contour等网关 能够满足咱们生产环境的需要。

部署

咱们看下社区默认的部署。

通过Deployment治理的一组istio-ingressgateway Pod。

IngressGateway,这是Envoy代理的封装。它的配置形式与服务网格中应用的Sidecar雷同。当咱们创立或更改Gateway或VirtualService时,Istio Pilot控制器会检测到更改,该控制器会将这些信息转换为Envoy配置并将其发送到相干代理,包含IngressGateway外部的Envoy。

apiVersion: apps/v1kind: Deploymentmetadata:  labels:    app: istio-ingressgateway    istio: ingressgateway    release: istio  name: istio-ingressgateway  namespace: istio-systemspec:  selector:    matchLabels:      app: istio-ingressgateway      istio: ingressgateway  strategy:    rollingUpdate:      maxSurge: 100%      maxUnavailable: 25%  template:    metadata:      annotations:        prometheus.io/path: /stats/prometheus        prometheus.io/port: "15090"        prometheus.io/scrape: "true"        sidecar.istio.io/inject: "false"      labels:        app: istio-ingressgateway        chart: gateways        heritage: Tiller        istio: ingressgateway        release: istio        service.istio.io/canonical-name: istio-ingressgateway        service.istio.io/canonical-revision: latest    spec:      affinity:        nodeAffinity:          preferredDuringSchedulingIgnoredDuringExecution:          - preference:              matchExpressions:              - key: kubernetes.io/arch                operator: In                values:                - amd64            weight: 2          - preference:              matchExpressions:              - key: kubernetes.io/arch                operator: In                values:                - ppc64le            weight: 2          - preference:              matchExpressions:              - key: kubernetes.io/arch                operator: In                values:                - s390x            weight: 2          requiredDuringSchedulingIgnoredDuringExecution:            nodeSelectorTerms:            - matchExpressions:              - key: kubernetes.io/arch                operator: In                values:                - amd64                - ppc64le                - s390x      containers:      - args:        - proxy        - router        - --domain        - $(POD_NAMESPACE).svc.cluster.local        - --proxyLogLevel=warning        - --proxyComponentLogLevel=misc:error        - --log_output_level=default:info        - --serviceCluster        - istio-ingressgateway        - --trust-domain=cluster.local        env:        - name: JWT_POLICY          value: third-party-jwt        - name: PILOT_CERT_PROVIDER          value: istiod        - name: CA_ADDR          value: istiod.istio-system.svc:15012        - name: NODE_NAME          valueFrom:            fieldRef:              apiVersion: v1              fieldPath: spec.nodeName        - name: POD_NAME          valueFrom:            fieldRef:              apiVersion: v1              fieldPath: metadata.name        - name: POD_NAMESPACE          valueFrom:            fieldRef:              apiVersion: v1              fieldPath: metadata.namespace        - name: INSTANCE_IP          valueFrom:            fieldRef:              apiVersion: v1              fieldPath: status.podIP        - name: HOST_IP          valueFrom:            fieldRef:              apiVersion: v1              fieldPath: status.hostIP        - name: SERVICE_ACCOUNT          valueFrom:            fieldRef:              fieldPath: spec.serviceAccountName        - name: CANONICAL_SERVICE          valueFrom:            fieldRef:              fieldPath: metadata.labels['service.istio.io/canonical-name']        - name: CANONICAL_REVISION          valueFrom:            fieldRef:              fieldPath: metadata.labels['service.istio.io/canonical-revision']        - name: ISTIO_META_WORKLOAD_NAME          value: istio-ingressgateway        - name: ISTIO_META_OWNER          value: kubernetes://apis/apps/v1/namespaces/istio-system/deployments/istio-ingressgateway        - name: ISTIO_META_MESH_ID          value: cluster.local        - name: ISTIO_META_ROUTER_MODE          value: sni-dnat        - name: ISTIO_META_CLUSTER_ID          value: Kubernetes        image: docker.io/istio/proxyv2:1.7.3        name: istio-proxy        ports:        - containerPort: 15021        - containerPort: 8080        - containerPort: 8443        - containerPort: 15443        - containerPort: 15090          name: http-envoy-prom          protocol: TCP        readinessProbe:          failureThreshold: 30          httpGet:            path: /healthz/ready            port: 15021            scheme: HTTP          initialDelaySeconds: 1          periodSeconds: 2          successThreshold: 1          timeoutSeconds: 1        resources:          limits:            cpu: 2000m            memory: 1024Mi          requests:            cpu: 100m            memory: 128Mi        securityContext:          allowPrivilegeEscalation: false          capabilities:            drop:            - ALL          privileged: false          readOnlyRootFilesystem: true        volumeMounts:        - mountPath: /etc/istio/proxy          name: istio-envoy        - mountPath: /etc/istio/config          name: config-volume        - mountPath: /var/run/secrets/istio          name: istiod-ca-cert        - mountPath: /var/run/secrets/tokens          name: istio-token          readOnly: true        - mountPath: /var/run/ingress_gateway          name: gatewaysdsudspath        - mountPath: /etc/istio/pod          name: podinfo        - mountPath: /etc/istio/ingressgateway-certs          name: ingressgateway-certs          readOnly: true        - mountPath: /etc/istio/ingressgateway-ca-certs          name: ingressgateway-ca-certs          readOnly: true      securityContext:        fsGroup: 1337        runAsGroup: 1337        runAsNonRoot: true        runAsUser: 1337      serviceAccountName: istio-ingressgateway-service-account      volumes:      - configMap:          name: istio-ca-root-cert        name: istiod-ca-cert      - downwardAPI:          items:          - fieldRef:              fieldPath: metadata.labels            path: labels          - fieldRef:              fieldPath: metadata.annotations            path: annotations        name: podinfo      - emptyDir: {}        name: istio-envoy      - emptyDir: {}        name: gatewaysdsudspath      - name: istio-token        projected:          sources:          - serviceAccountToken:              audience: istio-ca              expirationSeconds: 43200              path: istio-token      - configMap:          name: istio          optional: true        name: config-volume      - name: ingressgateway-certs        secret:          optional: true          secretName: istio-ingressgateway-certs      - name: ingressgateway-ca-certs        secret:          optional: true          secretName: istio-ingressgateway-ca-certs

咱们在IngressGateway部署中必须关怀的是SSL证书。为了可能拜访gateway资源中的证书,请确保已正确装置了证书。

 volumeMounts:        - mountPath: /etc/istio/ingressgateway-certs          name: ingressgateway-certs          readOnly: true        - mountPath: /etc/istio/ingressgateway-ca-certs          name: ingressgateway-ca-certs          readOnly: true           volumes:      - name: ingressgateway-certs        secret:          optional: true          secretName: istio-ingressgateway-certs      - name: ingressgateway-ca-certs        secret:          optional: true          secretName: istio-ingressgateway-ca-certs 

因为istio-ingressgateway 次要解决边界流量,所以必须创立LoadBalancer类型的service,所有内部流量都通过此云负载均衡器进入集群,该负载均衡器将流量路由到istio-ingressgateway的envoy容器。

apiVersion: v1kind: Servicemetadata:  labels:    app: istio-ingressgateway    istio: ingressgateway    release: istio  name: istio-ingressgateway  namespace: istio-systemspec:  ports:  - name: status-port    port: 15021    targetPort: 15021  - name: http2    port: 80    targetPort: 8080  - name: https    port: 443    targetPort: 8443  - name: tls    port: 15443    targetPort: 15443  selector:    app: istio-ingressgateway    istio: ingressgateway  type: LoadBalancer
出于性能思考,咱们应该讲.spec.externalTrafficPolicy设置为local模式,防止二跳。

其余包含HPA,PDB以及RBAC等资源。

单集群多Gateway

有时创立多个ingress gateway也很有用。例如,在一个十分大的集群中,有成千上万的服务,您可能不想通过一个云负载均衡器和一个部署来驱动所有内部流量,但心愿程度分担负载。

部署多个Gateway,比较简单,参照上一步部署,留神更改一下命名,复制多个部署即可。

那咱们如何抉择ingress gateway那?通过selector抉择。如下:

metadata:  name: gatewayspec:  selector:    istio: second-istio-ingressgateway

配置

Ingress Gateway 不蕴含任何流量路由配置。Ingress 流量的路由应用 Istio 路由规定来配置,和外部服务申请齐全一样。

让咱们一起来看如何为 HTTP 流量在 80 端口上配置 Gateway

  1. 创立 Istio Gateway
$ kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:  name: httpbin-gatewayspec:  selector:    istio: ingressgateway # use Istio default gateway implementation  servers:  - port:      number: 80      name: http      protocol: HTTP    hosts:    - "httpbin.example.com"EOF
  1. 为通过 Gateway 的入口流量配置路由:
$ kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:  name: httpbinspec:  hosts:  - "httpbin.example.com"  gateways:  - httpbin-gateway  http:  - match:    - uri:        prefix: /status    - uri:        prefix: /delay    route:    - destination:        port:          number: 8000        host: httpbinEOF

已为 httpbin 服务创立了虚构服务配置,蕴含两个路由规定,容许流量流向门路 /status/delay

gateways 列表规约了哪些申请容许通过 httpbin-gateway 网关。 所有其余内部申请均被回绝并返回 404 响应。

安全性

应用 SDS 为 Gateway 提供 HTTPS 加密反对

能够配置 TLS Ingress Gateway ,让它从 Ingress Gateway 代理通过 SDS 获取凭据。Ingress Gateway 代理和 Ingress Gateway 在同一个 Pod 中运行,监督 Ingress Gateway 所在命名空间中新建的 Secret。在 Ingress Gateway 中启用 SDS 具备如下益处:

  • Ingress Gateway 无需重启,就能够动静的新增、删除或者更新密钥/证书对以及根证书。
  • 无需加载 Secret 卷。创立了 kubernetes`Secret 之后,这个 Secret` 就会被 Gateway 代理捕捉,并以密钥/证书对和根证书的模式发送给 Ingress Gateway 。
  • Gateway 代理可能监督多个密钥/证书对。只须要为每个主机名创立 Secret 并更新 Gateway 定义就能够了。

无 TLS 终止的 Ingress Gateway

配置 Ingress Gateway 以执行 SNI 透传,而不是对传入申请进行 TLS 终止。例如:

apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:  name: mygatewayspec:  selector:    istio: ingressgateway # use istio default ingress gateway  servers:  - port:      number: 443      name: https      protocol: HTTPS    tls:      mode: PASSTHROUGH    hosts:    - nginx.example.com