Technical Theory

Managing Ingress Traffic with Gateway API

Introduction

This tutorial guides you through using the Artifact Hub OCI Gateway API to manage Ingress traffic in Kubernetes. We’ll cover setting up a Kubernetes cluster, deploying an Ingress controller, interacting with the Artifact Hub OCI Gateway API, and verifying the traffic routing.

Prerequisites:

  • A Kubernetes cluster (e.g., Minikube, Kind, or a cloud-based cluster).
  • kubectl configured to interact with your cluster.
  • Basic understanding of Kubernetes concepts like Pods, Services, and Ingress.
  • curl or a similar tool for making HTTP requests.
  • An Artifact Hub account (optional, for publishing your own Ingress resources).

Task 1: Deploying an Ingress Controller

An Ingress controller is responsible for routing external traffic to the appropriate Services within your cluster. We’ll use the Nginx Ingress Controller.

  1. Apply the manifest for the Nginx Ingress Controller:

    NODE_TYPE // bash
    kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.5/deploy/static/provider/cloud/deploy.yaml
    Replace controller-v1.9.5 with the latest version available from the ingress-nginx repository.

    This command deploys the necessary resources for the Nginx Ingress Controller. It may take a few minutes for the controller to be ready.

  2. Verify the Ingress controller is running:

    NODE_TYPE // bash
    kubectl get pods -n ingress-nginx
    NODE_TYPE // output
    NAME                                        READY   STATUS    RESTARTS   AGE
    ingress-nginx-controller-6b8c6b959f-mql4p   1/1     Running   0          2m

Task 2: Deploying Sample Applications

Let’s deploy two simple applications that we’ll route traffic to using Ingress.

  1. Create a deployment.yaml file with the following content:

    NODE_TYPE // yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: app-one
      labels:
        app: app-one
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: app-one
      template:
        metadata:
          labels:
            app: app-one
        spec:
          containers:
          - name: app-one
            image: nginx:latest
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: app-one-service
    spec:
      selector:
        app: app-one
      ports:
      - protocol: TCP
        port: 80
        targetPort: 80
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: app-two
      labels:
        app: app-two
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: app-two
      template:
        metadata:
          labels:
            app: app-two
        spec:
          containers:
          - name: app-two
            image: httpd:latest
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: app-two-service
    spec:
      selector:
        app: app-two
      ports:
      - protocol: TCP
        port: 80
        targetPort: 80
  2. Apply the deployment:

    NODE_TYPE // bash
    kubectl apply -f deployment.yaml
    NODE_TYPE // output
    deployment.apps/app-one created
    service/app-one-service created
    deployment.apps/app-two created
    service/app-two-service created
  3. Verify the deployments and services are running:

    NODE_TYPE // bash
    kubectl get deployments,services
    NODE_TYPE // output
    NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/app-one      1/1     1            1           1m
    deployment.apps/app-two      1/1     1            1           1m
    
    NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
    service/app-one-service   ClusterIP   10.108.189.233   <none>        80/TCP    1m
    service/app-two-service   ClusterIP   10.98.138.191    <none>        80/TCP    1m
    service/kubernetes      ClusterIP   10.96.0.1        <none>        443/TCP   4h2m

Task 3: Creating an Ingress Resource

Now, let’s define an Ingress resource to route traffic to our applications based on hostnames.

  1. Create an ingress.yaml file with the following content:

    NODE_TYPE // yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      rules:
      - host: appone.example.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app-one-service
                port:
                  number: 80
      - host: apptwo.example.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app-two-service
                port:
                  number: 80

    This Ingress resource will route traffic to app-one-service when the hostname is appone.example.com and to app-two-service when the hostname is apptwo.example.com.

  2. Apply the Ingress resource:

    NODE_TYPE // bash
    kubectl apply -f ingress.yaml
    NODE_TYPE // output
    ingress.networking.k8s.io/my-ingress created
  3. Get the Ingress details

    NODE_TYPE // bash
    kubectl get ingress
    NODE_TYPE // output
    NAME         CLASS   HOSTS                               ADDRESS         PORTS   AGE
    my-ingress   nginx   appone.example.com,apptwo.example.com   192.168.49.2   80      10s

Task 4: Interacting with the Artifact Hub OCI Gateway API

The Artifact Hub OCI Gateway API allows you to manage Ingress resources as OCI artifacts. While the specifics of the API interaction (authentication, registry details, etc.) depend on your Artifact Hub setup, the general process involves:

  1. Publishing Ingress Resources:

    You would package your ingress.yaml as an OCI artifact and push it to an OCI registry that the Artifact Hub OCI Gateway is configured to watch. This typically involves using tools like oras.

    NODE_TYPE // bash
    # Example using oras (replace with your registry and artifact details)
    oras push <your-oci-registry>/<your-artifact-name>:v1 ingress.yaml:application/x-yaml
    Consult the Artifact Hub documentation for specific instructions on packaging and pushing OCI artifacts.
  2. Retrieving Ingress Resources:

    The Artifact Hub OCI Gateway then makes these Ingress resources available via an API endpoint. The format of the API endpoint will depend on your Artifact Hub setup.

    NODE_TYPE // bash
    # Example (replace with the correct API endpoint)
    curl -X GET "https://<your-artifact-hub-gateway>/api/v1/ingresses/<your-artifact-name>"

    The API response would contain the YAML definition of your Ingress resource, which you could then apply to your Kubernetes cluster.

  3. Applying Ingress Resources (programmatically):

    You can use kubectl apply to apply the retrieved Ingress definition. This can be automated in a CI/CD pipeline or other management tools.

    NODE_TYPE // bash
    # Example (assuming you have jq installed and the Ingress YAML in a file)
    curl -s "https://<your-artifact-hub-gateway>/api/v1/ingresses/<your-artifact-name>" | jq -r '.spec' > ingress.yaml
    kubectl apply -f ingress.yaml
    The Artifact Hub OCI Gateway API details (endpoint, authentication, etc.) are highly specific to your deployment. Consult your Artifact Hub administrator for the correct information.

Task 5: Verifying Traffic Routing

To verify that the Ingress is routing traffic correctly, you need to update your local machine’s /etc/hosts file (or use a DNS server) to point appone.example.com and apptwo.example.com to the IP address of your Ingress controller.

  1. Get the external IP address of the Ingress controller:

    NODE_TYPE // bash
    kubectl get service -n ingress-nginx ingress-nginx-controller

    If you are using Minikube, you can use the Minikube IP:

    NODE_TYPE // bash
    minikube ip
    NODE_TYPE // output
    192.168.49.2
  2. Edit your /etc/hosts file (you will need administrator privileges):

    NODE_TYPE // bash
    sudo vi /etc/hosts
  3. Add the following lines to the /etc/hosts file, replacing 192.168.49.2 with the actual IP address of your Ingress controller:

    NODE_TYPE // text
    192.168.49.2  appone.example.com
    192.168.49.2  apptwo.example.com
  4. Access the applications in your browser:

    • Open http://appone.example.com in your browser. You should see the default Nginx page (served by app-one).
    • Open http://apptwo.example.com in your browser. You should see the default Apache page (served by app-two).

Conclusion

In this tutorial, you learned how to use the Artifact Hub OCI Gateway API to manage Ingress traffic in Kubernetes. You deployed an Ingress controller, defined Ingress resources, and verified that traffic was routed correctly based on hostnames. You explored the concepts of publishing and retrieving Ingress resources as OCI artifacts via the Artifact Hub OCI Gateway API. Remember to consult your Artifact Hub administrator for the specific API endpoint and authentication details for your deployment.

Next Topic