传统上,Kubernetes使用Ingress
控制器来处理从外部进入集群的流量。使用Istio时,状况再也不如此。 Istio已用新的Gateway
和VirtualServices
资源替换了熟悉的Ingress
资源。它们协同工做,将流量路由到网格中。在网格内部,不须要Gateway
,由于服务能够经过集群本地服务名称相互访问。node
正如我以前文章介绍过的,kubernetes提供的Ingress过于简单,暴露出来的属性表达性太弱。固然社区也意识到了这个问题,从kubernetes1.19 版本,在逐步补全功能。Istio解决方案中,本身实现了Istio gateway。在非istio场景外,gloo,ambasaador ,contour等网关 能够知足咱们生产环境的需求。
咱们看下社区默认的部署。nginx
经过Deployment管理的一组istio-ingressgateway
Pod。docker
IngressGateway,这是Envoy代理的封装。它的配置方式与服务网格中使用的Sidecar相同。当咱们建立或更改Gateway或VirtualService时,Istio Pilot控制器会检测到更改,该控制器会将这些信息转换为Envoy配置并将其发送到相关代理,包括IngressGateway内部的Envoy。api
apiVersion: apps/v1 kind: Deployment metadata: labels: app: istio-ingressgateway istio: ingressgateway release: istio name: istio-ingressgateway namespace: istio-system spec: 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容器。app
apiVersion: v1 kind: Service metadata: labels: app: istio-ingressgateway istio: ingressgateway release: istio name: istio-ingressgateway namespace: istio-system spec: 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等资源。负载均衡
有时建立多个ingress gateway也颇有用。例如,在一个很是大的集群中,有成千上万的服务,您可能不想经过一个云负载均衡器和一个部署来驱动全部外部流量,但但愿水平分担负载。dom
部署多个Gateway,比较简单,参照上一步部署,注意更改一下命名,复制多个部署便可。ide
那咱们如何选择ingress gateway那?经过selector选择。以下:性能
metadata: name: gateway spec: selector: istio: second-istio-ingressgateway
Ingress Gateway 不包含任何流量路由配置。Ingress 流量的路由使用 Istio 路由规则来配置,和内部服务请求彻底同样。
让咱们一块儿来看如何为 HTTP 流量在 80 端口上配置 Gateway
。
Gateway
:$ 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
Gateway
的入口流量配置路由:$ 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
已为 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 具备以下好处:
Secret
卷。建立了 kubernetes
`Secret 以后,这个
Secret` 就会被 Gateway 代理捕获,并以密钥/证书对和根证书的形式发送给 Ingress Gateway 。Secret
并更新 Gateway 定义就能够了。无 TLS 终止的 Ingress Gateway
配置 Ingress Gateway 以执行 SNI 透传,而不是对传入请求进行 TLS 终止。例如:
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: mygateway spec: selector: istio: ingressgateway # use istio default ingress gateway servers: - port: number: 443 name: https protocol: HTTPS tls: mode: PASSTHROUGH hosts: - nginx.example.com