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
Podemos verificar el estado con
$ kubectl get nodes -o wide
Donde obtendremos una salida similar a esta:
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í:
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
Podemos verificar la instalación utilizando
$ helm version
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
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
Podemos comprobar el estado del servicio usando
$ kubectl get svc
Donde tendremos una salida similar a la siguiente image
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
Donde usaremos VIM para editar nuestro servicio añadiendo al nivel del type: LoadBalancer nuestra IP externa
…
type: LoadBalancer
externalIPs:
- XXX.XXX.XXX.XXX
…
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
Levantamos el deployment:
kubectl create -f kuard-deploy.yaml
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
Levantamos el ingress:
kubectl create -f kuard-ingress.yaml
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'
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
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
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
Creamos ambos issuers.
$ kubectl create -f lets-staging.yaml
$ kubectl create -f lets-prod.yaml
$ kubectl get Issuers
$ kubectl describe issuer letsencrypt-staging
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
Y volvemos a levantar nuestro Ingress.
$ kubectl apply -f kuard-ingress.yaml
O sino eliminamos el Ingress y levantamos nuevamente.
$ kubectl delete -f kuard-ingress.yaml
$ kubectl create -f kuard-ingress.yaml
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
Podemos ver más detalles del mismo
$ kubectl describe certificate quickstart-example-tls
$ kubectl describe secret quickstart-example-tls
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
Y volvemos a levantar nuestro Ingress.
$ kubectl apply -f kuard-ingress.yaml
O sino eliminamos el Ingress y levantamos nuevamente.
$ kubectl delete -f kuard-ingress.yaml
$ kubectl create -f kuard-ingress.yaml
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
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
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}")
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
Utilizando helm podemos ver todos nuestros charts instalados incluido openfaas
$ helm list --all-namespaces
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
Una vez creado nuestro archivo de Issuers levantamos el mismo
$ kubectl create -f letsencrypt-issuer.yaml
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: /
Actualizamos nuestro chart
$ helm upgrade openfaas --namespace openfaas --reuse-values --values tls.yaml openfaas/openfaas
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
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: /
Volvemos a actualizar nuestro chart con helm de openfaas
$ helm upgrade openfaas --namespace openfaas --reuse-values --values tls.yaml openfaas/openfaas
Si el certificado no se regenera con el Issuer de producción puede ser necesario eliminarlo.
$ kubectl -n openfaas delete secret openfaas-crt
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
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
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)