NOTE: 1 year after i wrote this, I found it in my “drafts”. I don’t recall why i haven’t published it. Since 1 year has passed, I decided to publish AS-IS.
There are only guides but it took forever (aka more than 1 day) to set everything up and working. Here a list of the things I did to make everything working.
The result is that:
- Nginx is used as ingress, (nginx-ingress) and an ingress resource is used to route to your service
- TLS for the connection, issued by letsencrypt
- static IP and DNS set up to your domain
Let’s go step by step.
0. Assumptions:
It’s assumed that you have a Kubernetes cluster with services running, Helm installed and working.
Setup a static IP and DNS
From the Google console create a static IP (give a name you like), not it down somewhere.
Create a DNS record that points to that IP, in my case it’s api.k8s.chino.io
Helm Templates
The tricky part is to have a correct helm configuration (then generate Kubernetes instructions correctly). In the templates folder, I’ve this ingress.yaml file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{{- if .Values.ingress.enabled -}} | |
{{- $serviceName := include "fullname" . -}} | |
{{- $servicePort := .Values.service.targetPort -}} | |
apiVersion: extensions/v1beta1 | |
kind: Ingress | |
metadata: | |
name: {{ template "fullname" . }} | |
labels: | |
app: {{ template "fullname" . }} | |
chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" | |
release: "{{ .Release.Name }}" | |
heritage: "{{ .Release.Service }}" | |
annotations: | |
{{- range $key, $value := .Values.ingress.annotations }} | |
{{ $key }}: {{ $value }} | |
{{- end }} | |
spec: | |
rules: | |
– host: "{{ .Values.ingress.dnsNames }}" | |
http: | |
paths: | |
– path: / | |
backend: | |
serviceName: {{ $serviceName }} | |
servicePort: {{ $servicePort }} | |
{{- if .Values.ingress.tls }} | |
tls: | |
{{ toYaml .Values.ingress.tls | indent 4 }} | |
{{- end -}} | |
{{- end -}} |
(note that your deployment must use ClusterIP and the port is the targetPort, in my case is 8000 and not 80)
then I created a certificate.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
apiVersion: certmanager.k8s.io/v1alpha1 | |
kind: Certificate | |
metadata: | |
name: {{.Values.certificate.secretName}} | |
spec: | |
secretName: {{.Values.certificate.secretName}} | |
issuerRef: | |
name: {{.Values.certificate.certIssuer}} | |
dnsNames: | |
– {{.Values.certificate.dnsNames}} | |
acme: | |
config: | |
– http01: | |
ingressClass: {{.Values.certificate.ingressClass}} | |
domains: | |
{{- range .Values.certificate.domains }} | |
– {{ . }} | |
{{- end }} |
and this in values.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
certificate: | |
secretName: chino-io-tls-prod | |
certIssuer: letsencrypt-prod | |
dnsNames: api.k8s.chino.io | |
ingressClass: nginx | |
domains: | |
– api.k8s.chino.io | |
ingress: | |
dnsNames: api.k8s.chino.io | |
enabled: true | |
annotations: | |
kubernetes.io/ingress.class: nginx | |
certmanager.k8s.io/cluster-issuer: letsencrypt-prod | |
tls: | |
– secretName: chino-io-tls-prod | |
hosts: | |
– api.k8s.chino.io |
Briefly, this will create an ingress for the service that resolves the url set in the values. Plus creates a certificate, using the letsencrypt prod system (you can use staging for test environment, we go on this later on).
Install nginx-ingress
First of all install nginx-ingress using helm, set it to use your static ip.
helm install --name nginx-ingress --set controller.service.loadBalancerIP=YOURSTATICIP stable/nginx-ingress
Install cert-manager
First, create the issuer by using this yaml file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
apiVersion: certmanager.k8s.io/v1alpha1 | |
kind: Issuer | |
metadata: | |
name: letsencrypt-prod | |
namespace: default | |
spec: | |
acme: | |
# The ACME server URL | |
server: https://acme-v02.api.letsencrypt.org/directory | |
# Email address used for ACME registration | |
email: email@example.com | |
# Name of a secret used to store the ACME account private key | |
privateKeySecretRef: | |
name: letsencrypt-prod | |
# Enable the HTTP-01 challenge provider | |
http01: {} |
(the value letsencrypt-prod is used in the values.yaml and links to this one)
Then launch the cert manager with helm
helm install --name cert-manager stable/cert-manager
this will take care of generating the certificate.
Launch your helm
launch the helm that you updated at the beginning. everything should be working and having the TLS enabled.