DEV Community

Jonathan
Jonathan

Posted on • Updated on

OpenFaaS con K3S en un servidor ARM64 (1/2)

En esta ocasión escribo acerca de mi experiencia levantando un servicio propio de funciones utilizando https://www.openfaas.com/

Antes que nada primero veremos los requisitos para esta tarea.

Primero fue levantado en un servidor Ampere A1 con 2 nucleos y 12 de Memoria y 100 GB de almacenamiento, se encuentra alojado en Oracle Cloud, cuenta con una IP pública.

Después para los certificados de seguridad y asegurado del sitio mediante SSL se necesita un dominio con el cual se pueda hacer pruebas y configurar el DNS. La forma más económica de obtener un dominio para mi fue comprarlo en namecheap, desde el cual voy a crear un subdominio para acceder al servicio de funciones.

Con estos requisitos podemos iniciar, lo primero que hice fue instalar K3S, nos permite instalar una versión “Lightweight Kubernetes”, una versión ligera y rápida para desarrollar y poner en producción un cluster de Kubernetes.

Para instalar el cluster usamos, en cual instalaremos el cluster de pruebas y su acceso a través del usuario actual que tenemos en el servidor, se podría implementar en un cluster con más nodos, en mi caso solo utilizaré uno.

$ curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644
$ kubectl config view --raw > ~/.kube/config
Enter fullscreen mode Exit fullscreen mode

Podemos verificar el estado con

$ kubectl get nodes -o wide
Enter fullscreen mode Exit fullscreen mode

Donde obtendremos una salida similar a esta:

Get Nodes

La idea es siempre hacerlo simple entender que está sucediendo ya que son un conjunto de cosas que funcionan entre sí, para lo cual la solución pensada es similar a algo así:

Arquitecture

Asi que bueno:

“Divide y vencerás”

Antes de iniciar con la instalación de los diferentes componentes utilizaremos dos gestores de paquetes para Kubernetes

Helm donde podemos instalarlo siguiendo la documentación Helm Install

$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
$ chmod 700 get_helm.sh
$ ./get_helm.sh
Enter fullscreen mode Exit fullscreen mode

Podemos verificar la instalación utilizando

$ helm version
Enter fullscreen mode Exit fullscreen mode

El segundo gestor de paquetes que utilizaremos es Arkade un gestor de paquetes que nos permite instalar charts con un solo comando de manera rápida
Podemos instalarla y verificar utilizando los siguientes comandos

$ curl -sLS https://get.arkade.dev | sudo sh
$ arkade --help
Enter fullscreen mode Exit fullscreen mode

Ahora que ya están instalados podemos continuar con los despliegues.

Primero el Ingress, encargarnos del Ingress para lo cual primero nos asignaremos un subdominio a nuestra ip pública, algo así “openfaas.example.com” con la cual nos aseguraremos que todo funcione incluso la emisión de certificados SSL antes de instalar open faas, en caso de utilizar Namecheap para el dominio puede seguir el siguiente enlace que explica como crear un subdominio y apuntar a la IP que vayamos a utilizar, cuando se realiza el registro puede llevar un tiempo en reflejarse me ha pasado que a veces tarda unos 10 minutos en detectar el subdominio el DNS hasta un 1 dia entero asi a tener paciencia xD Crear Subdominio en Namecheap

En el ejemplo utilizamos dos subdominios uno de prueba para una aplicación de demostración y otra que nos permita acceder a openfaas.

Como vamos a utilizar Nginx-ingress, necesitamos también asegurar nuestros sitios para lo cual utilizaremos cert-manager. Puede leer más al respecto del cert-manager

Nginx Ingress

Lo primero vamos a instalar utilizando helm nuestro Nginx Ingress usando sus repositorios

$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
$ helm repo update
$ helm install nginxingress ingress-nginx/ingress-nginx
Enter fullscreen mode Exit fullscreen mode

Podemos comprobar el estado del servicio usando

$ kubectl get svc
Enter fullscreen mode Exit fullscreen mode

Donde tendremos una salida similar a la siguiente image

get svc

Donde en principio se encontrara pendiente hasta que se asocie a la IP pública, en caso de suceder puede realizarlo manualmente editando el servicio usando Kubernetes.

$ kubectl edit svc nginxingress-ingress-nginx-controller
Enter fullscreen mode Exit fullscreen mode

Donde usaremos VIM para editar nuestro servicio añadiendo al nivel del type: LoadBalancer nuestra IP externa

type: LoadBalancer
  externalIPs:
  - XXX.XXX.XXX.XXX
…
Enter fullscreen mode Exit fullscreen mode

Para probar nuestro Ingress y Cert Manager utilizaremos un deploy de demostración llamado KUARD. Para lo cual crearemos los dos archivos del deploy y del ingress

# kuard-ingress.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kuard
spec:
  selector:
    matchLabels:
      app: kuard
  replicas: 1
  template:
    metadata:
      labels:
        app: kuard
    spec:
      containers:
      - image: gcr.io/kuar-demo/kuard-arm64:1
        imagePullPolicy: Always
        name: kuard
        ports:
        - containerPort: 8080
Enter fullscreen mode Exit fullscreen mode

Levantamos el deployment:

kubectl create -f kuard-deploy.yaml
Enter fullscreen mode Exit fullscreen mode

Luego configuramos nuestro ingress para Kuard:

#kuard-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kuard
  annotations:
    kubernetes.io/ingress.class: "nginx"
    # cert-manager.io/issuer: "letsencrypt-prod"

spec:
  tls:
  - hosts:
    - kuard.example.com # Dominio de prueba
    secretName: quickstart-example-tls # Nombre de nuestro Certificado
  rules:
  - host: kuard.example.com # Dominio de prueba
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kuard
            port:
              number: 80
Enter fullscreen mode Exit fullscreen mode

Levantamos el ingress:

kubectl create -f kuard-ingress.yaml
Enter fullscreen mode Exit fullscreen mode

Podemos verificar el estado de nuestro deploy e ingres utilizando

$ kubectl get ingress,deploy -o wide
# probar el acceso a nuestro dominio de prueba usando su IP
$ curl -kivL -H 'Host: kuard.example.com' 'http://10.0.0.210'
Enter fullscreen mode Exit fullscreen mode

Una vez levantado el deploy y el Ingress tenemos que configurar nuestro cert manager que se encargará de gestionar los certificados para nuestro sitio, para lo cual nos ayudará helm

$ helm repo add jetstack https://charts.jetstack.io
$ helm update
$  kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.2/cert-manager.crds.yaml 
$ helm install   cert-manager jetstack/cert-manager   --namespace cert-manager   --create-namespace   --version v1.8.2
Enter fullscreen mode Exit fullscreen mode

Una vez instalado procedemos a crear nuestros issuers, que se encargaran de generar los certificados en nuestro caso usaremos letsencrypt creando los dos siguientes issuers:

# lets-staging.yaml
   apiVersion: cert-manager.io/v1
   kind: Issuer
   metadata:
     name: letsencrypt-staging
   spec:
     acme:
       # The ACME server URL
       server: https://acme-staging-v02.api.letsencrypt.org/directory
       # Email address used for ACME registration
       email: me@example.com
       # Name of a secret used to store the ACME account private key
       privateKeySecretRef:
         name: letsencrypt-staging
       # Enable the HTTP-01 challenge provider
       solvers:
       - http01:
           ingress:
             class:  nginx

Enter fullscreen mode Exit fullscreen mode

Y el archivo para generar certificados en prod

# lets-prod.yaml
   apiVersion: cert-manager.io/v1
   kind: Issuer
   metadata:
     name: letsencrypt-prod
   spec:
     acme:
       # The ACME server URL
       server: https://acme-v02.api.letsencrypt.org/directory
       # Email address used for ACME registration
       email: me@example.com
       # Name of a secret used to store the ACME account private key
       privateKeySecretRef:
         name: letsencrypt-prod
       # Enable the HTTP-01 challenge provider
       solvers:
       - http01:
           ingress:
             class: nginx
Enter fullscreen mode Exit fullscreen mode

Creamos ambos issuers.

$ kubectl create -f lets-staging.yaml
$ kubectl create -f lets-prod.yaml
$ kubectl get Issuers
$ kubectl describe issuer letsencrypt-staging
Enter fullscreen mode Exit fullscreen mode

Hasta este punto ya tenemos el cert-manager con nuestros Issuers, ahora toca configurar nuestro Ingress que estamos probando, editamos nuestro kuard-ingress.yaml

#kuard-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kuard
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/issuer: "letsencrypt-staging"

spec:
  tls:
  - hosts:
    - kuard.example.com # Dominio de prueba
    secretName: quickstart-example-tls # Nombre de nuestro Certificado
  rules:
  - host: kuard.example.com # Dominio de prueba
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kuard
            port:
              number: 80
Enter fullscreen mode Exit fullscreen mode

Y volvemos a levantar nuestro Ingress.

$ kubectl apply -f kuard-ingress.yaml
Enter fullscreen mode Exit fullscreen mode

O sino eliminamos el Ingress y levantamos nuevamente.

$ kubectl delete -f kuard-ingress.yaml
$ kubectl create -f kuard-ingress.yaml
Enter fullscreen mode Exit fullscreen mode

En este punto se creará el punto de ingreso y el certificado.

$ kubectl get certificate
NAME                     READY   SECRET                   AGE
quickstart-example-tls   True    quickstart-example-tls   16m
Enter fullscreen mode Exit fullscreen mode

Podemos ver más detalles del mismo

$ kubectl describe certificate quickstart-example-tls
$ kubectl describe secret quickstart-example-tls
Enter fullscreen mode Exit fullscreen mode

Una vez comprobado que existen los certificados podemos hacer la actualización a producción de nuestro Ingress.

#kuard-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kuard
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/issuer: "letsencrypt-prod"

spec:
  tls:
  - hosts:
    - kuard.example.com # Dominio de prueba
    secretName: quickstart-example-tls # Nombre de nuestro Certificado
  rules:
  - host: kuard.example.com # Dominio de prueba
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kuard
            port:
              number: 80
Enter fullscreen mode Exit fullscreen mode

Y volvemos a levantar nuestro Ingress.

$ kubectl apply -f kuard-ingress.yaml
Enter fullscreen mode Exit fullscreen mode

O sino eliminamos el Ingress y levantamos nuevamente.

$ kubectl delete -f kuard-ingress.yaml
$ kubectl create -f kuard-ingress.yaml
Enter fullscreen mode Exit fullscreen mode

También es necesario eliminar el certificado en estado de staging para que se pueda generar el certificado en producción.

$  kubectl delete secret quickstart-example-tls
Enter fullscreen mode Exit fullscreen mode

Una vez eliminado esperamos un poco hasta que se vuelva a generar un certificado esta vez apuntando al issuer de producción.
En este punto accediendo desde el navegador puede comprobar la validez del certificado accediendo a su dominio kuard.example.com.

En este punto terminamos la parte inicial de nuestro esquema, ya tenemos nuestro Ingress y Nuestro Cert Manager Funcionando correctamente ahora toca instalar OpenFaas para el servicio de Funciones.

Kuard muestra un poco de información sensible así que se recomienda eliminarlo cuando no se lo esté utilizando, puede eliminar el secret, el ingress y el deploy y eliminar el subdominio de prueba “kuard.example.com” para continuar con el servicio de OpenFaas

$  kubectl delete -f kuard-ingress.yaml
$  kubectl delete secret quickstart-example-tls
$  kubectl delete -f kuard-deploy.yaml
Enter fullscreen mode Exit fullscreen mode

En caso de querer revisar los logs de nuestro ingress nginx podemos utilizar un comando similar a este:

kubectl logs -f $(kubectl get po -l "app.kubernetes.io/instance=nginxingress,app.kubernetes.io/component=controller" -o jsonpath="{.items[0].metadata.name}")
Enter fullscreen mode Exit fullscreen mode

OpenFaas

Es un servicio de Funciones Self Hosted, que nos permite levantar e implementar funciones basados en eventos sobre Kubernetes, generando un endpoint, tal como Azure Functions o Amazon Lambda https://docs.openfaas.com/.

Puede leer más información sobre el proceso de instalación

Para instalar OpenFaas sobre nuestro Kubernetes utilizaremos arkade:

$ arkade install openfaas
Enter fullscreen mode Exit fullscreen mode

Utilizando helm podemos ver todos nuestros charts instalados incluido openfaas

$ helm list --all-namespaces
Enter fullscreen mode Exit fullscreen mode

Helm List

Una vez instalado openfaas vamos a crear los issuers para su namespace openfaas en el cual estaran almacenados

# letsencrypt-issuer.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-staging
  namespace: openfaas
spec:
  acme:
    email: me@example.com
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: staging-issuer-account-key
    solvers:
    - http01:
        ingress:
          class: nginx
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-prod
  namespace: openfaas
spec:
  acme:
    email: me@example.com
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: prod-issuer-account-key
    solvers:
    - http01:
        ingress:
          class: nginx
Enter fullscreen mode Exit fullscreen mode

Una vez creado nuestro archivo de Issuers levantamos el mismo

$ kubectl create -f letsencrypt-issuer.yaml
Enter fullscreen mode Exit fullscreen mode

Ahora procedemos a configurar nuestro openfaas creando un archivo tls.yaml y actualizando con helm nuestro chart de faas

# tls.yaml
ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/issuer: letsencrypt-staging # utilizaremos staging de pruebas
  tls:
    - hosts:
        - openfaas.example.com
      secretName: openfaas-crt
  hosts:
    - host: openfaas.example.com
      serviceName: gateway
      servicePort: 8080
      path: /
Enter fullscreen mode Exit fullscreen mode

Actualizamos nuestro chart

$ helm upgrade openfaas --namespace openfaas --reuse-values --values tls.yaml openfaas/openfaas
Enter fullscreen mode Exit fullscreen mode

Esperamos un poco a que se apliquen los cambios y genere el certificado en staging y podemos comprobarlo con

$ kubectl describe certificate   -n openfaas   openfaas-crt
Enter fullscreen mode Exit fullscreen mode

Al poder comprobar que se encuentre creado podemos cambiar ahora a prod nuestro staging

# tls.yaml
ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/issuer: letsencrypt-prod # Cambiamos a prod
  tls:
    - hosts:
        - openfaas.example.com
      secretName: openfaas-crt
  hosts:
    - host: openfaas.example.com
      serviceName: gateway
      servicePort: 8080
      path: /
Enter fullscreen mode Exit fullscreen mode

Volvemos a actualizar nuestro chart con helm de openfaas

$ helm upgrade openfaas --namespace openfaas --reuse-values --values tls.yaml openfaas/openfaas
Enter fullscreen mode Exit fullscreen mode

Si el certificado no se regenera con el Issuer de producción puede ser necesario eliminarlo.

$ kubectl -n openfaas delete secret  openfaas-crt
Enter fullscreen mode Exit fullscreen mode

Ahora hay q descargar las credenciales auth del admin del open faas para poder acceder desde el cliente o la web

$ PASSWORD=$(kubectl get secret -n openfaas basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode; echo)
$ echo $PASSWORD
Enter fullscreen mode Exit fullscreen mode

Este password guardalo con mucha seguridad ya que es la clave de acceso a su openfaas.

Una vez que se genera el certificado, ya se encuentra listo para acceder a su openfaas para lo cual puede realizarlo desde el navegador accediendo a su dominio openfaas.example.com

OpenFaas

Como se puede observar se encuentra ya con https y está listo para poder empezar a deployar sus funciones, tanto desde la web como desde su cliente.

Para la instalación del cliente de openfaas

Recursos utilizados:

https://docs.oracle.com/iaas/Content/FreeTier/freetier_topic-Always_Free_Resources.htm
https://rancher.com/docs/k3s/latest/en/
https://helm.sh/docs/intro/install/
https://github.com/alexellis/arkade
https://cert-manager.io/docs/tutorials/acme/nginx-ingress/
https://docs.openfaas.com/deployment/kubernetes/
https://docs.openfaas.com/cli/install/

Aqui esta el siguiente POST de una función en Python con OpenFaas
"Crear una función en Python para desplegar en OpenFaas (2/2)"

Ahí les dejo mi página personal jevillanueva.dev

Top comments (0)