Cloud Composer 1 | Cloud Composer 2
Nesta página, descrevemos como usar o KubernetesPodOperator
para implantar pods do Kubernetes do Cloud Composer no cluster do Google Kubernetes Engine, que faz parte do ambiente do Cloud Composer, e para garantir que ele tenha os recursos apropriados.
KubernetesPodOperator
inicia pods do Kubernetes
no
cluster do ambiente. Os
operadores do Google Kubernetes Engine
executam pods do Kubernetes em um cluster especificado,
que pode ser um cluster separado não relacionado ao seu ambiente. Também é possível criar e excluir
clusters usando os operadores do Google Kubernetes Engine.
O KubernetesPodOperator
é uma boa opção, se você precisar de:
- Dependências personalizadas do Python que não estão disponíveis no repositório PyPI público.
- Dependências binárias que não estão disponíveis na imagem do worker do Cloud Composer.
Nesta página, você verá um exemplo de DAG do Airflow que inclui as seguintes configurações de KubernetesPodOperator
:
- Configuração mínima: define somente os parâmetros obrigatórios.
- Configuração de modelo: usa parâmetros que você pode usar como modelo com o Jinja.
- Configuração de variáveis secrets: transmite um objeto Secret do Kubernetes para o pod.
- A configuração de afinidade de pod não está disponível no Cloud Composer 2. Em vez disso, use os operadores do GKE para iniciar pods em um cluster diferente.
Configuração completa: inclui todas as configurações.
Antes de começar
No Cloud Composer 2, o cluster do ambiente é escalonado automaticamente. As cargas de trabalho extras que você executa usando
KubernetesPodOperator
são escalonadas independentemente do ambiente. Seu ambiente não é afetado pelo aumento da demanda de recursos, mas o cluster do ambiente aumenta ou diminui dependendo da demanda de recursos. Os preços das cargas de trabalho extras executadas no cluster do ambiente seguem o modelo de preços do Cloud Composer 2 e usam as SKUs do Cloud Composer Compute.Os clusters do Cloud Composer 2 usam a Identidade da carga de trabalho. Por padrão, os pods executados em namespaces recém-criados ou o namespace
composer-user-workloads
não podem acessar os recursos do Google Cloud. Ao usar a Identidade da carga de trabalho, as contas de serviço do Kubernetes associadas a namespaces precisam ser mapeadas para contas de serviço do Google Cloud para permitir a autorização da identidade do serviço para solicitações às APIs do Google e outros serviços.Por isso, se você executar pods no namespace
composer-user-workloads
ou em um namespace recém-criado no cluster do ambiente, as vinculações adequadas do IAM entre as contas de serviço do Kubernetes e do Google Cloud não serão criadas e esses pods não poderão acessar os recursos do projeto do Google Cloud.Se você quiser que seus pods tenham acesso aos recursos do Google Cloud, use o namespace
composer-user-workloads
ou crie seu próprio namespace, conforme descrito mais adiante.Para fornecer acesso aos recursos do seu projeto, siga as orientações na Identidade da carga de trabalho e configure as vinculações:
- Crie um namespace separado no cluster do ambiente.
- Crie uma vinculação entre a
conta de serviço do Kubernetes
composer-user-workloads/<namespace_name>
e a conta de serviço do ambiente. - Adicione a anotação da conta de serviço do seu ambiente à conta de serviço do Kubernetes.
- Ao usar
KubernetesPodOperator
, especifique o namespace e a conta de serviço do Kubernetes nos parâmetrosnamespace
eservice_account_name
.
Se a versão 5.0.0 do provedor de Kubernetes CNCF for usada, siga as instruções da seção sobre o provedor de Kubernetes CNCF.
O Cloud Composer 2 usa clusters do GKE com a Identidade da carga de trabalho. O servidor de metadados do GKE leva alguns segundos para começar a aceitar solicitações em um pod recém-criado. Portanto, as tentativas de autenticação usando a Identidade da carga de trabalho podem falhar nos primeiros segundos da vida útil de um pod. Clique neste link para saber mais sobre essa limitação.
O Cloud Composer 2 usa clusters do Autopilot que apresentam a noção de classes de computação. Por padrão, se nenhuma classe for selecionada, a classe
general-purpose
será presumida quando você criar pods usandoKubernetesPodOperator
.- Cada classe está associada a propriedades e limites de recursos específicos. Leia mais sobre isso na documentação do Autopilot. Por exemplo, os pods executados
na classe
general-purpose
podem usar até 110 GiB de memória.
- Cada classe está associada a propriedades e limites de recursos específicos. Leia mais sobre isso na documentação do Autopilot. Por exemplo, os pods executados
na classe
Configuração do KubernetesPodOperator
Para acompanhar este exemplo, coloque todo o arquivo kubernetes_pod_operator.py
na pasta dags/
do ambiente ou
adicione o código relevante KubernetesPodOperator
a um DAG.
As seções a seguir explicam cada configuração KubernetesPodOperator
no exemplo. Para mais informações sobre cada variável de configuração, consulte a referência do Airflow.
Configuração mínima
Para criar um KubernetesPodOperator
, são necessários apenas o name
, o namespace
em que o pod é executado, o image
para usar e o task_id
do pod.
Quando você colocar este snippet de código em um DAG, a configuração usará os
padrões em /home/airflow/composer_kube_config
. Não é necessário modificar o
código para que a tarefa pod-ex-minimum
seja bem-sucedida.
Configuração do modelo
O Airflow é compatível com o
modelo Jinja.
Você precisa declarar as variáveis necessárias (task_id
, name
, namespace
e image
) com o operador. Como mostra o exemplo a seguir, é possível
criar modelos de todos os outros parâmetros com o Jinja, incluindo cmds
, arguments
,
env_vars
e config_file
.
Sem alterar o DAG ou ambiente, a tarefa ex-kube-templates
falha devido a dois erros. Os registros mostram que a tarefa está falhando porque a
variável apropriada não existe (my_value
). O segundo erro, que você
pode receber após corrigir o primeiro erro, mostra que a tarefa falha porque
core/kube_config
não é encontrado em config
.
Para corrigir os dois erros, siga as etapas descritas mais detalhadamente.
Para definir my_value
com gcloud
ou a IU do Airflow:
IU do Airflow
Na IU do Airflow 2:
Acesse a IU do Airflow.
Na barra de ferramentas, selecione Administrador > Variáveis.
Na página Listar variáveis, clique em Adicionar um novo registro.
Na página Adicionar variável, digite as seguintes informações:
- Chave:
my_value
- Val:
example_value
- Chave:
Clique em Salvar.
gcloud
No Airflow 2, digite o seguinte comando:
gcloud composer environments run ENVIRONMENT \
--location LOCATION \
variables set -- \
my_value example_value
Substitua:
ENVIRONMENT
pelo nome do ambienteLOCATION
pela região em que o ambiente está localizado;
Para se referir a um config_file
personalizado (um arquivo de configuração do Kubernetes),
modifique a opção de configuração kube_config
do Airflow para uma
configuração válida do Kubernetes:
Seção | Chave | Valor |
---|---|---|
core |
kube_config |
/home/airflow/composer_kube_config |
Aguarde alguns minutos para que o ambiente seja atualizado. Em seguida,
execute a tarefa ex-kube-templates
novamente e verifique se a
tarefa ex-kube-templates
é bem-sucedida.
Configuração de variáveis de secret
Um secret
do Kubernetes é um objeto que contém dados confidenciais. É possível transmitir secrets para
os pods do Kubernetes usando o KubernetesPodOperator
.
Os secrets precisam ser definidos no Kubernetes ou o pod não será iniciado.
Neste exemplo, mostramos duas maneiras de usar os Kubernetes Secrets: como uma variável de ambiente e como um volume ativado pelo pod.
O primeiro secret, airflow-secrets
, é definido
como uma variável de ambiente do Kubernetes chamada SQL_CONN
(em vez de uma variável de ambiente do Airflow
ou do Cloud Composer).
O segundo secret, service-account
, instala service-account.json
, um arquivo
com um token de conta de serviço, em /var/secrets/google
.
Veja a aparência dos secrets:
O nome do primeiro secret do Kubernetes é definido na variável secret
.
Esse secret privado é chamado de airflow-secrets
. Ele é exposto como uma variável de ambiente, conforme ditado por deploy_type
. A variável
de ambiente definida para, deploy_target
, é SQL_CONN
. Por fim, o key
do
secret armazenado no deploy_target
é sql_alchemy_conn
.
O nome do segundo secret do Kubernetes é definido na variável secret
.
Esse secret privado é chamado de service-account
. Ele é exposto como um
volume, conforme determinado pelo deploy_type
. O caminho do arquivo a ser
ativado, deploy_target
, é /var/secrets/google
. Por fim, o key
do secret
armazenado no deploy_target
é service-account.json
.
A configuração do operador vai ficar assim:
Sem fazer alterações no DAG ou no ambiente, a tarefa
ex-kube-secrets
falha. Se você analisar os registros, a tarefa falhará devido
a um erro Pod took too long to start
. Esse erro ocorre porque o Airflow
não encontrou o secret especificado na configuração, secret_env
.
gcloud
Para definir o secret usando gcloud
:
Receba informações sobre o cluster de ambiente do Cloud Composer.
Execute este comando:
gcloud composer environments describe ENVIRONMENT \ --location LOCATION \ --format="value(config.gkeCluster)"
Substitua:
ENVIRONMENT
pelo nome do ambiente.LOCATION
é a região em que o ambiente do Cloud Composer está localizado.
A saída desse comando usa o seguinte formato:
projects/<your-project-id>/locations/<location-of-composer-env>/clusters/<your-cluster-id>
.Para receber o ID do cluster do GKE, copie a saída depois de
/clusters/
(termina em-gke
).
Conecte-se ao cluster do GKE executando este comando:
gcloud container clusters get-credentials CLUSTER_ID \ --project PROJECT \ --region LOCATION
Substitua:
CLUSTER_ID
pelo ID do cluster do GKE.PROJECT
pelo ID do seu projeto do Google Cloud.LOCATION
é a região em que o ambiente do Cloud Composer está localizado.
Crie secrets do Kubernetes.
Execute o seguinte comando para criar um secret do Kubernetes que defina o valor de
sql_alchemy_conn
paratest_value
:kubectl create secret generic airflow-secrets \ --from-literal sql_alchemy_conn=test_value -n composer-user-workloads
Crie um secret do Kubernetes que defina o valor de
service-account.json
como um caminho local de um arquivo de chave da conta de serviço chamadokey.json
executando o seguinte comando:kubectl create secret generic service-account \ --from-file service-account.json=./key.json -n composer-user-workloads
Depois de definir os secrets, execute a tarefa
ex-kube-secrets
novamente na IU do Airflow.Verifique se a tarefa
ex-kube-secrets
foi bem-sucedida.
Configuração completa
Este exemplo mostra todas as variáveis que você pode configurar em KubernetesPodOperator
. Não é necessário modificar o código para que a tarefa
ex-all-configs
seja bem-sucedida.
Para ver detalhes sobre cada variável, consulte a
referência KubernetesPodOperator
do Airflow.
Informações sobre o provedor de Kubernetes CNCF
GKEStartPodOperator e KubernetesPodOperator são implementados no
provedor apache-airflow-providers-cncf-kubernetes
.
Para ler as notas de versão com falha do provedor do Kubernetes CNCF, consulte o site do provedor do Kubernetes da CNCF.
Versão 6.0.0
Na versão 6.0.0 do pacote CNCF Kubernetes Provider,
a conexão kubernetes_default
é usada por padrão no
KubernetesPodOperator
.
Se você especificou uma conexão personalizada na versão 5.0.0, essa conexão personalizada
ainda será usada pelo operador. Para voltar a usar a conexão kubernetes_default
, faça o ajuste correto dos DAGs.
Versão 5.0.0
Esta versão apresenta algumas alterações incompatíveis com versões anteriores em comparação com a versão 4.4.0. Os mais importantes que você precisa saber
estão relacionados à conexão kubernetes_default
, que não é usada na
versão 5.0.0.
- A conexão
kubernetes_default
precisa ser modificada. O caminho de configuração do Kube precisa ser definido como/home/airflow/composer_kube_config
(veja a Figura 1) ou, como alternativa,config_file
precisa ser adicionado à configuraçãoKubernetesPodOperator
(como foi apresentado abaixo).
- Modifique o código de uma tarefa com o KubernetesPodOperator da seguinte maneira
KubernetesPodOperator(
# config_file parameter - can be skipped if connection contains this setting
config_file="/home/airflow/composer_kube_config",
# definition of connection to be used by the operator
kubernetes_conn_id='kubernetes_default',
...
)
Para mais informações sobre a versão 5.0.0, consulte as Notas de lançamento do provedor Kubernetes da CNCF.
Solução de problemas
Dicas para solucionar problemas de falhas no pod
Além de verificar os registros de tarefas na IU do Airflow, verifique também os seguintes registros:
Saída do programador e dos workers do Airflow:
No console do Google Cloud, acesse a página Ambientes.
Acesse o link DAGs para seu ambiente.
No bucket do ambiente, suba um nível.
Revise os registros na pasta
logs/<DAG_NAME>/<TASK_ID>/<EXECUTION_DATE>
.
Registros detalhados do pod no console do Google Cloud em "Cargas de trabalho do GKE". Esses registros incluem o arquivo YAML de definição, os eventos e os detalhes do pod.
Códigos de retorno diferente de zero quando também usar GKEStartPodOperator
Ao usar KubernetesPodOperator
e GKEStartPodOperator
, o
código de retorno do ponto de entrada do contêiner determina se a tarefa é
considerada bem-sucedida ou não. Os códigos de retorno diferentes de zero indicam a falha.
Um padrão comum ao usar
KubernetesPodOperator
e GKEStartPodOperator
é executar um script de shell como o ponto de entrada do
contêiner para agrupar várias operações dentro do contêiner.
Se você estiver escrevendo esse script, recomendamos que inclua o comando set -e
na parte superior para que comandos com falha encerrem o script e propaguem a falha para a instância de tarefa do Airflow.
Tempos limite do pod
O tempo limite padrão para KubernetesPodOperator
é de 120 segundos, o que pode resultar na ocorrência de tempos limite antes do download de imagens maiores. É possível aumentar o tempo limite alterando o parâmetro startup_timeout_seconds
, quando você cria o KubernetesPodOperator
.
Quando um pod expira, o registro específico da tarefa fica disponível na IU do Airflow. Exemplo:
Executing <Task(KubernetesPodOperator): ex-all-configs> on 2018-07-23 19:06:58.133811
Running: ['bash', '-c', u'airflow run kubernetes-pod-example ex-all-configs 2018-07-23T19:06:58.133811 --job_id 726 --raw -sd DAGS_FOLDER/kubernetes_pod_operator_sample.py']
Event: pod-name-9a8e9d06 had an event of type Pending
...
...
Event: pod-name-9a8e9d06 had an event of type Pending
Traceback (most recent call last):
File "/usr/local/bin/airflow", line 27, in <module>
args.func(args)
File "/usr/local/lib/python2.7/site-packages/airflow/bin/cli.py", line 392, in run
pool=args.pool,
File "/usr/local/lib/python2.7/site-packages/airflow/utils/db.py", line 50, in wrapper
result = func(*args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/airflow/models.py", line 1492, in _run_raw_task
result = task_copy.execute(context=context)
File "/usr/local/lib/python2.7/site-packages/airflow/contrib/operators/kubernetes_pod_operator.py", line 123, in execute
raise AirflowException('Pod Launching failed: {error}'.format(error=ex))
airflow.exceptions.AirflowException: Pod Launching failed: Pod took too long to start
Os tempos limite do pod também podem ocorrer quando a conta de serviço do Composer não tiver as permissões necessárias do IAM para executar a tarefa em questão. Para verificar isso, veja os erros no nível do pod usando os painéis do GKE para analisar os registros para uma carga de trabalho específica, ou use o Cloud Logging.
Falha ao estabelecer uma nova conexão
O upgrade automático é ativado por padrão nos clusters do GKE. Se um pool de nós estiver em um cluster que está fazendo um upgrade, você poderá receber este erro:
<Task(KubernetesPodOperator): gke-upgrade> Failed to establish a new
connection: [Errno 111] Connection refused
Para verificar se o cluster está sendo atualizado, no console do Google Cloud, acesse a página Clusters do Kubernetes e procure o ícone de carregamento ao lado do nome do cluster do ambiente.