Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

We defer the following goals to a future design:

  • Dynamic service account binding during task execution.

  • Revoking a service account in the middle of task execution.

  • ACL support around service accounts (e.g., which group of workflow/dag users can access a particular service account).


High-Level Overview


Our design primarily leverages the admission controller mechanism in Kubernetes for offloading service account configuration when each task Pod is started. The set of service accounts used by Airflow workflows/dags will be injected as secrets in the Kubernetes cluster. In addition, a service account initializer(proposed by ahmetb@google.com and etune@google.com) is started. An initializer is somewhat similar to PodPreset but offers more flexibilities post cluster creation. The service account initializer is a one-time configuration work and does the actual service account Pod-manifest modifications (i.e., volumes, volumeMounts, and GOOGLE_APPLICATION_CREDENTIALS env) based on Pod annotations. The pod annotations, derived from Airflow task properties, are provided by the KubernetesExecutor during task creation.

KubernetesExecutor

Config

The KubernetesExecutor config is extended to include a list of service accounts used:

[kubernetes]
gcp_service_accounts=key_name1=key_path1,key_name2=key_path2,key_name3=key_path3

where key_name is the service account ID (e.g., service-account@xxx.iam.gserviceaccount.com) and key_path saves the service account key file location, accessible from the KubernetesExecutor.

Setup

When the Airflow Scheduler and KubernetesExecutor are initialized, the following steps related to service account management are executed:

  1. Read gcp_service_accounts config and inject these service accounts into Kubernetes cluster as secrets: 

    kubectl create secret generic service-account-name --from-file=key.json=<PATH-TO-KEY-FILE>.json 
  2. Start the service account initializer controller (the controller code will check for uninitialized pod object, modify the Pod manifest to include service account volumes|volumeMounts|GOOGLE_APPLICATION_CREDENTIALS ENV so that k8s master will schedule the Pod): 

    kubectl create -f initializer-controller-deployment.yaml 
  3. Create the service account initializer config: 

    apiVersion: admissionregistration.k8s.io/v1alpha1
    kind: InitializerConfiguration
    Metadata:
      name: example-service-account-config 
    initializers:
    - name: serviceaccounts.google.com
      rules: 
      - apiGroups:
        - "" 
        apiVersions:
        - v1
        resources:
        - pods  

Task Execution

When a task is about to run, the following annotation (if present in task properties) is added to the Pod spec by KubernetesExecutor:

annotations:
  iam.cloud.google.com/service-account: “service-account-name”

Airflow Operator/Task

The GCP service account annotation is specified as part of the task executor_config. Here is a concrete example:

t = BashOperator(
  task_id = ‘account-test’,
  bash_command = ‘gcloud auth application-default login’,
  dag = dag,
  executor_config = {
   ‘gcp-service-account’ : ‘service-account@xxx.iam.gserviceaccount.com
  }
)

Conclusion

In summary, the mechanisms discussed in this doc fulfillsour initial objectives and introduce minimal implementation and configuration complexities. We can easily extended this design to other types of credentials (e.g., AWS access key) by modifying the service account initializer and attaching additional annotations during task Pod creation.