
Questo articolo conclude il ciclo di note di traduzione su OpenWhisk dell'autore . 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 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).
- Installiamo il gestore di pacchetti
asdf, dopo di che correggiamo automaticamente˜/.bash_profileo 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]
- Aggiungiamo i plugin
minikubeekubelet:
$ asdf plugin-add kubectl
$ asdf plugin-add minikube[Ancora una volta saltiamo questo passaggio su Linux. — nota del traduttore]
- 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/- 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"- Spostiamo la rete in Docker in modalità promiscuous:
$ minikube ssh -- sudo ip link set docker0 promisc on- Creiamo un namespace e etichettiamo il nodo di lavoro:
$ kubectl create namespace openwhisk
$ kubectl label nodes --all openwhisk-role=invoker- 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- 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- 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- Configuriamo wsk per funzionare:
$ wsk property set --apihost 192.168.99.100:31001
$ wsk property set --auth 23bc46b1-71f6-4ed5-8c54-816aa4f8c502:123zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwPControllando:
$ wsk -i list
Entities in namespace: default
packages
actions
triggers
rulesProblemi 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 rifiutataControlliamo 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 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
Costruzione e funzionamento di OpenWhisk su Knative
- Otteniamo il contenuto :
$ git clone https://github.com/tektoncd/catalog/
$ cd catalog/openwhisk- 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.yamlControllando:
$ kubectl get secret
NAME TYPE DATA AGE
dockerhub-user-pass kubernetes.io/basic-auth 2 21s- Creiamo un account per costruire gli ambienti:
$ kubectl apply -f service-account.yamlControllando:
$ kubectl get serviceaccount/openwhisk-runtime-builder
NAME SECRETS AGE
openwhisk-runtime-builder 2 31m- Creiamo un'attività per costruire l'immagine per OpenWhisk
$ kubectl apply -f openwhisk.yaml
task.tekton.dev/openwhisk created- 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.yamlApplichiamo:
$ 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 createdLa 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.comIn 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
Fonte: habr.com
