传统上,Kubernetes应用Ingress
控制器来解决从内部进入集群的流量。应用Istio时,状况不再如此。 Istio已用新的Gateway
和VirtualServices
资源替换了相熟的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
。
- 创立 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
- 为通过
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