Traditionally ,Kubernetes Use Ingress
Controller to handle traffic from outside into the cluster . Use Istio when , This is no longer the case . Istio Have used new Gateway
and VirtualServices
Resources replace the familiar Ingress
resources . They work together , Route traffic to the grid . Inside the grid , Unwanted Gateway
, Because services can access each other through cluster local service names .
As I mentioned in my previous article ,kubernetes Provided Ingress Too simple , The exposed attributes are too weak to express . Of course, the community is aware of the problem , from kubernetes1.19 edition , Gradually complete the function .Istio In solution , Did it on its own Istio gateway. In Africa istio Out of the scene ,gloo,ambasaador ,contour Equal gateway It can meet the needs of our production environment .
Deploy
Let's take a look at the community's default deployment .
adopt Deployment A group of managers istio-ingressgateway
Pod.
IngressGateway, This is a Envoy Encapsulation of agents . It is configured in the same way as the one used in the service grid Sidecar identical . When we create or change Gateway or VirtualService when ,Istio Pilot The controller will detect the change , The controller will convert this information into Envoy Configure and send it to the relevant agents , Include IngressGateway Inside 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
We are IngressGateway What you have to care about in deployment is SSL certificate . In order to be able to access gateway Certificates in resources , Please make sure the certificate is installed correctly .
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
because istio-ingressgateway
It mainly deals with boundary flow , So you have to create LoadBalancer Type of service, All external traffic enters the cluster through this cloud load balancer , The load balancer routes traffic to istio-ingressgateway
Of envoy Containers .
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
For performance reasons , We should say .spec.externalTrafficPolicy Set to local Pattern , Avoid two jumps .
Others include HPA,PDB as well as RBAC And so on .
More than one cluster Gateway
Sometimes create multiple ingress gateway It's also very useful. . for example , In a very large cluster , There are thousands of services , You may not want to drive all external traffic through a cloud load balancer and a deployment , But want to share the load horizontally .
Deploy multiple Gateway, Relatively simple , Refer to the previous step to deploy , Notice to change the name , Copy multiple deployments .
So how do we choose ingress gateway that ? adopt selector choice . as follows :
metadata:
name: gateway
spec:
selector:
istio: second-istio-ingressgateway
To configure
Ingress Gateway Does not contain any traffic routing configuration .Ingress The routing of traffic uses Istio Routing rules to configure , It's exactly the same as an internal service request .
Let's see how to do it for HTTP The flow in 80 Configuration on port Gateway
.
- establish 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
- For adoption
Gateway
To configure the route for the entry traffic of :
$ 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
Already been httpbin
The service created A virtual service To configure , Contains two routing rules , Allow traffic to flow to the path /status
and /delay
.
gateways The list specifies which requests are allowed to pass through httpbin-gateway
gateway . All other external requests are rejected and returned 404 Respond to .
Security
Use SDS by Gateway Provide HTTPS Encryption support
You can configure the TLS Ingress Gateway , Let it come from Ingress Gateway Agent through SDS Obtain the credentials .Ingress Gateway Agents and Ingress Gateway In the same Pod Run in , monitor Ingress Gateway Created in the namespace Secret
. stay Ingress Gateway Enable SDS It has the following advantages :
- Ingress Gateway No need to restart , You can dynamically add 、 Delete or update the key / Certificate pairs and root certificates .
- No load required
Secret
volume . Createdkubernetes
`Secretafter , This
Secret` Will be Gateway Agent capture , And with the key / Certificate pairs and root certificates are sent to Ingress Gateway . - Gateway Agents can monitor multiple keys / Certificate to . Just create... For each host name
Secret
And update the Gateway Definition is fine .
nothing TLS Terminated Ingress Gateway
To configure Ingress Gateway To carry out SNI transparent transmission , Not on incoming requests TLS End . for example :
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