Calcolo senza server basato su OpenWhisk, parte 4

Calcolo senza server basato su OpenWhisk, parte 4

Questo articolo conclude il ciclo di note di traduzione su OpenWhisk dell'autore Priti Desai. Oggi esamineremo il processo di distribuzione di OpenWhisk su Kubernetes con comandi corretti per funzionare con le versioni attuali delle applicazioni. Descriverò anche il processo di esecuzione delle funzioni OpenWhisk utilizzando Knative e TektonCD in Kubernetes con un ambiente di esecuzione Nodejs.

Distribuiamo OpenWhisk su Kubernetes

Negli ultimi giorni ho condotto un esperimento per distribuire OpenWhisk su Kubernetes per creare un ambiente semplice e veloce per allenare le mie competenze. Poiché sono un principiante in Kubernetes, ritengo che un giorno e mezzo sia stato impiegato per una distribuzione di successo. Nel questo repository ci sono istruzioni molto chiare per distribuire OpenWhisk su Kubernetes. Qui ci saranno istruzioni per la distribuzione, fatte per Mac (farò tutto su Linux, perché preferisco Linux. — nota del traduttore).

  1. Installiamo il gestore di pacchetti asdf, dopo di che correggiamo automaticamente ˜/.bash_profile o un suo equivalente così:

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

[Su Linux questo passaggio non è necessario, anche se brew è disponibile. — nota del traduttore]

  1. Aggiungiamo i plugin minikube e kubelet:

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

[Ancora una volta saltiamo questo passaggio su Linux. — nota del traduttore]

  1. Instaliamo minikube e 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

[si installano versioni specifiche, ma ho controllato tutto sulle ultime versioni disponibili per Linux; sospetto che si possa tranquillamente installare l'ultima. — nota del traduttore]

Su Linux questo passaggio si fa più o meno così (tutto viene installato in ~/.bin, che ho impostato nel PATH, nota del traduttore):

$ 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. Creiamo una macchina virtuale minikube (VirtualBox deve essere installato in precedenza):

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

[A me funziona con il comando minikube start , senza parametri e valori predefiniti. — nota del traduttore]

$ minikube start
  minikube v1.5.2 su Debian 8.11
  Driver 'virtualbox' selezionato automaticamente
  Downloading VM boot image ...
    > 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
  Creazione della VM virtualbox (CPUs=2, Memoria=4096MB, Disco=20000MB) ...
  Preparazione di Kubernetes v1.16.2 su Docker '18.09.9' ...
  Downloading kubelet v1.16.2
  Downloading kubeadm v1.16.2
  Pulling images ...
  Lancio di Kubernetes ...  In attesa di: apiserver
  Fatto! kubectl ora è configurato per utilizzare "minikube"

  1. Spostiamo la rete in Docker in modalità promiscuous:

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

  1. Creiamo un namespace e etichettiamo il nodo di lavoro:

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

  1. Otteniamo il contenuto del repository e sovrascriviamo il tipo per l'ingresso nel file 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. Installiamo Helm e eseguiamo la distribuzione con esso:

$ brew install kubernetes-helm
$ helm init # init Helm Tiller, non necessario su Helm v3+
$ kubectl get pods -n kube-system # verifica che tiller-deploy sia in stato di esecuzione, non necessario su helm v3+
$ kubectl create clusterrolebinding tiller-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default
$ helm install ./openwhisk/helm/ --namespace=openwhisk -f mycluster.yaml

[Su Linux con le ultime versioni (era disponibile v3.0.1) sarà un po' diverso. — nota del traduttore]

$ 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. Controlliamo che tutto sia attivo (STATUS = Running o 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. Configuriamo wsk per funzionare:

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

Controllando:

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

Problemi e loro soluzioni

getsockopt: connessione rifiutata

$ wsk -i list
error: Impossibile ottenere l'elenco delle entità per lo spazio dei nomi 'default': Get http://192.168.99.100:31001/api/v1/namespaces/_/actions?limit=0&skip=0: dial tcp 192.168.99.100:31001: getsockopt: connessione rifiutata

Controlliamo che i contenitori siano nello spazio dei nomi openwhisk in stato Esecuzione, poiché a volte si arresta con errori CreateContainerConfigError.

Invoker ancora in fase di inizializzazione — Init:1/2

Il processo di download di vari ambienti di esecuzione può richiedere molto tempo. Per accelerare è possibile specificare un elenco minimo abbreviato nel file mycluster.yaml:

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

Contenitore di nome -install-packages- esce con Error

Semplicemente aumentare i timeout per i test di liveness.

Installazione di OpenWhisk su Knative

Priti Desai ha effettuato l'installazione su un cluster nell'IBM cloud, così come su un normale minikube, utilizzando Knative Build e BuildTemplates. Anche io installerò su minikube, basandomi su ciò che è stato descritto nel nostro blog in precedenza — utilizzando le ultime versioni del software. Poiché Knative Build e BuildTemplates sono ufficialmente dichiarati obsoleti, utilizzerò la sostituzione consigliata rappresentata da Tekton Pipelines. La parte successiva dell'articolo è scritta dopo la lettura della documentazione di Tekton Pipelines, ma si basa sulle idee di Priti. Per lavorare sarà necessario avere accesso a un Docker Registry — io, come l'autore originale, utilizzerò DockerHub.

$ 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

Calcolo senza server basato su OpenWhisk, parte 4
Costruzione e funzionamento di OpenWhisk su Knative

  1. Otteniamo il contenuto di questo repository:

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

  1. Impostiamo come variabili d'ambiente i dati per l'accesso al Registry e li salviamo come segreto di Kubernetes:

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

Controllando:

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

  1. Creiamo un account per costruire gli ambienti:

$ kubectl apply -f service-account.yaml

Controllando:

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

  1. Creiamo un'attività per costruire l'immagine per OpenWhisk

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

  1. Avviamo l'attività per costruire l'immagine (prendendo come esempio NodeJS):

Creiamo un file taskrun.yaml con il contenuto:

# 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
---

Applichiamo i dati correnti per questo file:

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

Applichiamo:

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

La verifica del funzionamento consiste nel ricevere il nome del pod, visualizzare il suo stato. È anche possibile controllare il registro di esecuzione di ciascun passaggio, ad esempio:

$ 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":"Fetch GitHub commit ID from kodata failed: open "/var/run/ko/refs/heads/master: no such file or directory"}
{"level":"info","ts":1576532936.538926,"logger":"fallback-logger","caller":"git/git.go:81","msg":"Successfully cloned https://github.com/apache/openwhisk-runtime-nodejs.git @ master in path /workspace/runtime-git"}
{"level":"warn","ts":1576532936.5395331,"logger":"fallback-logger","caller":"git/git.go:128","msg":"Unexpected error: creating symlink: symlink /tekton/home/.ssh /root/.ssh: file exists"}
{"level":"info","ts":1576532936.8202565,"logger":"fallback-logger","caller":"git/git.go:109","msg":"Successfully initialized and updated submodules in path /workspace/runtime-git"}

Dopo l'esecuzione, avremo un'immagine nel Registry che può essere distribuita utilizzando l'utilità kn, progettata per lavorare con i servizi Knative, ad esempio:

kn service create nodejs-helloworld --image docker.io/${DOCKER_USERNAME}/openwhisk-nodejs-helloworld
Service 'nodejs-helloworld' successfully created in namespace 'default'.
Waiting for service 'nodejs-helloworld' to become ready ... OK

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

In caso di utilizzo di Gloo, è possibile verificare il funzionamento in questo modo:

$ 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":"Hello World!"}

Altri articoli del ciclo

Calcolo serverless basato su OpenWhisk, parte 1
Calcolo serverless basato su OpenWhisk, parte 2
Calcolo serverless basato su OpenWhisk, parte 3
Calcolo senza server basato su OpenWhisk, parte 4

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS | ProHoster