Skip to content

igor-primo/lab-proxmox-doc

Repository files navigation

Roteiro Kubernetes

Introdução

Essa documentação utiliza princípios de programação letrada. Consequentemente, alguns snippets que são descritos abaixo então contidos em scripts extraídos da documentação. O nome do script que contém o snippet respectivo está em um comentário na primeira linha do snippet.

Todos os scripts e comandos devem ser executados como usuário raiz. Recomenda-se que se utilize uma máquina exterior ao cluster para fazer a instalação.

O login de usuário root via SSH deve estar habilitado também.

Clonar VMs

A clonagem das VMs é feita através do ProxMox manualmente. Para clonar uma VM utilize o template chamado “rocky9vm”; clique com o botão direito do mouse na VM e clique em “clone”. Ajuste as configurações como quiser, mas recomenda-se a utilização de modo “Linked Clone”. Uma VM gerada com essa configuração requer menos espaço em disco, mas não pode executar sem acesso à VM template base utilizida, i.e., “rocky9vm”. Após a clonagem você terá uma nova VM para ser utilizada.

SSH

Para termos a conveniência de logarmos na máquina sem introduzir senha toda vez, devemos criar chaves assimétricas para acesso sem senha. Esse passo deve ser feito manualmente.

Criação das chaves assimétricas

# A variável HOSTS deve conter os IPs dos hosts da instalação do cluster
# separados por um espaço.
# Exemplo: HOSTS=(10.20.1.123 10.20.1.124)
HOSTS=()
# Gera uma chave RSA
# Explicação para as bandeiras para o programa ssh-keygen
# -q: modo silencioso
# -t: especifica o tipo de chave a ser criada
# -b: especifica o número de bits na chave a ser criada
# -f: especifica o nome do arquivo do arquivo da chave
# -P: especifica a senha antiga
ssh-keygen -q -t rsa -b 4096 -f ~/.ssh/id_rsa -P ""
# Copia a chave pública correspondente para os hospedeiros remotos
for HOST in "${HOSTS[@]}"; do ssh-copy-id $USER@$HOST; done

Instalar Python

Para executar e instalar o Ansible, precisamos do Python e do Pip no host de onde partirá a instalação do cluster Kubernete. O seguinte snippet instala Python e Pip em sistemas baseados em RPM. Caso o sistema ponto de partida não seja baseado em RPM, deve-se utilizar os comandos cabíveis.

# ./deps-install.sh
sudo dnf install python39 python3-pip -y
pip3 install --upgrade pip

Clonar repositório do Kubespray e instalar dependências

Caso a instalação esteja partindo de uma máquina exterior ao cluster, pode-se utilizar o seguinte script integralmente; mas se a instalação estiver partindo de um dos nós do cluster, deve-se omitir a instalação do ambiente virtual Python.

O script abaixo instala as dependências Python do Kubespray no diretório ./kubespray-venv na raíz desse projeto. Segundo a documentação do Python, esses ambientes virtuais servem para resolver problemas de incompatibilidade entre versões de um mesmo software requerido em versões diversas. Em alguns dos scripts/snippets que seguem, utilizaremos essas dependências por conveniência.

Caso seu sistema não possua os utilitários “wget” e “tar”, instale-os:

dnf install -y wget tar
	# ./kubespray-install.sh
	if [ ! -d ./kubespray-2.22.0 ]; then
		wget https://github.com/kubernetes-sigs/kubespray/archive/refs/tags/v2.22.0.tar.gz
		tar -xf v2.22.0.tar.gz
		rm v2.22.0.tar.gz
	fi

	EXTERNAL=""
	read -p "A instalação do cluster parte de uma máquina externa ao cluster? (y/N)" EXTERNAL
	if [ $EXTERNAL = "y" ]; then
	  pip install virtualenv
	  VENVDIR=kubespray-venv
	  KUBESPRAYDIR=kubespray-2.22.0
	  ANSIBLE_VERSION=2.12
	  virtualenv  --python=$(which python3) $VENVDIR
	  source $VENVDIR/bin/activate
	  cd $KUBESPRAYDIR
	  pip install -U -r requirements-$ANSIBLE_VERSION.txt
	elif [ $EXTERNAL = "N" ]; then 
	  cd kubespray-2.22.0
	  pip install -U -r requirements.txt
	else
	  echo "Entrada inválida"
	fi

Atualizar sistemas

Caso julgue necessário, atualize os sistemas operacionais. Esse script depende da existência dos arquivos “inventory.ini” e “update-systems-playbook.yaml” que são providos nesse repositório.

Esse é playbook Ansible que especifica a tarefa para atualizar os pacotes do sistema operacional alvo para as versões mais recentes da distribuição. Não precisa ser modificado.

- name: Atualiza sistema
  hosts: server*
  become: true
  tasks:
  - name: Atualiza sistema
    package:
      name: '*'
      state: latest

Esse é o inventário contendo configuração para acesso aos hosts. Esse arquivo deve ser atualizado com os IPs dos hosts do cluster manualmente.

server1 ansible_host=10.20.1.113
server2 ansible_host=10.20.1.115

Esse é o mini-roteiro a ser utilizado para aplicar o YAML anterior.

# ./update-systems.sh
(
	  # Se o diretório ./kubespray-venv existe, assume que
	  # a instalação parte de uma máquina exterior ao cluster
	  # e carrega as variáveis do ambiente virtual para o sub-shell
	  if [ -d ./kubespray-venv ]; then
		  source ./kubespray-venv/bin/activate
	  fi
	  ansible-playbook -i inventory.ini update-systems-playbook.yaml --become --become-user=root
)

Desabilitar firewall

Caso os firewalls não tenham sido desabilitados, desabilitá-los para simplificar a instalação. É recomendável que após a instalação, faça-se uma configuração adequada do firewall.

Esse é o playbook Ansible utilizado para instruir o Ansible para executar os comandos para parar e desabilitar o serviço de firewall nas máquinas alvo.

Esse playbook utiliza o inventário mencionado na seção anterior, portanto ele deve estar atualizado com os IPs das máquianas alvo.

- name: Remove firewall e habilitar login de root via SSH
  hosts: server*
  become: true
  tasks:
  - name: Remove firewall
    shell: |
      systemctl stop firewalld.service
      systemctl disable firewalld.service

Esse é o snippet para aplicar a configuração.

# ./remove-firewall.sh
(
	  # Se o diretório ./kubespray-venv existe, assuma que
	  # a instalação parte de uma máquina exterior ao cluster
	  # e carregue as variáveis do ambiente virtual no sub-shell
	  if [ -d ./kubespray-venv ]; then
		  source ./kubespray-venv/bin/activate
	  fi
	  ansible-playbook -i inventory.ini remove-firewall-playbook.yaml --become --become-user=root
)

Instalação do Kubernetes

A instalação do Kubernetes pode ser feita seguindo o seguinte snippet. Mas há algumas ressalvas. A instalação utilizando ambientes virtuais do Python quando a instalação é feita a partir de uma máquina que será um nó do cluster apresenta erros na busca de dependências do python. Mas como caso a máquina deva ser parte do cluster esse roteiro instrui para não utilizar ambientes virtuais do Python para instalar as dependências do Kubespray, esse problema já foi contornado.

Os seguintes passos, que são os mais importantes, devem ser executados manualmente:

# Na raíz do projeto kubespray.
cd kubespray-2.22.0

cp -rfp inventory/sample inventory/mycluster
# IPS é um vetor contendo os IPs dos hosts do cluster.
declare -a IPS=()

# A seguinte linha deve ser executada somente se a máquina de onde parte
# a instalação for externa ao cluster.
source ../kubespray-venv/bin/activate

# Esse script gera o inventário automaticamente com configuração padrão.
CONFIG_FILE=inventory/mycluster/hosts.yaml python3 contrib/inventory_builder/inventory.py ${IPS[@]}
# Nesse ponto pode-se revisar e modificar as variáveis em
# inventory/mycluster/group_vars/all/all.yml e
# inventory/mycluster/group_vars/k8s_cluster/k8s_cluster.yml.

# Para limpar um cluster velho, executar como root:
ansible-playbook -i inventory/mycluster/hosts.yaml --become --become-user=root reset.yml
# Para fazer uma nova instalação do kubernetes, executar como root:
ansible-playbook -i inventory/mycluster/hosts.yaml --become --become-user=root cluster.yml

Mais detalhes são documentados no repositório oficial do Kubespray.

Documentação extendida

Para mais detalhes sobre conceitos do Kubernetes, vide a documentação oficial.

Os arquivos de manifesto YAML, que utilizaremos a seguir, são extensos e seus campos difíceis de se entender pelos seus nomes. Para fazer consultas rápidas e singelas sobre os campos dos manifestos, pode-se utilizar o seguinte comando em um nó master:

kubectl explain <COMPONENT>

Por exemplo:

kubectl explain deployment
kubectl explain pod
kubectl explain pod.spec
kubectl explain pod.spec.tolerations

Na medida do possível, quando parecer cabível, deixarei uma breve explicação da terminologia.

Instalação do Wordpress + MySQL

Terminologia:

Node
Máquinas físicas ou virtuais que executam Pods.
Pod
Um Pod é um grupo de um ou mais contêineres, com armazenamento e recursos de rede compartilhados, e uma especificação de como executar os contêineres.
Deployment
Componente que fornece atualizações declarativas para Pods e ReplicaSets. O propósito de um ReplicaSet é manter um conjunto estável de réplicas de Pods executando em um dado momento. O ReplicaSet cumpre o seu propósito criando e deletando Pods quando necessário para atingir o número desejado de Pods. O Deployment cria ReplicaSets que criam Pods replicados.
Service
É um método para expor uma aplicação de rede que está sendo executado como um ou mais Pods no cluster. É necessário porque apesar de um IP ser atribuído a um Pod pelos plugins de rede nativos do Kubernetes, Pods são componentes efêmeros, podendo ser destruídos e reconstruídos por Deployments, o que pode modificar seus IPs. Services servem para atrelar um IP fixo de acesso aos serviços nos Pods.
Toleration e Taint
“Tolerations” e “Taints” são termos relacionados ao conceito de afinidade de nó, que é uma propriedade de Pods que os “atrai” para um conjunto de nós, seja como preferência ou exclusividade. Taints são propriedades de Pods que os repelem de um conjunto de nós. Tolerations especificam condições de tolerância para a permanência de um Pod em um nó. Pode-se especificar condições de memória, processamento ou rede. Quando essas condições de tolerância são verificadas, o Pod possuindo a tolerância é reagendado para outro nó.

Os passos utilizados para instalação do Wordpress e MySQL consistem na aplicação de um deployment e de um service para cada componente. Cada deployment possuirá também uma configuração para utilizar um servidor NFS como armazenamento persistente, com o intuito de preservar a configuração das aplicações e dos dados do banco de dados entre possíveis deployments (ex.: quando seu nó é desligado ou cai). Também possuirá uma configuração que especifica uma toleration, nesse caso, um espaço de tempo que um container permanecerá atrelado a um nó enquanto uma taint for verificada, por exemplo, quando a taint not-ready estiver verificada quando o nó estiver fora do ar.

Para mais detalhes sobre o que esses termos significam, vide a documentação referenciada na seção anterior ou utilize os comando

kubectl explain <COMPONENT>
# Exemplo
kubectl explain pod.spec.tolerations

em um nó master para visualizar uma explicação sobre algum componente.

Instalação do servidor NFS

Nesse guia utilizaremos um servidor NFS exterior ao cluster Kubernetes. Dedique uma VM para hospedar esse servidor. Para levantar o serviço NFS no host onde o servidor NFS será hospedado, execute, como raiz:

# Como raiz.
dnf install nfs-utils -y
mkdir /var/nfs/general -p
touch /etc/exports

# Colocar IPs dos workers no vetor HOSTS.
# Exemplo: HOSTS=(10.20.1.113 10.20.1.118)
# Exportamos a variável para podermos utilizar essa variável em outros momentos, caso cabível.
export HOSTS=()

# O seguinte laço estabelece o ponto de montagem com permissões e configurações para o IP respectivo.
# rw: permissões de leitura e escrita
# no_subtree_check: desativa checagens que o servidor faz para ter certeza de que o cliente está acessando
#   um arquivo/diretório dentro do diretório exportado. Melhora performance.
# no_root_squash: permite que o cliente root leia e escreva arquivos como usuário root
for i in "${HOSTS[@]}"; do echo "/var/nfs/general $i(rw,no_subtree_check,no_root_squash)" >> /etc/exports;done

systemctl enable nfs-server
systemctl start nfs-server

# Esse comando deve ser executado toda vez que o arquivo /etc/exports
# for modificado.
exportfs -ra

# Os hosts clientes também precisam do pacote nfs-utils, caso não estejam instalados
# então instalamos ele:
for i in "${HOSTS[@]}"; do ssh $USER@$i "dnf install nfs-utils -y";done

Caso o servidor NFS já exista, deve-se executar apenas os seguintes comandos no servidor:

# Modificar manualemente o arquivo /etc/exports
# ou então executar o seguinte snippet.
HOSTS=()  # Colocar IPs dos workers no vetor HOSTS.
for i in "${HOSTS[@]}"; do echo "/var/nfs/general $i(rw,no_subtree_check,no_root_squash)" >> /etc/exports;done

exportfs -ra

Os comandos acima especificam o diretório a ser montado nos clientes, os IPS dos clientes e configurações por IP.

Deve-se também criar pastas específicas de cada aplicação no diretório var/nfs/general (ex.: /var/nfs/general/mysql-igor) e deixá-las com permissão 777 para evitar erros de permissão e também com usuário e grupo nobody. Os comandos são esses, por exemplo:

chmod -R 777 /var/nfs/general/mysql-igor
chown -R nobody:nobody /var/nfs/general/mysql-igor

Cópia dos arquivos de configuração para o cluster

Copie os arquivos de configuração mysql-dep.yml, mysql-serv.yml, wordpress-dep.yml e wordpress-serv.yml para um master do cluster utilizando o comando, na raíz do projeto:

scp wordpress/*.yml root@<HOST-IP>

Onde HOST-IP é o IP de um dos control_planes do cluster.

Troubleshooting

Para fazer troubleshooting, visualizar logs e informações sobre as ações do kubernetes pode-se utilizar esses comandos:

# Lista deployments
kubectl get deployments -o wide

# Lista pods
kubectl get pods -o wide

# Lista serviços
kubectl get svc -o wide

# Visualiza detalhes sobre um recurso ou grupo de recursos específico
kubectl describe deployments
kubectl describe deployment <DEPLOYMENT_NAME>

# Visualiza logs emitidos por um pod
kubectl logs --follow <POD_NAME>

# Para ver os detalhes de todos os comandos possívels
kubectl --help | less

Para mais detalhes sobre as possibilidades de comandos, vide o cheat sheet oficial.

Aplicação do Deployment do MySQL

Logado em um dos master nodes (control_planes) modificar o seguinte arquivo de configuração para servir suas necessidades, como o caminho para o diretório dos arquivos da aplicação no servidor NFS.

No seguinte arquivo de configuração instruímos o Deployment para gerar 1 réplica de Pod identificado pela Label ‘app=mysql’. O campo ‘spec’ mais aninhado especifica a imagem a ser utilizada pelo contêiner, as variáveis de ambiente para o contêiner, a porta do serviço do contêiner e os pontos de montagem de volume. O campo ‘volumes’ especifica o tipo de volume que utilizaremos, nesse caso, um servidor NFS. O campo ‘tolerations’ especifica condições para o Pod ser reagendado para outro nó. Nesse caso, quando o nó apresenta as condições ‘not-ready’ ou ‘unreachable’, o Pod deve ser reagendado, observando uma tolerância de 30 segundos para essas condições.

Para mais detalhes sobre o significado desses campos de manifesto, vide o comando

kubectl explain <COMPONENT>
# Exemplos
kubectl explain deployment
kubectl explain pod
kubectl explain pod.spec.tolerations
 # Arquivo: ./wordpress/mysql-dep.yml
 apiVersion: apps/v1
 kind: Deployment
 metadata:
	name: mysql-deployment
 spec:
	replicas: 1
	selector:
	  matchLabels:
		app: mysql
	template:
	  metadata:
		labels:
		  app: mysql
	  spec:
		containers:
		- name: mysql
		  image: mysql:latest
		  env:
		  - name: MYSQL_ROOT_PASSWORD
			value: password
		  ports:
		  - containerPort: 3306
		  volumeMounts:
		  - name: nfs-volume
			mountPath: /var/lib/mysql
		volumes:
		- name: nfs-volume
		  nfs:
			server: 10.20.1.111
			path: /var/nfs/general/mysql-igor
			readOnly: no
		tolerations:
		- effect: NoExecute
		  key: node.kubernetes.io/not-ready
		  operator: Exists
		  tolerationSeconds: 30
		- effect: NoExecute
		  key: node.kubernetes.io/unreachable
		  operator: Exists
		  tolerationSeconds: 30

Depois execute o seguinte comando para levantar o deployment do MySQL.

kubectl apply -f mysql-dep.yml

Aplicação do Service do MySQL

O seguinte arquivo configura o serviço para o MySQL. Caso queira, pode modificar a porta de acesso externo serviço do Pod modificando o campo “targetPort”.

A seguinte configuração especifica um Service para expor os recursos do servidor MySQL para outros Pods no cluster. A identificação do Pod é feito pelo campo ‘selector’, que aponta para o objeto com label ‘app=mysql’. O campo ‘ports’ especifica a porta de entrada para o serviço do Pod. O ‘port’ é a porta utilizada pelos clientes, como outros Pods no cluster, e ‘targetPort’ é a porta alvo, a porta onde o Pod exposto está de fato escutando.

# Arquivo: ./wordpress/mysql-serv.yml
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  selector:
    app: mysql
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306

Utilize o seguinte comando para aplicar a configuração do serviço MySQL.

kubectl apply -f mysql-serv.yml

Aplicação do Deployment do Wordpress

Novamente, revise o seguinte arquivo de configuração do Deployment para o Wordpress e modifique os campos que forem necessários, como o para os arquivos específicos do Wordpress no servidor NFS.

# Arquivo: ./wordpress/wordpress-dep.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      containers:
      - name: wordpress
        image: wordpress:latest
        env:
        - name: WORDPRESS_DB_HOST
          value: mysql-service
        - name: WORDPRESS_DB_USER
          value: root
        - name: WORDPRESS_DB_PASSWORD
          value: password
        - name: WORDPRESS_DB_NAME
          value: wordpress
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nfs-volume
          mountPath: /var/www/html
      volumes:
      - name: nfs-volume
        nfs:
          server: 10.20.1.111
          path: /var/nfs/general/wordpress-igor
          readOnly: no
      tolerations:
      - effect: NoExecute
        key: node.kubernetes.io/not-ready
        operator: Exists
        tolerationSeconds: 30
      - effect: NoExecute
        key: node.kubernetes.io/unreachable
        operator: Exists
        tolerationSeconds: 30

Utilize o seguinte comando para aplicar o deployment do Wordpress.

kubectl apply -f wordpress-dep.yml

Aplicação do Service do Wordpress

Revise o arquivo de configuração do serviço Wordpress e modifique os campos que achar necessário.

O campo ‘nodePort’ no campo ‘ports’ especifica a porta pela qual clientes fora do cluster podem acessar o serviço exposto pelo Pod do Wordpress.

# Arquivo: ./wordpress/wordpress-serv.yml
apiVersion: v1
kind: Service
metadata:
  name: wordpress-service
spec:
  selector:
    app: wordpress
  type: NodePort
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30036 

O seguinte comando aplica a configuração do serviço Wordpress.

kubectl apply -f wordpress-serv.yml

Criação do banco de dados MySQL no container

Para que o Wordpress funcione precisamos criar, manualmente, um banco de dados chamado ‘wordpress’. Para isso, logamos no container do MySQL e utilizamos o utilitário ‘mysql’ para emitir o comando de criação do banco de dados.

A partir de control_plane logar no container:

# Para resgatar o nome do Pod do MySQL
kubectl get pods
# Para logar no contêiner no Pod
kubectl exec -it <MYSQL_POD_NAME> -- bash
mysql -u root -p
# no prompt do shell do mysql:
create database wordpress;
exit
exit

Agora pode visitar qualquer endereço pertencente ao cluster Kubernetes utilizando a porta especificada no Deployment para o Wordpress para visualizar a tela principal da interface Web do Wordpress.

Instalação do Gitlab

Aplicação do Service para o Gitlab

Revise o arquivo de configuração para o serviço do Gitlab e edite o que achar necessário.

# Arquivo: ./gitlab/gitlab-serv
apiVersion: v1
kind: Service
metadata:
  name: gitlab-service
spec:
  selector:
    app: gitlab
  type: NodePort
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30036 

Execute o seguinte comando para aplicar a configuração:

kubectl apply -f gitlab-serv.yml

Aplicação do Deployment para o Gitlab

Revise o arquivo de configuração do deployment para o Gitlab e edite os campos necessários, como os caminhos nos volumes “gitlab-data”, “gitlab-logs” e “gitlab-config” para servir a sua configuração. Vale ressaltar que os caminhos para esses volumes devem ser diferentes. A variável de ambiente GITLAB_OMNIBUS_CONFIG deve ter como valor o IP no campo “cluster-ip” da saída do comando

kubectl get svc -o wide

para o serviço do Gitlab que foi aplicado na seção anterior. Esse endereço será utilizado pelo GitLab Runner para clonar seus repositórios durante uma pipeline CI/CD.

# Arquivo: ./gitlab/gitlab-dep.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gitlab-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gitlab
  template:
    metadata:
      labels:
        app: gitlab
    spec:
      containers:
      - name: gitlab
        image: gitlab/gitlab-ce:latest
        env:
        - name: GITLAB_OMNIBUS_CONFIG
          value: |
            external_url 'http://localhost'
# O endereco external_url deve ser o IP apontado pelo campo cluster-ip na saída do comando kubectl get svc -o wide
        ports:
        - containerPort: 80
        volumeMounts:
        - name: gitlab-data
          mountPath: /var/opt/gitlab
        - name: gitlab-logs
          mountPath: /var/log/gitlab
        - name: gitlab-config
          mountPath: /etc/gitlab
      volumes:
      - name: gitlab-data
        nfs:
          server: 10.20.9.111
          path: /var/nfs/general/gitlab-igor/data
          readOnly: no
      - name: gitlab-logs
        nfs:
          server: 10.20.9.111
          path: /var/nfs/general/gitlab-igor/logs
          readOnly: no
      - name: gitlab-config
        nfs:
          server: 10.20.9.111
          path: /var/nfs/general/gitlab-igor/config
          readOnly: no
      tolerations:
      - effect: NoExecute
        key: node.kubernetes.io/not-ready
        operator: Exists
        tolerationSeconds: 30
      - effect: NoExecute
        key: node.kubernetes.io/unreachable
        operator: Exists
        tolerationSeconds: 30

Execute o seguinte comando para aplicar a configuração do deployment:

kubectl apply -f gitlab-dep.yml

Para configurar uma senha para o usuário raíz:

kubectl exec -it <GITLAB_POD_NAME> -- /bin/bash -c "gitlab-rake 'gitlab:password:reset[root]'"
kubectl exec -it <GITLAB_POD_NAME> -- /bin/bash -c "gitlab-ctl reconfigure"

Instalação de um Runner no Gitlab

Antes de de fato instalarmos o Runner do Gitlab, precisamos registrá-lo no Gitlab. Para isso, instalamos o Runner num container Docker apenas para registrá-lo no Gitlab. Depois descartamos o container e instalamos outro Runner utilizando kubectl e um manifesto e utilizamos a configuração do outro Runner, modificada, para configurar o novo Runner.

Instalação do Docker

# ./install-docker.sh
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf upgrade --refresh -y
dnf install docker-ce docker-ce-cli containerd.io
systemctl start docker

Logar numa instância Docker do Gitlab Runner

docker run -it --entrypoint /bin/bash gitlab/gitlab-runner:latest

Registrar o Gitlab Runner

Gerar um token para registrar o Gitlab Runner

Crie um repositório teste na sua instância do Gitlab. Acesse o repositório teste e na tela do repositório vá em Settings -> CI/CD -> Runners e siga as instruções para registrar um novo runner. O runner no nosso caso deve utilizar a plataforma Linux e deve ser configurado para executar trabalhados sem tag acionando o checkbox “Run untagged jobs”.

Ao adicionar o Runner você pode encontrar um erro de conexão. Isso porque o Gitlab utiliza o URL armazenado na variável de ambiente GITLAB_OMNIBUS_CONFIG, que aponta para o IP fixo de cluster do Gitlab, que não é o IP que utilizamos para expor o serviço do Gitlab para fora do cluster, i.e., o IP de algum dos nós do cluster. Modificar o IP armazenado nessa variável de ambiente para apontar para algum nó do cluster resulta em erro ao tentar acessar a interface Web do Gitlab.

Como workaround temporário, você pode simplesmente colocar na URL da página de erro o IP e a porta adequados para acessar o Gitlab, preservando os outros elementos da URL. Depois disso, você será redirecionado para uma página contendo o comando que deve ser utilizado para registrar o Runner.

Registrar

Volte para o shell logado no container Docker e execute:

gitlab-runner register --url <CAMINHO_PARA_O_CLUSTER> --token <TOKEN_GERADO>

O CAMINHO_PARA_O_CLUSTER é o IP para qualquer nó do cluster (ex.: http://10.20.9.116:30036). Você receberá um prompt para entregar algumas informações. O nome do Runner fica a seu critério e o executor deve ser “kubernetes”. Você pode visualizar o arquivo de configuração, gerado automaticamente, do Runner com o comando:

more /etc/gitlab-runner/config.toml

Salve esse arquivo. Nós vamos utilizar esse arquivo para configurar o nosso container Kubernetes do Gitlab Runner. No meu caso o arquivo é estruturado assim:

concurrent = 1
check_interval = 0
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "runner"
  url = "http://10.20.9.116:30036"
  id = 1
  token = "glrt-qJDS_pTGimZC8YtaoBPw"
  token_obtained_at = 2023-05-31T16:40:36Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "docker"
  [runners.cache]
    MaxUploadedArchiveSize = 0
  [runners.docker]
    tls_verify = false
    image = "busybox:latest"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    shm_size =0 

Agora podemos deslogar do container Docker e derrubar o serviço Docker e proceder para os próximos passos. Podemos também parar o serviço Docker:

systemctl stop docker

Configurar o Gitlab Runner no Kubernetes

Para configurar o Gitlab Runner, precisamos adicionar um ServiceAccount, um Role e um RoleBinding respectivo ao Runner no cluster para gerenciar as permissões do Runner.

Novamente, para conseguir mais informações singelas sobre esses termos ou componentes execute o comando

kubectl explain <COMPONENT>
# Exemplos
kubectl explain serviceaccount
kubectl explain role
kubectl explain rolebinding
kubectl explain configmap

O seguinte arquivo provê essa configuração:

# Arquivo: ./gitlab/gitlab-runner-authentication.yml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: gitlab-admin
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: gitlab-admin
rules:
  - apiGroups: [""]
    resources: ["*"]
    verbs: ["*"]

---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: gitlab-admin
subjects:
  - kind: ServiceAccount
    name: gitlab-admin
roleRef:
  kind: Role
  name: gitlab-admin
  apiGroup: rbac.authorization.k8s.io

Aplique essa configuração com o comando:

kubectl apply -f gitlab-runner-authentication.yml

Depois de termos um ServiceAccount, Role e RoleBinding configurados precisamos de um ConfigMap para persistir a configuração do runner. O arquivo de configuração do ConfigMap deve especificar o arquivo de configuração do runner que roubamos do container Docker com algumas modificações para adaptá-lo ao ambiente Kubernetes. No meu caso, ficou assim:

# Arquivo: ./gitlab/gitlab-runner-config.yml
apiVersion: v1
kind: ConfigMap
metadata:
  name: gitlab-runner-config
data:
  config.toml: |-
     concurrent = 4
     [[runners]]
       name = "runner"
       url = "http://10.20.9.116:30036"
       id = 1
       token = "glrt-qJDS_pTGimZC8YtaoBPw"
       token_obtained_at = 2023-05-31T16:40:36Z
       token_expires_at = 0001-01-01T00:00:00Z
       executor = "kubernetes"
       [runners.kubernetes]
          poll_timeout = 600
          cpu_request = "1"
          service_cpu_request = "200m"

Após a aplicação dessa configuração, aplicamos a configuração do Deployment:

# Arquivo: ./gitlab/gitlab-runner-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gitlab-runner
spec:
  replicas: 1
  selector:
    matchLabels:
      name: gitlab-runner
  template:
    metadata:
      labels:
        name: gitlab-runner
    spec:
      serviceAccountName: gitlab-admin
      containers:
        - args:
          - run
          image: gitlab/gitlab-runner:latest
          imagePullPolicy: Always
          name: gitlab-runner
          resources:
            requests:
              cpu: "100m"
            limits:
              cpu: "100m"
          volumeMounts:
            - name: config
              mountPath: /etc/gitlab-runner/config.toml
              readOnly: true
              subPath: config.toml
      volumes:
        - name: config
          configMap:
            name: gitlab-runner-config
      restartPolicy: Always

Verificar a instalação do Runner

Você pode verificar se a instalação do Runner obteve sucesso indo para a tela Settings -> CI/CD -> Runners e checando se há um runner verde na seção “Assigned project runners”.

Referência

Vide referência.

Criação de pipeline de CI/CD no Gitlab

Pipelines de CI/CD (Continuous Integration / Continuous Delivery) consistem em uma série de etapas a serem realizadas para a disponibilização de uma nova versão de um software. Elas são uma prática que tem como objetivo acelerar a disponibilização de softwares, adotando a abordagem de DevOps ou de engenharia de confiabilidade de sites (SRE). O pipeline de CI/CD inclui o **monitoramento** e **automação** para melhorar o processo de desenvolvimento de aplicações principalmente nos estágios de integração e teste, mas também na entrega e na imnplantação.

Como solução de **monitoramente** utilizaremos o **Grafana**. Grafana é uma plataforma de fonte aberta interativa de visualização de dados, desenvolvieda pela Grafana Labs, que permite aos usuários ver dados por meio de tabelas e gráficos unificados em um painel ou vários, para facilitar a interpretação e a compreensão. Com o Grafana pode-se consultar e definir alertas sobre informações e métricas de qualquer lugar que os dados esteja, sejam ambientes tradicionais de servidor, clusters do Kubernetes, etc. Grafana foi construído com base nos princípios open source e na crença de que os dados devem ser acessíveis em toda a organização, não apenas para um pequeno grupo de pessoas. Isso promove uma cultura em que os dados podem ser **facilmente encontrados e usados** por qualquer pessoa que precise deles, capacitando as equipes a serem mais abertas, inovadoras e colaborativas.

**Prometheus** é um conjunto de ferramentas de fonte aberta para monitoramento de sistemas. Ele coleta e armazena suas métricas como dados de séries temporais, i.e., informações de métricas são aramazenados com o timestamp em que foi gravado.

Em nossa solução, utilizaremos o Prometheus para coletar as métricas do Gitlab e o Grafana para tramar gráficos para visualização.

Configuração do Gitlab

Para que o Prometheus possa rastrear as métricas do Gitlab precisamos primeiro expor os serviços exportadores de métricas no Gitlab. Para isso, editamos os arquivo ‘/etc/gitlab/gitlab.rb’ no contêiner do Gitlab. Para facilitar esse processo podemos ao invés disso editar o arquivo, no servidor NFS, ‘/var/nfs/general/gitlab/config/gitalb.rb’, que para você pode ser um caminho diferente a depender de onde você especificou o ponto de montagem no arquivo de Deployment do Gitlab.

Para configurar o Gitlab para expor esses serviços você pode copiar o arquivo “gitlab.rb” presente na raíz desse repositório para a pasta “config” que fica no seu diretório de configuração do Gitlab no seu servidor NFS. Por exemplo, /var/nfs/general/gitlab-igor/config.

Se quiser editar o arquivo manualmente, você deve abrir o arquivo /var/nfs/general/<SUA-PASTA-GITLAB>/config/gitlab.rb com um editor de texto, buscar as seguintes linhas, descomentar e editá-las para ficar assim:

gitlab_rails['monitoring_whitelist'] = ['127.0.0.0/8', '::1/128', '0.0.0.0/0']
registry['debug_addr'] = "0.0.0.0:5001"
gitlab_workhorse['prometheus_listen_addr'] = "0.0.0.0:9229"
sidekiq['listen_address'] = "0.0.0.0"
gitlab_rails['gitlab_kas_enabled'] = true
gitlab_rails['gitlab_kas_external_url'] = 'ws://gitlab.example.com/-/kubernetes-agent/'
gitlab_rails['gitlab_kas_internal_url'] = 'grpc://localhost:8153'
gitlab_rails['gitlab_kas_external_k8s_proxy_url'] = 'https://gitlab.example.com/-/kubernetes-agent/k8s-proxy/'
gitlab_kas_external_url "ws://gitlab.example.com/-/kubernetes-agent/"
gitlab_kas['enable'] = true
gitlab_kas['private_api_listen_address'] = 'localhost:8155'
gitlab_kas['env'] = {
  'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/",
  'OWN_PRIVATE_API_URL' => 'grpc://localhost:8155'
}
gitlab_rails['prometheus_address'] = '127.0.0.1:9090'
node_exporter['enable'] = true
node_exporter['listen_address'] = '0.0.0.0:9100'
redis_exporter['listen_address'] = '0.0.0.0:9121'
postgres_exporter['listen_address'] = '0.0.0.0:9187'
pgbouncer_exporter['listen_address'] = '0.0.0.0:9188'
gitlab_exporter['listen_address'] = '0.0.0.0'
gitlab_exporter['listen_port'] = '9168'
gitaly['configuration'] = {
  prometheus_listen_addr: '0.0.0.0:9236',
}

Depois disso você deve reconfigurar e reiniciar o contêiner do Gitlab. Para isso, num nó control-plane (master) execute:

# Para pegar pegar o nome do pod do Gitlab:
kubectl get pod
# Para reconfigurar e reiniciar:
kubectl exec -it <GITLAB_POD_NAME> -- /bin/bash -c 'gitlab-ctl reconfigure ; gitlab-ctl restart'

Agora você deve criar os serviços para expor esses endpoinst para o cluster Kubernetes.

Criação de services para expor endpoints dentro do container do Gitlab

As portas utilizadas para o campo “targetPort” ficam à sua discrição. Configuração para expor serviços internos do Gitlab para o cluster:

# Arquivo: ./gitlab/services-integration-prometheus/integration-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: integration-service
spec:
  selector:
    app: gitlab
  type: NodePort
  ports:
    - name: node-exporter-metrics
      protocol: TCP
      port: 9100
      targetPort: 9100
      nodePort: 30086
    - name: gitlab-workhorse-metrics
      protocol: TCP
      port: 9229
      targetPort: 9229
      nodePort: 30087
    - name: gitlab-exporter-metrics
      protocol: TCP
      port: 9168
      targetPort: 9168
      nodePort: 30088
    - name: registry-metrics
      protocol: TCP
      port: 5001
      targetPort: 5001
      nodePort: 30089
    - name: sidekiq-metrics
      protocol: TCP
      port: 8082
      targetPort: 8082
      nodePort: 30090
    - name: redis-exporter-metrics
      protocol: TCP
      port: 9121
      targetPort: 9121
      nodePort: 30091
    - name: postgres-metrics
      protocol: TCP
      port: 9187
      targetPort: 9187
      nodePort: 30092
    - name: gitaly-metrics
      protocol: TCP
      port: 9236
      targetPort: 9236
      nodePort: 30093
    - name: pgbouncer-metrics
      protocol: TCP
      port: 9188
      targetPort: 9188
      nodePort: 30094

Aplicação da configuração:

kubectl apply -f integration-service.yaml

Instalação de Prometheus

Deploy

O seguinte arquivo cria o ClusterRole e ClusterRoleBinding para configurar o mecanismo de autorização para o Prometheus acessar recursos protegidos do Kubernetes.

Novamente, para informações singelas sobre os termos utilizados, execute o comando

kubectl explain <COMPONENT>
# Exemplo
kubectl explain clusterrole
kubectl explain clusterrolebinding

Essa configuração dá para o Prometheus permissões para acessar recursos da API do Kubernetes.

# Arquivo: ./prometheus/alternative/kubernetes-prometheus/clusterRole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole # contem regras que representam um conjunto de permissoes
metadata:
  name: prometheus
rules:
- apiGroups: [""] # "" indica o grupo de API base
  resources:      # especifica os recursos suplicados
  - nodes
  - nodes/proxy
  - services
  - endpoints
  - pods
  verbs: ["get", "list", "watch"]
- apiGroups:
  - extensions
  resources:
  - ingresses
  verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
  verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding # concede as permissoes definidas em um papel para um usuario ou conjunto de usuarios
metadata:
  name: prometheus
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus
subjects:
- kind: ServiceAccount
  name: default
  namespace: monitoring

Aplicação da configuração:

kubectl apply -f clusterRole.yaml

Crie o namespace ‘monitoring’:

kubectl create namespace monitoring

O seguinte arquivo especifica a configuração base do Prometheus e os ‘targets’, isto é, as endpoints aonde o Prometheus buscará as métricas. Atenção: você deve modificar o IP alvo para cada “job_name” que rastreia os serviços de exposição de métricas do Gitlab para apontar para um nó do cluster Kubernetes e deve modificar a porta a ser acessada para ser a porta especificada no arquivo de configuração ./gitlab/services-integration-prometheus/integration-service.yaml que foi utilizado para expor os serviços de exposição de métricas do Gitlab.

# Arquivo: ./prometheus/alternative/kubernetes-prometheus/config-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-server-conf
  labels:
    name: prometheus-server-conf
  namespace: monitoring
data:
  prometheus.rules: |-
    groups:
    - name: devopscube demo alert
      rules:
      - alert: High Pod Memory
        expr: sum(container_memory_usage_bytes) > 1
        for: 1m
        labels:
          severity: slack
        annotations:
          summary: High Memory Usage
  prometheus.yml: |-
    global:
      scrape_interval: 5s
      evaluation_interval: 5s
    rule_files:
      - /etc/prometheus/prometheus.rules
    alerting:
      alertmanagers:
      - scheme: http
        static_configs:
        - targets:
          - "alertmanager.monitoring.svc:9093"
    scrape_configs:
      - job_name: 'node-exporter'
        kubernetes_sd_configs:
          - role: endpoints
        relabel_configs:
        - source_labels: [__meta_kubernetes_endpoints_name]
          regex: 'node-exporter'
          action: keep
      - job_name: 'kubernetes-apiservers'
        kubernetes_sd_configs:
        - role: endpoints
        scheme: https
        tls_config:
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
        relabel_configs:
        - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
          action: keep
          regex: default;kubernetes;https
      - job_name: 'kubernetes-nodes'
        scheme: https
        tls_config:
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
        kubernetes_sd_configs:
        - role: node
        relabel_configs:
        - action: labelmap
          regex: __meta_kubernetes_node_label_(.+)
        - target_label: __address__
          replacement: kubernetes.default.svc:443
        - source_labels: [__meta_kubernetes_node_name]
          regex: (.+)
          target_label: __metrics_path__
          replacement: /api/v1/nodes/${1}/proxy/metrics
      - job_name: 'kubernetes-pods'
        kubernetes_sd_configs:
        - role: pod
        relabel_configs:
        - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
          action: keep
          regex: true
        - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
          action: replace
          target_label: __metrics_path__
          regex: (.+)
        - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
          action: replace
          regex: ([^:]+)(?::\d+)?;(\d+)
          replacement: $1:$2
          target_label: __address__
        - action: labelmap
          regex: __meta_kubernetes_pod_label_(.+)
        - source_labels: [__meta_kubernetes_namespace]
          action: replace
          target_label: kubernetes_namespace
        - source_labels: [__meta_kubernetes_pod_name]
          action: replace
          target_label: kubernetes_pod_name
      - job_name: 'kubernetes-cadvisor'
        scheme: https
        tls_config:
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
        kubernetes_sd_configs:
        - role: node
        relabel_configs:
        - action: labelmap
          regex: __meta_kubernetes_node_label_(.+)
        - target_label: __address__
          replacement: kubernetes.default.svc:443
        - source_labels: [__meta_kubernetes_node_name]
          regex: (.+)
          target_label: __metrics_path__
          replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
      - job_name: 'kubernetes-service-endpoints'
        kubernetes_sd_configs:
        - role: endpoints
        relabel_configs:
        - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
          action: keep
          regex: true
        - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
          action: replace
          target_label: __scheme__
          regex: (https?)
        - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
          action: replace
          target_label: __metrics_path__
          regex: (.+)
        - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
          action: replace
          target_label: __address__
          regex: ([^:]+)(?::\d+)?;(\d+)
          replacement: $1:$2
        - action: labelmap
          regex: __meta_kubernetes_service_label_(.+)
        - source_labels: [__meta_kubernetes_namespace]
          action: replace
          target_label: kubernetes_namespace
        - source_labels: [__meta_kubernetes_service_name]
          action: replace
          target_label: kubernetes_name
      - job_name: redis
        static_configs:
          - targets:
            - 10.20.9.116:30091
      - job_name: postgres
        static_configs:
          - targets:
            - 10.20.9.116:30092
      - job_name: node
        static_configs:
          - targets:
            - 10.20.9.116:30086
      - job_name: gitlab-workhorse
        static_configs:
          - targets:
            - 10.20.9.116:30087
      - job_name: gitlab-rails
        metrics_path: "/-/metrics"
        scheme: http
        static_configs:
          - targets:
            - 10.20.9.116:30036
      - job_name: gitlab-sidekiq
        static_configs:
          - targets:
            - 10.20.9.116:30090
      - job_name: gitlab_exporter_database
        metrics_path: "/database"
        static_configs:
          - targets:
            - 10.20.9.116:30088
      - job_name: gitaly
        static_configs:
          - targets:
            - 10.20.9.116:30093

Aplicação da configuração:

kubectl apply -f config-map.yaml

O seguinte arquivo especifica o Deployment do Prometheus.

# Arquivo: ./prometheus/alternative/kubernetes-prometheus/prometheus-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus-deployment
  namespace: monitoring
  labels:
    app: prometheus-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus-server
  template:
    metadata:
      labels:
        app: prometheus-server
    spec:
      containers:
        - name: prometheus
          image: prom/prometheus
          args:
            - "--config.file=/etc/prometheus/prometheus.yml"
            - "--storage.tsdb.path=/prometheus/"
          ports:
            - containerPort: 9090
          volumeMounts:
            - name: prometheus-config-volume
              mountPath: /etc/prometheus/
            - name: prometheus-storage-volume
              mountPath: /prometheus/
      volumes:
        - name: prometheus-config-volume
          configMap:
            defaultMode: 420
            name: prometheus-server-conf

        - name: prometheus-storage-volume
          emptyDir: {}

Aplicação da configuração:

kubectl apply -f prometheus-deployment.yaml

O seguinte arquivo especifica o Service para acesso aos recursos do Prometheus.

# Arquivo: ./prometheus/alternative/kubernetes-prometheus/prometheus-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: prometheus-service
  namespace: monitoring
  annotations:
      prometheus.io/scrape: 'true'
      prometheus.io/port:   '9090'

spec:
  selector: 
    app: prometheus-server
  type: NodePort  
  ports:
    - port: 8080
      targetPort: 9090 
      nodePort: 30000

Aplicação da configuração:

kubectl apply -f prometheus-service.yaml

Instalação de Grafana

Deployment

Configuração do Deployment e do Service do Grafana:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: grafana
  name: grafana
spec:
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      securityContext:
        fsGroup: 472
        supplementalGroups:
          - 0
      containers:
        - name: grafana
          image: grafana/grafana:9.1.0
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 3000
              name: http-grafana
              protocol: TCP
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /robots.txt
              port: 3000
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 30
            successThreshold: 1
            timeoutSeconds: 2
          livenessProbe:
            failureThreshold: 3
            initialDelaySeconds: 30
            periodSeconds: 10
            successThreshold: 1
            tcpSocket:
              port: 3000
            timeoutSeconds: 1
          resources:
            requests:
              cpu: 250m
              memory: 750Mi
          volumeMounts:
            - mountPath: /var/lib/grafana
              name: grafana-data
      volumes:
        - name: grafana-data
          nfs:
            server: 10.20.9.111
            path: /var/nfs/general/grafana-igor
            readOnly: no
---
apiVersion: v1
kind: Service
metadata:
  name: grafana
spec:
  ports:
    - port: 3000
      protocol: TCP
      targetPort: http-grafana
      nodePort: 30001
  selector:
    app: grafana
  sessionAffinity: None
  type: NodePort

Utilize o seguinte comando para aplicar a configuração.

kubectl apply -f grafana.yaml

Para fazer login na sua instância do Grafana, utilize como credênciais ‘admin’ para usuário e ‘admin’ para senha.

Visualização de dashboards no Grafana

Criação de um Data Source

  1. Acesse a interface Web da sua instância do grafana utilizando um

navegador de Internet.

  1. Procure pelo símbolo de configuração e clique em ‘Data sources’.
  2. Clique em ‘Add data source’.
  3. Escolha o banco de dados Prometheus.
  4. Preencha como nome do Data Source ‘GitLab Omnibus’.
  5. Forneça a URL para a instância do Prometheus (Como utilizamos exposição via nodePort o host pode ser qualquer host do cluster).
  6. Clique ‘Save & test’.

Importação de Dashboards do Gitlab

Na tela principal do Grafana, vá para a página de gerenciamento de Dashboards.

  1. Clique em ‘New’.
  2. Clique me ‘Import’.
  3. Clique em ‘Upload JSON file’.
  4. Navegue até o diretório lab-proxmox/gitlab/dashboards/grafana-dashboards-master/omnibus/
  5. Escolha o Dashboard que você deseja visualizar. Por exemplo, gitaly.json.

O dashboard mais útil para propósitos de experimentos com o cluster Kubernetes é o localizado em lab-proxmox-doc/dashboards/kubernetes-cluster-monitoring-via-prometheus_rev3.json. Para visualizar esse dashboard você precisa criar uma nova Data Source Prometheus chamada DS_PROMETHEUS e associar ao dashboard.

Testando uma pipeline CI/CD

Para testar uma pipeline CI/CD você pode clonar esse repositório e subí-lo para sua instância, por exemplo, colocá-lo no repositório utilizado para associar um Runner em uma das seções anteriores.

Ao fazer o primeiro push, a pipeline CI/CD iniciará automaticamente. O log da pipeline pode ser visualizada pelo caminho CI/CD -> Pipelines. No campo “Stages” você verá as Jobs. Clique no Job cujo log você quer visualizar.

No dashboard monitor do cluster Kubernetes você pode visualizar informações como o uso de CPU por nó, por contêiner, por processo, etc. O mesmo a respeito de uso de memória e de rede.

Configurações alternativas

Deploy do Prometheus

Para deploy do Prometheus pode-se utilizar a seguinte configuração. Entretanto, ela é complexa e difícil de configurar.

Deploy via Helm Charts

kubectl create namespace darwin
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/kube-prometheus-stack --namespace darwin --version 46.8.0
# Arquivo: ./prometheus/prometheus-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: darwin
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      scrape_timeout: 10s
      evaluation_interval: 15s
    scrape_configs:
      - job_name: 'darwin-service'
        scrape_interval: 5s
        static_configs:
          - targets: ['darwin-service:8080']
      - job_name: nginx
        static_configs:
          - targets:
            - 1.1.1.1:8060
      - job_name: redis
        static_configs:
          - targets:
            - 1.1.1.1:9121
      - job_name: postgres
        static_configs:
          - targets:
            - 1.1.1.1:9187
      - job_name: node
        static_configs:
          - targets:
            - 1.1.1.1:9100
      - job_name: gitlab-workhorse
        static_configs:
          - targets:
            - 1.1.1.1:9229
      - job_name: gitlab-rails
        metrics_path: "/-/metrics"
        scheme: https
        static_configs:
          - targets:
            - 1.1.1.1
      - job_name: gitlab-sidekiq
        static_configs:
          - targets:
            - 1.1.1.1:8082
      - job_name: gitlab_exporter_database
        metrics_path: "/database"
        static_configs:
          - targets:
            - 1.1.1.1:9168
      - job_name: gitlab_exporter_sidekiq
        metrics_path: "/sidekiq"
        static_configs:
          - targets:
            - 1.1.1.1:9168
      - job_name: gitaly
        static_configs:
          - targets:
            - 1.1.1.1:9236
# Arquivo: ./prometheus/darwin-prometheus-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: darwin-prometheus-service
  namespace: darwin
spec:
  type: NodePort
  selector:
    app.kubernetes.io/name: prometheus
  ports:
    - name: web
      port: 9090
      targetPort: 9090
      nodePort: 30000

About

Documentação de um laboratório Kubernetes

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published