Manage Ingress Certificates With Cert Manager
This tutorial will detail how to secure ingress using cert-manager.
Prerequisites#
- Prepare an available Kubernetes cluster in your workstation, we recommend you to use KIND to create a local Kubernetes cluster.
- Install Apache APISIX in Kubernetes by Helm Chart.
- Install apisix-ingress-controller.
- Install cert-manager.
In this guide, we assume that your APISIX is installed with ssl enabled, which is not enabled by default in the Helm Chart. To enable it, you need to set gateway.tls.enabled=true during installation.
For example, you could install APISIX and APISIX ingress controller by running:
helm install apisix apisix/apisix --set gateway.type=NodePort --set ingress-controller.enabled=true --set gateway.tls.enabled=true --set ingress-controller.config.apisix.serviceNamespace=defaultAssume that the SSL port is 9443.
Create Issuer#
For testing purposes, we will use a simple CA issuer. All required files can be found here.
To create a CA issuer, use the following commands:
kubectl apply -f ./cert-manager/ca.yamlkubectl apply -f ./cert-manager/issuer.yamlIf the cert-manager is working correctly, we should be able to see the Ready status by running:
kubectl get issuerIt should output:
NAME READY AGEca-issuer True 50sCreate Test Certificate#
To ensure that cert-manager is working properly, we can create a test Certificate resource.
apiVersion: cert-manager.io/v1kind: Certificatemetadata: name: demo-certspec: dnsNames: - example.com issuerRef: kind: Issuer name: ca-issuer secretName: example-cert usages: - digital signature - key enciphermentLike Issuer, we could see its readiness status by running:
kubectl get certificateIt should output:
NAME READY SECRET AGEdemo-cert True example.com 50sCheck the secrets by running:
kubectl get secretIt should output:
NAME TYPE DATA AGEexample.com kubernetes.io/tls 3 2m20sThis means that our cert-manager is working properly.
Create Test Service#
We use kennethreitz/httpbin as the service image.
Deploy it by running:
kubectl run httpbin --image kennethreitz/httpbin --expose --port 80Secure Ingress#
The cert-manager supports several ways to secure ingress. The easiest way is to use annotations.
By using annotations, we don't need to manage Certificate CRD manually.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: httpserver-ingress annotations: # add an annotation indicating the issuer to use. cert-manager.io/issuer: "ca-issuer"spec: # apisix-ingress-controller is only interested in Ingress # resources with the matched ingressClass name, in our case, # it's apisix. ingressClassName: apisix tls: - hosts: - local.httpbin.org # placing a host in the TLS config will determine what ends up in the cert's subjectAltNames secretName: ingress-cert-manager-tls # cert-manager will store the created certificate in this secret. rules: - host: local.httpbin.org http: paths: - path: / pathType: Prefix backend: service: name: httpbin port: number: 80The annotation cert-manager.io/issuer tells cert-manager which issuer should be used. The Issuer must be in the same namespace as the Ingress resource. Please read Securing Ingress Resources for more details.
We should now be able to see the certificate and secret resource created by cert-manager:
kubectl get certificatekubectl get secretIt should output:
NAME READY SECRET AGEingress-cert-manager-tls True ingress-cert-manager-tls 2m
NAME TYPE DATA AGEingress-cert-manager-tls kubernetes.io/tls 3 3mTest#
Run curl command in a APISIX pod to see if the Ingress and TLS configuration works.
kubectl -n <APISIX_NAMESPACE> exec -it <APISIX_POD_NAME> -- curl --resolve 'local.httpbin.org:9443:127.0.0.1' "https://local.httpbin.org:9443/ip" -kIt should output:
{ "origin": "127.0.0.1"}