Managing TLS Termination via Ingress Spec
One of the most valuable features of Ingress is its ability to handle TLS (Transport Layer Security) termination. This means the Ingress Controller can terminate the encrypted HTTPS connection from the external client, process the routing rules based on the decrypted HTTP request (host, path), and then forward the traffic to your backend Services/Pods, typically over unencrypted HTTP within the cluster network.
This significantly simplifies application development:
Your application containers don't need to handle TLS certificates or encryption/decryption.
TLS certificate management (renewal, deployment) is centralized at the Ingress layer.
Configuration for TLS termination is done directly within the Ingress
resource's spec.tls
section.
The spec.tls
Section Revisited
As briefly introduced earlier, spec.tls
is a slice of networkingv1.IngressTLS
objects. Each entry in this slice associates one or more hostnames with a Kubernetes Secret containing the necessary TLS certificate and private key.
Hosts
([]string): Specifies which hostnames listed in the Ingress rules this particular TLS configuration applies to. The TLS handshake will only succeed if the hostname requested by the client is listed here (and matches the certificate's Common Name (CN) or Subject Alternative Names (SANs)). IfHosts
is omitted, the certificate inSecretName
might be used as a default/fallback certificate by some Ingress controllers.SecretName
(string): The name of the Kubernetes Secret that holds the certificate (tls.crt
) and private key (tls.key
). Crucially, this Secret MUST exist in the same namespace as the Ingress resource.
The TLS Secret (kubernetes.io/tls
)
The Secret referenced by SecretName
is not just any Secret; it must adhere to specific requirements:
Type: The Secret's
type
must bekubernetes.io/tls
.Data Keys: It must contain two specific keys in its
data
field:tls.crt
: The value must be the base64-encoded server certificate (and potentially intermediate certificates concatenated).tls.key
: The value must be the base64-encoded private key corresponding to the certificate.
You typically create such Secrets using kubectl create secret tls <secret-name> --cert=/path/to/cert.pem --key=/path/to/key.pem -n <namespace>
or by defining them in YAML.
Adding TLS Configuration Programmatically
Adding or modifying the spec.tls
section in your Go code follows the same principles as managing rules. You construct or modify the []networkingv1.IngressTLS
slice within your Ingress
struct before calling Create
or Update
.
Let's adapt the update example from the previous section. Suppose we want to ensure the app.example.com
host in our example-ingress
uses the TLS secret app-tls-secret
.
Explanation:
Find/Add Logic: We iterate through the existing
spec.TLS
slice.Check Secret: We look for an entry matching the desired
SecretName
.Check Host: If the secret entry exists, we check if our target
Host
is already listed. If not, we append it to theHosts
slice of that entry.Add New Entry: If no entry for the
SecretName
exists, we create a newnetworkingv1.IngressTLS
struct and append it to thespec.TLS
slice.Conditional Update: We introduce flags (
ruleUpdated
,tlsNeedsUpdate
) to track if we actually made any changes. We only callingressClient.Update
if a modification occurred, preventing unnecessary API calls and potential conflicts.
Prerequisites and Considerations:
Secret Existence: The referenced Secret (
app-tls-secret
) must exist in the same namespace before the Ingress Controller tries to use it. Creating the Ingress resource itself doesn't create the Secret.Secret Permissions: The Ingress Controller's Service Account needs RBAC permissions (usually
get
,list
,watch
) for Secrets in the namespaces it manages Ingress resources for.Certificate Management: Directly managing TLS Secrets via
kubectl
orclient-go
is feasible for a few certificates, but it quickly becomes complex to handle renewals. Tools like cert-manager are commonly used in Kubernetes to automate the issuance and renewal of TLS certificates (e.g., from Let's Encrypt) and automatically create/update the necessarykubernetes.io/tls
Secrets. Your Go code would then just reference theSecretName
managed by cert-manager.
Programmatically managing the spec.tls
section allows you to automate the configuration of secure external access for your applications, ensuring that the correct certificates are associated with the right hostnames as defined in your Ingress rules.
Last updated
Was this helpful?