Install and Configure Istio service mesh

In the world of microservices, managing the complexities of service-to-service communication, security, and observability can be a significant challenge. This is where Istio, an open-source service mesh, comes in. Istio provides a transparent and language-independent way to connect, secure, control, and observe services.

While Cloudfleet provides robust L4 load balancing out-of-the-box, Istio’s Ingress Gateway unlocks a full suite of L7 capabilities, making it a premier ingress controller for your applications. In this tutorial, we’ll walk you through how to install Istio on your CFKE cluster using a production-grade configuration, enabling you to leverage the power of a service mesh with the simplicity and power of Cloudfleet.

Prerequisites

Before we begin, make sure you have the following:

Step 1: Download and Prepare Istio

First, you need to download the latest Istio release and prepare your environment.

  1. Download the Istio release:

    curl -L https://istio.io/downloadIstio | sh -
    
  2. Navigate into the Istio directory. The directory name will vary depending on the version you downloaded. This is your working directory for the rest of the tutorial.

    cd istio-*
    
  3. Add the istioctl client to your shell’s path:

    export PATH=$PWD/bin:$PATH
    

Step 2: Configure a Production-Grade Istio Installation

Instead of using a default profile, we will create a custom IstioOperator resource. This gives us fine-grained control over the installation, allowing us to optimize for performance, cost, and security on Cloudfleet.

Create a file named istio-operator.yaml and paste the following configuration into it:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  # A unique name to prevent installation of multiple control planes
  name: istio-cfke
spec:
  # Specify the image hub
  hub: gcr.io/istio-release
  components:
    # Configuration for the Istio control plane (Pilot)
    pilot:
      k8s:
        # Pin the control plane to nodes from a specific provider and region
        # This is a key advantage of Cloudfleet's multi-cloud capabilities
        nodeSelector:
          cfke.io/provider: hetzner
          topology.kubernetes.io/region: nbg1

    # Configuration for the public-facing Ingress Gateway, our L7 entry point
    ingressGateways:
      - name: istio-ingressgateway
        enabled: true
        label:
          istio-gateway: istio-ingressgateway
        k8s:
          # Also pin the gateway to the same provider and region for optimal routing
          nodeSelector:
            cfke.io/provider: hetzner
            topology.kubernetes.io/region: nbg1
          # This service will become a LoadBalancer, managed by Cloudfleet, giving us a stable external IP
          service:
            # Use 'Local' traffic policy to avoid extra network hops, improving latency and cost
            externalTrafficPolicy: Local
            type: LoadBalancer

    # Enable the Istio CNI for enhanced security and performance
    # [https://istio.io/latest/docs/setup/additional-setup/cni/](https://istio.io/latest/docs/setup/additional-setup/cni/)
    cni:
      enabled: true
      namespace: kube-system

  # Advanced configuration values
  values:
    pilot:
      env:
        # Use the more efficient native Kubernetes sidecars
        ENABLE_NATIVE_SIDECARS: true
    global:
      # Use smaller, more secure distroless images
      variant: distroless

Why This Configuration Rocks on Cloudfleet:

  • Advanced L7 Ingress Control: Cloudfleet Kubernetes Engine provides powerful and reliable L4 (TCP/UDP) load balancing out-of-the-box via the LoadBalancer service type. This is perfect for exposing TCP services directly. However, for modern applications, you need L7 (HTTP/S) routing for features like path-based routing (/service-a vs. /service-b), host-based routing, and TLS termination. Istio’s Ingress Gateway acts as a sophisticated ingress controller, building on top of Cloudfleet’s L4 load balancer to provide these critical L7 features. You get the best of both worlds: Cloudfleet’s managed infrastructure and Istio’s advanced application-aware routing.
  • Provider-Specific Scheduling (nodeSelector): You’re telling Istio’s control plane and ingress gateway to run only on nodes provided by Hetzner in the nbg1 region. This is a powerful Cloudfleet feature that lets you optimize for cost and data locality. Naturally, Hetzner is just an example. You can use any supported cloud or self-managed node on Cloudfleet.
  • Efficient Traffic Routing (externalTrafficPolicy: Local): This ensures that incoming traffic is routed directly to a gateway pod on the node that received it, preventing extra, potentially cross-zone network hops. See here to learn how externalTrafficPolicy: Local works in Cloudfleet’s global architecture.

Step 3: Install Istio Using the Custom Configuration

Now, apply your custom IstioOperator configuration using istioctl:

istioctl install -f istio-operator.yaml -y

This command will install Istio precisely as you’ve defined. You should see a confirmation message once the installation is complete.

✔ Istio core installed ✔ Istiod installed ✔ CNI installed ✔ Ingress gateways installed ✔ Installation complete

Next, label the default namespace to enable automatic sidecar injection for your applications:

kubectl label namespace default istio-injection=enabled

Step 4: Deploy and Route to Real-World Services

Now for the real-world example. We’ll deploy two simple “hello world” web applications and then use Istio’s Gateway and VirtualService to route traffic to them based on the URL path.

  1. Create a file named sample-apps.yaml with the following content. This defines two applications, hello-cloudfleet and hello-istio, each with a Deployment and a Service.

    apiVersion: v1
    kind: Service
    metadata:
      name: hello-cloudfleet
      labels:
        app: hello-cloudfleet
    spec:
      ports:
      - port: 8080
        name: http
      selector:
        app: hello-cloudfleet
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-cloudfleet
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: hello-cloudfleet
      template:
        metadata:
          labels:
            app: hello-cloudfleet
        spec:
          containers:
          - name: web
            image: gcr.io/google-samples/hello-app:1.0
            ports:
            - containerPort: 8080
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: hello-istio
      labels:
        app: hello-istio
    spec:
      ports:
      - port: 8080
        name: http
      selector:
        app: hello-istio
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-istio
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: hello-istio
      template:
        metadata:
          labels:
            app: hello-istio
        spec:
          containers:
          - name: web
            image: gcr.io/google-samples/hello-app:2.0
            ports:
            - containerPort: 8080
    
  2. Create a file named routing.yaml for the Istio resources. This Gateway opens port 80 to the world, and the VirtualService directs traffic based on the URI.

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: http-gateway
    spec:
      selector:
        istio: ingressgateway # use istio default ingress gateway
      servers:
      - port:
          number: 80
          name: http
          protocol: HTTP
        hosts:
        - "*"
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: path-router
    spec:
      hosts:
      - "*"
      gateways:
      - http-gateway
      http:
      - match:
        - uri:
            prefix: /cloudfleet
        route:
        - destination:
            host: hello-cloudfleet
            port:
              number: 8080
      - match:
        - uri:
            prefix: /istio
        route:
        - destination:
            host: hello-istio
            port:
              number: 8080
    
  3. Apply the configurations:

    kubectl apply -f sample-apps.yaml
    kubectl apply -f routing.yaml
    
  4. Get the external IP address of your ingress gateway. It might take a minute for the cloud provider to assign the IP.

    kubectl get svc istio-ingressgateway -n istio-system
    

    Look for the EXTERNAL-IP value.

  5. Test the routing! Replace <EXTERNAL-IP> with the address from the previous step.

    • This request should be routed to the hello-cloudfleet app:
      curl http://<EXTERNAL-IP>/cloudfleet
      # Expected output: Hello, world! Version: 1.0.0
      
    • This request should be routed to the hello-istio app:
      curl http://<EXTERNAL-IP>/istio
      # Expected output: Hello, world! Version: 2.0.0
      

Conclusion

You have now successfully deployed a production-grade Istio service mesh on your Cloudfleet Kubernetes Engine cluster. By using a custom IstioOperator resource, you’ve not only tailored the installation for a secure and efficient mesh but also deployed a powerful ingress controller. With a practical example of path-based routing, you’ve seen how to manage traffic to different backend services through a single entry point, leveraging CFKE’s powerful features to create a highly available and performant ingress for your applications.

Istio does much more than load balancing. Explore Istio features like traffic splitting, retries, and observability to further enhance your microservices architecture. For more information on Istio, check out the official documentation.