传统上,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/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 容器。
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 等资源。
单集群多 Gateway
有时创立多个 ingress gateway 也很有用。例如,在一个十分大的集群中,有成千上万的服务,您可能不想通过一个云负载均衡器和一个部署来驱动所有内部流量,但心愿程度分担负载。
部署多个 Gateway,比较简单,参照上一步部署,留神更改一下命名,复制多个部署即可。
那咱们如何抉择 ingress gateway 那?通过 selector 抉择。如下:
metadata:
name: gateway
spec:
selector:
istio: second-istio-ingressgateway
配置
Ingress Gateway 不蕴含任何流量路由配置。Ingress 流量的路由应用 Istio 路由规定来配置,和外部服务申请齐全一样。
让咱们一起来看如何为 HTTP 流量在 80 端口上配置 Gateway
。
- 创立 Istio
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 具备如下益处:
- Ingress Gateway 无需重启,就能够动静的新增、删除或者更新密钥 / 证书对以及根证书。
- 无需加载
Secret
卷。创立了kubernetes
`Secret之后,这个
Secret` 就会被 Gateway 代理捕捉,并以密钥 / 证书对和根证书的模式发送给 Ingress Gateway。 - 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