Setting up knative

functions functions functions

Published November 29, 2021 #kubernetes, #helm, #knative

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. For this post, we will only being using serving.

Operator

kubectl apply -f https://github.com/knative/operator/releases/download/knative-v1.0.0/operator.yaml

Check status:

kubectl get deployment knative-operator
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
knative-operator   1/1     1            1           24h

Serving

We will now tell the operator to deploy knative serving, and we will use kourier, and set our domain to gitgratitude.com:

serving.yml:

  apiVersion: v1
  kind: Namespace
  metadata:
    name: knative-serving
  ---
  apiVersion: operator.knative.dev/v1alpha1
  kind: KnativeServing
  metadata:
    name: knative-serving
    namespace: knative-serving
  spec:
    ingress:
      kourier:
        enabled: true
    config:
      network:
        ingress.class: "kourier.ingress.networking.knative.dev"
      domain:
        gitgratitude.com: ""
  kubectl apply -f serving.yaml
namespace/knative-serving configured
knativeserving.operator.knative.dev/knative-serving configured

And to see what the status of the deployment is:

kubectl get deployment -n knative-serving

Add default domain

Lets add the default domain serving as well.

  kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.0.0/serving-default-domain.yaml
job.batch/default-domain created
service/default-domain-service created

Add the certmanager-controller:

This tells knative to use the certmanager when services get created/deleted:

  kubectl apply --filename https://github.com/knative/net-certmanager/releases/download/knative-v1.0.0/release.yaml

Set the cert-manager config map

  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: config-certmanager
    namespace: knative-serving
    labels:
      networking.knative.dev/certificate-provider: cert-manager
  data:
    issuerRef: |
      kind: ClusterIssuer
      name: letsencrypt-staging
  kubectl apply -f cert-config.yaml
configmap/config-certmanager configured

Add revision garbage collection

apiVersion: v1
kind: ConfigMap
metadata:
  name: config-gc
  namespace: knative-serving
data:
  max-non-active-revisions: "1"
  retain-since-create-time: "disabled"
  retain-since-last-active-time: "disabled"
  kubectl apply -f gc.yaml
configmap/config-gc configured

Install cert-manager

Install helm package

  helm repo add jetstack https://charts.jetstack.io
  helm upgrade --install \
       cert-manager jetstack/cert-manager \
       --namespace cert-manager \
       --create-namespace \
       --version v1.6.0 \
       --set installCRDs=true

Configure letencrypt

Create certs.yaml to define how we interact with let-encrypt. I'm going to use the http challenge here.

Also replace wschenk@gmail.com with your email address.

  apiVersion: cert-manager.io/v1
  kind: ClusterIssuer
  metadata:
    name: letsencrypt-staging
  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-staging-v02.api.letsencrypt.org/directory
      privateKeySecretRef:
        # Secret resource that will be used to store the account's private key.
        name: staging-issuer-account-key
      # Add a single challenge solver, HTTP01 using nginx
      solvers:
      - http01:
          ingress:
            class: istio #.ingress.networking.knative.dev
  ---
  apiVersion: cert-manager.io/v1
  kind: ClusterIssuer
  metadata:
    name: letsencrypt-prod
  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
      # Add a single challenge solver, HTTP01 using nginx
      solvers:
      - http01:
          ingress:
            class: istio
            #.ingress.networking.knative.dev

Then apply it:

  kubectl apply -f certs.yaml

DNS

Set the domain

My domain is gitgratitude.com – you should use yours.

Check above where we setup knative-serving.

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"}}'
configmap/config-network patched (no change)

DNS

Get the IP

  kubectl --namespace knative-serving get service kourier -o json| jq ".status.loadBalancer.ingress[0].ip"
"143.244.212.121"
  doctl compute domain records create gitgratitude.com --record-type A --record-data 143.244.212.121 --record-name default
ID           Type    Name       Data               Priority    Port    TTL     Weight
280306756    A       default    143.244.212.121    0           0       1800    0

Then setup a wildcard CNAME to point to the root.

  doctl compute domain records create gitgratitude.com --record-type CNAME --record-data default\. --record-name \*.default
ID           Type     Name         Data                        Priority    Port    TTL     Weight
280306923    CNAME    *.default    default.gitgratitude.com    0           0       1800    0

Testing out a simple service

  kn service create helloworld-go --image gcr.io/knative-samples/helloworld-go
Creating service 'helloworld-go' in namespace 'default':

  0.036s The Route is still working to reflect the latest desired specification.
  0.064s Configuration "helloworld-go" is waiting for a Revision to become ready.
  0.099s ...
 17.273s ...
 17.343s Ingress has not yet been reconciled.
 17.416s Waiting for load balancer to be ready
 17.628s Ready to serve.

Service 'helloworld-go' created to latest revision 'helloworld-go-00001' is available at URL:
http://helloworld-go.default.gitgratitude.com

And you should be able to hit your function now.

curl -k http://helloworld-go.default.gitgratitude.com
Hello GitHub!

Look to see if a tls endpoint has been added

kn service ls
NAME            URL                                              LATEST                AGE    CONDITIONS   READY   REASON
helloworld-go   https://helloworld-go.default.gitgratitude.com   helloworld-go-00001   114s   3 OK / 3     True    

Look at the certificates

kubectl get certificates
NAME                                         READY   SECRET                                       AGE
route-7bbf3267-6eb1-4516-bbb8-e65d81e0b968   True    route-7bbf3267-6eb1-4516-bbb8-e65d81e0b968   62s
  curl --insecure -vvI https://helloworld-go.default.gitgratitude.com 2>&1 | \
      awk 'BEGIN { cert=0 } /^\* SSL connection/ { cert=1 } /^\*/ { if (cert) print }'
,* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
,* ALPN, server accepted to use h2
,* Server certificate:
,*  subject: CN=helloworld-go.default.gitgratitude.com
,*  start date: Dec  7 10:28:31 2021 GMT
,*  expire date: Mar  7 10:28:30 2022 GMT
,*  issuer: C=US; O=(STAGING) Let's Encrypt; CN=(STAGING) Artificial Apricot R3
,*  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
,* Using HTTP2, server supports multi-use
,* Connection state changed (HTTP/2 confirmed)
,* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
,* Using Stream ID: 1 (easy handle 0x120012a00)
,* Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)!
,* Connection #0 to host helloworld-go.default.gitgratitude.com left intact

References

  1. https://knative.dev/docs/install/operator/knative-with-operators/

  2. https://knative.dev/docs/serving/samples/hello-world/helloworld-ruby/

  3. https://knative.dev/docs/serving/using-auto-tls/

  4. https://github.com/knative/docs/blob/main/docs/install/serving/install-serving-with-yaml.md

Read next

See also

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

Deploying OpenFaaS on Digital Ocean with Terraform

Everything functional

We are going to look at how to use Terraform to deploy a Kubernetes cluster on Digital Ocean, add a managed postgres database, and redis and OpenFaaS in kubernetes. This will show how to use Terraform to manage the configuration and how we can access both cloud and kubernetes managed services from OpenFaaS functions. We are going to use the digitalocean, kubernetes, and helm terraform providers. The plan Provision a digitalocean_kubernetes_cluster Provision a digitalocean_database_cluster Provision 2 kubernetes_namespace for openfaas and openfaas-fn Provision a helm_release for openfaas Provision a helm_release for redis Provision 2 kubernetes_secret to point to the databases Deploy an OpenFaaS function that reads those secrets and talks to the database.

Read more