Atividade 04 - Recursos Básicos do Kubernetes
Namespaces
Criar um Namespace no Kubernetes utilizando dois métodos: imperativo (linha de comando) e declarativo (arquivo YAML).
Parte 1: Criando um Namespace de forma Imperativa
Utilize o comando abaixo para criar um Namespace chamado meu-namespace:
kubectl create namespace meu-namespace
Verifique se o Namespace foi criado:
kubectl get namespaces
Delete o Namespace criado:
kubectl delete namespace meu-namespace
Parte 2: Criando um Namespace de forma Declarativa
Crie um arquivo chamado namespace.yaml com o seguinte conteúdo:
apiVersion: v1
kind: Namespace
metadata:
name: meu-namespace
Aplique o arquivo para criar o Namespace:
kubectl apply -f namespace.yaml
Confirme a criação do Namespace:
kubectl get namespaces
Para remover o Namespace, use:
kubectl delete -f namespace.yaml
Comandos úteis
Para listar recursos de um Namespace:
kubectl --namespace meu-namespace get pods
# pode ser abreviado para "-n meu-namespace"
Definir um Namespace padrão para comandos do kubectl
kubectl config set-context --current --namespace meu-namespace
ConfigMaps
ConfigMap com variáveis de ambiente
Crie um arquivo chamado app-configmap.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_MODE: "production"
APP_DEBUG: "false"
Aplique:
kubectl apply -f app-configmap.yaml
Crie um arquivo chamado app-deploy-env.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: configmap-env-demo
spec:
replicas: 1
selector:
matchLabels:
app: configmap-env
template:
metadata:
labels:
app: configmap-env
spec:
containers:
- name: alpine
image: alpine
command: ["sh", "-c", "env && sleep 3600"]
envFrom:
- configMapRef:
name: app-config
Aplique:
kubectl apply -f app-deploy-env.yaml
Verificar variáveis no container
Liste os Pods:
kubectl get pods
Entre no container:
kubectl exec -it <nome-do-pod> -- sh
Veja as variáveis de ambiente:
echo $APP_MODE
echo $APP_DEBUG
ConfigMap como arquivos
Crie um arquivo chamado configmap-arquivos.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-files
data:
app.conf: |
APP_NAME=MinhaApp
APP_VERSION=1.0
log.properties: |
level=debug
output=stdout
Aplique o ConfigMap:
kubectl apply -f configmap-arquivos.yaml
Crie um arquivo chamado deployment-arquivos.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-com-configmap-arquivo
spec:
replicas: 1
selector:
matchLabels:
app: configmap-arquivo
template:
metadata:
labels:
app: configmap-arquivo
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "cat /config/app.conf && cat /config/log.properties && echo && sleep 3600"]
volumeMounts:
- name: config-volume
mountPath: /config
volumes:
- name: config-volume
configMap:
name: app-config-files
Aplique:
kubectl apply -f deployment-arquivos.yaml
Verificar o conteúdo dos arquivos montados
Veja os logs do Pod:
kubectl logs -l app=configmap-arquivo
Você deve ver:
APP_NAME=MinhaApp
APP_VERSION=1.0
level=debug
output=stdout
Secrets
Usando Secrets como Variáveis de Ambiente
Criar o Secret
kubectl create secret generic meu-secret \
--from-literal=DB_USER=admin \
--from-literal=DB_PASS=supersecreta
Verifique:
kubectl describe secret meu-secret
Criar o Deployment que injeta o Secret como env
Crie um arquivo deployment-secret-env.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-com-secret-env
spec:
replicas: 1
selector:
matchLabels:
app: secret-env
template:
metadata:
labels:
app: secret-env
spec:
containers:
- name: busybox
image: busybox
command: ["sh", "-c", "echo DB_USER=$DB_USER && echo DB_PASS=$DB_PASS && sleep 3600"]
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: meu-secret
key: DB_USER
- name: DB_PASS
valueFrom:
secretKeyRef:
name: meu-secret
key: DB_PASS
Aplique:
kubectl apply -f deployment-secret-env.yaml
Verifique:
kubectl logs -l app=secret-env
Você verá:
DB_USER=admin
DB_PASS=supersecreta
Montar Secrets como Arquivos
Criar novo Deployment montando o Secret Crie um arquivo deployment-secret-volume.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-com-secret-volume
spec:
replicas: 1
selector:
matchLabels:
app: secret-volume
template:
metadata:
labels:
app: secret-volume
spec:
containers:
- name: busybox
image: busybox
command: ["sh", "-c", "cat /secrets/DB_USER && echo && cat /secrets/DB_PASS && echo && sleep 3600"]
volumeMounts:
- name: secret-volume
mountPath: /secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: meu-secret
Aplique:
kubectl apply -f deployment-secret-volume.yaml
Verifique os logs:
kubectl logs -l app=secret-volume
SideCar
Criar um Deployment com um container nginx e um sidecar php-fpm
Arquivo nginx-php-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-php-deploy
spec:
replicas: 1
selector:
matchLabels:
app: nginx-php
template:
metadata:
labels:
app: nginx-php
spec:
volumes:
- name: app-volume
emptyDir: {}
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: app-volume
mountPath: /usr/share/nginx/html
# Custom NGINX config to use PHP-FPM (opcional: pode montar um config aqui se quiser)
- name: php
image: php:8.1-fpm-alpine
volumeMounts:
- name: app-volume
mountPath: /usr/share/nginx/html
Aplique o Deployment:
kubectl apply -f nginx-php-deployment.yaml
Após o Deployment estar no ar:
kubectl get pods -l app=nginx-php
# copie o nome do pod e rode:
kubectl exec -it <nome-do-pod> -c php -- sh -c 'echo "<?php phpinfo(); ?>" > /usr/share/nginx/html/index.php'
Expor via port-forward
kubectl port-forward deployment/nginx-php-deploy 8080:80
Acesse via navegador http://localhost:8080/index.php
Projeto
Crie um ConfigMap para manter as informações não sensíveis de banco de dados (usuário e banco). Configure o Deployment da aplicação e o StatefulSet do banco de dados para utilizar essas informações.
Crie um Secret para manter as senhas do banco de dados (senha de usuário e senha de root), e configure o Deployment da aplicação e o StatefulSet do banco de dados para utilizar essas senhas.
Crie um ConfigMap para manter o init_db.sql, e configure o StatefulSet do banco de dados para montar esse script na pasta /docker-entrypoint-initdb.d/.
Desafio
O que aconteceu?
Como configurar o nginx para enviar as requisições de páginas php para o PHP-FPM?
Dica: Configuração básica do nginx para prover php:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass <SERVIDOR>:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
}