Deploying custom Istio gateways
Create an IstioOperator
(IOP) custom resource that defines your own ingress and egress gateways for Istio-managed app traffic.
By default, one istio-ingressgateway
deployment is created in the istio-system
namespace of your cluster. This deployment is exposed as a public load balancer service with an externally accessible IP address. You can
then define ports for your Istio-managed apps in a Gateway
resource, which configures the istio-ingressgateway
load balancer to listen for inbound HTTP/TCP traffic to those ports. Additionally, one istio-egressgateway
is created by default and is exposed as a load balancer service to managing outbound traffic from your Istio-managed apps.
However, you might want to create additional ingress or egress gateway deployments beyond these default gateways. For example, you might create additional gateways to run alongside the default gateways or to run in place of the default gateways for the following reasons:
- Separate traffic flows between certain workloads or namespaces
- Create an ingress gateway for private network traffic
- Modify a gateway with customizations, such as gateway pod node affinity, minimum replicas, and zone-specific load balancers
- Control gateway version updates independently of automatic version updates that are rolled out for all components of the managed Istio add-on
Considerations
Before you begin, review the following considerations for using custom gateways.
- The managed Istio add-on does not manage or reconcile any custom gateways that you create. You are responsible for creating, managing, and maintaining these resources.
- After you deploy your custom gateway, check the Istio operator pod logs for syntax errors by running
kubectl logs -n ibm-operators -l name=addon-istio-operator
. The Istio operator validates and reconciles any customIstioOperator
(IOP) changes that you make. If you notice a reconcile loop, indicated by theinfo installer Reconciling IstioOperator
repeating in the logs, follow the steps to find the line in the configuration that is causing the loop error. - Additionally, ensure that the
istio-global-proxy-accessLogFile
option in themanaged-istio-custom
ConfigMap is set to"/dev/stdout"
. Envoy proxies print access information to their standard output, which you can view by runningkubectl logs
commands for the Envoy containers.
Creating a custom ingress gateway for public traffic
Use an IstioOperator
(IOP) to create a custom ingress gateway deployment and public load balancer service in a custom-gateways
namespace.
-
Create a namespace for the custom ingress gateway.
kubectl create namespace custom-gateways
-
Create a YAML file that is named
custom-ingress-iop.yaml
for anIstioOperator
(IOP) resource. To force the custom gateway pods to run a specific version of managed Istio, specify the version in thetag
field. For more information, see Controlling custom gateway updates and versions.apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: namespace: ibm-operators name: custom-ingressgateway-iop spec: profile: empty hub: icr.io/ext/istio # tag: 1.23.1 components: ingressGateways: - name: custom-ingressgateway label: istio: custom-ingressgateway namespace: custom-gateways enabled: true k8s: serviceAnnotations: service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type: public
-
Create the
IstioOperator
(IOP) resource in your cluster. The managed Istio operator in theibm-operators
namespace uses the IOP resource to deploy and expose the ingress gateway in thecustom-gateways
namespace with a public load balancer service.kubectl apply -f ./custom-ingress-iop.yaml
-
Verify that the ingress gateway deployment and service are created in the
custom-gateways
namespace.kubectl get deploy,svc -n custom-gateways
Example output
NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/custom-ingressgateway 1/1 1 1 4m53s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/custom-ingressgateway LoadBalancer 172.21.98.120 52.117.68.222 15020:32656/TCP,80:30576/TCP,443:32689/TCP,15029:31885/TCP,15030:30198/TCP,15031:32637/TCP,15032:30869/TCP,31400:30310/TCP,15443:31698/TCP 4m53s
-
In the output for the
service/custom-ingressgateway
load balancer, note the IP address (classic clusters) or hostname (VPC clusters) in theEXTERNAL-IP
column.
You can now specify the name of this ingress gateway load balancer, custom-ingressgateway
, in a Gateway
resource that defines the port for your Istio-managed app. Then, you can specify the name of the Gateway
in a VirtualService
resource that defines the paths for the microservices in your service mesh. For an example of using a Gateway
and VirtualService
with your custom gateway load balancer, try the
BookInfo sample app.
Set up the BookInfo sample
Deploy the BookInfo sample application for Istio to test access to your custom ingress gateway load balancer.
- Create a
bookinfo
namespace and label the namespace for automatic sidecar injection.kubectl create namespace bookinfo kubectl label namespace bookinfo istio-injection=enabled
- Deploy the BookInfo sample app. Replace
<version>
with the major.minor version that your managed Istio add-on runs, which you can find by runningibmcloud ks cluster addon ls -c <cluster_name_or_ID>
.kubectl apply -n bookinfo -f https://raw.githubusercontent.com/istio/istio/release-<version>/samples/bookinfo/platform/kube/bookinfo.yaml
- Ensure that the BookInfo microservices and their corresponding pods are deployed.
kubectl get svc -n bookinfo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE details ClusterIP 172.21.19.104 <none> 9080/TCP 2m kubernetes ClusterIP 172.21.0.1 <none> 443/TCP 1d productpage ClusterIP 172.21.168.196 <none> 9080/TCP 2m ratings ClusterIP 172.21.11.131 <none> 9080/TCP 2m reviews ClusterIP 172.21.117.164 <none> 9080/TCP 2m
kubectl get pods -n bookinfo
NAME READY STATUS RESTARTS AGE details-v1-6865b9b99d-7v9h8 2/2 Running 0 2m productpage-v1-f8c8fb8-tbsz9 2/2 Running 0 2m ratings-v1-77f657f55d-png6j 2/2 Running 0 2m reviews-v1-6b7f6db5c5-fdmbq 2/2 Running 0 2m reviews-v2-7ff5966b99-zflkv 2/2 Running 0 2m reviews-v3-5df889bcff-nlmjp 2/2 Running 0 2m
- Create a YAML file called
bookinfo-custom-gateway.yaml
to defineGateway
andVirtualService
resources. Note that theGateway
resource specifiescustom-ingressgateway
for the name of the custom ingress load balancer that you previously created, and theVirtualService
resource specifiesbookinfo-gateway
for the name of theGateway
resource.apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: bookinfo-gateway spec: selector: istio: custom-ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: bookinfo spec: hosts: - "*" gateways: - bookinfo-gateway http: - match: - uri: exact: /productpage - uri: prefix: /static - uri: exact: /login - uri: exact: /logout - uri: prefix: /api/v1/products route: - destination: host: productpage port: number: 9080
- Create the
Gateway
andVirtualService
resources in your cluster.kubectl apply -f bookinfo-custom-gateway.yaml -n bookinfo
- Using the IP address (classic) or hostname (VPC) that you found for the
service/custom-ingressgateway
load balancer in the previous section, open the product page for the BookInfo app in a browser.http://<IP_OR_HOSTNAME>/productpage
Your custom ingress gateway load balancer now uses the port in the Gateway
resource and the microservice paths in the VirtualService
resource to route traffic to the BookInfo app. Next, you can optionally create a DNS record for the custom gateway load balancer.
Exposing BookInfo by using an IBM-provided subdomain with TLS
Create an IBM-provided subdomain to register the IP address (classic) or hostname (VPC) of the custom gateway load balancer with a DNS record. The TLS certificate that is generated for the subdomain enables HTTPS connections to the BookInfo app.
-
Register the IP address or hostname of the custom gateway load balancer by creating a DNS subdomain. Specify the
custom-gateway
namespace for the TLS secrets.- Classic clusters
ibmcloud ks nlb-dns create classic --cluster <cluster_name_or_id> --ip <LB_IP> --secret-namespace custom-gateways
- VPC clusters
ibmcloud ks nlb-dns create vpc-gen2 -c <cluster_name_or_ID> --lb-host <LB_hostname> --secret-namespace custom-gateways
- Classic clusters
-
Verify that the subdomain is created.
ibmcloud ks nlb-dns ls --cluster <cluster_name_or_id>
Example output for classic clusters
Hostname IP(s) Health Monitor SSL Cert Status SSL Cert Secret Name mycluster-a1b2cdef345678g9hi012j3kl4567890-0001.us-south.containers.appdomain.cloud ["168.1.1.1"] None created <certificate>
Example output for VPC clusters
Subdomain Load Balancer Hostname Health Monitor SSL Cert Status SSL Cert Secret Name mycluster-a1b2cdef345678g9hi012j3kl4567890-0001.us-south.containers.appdomain.cloud ["1234abcd-us-south.lb.appdomain.cloud"] None created <certificate>
-
Get the name of the secret for your subdomain.
kubectl get secret -n custom-gateways
Example output
mycluster-af23f234rwr3asdfasdf-002 kubernetes.io/tls 2 15m
-
In the
bookinfo-custom-gateway.yaml
that you created in the previous section, modify thebookinfo-gateway
Gateway
resource by adding an HTTPS port 443 and a TLS section that specifies your subdomain's secret.apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: bookinfo-gateway spec: selector: istio: custom-ingressgateway servers: - port: number: 443 name: https protocol: HTTPS tls: mode: SIMPLE credentialName: mycluster-af23f234rwr3asdfasdf-002 # secret name hosts: - "*" --- ...
-
Create the modified
Gateway
resource in your cluster.kubectl apply -f bookinfo-custom-gateway.yaml -n bookinfo
-
In a web browser, open the BookInfo product page. Ensure that you use HTTPS for the subdomain that you found in step 2.
https://<subdomain>/productpage
Creating a custom ingress gateway for private network traffic
To create a custom ingress gateway deployment and expose it with a private load balancer service, follow the steps in Creating a custom ingress gateway for public traffic. When you create the IOP
in step 3, specify the service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type: private
annotation, instead of public
.
Note the following considerations:
- If your classic cluster is connected to private VLANs only, or if your VPC cluster has only the private cloud service endpoint enabled, a private load balancer is created by default when you apply the IOP.
- For classic clusters only, you can't use the
ibmcloud ks nlb-dns create classic
to create a DNS record and IBM-provided subdomain for the IP address of the custom gateway load balancer.
Controlling custom gateway updates and versions
Manually update and control the managed Istio version of custom ingress gateways.
IBM Cloud keeps all your Istio components up-to-date by automatically rolling out patch updates to the most recent version of Istio that is supported by IBM Cloud Kubernetes Service. For example, when patch version 1.23.1 is released, all ingress gateway pods are automatically updated to this latest patch version. Patch versions are completed by using the rolling update strategy to avoid downtime for your apps. However, you might want to prevent automatic updates of custom gateway pods, such as if you want to test for any potential regressions with the latest patch version.
To manage updates for your custom ingress gateways, you might use the following rollout strategy:
- Create a custom ingress gateway IOPs. In the
tag
field, specify a patch version that is the same or earlier than the control plane version. You can find the control plane version by runningistioctl version
. - When a new patch version is released for the managed Istio add-on, edit the IOP YAML file for one custom gateway to use the latest patch version, and re-apply the IOP in your cluster.
- After the custom gateway's pods are updated to the latest patch, test any changes to the custom gateway.
- When you are satisfied with the changes, modify the configurations for the rest of your custom gateways to update them to the latest patch.
Do not set the tag to a version that is later than your Istio add-on's control plane version.
Update your custom gateway pods as soon as possible after a version is released. Custom gateways that run earlier versions can be exposed to security vulnerabilities.
Additional gateway customizations
Custom ingress gateways can be configured with additional customizations, including deploying the gateway load balancer to a specific zone, specifying the minimum number of gateway pod replicas, scheduling custom gateway pods onto edge nodes,
adding preStop
lifecycle hooks for graceful shutdowns, and specifying anti-affinity and worker node affinity.
Review examples of these additional customizations in the following IOP YAML file.
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: ibm-operators
name: custom-ingressgateway-iop
spec:
profile: empty
hub: icr.io/ext/istio
# tag: 1.23.1 # Force the gateway to a specific managed Istio version
components:
ingressGateways:
- name: custom-ingressgateway
label:
istio: custom-ingressgateway
namespace: custom-gateways
enabled: true
k8s:
serviceAnnotations:
service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type: public
service.kubernetes.io/ibm-load-balancer-cloud-provider-zone: "dal12" # Deploy the load balancer to a specific zone in your cluster
hpaSpec: # Specify the minimum number of pod replicas
minReplicas: 2
tolerations: # Schedule the custom gateway pods onto edge nodes
- key: dedicated
value: edge
env:
- name: TERMINATION_DRAIN_DURATION
value: 30s
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- istio-ingressgateway
topologyKey: kubernetes.io/hostname
weight: 100
nodeAffinity: # Example node affinities to control the zone or the edge
preferredDuringSchedulingIgnoredDuringExecution: # Could be requiredDuringSchedulingIgnoredDuringExecution instead
nodeSelectorTerms:
- matchExpressions:
- key: ibm-cloud.kubernetes.io/zone
operator: In
values:
- "dal12" # Deploy the load balancer to a specific zone in your cluster
preferredDuringSchedulingIgnoredDuringExecution:
- preference:
matchExpressions:
- key: dedicated
operator: In
values:
- edge
weight: 100
Creating a custom egress gateway
In version 1.8 and later of the managed Istio add-on, you can create custom egress gateways. Egress gateways serve as the exit point for all outbound traffic from apps in the service mesh to external destinations.
For example, to create a custom egress gateway, you can apply the following YAML file for an IOP in your cluster.
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: ibm-operators
name: custom-egressgateway-iop
spec:
profile: empty
hub: icr.io/ext/istio
# tag: 1.23.1 # Force the Gateway to a specific version
components:
egressGateways:
- name: custom-egressgateway
label:
istio: custom-egressgateway
namespace: custom-gateways
enabled: true
For more information about configuring and using custom egress gateways, see the Istio open-source documentation.
Disabling the default gateways
If you don't need the default istio-ingressgateway
or istio-egressgateway
deployments after you create custom gateways, you can optionally disable them.
If you want you apps to be accessible to clients, ensure that at least one gateway load balancer is enabled and configured to route traffic to your apps. If you disable the default gateway load balancers in all zones, your app is no longer exposed and can't be accessed externally.
-
Edit the
managed-istio-custom
ConfigMap resource.kubectl edit cm managed-istio-custom -n ibm-operators
-
Disable the default ingress gateways by setting the
istio-ingressgateway-public-1|2|3-enabled
fields to"false"
.istio-ingressgateway-public-1-enabled: "false" istio-ingressgateway-public-2-enabled: "false" istio-ingressgateway-public-3-enabled: "false"
-
To disable the default egress gateway, add the
istio-egressgateway-public-1-enabled: "false"
field.istio-egressgateway-public-1-enabled: "false"
-
Save and close the configuration file.
-
Verify that the default gateway services are removed.
kubectl get svc -n istio-system