ΠΠΎΡΠΎΠ³ΠΈΠ΅ ΡΠΈΡΠ°ΡΠ΅Π»ΠΈ, Π΄ΠΎΠ±ΡΠΎΠ³ΠΎ Π΄Π½Ρ. Π‘Π΅Π³ΠΎΠ΄Π½Ρ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡΠΈΠΌ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎ Apache Spark ΠΈ Π΅Π³ΠΎ ΠΏΠ΅ΡΡΠΏΠ΅ΠΊΡΠΈΠ²Ρ ΡΠ°Π·Π²ΠΈΡΠΈΡ.
Π ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΌ ΠΌΠΈΡΠ΅ Big Data Apache Spark ΡΠ²Π»ΡΠ΅ΡΡΡ Π΄Π΅ ΡΠ°ΠΊΡΠΎ ΡΡΠ°Π½Π΄Π°ΡΡΠΎΠΌ ΠΏΡΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ΅ Π·Π°Π΄Π°Ρ ΠΏΠ°ΠΊΠ΅ΡΠ½ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ Π΄Π°Π½Π½ΡΡ
. ΠΠΎΠΌΠΈΠΌΠΎ ΡΡΠΎΠ³ΠΎ, ΠΎΠ½ ΡΠ°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΡΡΠΈΠΌΠΈΠ½Π³ΠΎΠ²ΡΡ
ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΡΠ°Π±ΠΎΡΠ°ΡΡΠΈΡ
Π² ΠΊΠΎΠ½ΡΠ΅ΠΏΡΠΈΠΈ micro batch, ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡΠΈΡ
ΠΈ ΠΎΡΠ³ΡΡΠΆΠ°ΡΡΠΈΡ
Π΄Π°Π½Π½ΡΠ΅ ΠΌΠ°Π»Π΅Π½ΡΠΊΠΈΠΌΠΈ ΠΏΠΎΡΡΠΈΡΠΌΠΈ (Spark Structured Streaming). Π ΡΡΠ°Π΄ΠΈΡΠΈΠΎΠ½Π½ΠΎ ΠΎΠ½ ΡΠ²Π»ΡΠ»ΡΡ ΡΠ°ΡΡΡΡ ΠΎΠ±ΡΠ΅Π³ΠΎ ΡΡΠ΅ΠΊΠ° Hadoop, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅ΡΠ° ΡΠ΅ΡΡΡΡΠΎΠ² YARN (ΠΈΠ»ΠΈ, Π² Π½Π΅ΠΊΠΎΡΠΎΡΡΡ
ΡΠ»ΡΡΠ°ΡΡ
, Apache Mesos). Π 2020 Π³ΠΎΠ΄Ρ Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π² ΡΡΠ°Π΄ΠΈΡΠΈΠΎΠ½Π½ΠΎΠΌ Π²ΠΈΠ΄Π΅ Π΄Π»Ρ Π±ΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²Π° ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΉ Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡΡ ΠΏΠΎΠ΄ Π±ΠΎΠ»ΡΡΠΈΠΌ Π²ΠΎΠΏΡΠΎΡΠΎΠΌ Π² Π²ΠΈΠ΄Ρ ΠΎΡΡΡΡΡΡΠ²ΠΈΡ ΠΏΡΠΈΠ»ΠΈΡΠ½ΡΡ
Π΄ΠΈΡΡΡΠΈΠ±ΡΡΠΈΠ²ΠΎΠ² Hadoop β ΡΠ°Π·Π²ΠΈΡΠΈΠ΅ HDP ΠΈ CDH ΠΎΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΎ, CDH Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΏΡΠΎΡΠ°Π±ΠΎΡΠ°Π½ ΠΈ ΠΈΠΌΠ΅Π΅Ρ Π²ΡΡΠΎΠΊΡΡ ΡΡΠΎΠΈΠΌΠΎΡΡΡ, Π° ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅ ΠΏΠΎΡΡΠ°Π²ΡΠΈΠΊΠΈ Hadoop Π»ΠΈΠ±ΠΎ ΠΏΡΠ΅ΠΊΡΠ°ΡΠΈΠ»ΠΈ ΡΠ²ΠΎΡ ΡΡΡΠ΅ΡΡΠ²ΠΎΠ²Π°Π½ΠΈΠ΅, Π»ΠΈΠ±ΠΎ ΠΈΠΌΠ΅ΡΡ ΡΡΠΌΠ°Π½Π½ΠΎΠ΅ Π±ΡΠ΄ΡΡΠ΅Π΅. ΠΠΎΡΡΠΎΠΌΡ Π²ΡΡ Π±ΠΎΠ»ΡΡΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΠ΅Ρ Ρ ΡΠΎΠΎΠ±ΡΠ΅ΡΡΠ²Π° ΠΈ ΠΊΡΡΠΏΠ½ΡΡ
ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΉ Π²ΡΠ·ΡΠ²Π°Π΅Ρ Π·Π°ΠΏΡΡΠΊ Apache Spark Ρ ΠΏΠΎΠΌΠΎΡΡΡ Kubernetes β ΡΡΠ°Π² ΡΡΠ°Π½Π΄Π°ΡΡΠΎΠΌ Π² ΠΎΡΠΊΠ΅ΡΡΡΠ°ΡΠΈΠΈ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΎΠ² ΠΈ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠΈ ΡΠ΅ΡΡΡΡΠ°ΠΌΠΈ Π² ΠΏΡΠΈΠ²Π°ΡΠ½ΡΡ
ΠΈ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΡ
ΠΎΠ±Π»Π°ΠΊΠ°Ρ
, ΠΎΠ½ ΡΠ΅ΡΠ°Π΅Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Ρ Π½Π΅ΡΠ΄ΠΎΠ±Π½ΡΠΌ ΠΏΠ»Π°Π½ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΠ΅ΡΡΡΡΠΎΠ² Π·Π°Π΄Π°Ρ Spark Π½Π° YARN ΠΈ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΡΠ°Π±ΠΈΠ»ΡΠ½ΠΎ ΡΠ°Π·Π²ΠΈΠ²Π°ΡΡΡΡΡΡ ΠΏΠ»Π°ΡΡΠΎΡΠΌΡ Ρ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎΠΌ ΠΊΠΎΠΌΠΌΠ΅ΡΡΠ΅ΡΠΊΠΈΡ
ΠΈ ΠΎΡΠΊΡΡΡΡΡ
Π΄ΠΈΡΡΡΠΈΠ±ΡΡΠΈΠ²ΠΎΠ² Π΄Π»Ρ ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΉ Π²ΡΠ΅Ρ
ΡΠ°Π·ΠΌΠ΅ΡΠΎΠ² ΠΈ ΠΌΠ°ΡΡΠ΅ΠΉ. Π ΡΠΎΠΌΡ ΠΆΠ΅ Π½Π° Π²ΠΎΠ»Π½Π΅ ΠΏΠΎΠΏΡΠ»ΡΡΠ½ΠΎΡΡΠΈ Π±ΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²ΠΎ ΡΠΆΠ΅ ΡΡΠΏΠ΅Π»ΠΎ ΠΎΠ±Π·Π°Π²Π΅ΡΡΠΈΡΡ ΠΏΠ°ΡΠΎΠΉ-ΡΡΠΎΠΉΠΊΠΎΠΉ ΡΠ²ΠΎΠΈΡ
ΠΈΠ½ΡΡΠ°Π»Π»ΡΡΠΈΠΉ ΠΈ Π½Π°ΡΠ°ΡΡΠΈΡΡ ΡΠΊΡΠΏΠ΅ΡΡΠΈΠ·Ρ Π² Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ, ΡΡΠΎ ΡΠΏΡΠΎΡΠ°Π΅Ρ ΠΏΠ΅ΡΠ΅Π΅Π·Π΄.
ΠΠ°ΡΠΈΠ½Π°Ρ Ρ Π²Π΅ΡΡΠΈΠΈ 2.3.0 Apache Spark ΠΎΠ±Π·Π°Π²ΡΠ»ΡΡ ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠΉ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΎΠΉ Π·Π°ΠΏΡΡΠΊΠ° Π·Π°Π΄Π°Ρ Π² ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ Kubernetes ΠΈ ΡΠ΅Π³ΠΎΠ΄Π½Ρ, ΠΌΡ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡΠΈΠΌ ΠΎ ΡΠ΅ΠΊΡΡΠ΅ΠΉ Π·ΡΠ΅Π»ΠΎΡΡΠΈ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄Π°, ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ
Π²Π°ΡΠΈΠ°Π½ΡΠ°Ρ
Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΈ ΠΏΠΎΠ΄Π²ΠΎΠ΄Π½ΡΡ
ΠΊΠ°ΠΌΠ½ΡΡ
, Ρ ΠΊΠΎΡΠΎΡΡΠΌΠΈ ΠΏΡΠ΅Π΄ΡΡΠΎΠΈΡ ΡΡΠΎΠ»ΠΊΠ½ΡΡΡΡΡ ΠΏΡΠΈ Π²Π½Π΅Π΄ΡΠ΅Π½ΠΈΠΈ.
ΠΡΠ΅ΠΆΠ΄Π΅ Π²ΡΠ΅Π³ΠΎ, ΡΠ°ΡΡΠΌΠΎΡΡΠΈΠΌ ΠΏΡΠΎΡΠ΅ΡΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ Π·Π°Π΄Π°Ρ ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π° Π±Π°Π·Π΅ Apache Spark ΠΈ Π²ΡΠ΄Π΅Π»ΠΈΠΌ ΡΠΈΠΏΠΎΠ²ΡΠ΅ ΡΠ»ΡΡΠ°ΠΈ, Π² ΠΊΠΎΡΠΎΡΡΡ
ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π·Π°ΠΏΡΡΡΠΈΡΡ Π·Π°Π΄Π°ΡΡ Π½Π° ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ Kubernetes. ΠΡΠΈ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΊΠ΅ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΡΠ° Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π΄ΠΈΡΡΡΠΈΠ±ΡΡΠΈΠ²Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ OpenShift ΠΈ Π±ΡΠ΄ΡΡ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Ρ ΠΊΠΎΠΌΠ°Π½Π΄Ρ, Π°ΠΊΡΡΠ°Π»ΡΠ½ΡΠ΅ Π΄Π»Ρ Π΅Π³ΠΎ ΡΡΠΈΠ»ΠΈΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ (oc). ΠΠ»Ρ Π΄ΡΡΠ³ΠΈΡ
Π΄ΠΈΡΡΡΠΈΠ±ΡΡΠΈΠ²ΠΎΠ² Kubernetes ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΉ ΡΡΠΈΠ»ΠΈΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ Kubernetes (kubectl) Π»ΠΈΠ±ΠΎ ΠΈΡ
Π°Π½Π°Π»ΠΎΠ³ΠΈ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π΄Π»Ρ oc adm policy).
ΠΠ΅ΡΠ²ΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ β spark-submit
Π ΠΏΡΠΎΡΠ΅ΡΡΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ Π·Π°Π΄Π°Ρ ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΡ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ Π·Π°Π΄Π°ΡΠΈ Π΄Π»Ρ ΠΎΡΠ»Π°Π΄ΠΊΠΈ ΡΡΠ°Π½ΡΡΠΎΡΠΌΠ°ΡΠΈΠΈ Π΄Π°Π½Π½ΡΡ . Π’Π΅ΠΎΡΠ΅ΡΠΈΡΠ΅ΡΠΊΠΈ Π΄Π»Ρ ΡΡΠΈΡ ΡΠ΅Π»Π΅ΠΉ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Ρ Π·Π°Π³Π»ΡΡΠΊΠΈ, Π½ΠΎ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ° Ρ ΡΡΠ°ΡΡΠΈΠ΅ΠΌ ΡΠ΅Π°Π»ΡΠ½ΡΡ (ΠΏΡΡΡΡ ΠΈ ΡΠ΅ΡΡΠΎΠ²ΡΡ ) ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠ² ΠΊΠΎΠ½Π΅ΡΠ½ΡΡ ΡΠΈΡΡΠ΅ΠΌ, ΠΏΠΎΠΊΠ°Π·Π°Π»Π° ΡΠ΅Π±Ρ Π² ΡΡΠΎΠΌ ΠΊΠ»Π°ΡΡΠ΅ Π·Π°Π΄Π°Ρ Π±ΡΡΡΡΠ΅Π΅ ΠΈ ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅Π½Π½Π΅Π΅. Π ΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅, ΠΊΠΎΠ³Π΄Π° ΠΌΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠΌ ΠΎΡΠ»Π°Π΄ΠΊΡ Π½Π° ΡΠ΅Π°Π»ΡΠ½ΡΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°Ρ ΠΊΠΎΠ½Π΅ΡΠ½ΡΡ ΡΠΈΡΡΠ΅ΠΌ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ Π΄Π²Π° ΡΡΠ΅Π½Π°ΡΠΈΡ ΡΠ°Π±ΠΎΡΡ:
- ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊ Π·Π°ΠΏΡΡΠΊΠ°Π΅Ρ Π·Π°Π΄Π°ΡΡ Spark Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ standalone;
- ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊ Π·Π°ΠΏΡΡΠΊΠ°Π΅Ρ Π·Π°Π΄Π°ΡΡ Spark Π½Π° ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ Kubernetes Π² ΡΠ΅ΡΡΠΎΠ²ΠΎΠΌ ΠΊΠΎΠ½ΡΡΡΠ΅.
ΠΠ΅ΡΠ²ΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ ΠΈΠΌΠ΅Π΅Ρ ΠΏΡΠ°Π²ΠΎ Π½Π° ΡΡΡΠ΅ΡΡΠ²ΠΎΠ²Π°Π½ΠΈΠ΅, Π½ΠΎ Π²Π»Π΅ΡΡΡ Π·Π° ΡΠΎΠ±ΠΎΠΉ ΡΡΠ΄ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΊΠΎΠ²:
- Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΡΡ Π΄ΠΎΡΡΡΠΏ Ρ ΡΠ°Π±ΠΎΡΠ΅Π³ΠΎ ΠΌΠ΅ΡΡΠ° Π΄ΠΎ Π²ΡΠ΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΡ Π΅ΠΌΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠ² ΠΊΠΎΠ½Π΅ΡΠ½ΡΡ ΡΠΈΡΡΠ΅ΠΌ;
- Π½Π° ΡΠ°Π±ΠΎΡΠ΅ΠΉ ΠΌΠ°ΡΠΈΠ½Π΅ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠ΅ΡΡΡΡΠΎΠ² Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ° ΡΠ°Π·ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌΠΎΠΉ Π·Π°Π΄Π°ΡΠΈ.
ΠΡΠΎΡΠΎΠΉ Π²Π°ΡΠΈΠ°Π½Ρ Π»ΠΈΡΡΠ½ Π΄Π°Π½Π½ΡΡ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΊΠΎΠ², ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠ»Π°ΡΡΠ΅ΡΠ° Kubernetes ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π²ΡΠ΄Π΅Π»ΠΈΡΡ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠΉ ΠΏΡΠ» ΡΠ΅ΡΡΡΡΠΎΠ² Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ° Π·Π°Π΄Π°Ρ ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΡΡ Π΄Π»Ρ Π½Π΅Π³ΠΎ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ Π΄ΠΎΡΡΡΠΏΡ ΠΊ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°ΠΌ ΠΊΠΎΠ½Π΅ΡΠ½ΡΡ ΡΠΈΡΡΠ΅ΠΌ, Π³ΠΈΠ±ΠΊΠΎ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΡ ΠΊ Π½Π΅ΠΌΡ Π΄ΠΎΡΡΡΠΏ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠΎΠ»Π΅Π²ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ Kubernetes Π΄Π»Ρ Π²ΡΠ΅Ρ ΡΠ»Π΅Π½ΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ. ΠΡΠ΄Π΅Π»ΠΈΠΌ Π΅Π³ΠΎ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ Π²Π°ΡΠΈΠ°Π½ΡΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ β Π·Π°ΠΏΡΡΠΊ Π·Π°Π΄Π°Ρ Spark Ρ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠΉ ΠΌΠ°ΡΠΈΠ½Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° Π½Π° ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ Kubernetes Π² ΡΠ΅ΡΡΠΎΠ²ΠΎΠΌ ΠΊΠΎΠ½ΡΡΡΠ΅.
Π Π°ΡΡΠΊΠ°ΠΆΠ΅ΠΌ ΠΏΠΎΠ΄ΡΠΎΠ±Π½Π΅Π΅ ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ΅ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ Spark Π΄Π»Ρ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠ³ΠΎ Π·Π°ΠΏΡΡΠΊΠ°. Π§ΡΠΎΠ±Ρ Π½Π°ΡΠ°ΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Spark Π΅Π³ΠΎ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ:
mkdir /opt/spark
cd /opt/spark
wget http://mirror.linux-ia64.org/apache/spark/spark-2.4.5/spark-2.4.5.tgz
tar zxvf spark-2.4.5.tgz
rm -f spark-2.4.5.tgz
Π‘ΠΎΠ±ΠΈΡΠ°Π΅ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ ΠΏΠ°ΠΊΠ΅ΡΡ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ Kubernetes:
cd spark-2.4.5/
./build/mvn -Pkubernetes -DskipTests clean package
ΠΠΎΠ»Π½Π°Ρ ΡΠ±ΠΎΡΠΊΠ° Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ ΠΌΠ½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, Π° Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΎΠ±ΡΠ°Π·ΠΎΠ² Docker ΠΈ ΠΈΡ Π·Π°ΠΏΡΡΠΊΠ° Π½Π° ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ Kubernetes Π² ΡΠ΅Π°Π»ΡΠ½ΠΎΡΡΠΈ Π½ΡΠΆΠ½Ρ ΡΠΎΠ»ΡΠΊΠΎ jar ΡΠ°ΠΉΠ»Ρ ΠΈΠ· Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ Β«assembly/Β», ΠΏΠΎΡΡΠΎΠΌΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ±ΡΠ°ΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π°Π½Π½ΡΠΉ ΠΏΠΎΠ΄ΠΏΡΠΎΠ΅ΠΊΡ:
./build/mvn -f ./assembly/pom.xml -Pkubernetes -DskipTests clean package
ΠΠ»Ρ Π·Π°ΠΏΡΡΠΊΠ° Π·Π°Π΄Π°Ρ Spark Π² Kubernetes ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΠΎΠ·Π΄Π°ΡΡ ΠΎΠ±ΡΠ°Π· Docker, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ. ΠΠ΄Π΅ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ 2 ΠΏΠΎΠ΄Ρ ΠΎΠ΄Π°:
- Π‘ΠΎΠ·Π΄Π°Π½Π½ΡΠΉ ΠΎΠ±ΡΠ°Π· Docker Π²ΠΊΠ»ΡΡΠ°Π΅Ρ Π² ΡΠ΅Π±Ρ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΠΊΠΎΠ΄ Π·Π°Π΄Π°ΡΠΈ Spark;
- Π‘ΠΎΠ·Π΄Π°Π½Π½ΡΠΉ ΠΎΠ±ΡΠ°Π· Π²ΠΊΠ»ΡΡΠ°Π΅Ρ Π² ΡΠ΅Π±Ρ ΡΠΎΠ»ΡΠΊΠΎ Spark ΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ, ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΠΊΠΎΠ΄ ΡΠ°Π·ΠΌΠ΅ΡΠ°Π΅ΡΡΡ ΡΠ΄Π°Π»ΡΠ½Π½ΠΎ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π² HDFS).
ΠΠ»Ρ Π½Π°ΡΠ°Π»Π° ΡΠΎΠ±Π΅ΡΡΠΌ ΠΎΠ±ΡΠ°Π· Docker, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠΉ ΡΠ΅ΡΡΠΎΠ²ΡΠΉ ΠΏΡΠΈΠΌΠ΅Ρ Π·Π°Π΄Π°ΡΠΈ Spark. ΠΠ»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΎΠ±ΡΠ°Π·ΠΎΠ² Docker Ρ Spark Π΅ΡΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ°Ρ ΡΡΠΈΠ»ΠΈΡΠ° ΠΏΠΎΠ΄ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ Β«docker-image-toolΒ». ΠΠ·ΡΡΠΈΠΌ ΠΏΠΎ Π½Π΅ΠΉ ΡΠΏΡΠ°Π²ΠΊΡ:
./bin/docker-image-tool.sh --help
Π‘ Π΅Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΠΎΠ±ΡΠ°Π·Ρ Docker ΠΈ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΡΡ ΠΈΡ Π·Π°Π³ΡΡΠ·ΠΊΡ Π² ΡΠ΄Π°Π»ΡΠ½Π½ΡΠ΅ ΡΠ΅Π΅ΡΡΡΡ, Π½ΠΎ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΠΎΠ½Π° ΠΈΠΌΠ΅Π΅Ρ ΡΡΠ΄ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΊΠΎΠ²:
- Π² ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎΠΌ ΠΏΠΎΡΡΠ΄ΠΊΠ΅ ΡΠΎΠ·Π΄Π°ΡΡ ΡΡΠ°Π·Ρ 3 ΠΎΠ±ΡΠ°Π·Π° Docker β ΠΏΠΎΠ΄ Spark, PySpark ΠΈ R;
- Π½Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠΊΠ°Π·Π°ΡΡ ΠΈΠΌΡ ΠΎΠ±ΡΠ°Π·Π°.
ΠΠΎΡΡΠΎΠΌΡ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΌΠΎΠ΄ΠΈΡΠΈΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ Π΄Π°Π½Π½ΠΎΠΉ ΡΡΠΈΠ»ΠΈΡΡ, ΠΏΡΠΈΠ²Π΅Π΄ΡΠ½Π½ΡΠΉ Π½ΠΈΠΆΠ΅:
vi bin/docker-image-tool-upd.sh
#!/usr/bin/env bash
function error {
echo "$@" 1>&2
exit 1
}
if [ -z "${SPARK_HOME}" ]; then
SPARK_HOME="$(cd "`dirname "$0"`"/..; pwd)"
fi
. "${SPARK_HOME}/bin/load-spark-env.sh"
function image_ref {
local image="$1"
local add_repo="${2:-1}"
if [ $add_repo = 1 ] && [ -n "$REPO" ]; then
image="$REPO/$image"
fi
if [ -n "$TAG" ]; then
image="$image:$TAG"
fi
echo "$image"
}
function build {
local BUILD_ARGS
local IMG_PATH
if [ ! -f "$SPARK_HOME/RELEASE" ]; then
IMG_PATH=$BASEDOCKERFILE
BUILD_ARGS=(
${BUILD_PARAMS}
--build-arg
img_path=$IMG_PATH
--build-arg
datagram_jars=datagram/runtimelibs
--build-arg
spark_jars=assembly/target/scala-$SPARK_SCALA_VERSION/jars
)
else
IMG_PATH="kubernetes/dockerfiles"
BUILD_ARGS=(${BUILD_PARAMS})
fi
if [ -z "$IMG_PATH" ]; then
error "Cannot find docker image. This script must be run from a runnable distribution of Apache Spark."
fi
if [ -z "$IMAGE_REF" ]; then
error "Cannot find docker image reference. Please add -i arg."
fi
local BINDING_BUILD_ARGS=(
${BUILD_PARAMS}
--build-arg
base_img=$(image_ref $IMAGE_REF)
)
local BASEDOCKERFILE=${BASEDOCKERFILE:-"$IMG_PATH/spark/docker/Dockerfile"}
docker build $NOCACHEARG "${BUILD_ARGS[@]}"
-t $(image_ref $IMAGE_REF)
-f "$BASEDOCKERFILE" .
}
function push {
docker push "$(image_ref $IMAGE_REF)"
}
function usage {
cat <<EOF
Usage: $0 [options] [command]
Builds or pushes the built-in Spark Docker image.
Commands:
build Build image. Requires a repository address to be provided if the image will be
pushed to a different registry.
push Push a pre-built image to a registry. Requires a repository address to be provided.
Options:
-f file Dockerfile to build for JVM based Jobs. By default builds the Dockerfile shipped with Spark.
-p file Dockerfile to build for PySpark Jobs. Builds Python dependencies and ships with Spark.
-R file Dockerfile to build for SparkR Jobs. Builds R dependencies and ships with Spark.
-r repo Repository address.
-i name Image name to apply to the built image, or to identify the image to be pushed.
-t tag Tag to apply to the built image, or to identify the image to be pushed.
-m Use minikube's Docker daemon.
-n Build docker image with --no-cache
-b arg Build arg to build or push the image. For multiple build args, this option needs to
be used separately for each build arg.
Using minikube when building images will do so directly into minikube's Docker daemon.
There is no need to push the images into minikube in that case, they'll be automatically
available when running applications inside the minikube cluster.
Check the following documentation for more information on using the minikube Docker daemon:
https://kubernetes.io/docs/getting-started-guides/minikube/#reusing-the-docker-daemon
Examples:
- Build image in minikube with tag "testing"
$0 -m -t testing build
- Build and push image with tag "v2.3.0" to docker.io/myrepo
$0 -r docker.io/myrepo -t v2.3.0 build
$0 -r docker.io/myrepo -t v2.3.0 push
EOF
}
if [[ "$@" = *--help ]] || [[ "$@" = *-h ]]; then
usage
exit 0
fi
REPO=
TAG=
BASEDOCKERFILE=
NOCACHEARG=
BUILD_PARAMS=
IMAGE_REF=
while getopts f:mr:t:nb:i: option
do
case "${option}"
in
f) BASEDOCKERFILE=${OPTARG};;
r) REPO=${OPTARG};;
t) TAG=${OPTARG};;
n) NOCACHEARG="--no-cache";;
i) IMAGE_REF=${OPTARG};;
b) BUILD_PARAMS=${BUILD_PARAMS}" --build-arg "${OPTARG};;
esac
done
case "${@: -1}" in
build)
build
;;
push)
if [ -z "$REPO" ]; then
usage
exit 1
fi
push
;;
*)
usage
exit 1
;;
esac
Π‘ Π΅Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠΎΠ±ΠΈΡΠ°Π΅ΠΌ Π±Π°Π·ΠΎΠ²ΡΠΉ ΠΎΠ±ΡΠ°Π· Spark, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠΉ Π² ΡΠ΅Π±Π΅ ΡΠ΅ΡΡΠΎΠ²ΡΡ Π·Π°Π΄Π°ΡΡ Π΄Π»Ρ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ ΡΠΈΡΠ»Π° Pi Ρ ΠΏΠΎΠΌΠΎΡΡΡ Spark (Π·Π΄Π΅ΡΡ {docker-registry-url} β URL Π²Π°ΡΠ΅Π³ΠΎ ΡΠ΅Π΅ΡΡΡΠ° ΠΎΠ±ΡΠ°Π·ΠΎΠ² Docker, {repo} β ΠΈΠΌΡ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ Π²Π½ΡΡΡΠΈ ΡΠ΅Π΅ΡΡΡΠ°, ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡΡΠ΅Π΅ Ρ ΠΏΡΠΎΠ΅ΠΊΡΠΎΠΌ Π² OpenShift, {image-name} β ΠΈΠΌΡ ΠΎΠ±ΡΠ°Π·Π° (Π΅ΡΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΡΡΡ ΡΡΠΎΠ²Π½Π΅Π²ΠΎΠ΅ ΡΠ°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ°Π·ΠΎΠ², Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΊΠ°ΠΊ Π² ΠΈΠ½ΡΠ΅Π³ΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΌ ΡΠ΅Π΅ΡΡΡΠ΅ ΠΎΠ±ΡΠ°Π·ΠΎΠ² Red Hat OpenShift), {tag} β ΡΠ΅Π³ Π΄Π°Π½Π½ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ ΠΎΠ±ΡΠ°Π·Π°):
./bin/docker-image-tool-upd.sh -f resource-managers/kubernetes/docker/src/main/dockerfiles/spark/Dockerfile -r {docker-registry-url}/{repo} -i {image-name} -t {tag} build
ΠΠ²ΡΠΎΡΠΈΠ·ΡΠ΅ΠΌΡΡ Π² ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ OKD Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΊΠΎΠ½ΡΠΎΠ»ΡΠ½ΠΎΠΉ ΡΡΠΈΠ»ΠΈΡΡ (Π·Π΄Π΅ΡΡ {OKD-API-URL} β URL API ΠΊΠ»Π°ΡΡΠ΅ΡΠ° OKD):
oc login {OKD-API-URL}
ΠΠΎΠ»ΡΡΠΈΠΌ ΡΠΎΠΊΠ΅Π½ ΡΠ΅ΠΊΡΡΠ΅Π³ΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π΄Π»Ρ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΈ Π² Docker Registry:
oc whoami -t
ΠΠ²ΡΠΎΡΠΈΠ·ΡΠ΅ΠΌΡΡ Π²ΠΎ Π²Π½ΡΡΡΠ΅Π½Π½Π΅ΠΌ Docker Registry ΠΊΠ»Π°ΡΡΠ΅ΡΠ° OKD (Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΏΠ°ΡΠΎΠ»Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΠΎΠΊΠ΅Π½, ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΡΠΉ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ):
docker login {docker-registry-url}
ΠΠ°Π³ΡΡΠ·ΠΈΠΌ ΡΠΎΠ±ΡΠ°Π½Π½ΡΠΉ ΠΎΠ±ΡΠ°Π· Docker Π² Docker Registry OKD:
./bin/docker-image-tool-upd.sh -r {docker-registry-url}/{repo} -i {image-name} -t {tag} push
ΠΡΠΎΠ²Π΅ΡΠΈΠΌ, ΡΡΠΎ ΡΠΎΠ±ΡΠ°Π½Π½ΡΠΉ ΠΎΠ±ΡΠ°Π· Π΄ΠΎΡΡΡΠΏΠ΅Π½ Π² OKD. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ ΠΎΡΠΊΡΠΎΠ΅ΠΌ Π² Π±ΡΠ°ΡΠ·Π΅ΡΠ΅ URL ΡΠΎ ΡΠΏΠΈΡΠΊΠΎΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠ² ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ° (Π·Π΄Π΅ΡΡ {project} β ΠΈΠΌΡ ΠΏΡΠΎΠ΅ΠΊΡΠ° Π²Π½ΡΡΡΠΈ ΠΊΠ»Π°ΡΡΠ΅ΡΠ° OpenShift, {OKD-WEBUI-URL} β URL Web ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ OpenShift) β https://{OKD-WEBUI-URL}/console/project/{project}/browse/images/{image-name}.
ΠΠ»Ρ Π·Π°ΠΏΡΡΠΊΠ° Π·Π°Π΄Π°Ρ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΡΠΎΠ·Π΄Π°Π½ ΡΠ΅ΡΠ²ΠΈΡΠ½ΡΠΉ Π°ΠΊΠΊΠ°ΡΠ½Ρ Ρ ΠΏΡΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΡΠΌΠΈ Π·Π°ΠΏΡΡΠΊΠ° ΠΏΠΎΠ΄ΠΎΠ² ΠΏΠΎΠ΄ root (Π² Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅ΠΌ ΠΎΠ±ΡΡΠ΄ΠΈΠΌ ΡΡΠΎΡ ΠΌΠΎΠΌΠ΅Π½Ρ):
oc create sa spark -n {project}
oc adm policy add-scc-to-user anyuid -z spark -n {project}
ΠΡΠΏΠΎΠ»Π½ΠΈΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Ρ spark-submit Π΄Π»Ρ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ Π·Π°Π΄Π°ΡΠΈ Spark Π² ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ OKD, ΡΠΊΠ°Π·Π°Π² ΡΠΎΠ·Π΄Π°Π½Π½ΡΠΉ ΡΠ΅ΡΠ²ΠΈΡΠ½ΡΠΉ Π°ΠΊΠΊΠ°ΡΠ½Ρ ΠΈ ΠΎΠ±ΡΠ°Π· Docker:
/opt/spark/bin/spark-submit --name spark-test --class org.apache.spark.examples.SparkPi --conf spark.executor.instances=3 --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark --conf spark.kubernetes.namespace={project} --conf spark.submit.deployMode=cluster --conf spark.kubernetes.container.image={docker-registry-url}/{repo}/{image-name}:{tag} --conf spark.master=k8s://https://{OKD-API-URL} local:///opt/spark/examples/target/scala-2.11/jars/spark-examples_2.11-2.4.5.jar
ΠΠ΄Π΅ΡΡ:
—name β ΠΈΠΌΡ Π·Π°Π΄Π°ΡΠΈ, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π±ΡΠ΄Π΅Ρ ΡΡΠ°ΡΡΠ²ΠΎΠ²Π°ΡΡ Π² ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ ΠΈΠΌΠ΅Π½ΠΈ ΠΏΠΎΠ΄ΠΎΠ² Kubernetes;
—class β ΠΊΠ»Π°ΡΡ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°, Π²ΡΠ·ΡΠ²Π°Π΅ΠΌΡΠΉ ΠΏΡΠΈ Π·Π°ΠΏΡΡΠΊΠ΅ Π·Π°Π΄Π°ΡΠΈ;
—conf β ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Spark;
spark.executor.instances β ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌΡΡ ΡΠΊΠ·Π΅ΠΊΡΡΡΠΎΡΠΎΠ² Spark;
spark.kubernetes.authenticate.driver.serviceAccountName β ΠΈΠΌΡ ΡΠ»ΡΠΆΠ΅Π±Π½ΠΎΠΉ ΡΡΡΡΠ½ΠΎΠΉ Π·Π°ΠΏΠΈΡΠΈ Kubernetes, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΠΎΠΉ ΠΏΡΠΈ Π·Π°ΠΏΡΡΠΊΠ΅ ΠΏΠΎΠ΄ΠΎΠ² (Π΄Π»Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠ΅ΠΉ ΠΏΡΠΈ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠΈ Ρ API Kubernetes);
spark.kubernetes.namespace β ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ ΠΈΠΌΡΠ½ Kubernetes, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π±ΡΠ΄ΡΡ Π·Π°ΠΏΡΡΠΊΠ°ΡΡΡΡ ΠΏΠΎΠ΄Ρ Π΄ΡΠ°ΠΉΠ²Π΅ΡΠ° ΠΈ ΡΠΊΠ·Π΅ΠΊΡΡΡΠ΅ΡΠΎΠ²;
spark.submit.deployMode β ΡΠΏΠΎΡΠΎΠ± Π·Π°ΠΏΡΡΠΊΠ° Spark (Π΄Π»Ρ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠ³ΠΎ spark-submit ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Β«clusterΒ», Π΄Π»Ρ Spark Operator ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ·Π΄Π½ΠΈΡ Π²Π΅ΡΡΠΈΠΉ Spark Β«clientΒ»);
spark.kubernetes.container.image β ΠΎΠ±ΡΠ°Π· Docker, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠΉ Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ° ΠΏΠΎΠ΄ΠΎΠ²;
spark.master β URL API Kubernetes (ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΡΡΡ Π²Π½Π΅ΡΠ½ΠΈΠΉ ΡΠ°ΠΊ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ Ρ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠΉ ΠΌΠ°ΡΠΈΠ½Ρ);
local:// β ΠΏΡΡΡ Π΄ΠΎ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° Spark Π²Π½ΡΡΡΠΈ ΠΎΠ±ΡΠ°Π·Π° Docker.
ΠΠ΅ΡΠ΅Ρ ΠΎΠ΄ΠΈΠΌ Π² ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ ΠΏΡΠΎΠ΅ΠΊΡ OKD ΠΈ ΠΈΠ·ΡΡΠ°Π΅ΠΌ ΡΠΎΠ·Π΄Π°Π½Π½ΡΠ΅ ΠΏΠΎΠ΄Ρ β https://{OKD-WEBUI-URL}/console/project/{project}/browse/pods.
ΠΠ»Ρ ΡΠΏΡΠΎΡΠ΅Π½ΠΈΡ ΠΏΡΠΎΡΠ΅ΡΡΠ° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ Π΅ΡΡ ΠΎΠ΄ΠΈΠ½ Π²Π°ΡΠΈΠ°Π½Ρ, ΠΏΡΠΈ ΠΊΠΎΡΠΎΡΠΎΠΌ ΡΠΎΠ·Π΄Π°ΡΡΡΡ ΠΎΠ±ΡΠΈΠΉ Π±Π°Π·ΠΎΠ²ΡΠΉ ΠΎΠ±ΡΠ°Π· Spark, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠΉ Π²ΡΠ΅ΠΌΠΈ Π·Π°Π΄Π°ΡΠ°ΠΌΠΈ Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ°, Π° ΡΠ½ΡΠΏΡΠΎΡΡ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΡ ΡΠ°ΠΉΠ»ΠΎΠ² ΠΏΡΠ±Π»ΠΈΠΊΡΡΡΡΡ Π²ΠΎ Π²Π½Π΅ΡΠ½Π΅Π΅ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Hadoop) ΠΈ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡΡΡ ΠΏΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ spark-submit Π² Π²ΠΈΠ΄Π΅ ΡΡΡΠ»ΠΊΠΈ. Π ΡΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ Π²Π΅ΡΡΠΈΠΈ Π·Π°Π΄Π°Ρ Spark Π±Π΅Π· ΠΏΠ΅ΡΠ΅ΡΠ±ΠΎΡΠΊΠΈ ΠΎΠ±ΡΠ°Π·ΠΎΠ² Docker, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Π΄Π»Ρ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ ΠΎΠ±ΡΠ°Π·ΠΎΠ², Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, WebHDFS. ΠΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌ Π·Π°ΠΏΡΠΎΡ Π½Π° ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΠ°ΠΉΠ»Π° (Π·Π΄Π΅ΡΡ {host} β Ρ ΠΎΡΡ ΡΠ΅ΡΠ²ΠΈΡΠ° WebHDFS, {port} β ΠΏΠΎΡΡ ΡΠ΅ΡΠ²ΠΈΡΠ° WebHDFS, {path-to-file-on-hdfs} β ΠΆΠ΅Π»Π°Π΅ΠΌΡΠΉ ΠΏΡΡΡ ΠΊ ΡΠ°ΠΉΠ»Ρ Π½Π° HDFS):
curl -i -X PUT "http://{host}:{port}/webhdfs/v1/{path-to-file-on-hdfs}?op=CREATE
ΠΡΠΈ ΡΡΠΎΠΌ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ ΠΎΡΠ²Π΅Ρ Π²ΠΈΠ΄Π° (Π·Π΄Π΅ΡΡ {location} β ΡΡΠΎ URL, ΠΊΠΎΡΠΎΡΡΠΉ Π½ΡΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄Π»Ρ Π·Π°Π³ΡΡΠ·ΠΊΠΈ ΡΠ°ΠΉΠ»Π°):
HTTP/1.1 307 TEMPORARY_REDIRECT
Location: {location}
Content-Length: 0
ΠΠ°Π³ΡΡΠΆΠ°Π΅ΠΌ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΡΠ°ΠΉΠ» Spark Π² HDFS (Π·Π΄Π΅ΡΡ {path-to-local-file} β ΠΏΡΡΡ ΠΊ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠΌΡ ΡΠ°ΠΉΠ»Ρ Spark Π½Π° ΡΠ΅ΠΊΡΡΠ΅ΠΌ Ρ ΠΎΡΡΠ΅):
curl -i -X PUT -T {path-to-local-file} "{location}"
ΠΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π΅Π»Π°ΡΡ spark-submit Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΠ°ΠΉΠ»Π° Spark, Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ Π½Π° HDFS (Π·Π΄Π΅ΡΡ {class-name} β ΠΈΠΌΡ ΠΊΠ»Π°ΡΡΠ°, ΠΊΠΎΡΠΎΡΡΠΉ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π·Π°ΠΏΡΡΡΠΈΡΡ Π΄Π»Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π·Π°Π΄Π°ΡΠΈ):
/opt/spark/bin/spark-submit --name spark-test --class {class-name} --conf spark.executor.instances=3 --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark --conf spark.kubernetes.namespace={project} --conf spark.submit.deployMode=cluster --conf spark.kubernetes.container.image={docker-registry-url}/{repo}/{image-name}:{tag} --conf spark.master=k8s://https://{OKD-API-URL} hdfs://{host}:{port}/{path-to-file-on-hdfs}
ΠΡΠΈ ΡΡΠΎΠΌ Π½Π°Π΄ΠΎ Π·Π°ΠΌΠ΅ΡΠΈΡΡ, ΡΡΠΎ Π΄Π»Ρ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ HDFS ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠ΅Π½ΠΈΡ ΡΠ°Π±ΠΎΡΡ Π·Π°Π΄Π°ΡΠΈ ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΡΡΠ΅Π±ΠΎΠ²Π°ΡΡΡΡ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ Dockerfile ΠΈ ΡΠΊΡΠΈΠΏΡ entrypoint.sh β Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π² Dockerfile Π΄ΠΈΡΠ΅ΠΊΡΠΈΠ²Ρ Π΄Π»Ρ ΠΊΠΎΠΏΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π·Π°Π²ΠΈΡΠΈΠΌΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ Π² Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ /opt/spark/jars ΠΈ Π²ΠΊΠ»ΡΡΠΈΡΡ ΡΠ°ΠΉΠ» ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ HDFS Π² SPARK_CLASSPATH Π² entrypoint.sh.
ΠΡΠΎΡΠΎΠΉ Π²Π°ΡΠΈΠ°Π½Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ β Apache Livy
ΠΠ°Π»Π΅Π΅, ΠΊΠΎΠ³Π΄Π° Π·Π°Π΄Π°ΡΠ° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠ°Π½Π° ΠΈ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠΈΡΠΎΠ²Π°ΡΡ ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΡΠΉ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ, Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ Π²ΠΎΠΏΡΠΎΡ Π΅Ρ Π·Π°ΠΏΡΡΠΊΠ° Π² ΡΠ°ΠΌΠΊΠ°Ρ ΠΏΡΠΎΡΠ΅ΡΡΠ° CI/CD ΠΈ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΡ ΡΡΠ°ΡΡΡΠΎΠ² Π΅Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ. ΠΠΎΠ½Π΅ΡΠ½ΠΎ, ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ Π΅Ρ ΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠ³ΠΎ Π²ΡΠ·ΠΎΠ²Π° spark-submit, Π½ΠΎ ΡΡΠΎ ΡΡΠ»ΠΎΠΆΠ½ΡΠ΅Ρ ΠΈΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΡ CI/CD ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΡΠ΅Π±ΡΠ΅Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΡ ΠΈ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Spark Π½Π° Π°Π³Π΅Π½ΡΠ°Ρ /ΡΠ°Π½Π½Π΅ΡΠ°Ρ CI ΡΠ΅ΡΠ²Π΅ΡΠ° ΠΈ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ API Kubernetes. ΠΠ»Ρ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΡΠ»ΡΡΠ°Ρ ΡΠ΅Π»Π΅Π²ΠΎΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠ΅ΠΉ Π²ΡΠ±ΡΠ°Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Apache Livy Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ REST API Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ° Π·Π°Π΄Π°Ρ Spark, ΡΠ°Π·ΠΌΠ΅ΡΡΠ½Π½ΠΎΠ³ΠΎ Π²Π½ΡΡΡΠΈ ΠΊΠ»Π°ΡΡΠ΅ΡΠ° Kubernetes. Π‘ Π΅Π³ΠΎ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ Π·Π°Π΄Π°ΡΠΈ Spark Π½Π° ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ Kubernetes ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΠΎΠ±ΡΡΠ½ΡΠ΅ cURL Π·Π°ΠΏΡΠΎΡΡ, ΡΡΠΎ Π»Π΅Π³ΠΊΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅ΠΌΠΎ Π½Π° Π±Π°Π·Π΅ Π»ΡΠ±ΠΎΠ³ΠΎ CI ΡΠ΅ΡΠ΅Π½ΠΈΡ, Π° Π΅Π³ΠΎ ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½ΠΈΠ΅ Π²Π½ΡΡΡΠΈ ΠΊΠ»Π°ΡΡΠ΅ΡΠ° Kubernetes ΡΠ΅ΡΠ°Π΅Ρ Π²ΠΎΠΏΡΠΎΡ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ ΠΏΡΠΈ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠΈ Ρ API Kubernetes.
ΠΡΠ΄Π΅Π»ΠΈΠΌ Π΅Π³ΠΎ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π²ΡΠΎΡΠΎΠ³ΠΎ Π²Π°ΡΠΈΠ°Π½ΡΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ β Π·Π°ΠΏΡΡΠΊ Π·Π°Π΄Π°Ρ Spark Π² ΡΠ°ΠΌΠΊΠ°Ρ
ΠΏΡΠΎΡΠ΅ΡΡΠ° CI/CD Π½Π° ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ Kubernetes Π² ΡΠ΅ΡΡΠΎΠ²ΠΎΠΌ ΠΊΠΎΠ½ΡΡΡΠ΅.
ΠΠ΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎ Apache Livy β ΠΎΠ½ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΠΊΠ°ΠΊ HTTP ΡΠ΅ΡΠ²Π΅Ρ, ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΡΡΠΈΠΉ Web ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΠΈ RESTful API, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠΈΠΉ ΡΠ΄Π°Π»ΡΠ½Π½ΠΎ Π·Π°ΠΏΡΡΡΠΈΡΡ spark-submit, ΠΏΠ΅ΡΠ΅Π΄Π°Π² Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ. Π’ΡΠ°Π΄ΠΈΡΠΈΠΎΠ½Π½ΠΎ ΠΎΠ½ ΠΏΠΎΡΡΠ°Π²Π»ΡΠ»ΡΡ Π² ΡΠΎΡΡΠ°Π²Π΅ Π΄ΠΈΡΡΡΠΈΠ±ΡΡΠΈΠ²Π° HDP, Π½ΠΎ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΠ°Π·Π²ΡΡΠ½ΡΡ Π² OKD ΠΈΠ»ΠΈ Π»ΡΠ±ΠΎΠΉ Π΄ΡΡΠ³ΠΎΠΉ ΠΈΠ½ΡΡΠ°Π»Π»ΡΡΠΈΠΈ Kubernetes Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π³ΠΎ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ° ΠΈ Π½Π°Π±ΠΎΡΠ° ΠΎΠ±ΡΠ°Π·ΠΎΠ² Docker, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΡΠΎΠ³ΠΎ β
FROM java:8-alpine
ENV SPARK_HOME=/opt/spark
ENV LIVY_HOME=/opt/livy
ENV HADOOP_CONF_DIR=/etc/hadoop/conf
ENV SPARK_USER=spark
WORKDIR /opt
RUN apk add --update openssl wget bash &&
wget -P /opt https://downloads.apache.org/spark/spark-2.4.5/spark-2.4.5-bin-hadoop2.7.tgz &&
tar xvzf spark-2.4.5-bin-hadoop2.7.tgz &&
rm spark-2.4.5-bin-hadoop2.7.tgz &&
ln -s /opt/spark-2.4.5-bin-hadoop2.7 /opt/spark
RUN wget http://mirror.its.dal.ca/apache/incubator/livy/0.7.0-incubating/apache-livy-0.7.0-incubating-bin.zip &&
unzip apache-livy-0.7.0-incubating-bin.zip &&
rm apache-livy-0.7.0-incubating-bin.zip &&
ln -s /opt/apache-livy-0.7.0-incubating-bin /opt/livy &&
mkdir /var/log/livy &&
ln -s /var/log/livy /opt/livy/logs &&
cp /opt/livy/conf/log4j.properties.template /opt/livy/conf/log4j.properties
ADD livy.conf /opt/livy/conf
ADD spark-defaults.conf /opt/spark/conf/spark-defaults.conf
ADD entrypoint.sh /entrypoint.sh
ENV PATH="/opt/livy/bin:${PATH}"
EXPOSE 8998
ENTRYPOINT ["/entrypoint.sh"]
CMD ["livy-server"]
Π‘ΠΎΠ·Π΄Π°Π½Π½ΡΠΉ ΠΎΠ±ΡΠ°Π· ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΠΎΠ±ΡΠ°Π½ ΠΈ Π·Π°Π³ΡΡΠΆΠ΅Π½ Π² ΠΈΠΌΠ΅ΡΡΠΈΠΉΡΡ Ρ Π²Π°Ρ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ Docker, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π²Π½ΡΡΡΠ΅Π½Π½ΠΈΠΉ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ OKD. ΠΠ»Ρ Π΅Π³ΠΎ ΡΠ°Π·Π²ΡΡΡΡΠ²Π°Π½ΠΈΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ ({registry-url} β URL ΡΠ΅Π΅ΡΡΡΠ° ΠΎΠ±ΡΠ°Π·ΠΎΠ² Docker, {image-name} β ΠΈΠΌΡ ΠΎΠ±ΡΠ°Π·Π° Docker, {tag} β ΡΠ΅Π³ ΠΎΠ±ΡΠ°Π·Π° Docker, {livy-url} β ΠΆΠ΅Π»Π°Π΅ΠΌΡΠΉ URL, ΠΏΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌΡ Π±ΡΠ΄Π΅Ρ Π΄ΠΎΡΡΡΠΏΠ΅Π½ ΡΠ΅ΡΠ²Π΅Ρ Livy; ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ Β«RouteΒ» ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ Π² ΡΠ»ΡΡΠ°Π΅, Π΅ΡΠ»ΠΈ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π΄ΠΈΡΡΡΠΈΠ±ΡΡΠΈΠ²Π° Kubernetes ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Red Hat OpenShift, Π² ΠΏΡΠΎΡΠΈΠ²Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ Ingress ΠΈΠ»ΠΈ Service ΡΠΈΠΏΠ° NodePort):
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
component: livy
name: livy
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
component: livy
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
component: livy
spec:
containers:
- command:
- livy-server
env:
- name: K8S_API_HOST
value: localhost
- name: SPARK_KUBERNETES_IMAGE
value: 'gnut3ll4/spark:v1.0.14'
image: '{registry-url}/{image-name}:{tag}'
imagePullPolicy: Always
name: livy
ports:
- containerPort: 8998
name: livy-rest
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/log/livy
name: livy-log
- mountPath: /opt/.livy-sessions/
name: livy-sessions
- mountPath: /opt/livy/conf/livy.conf
name: livy-config
subPath: livy.conf
- mountPath: /opt/spark/conf/spark-defaults.conf
name: spark-config
subPath: spark-defaults.conf
- command:
- /usr/local/bin/kubectl
- proxy
- '--port'
- '8443'
image: 'gnut3ll4/kubectl-sidecar:latest'
imagePullPolicy: Always
name: kubectl
ports:
- containerPort: 8443
name: k8s-api
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: spark
serviceAccountName: spark
terminationGracePeriodSeconds: 30
volumes:
- emptyDir: {}
name: livy-log
- emptyDir: {}
name: livy-sessions
- configMap:
defaultMode: 420
items:
- key: livy.conf
path: livy.conf
name: livy-config
name: livy-config
- configMap:
defaultMode: 420
items:
- key: spark-defaults.conf
path: spark-defaults.conf
name: livy-config
name: spark-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: livy-config
data:
livy.conf: |-
livy.spark.deploy-mode=cluster
livy.file.local-dir-whitelist=/opt/.livy-sessions/
livy.spark.master=k8s://http://localhost:8443
livy.server.session.state-retain.sec = 8h
spark-defaults.conf: 'spark.kubernetes.container.image "gnut3ll4/spark:v1.0.14"'
---
apiVersion: v1
kind: Service
metadata:
labels:
app: livy
name: livy
spec:
ports:
- name: livy-rest
port: 8998
protocol: TCP
targetPort: 8998
selector:
component: livy
sessionAffinity: None
type: ClusterIP
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
labels:
app: livy
name: livy
spec:
host: {livy-url}
port:
targetPort: livy-rest
to:
kind: Service
name: livy
weight: 100
wildcardPolicy: None
ΠΠΎΡΠ»Π΅ Π΅Π³ΠΎ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡ ΠΈ ΡΡΠΏΠ΅ΡΠ½ΠΎΠ³ΠΎ Π·Π°ΠΏΡΡΠΊΠ° ΠΏΠΎΠ΄Π° Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Livy Π΄ΠΎΡΡΡΠΏΠ΅Π½ ΠΏΠΎ ΡΡΡΠ»ΠΊΠ΅: http://{livy-url}/ui. Π‘ ΠΏΠΎΠΌΠΎΡΡΡ Livy ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΏΡΠ±Π»ΠΈΠΊΠΎΠ²Π°ΡΡ Π½Π°ΡΡ Π·Π°Π΄Π°ΡΡ Spark, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ REST Π·Π°ΠΏΡΠΎΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΈΠ· Postman. ΠΡΠΈΠΌΠ΅Ρ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ Ρ Π·Π°ΠΏΡΠΎΡΠ°ΠΌΠΈ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ Π½ΠΈΠΆΠ΅ (Π² ΠΌΠ°ΡΡΠΈΠ²Π΅ Β«argsΒ» ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π½Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΡΠ΅ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡ Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΌΠΈ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠΌΠΈ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌΠΎΠΉ Π·Π°Π΄Π°ΡΠΈ):
{
"info": {
"_postman_id": "be135198-d2ff-47b6-a33e-0d27b9dba4c8",
"name": "Spark Livy",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "1 Submit job with jar",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{nt"file": "local:///opt/spark/examples/target/scala-2.11/jars/spark-examples_2.11-2.4.5.jar", nt"className": "org.apache.spark.examples.SparkPi",nt"numExecutors":1,nt"name": "spark-test-1",nt"conf": {ntt"spark.jars.ivy": "/tmp/.ivy",ntt"spark.kubernetes.authenticate.driver.serviceAccountName": "spark",ntt"spark.kubernetes.namespace": "{project}",ntt"spark.kubernetes.container.image": "{docker-registry-url}/{repo}/{image-name}:{tag}"nt}n}"
},
"url": {
"raw": "http://{livy-url}/batches",
"protocol": "http",
"host": [
"{livy-url}"
],
"path": [
"batches"
]
}
},
"response": []
},
{
"name": "2 Submit job without jar",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{nt"file": "hdfs://{host}:{port}/{path-to-file-on-hdfs}", nt"className": "{class-name}",nt"numExecutors":1,nt"name": "spark-test-2",nt"proxyUser": "0",nt"conf": {ntt"spark.jars.ivy": "/tmp/.ivy",ntt"spark.kubernetes.authenticate.driver.serviceAccountName": "spark",ntt"spark.kubernetes.namespace": "{project}",ntt"spark.kubernetes.container.image": "{docker-registry-url}/{repo}/{image-name}:{tag}"nt},nt"args": [ntt"HADOOP_CONF_DIR=/opt/spark/hadoop-conf",ntt"MASTER=k8s://https://kubernetes.default.svc:8443"nt]n}"
},
"url": {
"raw": "http://{livy-url}/batches",
"protocol": "http",
"host": [
"{livy-url}"
],
"path": [
"batches"
]
}
},
"response": []
}
],
"event": [
{
"listen": "prerequest",
"script": {
"id": "41bea1d0-278c-40c9-ad42-bf2e6268897d",
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"id": "3cdd7736-a885-4a2d-9668-bd75798f4560",
"type": "text/javascript",
"exec": [
""
]
}
}
],
"protocolProfileBehavior": {}
}
ΠΡΠΏΠΎΠ»Π½ΠΈΠΌ ΠΏΠ΅ΡΠ²ΡΠΉ Π·Π°ΠΏΡΠΎΡ ΠΈΠ· ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ, ΠΏΠ΅ΡΠ΅ΠΉΠ΄ΡΠΌ Π² ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ OKD ΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌ, ΡΡΠΎ Π·Π°Π΄Π°ΡΠ° ΡΡΠΏΠ΅ΡΠ½ΠΎ Π·Π°ΠΏΡΡΠ΅Π½Π° β https://{OKD-WEBUI-URL}/console/project/{project}/browse/pods. ΠΡΠΈ ΡΡΠΎΠΌ Π² ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ΅ Livy (http://{livy-url}/ui) ΠΏΠΎΡΠ²ΠΈΡΡΡ ΡΠ΅ΡΡΠΈΡ, Π² ΡΠ°ΠΌΠΊΠ°Ρ ΠΊΠΎΡΠΎΡΠΎΠΉ Ρ ΠΏΠΎΠΌΠΎΡΡΡ API Livy ΠΈΠ»ΠΈ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°ΡΡ Ρ ΠΎΠ΄ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π·Π°Π΄Π°ΡΠΈ ΠΈ ΠΈΠ·ΡΡΠ°ΡΡ Π»ΠΎΠ³ΠΈ ΡΠ΅ΡΡΠΈΠΈ.
Π’Π΅ΠΏΠ΅ΡΡ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ ΡΠ°Π±ΠΎΡΡ Livy. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ ΠΈΠ·ΡΡΠΈΠΌ ΠΆΡΡΠ½Π°Π»Ρ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ° Livy Π²Π½ΡΡΡΠΈ ΠΏΠΎΠ΄Π° Ρ ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ Livy β https://{OKD-WEBUI-URL}/console/project/{project}/browse/pods/{livy-pod-name}?tab=logs. ΠΠ· Π½ΠΈΡ Π²ΠΈΠ΄Π½ΠΎ, ΡΡΠΎ ΠΏΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ REST API Livy Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ΅ Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ Β«livyΒ» Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ spark-submit, Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½ΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΠΎΠΌΡ Π½Π°ΠΌΠΈ Π²ΡΡΠ΅ (Π·Π΄Π΅ΡΡ {livy-pod-name} β ΠΈΠΌΡ ΡΠΎΠ·Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄Π° Ρ ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ Livy). Π ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ ΡΠ°ΠΊΠΆΠ΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ Π²ΡΠΎΡΠΎΠΉ Π·Π°ΠΏΡΠΎΡ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠΈΠΉ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ Π·Π°Π΄Π°ΡΠΈ Ρ ΡΠ΄Π°Π»ΡΠ½Π½ΡΠΌ ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½ΠΈΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° Spark Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠ΅ΡΠ²Π΅ΡΠ° Livy.
Π’ΡΠ΅ΡΠΈΠΉ Π²Π°ΡΠΈΠ°Π½Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ β Spark Operator
Π’Π΅ΠΏΠ΅ΡΡ, ΠΊΠΎΠ³Π΄Π° Π·Π°Π΄Π°ΡΠ° ΠΏΡΠΎΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½Π°, Π²ΡΡΠ°ΡΡ Π²ΠΎΠΏΡΠΎΡ Π΅Ρ ΡΠ΅Π³ΡΠ»ΡΡΠ½ΠΎΠ³ΠΎ Π·Π°ΠΏΡΡΠΊΠ°. ΠΠ°ΡΠΈΠ²Π½ΡΠΌ ΡΠΏΠΎΡΠΎΠ±ΠΎΠΌ Π΄Π»Ρ ΡΠ΅Π³ΡΠ»ΡΡΠ½ΠΎΠ³ΠΎ Π·Π°ΠΏΡΡΠΊΠ° Π·Π°Π΄Π°Ρ Π² ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ Kubernetes ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΡΡΠ½ΠΎΡΡΡ CronJob ΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΅Ρ, Π½ΠΎ Π² Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ Π±ΠΎΠ»ΡΡΡΡ ΠΏΠΎΠΏΡΠ»ΡΡΠ½ΠΎΡΡΡ ΠΈΠΌΠ΅Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠΎΠ² Π΄Π»Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΠΌΠΈ Π² Kubernetes ΠΈ Π΄Π»Ρ Spark ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π·ΡΠ΅Π»ΡΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ, ΠΊΠΎΡΠΎΡΡΠΉ, Π² ΡΠΎΠΌ ΡΠΈΡΠ»Π΅, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π² ΡΠ΅ΡΠ΅Π½ΠΈΡΡ Enterprise ΡΡΠΎΠ²Π½Ρ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Lightbend FastData Platform). ΠΡ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΅Π³ΠΎ β ΡΠ΅ΠΊΡΡΠ°Ρ ΡΡΠ°Π±ΠΈΠ»ΡΠ½Π°Ρ Π²Π΅ΡΡΠΈΡ Spark (2.4.5) ΠΈΠΌΠ΅Π΅Ρ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½Π½ΡΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ ΠΏΠΎ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Π·Π°ΠΏΡΡΠΊΠ° Π·Π°Π΄Π°Ρ Spark Π² Kubernetes, ΠΏΡΠΈ ΡΡΠΎΠΌ Π² ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ ΠΌΠ°ΠΆΠΎΡΠ½ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ (3.0.0) Π·Π°ΡΠ²Π»Π΅Π½Π° ΠΏΠΎΠ»Π½ΠΎΡΠ΅Π½Π½Π°Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠ° Kubernetes, Π½ΠΎ Π΄Π°ΡΠ° Π΅Ρ Π²ΡΡ ΠΎΠ΄Π° ΠΎΡΡΠ°ΡΡΡΡ Π½Π΅ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎΠΉ. Spark Operator ΠΊΠΎΠΌΠΏΠ΅Π½ΡΠΈΡΡΠ΅Ρ ΡΡΠΎΡ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΎΠΊ, Π΄ΠΎΠ±Π°Π²Π»ΡΡ Π²Π°ΠΆΠ½ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΌΠΎΠ½ΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ConfigMap Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠ΅ΠΉ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ Hadoop Π² ΠΏΠΎΠ΄Ρ Spark) ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΡΠ΅Π³ΡΠ»ΡΡΠ½ΠΎΠ³ΠΎ Π·Π°ΠΏΡΡΠΊΠ° Π·Π°Π΄Π°ΡΠΈ ΠΏΠΎ ΡΠ°ΡΠΏΠΈΡΠ°Π½ΠΈΡ.
ΠΡΠ΄Π΅Π»ΠΈΠΌ Π΅Π³ΠΎ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΡΠ΅ΡΡΠ΅Π³ΠΎ Π²Π°ΡΠΈΠ°Π½ΡΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ β ΡΠ΅Π³ΡΠ»ΡΡΠ½ΡΠΉ Π·Π°ΠΏΡΡΠΊ Π·Π°Π΄Π°Ρ Spark Π½Π° ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ Kubernetes Π² ΠΏΡΠΎΠ΄ΡΠΊΡΠΈΠ²Π½ΠΎΠΌ ΠΊΠΎΠ½ΡΡΡΠ΅.
Spark Operator ΠΈΠΌΠ΅Π΅Ρ ΠΎΡΠΊΡΡΡΡΠΉ ΠΈΡΡ
ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ ΠΈ ΡΠ°Π·ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΡΡΡ Π² ΡΠ°ΠΌΠΊΠ°Ρ
Google Cloud Platform β
- Π ΡΠ°ΠΌΠΊΠ°Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ Lightbend FastData Platform/Cloudflow;
- Π‘ ΠΏΠΎΠΌΠΎΡΡΡ Helm:
helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator helm install incubator/sparkoperator --namespace spark-operator
- ΠΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΎΠ² ΠΈΠ· ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ (https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/tree/master/manifest). ΠΡΠΈ ΡΡΠΎΠΌ ΡΡΠΎΠΈΡ ΠΎΡΠΌΠ΅ΡΠΈΡΡ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π΅ β Π² ΡΠΎΡΡΠ°Π² Cloudflow Π²Ρ
ΠΎΠ΄ΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ Ρ Π²Π΅ΡΡΠΈΠ΅ΠΉ API v1beta1. ΠΡΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π°Π½Π½ΡΠΉ ΡΠΈΠΏ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ, ΡΠΎ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΎΠ² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Spark Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΡΡΠΎΠΈΡΡΡΡ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ ΠΏΡΠΈΠΌΠ΅ΡΠΎΠ² ΠΈΠ· ΡΠ΅Π³ΠΎΠ² Π² Git Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅ΠΉ Π²Π΅ΡΡΠΈΠ΅ΠΉ API, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Β«v1beta1-0.9.0-2.4.0Β». ΠΠ΅ΡΡΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡΡΠ΅ΡΡ Π² ΠΎΠΏΠΈΡΠ°Π½ΠΈΠΈ CRD, Π²Ρ
ΠΎΠ΄ΡΡΠ΅Π³ΠΎ Π² ΡΠΎΡΡΠ°Π² ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° Π² ΡΠ»ΠΎΠ²Π°ΡΠ΅ Β«versionsΒ»:
oc get crd sparkapplications.sparkoperator.k8s.io -o yaml
ΠΡΠ»ΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ, ΡΠΎ Π² ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅ΠΌ ΠΏΡΠΎΠ΅ΠΊΡΠ΅ ΠΏΠΎΡΠ²ΠΈΡΡΡ Π°ΠΊΡΠΈΠ²Π½ΡΠΉ ΠΏΠΎΠ΄ Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠΎΠΌ Spark (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, cloudflow-fdp-sparkoperator Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅ Cloudflow Π΄Π»Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ Cloudflow) ΠΈ ΠΏΠΎΡΠ²ΠΈΡΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ ΡΠΈΠΏ ΡΠ΅ΡΡΡΡΠΎΠ² Kubernetes Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ Β«sparkapplicationsΒ». ΠΠ·ΡΡΠΈΡΡ ΠΈΠΌΠ΅ΡΡΠΈΠ΅ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Spark ΠΌΠΎΠΆΠ½ΠΎ ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ:
oc get sparkapplications -n {project}
ΠΠ»Ρ Π·Π°ΠΏΡΡΠΊΠ° Π·Π°Π΄Π°Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Spark Operator ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΠ΄Π΅Π»Π°ΡΡ 3 Π²Π΅ΡΠΈ:
- ΡΠΎΠ·Π΄Π°ΡΡ ΠΎΠ±ΡΠ°Π· Docker, Π²ΠΊΠ»ΡΡΠ°ΡΡΠΈΠΉ Π² ΡΠ΅Π±Ρ Π²ΡΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΡΠ΅ ΠΈ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠ΅ ΡΠ°ΠΉΠ»Ρ. Π ΡΠ΅Π»Π΅Π²ΠΎΠΉ ΠΊΠ°ΡΡΠΈΠ½Π΅ ΡΡΠΎ ΠΎΠ±ΡΠ°Π·, ΡΠΎΠ·Π΄Π°Π½Π½ΡΠΉ Π½Π° ΡΡΠ°ΠΏΠ΅ CI/CD ΠΈ ΠΏΡΠΎΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ Π½Π° ΡΠ΅ΡΡΠΎΠ²ΠΎΠΌ ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅;
- ΠΎΠΏΡΠ±Π»ΠΈΠΊΠΎΠ²Π°ΡΡ ΠΎΠ±ΡΠ°Π· Docker Π² ΡΠ΅Π΅ΡΡΡ, Π΄ΠΎΡΡΡΠΏΠ½ΡΠΉ ΠΈΠ· ΠΊΠ»Π°ΡΡΠ΅ΡΠ° Kubernetes;
- ΡΡΠΎΡΠΌΠΈΡΠΎΠ²Π°ΡΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ Ρ ΡΠΈΠΏΠΎΠΌ Β«SparkApplicationΒ» ΠΈ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ΠΌ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌΠΎΠΉ Π·Π°Π΄Π°ΡΠΈ. ΠΡΠΈΠΌΠ΅ΡΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΎΠ² Π΄ΠΎΡΡΡΠΏΠ½Ρ Π² ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠΌ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΈ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ,
github.com/GoogleCloudPlatform/spark-on-k8s-operator/blob/v1beta1-0.9.0-2.4.0/examples/spark-pi.yaml ). Π‘ΡΠΎΠΈΡ ΠΎΡΠΌΠ΅ΡΠΈΡΡ Π²Π°ΠΆΠ½ΡΠ΅ ΠΌΠΎΠΌΠ΅Π½ΡΡ ΠΊΠ°ΡΠ°ΡΠ΅Π»ΡΠ½ΠΎ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ°:- Π² ΡΠ»ΠΎΠ²Π°ΡΠ΅ Β«apiVersionΒ» Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡΡΡ ΡΠΊΠ°Π·Π°Π½Π° Π²Π΅ΡΡΠΈΡ API, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ°Ρ Π²Π΅ΡΡΠΈΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ°;
- Π² ΡΠ»ΠΎΠ²Π°ΡΠ΅ Β«metadata.namespaceΒ» Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ ΡΠΊΠ°Π·Π°Π½ΠΎ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ ΠΈΠΌΡΠ½, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π±ΡΠ΄Π΅Ρ Π·Π°ΠΏΡΡΠ΅Π½ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅;
- Π² ΡΠ»ΠΎΠ²Π°ΡΠ΅ Β«spec.imageΒ» Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΡΠΊΠ°Π·Π°Π½ Π°Π΄ΡΠ΅Ρ ΡΠΎΠ·Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ°Π·Π° Docker Π² Π΄ΠΎΡΡΡΠΏΠ½ΠΎΠΌ ΡΠ΅Π΅ΡΡΡΠ΅;
- Π² ΡΠ»ΠΎΠ²Π°ΡΠ΅ Β«spec.mainClassΒ» Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΡΠΊΠ°Π·Π°Π½ ΠΊΠ»Π°ΡΡ Π·Π°Π΄Π°ΡΠΈ Spark, ΠΊΠΎΡΠΎΡΡΠΉ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π·Π°ΠΏΡΡΡΠΈΡΡ ΠΏΡΠΈ Π·Π°ΠΏΡΡΠΊΠ΅ ΠΏΡΠΎΡΠ΅ΡΡΠ°;
- Π² ΡΠ»ΠΎΠ²Π°ΡΠ΅ Β«spec.mainApplicationFileΒ» Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΡΠΊΠ°Π·Π°Π½ ΠΏΡΡΡ ΠΊ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠΌΡ jar ΡΠ°ΠΉΠ»Ρ;
- Π² ΡΠ»ΠΎΠ²Π°ΡΠ΅ Β«spec.sparkVersionΒ» Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡΡΡ ΡΠΊΠ°Π·Π°Π½Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΠ°Ρ Π²Π΅ΡΡΠΈΡ Spark;
- Π² ΡΠ»ΠΎΠ²Π°ΡΠ΅ Β«spec.driver.serviceAccountΒ» Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡΡΡ ΡΠΊΠ°Π·Π°Π½Π° ΡΠ΅ΡΠ²ΠΈΡΠ½Π°Ρ ΡΡΡΡΠ½Π°Ρ Π·Π°ΠΏΠΈΡΡ Π²Π½ΡΡΡΠΈ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π³ΠΎ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π° ΠΈΠΌΡΠ½ Kubernetes, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Π° Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ;
- Π² ΡΠ»ΠΎΠ²Π°ΡΠ΅ Β«spec.executorΒ» Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ ΡΠΊΠ°Π·Π°Π½ΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠ΅ΡΡΡΡΠΎΠ², Π²ΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ;
- Π² ΡΠ»ΠΎΠ²Π°ΡΠ΅ Β«spec.volumeMountsΒ» Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡΡΡ ΡΠΊΠ°Π·Π°Π½Π° Π»ΠΎΠΊΠ°Π»ΡΠ½Π°Ρ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ Π±ΡΠ΄ΡΡ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ ΡΠ°ΠΉΠ»Ρ Π·Π°Π΄Π°ΡΠΈ Spark.
ΠΡΠΈΠΌΠ΅Ρ ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ° (Π·Π΄Π΅ΡΡ {spark-service-account} β ΡΠ΅ΡΠ²ΠΈΡΠ½ΡΠΉ Π°ΠΊΠΊΠ°ΡΠ½Ρ Π²Π½ΡΡΡΠΈ ΠΊΠ»Π°ΡΡΠ΅ΡΠ° Kubernetes Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ° Π·Π°Π΄Π°Ρ Spark):
apiVersion: "sparkoperator.k8s.io/v1beta1"
kind: SparkApplication
metadata:
name: spark-pi
namespace: {project}
spec:
type: Scala
mode: cluster
image: "gcr.io/spark-operator/spark:v2.4.0"
imagePullPolicy: Always
mainClass: org.apache.spark.examples.SparkPi
mainApplicationFile: "local:///opt/spark/examples/jars/spark-examples_2.11-2.4.0.jar"
sparkVersion: "2.4.0"
restartPolicy:
type: Never
volumes:
- name: "test-volume"
hostPath:
path: "/tmp"
type: Directory
driver:
cores: 0.1
coreLimit: "200m"
memory: "512m"
labels:
version: 2.4.0
serviceAccount: {spark-service-account}
volumeMounts:
- name: "test-volume"
mountPath: "/tmp"
executor:
cores: 1
instances: 1
memory: "512m"
labels:
version: 2.4.0
volumeMounts:
- name: "test-volume"
mountPath: "/tmp"
Π Π΄Π°Π½Π½ΠΎΠΌ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ΅ ΡΠΊΠ°Π·Π°Π½Π° ΡΠ΅ΡΠ²ΠΈΡΠ½Π°Ρ ΡΡΡΡΠ½Π°Ρ Π·Π°ΠΏΠΈΡΡ, Π΄Π»Ρ ΠΊΠΎΡΠΎΡΠΎΠΉ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π΄ΠΎ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ° ΡΠΎΠ·Π΄Π°ΡΡ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ ΠΏΡΠΈΠ²ΡΠ·ΠΊΠΈ ΡΠΎΠ»Π΅ΠΉ, ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΡΡΠΈΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ ΠΏΡΠ°Π²Π° Π΄ΠΎΡΡΡΠΏΠ° Π΄Π»Ρ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Spark Ρ API Kubernetes (Π΅ΡΠ»ΠΈ Π½ΡΠΆΠ½ΠΎ). Π Π½Π°ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π½ΡΠΆΠ½Ρ ΠΏΡΠ°Π²Π° Π½Π° ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Pod’ΠΎΠ². Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΡ ΠΏΡΠΈΠ²ΡΠ·ΠΊΡ ΡΠΎΠ»ΠΈ:
oc adm policy add-role-to-user edit system:serviceaccount:{project}:{spark-service-account} -n {project}
Π’Π°ΠΊΠΆΠ΅ ΡΡΠΎΠΈΡ ΠΎΡΠΌΠ΅ΡΠΈΡΡ, ΡΡΠΎ Π² ΡΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ° ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΠΊΠ°Π·Π°Π½ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ Β«hadoopConfigMapΒ», ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠΊΠ°Π·Π°ΡΡ ConfigMap Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠ΅ΠΉ Hadoop Π±Π΅Π· Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠΌΠ΅ΡΠ΅Π½ΠΈΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π³ΠΎ ΡΠ°ΠΉΠ»Π° Π² ΠΎΠ±ΡΠ°Π· Docker. Π’Π°ΠΊΠΆΠ΅ ΠΎΠ½ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΠΈΡ Π΄Π»Ρ ΡΠ΅Π³ΡΠ»ΡΡΠ½ΠΎΠ³ΠΎ Π·Π°ΠΏΡΡΠΊΠ° Π·Π°Π΄Π°Ρ β Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° Β«scheduleΒ» ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΠΊΠ°Π·Π°Π½ΠΎ ΡΠ°ΡΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π·Π°ΠΏΡΡΠΊΠ° Π΄Π°Π½Π½ΠΎΠΉ Π·Π°Π΄Π°ΡΠΈ.
ΠΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ ΡΠΎΡ ΡΠ°Π½ΡΠ΅ΠΌ Π½Π°Ρ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ Π² ΡΠ°ΠΉΠ» spark-pi.yaml ΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ Π΅Π³ΠΎ ΠΊ Π½Π°ΡΠ΅ΠΌΡ ΠΊΠ»Π°ΡΡΠ΅ΡΡ Kubernetes:
oc apply -f spark-pi.yaml
ΠΡΠΈ ΡΡΠΎΠΌ ΡΠΎΠ·Π΄Π°ΡΡΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ ΡΠΈΠΏΠ° Β«sparkapplicationsΒ»:
oc get sparkapplications -n {project}
> NAME AGE
> spark-pi 22h
ΠΡΠΈ ΡΡΠΎΠΌ Π±ΡΠ΄Π΅Ρ ΡΠΎΠ·Π΄Π°Π½ ΠΏΠΎΠ΄ Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ, ΡΡΠ°ΡΡΡ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π±ΡΠ΄Π΅Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°ΡΡΡΡ Π² ΡΠΎΠ·Π΄Π°Π½Π½ΠΎΠΌ Β«sparkapplicationsΒ». ΠΠ³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡΡΠ΅ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ:
oc get sparkapplications spark-pi -o yaml -n {project}
ΠΠΎ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠΈ Π·Π°Π΄Π°ΡΠΈ POD ΠΏΠ΅ΡΠ΅ΠΉΠ΄ΡΡ Π² ΡΡΠ°ΡΡΡ Β«CompletedΒ», ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ°ΠΊΠΆΠ΅ ΠΎΠ±Π½ΠΎΠ²ΠΈΡΡΡ Π² Β«sparkapplicationsΒ». ΠΠΎΠ³ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡΡΠ΅ΡΡ Π² Π±ΡΠ°ΡΠ·Π΅ΡΠ΅ ΠΈΠ»ΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ (Π·Π΄Π΅ΡΡ {sparkapplications-pod-name} β ΠΈΠΌΡ ΠΏΠΎΠ΄Π° Π·Π°ΠΏΡΡΠ΅Π½Π½ΠΎΠΉ Π·Π°Π΄Π°ΡΠΈ):
oc logs {sparkapplications-pod-name} -n {project}
Π’Π°ΠΊΠΆΠ΅ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ Π·Π°Π΄Π°ΡΠ°ΠΌΠΈ Spark ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΎΡΡΡΠ΅ΡΡΠ²Π»Π΅Π½ΠΎ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΡΡΠΈΠ»ΠΈΡΡ sparkctl. ΠΠ»Ρ Π΅Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΠΊΠ»ΠΎΠ½ΠΈΡΡΠ΅ΠΌ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ Ρ Π΅Ρ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΌ ΠΊΠΎΠ΄ΠΎΠΌ, ΡΡΡΠ°Π½ΠΎΠ²ΠΈΠΌ Go ΠΈ ΡΠΎΠ±Π΅ΡΡΠΌ Π΄Π°Π½Π½ΡΡ ΡΡΠΈΠ»ΠΈΡΡ:
git clone https://github.com/GoogleCloudPlatform/spark-on-k8s-operator.git
cd spark-on-k8s-operator/
wget https://dl.google.com/go/go1.13.3.linux-amd64.tar.gz
tar -xzf go1.13.3.linux-amd64.tar.gz
sudo mv go /usr/local
mkdir $HOME/Projects
export GOROOT=/usr/local/go
export GOPATH=$HOME/Projects
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
go -version
cd sparkctl
go build -o sparkctl
sudo mv sparkctl /usr/local/bin
ΠΠ·ΡΡΠΈΠΌ ΡΠΏΠΈΡΠΎΠΊ Π·Π°ΠΏΡΡΠ΅Π½Π½ΡΡ Π·Π°Π΄Π°Ρ Spark:
sparkctl list -n {project}
Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π΄Π»Ρ Π·Π°Π΄Π°ΡΠΈ Spark:
vi spark-app.yaml
apiVersion: "sparkoperator.k8s.io/v1beta1"
kind: SparkApplication
metadata:
name: spark-pi
namespace: {project}
spec:
type: Scala
mode: cluster
image: "gcr.io/spark-operator/spark:v2.4.0"
imagePullPolicy: Always
mainClass: org.apache.spark.examples.SparkPi
mainApplicationFile: "local:///opt/spark/examples/jars/spark-examples_2.11-2.4.0.jar"
sparkVersion: "2.4.0"
restartPolicy:
type: Never
volumes:
- name: "test-volume"
hostPath:
path: "/tmp"
type: Directory
driver:
cores: 1
coreLimit: "1000m"
memory: "512m"
labels:
version: 2.4.0
serviceAccount: spark
volumeMounts:
- name: "test-volume"
mountPath: "/tmp"
executor:
cores: 1
instances: 1
memory: "512m"
labels:
version: 2.4.0
volumeMounts:
- name: "test-volume"
mountPath: "/tmp"
ΠΠ°ΠΏΡΡΡΠΈΠΌ ΠΎΠΏΠΈΡΠ°Π½Π½ΡΡ Π·Π°Π΄Π°ΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ sparkctl:
sparkctl create spark-app.yaml -n {project}
ΠΠ·ΡΡΠΈΠΌ ΡΠΏΠΈΡΠΎΠΊ Π·Π°ΠΏΡΡΠ΅Π½Π½ΡΡ Π·Π°Π΄Π°Ρ Spark:
sparkctl list -n {project}
ΠΠ·ΡΡΠΈΠΌ ΡΠΏΠΈΡΠΎΠΊ ΡΠΎΠ±ΡΡΠΈΠΉ Π·Π°ΠΏΡΡΠ΅Π½Π½ΠΎΠΉ Π·Π°Π΄Π°ΡΠΈ Spark:
sparkctl event spark-pi -n {project} -f
ΠΠ·ΡΡΠΈΠΌ ΡΡΠ°ΡΡΡ Π·Π°ΠΏΡΡΠ΅Π½Π½ΠΎΠΉ Π·Π°Π΄Π°ΡΠΈ Spark:
sparkctl status spark-pi -n {project}
Π Π·Π°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Ρ ΠΎΡΠ΅Π»ΠΎΡΡ Π±Ρ ΡΠ°ΡΡΠΌΠΎΡΡΠ΅ΡΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½Π½ΡΠ΅ ΠΌΠΈΠ½ΡΡΡ ΡΠΊΡΠΏΠ»ΡΠ°ΡΠ°ΡΠΈΠΈ ΡΠ΅ΠΊΡΡΠ΅ΠΉ ΡΡΠ°Π±ΠΈΠ»ΡΠ½ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ Spark (2.4.5) Π² Kubernetes:
- ΠΠ΅ΡΠ²ΡΠΉ ΠΈ, ΠΏΠΎΠΆΠ°Π»ΡΠΉ, Π³Π»Π°Π²Π½ΡΠΉ ΠΌΠΈΠ½ΡΡ β ΡΡΠΎ ΠΎΡΡΡΡΡΡΠ²ΠΈΠ΅ Data Locality. ΠΠ΅ΡΠΌΠΎΡΡΡ Π½Π° Π²ΡΠ΅ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΊΠΈ YARN Π±ΡΠ»ΠΈ ΠΈ ΠΏΠ»ΡΡΡ Π² Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΡΠΈΠ½ΡΠΈΠΏ Π΄ΠΎΡΡΠ°Π²ΠΊΠΈ ΠΊΠΎΠ΄Π° ΠΊ Π΄Π°Π½Π½ΡΠΌ (Π° Π½Π΅ Π΄Π°Π½Π½ΡΡ ΠΊ ΠΊΠΎΠ΄Ρ). ΠΠ»Π°Π³ΠΎΠ΄Π°ΡΡ Π΅ΠΌΡ Π·Π°Π΄Π°ΡΠΈ Spark Π²ΡΠΏΠΎΠ»Π½ΡΠ»ΠΈΡΡ Π½Π° ΡΠ·Π»Π°Ρ , Π³Π΄Π΅ ΡΠ°ΡΠΏΠΎΠ»Π°Π³Π°Π»ΠΈΡΡ Π΄Π°Π½Π½ΡΠ΅, ΡΡΠ°ΡΡΠ²ΡΡΡΠΈΠ΅ Π² Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡΡ , ΠΈ Π·Π°ΠΌΠ΅ΡΠ½ΠΎ ΡΠΌΠ΅Π½ΡΡΠ°Π»ΠΎΡΡ Π²ΡΠ΅ΠΌΡ Π½Π° Π΄ΠΎΡΡΠ°Π²ΠΊΡ Π΄Π°Π½Π½ΡΡ ΠΏΠΎ ΡΠ΅ΡΠΈ. ΠΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ Kubernetes ΠΌΡ ΡΡΠ°Π»ΠΊΠΈΠ²Π°Π΅ΠΌΡΡ Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΠ΅Π½ΠΈΡ ΠΏΠΎ ΡΠ΅ΡΠΈ Π΄Π°Π½Π½ΡΡ , Π·Π°Π΄Π΅ΠΉΡΡΠ²ΠΎΠ²Π°Π½Π½ΡΡ Π² ΡΠ°Π±ΠΎΡΠ΅ Π·Π°Π΄Π°ΡΠΈ. Π ΡΠ»ΡΡΠ°Π΅, Π΅ΡΠ»ΠΈ ΠΎΠ½ΠΈ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π±ΠΎΠ»ΡΡΠΈΠ΅, ΡΠΎ Π²ΡΠ΅ΠΌΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π·Π°Π΄Π°ΡΠΈ ΠΌΠΎΠΆΠ΅Ρ ΡΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΠΎ ΡΠ²Π΅Π»ΠΈΡΠΈΡΡΡΡ, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΏΠΎΡΡΠ΅Π±ΠΎΠ²Π°ΡΡΡΡ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π±ΠΎΠ»ΡΡΠΎΠΉ ΠΎΠ±ΡΡΠΌ Π΄ΠΈΡΠΊΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π°, Π²ΡΠ΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°ΠΌ Π·Π°Π΄Π°ΡΠΈ Spark Π΄Π»Ρ ΠΈΡ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ. ΠΠ°Π½Π½ΡΠΉ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΠ½ΠΈΠΆΠ΅Π½ Π·Π° ΡΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΡ ΡΡΠ΅Π΄ΡΡΠ², ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°ΡΡΠΈΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΡΡΡ Π΄Π°Π½Π½ΡΡ Π² Kubernetes (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Alluxio), Π½ΠΎ ΡΡΠΎ ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΡ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ ΠΏΠΎΠ»Π½ΠΎΠΉ ΠΊΠΎΠΏΠΈΠΈ Π΄Π°Π½Π½ΡΡ Π½Π° ΡΠ·Π»Π°Ρ ΠΊΠ»Π°ΡΡΠ΅ΡΠ° Kubernetes.
- ΠΡΠΎΡΠΎΠΉ Π²Π°ΠΆΠ½ΡΠΉ ΠΌΠΈΠ½ΡΡ β ΡΡΠΎ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ. ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΈ, ΡΠ²ΡΠ·Π°Π½Π½ΡΠ΅ Ρ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠ΅Π½ΠΈΠ΅ΠΌ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ ΠΊΠ°ΡΠ°ΡΠ΅Π»ΡΠ½ΠΎ Π·Π°ΠΏΡΡΠΊΠ° Π·Π°Π΄Π°Ρ Spark ΠΎΡΠΊΠ»ΡΡΠ΅Π½Ρ, Π²Π°ΡΠΈΠ°Π½Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ Kerberos Π² ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠΉ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ Π½Π΅ ΠΎΡ Π²Π°ΡΠ΅Π½ (Ρ ΠΎΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΏΠΎΡΠ²ΠΈΠ»ΠΈΡΡ Π² Π²Π΅ΡΡΠΈΠΈ 3.0.0, ΡΡΠΎ ΠΏΠΎΡΡΠ΅Π±ΡΠ΅Ρ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎΠΉ ΠΏΡΠΎΡΠ°Π±ΠΎΡΠΊΠΈ), Π° Π² Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ ΠΏΠΎ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠ΅Π½ΠΈΡ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ Spark (https://spark.apache.org/docs/2.4.5/security.html) Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡ ΠΊΠ»ΡΡΠ΅ΠΉ ΡΠΈΠ³ΡΡΠΈΡΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ YARN, Mesos ΠΈ Standalone Cluster. ΠΡΠΈ ΡΡΠΎΠΌ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ, ΠΏΠΎΠ΄ ΠΊΠΎΡΠΎΡΡΠΌ Π·Π°ΠΏΡΡΠΊΠ°ΡΡΡΡ Π·Π°Π΄Π°ΡΠΈ Spark, Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΠΊΠ°Π·Π°Π½ Π½Π°ΠΏΡΡΠΌΡΡ β ΠΌΡ Π»ΠΈΡΡ Π·Π°Π΄Π°ΡΠΌ ΡΠ΅ΡΠ²ΠΈΡΠ½ΡΡ ΡΡΡΡΠ½ΡΡ Π·Π°ΠΏΠΈΡΡ, ΠΏΠΎΠ΄ ΠΊΠΎΡΠΎΡΠΎΠΉ Π±ΡΠ΄Π΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΏΠΎΠ΄, Π° ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π²ΡΠ±ΠΈΡΠ°Π΅ΡΡΡ ΠΈΡΡ ΠΎΠ΄Ρ ΠΈΠ· Π½Π°ΡΡΡΠΎΠ΅Π½Π½ΡΡ ΠΏΠΎΠ»ΠΈΡΠΈΠΊ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ. Π ΡΠ²ΡΠ·ΠΈ Ρ ΡΡΠΈΠΌ Π»ΠΈΠ±ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ root, ΡΡΠΎ Π½Π΅ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ Π² ΠΏΡΠΎΠ΄ΡΠΊΡΠΈΠ²Π½ΠΎΠΌ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠΈ, Π»ΠΈΠ±ΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Ρ ΡΠ»ΡΡΠ°ΠΉΠ½ΡΠΌ UID, ΡΡΠΎ Π½Π΅ΡΠ΄ΠΎΠ±Π½ΠΎ ΠΏΡΠΈ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ ΠΏΡΠ°Π² Π΄ΠΎΡΡΡΠΏΠ° ΠΊ Π΄Π°Π½Π½ΡΠΌ (ΡΠ΅ΡΠ°Π΅ΠΌΠΎ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ΠΌ PodSecurityPolicies ΠΈ ΠΈΡ ΠΏΡΠΈΠ²ΡΠ·ΠΊΠΎΠΉ ΠΊ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΌ ΡΠ»ΡΠΆΠ΅Π±Π½ΡΠΌ ΡΡΡΡΠ½ΡΠΌ Π·Π°ΠΏΠΈΡΡΠΌ). ΠΠ° ΡΠ΅ΠΊΡΡΠΈΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ ΡΠ΅ΡΠ°Π΅ΡΡΡ Π»ΠΈΠ±ΠΎ ΠΏΠΎΠΌΠ΅ΡΠ΅Π½ΠΈΠ΅ΠΌ Π²ΡΠ΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΡ ΡΠ°ΠΉΠ»ΠΎΠ² Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ Π² ΠΎΠ±ΡΠ°Π· Docker, Π»ΠΈΠ±ΠΎ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΈΠ΅ΠΉ ΡΠΊΡΠΈΠΏΡΠ° Π·Π°ΠΏΡΡΠΊΠ° Spark Π΄Π»Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΠ° Ρ ΡΠ°Π½Π΅Π½ΠΈΡ ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΠ΅ΠΊΡΠ΅ΡΠΎΠ², ΠΏΡΠΈΠ½ΡΡΠΎΠ³ΠΎ Π² ΠΠ°ΡΠ΅ΠΉ ΠΎΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΠΈ.
- ΠΠ°ΠΏΡΡΠΊ Π·Π°Π΄Π°Ρ Spark Ρ ΠΏΠΎΠΌΠΎΡΡΡ Kubernetes ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎ Π΄ΠΎ ΡΠΈΡ ΠΏΠΎΡ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠ°Π»ΡΠ½ΠΎΠΌ ΡΠ΅ΠΆΠΈΠΌΠ΅ ΠΈ Π² Π±ΡΠ΄ΡΡΠ΅ΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π² ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ Π°ΡΡΠ΅ΡΠ°ΠΊΡΠ°Ρ (ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΡΡ ΡΠ°ΠΉΠ»Π°Ρ , Π±Π°Π·ΠΎΠ²ΡΡ ΠΎΠ±ΡΠ°Π·ΠΎΠ² Docker ΠΈ ΡΠΊΡΠΈΠΏΡΠ°Ρ Π·Π°ΠΏΡΡΠΊΠ°). Π Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ β ΠΏΡΠΈ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΊΠ΅ ΠΌΠ°ΡΠ΅ΡΠΈΠ°Π»Π° ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π»ΠΈΡΡ Π²Π΅ΡΡΠΈΠΈ 2.3.0 ΠΈ 2.4.5, ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΡΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΠΎ ΠΎΡΠ»ΠΈΡΠ°Π»ΠΎΡΡ.
ΠΡΠ΄Π΅ΠΌ ΠΆΠ΄Π°ΡΡ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΉ β Π½Π΅Π΄Π°Π²Π½ΠΎ Π²ΡΡΠ»Π° ΡΠ²Π΅ΠΆΠ°Ρ Π²Π΅ΡΡΠΈΡ Spark (3.0.0), ΠΏΡΠΈΠ½ΡΡΡΠ°Ρ ΠΎΡΡΡΠΈΠΌΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π² ΡΠ°Π±ΠΎΡΡ Spark Π½Π° Kubernetes, Π½ΠΎ ΡΠΎΡ ΡΠ°Π½ΠΈΠ²ΡΠ°Ρ ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠ°Π»ΡΠ½ΡΠΉ ΡΡΠ°ΡΡΡ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅ΡΠ° ΡΠ΅ΡΡΡΡΠΎΠ². ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡ Π² ΠΏΠΎΠ»Π½ΠΎΠΉ ΠΌΠ΅ΡΠ΅ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°ΡΡ ΠΎΡΠΊΠ°Π·Π°ΡΡΡΡ ΠΎΡ YARN ΠΈ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ Π·Π°Π΄Π°ΡΠΈ Spark Π½Π° Kubernetes, Π½Π΅ ΠΎΠΏΠ°ΡΠ°ΡΡΡ Π·Π° Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ ΠΠ°ΡΠ΅ΠΉ ΡΠΈΡΡΠ΅ΠΌΡ ΠΈ Π±Π΅Π· Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ ΡΠ°ΠΌΠΎΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎΠΉ Π΄ΠΎΡΠ°Π±ΠΎΡΠΊΠΈ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ².
Fin.
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com