DEV Community

Jello
Jello

Posted on • Updated on

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

Image description

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

Image description

⚠️ 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

Image description

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

Image description

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

Image description

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

Image description

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)

Image description

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

Image description

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
Image description

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

Image description

Now you can visit fe-2.yourdomain.com

Image description

Top comments (0)