Exposing HTTP
While pods are not accessible from outside the cluster, you can expose the http services provided by pods by using the Ingress controllers. In general we don’t allow exposing non-http applications via TCP ports, but if you really need to do that, contact us on Matrix.
For a complete example see the (Tutorial)
Refer to the haproxy ingress documentation to set up additional config.
To expose a port in your pod, you first need to create a service for it. For the pod
apiVersion: v1kind: Podmetadata: name: my-pod labels: k8s-app: test-httpspec: containers: - name: mypod image: nginxdemos/hello:plain-text
The service might look like:
apiVersion: v1kind: Servicemetadata: labels: k8s-app: test-svc name: test-svcspec: ports: - port: 8080 protocol: TCP targetPort: 80 selector: k8s-app: test-http type: ClusterIP
Where spec.selector.<label>
should match the label of the target pod (k8s-app: test-http
), and targetPort
should match the port you want to expose. You can test the pod/service by creating a tunnel (kubectl port-forward service/test-svc 8080:80
) and querying service (curl http://localhost:8080/
).
After that you can create the Ingress object:
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: annotations: kubernetes.io/ingress.class: haproxy name: test-ingressspec: rules: - host: test-service.nrp-nautilus.io http: paths: - path: / pathType: Prefix backend: service: name: test-svc port: number: 8080 tls: - hosts: - test-service.nrp-nautilus.io
You can choose the host subdomain to be whatever you want (<whatever>.nrp-nautilus.io
). This is enough to have your pod served under test-service.nrp-nautilus.io
. You can test this example via curl (curl https://test-service.nrp-nautilus.io
)
Using my own domain name
If you need to use your own domain, you would have to also provide a valid certificate in a secret in your namespace:
apiVersion: v1kind: Secretmetadata: name: my-own-hostname-tlstype: kubernetes.io/tlsdata: ca.crt: <optional base64-encoded ca> tls.crt: <base64-encoded crt> tls.key: <base64-encoded key>
and add a section to the Ingress:
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: annotations: kubernetes.io/ingress.class: haproxy name: test-ingressspec: rules: - host: my-own-hostname.com http: paths: - backend: service: name: test-svc port: number: 8080 path: / pathType: Prefix tls: - hosts: - my-own-hostname.com secretName: my-own-hostname-tls
Create the CNAME DNS record for your domain pointing to nrp-nautilus.io
(for geo-balanced multi-region DNS record) or east.nrp-nautilus.io
(just the eastern region).
Auto renewing the certificate
The Cert Manager installed in our cluster supports auto retrieving and updating ACME Let’s Encrypt certificates. To set up the HTTP challenge, create an issuer:
apiVersion: cert-manager.io/v1kind: Issuermetadata: name: letsencryptspec: acme: email: <your_email> preferredChain: "" privateKeySecretRef: name: issuer-account-key server: https://acme-v02.api.letsencrypt.org/directory solvers: - http01: ingress: class: haproxy ingressTemplate: metadata: annotations: ingress.kubernetes.io/ssl-redirect: "false" serviceType: ClusterIP
And then request the new certificate:
apiVersion: cert-manager.io/v1kind: Certificatemetadata: annotations: name: my-own-hostname-certspec: commonName: my-own-hostname.com dnsNames: - my-own-hostname.com issuerRef: kind: Issuer name: letsencrypt secretName: my-own-hostname-tls
Check the status of your certificate:
kubectl get certificate -o wide
If STATUS
is not Certificate is up to date and has not expired
, use kubectl describe certificate ...
and kubectl describe order ...
to debug the problem.
Once the certificate was issued, refer to the previous section to use one in your Ingress.