K8sGPT
A conversa sobre Inteligência Artificial é tão predominante que é surpreendente que ainda não tenhamos visto uma aplicação para o Kubernetes. O projeto K8sGPT surge como uma iniciativa para unir o Kubernetes e a IA, visando analisar como essa fusão pode proporcionar benefícios tangíveis.
Embora o projeto K8sGPT esteja em seus estágios iniciais de desenvolvimento, promete ser uma ferramenta revolucionária na maneira como interagimos com o Kubernetes, desde que o modelo de IA seja treinado de forma adequada.
Para saber mais sobre o projeto K8sGPT, acesse K8sGPT.
Qual o problema?
Quando nos deparamos com desafios técnicos, nossa abordagem usual é recorrer a plataformas como o Stack Overflow ou a busca por issues nos repositórios do Github. Costumamos postar nossos problemas e examinar as respostas em busca da mais adequada. No entanto, muitas vezes compartilhamos apenas uma fração do problema ou do erro, e nenhuma dessas ferramentas pode estar onde nós estamos - sentados diante do computador, lidando com algo complexo e em constante mudança.
Para resolver adequadamente esses problemas, precisamos mudar de contexto, acessando logs, dados em ferramentas como Grafana, Jaeger e Kiali, ou consultando colegas de equipe no Slack. Temos acesso ao terminal, onde podemos interagir com o cluster usando o kubectl para obter mais informações.
No entanto, acabamos passando muito tempo copiando e colando dados de um lado para o outro na tentativa de solucionar o problema. O que realmente queremos é uma ferramenta que esteja ao nosso lado, com acesso aos dados que temos, para nos ajudar a investigar o problema sem comprometer a segurança das informações.
Nossa busca é por uma solução que nos permita interagir com uma IA capaz de analisar profundamente nosso cluster diretamente do terminal em que estamos trabalhando, sem a necessidade de mudar de contexto. Essa IA ideal seria capaz de:
- Identificar problemas no cluster.
- Explicar o problema.
- Corrigir ou propor soluções caso não for capaz de corrigir.
- Sugerir melhorias
Embora possamos sonhar com uma IA perfeita que resolva todos os nossos problemas, devemos ser realistas e entender que muitas questões estão relacionadas à arquitetura desejada ou a decisões de alto escalão. No entanto, mesmo que não seja perfeita, uma IA que trabalhe conosco e nos ajude a realizar tarefas de maneira mais eficiente seria um avanço significativo no universo do Kubernetes.
Estava buscando na CNCF e encontrei K8sGPT e resolvi analisar para ver qual o ganha será possível.
Instalação
Tenho um cluster local usando o kind já para nosso exemplo. Não temos nada ainda rodando no nosso cluster para avaliar, vamos somente fazer a instalação do K8sGPT e depois colocar algumas coisas erradas para ele avaliar. Em um segundo momento vamos tentar fornecer mais dados utilizando mais métricas para ver o que ele consegue fazer.
Podemos somente usar o binário do K8sGPT que irá interagir com o nosso cluster trazendo resultados sem precisar de nada instalado no cluster. Também podemos utilizar o K8sGPT-Operator que é instalado dentro do cluster e fará esta analise. Podemos ter ambos instalados, mas cada um possui suas configurações independentes.
Para instalar o binário:
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
# Esse passo é para criar o auto complete no meu cenário. Não é necessário caso não utilize o plugin zsh-completions do 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
O client irá utilizar o current context setado no seu kubeconfig para identificar o cluster que ele irá procurar o service que vamos instalar abaixo.
Agora vamos baixar o chart do K8sGPT Operator, fazer alguns ajustes e aplicar no nosso cluster.
# add repo
helm repo add k8sgpt https://charts.k8sgpt.ai/
helm repo update
helm show values k8sgpt/k8sgpt-operator > values.yaml
Este é o values.yaml default, mas podemos fazer algumas mudanças antes de começar.
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
Olhando o values acima podemos observar que o K8sGPT acessa as métricas do metric server, vamos garantir a instalação. É necessário que o metric server esteja funcionando no 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
Se estiver com algum problema por estar usando o kind é necessário adicionar esse argumento ao 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 #<<<< Add this
E confira se esta 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 ele também tem conexão com o Prometheus e Grafana então vamos deployar. Para facilitar vamos usar o Prometheus-Stack que já contém a stack de observabilidade completa incluindo essa duas ferramentas configuradas. dashboards.
O login para o grafana é user: admin e 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
Agora vamos ajustar o nosso values.yaml para habilitar os dois recursos e ter tudo disponível.
serviceMonitor:
enabled: true
grafanaDashboard:
enabled: true
Podemos então deployar o nosso K8sGPT uma vez que já temos o Metric Server, o Prometheus e o Grafana que é tudo que precisamos para aplicar o K8sGPT com todo seu 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 utilizar um custom resource definition criado para a instalação para configurar o K8sGPT-Operator no nosso cluster.
Os dados recolhido pelo client precisam precisam ser processados por algum backend que também são chamados de Providers. Esse é um serviço que fornece acesso a um modelo de linguagem de IA. O backend padrão é o OpenAI, mas pode ser mudado caso queira.
Como estamos fazendo duas instalações ao mesmo tempo, só para separar, vamos gerar duas api keys na sua conta da OpenAI. Se você não tem uma conta no OpenAI crie uma gratuitamente. Entre no link https://platform.openai.com/api-keys e gere uma api-key para o operator e outra para o client e salve em algum lugar que já vamos utilizá-las.
Vamos colocar a api-key para o operator no namespace o k8sgpt-operator-system que é onde temos o nosso operator rodando.
kubectl create secret generic k8sgpt-secret --from-literal=openai-api-key=SUA-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: portuguese
noCache: false
version: v0.3.29
# filters: # Configurações dos filtros e outras coisas
# - Ingress
# sink:
# type: slack
# webhook: <webhook-url>
# extraOptions:
# backstage:
# enabled: true
EOF
Os filters, sink, extraOptions e outras coisas futuras seriam configurados usando o custom resource acima.
No caso da cli ficaria em ~/.config/k8sgpt/k8sgpt.yaml.
Usando o K8sGpt
Vamos utilizar o client um pouquinho. Até agora somente temos um client que nada mais é do que um binário. Também precisamos configurar um backend aqui. O backend padrão é o OpenAI, mas pode ser mudado caso queira.
k8sgpt auth list
Default:
> openai
Active:
> openai
Unused:
> localai
> azureopenai
> noopai
> cohere
> amazonbedrock
> amazonsagemaker
# O comando abaixo seria uma ajuda como gerar um chave 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
# Já que ele é o default podemos apenas digitar o comando abaixo e colar a chave de api gerada anteriormente para o client
k8sgpt auth add -b openai
Vamos fazer a primeira analise do nosso cluster. Preparei um pod test usando uma imagem blablabla que não existe.
# Não usará a IA para tentar explicar o problema
k8sgpt analyze --filter Pod
AI Provider: AI not used; --explain not set
0 default/test(test)
- Error: Back-off pulling image "blablabla"
# Com o explain usamos a IA para tentar explicar o problema
k8sgpt analyze --filter Pod --explain --language Portuguese
AI Provider: openai
# Coloquei uma imagem que existe
kubectl set image pod/test test=nginx:latest ─╯
pod/test image updated
## O anonymize serve para mascarar os dados sensíveis caso exista
k8sgpt analyze --filter Pod --explain --language Portuguese --anonymize
AI Provider: openai
No problems detected
O K8sGPT esta crescendo esperando muitas integrações. Uma que já existe é o Trivy que já é muito utilizado para escanear problemas com segurança nas imagens utilizadas pelos containers.
k8sgpt integration list
Active:
Unused:
> trivy
> aws
> prometheus
# Aqui estamos deployando o trivy junto ao namespace do k8sgpt, se não for passado irá para o 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 abaixo
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
O trivy-operator tentará criará um pod que no control plane e se tiver uma taint ficará em estado de pending. Só para ficar mais fácil essa documentação e focar na IA, remova a taint do control plane para permitir que esse pod avance.
Vamos também colocar a integração com o prometheus.
# O prometheus já existe e como deployamos anteriormente
k8sgpt integration activate prometheus -n observability
Activating prometheus integration...
Found existing installation
Activated integration prometheus
k8sgpt integration list
Active:
> trivy
> prometheus
Unused:
> aws
Adicionando integrações mais objetos aparecerão nos filtros para serem feito análise.
k8sgpt filter list ─╯
Active:
> Ingress
> PersistentVolumeClaim
> ReplicaSet
> MutatingWebhookConfiguration
> Deployment
> ValidatingWebhookConfiguration
> PrometheusConfigValidate (integration) # Não é default (Aparece depois da integração com o prometheus)
> VulnerabilityReport (integration) # # Não é default (Aparece depois da integração com o trivy)
> StatefulSet
> ConfigAuditReport (integration) # # Não é default (Aparece depois da integração com o trivy)
> Service
> PrometheusConfigRelabelReport (integration) # Não é default (Aparece depois da integração com o prometheus)
> Node
> Pod
> CronJob
Unused:
> GatewayClass
> Gateway
> HTTPRoute
> HorizontalPodAutoScaler
> PodDisruptionBudget
> NetworkPolicy
> Log
Podemos adicionar ou remover esses filtros usando o comando k8sgpt filter. Esses são os mesmo filtros que podemos configurar no custom resource definition do K8sGPT-Operator.
O K8sGPT-operator cria um board no grafana. Esse board esta mostrando as métricas dos resultados ao longo do período que foram corrigidos. Toda vez que o pod executa a analise o é criado um objeto result que é um custom resource definition do k8sgpt-operator.

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": ""
}
}
Conclusão
É uma ferramenta promissora se for treinada corretamente. Acredito que nesta fase inicial precisa de muita contribuição para fazer uma análise precisa.
- Ainda não faz o analise como gostaríamos
- Documentação ruim
- Os filtros ainda cobrem somente o básico
- Observando que algumas integrações aumentaram os filtros, ainda precisa de muitas integrações como o Istio, Nginx, Cert-Manager, External-DNS, etc.