Serving a knative function on the root

root to services

Published December 1, 2021 #kubernetes, #knative, #kourier

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:

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

Then

kn domain create gitgratitude.com --ref=homepage

That's it.

Hardway

Left here for the record.

Add ingress-nginx

  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:

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
  kubectl apply -f nginx-certs.yaml

DNS

Find the ip

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

Create DNS entry

  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.

  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

  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

  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
  kubectl apply -f proxy.yaml
deployment.apps/homepage-proxy configured
service/homepage-proxy unchanged

Create ingress.yaml

ingress.yaml:

  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
  kubectl apply -f ingress.yaml
ingress.networking.k8s.io/gitgratitude-root configured

Testing

kn service update helloworld-go --env TARGET="World"
  curl https://gitgratitude.com
Hello World!
kn service update helloworld-go --env TARGET="from knative"
  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.

References

  1. https://github.com/http-party/node-http-proxy#setup-a-basic-stand-alone-proxy-server

  2. https://www.starkandwayne.com/blog/public-traffic-into-knative-on-gke/

Read next

See also

Setting up knative

functions functions functions

Let's walk through how to setup a k8 cluster on digitalocean with knative. Digital Ocean Start the cluster Installing and configure the doctl tool. Then setup a cluster: doctl kubernetes cluster create gratitude \ --auto-upgrade \ "--node-pool=name=default;min-nodes=1;max-nodes=10;size=s-4vcpu-8gb;auto-scale=true" Once that's in place, make sure that you have a domain, in my case gitgratitude.com: doctl compute domain create gitgratitude.com Installing knative We are going to use the knative operator to setup the install.

Read more

K8 Dashboard on Docker Desktop

what’s going on

Pretty easy to setup, but here are the steps. Docker Desktop To easily get going on a local Mac, you can install the compoents using homebrew. brew install --cask docker brew install kubernetes-cli brew install kn Start up Docker, and then turn on kubernetes and make sure that you have a running node. kubectl get nodes NAME STATUS ROLES AGE VERSION docker-desktop Ready control-plane,master 5h59m v1.

Read more

Rails on Kubernetes with TLS

certmanager

I wanted to see how to really use kubernetes like I'm used to using heroku, so lets recreate everything using terraform, digital ocean, kubernetes and MAGIC! Sample rails app Build image First thing we'll do is to create a docker image that we'll use to build our rails app. Dockerfile.build: FROMruby:3.0.1WORKDIR/app# nodejs and yarn and clocRUN curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -RUN echo "deb https://dl.

Read more