傳統上,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