Knative, Contour et Kind

Photo by Sharon McCutcheon from Pexels

TL;DR Cet article présente comment installer Knative sur Kind en utilisant Contour comme passerelle d'accès. La connexion de envoy à la machine hôte est notamment présentée avec précision.

Knative est un framework qui sert de base à de nombreuses offres telle que Google Cloud Run. Contour est une solution d'accès qui peut être utilisée pour Knative à la place d'Istio. La configuration de Knative et Contour sur Kind nécessite quelques adaptations que vous découvrirez ci-dessous.

Installer Kind avec un Ingress

L'installation de Kind avec un Ingress est décrit dans la section Install Kind with Ingress de la documentation. Pour les besoins de Knative, vous pourrez par exemple créer un noeud control-plane avec 2 workers à l'aide de la commande kind create cluster comme ci-dessous:

cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  image: kindest/node:v1.17.2
  kubeadmConfigPatches:
  - |
    kind: InitConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-labels: "ingress-ready=true"
        authorization-mode: "AlwaysAllow"
  extraPortMappings:
  - containerPort: 80
    hostPort: 80
    protocol: TCP
  - containerPort: 443
    hostPort: 443
    protocol: TCP
- role: worker
  image: kindest/node:v1.17.2
- role: worker
  image: kindest/node:v1.17.2
EOF

La section extraPortMappings sur le control-plane permet faire le lien entre les ports 80 et 443 du control-plane et ceux de votre hôte...

Installer Knative avec Contour

Pour démarrer, vous installerez Serving qui est le composant Function-as-a-Service de Knative. Pour cela, reportez-vous à Installing Knative en prenant soin de sélectionner Contour comme couche réseau. Procédez comme ci-dessous:

  • Installer les Custom Resource Definitions de Knative
kubectl apply --filename \
  https://github.com/knative/serving/releases/download/v0.13.0/serving-crds.yaml
  • Installer Serving
kubectl apply --filename \
  https://github.com/knative/serving/releases/download/v0.13.0/serving-core.yaml
  • Installer Contour
kubectl apply --filename \
  https://github.com/knative/net-contour/releases/download/v0.13.0/contour.yaml
  • Installer le controller Knative pour Contour
kubectl apply --filename \
  https://github.com/knative/net-contour/releases/download/v0.13.0/net-contour.yaml
  • Activer le fonctionnement de Knative avec Contour
kubectl patch configmap/config-network \
  --namespace knative-serving \
  --type merge \
  --patch '{"data":{"ingress.class":"contour.ingress.networking.knative.dev"}}'

Vous pourrez vérifier que le service envoy dans le namespace contour-external est de type loadbalancer et ne peut pas être pris en compte sur Kind:

kubectl --namespace contour-external get service envoy

Vous pouvez le supprimer le cas échéant.

Modifier le daemonset Envoy

Le daemonset envoy dans le namespace contour-external donne accès aux services Knative depuis l'extérieur. Vous devrez le modifier comme suit:

  • Modifiez le daemonset pour qu'il s'exécute uniquement sur le control-plane:
cat <<EOF >envoy-control-plane.json
{
  "spec": {
    "template": {
      "spec": {
        "nodeSelector": {
          "ingress-ready":"true"
        },
        "tolerations":[
          {
            "key":"node-role.kubernetes.io/master",
            "operator":"Equal",
            "effect":"NoSchedule"
          }
        ]
      }
    }
  }
}
EOF

kubectl patch daemonsets -n contour-external envoy \
  -p "$(cat envoy-control-plane.json)"
  • Modifiez le daemonset pour qu'il se connecte aux ports 80 et 443 du control-plane:
cat <<EOF >envoy-bind-ports.json
{
  "spec": {
    "template": {
      "spec": {
        "containers": [
          {
            "name": "envoy",
            "ports": [
              {
                "containerPort": 80,
                "hostPort": 80,
                "name": "http",
                "protocol": "TCP"
              },
              {
                "containerPort": 443,
                "hostPort": 443,
                "name": "https",
                "protocol": "TCP"
              }
            ]
          }
        ]
      }
    }
  }
}
EOF

kubectl patch daemonset -n contour-external envoy \
  -p "$(cat envoy-bind-ports.json)"
  • Verifiez que le serveur envoy externe est bien démarré sur le control-plane:
kubectl get pods -n contour-external \
  -l app=envoy \
  -o custom-columns=name:metadata.name,node:spec.nodeName,status:status.phase

name          node                 status
envoy-j7qfv   kind-control-plane   Running

Tester Knative

Pour tester la configuration, vous pouvez créer un service simple comme décrit dans Getting Started with App Deployment.

Pour cela, exécutez la commande ci-dessous:

cat <<EOF | kubectl apply -f -
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: helloworld-go
  namespace: default
spec:
  template:
    spec:
      containers:
        - image: gcr.io/knative-samples/helloworld-go
          env:
            - name: TARGET
              value: "Go Sample v1"
EOF

Vous pouvez vérifier que le service est bien créé et l'URL associée:

kubectl get ksvc helloworld-go \
  -o custom-columns=name:metadata.name,url:status.url

name            url
helloworld-go   http://helloworld-go.default.example.com

Avant de passer à la suite, vérifiez que vous pouvez accéder au service helloworld-go. Pour cela, créez une connexion au service envoy sur sur le namespace contour-external et lancez un curl en précisant bien le nom de domaine du service comme ci-dessous:

kubectl port-forward svc/envoy -n contour-external 8080:80 &
curl -H 'Host: helloworld-go.default.example.com' 127.0.0.1:8080

Vous pouvez alors tester que la connexion direct est bien en place ) l'aide de la commande ci-dessous:

curl -H 'Host: helloworld-go.default.example.com' 127.0.0.1

Enfin ajoutez la ligne ci-dessous dans le fichier /etc/hosts de votre machine:

127.0.0.1 helloworld-go.default.example.com

Vous pourrez alors interroger directement le service:

curl helloworld-go.default.example.com

Vous avez un environnement de test pour Knative...

Easyteam DevOps

Easyteam DevOps