[PYTHON] Dinge, die Sie bei der Implementierung von Airflow mit Docker-Compose beachten sollten

Da ich Airflow in meiner persönlichen Studie implementiert habe, werde ich schreiben, was mir damals aufgefallen ist [^ 1]. Ich hoffe, dass weniger Menschen von ähnlichen Problemen abhängig sind.

Annahme

Docker-Bild

Installieren Sie airflow == 1.10.10 basierend auf Python: 3.7.7

AIRFLOW_EXTRAS Es ist ein Plug-In zur Erweiterung des Luftstroms und bietet Zugriff auf GCP von einem DB-System wie MySQL. Das offizielle Dockerfile sagt:

ARG AIRFLOW_EXTRAS="async,aws,azure,celery,dask,elasticsearch,gcp,kubernetes,mysql,postgres,redis,slack,ssh,statsd,virtualenv"

crypto ist praktisch erforderlich, da es zum Generieren von FERNET_KEY benötigt wird. Da wir MySQL für die Backend-Datenbank und psycopg2 für die Verbindung zu Redshift verwenden, benötigen wir auch etwas in Bezug auf diese.

entrypoint.sh

Wie Sie in der Dokumentation (https://airflow.apache.org/docs/stable/howto/secure-connections.html) und im Puckel sehen können, können Sie jetzt einen "FERNET_KEY" generieren, um Ihre Verbindung zu verschlüsseln. Zu. Sicherer als festes Schreiben in airflow.cfg.

: "${AIRFLOW__CORE__FERNET_KEY:=${FERNET_KEY:=$(python -c "from cryptography.fernet import Fernet; FERNET_KEY = Fernet.generate_key().decode(); print(FERNET_KEY)")}}"

Bestätigung des DB-Starts durch den Befehl nc (netcat)

Selbst wenn Sie "abhängige_on: mysql" in "docker-compose.yml" ausführen, wartet es nur auf den Start des Containers und bestätigt nicht, dass die Datenbank gestartet wird. puckel verwendet den Befehl nc in entrypoint.sh, um zu überprüfen, ob eine Verbindung zur DB hergestellt wurde. So etwas ist sehr hilfreich.

wait_for_port() {
  local name="$1" host="$2" port="$3"
  local j=0
  while ! nc -z "$host" "$port" >/dev/null 2>&1 < /dev/null; do
    j=$((j+1))
    if [ $j -ge $TRY_LOOP ]; then
      echo >&2 "$(date) - $host:$port still not reachable, giving up"
      exit 1
    fi
    echo "$(date) - waiting for $name... $j/$TRY_LOOP"
    sleep 5
  done
}

DB-Einstellungen

MySQL-Einstellungen

Legen Sie die folgenden Umgebungsvariablen fest (Referenz). Dies sind die Einstellungen auf der DB-Seite, auf die jedoch über Airflow mit demselben Benutzerkennwort zugegriffen wird.

my.cnf Festlegen von "explizit_defaults_for_timestamp = 1" bei Verwendung von MySQL, wie in der Beschreibung des Airflow-Datenbank-Backends (https://airflow.apache.org/docs/stable/howto/initialize-database.html) beschrieben. Ist notwendig. Fügen Sie außerdem Einstellungen für die Behandlung von Multi-Byte-Zeichen hinzu.

[mysqld]
character-set-server=utf8mb4
explicit_defaults_for_timestamp=1

[client]
default-character-set=utf8mb4

Zugriff auf DB

AIRFLOW__CORE__SQL_ALCHEMY_CONN Der Standardwert ist sqlite, aber ändern Sie ihn entsprechend der Datenbank und dem Treiber. Informationen zum Schreiben finden Sie unter [Dokument] von SqlAlchemy (https://docs.sqlalchemy.org/en/13/core/engines.html).

Der Host ist derjenige, der durch "container_name" in "docker-compose.yml" angegeben wird, und der Port ist im Grunde 3306 für MySQL und 5432 für PostgreSQL. Der Benutzername und der DB-Name sind die oben festgelegten.

Verwendung von Umgebungsvariablen

Wo werden verschiedene Luftstromeinstellungen geschrieben?

Wie in Dokumentation beschrieben, können Einstellungen an mehreren Stellen geschrieben und Umgebungsvariablen priorisiert werden. Zu. Ich möchte Umgebungsvariablen für die AWS-Authentifizierung verwenden. Wenn Sie es statisch machen möchten, z. B. auf die Datenbank zugreifen, können Sie airflow.cfg verwenden. Auf Produktionsebene sollten die Mitglieder die Regeln richtig festlegen.

  1. set as an environment variable
  2. set as a command environment variable
  3. set in airflow.cfg
  4. command in airflow.cfg
  5. Airflow’s built in defaults

Die höheren haben Vorrang.

Wo werden Umgebungsvariablen definiert?

Dies ist auch sehr unterschiedlich. Dies sollte wie folgt priorisiert werden.

  1. Dockerfile: Verwenden Sie die mit wenigen Änderungen, wie die Standardeinstellung
  2. entrypoint.sh: Wie oben
  3. docker-compose.yml: Kann für andere Container geändert werden. Flexibler.
  4. .env-Datei: Wenn in docker-compose.yml als env_file angegeben, wird sie beim Start des Containers gelesen. Schreiben Sie hier das Authentifizierungssystem, das Sie nicht in Git belassen möchten.

DB-Einstellungen und SqlAlchemy-Einstellungen befinden sich in docker-compose.yml

Da dieselben Einstellungen verwendet werden, ist es einfacher zu verwalten und zu warten, wenn der Beschreibungsort identisch ist.

version: "3.7"
services:
    mysql:
        image: mysql:5.7
        container_name: mysql
        environment:
            - MYSQL_ROOT_PASSWORD=password
            - MYSQL_USER=airflow
            - MYSQL_PASSWORD=airflow
            - MYSQL_DATABASE=airflow
        volumes:
            - ./mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro
        ports:
            - "3306:3306"
    airflow:
        build: .
        container_name: airflow
        depends_on:
            - mysql
        environment:
            - AIRFLOW_HOME=/opt/airflow
            - AIRFLOW__CORE__LOAD_EXAMPLES=False
            - AIRFLOW__CORE__EXECUTOR=LocalExecutor
            - AIRFLOW__CORE__SQL_ALCHEMY_CONN=mysql+mysqldb://airflow:airflow@mysql:3306/airflow
            - MYSQL_PORT=3306
            - MYSQL_HOST=mysql
#Abkürzung

AWS- und Redshift-Verbindungen befinden sich in der .env-Datei

Abgesehen von Redshift sind AWS-Zugriffsschlüssel und geheime Schlüssel sehr sensibel, daher möchte ich sie nicht in "docker-compose.yml" oder "entrypoint.sh" schreiben. Bei airflow.cfg gibt es Raum für Überlegungen, in Wirklichkeit kann es sich jedoch um eine Beratung mit dem Entwicklungsteam handeln.

** Derzeit ist es nicht modern, die GUI einzugeben. ** **.

Lesen Sie beim Schreiben Dokumentation und schreiben Sie wie folgt.

Conn Id Conn Type Login Password Host Port Schema Environment Variable
redshift_conn_id postgres awsuser password your-cluster-host 5439 dev AIRFLOW_CONN_REDSHIFT_CONN_ID=postgres://awsuser:password@your-cluster-host:5439/dev
aws_conn_id aws your-access-key your-secret-key AIRFLOW_CONN_AWS_CONN_ID=aws://your-access-key:your-secret-key@

Selbst wenn die ID niedrig ist, ist der Name der Umgebungsvariablen hoch.

Für AWS-Schlüssel müssen Sie am Ende @ hinzufügen, auch wenn kein Host vorhanden ist. Andernfalls tritt ein Fehler auf. Wenn der Schlüssel einen Doppelpunkt oder Schrägstrich enthält, wird er nicht gut analysiert. Daher ist es besser, den Schlüssel neu zu generieren.

Im Gegenteil, Ich wollte das URI-Format der Verbindung kennen, das in die GUI usw. eingegeben wurde. Sie können wie folgt ausgeben.

from airflow.hooks.base_hook import BaseHook

conn = BaseHook.get_connection('postgres_conn_id')
print(f"AIRFLOW_CONN_{conn.conn_id.upper()}='{conn.get_uri()}'")

Stellen Sie den Luftstromschlüsselwert mit der Umgebungsvariablen ein

Wie bei Verbindungen können Sie Schlüsselwert festlegen. Als Methode

  1. Mit GUI einstellen
  2. Mit .py Code einstellen.
  3. Mit Umgebungsvariablen festlegen

Für Code

from airflow.models import Variable
Variable.set(key="foo", value="bar")

Für Umgebungsvariablen

Key Value Environment Variable
foo bar AIRFLOW_VAR_FOO=bar

Selbst wenn der Schlüssel niedriger ist, ist der Name der Umgebungsvariablen höher.

das Ende

Vorerst möchte ich das [Repository] vorstellen (https://github.com/ieiriyuki/ud_data_engineer/tree/master/project5).

[^ 1]: Ich bin ein Data Engineer von Udacity. Ich berührte Cassandra, Redshift, Spark, Airflow. Es wurde gesagt, dass es 5 Monate dauern würde, aber es endete in 3 Monaten, daher scheint es besser, einen monatlichen Vertrag zu unterschreiben. Außerdem erhalten Sie regelmäßig 50% Rabatt. Es wird daher empfohlen, sich zu diesem Zweck anzumelden. ~~ Sonst Takasugi ~~

[^ 2]: Als ich beim Schreiben eines Artikels Apache / Airflow: 11.1010 berührte, schien es relativ glatt zu sein. Wenn Sie "Docker Run -it - Name Test -p 8080 -d Apache / Airflow: 11.1010" "" ausführen, beginnt es mit "Bash" geöffnet, so dass es flexibel ist, wie "Docker Exec Test Airflow Initdb". Sie können es bedienen.

Recommended Posts

Dinge, die Sie bei der Implementierung von Airflow mit Docker-Compose beachten sollten
Worüber ich mir Sorgen gemacht habe, als ich Bilder mit matplotlib angezeigt habe
[Ansible] Worauf ich beim Schreiben von Ansible achten muss
[Go language] Seien Sie vorsichtig, wenn Sie einen Server mit mux + cors + alice erstellen. Besonders darüber, wovon ich in Bezug auf CORS süchtig war.
Wovon ich süchtig war, als ich Python Tornado benutzte
Was ich getan habe, als ich wütend war, es mit der Option enable-shared einzufügen
Wovon ich süchtig war, als ich mit riesigen Dateien in einer Linux 32-Bit-Umgebung umging
Wovon ich süchtig war, als der Processing-Benutzer zu Python wechselte
Was ich über Linux gelernt habe
Was wurde gefragt, wenn Random Forest in der Praxis verwendet wurde?
Wovon ich süchtig war, als ich ALE in Vim für Python einführte
Was ich mit json.dumps in Pythons base64-Codierung süchtig gemacht habe
Ich stieß auf einen Lambda-Ausdruck, als ich mir Sorgen um die Funktionalisierung machte
Ich habe versucht zusammenzufassen, was mit Qiita mit Word Cloud ausgegeben wurde
Ein Hinweis, dem ich beim Erstellen einer Tabelle mit SQL Alchemy verfallen war
Worauf ich bei der Verwendung von Airflow gestoßen bin
Wo ich mir Sorgen um Heroku machte
Was war überraschend an Python-Klassen?
Ich habe versucht, DeepPose mit PyTorch zu implementieren
Was ich über Qiitas Post überprüft habe
Über das Starten einer Instanz mit einem verschlüsselten EBS-Volume (wo ich süchtig war)
Da die Handhabung der Cython-Form mühsam war, fasste ich die Punkte zusammen, bei denen ich vorsichtig war
Eine Erinnerung an das, was ich beim Starten von Atcoder mit Python feststeckte
Worauf ich mich bei der Verwendung von Tensorflow-gpu eingelassen habe
Worauf ich mich beim Studium von tkinter bezog
Ich habe versucht, DeepPose mit PyTorch PartⅡ zu implementieren
Was ich mit Python-Arrays gemacht habe
Was ich süchtig nach Python Autorun war
Seien Sie vorsichtig, wenn Sie CakePHP3 mit PHP7.2 ausführen
Wovon ich beim Erstellen von Webanwendungen in einer Windows-Umgebung abhängig war
Ich habe beim Clustering mit k-means versagt, aber was soll ich tun (Implementierung des Kernels k-means)
Was ich getan habe, als ich mit Lambda Python im Zeitlimit steckte
Drei Dinge, von denen ich süchtig war, als ich Python und MySQL mit Docker verwendete
Ein Hinweis, dem ich beim Ausführen von Python mit Visual Studio Code verfallen war
Eine Geschichte, der ich nach der SFTP-Kommunikation mit Python verfallen war