#devops #http #kubernetes

First, use helm to install the ingress controller:

 1$ helm install stable/nginx-ingress --name nginx-ingress --set controller.publishService.enabled=true
 2NAME:   nginx-ingress
 3LAST DEPLOYED: ...
 4NAMESPACE: default
 5STATUS: DEPLOYED
 6
 7RESOURCES:
 8==> v1/ConfigMap
 9NAME                      DATA  AGE
10nginx-ingress-controller  1     0s
11
12==> v1/Pod(related)
13NAME                                            READY  STATUS             RESTARTS  AGE
14nginx-ingress-controller-7658988787-npv28       0/1    ContainerCreating  0         0s
15nginx-ingress-default-backend-7f5d59d759-26xq2  0/1    ContainerCreating  0         0s
16
17==> v1/Service
18NAME                           TYPE          CLUSTER-IP     EXTERNAL-IP  PORT(S)                     AGE
19nginx-ingress-controller       LoadBalancer  10.245.9.107   <pending>    80:31305/TCP,443:30519/TCP  0s
20nginx-ingress-default-backend  ClusterIP     10.245.221.49  <none>       80/TCP                      0s
21
22==> v1/ServiceAccount
23NAME           SECRETS  AGE
24nginx-ingress  1        0s
25
26==> v1beta1/ClusterRole
27NAME           AGE
28nginx-ingress  0s
29
30==> v1beta1/ClusterRoleBinding
31NAME           AGE
32nginx-ingress  0s
33
34==> v1beta1/Deployment
35NAME                           READY  UP-TO-DATE  AVAILABLE  AGE
36nginx-ingress-controller       0/1    1           0          0s
37nginx-ingress-default-backend  0/1    1           0          0s
38
39==> v1beta1/Role
40NAME           AGE
41nginx-ingress  0s
42
43==> v1beta1/RoleBinding
44NAME           AGE
45nginx-ingress  0s
46
47NOTES:
48...

Then wait for it to become available:

1$ kubectl get services -o wide -w nginx-ingress-controller

Then you need to add the jetstack helm repo:

1$ helm repo add jetstack https://charts.jetstack.io
2"jetstack" has been added to your repositories

Then, you can install cert-manager:

 1$ helm install --name cert-manager --namespace cert-manager jetstack/cert-manager --set installCRDs=true
 2NAME:   cert-manager
 3LAST DEPLOYED: ...
 4NAMESPACE: cert-manager
 5STATUS: DEPLOYED
 6
 7RESOURCES:
 8==> v1/ClusterRole
 9NAME                                    AGE
10cert-manager-edit                       3s
11cert-manager-view                       3s
12cert-manager-webhook:webhook-requester  3s
13
14==> v1/Pod(related)
15NAME                                     READY  STATUS             RESTARTS  AGE
16cert-manager-5d669ffbd8-rb6tr            0/1    ContainerCreating  0         2s
17cert-manager-cainjector-79b7fc64f-gqbtz  0/1    ContainerCreating  0         2s
18cert-manager-webhook-6484955794-v56lx    0/1    ContainerCreating  0         2s
19
20...
21
22NOTES:
23cert-manager has been deployed successfully!
24
25In order to begin issuing certificates, you will need to set up a ClusterIssuer
26or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).
27
28More information on the different types of issuers and how to configure them
29can be found in our documentation:
30
31https://docs.cert-manager.io/en/latest/reference/issuers.html
32
33For information on how to configure cert-manager to automatically provision
34Certificates for Ingress resources, take a look at the `ingress-shim`
35documentation:
36
37https://docs.cert-manager.io/en/latest/reference/ingress-shim.html

Lastly, set up an issuer which takes care of managing the certificates:

production-issuer.yaml

 1apiVersion: cert-manager.io/v1alpha2
 2kind: ClusterIssuer
 3metadata:
 4  name: letsencrypt-prod
 5spec:
 6  acme:
 7    server: https://acme-v02.api.letsencrypt.org/directory
 8    email: pieter@yellowduck.be
 9    privateKeySecretRef:
10      name: letsencrypt-production
11    solvers:
12    - http01:
13        ingress:
14          class: nginx

Deploy it:

1$ kubectl apply -f production-issuer.yaml
2clusterissuer.certmanager.k8s.io/letsencrypt-production created

Before we can issue the certificates, we need to create A records on the DNS server pointing to the load balancer. First, get the external IP address of the load balancer:

1$ kubectl get service nginx-ingress-controller
2NAME                       TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)                      AGE
3nginx-ingress-controller   LoadBalancer   10.0.254.55   52.136.238.205   80:30753/TCP,443:32721/TCP   17m

The external IP address is 52.136.238.205 in this case.

On the DNS server, add the following records:

1mywebsite.webhost.com A 52.136.238.205

Once you did this, create the ingress defintion:

ingress.yaml

 1apiVersion: extensions/v1beta1
 2kind: Ingress
 3metadata:
 4  name: ingress
 5  annotations:
 6    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
 7    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
 8    kubernetes.io/ingress.class: nginx
 9    certmanager.k8s.io/cluster-issuer: letsencrypt-production
10spec:
11  tls:
12  - hosts:
13    - mywebsite.webhost.com
14    secretName: letsencrypt-prod
15  rules:
16  - host: mywebsite.webhost.com
17    http:
18      paths:
19      - backend:
20          serviceName: <my-service>
21          servicePort: 80

Apply this as well and you're done.

1$ kubectl apply -f ingress.yaml

If you now browse to https://mywebsite.webhost.com, the correct content should show up and you should see that it's using a Let's Encrypt certificate.