
Este artículo concluye la serie de notas de traducción OpenWhisk de Priti Desai . Hoy veremos el proceso de implementación de OpenWhisk sobre Kubernetes con los comandos corregidos para trabajar con las últimas versiones de las aplicaciones. También describirá cómo ejecutar funciones OpenWhisk usando Knative y TektonCD en Kubernetes usando el tiempo de ejecución de Nodejs.
Implemente OpenWhisk en Kubernetes
En el transcurso de unos días, experimenté con la implementación de OpenWhisk en Kubernetes para crear un campo de entrenamiento rápido y fácil. Y como soy nuevo en Kubernetes, creo que se pasó un día y medio en una implementación exitosa. Este repositorio tiene instrucciones muy claras para implementar OpenWhisk en Kubernetes. Aquí están las instrucciones de implementación hechas para Mac ( también haré todo en Linux porque prefiero Linux. - Nota del traductor).
- Instalamos el administrador de paquetes
asdf
, después de lo cual reparamos automáticamente ~/.bash_profile
o su análogo como este:
$ brew install asdf $ [ -s "/usr/local/opt/asdf/asdf.sh" ] && . /usr/local/opt/asdf/asdf.sh $ source ~/.bash_profile
[ En Linux, este paso no es necesario, aunque hay una infusión. - aprox. traductor
- Agregue
minikube
y kubelet
:
$ asdf plugin-add kubectl $ asdf plugin-add minikube
[ Nuevamente omita este paso en Linux. - aprox. traductor
- Ponemos minikube y 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
[ se instalan versiones específicas, pero verifiqué todo en las últimas versiones disponibles para Linux; Sospecho que puedes poner con seguridad lo último. - aprox. traductor
En Linux, este paso se realiza así (todo se coloca en ~ / bin, que tengo en RUTA, nota del traductor):
$ 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/
- Creamos la máquina virtual minikube (VirtualBox debe estar preinstalado):
$ minikube start --cpus 2 --memory 4096 --kubernetes-version=v1.9.0 --extra-config=apiserver.Authorization.Mode=RBAC
[ Todo funciona para mí con el minikube start
, sin parámetros y con valores predeterminados. - aprox. traductor
$ minikube start minikube v1.5.2 on Debian 8.11 Automatically selected the 'virtualbox' driver 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 Creating virtualbox VM (CPUs=2, Memory=4096MB, Disk=20000MB) ... Preparing Kubernetes v1.16.2 on Docker '18.09.9' ... Downloading kubelet v1.16.2 Downloading kubeadm v1.16.2 Pulling images ... Launching Kubernetes ... Waiting for: apiserver Done! kubectl is now configured to use "minikube"
- Cambie la red en Docker al modo promiscuo:
$ minikube ssh -- sudo ip link set docker0 promisc on
- Cree un espacio de nombres y marque el nodo de trabajo:
$ kubectl create namespace openwhisk $ kubectl label nodes --all openwhisk-role=invoker
- Obtenemos el contenido del repositorio y redefinimos el tipo de ingreso en el archivo mycluster.yaml:
$ git clone https://github.com/apache/incubator-openwhisk-deploy-kube.git $ cd incubator-openwhisk-deploy-kube/ $ cat << "EOF" > mycluster.yaml whisk: ingress: type: NodePort api_host_name: 192.168.99.100 api_host_port: 31001 nginx: httpsNodePort: 31001 EOF
- Instale Helm e impleméntelo usándolo:
$ brew install kubernetes-helm $ helm init # init Helm Tiller, Helm v3+ $ kubectl get pods -n kube-system # verify that tiller-deploy is in the running state, helm v3+ $ kubectl create clusterrolebinding tiller-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default $ helm install ./openwhisk/helm/ --namespace=openwhisk -f mycluster.yaml
[ En Linux con las últimas versiones (v3.0.1 estaba disponible) será un poco diferente. - aprox. traductor
$ 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
- Comprueba que todo ha subido (ESTADO = En ejecución o Completado):
$ 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
- Configuramos wsk para el trabajo:
$ wsk property set --apihost 192.168.99.100:31001 $ wsk property set --auth 23bc46b1-71f6-4ed5-8c54-816aa4f8c502:123zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP
Comprobamos:
$ wsk -i list Entities in namespace: default packages actions triggers rules
Problemas y soluciones.
getsockopt: conexión rechazada
$ 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
Verificamos que los contenedores en el espacio de nombres openwhisk
en el estado Running
, porque a veces se bloquea con los errores CreateContainerConfigError
.
El invocador aún se está inicializando - Init: 1/2
El proceso de descarga de todo tipo de tiempos de ejecución puede llevar mucho tiempo. Para la velocidad, puede especificar una lista mínima acortada en el archivo mycluster.yaml
:
whisk: runtimes: "runtimes-minimal-travis.json"
Un contenedor llamado -install-packages- se cae en Error
Simplemente aumente los tiempos de espera para las pruebas de vida.
Instale OpenWhisk encima de Knative
Priti Desai realizó la instalación en la parte superior del clúster en la nube de IBM, así como en el minikube regular, utilizando Knative Build y BuildTemplates. También lo instalaré sobre minukube, según cómo se describió anteriormente en nuestro blog, utilizando las últimas versiones de software. Dado que Knative Build y BuildTemplates están oficialmente en desuso, utilizaré el reemplazo recomendado en forma de Tekton Pipelines. El resto del artículo fue escrito después de leer la documentación de Tekton Pipelines, pero basado en las ideas de Priti. Para trabajar, necesitará acceso a algunos registros de Docker. Yo, como el autor original, usaré 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

Construye y ejecuta OpenWhisk sobre Knative
- Obtenemos el contenido de este repositorio :
$ git clone https://github.com/tektoncd/catalog/ $ cd catalog/openwhisk
- Configuramos los datos para acceder al Registro en forma de variables de entorno y los guardamos como un secreto de Kubernetes:
$ export DOCKER_USERNAME=<your docker hub username> $ export DOCKER_PASSWORD=<your docker hub 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
Comprobamos:
$ kubectl get secret NAME TYPE DATA AGE dockerhub-user-pass kubernetes.io/basic-auth 2 21s
- Cree una cuenta para crear entornos:
$ kubectl apply -f service-account.yaml
Comprobamos:
$ kubectl get serviceaccount/openwhisk-runtime-builder NAME SECRETS AGE openwhisk-runtime-builder 2 31m
- Cree una tarea para construir una imagen para OpenWhisk
$ kubectl apply -f openwhisk.yaml task.tekton.dev/openwhisk created
- Ejecute la tarea para construir la imagen (usando NodeJS como ejemplo):
Cree el archivo taskrun.yaml con el contenido:
# 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 ---
Aplicamos los datos actuales para este archivo:
$ sed 's/${DOCKER_USERNAME}/'"$DOCKER_USERNAME"'/' -i taskrun.yaml
Aplicamos:
$ 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 comprobación del trabajo consiste en obtener el nombre del pod, ver su estado. También puede ver el registro de cada paso, por ejemplo:
$ 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"}
Después de la ejecución, aparecerá una imagen en nuestro Registro que se puede implementar utilizando la utilidad kn diseñada para funcionar con los servicios Knative, por ejemplo:
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
En el caso de usar Gloo, puede verificar la funcionalidad de la siguiente manera:
$ 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!"}
Otros artículos de ciclo
Computación sin servidor basada en OpenWhisk, parte 1
Computación sin servidor basada en OpenWhisk, parte 2
Computación sin servidor basada en OpenWhisk, parte 3
Computación sin servidor basada en OpenWhisk, parte 4