Tutorial

Como implantar um aplicativo Django escalável e seguro com o Kubernetes

Published on February 19, 2021
Português
Como implantar um aplicativo Django escalável e seguro com o Kubernetes

Introdução

Neste tutorial, você irá implantar um aplicativo de pesquisa do Django em contêiner em um cluster do Kubernetes.

O Django é um framework Web poderoso, que pode ajudar a acelerar a implantação do seu aplicativo Python. Ele inclui diversas funcionalidades convenientes, como um mapeador relacional do objeto, autenticação de usuário e uma interface administrativa personalizável para seu aplicativo. Ele também inclui um framework de cache e encoraja o design de aplicativos organizados através do seu URL Dispatcher e Sistema de modelos.

Em Como construir um aplicativo Django e Gunicorn com o Docker, o aplicativo Polls de tutorial do Django foi modificado de acordo com a metodologia do Twelve-Factor para a construção de aplicativos Web escaláveis e nativos na nuvem. Essa configuração em contêiner foi dimensionada e protegida com um proxy reverso do Nginx e autenticada pelo Let’s Encrypt com certificados TLS seguindo Como dimensionar e proteger um aplicativo Django com o Docker, Nginx e Let’s Encrypt. Neste tutorial final da série De contêineres ao Kubernetes com o Django, o aplicativo modernizado de pesquisa do Django será implantado em um cluster do Kubernetes.

O Kubernetes é um orquestrador de contêineres de código aberto poderoso, que automatiza a implantação, dimensionamento e gerenciamento de aplicativos em contêiner. Os objetos do Kubernetes como os ConfigMaps e Segredos permitem centralizar e desacoplar a configuração dos seus contêineres, enquanto os controladores como Deployments reiniciam automaticamente contêineres que falharam e habilitam o dimensionamento rápido de réplicas de contêineres. A criptografia TLS é habilitada com um objeto Ingress e o Controlador Ingress de código aberto ingress-nginx. O add-on cert-manager do Kubernetes renova e emite certificados usando a autoridade de certificação gratuita Let’s Encrypt.

Pré-requisitos

Para seguir este tutorial, será necessário:

Assim que tiver esses componentes configurados, tudo estará pronto para seguir o guia.

Passo 1 — Clonando e configurando o aplicativo

Neste passo, vamos clonar o código do aplicativo do GitHub e definir algumas configurações como as credenciais de banco de dados e chaves de armazenamento de objetos.

O código do aplicativo e o Dockerfile podem ser encontrados na ramificação polls-docker do repositório GitHub do aplicativo Polls de tutorial do Django. Esse repositório contém códigos para o aplicativo de amostra Polls da documentação do Django, que ensina como construir um aplicativo de pesquisa a partir do zero.

A ramificação polls-docker contém uma versão em Docker do aplicativo Polls. Para aprender como o aplicativo Polls foi modificado para funcionar efetivamente em um ambiente em contêiner, consulte Como construir um aplicativo Django e Gunicorn com o Docker.

Comece usando o git para clonar o branch polls-docker do repositório GitHub do aplicativo Polls do tutorial do Django em sua máquina local:

  1. git clone --single-branch --branch polls-docker https://github.com/do-community/django-polls.git

Navegue até o diretório django-polls:

  1. cd django-polls

Esse diretório contém o código Python do aplicativo Django, um Dockerfile que o Docker usará para compilar a imagem do contêiner, bem como um arquivo env que contém uma lista de variáveis de ambiente a serem passadas para o ambiente de execução do contêiner. Verifique o Dockerfile:

  1. cat Dockerfile
Output
FROM python:3.7.4-alpine3.10 ADD django-polls/requirements.txt /app/requirements.txt RUN set -ex \ && apk add --no-cache --virtual .build-deps postgresql-dev build-base \ && python -m venv /env \ && /env/bin/pip install --upgrade pip \ && /env/bin/pip install --no-cache-dir -r /app/requirements.txt \ && runDeps="$(scanelf --needed --nobanner --recursive /env \ | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ | sort -u \ | xargs -r apk info --installed \ | sort -u)" \ && apk add --virtual rundeps $runDeps \ && apk del .build-deps ADD django-polls /app WORKDIR /app ENV VIRTUAL_ENV /env ENV PATH /env/bin:$PATH EXPOSE 8000 CMD ["gunicorn", "--bind", ":8000", "--workers", "3", "mysite.wsgi"]

Esse Dockerfile usa a imagem Docker oficial do Python 3.7.4 como base e instala os requisitos de pacote Python do Django e do Gunicorn, conforme definido no arquivo django-polls/requirements.txt. Em seguida, ele remove alguns arquivos de compilação desnecessários, copia o código do aplicativo na imagem e define o PATH de execução. Por fim, ele declara que a porta 8000 será usada para aceitar conexões de contêiner recebidas e executa gunicorn com 3 trabalhadores, escutando na porta 8000.

Para aprender mais sobre cada um dos passos nesse Dockerfile, confira o Passo 6 de Como construir um aplicativo Django e Gunicorn com o Docker.

Agora, crie a imagem usando o docker build:

  1. docker build -t polls .

Nós demos o nome de polls para a imagem usando o sinalizador -t e passamos o diretório atual como um contexto de compilação, que é o conjunto de arquivos de referência ao compilar a imagem.

Depois que o Docker compilar e marcar a imagem, liste as imagens disponíveis usando docker images:

  1. docker images

Você deve ver a imagem polls listada:

OutputREPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
polls               latest              80ec4f33aae1        2 weeks ago         197MB
python              3.7.4-alpine3.10    f309434dea3a        8 months ago        98.7MB

Antes de executarmos o contêiner Django, precisamos configurar seu ambiente de execução usando o arquivo env presente no diretório atual. Esse arquivo será passado para o comando docker run usado para executar o contêiner, e o Docker irá injetar as variáveis de ambiente configuradas no ambiente de execução do contêiner.

Abra o arquivo env com o nano ou com o seu editor favorito:

  1. nano env
django-polls/env
DJANGO_SECRET_KEY=
DEBUG=True
DJANGO_ALLOWED_HOSTS=
DATABASE_ENGINE=postgresql_psycopg2
DATABASE_NAME=polls
DATABASE_USERNAME=
DATABASE_PASSWORD=
DATABASE_HOST=
DATABASE_PORT=
STATIC_ACCESS_KEY_ID=
STATIC_SECRET_KEY=
STATIC_BUCKET_NAME=
STATIC_ENDPOINT_URL=
DJANGO_LOGLEVEL=info

Preencha os valores que estão faltando para as seguintes chaves:

  • DJANGO_SECRET_KEY: defina isso como um valor único e imprevisível, conforme detalhado na documentação do Django. Um método para gerar essa chave é fornecido em Ajustando as configurações do aplicativo do tutorial sobre o Aplicativo Django escalável.
  • DJANGO_ALLOWED_HOSTS: essa variável protege o aplicativo e impede ataques de cabeçalho de host HTTP. Para fins de teste, defina isso como *, um coringa que irá corresponder a todos os hosts. Na produção, isso deve ser definido como your_domain.com. Para aprender mais sobre esse ajuste do Django, consulte as Core Settings da documentação do Django.
  • DATABASE_USERNAME: defina isso como o usuário do banco de dados PostgreSQL criado nos passos pré-requisitos.
  • DATABASE_NAME: defina isso como polls ou o nome do banco de dados PostgreSQL criado nos passos pré-requisitos.
  • DATABASE_PASSWORD: defina isso como a senha do usuário do banco de dados PostgreSQL criada nos passos pré-requisitos.
  • DATABASE_HOST: defina isso como o nome do host do seu banco de dados.
  • DATABASE_PORT: defina isso como a porta do seu banco de dados.
  • STATIC_ACCESS_KEY_ID: defina isso como a chave de acesso do seu espaço ou armazenamento de objetos.
  • STATIC_SECRET_KEY: defina isso como o segredo da chave de acesso do seu espaço ou armazenamento de objetos.
  • STATIC_BUCKET_NAME: defina isso como seu nome de espaço ou bucket de armazenamento de objetos.
  • STATIC_ENDPOINT_URL: defina isso como o URL do ponto de extremidade do espaço apropriado ou armazenamento de objetos, como https://your_space_name.nyc3.digitaloceanspaces.com se o espaço estiver localizado na região nyc3.

Assim que terminar a edição, salve e feche o arquivo.

No próximo passo, vamos executar o contêiner configurado localmente e criar o esquema de banco de dados. Além disso, vamos carregar ativos estáticos como folhas de estilos e imagens para o armazenamento de objetos.

Passo 2 — Criando o esquema de banco de dados e carregando ativos para o armazenamento de objetos

Com o contêiner construído e configurado, use o docker run para substituir o conjunto CMD no Dockerfile e criar o esquema de banco de dados usando os comandos manage.py makemigrations e manage.py migrate:

  1. docker run --env-file env polls sh -c "python manage.py makemigrations && python manage.py migrate"

Executamos a imagem de contêiner polls:latest, passamos o arquivo de variável de ambiente que acabamos de modificar e substituímos o comando do Dockerfile com sh -c "python manage.py makemigrations && python manage.py migrate", o que irá criar o esquema de banco de dados definido pelo código do aplicativo.

Se estiver executando isso pela primeira vez, você deve ver:

Output
No changes detected Operations to perform: Apply all migrations: admin, auth, contenttypes, polls, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying polls.0001_initial... OK Applying sessions.0001_initial... OK

Isso indica que o esquema de banco de dados foi criado com sucesso.

Se estiver executando migrate uma outra vez, o Django irá cancelar a operação a menos que o esquema de banco de dados tenha sido alterado.

Em seguida, vamos executar outra instância do contêiner de aplicativo e usar um shell interativo dentro dela para criar um usuário administrativo para o projeto Django.

  1. docker run -i -t --env-file env polls sh

Isso lhe fornecerá um prompt do shell dentro do contêiner em execução que você pode usar para criar o usuário do Django:

  1. python manage.py createsuperuser

Digite um nome de usuário, endereço de e-mail e senha para o seu usuário e, depois de criá-lo, pressione CTRL+D para sair do contêiner e encerrá-lo.

Por fim, vamos gerar os arquivos estáticos para o aplicativo e fazer o upload deles para o espaço da DigitalOcean usando o collectstatic. Observe que esse processo pode demorar um pouco de tempo para ser concluído.

  1. docker run --env-file env polls sh -c "python manage.py collectstatic --noinput"

Depois que esses arquivos forem gerados e enviados, você receberá a seguinte saída.

Output
121 static files copied.

Agora, podemos executar o aplicativo:

  1. docker run --env-file env -p 80:8000 polls
Output
[2019-10-17 21:23:36 +0000] [1] [INFO] Starting gunicorn 19.9.0 [2019-10-17 21:23:36 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1) [2019-10-17 21:23:36 +0000] [1] [INFO] Using worker: sync [2019-10-17 21:23:36 +0000] [7] [INFO] Booting worker with pid: 7 [2019-10-17 21:23:36 +0000] [8] [INFO] Booting worker with pid: 8 [2019-10-17 21:23:36 +0000] [9] [INFO] Booting worker with pid: 9

Aqui, executamos o comando padrão definido no Dockerfile, gunicorn --bind :8000 --workers 3 mysite.wsgi:application e expomos a porta do contêiner 8000 para que a porta 80 na sua máquina local seja mapeada para a porta 8000 do contêiner polls.

Agora, você deve ser capaz de navegar até o aplicativo polls usando seu navegador Web digitando http://localhost na barra de URL. Como não há nenhuma rota definida para o caminho /, você provavelmente receberá um erro 404 Page Not Found, o que é esperado.

Navegue até http://localhost/polls para ver a interface do aplicativo Polls:

Interface do aplicativo Polls

Para visualizar a interface administrativa, visite http://localhost/admin. Você deve ver a janela de autenticação do administrador do aplicativo Polls:

Página de autenticação de administrador do Polls

Digite o nome e a senha do usuário administrativo que você criou com o comando createsuperuser.

Depois de autenticar-se, você pode acessar a interface administrativa do aplicativo Polls:

Interface administrativa principal do Polls

Observe que os ativos estáticos para os aplicativos admin e polls estão sendo entregues diretamente do armazenamento de objetos. Para confirmar isso, consulte Testando a entrega de arquivos estáticos de espaços.

Quando terminar de explorar, aperte CTRL+C na janela do terminal executando o contêiner Docker para encerrar o contêiner.

Com a imagem Docker do aplicativo Django testada, ativos estáticos carregados no armazenamento de objetos e o esquema de banco de dados configurado e pronto para ser usado com seu aplicativo, tudo está pronto para carregar sua imagem do aplicativo Django em um registro de imagem como o Docker Hub.

Passo 3 — Enviando a imagem do aplicativo Django para o Docker Hub

Para implementar seu aplicativo no Kubernetes, sua imagem de aplicativo deve ser carregada em um registro como o Docker Hub. O Kubernetes irá puxar a imagem do aplicativo do seu repositório e implantá-la em seu cluster.

É possível usar um registro privado do Docker, como o registro do contêiner da DigitalOcean, atualmente gratuito em acesso antecipado, ou um registro público do Docker como o Docker Hub. O Docker Hub também permite criar repositórios privados do Docker. Um repositório público permite que qualquer pessoa veja e puxe as imagens do contêiner, enquanto um repositório privado permite restringir o acesso a você e seus membros de equipe.

Neste tutorial, vamos enviar a imagem do Django ao repositório público do Docker Hub criado nos pré-requisitos. Também é possível enviar sua imagem a um repositório privado, mas puxar imagens de um repositório privado está além do escopo deste artigo. Para aprender mais sobre a autenticação do Kubernetes com o Docker Hub e puxar imagens privadas, consulte Puxar uma imagem de um registro privado dos documentos do Kubernetes.

Comece fazendo login no Docker Hub em sua máquina local:

  1. docker login
Output
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username:

Digite seu nome de usuário e senha do Docker Hub para fazer login.

A imagem do Django possui atualmente o sinalizador polls:latest. Para enviá-la ao seu repositório do Docker Hub, sinalize novamente a imagem com seu nome de usuário e nome de repositório do Docker Hub:

  1. docker tag polls:latest your_dockerhub_username/your_dockerhub_repo_name:latest

Carregue a imagem no repositório:

  1. docker push sammy/sammy-django:latest

Neste tutorial, o nome de usuário do Docker Hub é sammy e o nome do repositório é sammy-django. Você deve substituir esses valores pelo seu nome de usuário e nome de repositório do Docker Hub.

Você verá um resultado que se atualiza conforme as camadas da imagem são enviadas ao Docker Hub.

Agora que sua imagem está disponível no Kubernetes no Docker Hub, você pode começar a implantá-la em seu cluster.

Passo 4 — Configurando o ConfigMap

Quando executamos o contêiner do Django localmente, passamos o arquivo env ao docker run para injetar variáveis de configuração no ambiente de tempo de execução. No Kubernetes, as variáveis de configuração podem ser injetadas usando o ConfigMaps e Segredos.

Os ConfigMaps devem ser usados para armazenar informações de configuração não confidenciais, como as configurações do aplicativo, enquanto os Segredos devem ser usados para informações confidenciais como chaves de API e credenciais de banco de dados. Ambos são injetados em contêineres de maneira similar, mas os Segredos têm recursos de controle de acesso e segurança adicionais, como a criptografia em repouso. Os Segredos também armazenam dados em base64, enquanto os ConfigMaps armazenam dados em texto simples.

Para começar, crie um diretório chamado yaml no qual vamos armazenar nossos manifestos do Kubernetes. Navegue até o diretório.

  1. mkdir yaml
  2. cd

Abra um arquivo chamado polls-configmap.yaml no nano ou seu editor de texto preferido:

  1. nano polls-configmap.yaml

Cole o seguinte manifesto do ConfigMap:

polls-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: polls-config
data:
  DJANGO_ALLOWED_HOSTS: "*"
  STATIC_ENDPOINT_URL: "https://your_space_name.space_region.digitaloceanspaces.com"
  STATIC_BUCKET_NAME: "your_space_name"
  DJANGO_LOGLEVEL: "info"
  DEBUG: "True"
  DATABASE_ENGINE: "postgresql_psycopg2"

As configurações não confidenciais foram extraídas do arquivo env modificado no Passo 1 e coladas em um manifesto do ConfigMap. O objeto do ConfigMap chama-se polls-config. Copie os mesmos valores inseridos no arquivo env no passo anterior.

Por motivos de teste, deixe o DJANGO_ALLOWED_HOSTS como * para desativar a filtragem baseada em cabeçalhos de host. Em um ambiente de produção, isso deve ser definido como o domínio do seu aplicativo.

Quando terminar de editar o arquivo, salve e feche-o.

Crie o ConfigMap em seu cluster usando o kubectl apply:

  1. kubectl apply -f polls-configmap.yaml
Output
configmap/polls-config created

Com o ConfigMap criado, vamos criar o Segredo usado pelo nosso aplicativo no próximo passo.

Passo 5 — Configurando o Segredo

Os valores do Segredo devem ser codificados em base64, o que significa que criar objetos Segredo em seu cluster é ligeiramente mais complicado do que criar ConfigMaps. É possível repetir o processo do passo anterior, manualmente codificar os valores do Segredo em base64 e colá-los em um arquivo de manifesto. Também é possível criá-los usando um arquivo de variável de ambiente, kubectl create e o sinalizador --from-env-file, o que será feito neste passo.

Novamente, vamos usar o arquivo env do Passo 1, removendo variáveis inseridas no ConfigMap. Faça uma cópia do arquivo env chamado polls-secrets no diretório yaml:

  1. cp ../env ./polls-secrets

Edite o arquivo em seu editor de preferência:

  1. nano polls-secrets
polls-secrets
DJANGO_SECRET_KEY=
DEBUG=True
DJANGO_ALLOWED_HOSTS=
DATABASE_ENGINE=postgresql_psycopg2
DATABASE_NAME=polls
DATABASE_USERNAME=
DATABASE_PASSWORD=
DATABASE_HOST=
DATABASE_PORT=
STATIC_ACCESS_KEY_ID=
STATIC_SECRET_KEY=
STATIC_BUCKET_NAME=
STATIC_ENDPOINT_URL=
DJANGO_LOGLEVEL=info

Exclua todas as variáveis inseridas no manifesto do ConfigMap. Quando terminar, ele deve ficar parecido com isto:

polls-secrets
DJANGO_SECRET_KEY=your_secret_key
DATABASE_NAME=polls
DATABASE_USERNAME=your_django_db_user
DATABASE_PASSWORD=your_django_db_user_password
DATABASE_HOST=your_db_host
DATABASE_PORT=your_db_port
STATIC_ACCESS_KEY_ID=your_space_access_key
STATIC_SECRET_KEY=your_space_access_key_secret

Certifique-se de usar os mesmos valores usados no Passo 1. Quando terminar, salve e feche o arquivo.

Crie o Segredo em seu cluster usando o kubectl create secret:

  1. kubectl create secret generic polls-secret --from-env-file=poll-secrets
Output
secret/polls-secret created

Aqui, criamos um objeto Segredo chamado polls-secret e o passamos no arquivo de Segredos que acabamos de criar.

Verifique o Segredo usando o kubectl describe:

  1. kubectl describe secret polls-secret
Output
Name: polls-secret Namespace: default Labels: <none> Annotations: <none> Type: Opaque Data ==== DATABASE_PASSWORD: 8 bytes DATABASE_PORT: 5 bytes DATABASE_USERNAME: 5 bytes DJANGO_SECRET_KEY: 14 bytes STATIC_ACCESS_KEY_ID: 20 bytes STATIC_SECRET_KEY: 43 bytes DATABASE_HOST: 47 bytes DATABASE_NAME: 5 bytes

Neste ponto, você armazenou a configuração do seu aplicativo em seu cluster do Kubernetes usando os tipos de objeto Segredo e ConfigMap. Agora, estamos prontos para implantar o aplicativo no cluster.

Passo 6 — Implementando o aplicativo do Django usando uma Implantação

Neste passo, você criará um Deployment (implantação) para seu aplicativo do Django. Uma Implantação do Kubernetes é um controlador que pode ser usado para gerenciar aplicativos sem estado em seu cluster. Um controlador é um loop de controle que regula cargas de trabalho aumentando ou diminuindo-as. Os controladores também reiniciam e limpam contêineres com falhas.

As Implantações controlam um ou mais Pods, a menor unidade implantável em um cluster do Kubernetes. Os Pods incluem um ou mais contêineres. Para aprender mais sobre os diferentes tipos de cargas de trabalho que você pode inicializar, consulte Uma introdução ao Kubernetes.

Inicie abrindo um arquivo chamado polls-deployment.yaml no seu editor de texto favorito:

  1. nano polls-deployment.yaml

Cole o manifesto de Implantação a seguir:

polls-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: polls-app
  labels:
    app: polls
spec:
	replicas: 2
  selector:
    matchLabels:
      app: polls
  template:
    metadata:
      labels:
        app: polls
    spec:
      containers:
        - image: your_dockerhub_username/app_repo_name:latest
          name: polls
          envFrom:
          - secretRef:
              name: polls-secret
          - configMapRef:
              name: polls-config
          ports:
            - containerPort: 8000
              name: gunicorn

Preencha o nome apropriado da imagem do contêiner, referenciando a imagem do Polls do Django que você enviou para o Docker Hub no Passo 2.

Aqui, definimos uma Implantação do Kubernetes chamada polls-app e a rotulamos com o par de chave-valor app: polls. Especificamos que queremos executar duas réplicas do Pod definido abaixo do campo template.

Usando o envFrom com o secretRef e o configMapRef, especificamos que todos os dados do Segredo polls-secret e do ConfigMap polls-config devem ser injetados nos contêineres como variáveis de ambiente. As chaves ConfigMap e Segredo tornam-se os nomes das variáveis de ambiente.

Por fim, expomos a containerPort 8000 e a nomeamos gunicorn.

Para aprender mais sobre como configurar as Implantações do Kubernetes, consulte Deployments na documentação do Kubernetes.

Quando terminar de editar o arquivo, salve e feche-o.

Crie uma Implantação no seu cluster usando o kubectl apply -f:

  1. kubectl apply -f polls-deployment.yaml
  1. deployment.apps/polls-app created

Verifique se a Implantação foi implantada corretamente usando o kubectl get:

  1. kubectl get deploy polls-app
Output
NAME READY UP-TO-DATE AVAILABLE AGE polls-app 2/2 2 2 6m38s

Se encontrar um erro ou algo não estiver funcionando, use o kubectl describe para verificar o Deployment que falhou:

  1. kubectl describe deploy

Verifique os dois Pods usando o kubectl get pod:

  1. kubectl get pod
Output
NAME READY STATUS RESTARTS AGE polls-app-847f8ccbf4-2stf7 1/1 Running 0 6m42s polls-app-847f8ccbf4-tqpwm 1/1 Running 0 6m57s

Agora, duas réplicas do seu aplicativo Django estão em funcionamento no cluster. Para acessar o aplicativo, é necessário criar um Service (serviço) do Kubernetes, que vamos fazer em seguida.

Passo 7 — Permitindo o acesso externo usando um Serviço

Neste passo, você irá criar um Serviço para seu aplicativo Django. Um Serviço do Kubernetes é uma abstração que permite expor um conjunto de Pods em execução como um serviço de rede. Ao usar um Serviço, é possível criar um ponto de extremidade estável para seu aplicativo que não muda à medida que os Pods são destruídos e recriados.

Existem vários tipos de Serviço, incluindo os Serviços de ClusterIP, que expõem o Serviço em um IP interno do cluster, os Serviços de NodePort, que expõem o Serviço em cada nó em uma porta estática chamada NodePort, além de os Serviços de LoadBalancer, que fornecem um balanceador de carga em nuvem para direcionar o tráfego externo aos Pods no seu cluster (através dos NodePorts, criados por ele automaticamente). Para aprender mais sobre isso, consulte Service nos documentos do Kubernetes.

Em nossa configuração final, vamos usar um Serviço de ClusterIP que é exposto usando um Ingress e um Controlador Ingress configurados nos pré-requisitos deste guia. Por enquanto, para testar se tudo está funcionando corretamente, vamos criar um Serviço de NodePort temporário para acessar o aplicativo Django.

Inicie criando um arquivo chamado polls-svc.yaml usando seu editor favorito:

  1. nano polls-svc.yaml

Cole o manifesto de Serviço a seguir:

polls-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: polls
  labels:
    app: polls
spec:
  type: NodePort
  selector:
    app: polls
  ports:
    - port: 8000
      targetPort: 8000

Aqui, criamos um Serviço de NodePort chamado polls e damos a ele o rótulo app: polls. Em seguida, selecionamos os Pods de backend com o rótulo app: polls e miramos em suas portas 8000.

Quando terminar de editar o arquivo, salve e feche-o.

Implemente o Serviço usando o kubectl apply:

  1. kubectl apply -f polls-svc.yaml
Output
service/polls created

Confirme se seu Serviço foi criado usando o kubectl get svc:

  1. kubectl get svc polls
Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE polls NodePort 10.245.197.189 <none> 8000:32654/TCP 59s

Esse resultado mostra o IP interno do cluster do Serviço e o NodePort (32654). Para nos conectar ao serviço, precisamos dos endereços IP externos para nossos nós de cluster:

  1. kubectl get node -o wide
Output
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME pool-7no0qd9e0-364fd Ready <none> 27h v1.18.8 10.118.0.5 203.0.113.1 Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9 pool-7no0qd9e0-364fi Ready <none> 27h v1.18.8 10.118.0.4 203.0.113.2 Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9 pool-7no0qd9e0-364fv Ready <none> 27h v1.18.8 10.118.0.3 203.0.113.3 Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9

Em seu navegador Web, visite seu aplicativo Polls usando um endereço IP externo de qualquer nó e o NodePort. De acordo com o resultado acima, a URL do aplicativo seria: http://203.0.113.1:32654/polls.

Você deve ver a mesma interface do aplicativo Polls que você acessou localmente no Passo 1:

Interface do aplicativo Polls

É possível repetir o mesmo teste usando a rota /admin: http://203.0.113.1:32654/admin. Você deve ver a mesma interface de administrador que antes:

Página de autenticação de administrador do Polls

Neste estágio, você já implantou duas réplicas do contêiner do aplicativo Polls do Django usando uma Implantação. Você também criou um ponto de extremidade de rede estável para essas duas réplicas, e o tornou externamente acessível usando um Serviço de NodePort.

O passo final neste tutorial é proteger o tráfego externo para seu aplicativo usando HTTPS. Para fazer isso, vamos usar o Controlador Ingress ingress-nginx instalado nos pré-requisitos e criar um objeto Ingress para rotear o tráfego externo para o Serviço polls do Kubernetes.

Passo 8 — Configurando o HTTPS usando o Nginx Ingress e o cert-manager

Os Ingresses do Kubernetes permitem o roteamento do tráfego externo ao cluster do seu Kubernetes de maneira flexível para os Serviços dentro de seu cluster. Isso é alcançado usando os objetos do Ingress, que definem as regras para rotear o tráfego HTTP e HTTPS para os Serviços do Kubernetes e para os Controladores do Ingress, os quais implementam as regras fazendo o balanceamento da carga do tráfego e o seu roteamento para os Serviços de backend apropriados.

Nos pré-requisitos, você instalou o Controlador Ingress ingress-nginx e o add-on de automação de certificados TLS cert-manager. Você também definiu a preparação e a produção de ClusterIssuers para seu domínio usando a autoridade de certificação Let’s Encrypt e criou um Ingress para testar a emissão de certificados e a criptografia TLS em dois Serviços de backend fictícios. Antes de continuar com este passo, deve-se excluir o Ingress echo-ingress criado no tutorial pré-requisito:

  1. kubectl delete ingress echo-ingress

Se desejar, também pode excluir os Serviços e Implantações fictícios usando o kubectl delete svc e o kubectl delete deploy, mas isso não é essencial para completar este tutorial.

Você também deve ter criado um registro de DNS A com your_domain.com apontando para o endereço IP público do balanceador de carga do Ingress. Se estiver usando um balanceador de carga da DigitalOcean, é possível encontrar esse endereço IP na seção Load Balancers do Painel de controle. Se estiver usando a DigitalOcean para gerenciar os registros de DNS do seu domínio, consulte Como gerenciar os registros de DNS para aprender como criar registros A.

Se estiver usando o Kubernetes da DigitalOcean, também certifique-se de ter implementado a solução descrita no Passo 5 de Como configurar um Nginx Ingress com o Cert-Manager no Kubernetes da DigitalOcean.

Assim que tiver um registro A apontando para o balanceador de carga do Ingress, crie um Ingress para your_domain.com e o Serviço polls.

Abra um arquivo chamado polls-ingress.yaml no seu editor favorito:

  1. nano polls-ingress.yaml

Cole o manifesto de Ingress a seguir:

[polls-ingress.yaml]
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: polls-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-staging"
spec:
  tls:
  - hosts:
    - your_domain.com
    secretName: polls-tls
  rules:
  - host: your_domain.com
    http:
      paths:
      - backend:
          serviceName: polls
          servicePort: 8000

Criamos um objeto Ingress chamado polls-ingress e o anotamos para instruir o plano de controle para usar o Controlador Ingress ingress-nginx e o ClusterIssuer de preparo. Também habilitamos o TLS para your_domain.com e armazenamos o certificado e a chave privada em um segredo chamado polls-tls. Por fim, definimos uma regra para rotear o tráfego para o host your_domain.com para o Serviço polls na porta 8000.

Quando terminar de editar o arquivo, salve e feche-o.

Crie o Ingress no seu cluster usando o kubectl apply:

  1. kubectl apply -f polls-ingress.yaml
Output
ingress.networking.k8s.io/polls-ingress created

É possível usar o kubectl describe para rastrear o estado do Ingress que acabou de ser criado:

  1. kubectl describe ingress polls-ingress
Output
Name: polls-ingress Namespace: default Address: workaround.your_domain.com Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>) TLS: polls-tls terminates your_domain.com Rules: Host Path Backends ---- ---- -------- your_domain.com polls:8000 (10.244.0.207:8000,10.244.0.53:8000) Annotations: cert-manager.io/cluster-issuer: letsencrypt-staging kubernetes.io/ingress.class: nginx Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 51s nginx-ingress-controller Ingress default/polls-ingress Normal CreateCertificate 51s cert-manager Successfully created Certificate "polls-tls" Normal UPDATE 25s nginx-ingress-controller Ingress default/polls-ingress

Também é possível executar um describe no certificado polls-tls para confirmar ainda mais se sua criação foi bem-sucedida:

  1. kubectl describe certificate polls-tls
Output
. . . Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Issuing 3m33s cert-manager Issuing certificate as Secret does not exist Normal Generated 3m32s cert-manager Stored new private key in temporary Secret resource "polls-tls-v9lv9" Normal Requested 3m32s cert-manager Created new CertificateRequest resource "polls-tls-drx9c" Normal Issuing 2m58s cert-manager The certificate has been successfully issued

Isso confirma que o certificado TLS foi emitido com sucesso e a criptografia do HTTPS agora está ativa para your_domain.com.

Como usamos o ClusterIssuer de preparo, a maior parte dos navegadores Web não irá confiar no certificado falso do Let’s Encrypt que ele emitiu, de forma que navegar até your_domain.com irá resultar em uma página de erro.

Para enviar um pedido de teste, vamos usar o wget a partir da linha de comando:

  1. wget -O - http://your_domain.com/polls
Output
. . . ERROR: cannot verify your_domain.com's certificate, issued by ‘CN=Fake LE Intermediate X1’: Unable to locally verify the issuer's authority. To connect to your_domain.com insecurely, use `--no-check-certificate'.

Vamos usar o sinalizador sugerido --no-check-certificate para ignorar a validação de certificados:

  1. wget --no-check-certificate -q -O - http://your_domain.com/polls
Output
<link rel="stylesheet" type="text/css" href="https://your_space.nyc3.digitaloceanspaces.com/django-polls/static/polls/style.css"> <p>No polls are available.</p>

Esse resultado mostra o HTML para a página de interface de /polls, o que também confirma que a folha de estilos está sendo exibida a partir do armazenamento de objetos.

Agora que você testou com sucesso a emissão de certificados usando o ClusterIssuer de preparo, modifique o Ingress para usar o ClusterIssuer de produção.

Abra o polls-ingress.yaml para editar mais uma vez:

  1. nano polls-ingress.yaml

Modifique a anotação do cluster-issuer:

[polls-ingress.yaml]
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: polls-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - your_domain.com
    secretName: polls-tls
  rules:
  - host: your_domain.com
    http:
      paths:
      - backend:
          serviceName: polls
          servicePort: 8000

Quando terminar, salve e feche o arquivo. Atualize o Ingress usando o kubectl apply:

  1. kubectl apply -f polls-ingress.yaml
Output
ingress.networking.k8s.io/polls-ingress configured

É possível usar o kubectl describe certificate polls-tls e o kubectl describe ingress polls-ingress para rastrear o status da emissão de certificados:

  1. kubectl describe ingress polls-ingress
Output
. . . Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 23m nginx-ingress-controller Ingress default/polls-ingress Normal CreateCertificate 23m cert-manager Successfully created Certificate "polls-tls" Normal UPDATE 76s (x2 over 22m) nginx-ingress-controller Ingress default/polls-ingress Normal UpdateCertificate 76s cert-manager Successfully updated Certificate "polls-tls"

O resultado acima confirma que o novo certificado de produção foi emitido com sucesso e armazenado no Secredo polls-tls.

Navegue até your_domain.com/polls no seu navegador Web para confirmar se a criptografia do HTTPS está habilitada e tudo está funcionando como esperado. Você deve ver a interface do aplicativo Polls:

Interface do aplicativo Polls

Verifique se a criptografia do HTTPS está ativa no seu navegador Web. Se estiver usando o Google Chrome, chegar na página acima sem erros confirma que tudo está funcionando corretamente. Além disso, você deve ver um cadeado na barra de URL. Clicar no cadeado permitirá verificar os detalhes do certificado do Let’s Encrypt.

Como uma tarefa de limpeza final, você pode alterar opcionalmente o tipo de Serviço polls do NodePort para o tipo exclusivamente interno ClusterIP.

Modifique o polls-svc.yaml usando seu editor:

  1. nano polls-svc.yaml

Altere o type de NodePort para ClusterIP:

polls-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: polls
  labels:
    app: polls
spec:
  type: ClusterIP
  selector:
    app: polls
  ports:
    - port: 8000
      targetPort: 8000

Quando terminar de editar o arquivo, salve e feche-o.

Implemente as alterações usando o kubectl apply:

  1. kubectl apply -f polls-svc.yaml --force
Output
service/polls configured

Confirme se seu Serviço foi modificado usando o kubectl get svc:

  1. kubectl get svc polls
Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE polls ClusterIP 10.245.203.186 <none> 8000/TCP 22s

Esse resultado mostra que o tipo de Serviço é agora ClusterIP. A única maneira de acessá-lo é através do seu domínio e do Ingress criados neste passo.

Conclusão

Neste tutorial, você implantou um aplicativo Django dimensionável e seguro via HTTPS em um cluster do Kubernetes. O conteúdo estático é servido diretamente do armazenamento de objetos, e o número de Pods em execução pode ser aumentado ou reduzido rapidamente usando o campo replicas no manifesto de Implantação polls-app.

Se estiver usando um espaço da DigitalOcean, também é possível habilitar a entrega de ativos estáticos através de uma rede de entrega de conteúdo e criar um subdomínio personalizado para seu espaço. Por favor, consulte Habilitando o CDN de Como configurar um aplicativo Django dimensionável com os bancos de dados e espaços gerenciados da DigitalOcean para aprender mais.

Para revisar o resto da série, visite nossa página da série De contêineres ao Kubernetes com o Django.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel