The Ingress Object via API

In the previous chapter, we explored Kubernetes Services (ClusterIP, NodePort) and how they provide stable internal IP addresses and basic load balancing for Pods. While NodePort and type: LoadBalancer Services can expose applications outside the cluster, they operate primarily at Layer 4 (TCP/UDP) and have limitations:

  • Each LoadBalancer Service typically provisions a separate cloud load balancer, which can be costly.

  • NodePort exposes services on high-numbered ports across all nodes, which isn't ideal for standard web traffic (ports 80/443).

  • Neither Service type inherently understands HTTP/S concepts like hostnames, URL paths, or TLS termination for routing traffic.

This is where Kubernetes Ingress comes in. Ingress provides a way to manage external access to services within the cluster, specifically focusing on Layer 7 (HTTP/S) routing. It acts as a smart router or reverse proxy, allowing you to define rules that direct external HTTP/S traffic to different internal Services based on requested hostnames or URL paths.

Critically, the Ingress resource itself doesn't do anything on its own. It's a configuration object that defines routing rules. You need an Ingress Controller (a separate application running in your cluster, like Nginx Ingress, Traefik, HAProxy Ingress, etc.) that reads these Ingress resources and configures the underlying proxy (e.g., Nginx) to implement the specified rules.

In this chapter, we'll focus on creating and managing Ingress resources programmatically using client-go. Let's start by examining the structure of the Ingress object in the API.

The Ingress Object via API (networking.k8s.io/v1.Ingress)

The stable version of the Ingress resource resides in the networking.k8s.io API group, version v1. When working with client-go, you'll primarily interact with the networkingv1.Ingress struct (k8s.io/api/networking/v1).

Like other Kubernetes objects, the key definitions are within the metadata and spec fields.

metadata

Includes the standard fields like name, namespace, labels, and annotations. Annotations are often heavily used by specific Ingress Controllers to configure controller-specific behavior (e.g., rewrite rules, authentication, timeouts) beyond the standard Ingress spec.

spec (v1.IngressSpec)

This defines the desired state of the Ingress routing rules and configuration.

  • spec.ingressClassName (string, optional but standard practice): This field links the Ingress resource to a specific Ingress Controller installed in the cluster. An IngressClass resource (a separate cluster-scoped object) defines parameters for an Ingress Controller. The Ingress Controller typically only processes Ingress resources that reference its associated IngressClassName. If omitted, behavior might depend on whether a default IngressClass is configured in the cluster, but explicitly setting it is recommended for clarity and predictability.

    # Example Ingress Spec Snippet - IngressClassName
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-app-ingress
      namespace: default
    spec:
      ingressClassName: "nginx-public" # Links to an IngressClass handled by a specific Nginx controller
      # ... rules, tls etc below
  • spec.rules ([]v1.IngressRule): This is the core of the Ingress, defining the routing logic. It's a list, allowing multiple rules within one Ingress resource. Each IngressRule contains:

    • host (string, optional): If specified, this rule only applies to requests matching this hostname (e.g., myapp.example.com). Wildcards (like *.example.com) are allowed. If omitted, the rule applies to all hostnames routed to the Ingress Controller.

    • http (*v1.HTTPIngressRuleValue): Contains the path-based routing rules for the specified host (or for all hosts if host is omitted). This has a paths field:

      • paths ([]v1.HTTPIngressPath): A list of path rules, processed in order by many controllers. Each HTTPIngressPath has:

        • path (string): The URL path prefix or exact path to match (e.g., /api, /login).

        • pathType (string): Specifies how the path should be matched. Crucial types:

          • Prefix: Matches URL paths prefixed by the path value (e.g., /api matches /api/users, /api/). This is common.

          • Exact: Matches the URL path exactly.

          • ImplementationSpecific: Matching depends on the ingressClassName. Usually defaults to behavior similar to Prefix.

        • backend (v1.IngressBackend): Defines where to forward requests matching this host/path combination. The key part is the service field:

          • service (*v1.IngressServiceBackend): Specifies the target Kubernetes Service.

            • name (string): The name of the Service to forward traffic to.

            • port (v1.ServiceBackendPort): Specifies the port on the target Service. Can be defined by:

              • number (int32): The specific port number of the Service.

              • name (string): The name of the port defined in the Service's spec.ports. Using the name is generally more robust.

    # Example Ingress Spec Snippet - Rules
    spec:
      ingressClassName: "nginx-public"
      rules:
      - host: "app.example.com" # Rule for specific hostname
        http:
          paths:
          - path: /login # Path within the host
            pathType: Prefix
            backend:
              service:
                name: login-service # Target service
                port:
                  name: http # Target named port on the service
          - path: /api/v1
            pathType: Prefix
            backend:
              service:
                name: api-v1-service
                port:
                  number: 8080 # Target port number on the service
      - http: # Rule applies if host doesn't match above (or if no host header)
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-service
                port:
                  name: http
  • spec.tls ([]v1.IngressTLS, optional): Configures TLS termination. The Ingress Controller terminates the encrypted connection from the client using the specified certificate, then forwards unencrypted (usually) traffic to the backend Service/Pods. This is a list, allowing different certificates for different hosts. Each IngressTLS entry contains:

    • hosts ([]string, optional): A list of hostnames covered by the TLS certificate specified in secretName. The certificate must be valid for these hosts. If omitted, the certificate is used for any host in the rules that doesn't have a specific TLS entry (often used for a default certificate).

    • secretName (string): The name of a Kubernetes Secret residing in the same namespace as the Ingress resource. This Secret must be of type kubernetes.io/tls and contain the tls.crt (certificate chain) and tls.key (private key) data. The Ingress Controller needs permission to read this Secret.

    # Example Ingress Spec Snippet - TLS
    spec:
      ingressClassName: "nginx-public"
      tls:
      - hosts:
        - app.example.com # This cert applies only to this host
        secretName: my-app-tls-secret # Name of the TLS secret
      # - hosts: # Could add another entry for a different host/cert
      #   - "*.internal.example.com"
      #   secretName: internal-wildcard-tls
      rules:
      # ... rules matching the hosts defined in tls section ...
  • spec.defaultBackend (*v1.IngressBackend, optional): Specifies a default Service to handle any requests that don't match any of the defined rules. If this is not set and no rules match, the Ingress Controller typically returns a 404 Not Found error.

The Ingress resource provides a powerful way to declare how external HTTP/S traffic should be routed to internal services. By creating and managing these objects using client-go, you can programmatically control application exposure, automate TLS certificate management integration, and build sophisticated traffic management solutions. Next, we'll look at the concept of Ingress Controllers in slightly more detail.

Last updated

Was this helpful?