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.
Para seguir este tutorial, será necessário:
kubectl
de linha de comando instalada em sua máquina local e configurada para se conectar ao seu cluster. Você pode ler mais sobre como instalar o kubectl
na documentação oficial. Se você estiver usando um cluster do Kubernetes da DigitalOcean, consulte Como se conectar a um cluster do Kubernetes da DigitalOcean para aprender como se conectar ao seu cluster usando o kubectl
.your_domain.com
do início ao fim. Você pode obter um domínio gratuitamente através do Freenom, ou usar o registrador de domínios de sua escolha.A
com your_domain.com
apontando para o endereço IP público do Balanceador de carga do Ingress. 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 um registro A
.Assim que tiver esses componentes configurados, tudo estará pronto para seguir o guia.
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:
- git clone --single-branch --branch polls-docker https://github.com/do-community/django-polls.git
Navegue até o diretório django-polls
:
- 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
:
- cat Dockerfile
OutputFROM 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
:
- 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
:
- 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:
- nano 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.
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
:
- 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:
OutputNo 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.
- 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:
- 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.
- 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.
Output121 static files copied.
Agora, podemos executar o aplicativo:
- 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:
Para visualizar a interface administrativa, visite http://localhost/admin
. Você deve ver a janela de autenticação do administrador do aplicativo 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:
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.
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:
- docker login
OutputLogin 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:
- docker tag polls:latest your_dockerhub_username/your_dockerhub_repo_name:latest
Carregue a imagem no repositório:
- 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.
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.
- mkdir yaml
- cd
Abra um arquivo chamado polls-configmap.yaml
no nano
ou seu editor de texto preferido:
- nano polls-configmap.yaml
Cole o seguinte manifesto do ConfigMap:
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
:
- kubectl apply -f polls-configmap.yaml
Outputconfigmap/polls-config created
Com o ConfigMap criado, vamos criar o Segredo usado pelo nosso aplicativo no próximo passo.
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
:
- cp ../env ./polls-secrets
Edite o arquivo em seu editor de preferência:
- nano 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:
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
:
- kubectl create secret generic polls-secret --from-env-file=poll-secrets
Outputsecret/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
:
- kubectl describe secret polls-secret
OutputName: 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.
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:
- nano polls-deployment.yaml
Cole o manifesto de Implantação a seguir:
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
:
- kubectl apply -f polls-deployment.yaml
- deployment.apps/polls-app created
Verifique se a Implantação foi implantada corretamente usando o kubectl get
:
- kubectl get deploy polls-app
OutputNAME 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:
- kubectl describe deploy
Verifique os dois Pods usando o kubectl get pod
:
- kubectl get pod
OutputNAME 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.
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:
- nano polls-svc.yaml
Cole o manifesto de Serviço a seguir:
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
:
- kubectl apply -f polls-svc.yaml
Outputservice/polls created
Confirme se seu Serviço foi criado usando o kubectl get svc
:
- kubectl get svc polls
OutputNAME 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:
- kubectl get node -o wide
OutputNAME 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:
É 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:
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.
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:
- 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:
- 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
:
- kubectl apply -f polls-ingress.yaml
Outputingress.networking.k8s.io/polls-ingress created
É possível usar o kubectl describe
para rastrear o estado do Ingress que acabou de ser criado:
- kubectl describe ingress polls-ingress
OutputName: 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:
- 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:
- 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:
- 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:
- 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
:
- kubectl apply -f polls-ingress.yaml
Outputingress.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:
- 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:
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:
- nano polls-svc.yaml
Altere o type
de NodePort
para ClusterIP
:
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
:
- kubectl apply -f polls-svc.yaml --force
Outputservice/polls configured
Confirme se seu Serviço foi modificado usando o kubectl get svc
:
- kubectl get svc polls
OutputNAME 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.
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.
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!