def build_pod_spec(name, bucket, data_dir): metadata = k8s.V1ObjectMeta(name=make_unique_pod_name(name), ) container = k8s.V1Container( name=name, lifecycle=k8s.V1Lifecycle( post_start=k8s.V1Handler(_exec=k8s.V1ExecAction(command=[ "gcsfuse", "--log-file", "/var/log/gcs_fuse.log", "--temp-dir", "/tmp", "--debug_gcs", bucket, data_dir, ])), pre_stop=k8s.V1Handler(_exec=k8s.V1ExecAction( command=["fusermount", "-u", data_dir])), ), security_context=k8s.V1SecurityContext( privileged=True, capabilities=k8s.V1Capabilities(add=["SYS_ADMIN"])), ) pod = k8s.V1Pod(metadata=metadata, spec=k8s.V1PodSpec(containers=[container])) return pod
def _get_init_containers(self) -> List[k8s.V1Container]: """When using git to retrieve the DAGs, use the GitSync Init Container""" # If we're using volume claims to mount the dags, no init container is needed if self.kube_config.dags_volume_claim or \ self.kube_config.dags_volume_host or self.kube_config.dags_in_image: return [] # Otherwise, define a git-sync init container init_environment = [ k8s.V1EnvVar(name='GIT_SYNC_REPO', value=self.kube_config.git_repo), k8s.V1EnvVar(name='GIT_SYNC_BRANCH', value=self.kube_config.git_branch), k8s.V1EnvVar(name='GIT_SYNC_ROOT', value=self.kube_config.git_sync_root), k8s.V1EnvVar(name='GIT_SYNC_DEST', value=self.kube_config.git_sync_dest), k8s.V1EnvVar(name='GIT_SYNC_REV', value=self.kube_config.git_sync_rev), k8s.V1EnvVar(name='GIT_SYNC_DEPTH', value='1'), k8s.V1EnvVar(name='GIT_SYNC_ONE_TIME', value='true') ] if self.kube_config.git_user: init_environment.append( k8s.V1EnvVar(name='GIT_SYNC_USERNAME', value=self.kube_config.git_user)) if self.kube_config.git_password: init_environment.append( k8s.V1EnvVar(name='GIT_SYNC_PASSWORD', value=self.kube_config.git_password)) volume_mounts = [ k8s.V1VolumeMount(mount_path=self.kube_config.git_sync_root, name=self.dags_volume_name, read_only=False) ] if self.kube_config.git_sync_credentials_secret: init_environment.extend([ k8s.V1EnvVar( name='GIT_SYNC_USERNAME', value_from=k8s.V1EnvVarSource( secret_key_ref=k8s.V1SecretKeySelector( name=self.kube_config.git_sync_credentials_secret, key='GIT_SYNC_USERNAME'))), k8s.V1EnvVar( name='GIT_SYNC_PASSWORD', value_from=k8s.V1EnvVarSource( secret_key_ref=k8s.V1SecretKeySelector( name=self.kube_config.git_sync_credentials_secret, key='GIT_SYNC_PASSWORD'))) ]) if self.kube_config.git_ssh_key_secret_name: volume_mounts.append( k8s.V1VolumeMount(name=self.git_sync_ssh_secret_volume_name, mount_path='/etc/git-secret/ssh', sub_path='ssh')) init_environment.extend([ k8s.V1EnvVar(name='GIT_SSH_KEY_FILE', value='/etc/git-secret/ssh'), k8s.V1EnvVar(name='GIT_SYNC_SSH', value='true') ]) if self.kube_config.git_ssh_known_hosts_configmap_name: volume_mounts.append( k8s.V1VolumeMount( name=self.git_sync_ssh_known_hosts_volume_name, mount_path='/etc/git-secret/known_hosts', sub_path='known_hosts')) init_environment.extend([ k8s.V1EnvVar(name='GIT_KNOWN_HOSTS', value='true'), k8s.V1EnvVar(name='GIT_SSH_KNOWN_HOSTS_FILE', value='/etc/git-secret/known_hosts') ]) else: init_environment.append( k8s.V1EnvVar(name='GIT_KNOWN_HOSTS', value='false')) init_containers = k8s.V1Container( name=self.kube_config.git_sync_init_container_name, image=self.kube_config.git_sync_container, env=init_environment, volume_mounts=volume_mounts) if self.kube_config.git_sync_run_as_user != "": init_containers.security_context = k8s.V1SecurityContext( run_as_user=self.kube_config.git_sync_run_as_user ) # git-sync user return [init_containers]
def test_construct_pod_with_mutation(self, mock_uuid): mock_uuid.return_value = self.static_uuid worker_config = k8s.V1Pod( metadata=k8s.V1ObjectMeta(name='gets-overridden-by-dynamic-args', annotations={'should': 'stay'}), spec=k8s.V1PodSpec(containers=[ k8s.V1Container(name='doesnt-override', resources=k8s.V1ResourceRequirements( limits={ 'cpu': '1m', 'memory': '1G' }), security_context=k8s.V1SecurityContext( run_as_user=1)) ])) executor_config = k8s.V1Pod(spec=k8s.V1PodSpec(containers=[ k8s.V1Container(name='doesnt-override-either', resources=k8s.V1ResourceRequirements(limits={ 'cpu': '2m', 'memory': '2G' })) ])) result = PodGenerator.construct_pod( 'dag_id', 'task_id', 'pod_id', 3, 'date', ['command'], executor_config, worker_config, 'namespace', 'uuid', ) sanitized_result = self.k8s_client.sanitize_for_serialization(result) self.metadata.update({'annotations': {'should': 'stay'}}) self.assertEqual( { 'apiVersion': 'v1', 'kind': 'Pod', 'metadata': self.metadata, 'spec': { 'containers': [{ 'args': [], 'command': ['command'], 'env': [], 'envFrom': [], 'name': 'base', 'ports': [], 'resources': { 'limits': { 'cpu': '2m', 'memory': '2G' } }, 'volumeMounts': [], 'securityContext': { 'runAsUser': 1 } }], 'hostNetwork': False, 'imagePullSecrets': [], 'volumes': [] } }, sanitized_result)
mount_path="/data/input", sub_path=None, read_only=True) outputs_volume = k8s.V1Volume( name="outputs-data", persistent_volume_claim=k8s.V1PersistentVolumeClaimVolumeSource( claim_name="force-airflow"), ) outputs_volume_mount = k8s.V1VolumeMount(name="outputs-data", mount_path=OUTPUTS_DATA_PATH, sub_path=None, read_only=False) security_context = k8s.V1SecurityContext(run_as_user=0) experiment_affinity = { "nodeAffinity": { # requiredDuringSchedulingIgnoredDuringExecution means in order # for a pod to be scheduled on a node, the node must have the # specified labels. However, if labels on a node change at # runtime such that the affinity rules on a pod are no longer # met, the pod will still continue to run on the node. "requiredDuringSchedulingIgnoredDuringExecution": { "nodeSelectorTerms": [{ "matchExpressions": [{ # When nodepools are created in Google Kubernetes # Engine, the nodes inside of that nodepool are # automatically assigned the label # 'cloud.google.com/gke-nodepool' with the value of