Dynamic, whitelabel-style Ingress to your application¶
If your application allows for end-customers to use their custom domain, we've offered Caddy to provide on-demand SSL certificates for a while.
However with our Kubernetes reference solution there is a more native and scalable solution through the Nginx Ingress Controller and Cert-manager.
Our recommended way is that your application interacts directly with the Kubernetes API to register (and de-register) Ingress objects on-demand. You can find a list of official and community-supported K8s client libraries in the documentation.
Via the API you can submit an Ingress for the end-customer's domain, for example:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/tls-acme: "true"
labels:
use-http-solver: "true"
name: www-example-com
namespace: my-namespace
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
name: http
tls:
- secretName: www-example-com-tls
hosts:
- www.example.com
Here's an example of how to create such Ingress via the Node.js K8s library: https://github.com/kubernetes-client/javascript/blob/master/examples/ingress.js.
Of course your application will also need credentials and the correct permissions to allow interaction with the K8s API. This can be controlled through Service Accounts and RBAC.
Create a ServiceAccount:
Create a Role with the proper permissions:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-app
namespace: my-namespace
rules:
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
Create a RoleBinding to attach the Role to the ServiceAccount:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-app
namespace: my-namespace
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: my-app
subjects:
- kind: ServiceAccount
name: my-app
namespace: my-namespace
Set the ServiceAccount for your Pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: my-namespace
spec:
template:
metadata:
# ...
spec:
serviceAccountName: my-app
containers:
# ...
This will automount the service account's Secret in your Pod and you can extract the required credentials from the following location:
- Token:
/var/run/secrets/kubernetes.io/serviceaccount/token - CA cert:
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
As endpoint of the API server it is recommended to use kubernetes.default.svc.
Note
Most client libraries will automatically pick up these credentials.
For more information on accessing the API from a Pod, and an example using the Go client library, check out the official documentation: https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#accessing-the-api-from-a-pod.