DEV Community

Jello
Jello

Posted on Edited on

Issuing wildcard certificates on Kubernetes Gateway API (Part 2/2)

If you have followed part1 you should should have cert-manager already running.

All the files are available on github: https://github.com/angjelo/cloud-infra

Let's see how we can build the following infrustrcture by using cilium and the gateway api.

Initially we need to create a gateway class and specify the controller that our gateway will be using, I am using cilium on my cluster that's why I have set controllerName: io.cilium/gateway-controller

apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
  name: cillium-gateway-class
spec:
  controllerName: io.cilium/gateway-controller
Enter fullscreen mode Exit fullscreen mode

After you have successfully created the gateway controller lets define the gateway which will be our entrypoint.
Few things:

  • The annotations field allows you to attach additional metadata to the resource. In this case, an annotation is used to specify the cluster issuer for certificates issued by Cert-Manager (a Kubernetes add-on for certificate management)
  • cert-manager.io/cluster-issuer:cloudflare-domain-issuer refers to the cluster-issuer that we created in part1
  • The secret used in the field certificateRefs is defined in the certificate.yml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
  name: fine-ops-gateway
  annotations:
    cert-manager.io/cluster-issuer: cloudflare-domain-issuer
spec:
  gatewayClassName: cillium-gateway-class
  listeners:
    - name: https
      hostname: "*.fine-ops.com"
      port: 443
      protocol: HTTPS
      tls:
        mode: Terminate
        certificateRefs:
        - kind: Secret
          name: fine-ops
Enter fullscreen mode Exit fullscreen mode

if we execute kubectl get svc then we shoulld see a public IP assigned to our gateway, if you are on aws usually you will get an ELB address that you can use to point to point your CNAME cloudflare

⚠️ Important Note: if you delete and recreate the gateway the load balancer will populate a new ip which you need to update manually on cloudflare



Now that we have defined our main entry point lets create our

  • tls-route
  • service
  • deployment for test-app1

This will be the nginx app deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-app1
  namespace: default
  labels:
    app: test-app1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: test-app1
  template:
    metadata:
      labels:
        app: test-app1
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        imagePullPolicy: Always
Enter fullscreen mode Exit fullscreen mode

kubectl apply -f test-app1-deployment.yml

To view if the pods are deployed successfully kubectl get pods

Now is time to create a service to expose the port internally in kubernetes:

apiVersion: v1
kind: Service
metadata:
  name: test-app1
  namespace: default
  labels:
    app: test-app1
spec:
  ports:
  - port: 80
    name: http
  selector:
    app: test-app1
Enter fullscreen mode Exit fullscreen mode

kubectl get svc to see if the service was created

Se we can see that test-app1 has been exposed to an internal IP. Now it's time create the tls-route and attach it to the service that we exposed earlier

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: test-app-1
spec:
  parentRefs:
  - name: fine-ops-gateway
    sectionName: https
  hostnames:
    - "fe-1.fine-ops.com"
  rules:
    - matches:
      - path:
          type: PathPrefix
          value: /
        method: GET
      backendRefs:
      - name: test-app1
        port: 80
Enter fullscreen mode Exit fullscreen mode

Lets break down some keypoints in the yaml:

  • parentRefs refers to the gateway name that we created earlier (fine-ops-gateway)
  • We are referencing the service created earlier for test-app1 validate that the route was created: kubectl get httproutes

Now that we have have created our http route, we can try to access the service on https://fe-1.fine-ops.com (make sure you have created an A record that points the Loadbalancer IP of the cilium gateway)

Now that we have deployed fe-1.fine-ops.com it time to deploy fe-2.fine-ops.com

Let's start again by creating the second deployment, similar to the previous nginx deployment but the app name is different this time

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-app2
  namespace: default
  labels:
    app: test-app2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test-app2
  template:
    metadata:
      labels:
        app: test-app2
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        imagePullPolicy: Always
Enter fullscreen mode Exit fullscreen mode

After verifying that the pods are running it is time to create the service to internally expose the port to kubernetes

apiVersion: v1
kind: Service
metadata:
  name: test-app2
  namespace: default
  labels:
    app: test-app2
spec:
  ports:
  - port: 90
    name: http
    targetPort: 80
  selector:
    app: test-app2
Enter fullscreen mode Exit fullscreen mode

Not it is time to create the TLS route for fe-2.fine-ops.com

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: http-app-2
spec:
  parentRefs:
  - name: fine-ops-gateway
    namespace: default
  hostnames:
    - "fe-2.fine-ops.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
      method: GET
    backendRefs:
    - name: test-app2
      port: 90
Enter fullscreen mode Exit fullscreen mode

kubectl get httproutes should display these routes

Lastly we need to add a new A for fe-2.fine-ops.com record to point to the load balancer IP,this is how the records should look like in cloudflare

Now you can visit fe-2.yourdomain.com

Top comments (0)