helm repo add apisix https://charts.apiseven.com
helm update
KUBECONFIG=/etc/rancher/k3s/k3s.yaml helm install apisix apisix/apisix --set gateway.tls.enabled=true --set ingress-controller.enabled=true --namespace ingress-apisix
In this post I’ll explain how to deploy a ready to prod k8s cluster (with only 1 node) using k3s and exposing a service using https with an auto-provisioned certificate using Let’s Encrypt
As a plus we’ll install Apisix, an OpenSource ApiGateway, to allow grow up our stack with more nodes+applications
A Linux server with (min) 2Gb
A registered DNS, for example api.jorge.io
kubectl installed
helm installed
K3s is a light implementation of kubernetes ready to production. You can find more information at https://docs.k3s.io/installation
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--tls-san api.jorge.io" sh -
Apisix is an ApiGateway. You can use it as standalone, with docker or integrate into your cluster. It has a lot of plugins and features ready to be used in production
We’ll use a namespace for Apisix:
kubectl create namespace ingress-apisix
We’ll install a basic/typical implementation:
helm repo add apisix https://charts.apiseven.com
helm update
KUBECONFIG=/etc/rancher/k3s/k3s.yaml helm install apisix apisix/apisix --set gateway.tls.enabled=true --set ingress-controller.enabled=true --namespace ingress-apisix
CertManager is the agent able to create and provision certificates. It allows to create diferent kinds of certificates and talk with different CAs to create and install them as secrets into our cluster. For our we’ll use it to install free SSL certificates from Let’s Encrypt
helm repo add jetstack https://charts.jetstack.io --force-update
helm update
KUBECONFIG=/etc/rancher/k3s/k3s.yaml helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.14.4
We’ll check if Apisix is ready
kubectl get all -n ingress-apisix
Pods and services are up and running
First thing (can be also last, of course, it doesnt matter) will be to redirect all plain http requests to https
apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: redirect-https spec: redirectScheme: scheme: https permanent: true
kubectl apply -f traefik-https-redirect-middleware.yaml
Next, we’ll create the issuer:
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt namespace: ingress-apisix spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: jorge@edn.es privateKeySecretRef: name: letsencrypt solvers: - selector: {} http01: ingress: class: traefik
kubectl apply -f cluster-issuer.yaml
We’ve created a ClusterIssuer (so all nodes and all namespaces in the cluster will be able to use it)
It will negociate with Lets Encrypt using the http01
method via traefik and will create a
secret into the cluster named letsencrypt
(or whatever you specify)
Now, we’ll send all trafic to Apisix
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: spec.ingressClassName: traefik cert-manager.io/cluster-issuer: letsencrypt traefik.ingress.kubernetes.io/router.middlewares: default-redirect-https@kubernetescrd name: api-jorge-ingress namespace: ingress-apisix spec: rules: - host: api.jorge.io http: paths: - pathType: Prefix path: / backend: service: name: apisix-gateway port: number: 80 tls: - hosts: - api.jorge.io secretName: letsencrypt-cert
kubectl apply -f ingress.yml
Pay attention to the annotations, this is the "trick":
we will use the traekif ingress
we’re instructing to the certificate manager to use the previous issuer created
we’re instructing to traefil to redirect all plain http to https
we’re instructing we want to use a certificate from a secret (created by cert-manager)
Now all traffic will be served from our k3s cluster using https with a certificate created by Lets’Encrypt
Obviously we’ll have a 404 as Apisix doesn’t know what to do with the request
We’ll deploy a typical service (httpbin)
kubectl run httpbin --image kennethreitz/httpbin --namespace ingress-apisix
(We are creating a deploying httpbin using the public image kennethreitz/httpbin)
and exposing it
kubectl expose pod httpbin -n ingress-apisix --port 80
It only remains to "link" Apisix with the new httpbin service:
apiVersion: apisix.apache.org/v2 kind: ApisixRoute metadata: name: httpbin spec: http: - name: httpbin match: paths: - /* hosts: - api.jorge.io backends: - serviceName: httpbin servicePort: 8080
We are creating an ApisixRoute to route all requests to api.jorge.io
to the httpbin service.
And this is all. Right now a request from outside will follow:
traefik redirecting http to https
cert-manager negociate, creates and store the certificate
traefik redirect all requests to Apisix
Apisix determine which service to use (httpbin in our case)
httpbin response to the requests
2019 - 2024 | Mixed with Bootstrap | Baked with JBake v2.6.7 | Terminos Terminos y Privacidad