Skip to main content

K8sGPT

k8sgpt-logo

La conversación sobre Inteligencia Artificial es tan predominante que es sorprendente que todavía no hayamos visto una aplicación para Kubernetes. El proyecto K8sGPT surge como una iniciativa para unir Kubernetes y la IA, buscando analizar cómo esa fusión puede proporcionar beneficios tangibles.

Aunque el proyecto K8sGPT esté en sus etapas iniciales de desarrollo, promete ser una herramienta revolucionaria en la manera como interactuamos con Kubernetes, desde que el modelo de IA sea entrenado de forma adecuada.

Para saber más sobre el proyecto K8sGPT, accede a K8sGPT.

¿Cuál es el problema?

Cuando nos enfrentamos a desafíos técnicos, nuestro enfoque usual es recurrir a plataformas como Stack Overflow o la búsqueda por issues en los repositorios de Github. Solemos publicar nuestros problemas y examinar las respuestas en busca de la más adecuada. Sin embargo, muchas veces compartimos apenas una fracción del problema o del error, y ninguna de esas herramientas puede estar donde nosotros estamos - sentados frente a la computadora, lidiando con algo complejo y en constante cambio.

Para resolver adecuadamente esos problemas, necesitamos cambiar de contexto, accediendo logs, datos en herramientas como Grafana, Jaeger y Kiali, o consultando colegas de equipo en Slack. Tenemos acceso al terminal, donde podemos interactuar con el cluster usando kubectl para obtener más información.

Sin embargo, acabamos pasando mucho tiempo copiando y pegando datos de un lado para otro en el intento de solucionar el problema. Lo que realmente queremos es una herramienta que esté a nuestro lado, con acceso a los datos que tenemos, para ayudarnos a investigar el problema sin comprometer la seguridad de las informaciones.

Nuestra búsqueda es por una solución que nos permita interactuar con una IA capaz de analizar profundamente nuestro cluster directamente del terminal en que estamos trabajando, sin la necesidad de cambiar de contexto. Esa IA ideal sería capaz de:

  1. Identificar problemas en el cluster.
  2. Explicar el problema.
  3. Corregir o proponer soluciones caso no sea capaz de corregir.
  4. Sugerir mejoras

Aunque podamos soñar con una IA perfecta que resuelva todos nuestros problemas, debemos ser realistas y entender que muchas cuestiones están relacionadas a la arquitectura deseada o a decisiones de alto escalón. Sin embargo, aunque no sea perfecta, una IA que trabaje con nosotros y nos ayude a realizar tareas de manera más eficiente sería un avance significativo en el universo de Kubernetes.

Estaba buscando en la CNCF y encontré K8sGPT y resolví analizar para ver cuál ganancia será posible.

Instalación

Tengo un cluster local usando kind ya para nuestro ejemplo. No tenemos nada todavía ejecutando en nuestro cluster para evaluar, vamos solamente hacer la instalación de K8sGPT y después colocar algunas cosas erradas para que él evalúe. En un segundo momento vamos a intentar proporcionar más datos utilizando más métricas para ver lo que consigue hacer.

Podemos solamente usar el binario de K8sGPT que interactuará con nuestro cluster trayendo resultados sin necesitar de nada instalado en el cluster. También podemos utilizar el K8sGPT-Operator que es instalado dentro del cluster y hará este análisis. Podemos tener ambos instalados, pero cada uno posee sus configuraciones independientes.

Para instalar el binario:

sudo apt-get update
sudo apt-get install build-essential -y

curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.29/k8sgpt_amd64.deb
sudo dpkg -i k8sgpt_amd64.deb

k8sgpt version
k8sgpt: 0.3.29 (5db4bc2), built at: unknown

# Este paso es para crear el auto complete en mi escenario. No es necesario caso no utilices el plugin zsh-completions de Oh My ZSH
k8sgpt completion zsh > .oh-my-zsh/custom/plugins/zsh-completions/src/_k8sgpt

k8sgpt
analyze -- This command will find problems within your Kubernetes cluster
auth -- Authenticate with your chosen backend
cache -- For working with the cache the results of an analysis
completion -- Generate the autocompletion script for the specified shell
filters -- Manage filters for analyzing Kubernetes resources
generate -- Generate Key for your chosen backend (opens browser)
help -- Help about any command
integration -- Integrate another tool into K8sGPT
serve -- Runs k8sgpt as a server
version -- Print the version number of k8sgpt

El client utilizará el current context seteado en tu kubeconfig para identificar el cluster que buscará el servicio que vamos a instalar abajo.

Ahora vamos a descargar el chart de K8sGPT Operator, hacer algunos ajustes y aplicar en nuestro cluster.

# Agregar repo
helm repo add k8sgpt https://charts.k8sgpt.ai/
helm repo update
helm show values k8sgpt/k8sgpt-operator > values.yaml

Este es el values.yaml por defecto, pero podemos hacer algunos cambios antes de comenzar.

serviceMonitor:
enabled: false
additionalLabels: {}
# The namespace where Prometheus expects to find the serviceMonitor
# namespace: ""
grafanaDashboard:
enabled: false
# The namespace where Grafana expects to find the dashboard
# namespace: ""
folder:
annotation: grafana_folder
name: ai
label:
key: grafana_dashboard
value: "1"
# create GrafanaDashboard custom resource referencing to the configMap.
# according to https://grafana-operator.github.io/grafana-operator/docs/examples/dashboard_from_configmap/readme/
grafanaOperator:
enabled: false
matchLabels:
dashboards: "grafana"
controllerManager:
kubeRbacProxy:
containerSecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
image:
repository: gcr.io/kubebuilder/kube-rbac-proxy
tag: v0.15.0
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 5m
memory: 64Mi
manager:
sinkWebhookTimeout: 30s
containerSecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
image:
repository: ghcr.io/k8sgpt-ai/k8sgpt-operator
tag: v0.1.2 # x-release-please-version
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi
replicas: 1
## Node labels for pod assignment
## ref: https://kubernetes.io/docs/user-guide/node-selection/
#
nodeSelector: {}
kubernetesClusterDomain: cluster.local
metricsService:
ports:
- name: https
port: 8443
protocol: TCP
targetPort: https
type: ClusterIP

Mirando el values arriba podemos observar que K8sGPT accede las métricas del metric server, vamos a garantizar la instalación. Es necesario que el metric server esté funcionando en el cluster.

curl -LO https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/high-availability-1.21+.yaml
kubectl apply -f high-availability-1.21+.yaml

Si estás con algún problema por estar usando kind es necesario agregar ese argumento al deployment.

      containers:
- args:
- --cert-dir=/tmp
- --secure-port=10250
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
- --kubelet-insecure-tls #<<<< Agregar esto

Y verifica si está funcionando.

kubectl get deployments.apps -n kube-system metrics-server
NAME READY UP-TO-DATE AVAILABLE AGE
metrics-server 2/2 2 2 5m54s

Podemos ver que también tiene conexión con Prometheus y Grafana, entonces vamos a desplegar. Para facilitar vamos a usar el Prometheus-Stack que ya contiene el stack de observabilidad completo incluyendo esas dos herramientas configuradas.

El login para grafana es user: admin y password: prom-operator.

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install observability prometheus-community/kube-prometheus-stack -n observability --create-namespace --set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false

kubectl get pods -n observability
NAME READY STATUS RESTARTS AGE
alertmanager-observability-kube-prometh-alertmanager-0 2/2 Running 0 4m30s
observability-grafana-7dc45dccc7-ht58h 3/3 Running 0 4m40s
observability-kube-prometh-operator-69f7854756-hskn4 1/1 Running 0 4m40s
observability-kube-state-metrics-6bfd9996d-42pq5 1/1 Running 0 4m40s
observability-prometheus-node-exporter-d74bb 1/1 Running 0 4m40s
observability-prometheus-node-exporter-mfsvw 1/1 Running 0 4m40s
observability-prometheus-node-exporter-wlxh2 1/1 Running 0 4m40s
prometheus-observability-kube-prometh-prometheus-0 2/2 Running 0 4m30s

Ahora vamos a ajustar nuestro values.yaml para habilitar los dos recursos y tener todo disponible.

serviceMonitor:
enabled: true
grafanaDashboard:
enabled: true

Podemos entonces desplegar nuestro K8sGPT una vez que ya tenemos el Metric Server, Prometheus y Grafana que es todo lo que necesitamos para aplicar K8sGPT con todo su potencial:

helm install k8sgpt k8sgpt/k8sgpt-operator -n k8sgpt-operator-system --create-namespace --values values.yaml --wait

k get deployments.apps -n k8sgpt-operator-system
NAME READY UP-TO-DATE AVAILABLE AGE
k8sgpt-k8sgpt-operator-controller-manager 1/1 1 1 24s

Vamos a utilizar un custom resource definition creado para la instalación para configurar el K8sGPT-Operator en nuestro cluster.

Los datos recolectados por el client necesitan ser procesados por algún backend que también son llamados de Providers. Ese es un servicio que proporciona acceso a un modelo de lenguaje de IA. El backend por defecto es OpenAI, pero puede ser cambiado caso quieras.

Como estamos haciendo dos instalaciones al mismo tiempo, solo para separar, vamos a generar dos api keys en tu cuenta de OpenAI. Si no tienes una cuenta en OpenAI crea una gratuitamente. Entra en el link https://platform.openai.com/api-keys y genera una api-key para el operator y otra para el client y guarda en algún lugar que ya vamos a utilizarlas.

Vamos a colocar la api-key para el operator en el namespace k8sgpt-operator-system que es donde tenemos nuestro operator ejecutando.

kubectl create secret generic k8sgpt-secret --from-literal=openai-api-key=TU-API-KEY-PARA-OPERATOR -n k8sgpt-operator-system

# Configurando
kubectl apply -f - << EOF
apiVersion: core.k8sgpt.ai/v1alpha1
kind: K8sGPT
metadata:
name: k8sgpt
namespace: k8sgpt-operator-system
spec:
ai:
enabled: true
model: gpt-3.5-turbo
backend: openai
secret:
name: k8sgpt-secret
key: openai-api-key
# anonymized: false
language: spanish
noCache: false
version: v0.3.29
# filters: # Configuraciones de los filtros y otras cosas
# - Ingress
# sink:
# type: slack
# webhook: <webhook-url>
# extraOptions:
# backstage:
# enabled: true
EOF

Los filters, sink, extraOptions y otras cosas futuras serían configurados usando el custom resource arriba.

En el caso del cli quedaría en ~/.config/k8sgpt/k8sgpt.yaml.

Usando K8sGpt

Vamos a utilizar el client un poquito. Hasta ahora solamente tenemos un client que nada más es que un binario. También necesitamos configurar un backend aquí. El backend por defecto es OpenAI, pero puede ser cambiado caso quieras.

k8sgpt auth list
Default:
> openai
Active:
> openai
Unused:
> localai
> azureopenai
> noopai
> cohere
> amazonbedrock
> amazonsagemaker

# El comando abajo sería una ayuda como generar una llave para backend openai
k8sgpt generate -b openai
#Opening: https://beta.openai.com/account/api-keys to generate a key for openai
#Please copy the generated key and run `k8sgpt auth` to add it to your config file

# Ya que es el default podemos apenas digitar el comando abajo y pegar la llave de api generada anteriormente para el client
k8sgpt auth add -b openai

Vamos a hacer el primer análisis de nuestro cluster. Preparé un pod test usando una imagen blablabla que no existe.

# No usará la IA para intentar explicar el problema
k8sgpt analyze --filter Pod
AI Provider: AI not used; --explain not set

0 default/test(test)
- Error: Back-off pulling image "blablabla"

# Con el explain usamos la IA para intentar explicar el problema
k8sgpt analyze --filter Pod --explain --language Spanish
AI Provider: openai

# Coloqué una imagen que existe
kubectl set image pod/test test=nginx:latest
pod/test image updated

## El anonymize sirve para enmascarar los datos sensibles caso exista
k8sgpt analyze --filter Pod --explain --language Spanish --anonymize
AI Provider: openai

No problems detected

K8sGPT está creciendo esperando muchas integraciones. Una que ya existe es Trivy que ya es muy utilizado para escanear problemas con seguridad en las imágenes utilizadas por los contenedores.

k8sgpt integration list
Active:
Unused:
> trivy
> aws
> prometheus

# Aquí estamos desplegando trivy junto al namespace de k8sgpt, si no es pasado irá para el default
k8sgpt integration activate trivy -n k8sgpt-operator-system

k get pod -n k8sgpt-operator-system
NAME READY STATUS RESTARTS AGE
k8sgpt-k8sgpt-operator-controller-manager-d87f55664-rbw9s 2/2 Running 0 26m
node-collector-6c9c585b94-frmqs 0/1 Pending 0 21s #<<<<Explicado abajo
scan-vulnerabilityreport-57fd85d74b-tlt9r 2/2 Running 0 11s
scan-vulnerabilityreport-644f484554-t85dh 0/1 Init:0/1 0 10s
scan-vulnerabilityreport-6984ffc9f-xxtd6 0/1 Init:0/1 0 9s
scan-vulnerabilityreport-757795c96c-4tzld 3/3 Running 0 17s
scan-vulnerabilityreport-b677d9c7d-fdk42 3/3 Running 0 13s
trivy-operator-k8sgpt-6c844cf96-wknvj 1/1 Running 0 22s

k8sgpt integration list
Active:
> trivy
Unused:
> aws
> prometheus

El trivy-operator intentará crear un pod que en el control plane y si tuviera un taint quedará en estado de pending. Solo para que sea más fácil esta documentación y enfocarse en la IA, remueve el taint del control plane para permitir que ese pod avance.

Vamos también a colocar la integración con prometheus.

# Prometheus ya existe y como desplegamos anteriormente
k8sgpt integration activate prometheus -n observability
Activating prometheus integration...
Found existing installation
Activated integration prometheus

k8sgpt integration list
Active:
> trivy
> prometheus
Unused:
> aws

Agregando integraciones más objetos aparecerán en los filtros para ser hechos análisis.

k8sgpt filter list
Active:
> Ingress
> PersistentVolumeClaim
> ReplicaSet
> MutatingWebhookConfiguration
> Deployment
> ValidatingWebhookConfiguration
> PrometheusConfigValidate (integration) # No es default (Aparece después de la integración con prometheus)
> VulnerabilityReport (integration) # # No es default (Aparece después de la integración con trivy)
> StatefulSet
> ConfigAuditReport (integration) # # No es default (Aparece después de la integración con trivy)
> Service
> PrometheusConfigRelabelReport (integration) # No es default (Aparece después de la integración con prometheus)
> Node
> Pod
> CronJob
Unused:
> GatewayClass
> Gateway
> HTTPRoute
> HorizontalPodAutoScaler
> PodDisruptionBudget
> NetworkPolicy
> Log

Podemos agregar o remover esos filtros usando el comando k8sgpt filter. Esos son los mismos filtros que podemos configurar en el custom resource definition de K8sGPT-Operator.

K8sGPT-operator crea un board en grafana. Ese board está mostrando las métricas de los resultados a lo largo del período que fueron corregidos. Toda vez que el pod ejecuta el análisis es creado un objeto result que es un custom resource definition de k8sgpt-operator.

k8sgpt_grafana

kubectl get results -o json -n k8sgpt-operator-system| jq .
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "core.k8sgpt.ai/v1alpha1",
"kind": "Result",
"metadata": {
"creationTimestamp": "2024-04-10T00:36:54Z",
"generation": 1,
"labels": {
"k8sgpts.k8sgpt.ai/backend": "openai",
"k8sgpts.k8sgpt.ai/name": "k8sgpt",
"k8sgpts.k8sgpt.ai/namespace": "k8sgpt-operator-system"
},
"name": "defaulttest",
"namespace": "k8sgpt-operator-system",
"resourceVersion": "312762",
"uid": "f3a5b460-d58c-4e3c-991d-9608044b6812"
},
"spec": {
"backend": "openai",
"details": "",
"error": [
{
"text": "failed to pull and unpack image \"docker.io/library/blablabla:latest\": failed to resolve reference \"docker.io/library/blablabla:latest\": pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed"
}
],
"kind": "Pod",
"name": "default/test",
"parentObject": ""
},
"status": {
"lifecycle": "historical"
}
}
],
"kind": "List",
"metadata": {
"resourceVersion": ""
}
}

Conclusión

Es una herramienta prometedora si es entrenada correctamente. Creo que en esta fase inicial necesita mucha contribución para hacer un análisis preciso.

  • Todavía no hace el análisis como nos gustaría
  • Documentación deficiente
  • Los filtros todavía cubren solamente lo básico
  • Observando que algunas integraciones aumentaron los filtros, todavía necesita muchas integraciones como Istio, Nginx, Cert-Manager, External-DNS, etc.