Como executar o Django no Google Kubernetes Engine

Os aplicativos Django executados no Google Kubernetes Engine (GKE) são bem dimensionados porque são executados na mesma infraestrutura que capacita todos os produtos do Google.

Neste tutorial, julgamos que você esteja familiarizado com o desenvolvimento de Web com Django. Se você não está familiarizado com o desenvolvimento em Django, tente escrever seu primeiro aplicativo Django antes de continuar. Nesse tutorial, os modelos do app representam pesquisas que contêm perguntas, e é possível interagir com os modelos usando o console de administração do Django.

Neste tutorial, é necessário usar o Python 2.7, 3.4 ou versão posterior (em inglês). Também é necessário ter o Docker instalado (em inglês).

Antes de começar

  1. Faça login na sua conta do Google.

    Se você ainda não tiver uma, inscreva-se.

  2. No Console do Cloud, na página do seletor de projetos, selecione ou crie um projeto do Cloud.

    Acessar a página do seletor de projetos

  3. Verifique se a cobrança está ativada para o seu projeto do Google Cloud. Saiba como confirmar se a cobrança está ativada para o seu projeto.

  4. Ative as APIs Cloud SQL, and Compute Engine.

    Ative as APIs

  5. Instale e inicialize o SDK do Cloud..

Fazer o download e executar o app

Depois de concluir os pré-requisitos, faça o download e execute o app de amostra do Django. As seções a seguir contêm as etapas de configuração, execução e implantação do aplicativo.

Como clonar o app do Django

O código para o aplicativo de amostra Django está no repositório GoogleCloudPlatform/python-docs-samples no GitHub.

  1. Você pode fazer o download da amostra como um arquivo zip e extraí-lo ou clonar o repositório para sua máquina local usando o seguinte comando:

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
    
  2. Acesse o diretório que contém o código de amostra:

    cd python-docs-samples/kubernetes_engine/django_tutorial
    

Como configurar o ambiente local

Quando implantado, seu aplicativo usa o Cloud SQL Proxy incorporado ao ambiente do App Engine para se comunicar com sua instância do Cloud SQL. No entanto, para testar o aplicativo no local, é necessário instalar e usar uma cópia local do proxy no ambiente de desenvolvimento.

Saiba mais sobre o Cloud SQL Proxy.

Para executar tarefas administrativas básicas na sua instância do Cloud SQL, use o cliente PostgreSQL.

Ativar a API Cloud SQL Admin

Antes de usar o Cloud SQL, ative a API Admin do Cloud SQL:

gcloud services enable sqladmin

Como instalar o Cloud SQL Proxy

Faça o download do Cloud SQL Proxy e instale-o. Ele se conectará à sua instância do Cloud SQL durante a execução local.

Linux de 64 bits

  1. Faça o download do proxy:
    wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
    
  2. Torne o proxy executável:
    chmod +x cloud_sql_proxy
    

Linux de 32 bits

  1. Faça o download do proxy:
    wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.386 -O cloud_sql_proxy
    
  2. Torne o proxy executável:
    chmod +x cloud_sql_proxy
    

macOS de 64 bits

  1. Faça o download do proxy:
    curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64
    
  2. Torne o proxy executável:
    chmod +x cloud_sql_proxy
    

macOS de 32 bits

  1. Faça o download do proxy:
    curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.386
    
  2. Torne o proxy executável:
    chmod +x cloud_sql_proxy
    

Windows de 64 bits

Para fazer o download do proxy, clique com o botão direito em https://dl.google.com/cloudsql/cloud_sql_proxy_x64.exe e selecione Salvar link como. Renomeie o arquivo para cloud_sql_proxy.exe.

Windows de 32 bits

Para fazer o download do proxy, clique com o botão direito em https://dl.google.com/cloudsql/cloud_sql_proxy_x86.exe e selecione Salvar link como. Renomeie o arquivo para cloud_sql_proxy.exe.
Caso seu sistema operacional não esteja incluído aqui, compile o proxy a partir da fonte.

Como criar uma instância do Cloud SQL

  1. Crie uma instância do Cloud SQL para PostgreSQL.

    Atribua o nome polls-instance ou outro similar à instância. Pode demorar alguns minutos para a instância ficar pronta. Quando isso acontecer, ela estará visível na lista de instâncias.

  2. Use o SDK do Cloud para executar o comando a seguir, em que [YOUR_INSTANCE_NAME] representa o nome da instância do Cloud SQL:
    gcloud sql instances describe [YOUR_INSTANCE_NAME]

    Na saída, observe o valor mostrado para [CONNECTION_NAME].

    O valor [CONNECTION_NAME] está no formato [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME].

Como inicializar a instância do Cloud SQL

  1. Inicie o Cloud SQL Proxy usando o valor [CONNECTION_NAME] da etapa anterior:

    Linux/macOS

    ./cloud_sql_proxy -instances="[YOUR_INSTANCE_CONNECTION_NAME]"=tcp:5432

    Windows

    cloud_sql_proxy.exe -instances="[YOUR_INSTANCE_CONNECTION_NAME]"=tcp:5432

    Substitua [YOUR_INSTANCE_CONNECTION_NAME] pelo valor de [CONNECTION_NAME] registrado na etapa anterior.

    Essa etapa estabelece uma conexão do computador local com a instância do Cloud SQL para testes locais. Mantenha o Cloud SQL Proxy em execução durante todo o teste local do aplicativo.

  2. Crie um usuário e um banco de dados do Cloud SQL:

    Console do Cloud

    1. Crie um novo banco de dados usando o Console do Cloud para a instância polls-instance do Cloud SQL. Por exemplo, use o nome polls.
    2. Crie um novo usuário usando o Console do Cloud para a instância do Cloud SQL polls-instance.

    Cliente Postgres

    1. Em uma guia de linha de comando separada, instale o cliente Postgres.
      sudo apt-get install postgresql
    2. Use o cliente Postgres ou programa semelhante para se conectar à instância. Quando solicitado, use a senha raiz configurada.
      psql --host 127.0.0.1 --user postgres --password
    3. Crie os bancos de dados, usuários e permissões de acesso necessários no banco de dados do Cloud SQL usando os comandos a seguir. Substitua [POSTGRES_USER] e [POSTGRES_PASSWORD] pelo nome de usuário e senha que você quer usar.
      CREATE DATABASE polls;
      CREATE USER [POSTGRES_USER] WITH PASSWORD '[POSTGRES_PASSWORD]';
      GRANT ALL PRIVILEGES ON DATABASE polls TO [POSTGRES_USER];
      GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO [POSTGRES_USER];
      

Criar uma conta de serviço

Para usar o proxy, é necessário ter uma conta de serviço com privilégios de Editor para sua instância do Cloud SQL. Para mais informações sobre contas de serviço, consulte a visão geral da autenticação do Google Cloud.

Caso queira usar uma conta de serviço para fornecer as credenciais ao proxy, você precisará criá-la com permissões suficientes. Se você estiver usando os papéis mais detalhados de gerenciamento de identidade e acesso (IAM) para gerenciar suas permissões do Cloud SQL, atribua à conta de serviço um papel que inclua a permissão cloudsql.instances.connect. Os papéis predefinidos do Cloud SQL que incluem essa permissão são os seguintes:

  • Cliente do Cloud SQL
  • Editor do Cloud SQL
  • Administrador do Cloud SQL

Se você estiver usando os papéis legados (visualizador, editor e proprietário) do projeto, a conta de serviço precisará ter pelo menos o papel de editor.

  1. Acesse a página Contas de serviço no Console do Google Cloud.

    Acessar a página "Contas de serviço"

  2. Selecione o projeto que contém a instância do Cloud SQL.
  3. Clique em Criar conta de serviço.
  4. Na caixa de diálogo Criar conta de serviço, forneça um nome descritivo para a conta.
  5. Em Papel, selecione um dos seguintes papéis:
    • Cloud SQL > Cliente do Cloud SQL
    • Cloud SQL > Editor do Cloud SQL
    • Cloud SQL > Administrador do Cloud SQL
  6. Altere o ID da conta de serviço para um valor exclusivo e facilmente reconhecível.
  7. Clique em Fornecer uma nova chave privada e confirme se o tipo de chave é JSON.
  8. Clique em Criar

    O arquivo da chave privada é transferido para sua máquina. Você pode movê-lo para outro local. Mantenha-o seguro.

Como definir as configurações do banco de dados

Use os seguintes comandos para definir variáveis de ambiente para o acesso ao banco de dados. Essas variáveis são usadas para testes locais.

Linux/macOS

export DATABASE_USER=<your-database-user>
export DATABASE_PASSWORD=<your-database-password>

Windows

set DATABASE_USER=<your-database-user>
set DATABASE_PASSWORD=<your-database-password>

Como definir sua configuração do GKE

  1. Esse aplicativo é representado por uma única configuração do Kubernetes chamada polls. Em polls.yaml, substitua <your-project-id> pelo ID do projeto do Google Cloud.

  2. Execute o comando a seguir e anote o valor de connectionName:

    gcloud beta sql instances describe [YOUR_INSTANCE_NAME]
    
  3. No arquivo polls.yaml, substitua <your-cloudsql-connection-string> pelo valor connectionName.

Como executar o app no computador local

  1. Para executar o app do Django no seu computador local, configure um ambiente de desenvolvimento do Python, incluindo Python, pip e virtualenv.

  2. Crie um ambiente Python isolado e instale as dependências. Se a instalação do Python 3 tiver um nome diferente, use-o no primeiro comando:

    virtualenv env
    source env/bin/activate
    pip install -r requirements.txt
    
  3. Execute as migrações do Django para definir seus modelos:

    python manage.py makemigrations
    python manage.py makemigrations polls
    python manage.py migrate
    
  4. Inicie um servidor da Web local:

    python manage.py runserver
    
  5. No navegador, acesse http://localhost:8000/.

    Você verá uma página com o seguinte texto: "Hello, world. Você está no índice de pesquisas". O servidor da Web do Django em execução no seu computador exibe as páginas do aplicativo de amostra.

  6. Pressione Control+C para interromper o servidor da Web local.

Como usar o console de administração do Django

  1. Crie um superusuário. Você precisa especificar um nome de usuário e uma senha.

    python manage.py createsuperuser
    
  2. Execute o programa principal:

    python manage.py runserver
    
  3. No navegador, acesse http://localhost:8000/admin.

  4. Faça login no site de administração usando o nome de usuário e a senha que você usou ao executar createsuperuser.

Como implantar o app no GKE

Quando o aplicativo é implantado no Google Cloud, ele usa o servidor Gunicorn. Como o conteúdo estático não é transmitido pelo Gunicorn, o Cloud Storage é usado para disponibilizar esse tipo de conteúdo.

Coletar e fazer upload de recursos estáticos

  1. Crie um bucket do Cloud Storage e torne-o acessível para leitura pública. Substitua [YOUR_GCS_BUCKET] por um nome de bucket de sua escolha. Por exemplo, você pode usar seu ID do projeto como um nome de bucket.

    gsutil mb gs://[YOUR_GCS_BUCKET]
    gsutil defacl set public-read gs://[YOUR_GCS_BUCKET]
    
  2. Reúna todo o conteúdo estático em uma pasta.

    python manage.py collectstatic
    
  3. Faça o upload de todo conteúdo estático no Cloud Storage:

    gsutil -m rsync -r ./static gs://[YOUR_GCS_BUCKET]/static
    
  4. Em mysite/settings.py, defina o valor de STATIC_URL para o seguinte URL, substituindo [YOUR_GCS_BUCKET] pelo nome do bucket:

    http://storage.googleapis.com/[YOUR_GCS_BUCKET]/static/
    

Configurar o GKE

  1. Para inicializar o GKE, acesse a página Clusters.

    Acessar a página de Clusters

    Quando você usa o GKE pela primeira vez em um projeto, é necessário aguardar até que o "Kubernetes Engine está se preparando. Isso pode demorar alguns minutos" desapareça.

  2. Criar um cluster do GKE

    gcloud container clusters create polls \
      --scopes "https://www.googleapis.com/auth/userinfo.email","cloud-platform" \
      --num-nodes 4 --zone "us-central1-a"
    

    Você recebeu o erro: "Projeto [PROJECT_ID] não foi totalmente inicializado com as contas de serviço padrão"?

    Inicializar o GKE

    Se você recebeu um erro, acesse o Console do Google Cloud para inicializar o GKE no seu projeto.

    Acessar a página de Clusters

    Aguarde até que a mensagem "O Kubernetes Engine está se preparando. Isso pode levar alguns minutos" desapareça.

  3. Depois que o cluster for criado, use a ferramenta de linha de comando kubectl, que é integrada à ferramenta gcloud, para interagir com o cluster do GKE. Como gcloud e kubectl são ferramentas separadas, verifique se kubectl está configurado para interagir com o cluster certo.

    gcloud container clusters get-credentials polls --zone "us-central1-a"
    

Configurar o Cloud SQL

  1. Você precisa de várias chaves secretas para permitir que o aplicativo do GKE se conecte à instância do Cloud SQL. Uma delas é necessária para acesso de nível de instância (conexão), enquanto outras duas são necessárias para acesso a banco de dados. Para saber mais informações sobre os dois níveis de controle de acesso, consulte Controle de acesso à instância.

    1. Para criar o secret do acesso no nível da instância, forneça o local ([PATH_TO_CREDENTIAL_FILE]) da chave da conta de serviço JSON que você salvou ao criar essa conta. Consulte Como criar um serviço conta):

      kubectl create secret generic cloudsql-oauth-credentials --from-file=credentials.json=[PATH_TO_CREDENTIAL_FILE]
      
    2. Para criar as chaves secretas para acesso ao banco de dados, use o [DATABASE_USERNAME] do SQL e o [PASSWORD] definidos na etapa 2 de Como inicializar a instância do Cloud SQL:

      kubectl create secret generic cloudsql --from-literal=username=[DATABASE_USERNAME] --from-literal=password=[PASSWORD]
      
  2. Recupere a imagem pública do Docker para o proxy do Cloud SQL.

    docker pull b.gcr.io/cloudsql-docker/gce-proxy
    
  3. Crie uma imagem do Docker, substituindo <your-project-id> pelo ID do projeto.

    docker build -t gcr.io/<your-project-id>/polls .
    
  4. Configure o Docker para usar gcloud como um auxiliar de credenciais, de modo que você possa enviar a imagem para o Container Registry:

    gcloud auth configure-docker
    
  5. Envie a imagem do Docker. Substitua <your-project-id> pelo ID do projeto.

    docker push gcr.io/<your-project-id>/polls
    
  6. Crie o recurso do GKE:

    kubectl create -f polls.yaml
    

Implantar o app no GKE

Depois que os recursos forem criados, haverá três pods polls no cluster. Verifique o status dos seus pods.

    kubectl get pods

Aguarde alguns minutos para que os status do pod sejam exibidos como Running. Se os pods não estiverem prontos ou se houver reinicializações, você poderá receber os registros de um pod específico para descobrir o problema. [YOUR-POD-ID] é uma parte da saída retornada pelo comando kubectl get pods anterior.

    kubectl logs [YOUR_POD_ID]

Como ver o aplicativo em execução no Google Cloud

Depois que os pods estiverem prontos, é possível saber o endereço IP público do balanceador de carga:

kubectl get services polls

Acesse o endereço EXTERNAL-IP no seu navegador para ver a página de destino básica do Django e acessar o Admin Console.

Como entender o código

O app de exemplo do Django foi criado com ferramentas padrão do Django. Estes comandos criam o projeto e o aplicativo de pesquisa:

django-admin startproject mysite
python manage.py startapp polls

O settings.py contém a configuração para seu banco de dados SQL:

DATABASES = {
    'default': {
        # If you are using Cloud SQL for MySQL rather than PostgreSQL, set
        # 'ENGINE': 'django.db.backends.mysql' instead of the following.
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'polls',
        'USER': os.getenv('DATABASE_USER'),
        'PASSWORD': os.getenv('DATABASE_PASSWORD'),
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}

O arquivo polls.yaml especifica dois recursos do Kubernetes. O primeiro é Serviço (em inglês), que define um nome consistente e um endereço IP privado para o app da Web em Django. O segundo é um balanceador de carga HTTP por um endereço IP externo público.

# The polls service provides a load-balancing proxy over the polls app
# pods. By specifying the type as a 'LoadBalancer', Container Engine will
# create an external HTTP load balancer.
# For more information about Services see:
#   https://cloud.google.com/container-engine/docs/services/
# For more information about external HTTP load balancing see:
#   https://cloud.google.com/container-engine/docs/load-balancer
apiVersion: v1
kind: Service
metadata:
  name: polls
  labels:
    app: polls
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: polls

Um nome de rede e um endereço IP são oferecidos pelo serviço e o código do aplicativo por trás do serviço são executados pelos pods do GKE. O arquivo polls.yaml especifica uma implantação que fornece atualizações declarativas para pods do GKE. O tráfego para a implantação é direcionado pelo serviço por meio da correspondência entre o seletor do serviço e o rótulo da implantação. Nesse caso, o seletor polls corresponde ao rótulo polls.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: polls
  labels:
    app: polls
spec:
  replicas: 3
  selector:
    matchLabels:
      app: polls
  template:
    metadata:
      labels:
        app: polls
    spec:
      containers:
      - name: polls-app
        # Replace  with your project ID or use `make template`
        image: gcr.io/<your-project-id>/polls
        # This setting makes nodes pull the docker image every time before
        # starting the pod. This is useful when debugging, but should be turned
        # off in production.
        imagePullPolicy: Always
        env:
            - name: DATABASE_USER
              valueFrom:
                secretKeyRef:
                  name: cloudsql
                  key: username
            - name: DATABASE_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: cloudsql
                  key: password
        ports:
        - containerPort: 8080

      - image: gcr.io/cloudsql-docker/gce-proxy:1.16
        name: cloudsql-proxy
        command: ["/cloud_sql_proxy", "--dir=/cloudsql",
                  "-instances=<your-cloudsql-connection-string>=tcp:5432",
                  "-credential_file=/secrets/cloudsql/credentials.json"]
        volumeMounts:
          - name: cloudsql-oauth-credentials
            mountPath: /secrets/cloudsql
            readOnly: true
          - name: ssl-certs
            mountPath: /etc/ssl/certs
          - name: cloudsql
            mountPath: /cloudsql
      volumes:
        - name: cloudsql-oauth-credentials
          secret:
            secretName: cloudsql-oauth-credentials
        - name: ssl-certs
          hostPath:
            path: /etc/ssl/certs
        - name: cloudsql
          emptyDir: {}