<p>I'm writing an Airflow DAG using the <code>KubernetesPodOperator</code>. A Python process running in the container must open a file with sensitive data:</p>
<pre><code>with open('credentials/jira_credentials.json', 'r') as f:
    creds = json.load(f)
</code></pre>
<p>and a CloudStorage client must be authenticated:</p>
<pre><code>os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = &quot;credentials/cloud_storage_credentials.json&quot;
</code></pre>
<p>According to the best security practices I don't package a container's image with sensitive data. Instead I use <a href="https://kubernetes.io/docs/concepts/configuration/secret/" rel="nofollow noreferrer">Kubernetes Secrets</a>. Using <a href="https://github.com/kubernetes-client/python" rel="nofollow noreferrer">Python API for Kubernetes</a> I'm trying to mount them as a volume but with no success. The <code>credentials/</code> directory exists in the container but it's empty. What should I do to make files <em>jira_crendentials.json</em> and <em>cloud_storage_credentials.json</em> accessible in the container?</p>
<p>My DAG's code:</p>
<pre><code>from airflow import DAG
from datetime import datetime, timedelta
from airflow.contrib.operators.kubernetes_pod_operator import KubernetesPodOperator
from airflow.kubernetes.secret import Secret
from airflow.kubernetes.volume import Volume
from airflow.kubernetes.volume_mount import VolumeMount
from airflow.operators.dummy_operator import DummyOperator
from kubernetes.client import models as k8s

default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'start_date': datetime.utcnow(),
    'email': ['airflow@example.com'],
    'email_on_failure': False,
    'email_on_retry': False,
    'retry_delay': timedelta(minutes=5)
}

volume = Volume(name=&quot;volume-credentials&quot;, configs={})
volume_mnt = VolumeMount(mount_path=&quot;/credentials&quot;, name=&quot;volume-credentials&quot;, sub_path=&quot;&quot;, read_only=True)

secret_jira_user = Secret(deploy_type=&quot;volume&quot;,
                          deploy_target=&quot;/credentials&quot;,
                          secret=&quot;jira-user-secret&quot;,
                          key=&quot;jira_credentials.json&quot;)
secret_storage_credentials = Secret(deploy_type=&quot;volume&quot;,
                                    deploy_target=&quot;/credentials&quot;,
                                    secret=&quot;jira-trans-projects-cloud-storage-creds&quot;,
                                    key=&quot;cloud_storage_credentials.json&quot;)



dag = DAG(
    dag_id=&quot;jira_translations_project&quot;,
    schedule_interval=&quot;0 1 * * MON&quot;,
    start_date=datetime(2021, 9, 5, 0, 0, 0),
    max_active_runs=1,
    default_args=default_args
)

start = DummyOperator(task_id='START', dag=dag)

passing = KubernetesPodOperator(namespace='default',
                                image=&quot;eu.gcr.io/data-engineering/jira_downloader:v0.18&quot;,
                                cmds=[&quot;/usr/local/bin/run_process.sh&quot;],
                                name=&quot;jira-translation-projects-01&quot;,
                                task_id=&quot;jira-translation-projects-01&quot;,
                                get_logs=True,
                                dag=dag,
                                volumes=[volume],
                                volume_mounts=[volume_mnt],
                                secrets=[
                                    secret_jira_user,
                                    secret_storage_credentials],
                                env_vars={'MIGRATION_DATETIME': '2021-01-02T03:04:05'}, 
                                )

start &gt;&gt; passing
</code></pre>

balkon16
<p>According to <a href="https://github.com/VBhojawala/airflow/blob/k8s-docs/docs/apache-airflow-providers-cncf-kubernetes/operators.rst#mounting-secrets-as-volume" rel="nofollow noreferrer">this</a> example, <code>Secret</code> is a special class that will handle creating volume mounts automatically. Looking at your code, seems that your own volume with mount <code>/credentials</code> is overriding <code>/credentials</code> mount created by <code>Secret</code>, and because you provide empty <code>configs={}</code>, that mount is empty as well.</p>
<p>Try supplying just <code>secrets=[secret_jira_user,secret_storage_credentials]</code> and removing manual <code>volume_mounts</code>.</p>
<hr />
<ul>
<li><a href="https://github.com/apache/airflow/blob/8505d2f0a4524313e3eff7a4f16b9a9439c7a79f/airflow/kubernetes/secret.py#L91-L108" rel="nofollow noreferrer">Code that generates secret volume mounts under the hood</a></li>
</ul>
