↓ Skip to main content
Security

Cert-Manager: TLS for ingress

A common use-case for cert-manager is requesting TLS signed certificates to secure your ingress resources.

cert-manager adds certificates and certificate issuers as resource types in Kubernetes clusters, and simplifies the process of obtaining, renewing and using those certificates.

Installation
#

The easiest way is to use helm charts.

helm repo add jetstack https://charts.jetstack.io
root@master>helm repo list
NAME                    URL                                                                                         
stable                  https://charts.helm.sh/stable                                                                                                        
jetstack                https://charts.jetstack.io
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.7.1 \
  --set prometheus.enabled=false \
  --set webhook.timeoutSeconds=4 \
  --set installCRDs=true

Once deployed you can see the k8s objects deployed

root@master>k get all -n cert-manager
NAME                                           READY   STATUS    RESTARTS   AGE
pod/cert-manager-86f4f985d6-ntgtf              1/1     Running   0          7d23h
pod/cert-manager-cainjector-56bc5f744c-tdhx6   1/1     Running   0          7d23h
pod/cert-manager-webhook-997b5dd88-4jbmf       1/1     Running   0          7d23h

NAME                           TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/cert-manager           ClusterIP   10.100.35.73   <none>        9402/TCP   67d
service/cert-manager-webhook   ClusterIP   10.96.67.112   <none>        443/TCP    67d

NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/cert-manager              1/1     1            1           67d
deployment.apps/cert-manager-cainjector   1/1     1            1           67d
deployment.apps/cert-manager-webhook      1/1     1            1           67d

NAME                                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/cert-manager-57d89b9548              0         0         0       67d
replicaset.apps/cert-manager-86f4f985d6              1         1         1       7d23h
replicaset.apps/cert-manager-cainjector-56bc5f744c   1         1         1       7d23h
replicaset.apps/cert-manager-cainjector-5bcf77b697   0         0         0       67d
replicaset.apps/cert-manager-webhook-997b5dd88       1         1         1       7d23h
replicaset.apps/cert-manager-webhook-9cb88bd6d       0         0         0       67d

Example
#

>kubectl get Issuers,ClusterIssuers,Certificates,CertificateRequests,Orders,Challenges -A

Issuers
#

NAMESPACE           NAME                                          READY   AGE
cert-manager-test   issuer.cert-manager.io/test-selfsigned        True    7d21h
jenkins             issuer.cert-manager.io/jenkins-selfsigned     True    6d18h
spinnaker           issuer.cert-manager.io/spinnaker-selfsigned   True    7d21h
NAMESPACE           NAME                                            READY   SECRET                AGE
cert-manager-test   certificate.cert-manager.io/selfsigned-cert     True    selfsigned-cert-tls   7d21h
jenkins             certificate.cert-manager.io/jenkinsdevops.com   True    jenkinsdevops.com     6d18h
spinnaker           certificate.cert-manager.io/devops.com          True    devops.com            7d19h
spinnaker           certificate.cert-manager.io/selfsigned-cert     True    devops.com            7d21h
NAMESPACE           NAME                                                         APPROVED   DENIED   READY   ISSUER                 REQUESTOR                                         AGE
cert-manager-test   certificaterequest.cert-manager.io/selfsigned-cert-hnd85     True                True    test-selfsigned        system:serviceaccount:cert-manager:cert-manager   7d21h
jenkins             certificaterequest.cert-manager.io/jenkinsdevops.com-75hdn   True                True    jenkins-selfsigned     system:serviceaccount:cert-manager:cert-manager   6d18h
spinnaker           certificaterequest.cert-manager.io/devops.com-g6b2m          True                True    spinnaker-selfsigned   system:serviceaccount:cert-manager:cert-manager   5d22h
spinnaker           certificaterequest.cert-manager.io/devops.com-rz6db          True                True    spinnaker-selfsigned   system:serviceaccount:cert-manager:cert-manager   5d23h
spinnaker           certificaterequest.cert-manager.io/devops.com-wzs4h          True                True    spinnaker-selfsigned   system:serviceaccount:cert-manager:cert-manager   5d22h
spinnaker           certificaterequest.cert-manager.io/selfsigned-cert-mfggn     True                True    spinnaker-selfsigned   system:serviceaccount:cert-manager:cert-manager   7d21h

After Installation, Configure
#

The first thing you’ll need to configure after you’ve installed cert-manager is an issuer which you can then use to issue certificates.

Before you begin
#

Issuers & ClusterIssuer
#

Issuers, and ClusterIssuers, are Kubernetes resources that represent certificate authorities (CAs) that are able to generate signed certificates by honoring certificate signing requests.

Example – Issuer
#

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: jenkins-selfsigned
  namespace: jenkins
spec:
  selfSigned: {}

Example – ClusterIssuer
#

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: selfsigned-cluster-issuer
spec:
  selfSigned: {}
An Issuer is a namespaced resource, and it is not possible to issue certificates from an Issuer in a different namespace.

If you want to create a single Issuer that can be consumed in multiple namespaces, you should consider creating a ClusterIssuer resource.

Certificate
#

A Certificate is a namespaced resource that references an Issuer or ClusterIssuer that determine what will be honoring the certificate request.

When a Certificate is created, a corresponding CertificateRequest resource is created by cert-manager containing the encoded X.509 certificate request, Issuer reference, and other options based upon the specification of the Certificate resource.

Securing Ingress
#

As I conclude the blog, let me use the deployed cert-manager to secure the TLS deployment for my spinnaker instance.

Supported Annotations in Ingress: https://cert-manager.io/docs/usage/ingress/#supported-annotations

In our example we will use mostly

  • cert-manager.io/issuer
  • cert-manager.io/cluster-issuer

Deployed Spinnaker Pods
#

root@master>k get pods -n spinnaker
NAME                                  READY   STATUS    RESTARTS   AGE
minio-5bbd54df5b-qnfvs                1/1     Running   0          8d
spin-clouddriver-ddd75554c-tts9z      1/1     Running   0          45h
spin-deck-649d97f44f-kp59x            1/1     Running   0          8d
spin-echo-9587cdc9d-gm7pt             1/1     Running   0          4d16h
spin-front50-7dbbb7668-qpr5f          1/1     Running   0          5d23h
spin-gate-69b9f88748-pppwm            1/1     Running   0          5d23h
spin-igor-6bcc768f9c-fzr8c            1/1     Running   0          47h
spin-orca-68ff75b6f8-r6872            1/1     Running   0          5d23h
spin-redis-864dff6b7-82m55            1/1     Running   0          8d
spin-rosco-68dc887685-sm9p8           1/1     Running   0          5d23h

Services
#

root@master>k get svc -n spinnaker
NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
minio                 ClusterIP   10.96.179.180    <none>        9000/TCP   8d
spin-clouddriver      ClusterIP   10.107.86.175    <none>        7002/TCP   8d
spin-deck             ClusterIP   10.106.159.232   <none>        9000/TCP   8d
spin-echo             ClusterIP   10.98.31.29      <none>        8089/TCP   8d
spin-front50          ClusterIP   10.106.148.148   <none>        8080/TCP   8d
spin-gate             ClusterIP   10.105.124.157   <none>        8084/TCP   8d
spin-igor             ClusterIP   10.99.29.79      <none>        8088/TCP   5d23h
spin-orca             ClusterIP   10.103.240.238   <none>        8083/TCP   8d
spin-redis            ClusterIP   10.99.134.213    <none>        6379/TCP   8d
spin-rosco            ClusterIP   10.110.22.96     <none>        8087/TCP   8d

I will use the Ingress to expose the UI and API

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    haproxy.org/cors-allow-origin: "*.devops.com"
    haproxy.org/ingress.class: haproxy
    cert-manager.io/issuer: "spinnaker-selfsigned"
    cert-manager.io/common-name: "devops.com"
  name: spinnaker-ingress
  namespace: spinnaker
spec:
  ingressClassName: haproxy
  rules:
  - host: ui.devops.com
    http:
      paths:
      - backend:
          service:
            name: spin-deck
            port:
              number: 9000
        path: /
        pathType: Prefix
  - host: api.devops.com
    http:
      paths:
      - backend:
          service:
            name: spin-gate
            port:
              number: 8084
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - ui.devops.com
    - api.devops.com
    secretName: devops.com

Please note the annotation cert-manager.io/issuer: "spinnaker-selfsigned" applied to the ingress once the resource is created using kubectl create -f <yaml>

k get ing -n spinnaker
NAME                  CLASS     HOSTS                                                 ADDRESS          PORTS     AGE
spinnaker-ingress     haproxy   ui.devops.com,api.devops.com,clouddriver.devops.com   10.98.117.100    80, 443   7d21h
Author
Samarthya
Engineer, learner, tinkerer. This is my trophy shelf of everyday work and leisure.

Related

Spinnaker: docker-registry

You will need a valid docker registry before you add any trigger in the pipeline in Spinnaker Official documentation is a good resource to seek more clarifications — Spinnaker In my case I have already added an account my-docker-registry as under (The final result after you successfully configure Docker.