Serverlose Berechnungen auf Basis von OpenWhisk, Teil 4

Serverlose Berechnungen auf Basis von OpenWhisk, Teil 4

Dieser Artikel beendet die Reihe von Übersetzungsnotizen zu OpenWhisk von der Autorin Priti Desai. Heute betrachten wir den Prozess des Deployments von OpenWhisk auf Kubernetes mit korrigierten Befehlen für die Kompatibilität mit aktuellen Versionen der Anwendungen. Außerdem wird der Prozess zum Starten von OpenWhisk-Funktionen unter Verwendung von Knative und TektonCD in Kubernetes mit der Ausführungsumgebung Node.js beschrieben.

OpenWhisk auf Kubernetes bereitstellen

In den letzten Tagen habe ich ein Experiment zum Deployment von OpenWhisk in Kubernetes durchgeführt, um eine einfache und schnelle Plattform zur Bearbeitung von Aufgaben zu schaffen. Da ich ein Neuling in Kubernetes bin, schätze ich, dass anderthalb Tage für ein erfolgreiches Deployment aufgewendet wurden. Im diesem Repository gibt es sehr klare Anleitungen für das Deployment von OpenWhisk in Kubernetes. Hier werden Anweisungen für das Deployment bereitgestellt, die für Mac (ich werde alles auch auf Linux durchführen, da ich Linux bevorzuge. — Anmerkung der Übersetzerin).

  1. Paketmanager installieren asdf, danach richten wir automatisch ~/.bash_profile oder ein ähnliches so ein:

$ brew install asdf
$ [ -s "/usr/local/opt/asdf/asdf.sh" ] && . /usr/local/opt/asdf/asdf.sh
$ source ~/.bash_profile

[Auf Linux ist dieser Schritt nicht notwendig, obwohl brew verfügbar ist. — Anmerkung der Übersetzerin]

  1. Plugins hinzufügen minikube und kubelet:

$ asdf plugin-add kubectl
$ asdf plugin-add minikube

[Diesen Schritt überspringen wir erneut unter Linux. — Anmerkung der Übersetzerin]

  1. Wir installieren minikube und kubelet:

$ asdf install kubectl 1.9.0
$ asdf global kubectl 1.9.0
$ asdf install minikube 0.25.2
$ asdf global minikube 0.25.2

[Es werden spezifische Versionen installiert, aber ich habe alles mit den neuesten verfügbaren Versionen für Linux überprüft; ich vermute, dass man problemlos die neueste Version installieren kann. — Anmerkung der Übersetzerin]

Unter Linux wird dieser Schritt ungefähr so durchgeführt (alles wird in ~/bin installiert, das in meinem PATH eingetragen ist, Anm. des Übersetzers):

$ curl -L0 minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube && mv minikube ~/bin/
$ curl -L0 https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && chmod +x kubectl && mv kubectl ~/bin/

  1. Wir erstellen die virtuelle Maschine minikube (VirtualBox muss vorher installiert sein):

$ minikube start --cpus 2 --memory 4096 --kubernetes-version=v1.9.0 --extra-config=apiserver.Authorization.Mode=RBAC

[Bei mir funktioniert alles mit dem Befehl minikube start , ohne Parameter und mit Standardwerten. — Anmerkung der Übersetzerin]

$ minikube start
  minikube v1.5.2 auf Debian 8.11
  Fahrer 'virtualbox' automatisch ausgewählt
  Lade VM-Boot-Image herunter ...
    > minikube-v1.5.1.iso.sha256: 65 B / 65 B [--------------] 100.00% ? p/s 0s
    > minikube-v1.5.1.iso: 143,76 MiB / 143,76 MiB [-] 100.00% 5,63 MiB p/s 26s
  Erstelle VirtualBox-VM (CPUs=2, Speicher=4096MB, Disk=20000MB) ...
  Bereite Kubernetes v1.16.2 auf Docker '18.09.9' vor ...
  Lade kubelet v1.16.2 herunter
  Lade kubeadm v1.16.2 herunter
  Ziehe Images ...
  Starte Kubernetes ...  Warte auf: apiserver
  Fertig! kubectl ist jetzt so konfiguriert, dass es "minikube" verwendet

  1. Wechseln Sie das Netzwerk in Docker in den promiscuous Modus:

$ minikube ssh -- sudo ip link set docker0 promisc on

  1. Erstellen Sie den Namespace und markieren Sie den Arbeitsknoten:

$ kubectl create namespace openwhisk
$ kubectl label nodes --all openwhisk-role=invoker

  1. Holen Sie sich den Inhalt des Repositories und überschreiben Sie den Typ für ingress in der Datei mycluster.yaml:

$ git clone https://github.com/apache/incubator-openwhisk-deploy-kube.git
$ cd incubator-openwhisk-deploy-kube/
$ cat < mycluster.yaml
whisk:
    ingress:
        type: NodePort
            api_host_name: 192.168.99.100
            api_host_port: 31001
nginx:
    httpsNodePort: 31001
EOF

  1. Installieren Sie Helm und führen Sie das Deployment mit seiner Hilfe durch:

$ brew install kubernetes-helm
$ helm init # init Helm Tiller, nicht erforderlich in Helm v3+
$ kubectl get pods -n kube-system # überprüfen, dass tiller-deploy im laufenden Zustand ist, nicht erforderlich in helm v3+
$ kubectl create clusterrolebinding tiller-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default
$ helm install ./openwhisk/helm/ --namespace=openwhisk -f mycluster.yaml

[Auf Linux mit den neuesten Versionen (v3.0.1 war verfügbar) wird es etwas anders sein. — Anmerkung der Übersetzerin]

$ curl -L0 https://get.helm.sh/helm-v3.0.1-linux-amd64.tar.gz | tar -xzvf - linux-amd64/helm --strip-components=1; sudo mv helm /usr/local/bin
$ kubectl create clusterrolebinding tiller-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default
$ helm install ./openwhisk/helm/ --namespace=openwhisk --generate-name -f mycluster.yaml

  1. Überprüfen Sie, ob alles gestartet ist (STATUS = Running oder Completed):

$ kubectl get pods -n openwhisk
NAME                                                              READY   STATUS      RESTARTS   AGE
openwhisk-1576070780-alarmprovider-6868dc694-plvpf                1/1     Running     1          1d5h
openwhisk-1576070780-apigateway-8d56f4979-825hf                   1/1     Running     1          1d5h
openwhisk-1576070780-cloudantprovider-544bb46596-9scph            1/1     Running     1          1d5h
openwhisk-1576070780-controller-0                                 1/1     Running     2          1d5h
openwhisk-1576070780-couchdb-7fd7f6c7cc-42tw6                     1/1     Running     1          1d5h
openwhisk-1576070780-gen-certs-z9nsb                              0/1     Completed   0          1d5h
openwhisk-1576070780-init-couchdb-r2vmt                           0/1     Completed   0          1d5h
openwhisk-1576070780-install-packages-27dtr                       0/1     Completed   0          1d4h
openwhisk-1576070780-invoker-0                                    1/1     Running     1          1d5h
openwhisk-1576070780-kafka-0                                      1/1     Running     1          1d5h
openwhisk-1576070780-kafkaprovider-f8b4cf4fc-7z4gt                1/1     Running     1          1d5h
openwhisk-1576070780-nginx-6dbdbf69bc-5x76n                       1/1     Running     1          1d5h
openwhisk-1576070780-redis-cfd8756f4-hkrt6                        1/1     Running     1          1d5h
openwhisk-1576070780-wskadmin                                     1/1     Running     1          1d5h
openwhisk-1576070780-zookeeper-0                                  1/1     Running     1          1d5h
wskopenwhisk-1576070780-invoker-00-1-prewarm-nodejs10             1/1     Running     0          61s
wskopenwhisk-1576070780-invoker-00-2-prewarm-nodejs10             1/1     Running     0          61s
wskopenwhisk-1576070780-invoker-00-3-whisksystem-invokerhealtht   1/1     Running     0          59s

  1. Настраиваем wsk для работы:

$ wsk property set --apihost 192.168.99.100:31001
$ wsk property set --auth 23bc46b1-71f6-4ed5-8c54-816aa4f8c502:123zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP

Überprüfen wir:

$ wsk -i list
Entities in namespace: default
packages
actions
triggers
rules

Проблемы и их решения

getsockopt: connection refused

$ wsk -i list
error: Unable to obtain the list of entities for namespace 'default': Get http://192.168.99.100:31001/api/v1/namespaces/_/actions?limit=0&skip=0: dial tcp 192.168.99.100:31001: getsockopt: connection refused

Проверяем, что контейнеры в namespace openwhisk в статусе Running, т.к. иногда оно падает с ошибками CreateContainerConfigError.

Invoker still initializing — Init:1/2

Процесс скачивания всевозможных сред выполнения может занять много времени. Для ускорения можно указать сокращенный минимальный список в файле mycluster.yaml:

whisk:
  runtimes: "runtimes-minimal-travis.json"

Контейнер с именем -install-packages- вываливается в Error

Просто нарастите таймауты для liveness тестов.

Установка OpenWhisk поверх Knative

Priti Desai проводила установку поверх кластера в облаке IBM, а также на обычном minikube, используя Knative Build и BuildTemplates. Я тоже буду устанавливать поверх minukube, по мотивам того, как это было описано In unserem Blog haben wir bereits die neuesten Softwareversionen verwendet. Da Knative Build und BuildTemplates offiziell als veraltet gelten, werde ich die empfohlene Alternative, die Tekton Pipelines, verwenden. Der restliche Artikel entstand nach dem Lesen der Dokumentation zu Tekton Pipelines, basiert jedoch auf den Ideen von Priti. Für die Arbeit wird der Zugriff auf eine Docker Registry benötigt – ich werde, wie der ursprüngliche Autor, DockerHub nutzen.

$ curl -L0 https://github.com/solo-io/gloo/releases/download/v1.2.10/glooctl-linux-amd64; chmod +x glooctl-linux-amd64; mv glooctl-linux-amd64 ~/bin
$ glooctl install knative
$ kubectl get pods -n knative-serving
NAME                              READY   STATUS    RESTARTS   AGE
activator-77fc555665-rvrst        1/1     Running   0          2m23s
autoscaler-5c98b7c9b6-x8hh4       1/1     Running   0          2m21s
autoscaler-hpa-5cfd4f6845-w87kq   1/1     Running   0          2m22s
controller-7fd74c8f67-tprm8       1/1     Running   0          2m19s
webhook-74847bb77c-txr2g          1/1     Running   0          2m17s
$ kubectl get pods -n gloo-system
NAME                                      READY   STATUS    RESTARTS   AGE
discovery-859d7fbc9c-8xhvh                1/1     Running   0          51s
gloo-545886d9c6-85mwt                     1/1     Running   0          51s
ingress-67d4996d75-lkkmw                  1/1     Running   0          50s
knative-external-proxy-767dfd656c-wwv2z   1/1     Running   0          50s
knative-internal-proxy-6fdddcc6b5-7vqd8   1/1     Running   0          51s

Serverlose Berechnungen auf Basis von OpenWhisk, Teil 4
Aufbau und Betrieb von OpenWhisk auf Knative

  1. Inhalt abrufen dieses Repository:

$ git clone https://github.com/tektoncd/catalog/
$ cd catalog/openwhisk

  1. Wir setzen die Zugangsdaten zum Registry als Umgebungsvariablen und speichern sie als Kubernetes-Secret:

$ export DOCKER_USERNAME=
$ export DOCKER_PASSWORD=
$ sed -e 's/${DOCKER_USERNAME}/"$DOCKER_USERNAME"/g' -e 's/${DOCKER_PASSWORD}/"$DOCKER_PASSWORD"/g' docker-secret.yaml.tmpl > docker-secret.yaml
$ kubectl apply -f docker-secret.yaml

Überprüfen wir:

$ kubectl get secret
NAME                    TYPE                                  DATA      AGE
dockerhub-user-pass     kubernetes.io/basic-auth              2         21s

  1. Erstellen Sie ein Benutzerkonto zum Bauen von Umgebungen:

$ kubectl apply -f service-account.yaml

Überprüfen wir:

$ kubectl get serviceaccount/openwhisk-runtime-builder
NAME                        SECRETS   AGE
openwhisk-runtime-builder   2         31m

  1. Erstellen Sie eine Aufgabe zum Bauen des OpenWhisk-Images

$ kubectl apply -f openwhisk.yaml
task.tekton.dev/openwhisk erstellt

  1. Starten Sie die Aufgabe zum Bauen des Images (am Beispiel von NodeJS):

Erstellen Sie die Datei taskrun.yaml mit folgendem Inhalt:

# Git Pipeline Resource for OpenWhisk NodeJS Runtime
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
    name: openwhisk-nodejs-runtime-git
spec:
    type: git
    params:
        - name: revision
          value: master
        - name: url
          value: https://github.com/apache/openwhisk-runtime-nodejs.git
---

# Image Pipeline Resource for OpenWhisk NodeJS Sample Application
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
    name: openwhisk-nodejs-helloworld-image
spec:
    type: image
    params:
        - name: url
          value: docker.io/${DOCKER_USERNAME}/openwhisk-nodejs-helloworld
---

# Task Run to build NodeJS image with the action source
apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
    name: openwhisk-nodejs-helloworld
spec:
    serviceAccountName: openwhisk-runtime-builder
    taskRef:
        name: openwhisk
    inputs:
        resources:
            - name: runtime-git
              resourceRef:
                name: openwhisk-nodejs-runtime-git
        params:
            - name: DOCKERFILE
              value: "./runtime-git/core/nodejs10Action/knative/Dockerfile"
            - name: OW_ACTION_NAME
              value: "nodejs-helloworld"
            - name: OW_ACTION_CODE
              value: "function main() {return {payload: 'Hello World!'};}"
            - name: OW_PROJECT_URL
              value: ""
    outputs:
        resources:
            - name: runtime-image
              resourceRef:
                name: openwhisk-nodejs-helloworld-image
---

Wenden Sie die aktuellen Daten für diese Datei an:

$ sed 's/${DOCKER_USERNAME}/"$DOCKER_USERNAME"/g' -i taskrun.yaml

Anwenden:

$ kubectl apply -f taskrun.yaml
pipelineresource.tekton.dev/openwhisk-nodejs-runtime-git erstellt
pipelineresource.tekton.dev/openwhisk-nodejs-helloworld-image erstellt
taskrun.tekton.dev/openwhisk-nodejs-helloworld erstellt

Die Überprüfung der Ausführung umfasst das Abrufen des Namens des Pods und das Überprüfen seines Status. Außerdem können Sie das Protokoll jedes Schrittes einsehen, zum Beispiel:

$ kubectl get taskrun
NAME                          SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
openwhisk-nodejs-helloworld   True        Succeeded   5m15s       44s
$ kubectl get pod openwhisk-nodejs-helloworld-pod-4640d3
NAME                                     READY   STATUS      RESTARTS   AGE
openwhisk-nodejs-helloworld-pod-4640d3   0/6     Completed   0          5m20s
$ kubectl logs openwhisk-nodejs-helloworld-pod-4640d3 -c step-git-source-openwhisk-nodejs-runtime-git-r8vhr
{"level":"info","ts":1576532931.5880227,"logger":"fallback-logger","caller":"logging/config.go:69","msg":"GitHub-Commit-ID aus kodata abrufen fehlgeschlagen: open /var/run/ko/refs/heads/master: Datei oder Verzeichnis nicht gefunden"}
{"level":"info","ts":1576532936.538926,"logger":"fallback-logger","caller":"git/git.go:81","msg":"Erfolgreich geklont https://github.com/apache/openwhisk-runtime-nodejs.git @ master in Pfad /workspace/runtime-git"}
{"level":"warn","ts":1576532936.5395331,"logger":"fallback-logger","caller":"git/git.go:128","msg":"Unerwarteter Fehler: Erstellen des Symlinks: symlink /tekton/home/.ssh /root/.ssh: Datei existiert bereits"}
{"level":"info","ts":1576532936.8202565,"logger":"fallback-logger","caller":"git/git.go:109","msg":"Submodule erfolgreich initialisiert und aktualisiert in Pfad /workspace/runtime-git"}

Nach der Ausführung haben wir ein Image im Registry, das mit dem Tool kn, das für die Arbeit mit Knative-Diensten gedacht ist, bereitgestellt werden kann, zum Beispiel:

kn service create nodejs-helloworld --image docker.io/${DOCKER_USERNAME}/openwhisk-nodejs-helloworld
Dienst 'nodejs-helloworld' erfolgreich im Namespace 'default' erstellt.
Warte, bis der Dienst 'nodejs-helloworld' bereit ist ... OK

Dienst-URL:
http://nodejs-helloworld.default.example.com

Im Fall der Verwendung von Gloo kann die Funktionsfähigkeit wie folgt überprüft werden:

$ curl -H "Host: nodejs-helloworld.default.example.com" -X POST $(glooctl proxy url --name knative-external-proxy)
{"OK":true}
$ curl -H "Host: nodejs-helloworld.default.example.com" -X POST $(glooctl proxy url --name knative-external-proxy)
{"payload":"Hallo Welt!"}

Andere Artikel der Reihe

Serverlose Berechnungen basierend auf OpenWhisk, Teil 1
Serverlose Berechnungen basierend auf OpenWhisk, Teil 2
Serverlose Berechnungen basierend auf OpenWhisk, Teil 3
Serverlose Berechnungen auf Basis von OpenWhisk, Teil 4

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster