En el post anterior Implementar AWX en GKE vimos como realizar una implementación basica de AWX en un Cluster de GKE utilizando la version 2.11.0 con Helm.
Ahora vamos a realizar una implementación production-ready. Vamos a asginar a nuestro deployment:
- Utilizaremos la versión 2.17.0 del Operador de AWX.
- Storage persistente (standard-rwo) en GKE.
- Solucionaremos: 1. Bug de Ingress en GKE y 2. Bug de AccesType en PV de los Pods de Task y Web.
- Ademas solucionaremos el Bug de permisos de acceso para escritura de datos en el PVC para el pod de Postgres.
Clonar repositorio
Primero debemos descargar el ultimo release disponible del Operator. A la fecha de este post, el ultimo release disponible es el 2.17.0. Para esto ejecutaremos los siguientes comandos:
git clone https://github.com/ansible/awx-operator/tree/2.17.0 awx-operator.2.17.0
cd .\awx-operator.2.17.0\
git checkout tags/2.17.0 -b release-2.17.0
code .
Esto nos asegurará tener los archivos disponibles a la versión del Release.
Editar Ingress jinja template
Basado en el este Issue del repositorio Oficial del Operador de AWX.
- Dentro de los roles, debemos ingresar al rol de installer.
- En la sección de templates ir a Networking y seleccionar el archivo ingress.yaml.j2.
- Path: .\roles\installer\templates\networking\ingress.yaml.j2
- Debemos reemplazar la linea 30 de dicho archivo, por el siguiente codigo:
- path: '{{ (ingress_path + '/*').replace("//","/") }}'
Este paso es importante ya que nos asegura que el manifiesto generado por el Operador del K8s Ingress (HTTPs Load Balancer en GKE) quede finalmente con un Path correcto.
Crear custom Operator Container
Ahora debemos crear y almacenar nuestra custom image del Operador en un Artifact Registry privado.
Crear GCP Artifact Registry
Ahora debemos crear un Artifact Registry en GCP para guardar nuestra imagen. Ejecutaremos el siguiente gcloud command:
gcloud artifacts repositories create awx_repo \
--repository-format=docker \
--location=us-east4 --description="AWX Containers Repo" \
--project=multicloudstech-gke
Ahora debemos autenticar Docker con gcloud para poder pushear las imagenes a este repo, ejecutando el siguiente comando:
gcloud auth configure-docker us-east4-docker.pkg.dev
Docker Build
Ahora realizaremos el build de nuestra propia imagen de Docker del AWX-Operator. Para esto, luego de haber modificado el Jinja2 File del Ingress, realizar el Docker Build:
docker build -t us-east4-docker.pkg.dev/multicloudstech-gke/awx-repo/awx-operator:2.17.0 . --no-cache
Podremos verificar la imagen construida:
Docker Push
Ahora realizaremos el push de la imagen creada a nuestro artifact registry. Ejecutaremos el siguiente comando:
docker push us-east4-docker.pkg.dev/multicloudstech-gke/awx-repo/awx-operator:2.17.0
Verificamos que la imagen fue pusheada exitosamente:
Configurar AWX Artifact Registry Login
Ahora debemos asignar los permisos necesarios a nuestra cuenta de servicio de nuestros nodos de Kubernetes para leer/pull images desde Artifact Registry. Para esto asignaremos el rol de Artifact Registry Reader la Service Account asignada a los nodos de GKE.
Crear AWX Operator Yaml
Ahora, utilizando las cualidades de Make, realizaremos la creación del Manifiesto de AWX Operator. Ejecutaremos el siguiente comando (en linux):
make gen-resources | tee awx-operator.yaml
Se creará el archivo para desplegar nuestro Operador:
Cambios al YAML del Operator
Ahora debemos realizar algunos cambios a nuestro manifiesto.
Image Pull Secret
En la linea 2860, debemos comentar la linea de Image Pull Secret.
Ahora reemplazaremos en la linea 2832, cambiando la imagen por defecto del Operador por la nueva que acabamos de crear.
Desplegar AWX Operator
Realizaremos el primer paso de despliegue, aplicaremos el manifiesto inicial del Operador. Para esto, ejecutaremos el siguiente comando:
kubectl apply -f .\awx-operator.yaml -n awx
Aquí veremos que se crean todos los recursos relacionados con el Namespace, los CRD, RBAC permissions, K8s Service Accounts, ConfigMaps, el Servicio del Operador y el Deployment.
Ahora podemos ver que nuestro Operador esta desplegado:
Desplegar recurso AWX
Ahora sí, con nuestro Operador desplegado y funcionando podemos realizar el despliegue de AWX. Para esto debemos generar nuestro manifiesto, pero antes un prerrequisito…
Prerrequisito
Primero debemos asegurarnos:
- HTTPs Load Balancing este habilitado en GKE.
- Crear una IP estática reservada para el ingress.
- Disponer de un certificado para configurar en el ingress
Crear Secret para el certificado
En este caso, disponemos de un certificado creado con Let’s Encrypt. Vamos a guardarlo como secret en Kubernetes, utiilzando el siguiente comando:
kubectl create secret tls awx-multiclouds-tech-cert --cert=C:\Users\Mateo\AppData\Local\Posh-ACME\LE_PROD\1629371947\awx.multiclouds.tech\cert.cer --key=C:\Users\Mateo\AppData\Local\Posh-ACME\LE_PROD\1629371947\awx.multiclouds.tech\cert.key -n awx
Crear manifiesto de recurso AWX
Ahora realizaremos la implementación de nuestro CRD. Para esto crearemos el siguiente manifiesto:
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: ansible-awx
namespace: awx
spec:
service_type: nodeport
postgres_storage_class: standard-rwo
projects_persistence: true
projects_storage_access_mode: ReadWriteOnce
ingress_type: ingress
ingress_path: /
ingress_path_type: ImplementationSpecific
hostname: awx.multiclouds.tech
ingress_tls_secret: awx-multiclouds-tech-cert
ingress_annotations: |
kubernetes.io/ingress.global-static-ip-name: <<< IP ADDRESS NAME >>>
cloud.google.com/backend-config: '{"ports": {"80":"awx-backendconfig"}}'
service_annotations: |
cloud.google.com/backend-config: '{"ports": {"80":"awx-backendconfig"}}'
cloud.google.com/neg: '{"ingress": true}'
- Recordar asignar el nombre de la reserva de IP address realizada en GCP en la 18.
- Es importante tener en cuenta que podes recibir un error si cambias el parametro projects_storage_access_mode.
Implementar AWX
Realizaremos el Apply de nuestro manifiesto ejecutando el siguiente commando:
kubectl apply -f .\awx-deploy.yaml -n awx
Ahora podremos revisar el status de nuestros Pods:
kubectl get pods -n awx -w
Si vemos los logs del pod, verificamos que:
El contenedor de Postgres no puede escribirr data al PVC:
Solucionar Postgres “mkdir: cannot create directory ‘/var/lib/pgsql/data/userdata’: Permission denied”
Para solucionar este error debemos generar un pod temporar para inspecionar el PVC y asignar permisos al usuario 26 que es el que postgres utiliza por default.
Vamos a crear el siguiente manificesto para un PVC-Inspector pod, a través del cual asignaremos los permisos al PVC.
apiVersion: v1
kind: Pod
metadata:
name: pvc-inspector
namespace: awx
spec:
containers:
- image: busybox
name: pvc-inspector
command: ["tail"]
args: ["-f", "/dev/null"]
volumeMounts:
- mountPath: /pvc
name: pvc-mount
volumes:
- name: pvc-mount
persistentVolumeClaim:
claimName: postgres-15-ansible-awx-postgres-15-0
Aplicamos el manifest:
kubectl apply -f .\pvc-inspector.yaml -n awx
Una vez creado ingresamos al pod:
kubectl exec -it pvc-inspector -n awx -- /bin/sh
Asignamos el siguiente permiso:
chown -R 26:26 /pvc/data/
Al realizar esto el pod de postgres debería pasar al estado “Running”. Si no lo hace de manera automatica, podemos eleiminarlo y se volverá a crear gracias al autohealing de nuestro deployment.
Luego continuará el deploy hasta tener todos los pods funcionando:
En este sentido, podemos ver que el Ingress no está tomando correctamente la ip address designada en el awx-deploy.yaml.
Solucionar problematica del Ingress
Como vimos en el punto anterior, el ingress no está funcionando correctamente. Ya que se está creando el HTTP Load Balancer que esperamos en GCP:
Utlizando el comando de kubctl describe, podemos ver el error arrojado:
kubectl describe ingress ansible-awx-ingress -n awx
Para solucionar esto vamos a crear el BackendConfig, generando el siguiente manifiesto:
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: awx-backendconfig
namespace: awx
Realizamos el Apply del backend-config file:
kubectl apply -f .\backend-config.yaml -n awx
Al configurarlo podemos verificar que un HTTPs Load Balancer es creado en GCP:
Luego de un momento, Kubernetes se da cuenta del cambio y realiza la correcta configuración del Ingress:
Así ahora podemos ver como podemos ingresar correctamente a nuestro Cluster 🙂
Leave a Reply