I want to deploy everything as a knative service, including the root of the domain.

Update: I found an easyier way.

Easy way

Turn on auto-tls and autocreate-cluster-domain-claims:

1
  kubectl patch configmap config-network --namespace knative-serving -p '{"data":{"auto-tls":"Enabled","autocreate-cluster-domain-claims":"true"}}'

Then

1
kn domain create gitgratitude.com --ref=homepage

That's it.

Hardway

Left here for the record.

Add ingress-nginx

1
2
3
  helm upgrade --install ingress-nginx ingress-nginx \
       --repo https://kubernetes.github.io/ingress-nginx \
       --namespace ingress-nginx --create-namespace

Configure letsencrypt

Make sure to change your email address

nginx-certs.yml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod-nginx
spec:
  acme:
    # You must replace this email address with your own.
    # Let's Encrypt will use this to contact you about expiring
    # certificates, and issues related to your account.
    email: wschenk@gmail.com
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      # Secret resource that will be used to store the account's private key.
      name: prod-issuer-account-key-nginx
    # Add a single challenge solver, HTTP01 using nginx
    solvers:
    - http01:
        ingress:
          class: nginx
1
  kubectl apply -f nginx-certs.yaml

DNS

Find the ip

1
  kubectl --namespace ingress-nginx get service ingress-nginx-controller -o json| jq ".status.loadBalancer.ingress[0].ip"
"137.184.240.185"

Create DNS entry

1
  doctl compute domain records create gitgratitude.com --record-type A --record-data 137.184.240.185 --record-name \@
ID           Type    Name    Data               Priority    Port    TTL     Weight
280663245    A       @       137.184.240.185    0           0       1800    0

Add a simple knative service

We are setting the min scale to 1 so there's no startup time for this service.

1
  kubectl service create homepage --image gcr.io/knative-samples/homepage --scale-min 1

Which will result in this being deployed internally as http://homepage.default.svc.cluster.local

Simple reverse proxy service

Code

This is available on https://github.com/wschenk/proxy

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
  const http = require('http');
  const httpProxy = require('http-proxy');

  const remote = process.env.REMOTE_TARGET || "http://homepage.default.svc.cluster.local";

  console.log( "Proxy starting up on port 3000" );
  console.log( `Proxing to ${remote}` );

  httpProxy.createProxyServer({
      target: remote,
      changeOrigin: true
  }).listen(3000);

I'm packaging this up at ghcr.io/wschenk/proxy

Setup the proxy service

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  kind: Deployment
  apiVersion: apps/v1
  metadata:
    name: homepage-proxy
  spec:
    replicas: 1
    selector:
      matchLabels:
        app: homepage-proxy
    template:
      metadata:
        labels:
          app: homepage-proxy
      spec:
        containers:
          - name: homepage-proxy
            image: ghcr.io/wschenk/proxy
            imagePullPolicy: Always
            ports:
              - containerPort: 3000
                name: http
            env:
            - name: REMOTE_TARGET
              value: http://homepage.default.svc.cluster.local

  ---
  apiVersion: v1
  kind: Service
  metadata:
    name: homepage-proxy

  spec:
    ports:
      - protocol: TCP
        port: 80
        targetPort: http
    selector:
      app: homepage-proxy
1
  kubectl apply -f proxy.yaml
deployment.apps/homepage-proxy configured
service/homepage-proxy unchanged

Create ingress.yaml

ingress.yaml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    name: gitgratitude-root
    annotations:
      # add an annotation indicating the issuer to use.
      cert-manager.io/cluster-issuer: letsencrypt-prod-nginx
      kubernetes.io/tls-acme: "true"
  spec:
    ingressClassName: nginx
    tls:
      - hosts:
        - gitgratitude.com
        secretName: gratitude-root-tls
    rules:
      - host: gitgratitude.com
        http:
          paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name:  homepage-proxy
                  port:
                    number: 80
1
  kubectl apply -f ingress.yaml
ingress.networking.k8s.io/gitgratitude-root configured

Testing

1
kn service update helloworld-go --env TARGET="World"
1
  curl https://gitgratitude.com
Hello World!
1
kn service update helloworld-go --env TARGET="from knative"
1
  curl https://gitgratitude.com
Hello from knative!

Conclusion

The reverse proxy is a little bit weird, since we are proxying through a couple of different layers, but this allows us to deploy everything as a knative service.

Previously

Setting up knative functions functions functions

2021-11-29

Next

NextJS with Prisma on Kubernetes deploy as a knative service

2021-12-08

howto

Previously

Setting up knative functions functions functions

2021-11-29

Next

NextJS with Prisma on Kubernetes deploy as a knative service

2021-12-08