# 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.

  ```yaml
  # 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.

  ```yaml
  # 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.

  ```yaml
  # 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.
