重要
この機能は不安定です。この機能は進化し続けているため、API は維持されない可能性があり、機能が変更または削除される可能性があります。
この機能を有効にしてクラスタで runC コンテナを実行すると、セキュリティ上の問題が発生する可能性があります。runC は多くの強力なカーネル機能と統合されているため、管理者はこの機能を有効にする前に runC のセキュリティを理解することが不可欠です。
runC は、Open Container Initiative (OCI) 仕様に従ってコンテナを生成して実行するための CLI ツールです。runC は元々 Docker の元のインフラストラクチャから分離されました。squashFS イメージを介して作成された rootfs マウントポイントと合わせて、runC を使用すると、ユーザーはアプリケーションを好ましい実行環境と共にバンドルして、ターゲットマシンで実行できます。OCI の詳細については、ウェブサイトを参照してください。
Linux Container Executor (LCE) を使用すると、YARN NodeManager は、ホストマシンで直接実行される YARN コンテナ、Docker コンテナ内、および runC コンテナ内で実行される YARN コンテナを起動できます。リソースを要求するアプリケーションは、各コンテナの実行方法を指定できます。LCE はセキュリティも強化しており、セキュアクラスタを展開する場合に必要です。LCE が runC コンテナで実行される YARN コンテナを起動する場合、アプリケーションは使用する runC イメージを指定できます。これらの runC イメージは、Docker イメージから構築できます。
runC コンテナは、アプリケーションのコードが実行されるカスタム実行環境を提供し、NodeManager や他のアプリケーションの実行環境から隔離されます。これらのコンテナには、アプリケーションに必要な特別なライブラリを含めることができ、Perl、Python、Java を含むネイティブツールとライブラリの異なるバージョンを持つことができます。runC コンテナでは、NodeManager で実行されているものとは異なるバージョンの Linux を実行することもできます。
YARN の runC は、一貫性(すべての YARN コンテナは同じソフトウェア環境を持つ)と分離(物理マシンにインストールされているものとの干渉がない)の両方を提供します。
LCE の runC のサポートはまだ進化しています。進捗状況を追跡し、runC の設計ドキュメントを参照するには、runC のサポートの改善に関する包括的な JIRA である YARN-9014 を確認してください。
LCE では、container-executor バイナリが root:hadoop が所有し、6050 の権限を持つ必要があります。runC コンテナを起動するには、runC コンテナが起動されるすべての NodeManager ホストに runC をインストールする必要があります。
次のプロパティを yarn-site.xml に設定する必要があります。
<configuration> <property> <name>yarn.nodemanager.container-executor.class</name> <value>org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor</value> <description> This is the container executor setting that ensures that all applications are started with the LinuxContainerExecutor. </description> </property> <property> <name>yarn.nodemanager.linux-container-executor.group</name> <value>hadoop</value> <description> The POSIX group of the NodeManager. It should match the setting in "container-executor.cfg". This configuration is required for validating the secure access of the container-executor binary. </description> </property> <property> <name>yarn.nodemanager.linux-container-executor.nonsecure-mode.limit-users</name> <value>false</value> <description> Whether all applications should be run as the NodeManager process' owner. When false, applications are launched instead as the application owner. </description> </property> <property> <name>yarn.nodemanager.runtime.linux.allowed-runtimes</name> <value>default,runc</value> <description> Comma separated list of runtimes that are allowed when using LinuxContainerExecutor. The allowed values are default, docker, runc, and javasandbox. </description> </property> <property> <name>yarn.nodemanager.runtime.linux.type</name> <value></value> <description> Optional. Sets the default container runtime to use. </description> </property> <property> <description>The runC image tag to manifest plugin class to be used.</description> <name>yarn.nodemanager.runtime.linux.runc.image-tag-to-manifest-plugin</name> <value>org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.runc.ImageTagToManifestPlugin</value> </property> <property> <description>The runC manifest to resources plugin class to be used.</description> <name>yarn.nodemanager.runtime.linux.runc.manifest-to-resources-plugin</name> <value>org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.runc.HdfsManifestToResourcesPlugin</value> </property> <property> <description>The HDFS location under which the oci image manifests, layers, and configs directories exist.</description> <name>yarn.nodemanager.runtime.linux.runc.image-toplevel-dir</name> <value>/runc-root</value> </property> <property> <description>Target count of layer mounts that we should keep on disk at one time.</description> <name>yarn.nodemanager.runtime.linux.runc.layer-mounts-to-keep</name> <value>100</value> </property> <property> <description>The interval in seconds between executions of reaping layer mounts.</description> <name>yarn.nodemanager.runtime.linux.runc.layer-mounts-interval-secs</name> <value>600</value> </property> <property> <description>Image to be used if no other image is specified.</description> <name>yarn.nodemanager.runtime.linux.runc.image-name</name> <value></value> </property> <property> <description>Allow or disallow privileged containers.</description> <name>yarn.nodemanager.runtime.linux.runc.privileged-containers.allowed</name> <value>false</value> </property> <property> <description>The set of networks allowed when launching containers using the RuncContainerRuntime.</description> <name>yarn.nodemanager.runtime.linux.runc.allowed-container-networks</name> <value>host,none,bridge</value> </property> <property> <description>The set of runtimes allowed when launching containers using the RuncContainerRuntime.</description> <name>yarn.nodemanager.runtime.linux.runc.allowed-container-runtimes</name> <value>runc</value> </property> <property> <description>ACL list for users allowed to run privileged containers.</description> <name>yarn.nodemanager.runtime.linux.runc.privileged-containers.acl</name> <value></value> </property> <property> <description>Allow host pid namespace for runC containers. Use with care.</description> <name>yarn.nodemanager.runtime.linux.runc.host-pid-namespace.allowed</name> <value>false</value> </property> <property> <description>The default list of read-only mounts to be bind-mounted into all runC containers that use RuncContainerRuntime.</description> <name>yarn.nodemanager.runtime.linux.runc.default-ro-mounts</name> <value></value> </property> <property> <description>The default list of read-write mounts to be bind-mounted into all runC containers that use RuncContainerRuntime.</description> <name>yarn.nodemanager.runtime.linux.runc.default-rw-mounts</name> <value></value> </property> <property> <description>Path to the seccomp profile to use with runC containers</description> <name>yarn.nodemanager.runtime.linux.runc.seccomp-profile</name> <value></value> </property> <property> <description>The HDFS location where the runC image tag to hash file exists.</description> <name>yarn.nodemanager.runtime.linux.runc.image-tag-to-manifest-plugin.hdfs-hash-file</name> <value>/runc-root/image-tag-to-hash</value> </property> <property> <description>The local file system location where the runC image tag to hash file exists.</description> <name>yarn.nodemanager.runtime.linux.runc.image-tag-to-manifest-plugin.local-hash-file</name> <value></value> </property> <property> <description>The interval in seconds between refreshing the hdfs image tag to hash cache.</description> <name>yarn.nodemanager.runtime.linux.runc.image-tag-to-manifest-plugin.cache-refresh-interval-secs</name> <value>60</value> </property> <property> <description>The number of manifests to cache in the image tag to hash cache.</description> <name>yarn.nodemanager.runtime.linux.runc.image-tag-to-manifest-plugin.num-manifests-to-cache</name> <value>10</value> </property> <property> <description>The timeout value in seconds for the values in the stat cache.</description> <name>yarn.nodemanager.runtime.linux.runc.hdfs-manifest-to-resources-plugin.stat-cache-timeout-interval-secs</name> <value>360</value> </property> <property> <description>The size of the stat cache which stores stats of the layers and config.</description> <name>yarn.nodemanager.runtime.linux.runc.hdfs-manifest-to-resources-plugin.stat-cache-size</name> <value>500</value> </property> </configuration>
さらに、container-executor.cfg ファイルが存在し、コンテナ実行プログラムの設定が含まれている必要があります。このファイルは、root が所有し、0400 の権限を持つ必要があります。ファイルの形式は標準的な Java プロパティファイル形式です(例:)。
`key=value`
runC のサポートを有効にするには、次のプロパティが必要です。
設定名 | 説明 |
---|---|
yarn.nodemanager.linux-container-executor.group |
NodeManager の Unix グループ。yarn-site.xml ファイルの yarn.nodemanager.linux-container-executor.group と一致する必要があります。 |
container-executor.cfg には、コンテナに許可される機能を決定するセクションが含まれている必要があります。次のプロパティが含まれています。
設定名 | 説明 |
---|---|
module.enabled |
runC コンテナの起動を有効または無効にするには、「true」または「false」にする必要があります。デフォルト値は 0 です。 |
runc.binary |
runC コンテナの起動に使用されるバイナリ。デフォルトは /usr/bin/runc です。 |
runc.run-root |
すべてのランタイムマウントとオーバーレイマウントが配置されるディレクトリ。 |
runc.allowed.ro-mounts |
コンテナが読み取り専用モードでマウントできるディレクトリをコンマで区切ったリスト。デフォルトでは、どのディレクトリもマウントできません。 |
runc.allowed.rw-mounts |
コンテナが読み書きモードでマウントできるディレクトリをコンマで区切ったリスト。デフォルトでは、どのディレクトリもマウントできません。 |
YARN ローカルディレクトリへのアクセスを必要とする runC コンテナを実行する場合は、それらを runc.allowed.rw-mounts リストに追加する必要があることに注意してください。
さらに、コンテナは、container-executor.cfg ディレクトリの親ディレクトリを読み書きモードでマウントすることは許可されていません。
次のプロパティはオプションです。
設定名 | 説明 |
---|---|
min.user.id |
アプリケーションの起動が許可される最小 UID。デフォルトでは最小値はありません。 |
banned.users |
アプリケーションの起動が許可されないユーザー名のコンマ区切りリスト。デフォルト設定は yarn、mapred、hdfs、bin です。 |
allowed.system.users |
構成された最小値を下回る UID であっても、アプリケーションの起動が許可されるユーザー名のコンマ区切りリスト。allowed.system.users と banned.users の両方にユーザーが表示されている場合、そのユーザーは禁止されたと見なされます。 |
feature.tc.enabled |
「true」または「false」にする必要があります。「false」はトラフィック制御コマンドが無効になっていることを意味し、「true」はトラフィック制御コマンドが許可されていることを意味します。 |
feature.yarn.sysfs.enabled |
「true」または「false」にする必要があります。詳細は YARN sysfs のサポートを参照してください。デフォルト設定は無効です。 |
runC コンテナの起動を許可する container-executor.cfg の一部を以下に示します。
yarn.nodemanager.linux-container-executor.group=yarn [runc] module.enabled=true runc.binary=/usr/bin/runc runc.run-root=/run/yarn-container-executor runc.allowed.ro-mounts=/sys/fs/cgroup runc.allowed.rw-mounts=/var/hadoop/yarn/local-dir,/var/hadoop/yarn/log-dir
runC コンテナは、Docker イメージから派生したイメージ内で実行されます。Docker イメージは、一連の squashFS ファイルイメージに変換され、HDFS にアップロードされます。YARN で動作するには、これらの Docker イメージにはいくつかの要件があります。
runC コンテナは、アプリケーション所有者をコンテナユーザーとして明示的に起動されます。アプリケーション所有者が Docker イメージで有効なユーザーでない場合、アプリケーションは失敗します。コンテナユーザーはユーザーの UID で指定されます。NodeManager ホストと Docker イメージの間でユーザーの UID が異なる場合、コンテナは間違ったユーザーとして起動されるか、UID が存在しないために起動に失敗する可能性があります。詳細については、runC コンテナでのユーザー管理セクションを参照してください。
Docker イメージには、アプリケーションの実行に必要なものが含まれている必要があります。Hadoop(MapReduce または Spark)の場合、Docker イメージには JRE と Hadoop ライブラリが含まれており、必要な環境変数(JAVA_HOME、HADOOP_COMMON_PATH、HADOOP_HDFS_HOME、HADOOP_MAPRED_HOME、HADOOP_YARN_HOME、HADOOP_CONF_DIR)が設定されている必要があります。Docker イメージで使用可能な Java および Hadoop コンポーネントのバージョンは、クラスタにインストールされているものや、同じジョブの他のタスクに使用されている他の Docker イメージとの互換性がある必要があります。そうでない場合、runC コンテナで開始された Hadoop コンポーネントは、外部の Hadoop コンポーネントと通信できなくなる可能性があります。
/bin/bash
はイメージ内で使用可能である必要があります。これは一般的に当てはまりますが、小さな Docker イメージ(シェルコマンドに busybox を使用するものなど)には bash がインストールされていない場合があります。この場合、次のエラーが表示されます。
Container id: container_1561638268473_0015_01_000002 Exit code: 7 Exception message: Launch container failed Shell error output: /usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:235: starting container process caused "exec: \"bash\": executable file not found in $PATH". Shell output: main : command provided 4
find
コマンドもイメージ内で使用可能である必要があります。find
がない場合、このエラーが発生します。
Container exited with a non-zero exit code 127. Error file: prelaunch.err. Last 4096 bytes of prelaunch.err : /tmp/hadoop-systest/nm-local-dir/usercache/hadoopuser/appcache/application_1561638268473_0017/container_1561638268473_0017_01_000002/launch_container.sh: line 44: find: command not found
Docker イメージにエントリポイントが設定されている場合、エントリポイントは、コンテナの起動コマンドをその引数として実行されます。
Dockerイメージから派生したrunCイメージは、他のローカライズされたリソースと同様に、runCコンテナが実行されるホストにローカライズされます。MapReduceとSparkはどちらも、進捗状況の報告に10分以上かかるタスクは停止していると仮定しているため、イメージサイズが大きいと、ローカライズに時間がかかりすぎてアプリケーションが失敗する可能性があります。
すべてのDockerイメージは、以下の3つの要素で構成されています。- ファイルシステムを作成する一連のレイヤー。- イメージの環境に関する情報を保持する設定ファイル。- どのようなレイヤーと設定がそのイメージに必要なかを記述するマニフェスト。
これら3つの要素が組み合わさり、Open Container Initiative (OCI)準拠のイメージが作成されます。runCはOCI準拠のコンテナ上で動作しますが、小さな違いがあります。runCランタイムが使用する各レイヤーは、squashFSファイルシステムに圧縮されます。squashFSレイヤー、設定ファイル、マニフェストは、イメージタグとそれに関連付けられたマニフェストのマッピングを記述するimage-tag-to-hash mapping
ファイルと共にHDFSにアップロードされます。これらすべてを設定するのは複雑で面倒なプロセスです。変換プロセスを支援するための、docker-to-squash.py
という非公式のPythonスクリプトを含むパッチがYARN-9564にあります。このツールは、入力としてDockerイメージを受け取り、そのすべてのレイヤーをsquashFSファイルシステムに変換し、squashFSレイヤー、設定ファイル、マニフェストをrunc-rootの下にあるHDFSにアップロードします。また、image-tag-to-hash
マッピングファイルを作成または更新します。以下は、centos:latest
という名前のイメージをrunCイメージ名centos
でHDFSにアップロードするためのスクリプトの呼び出し例です。
[user@foobar sbin]$ pwd /home/user/hadoop/hadoop-dist/target/hadoop-3.3.0-SNAPSHOT/sbin [user@foobar sbin]$ ls distribute-exclude.sh hadoop-daemons.sh refresh-namenodes.sh start-dfs.cmd start-yarn.sh stop-dfs.cmd stop-yarn.sh docker_to_squash.py httpfs.sh start-all.cmd start-dfs.sh stop-all.cmd stop-dfs.sh workers.sh FederationStateStore kms.sh start-all.sh start-secure-dns.sh stop-all.sh stop-secure-dns.sh yarn-daemon.sh hadoop-daemon.sh mr-jobhistory-daemon.sh start-balancer.sh start-yarn.cmd stop-balancer.sh stop-yarn.cmd yarn-daemons.sh [user@foobar sbin]$ hadoop fs -ls / Found 3 items drwxrwx--- - user supergroup 0 2019-08-07 19:35 /home drwx------ - user supergroup 0 2019-08-07 19:35 /tmp drwx------ - user supergroup 0 2019-08-07 19:35 /user [user@foobar sbin]$ ./docker_to_squash.py --working-dir /tmp --log=DEBUG pull-build-push-update centos:latest,centos DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'version'] DEBUG: command: ['skopeo', '-v'] DEBUG: command: ['mksquashfs', '-version'] DEBUG: args: Namespace(LOG_LEVEL='DEBUG', check_magic_file=False, force=False, func=<function pull_build_push_update at 0x7fe6974cd9b0>, hadoop_prefix='/hadoop-2.8.6-SNAPSHOT', hdfs_root='/runc-root', image_tag_to_hash='image-tag-to-hash', images_and_tags=['centos:latest,centos'], magic_file='etc/dockerfile-version', pull_format='docker', replication=1, skopeo_format='dir', sub_command='pull-build-push-update', working_dir='/tmp') DEBUG: extra: [] DEBUG: image-tag-to-hash: image-tag-to-hash DEBUG: LOG_LEVEL: DEBUG DEBUG: HADOOP_BIN_DIR: /hadoop-2.8.6-SNAPSHOT/bin DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', '/runc-root'] ls: `/runc-root': No such file or directory DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-mkdir', '/runc-root'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', '/runc-root'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-chmod', '755', '/runc-root'] DEBUG: Setting up squashfs dirs: ['/runc-root/layers', '/runc-root/config', '/runc-root/manifests'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', '/runc-root/layers'] ls: `/runc-root/layers': No such file or directory DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-mkdir', '/runc-root/layers'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', '/runc-root/layers'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-chmod', '755', '/runc-root/layers'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', '/runc-root/config'] ls: `/runc-root/config': No such file or directory DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-mkdir', '/runc-root/config'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', '/runc-root/config'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-chmod', '755', '/runc-root/config'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', '/runc-root/manifests'] ls: `/runc-root/manifests': No such file or directory DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-mkdir', '/runc-root/manifests'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', '/runc-root/manifests'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-chmod', '755', '/runc-root/manifests'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', '/runc-root/image-tag-to-hash'] ls: `/runc-root/image-tag-to-hash': No such file or directory INFO: Working on image centos:latest with tags ['centos'] DEBUG: command: ['skopeo', 'inspect', '--raw', 'docker://centos:latest'] DEBUG: skopeo inspect --raw returned a list of manifests DEBUG: amd64 manifest sha is: sha256:ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66 DEBUG: command: ['skopeo', 'inspect', '--raw', u'docker://centos@sha256:ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66'] INFO: manifest: {u'layers': [{u'mediaType': u'application/vnd.docker.image.rootfs.diff.tar.gzip', u'digest': u'sha256:8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df', u'size': 75403831}], u'schemaVersion': 2, u'config': {u'mediaType': u'application/vnd.docker.container.image.v1+json', u'digest': u'sha256:9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1', u'size': 2182}, u'mediaType': u'application/vnd.docker.distribution.manifest.v2+json'} INFO: manifest: {u'layers': [{u'mediaType': u'application/vnd.docker.image.rootfs.diff.tar.gzip', u'digest': u'sha256:8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df', u'size': 75403831}], u'schemaVersion': 2, u'config': {u'mediaType': u'application/vnd.docker.container.image.v1+json', u'digest': u'sha256:9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1', u'size': 2182}, u'mediaType': u'application/vnd.docker.distribution.manifest.v2+json'} DEBUG: Layers: [u'8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df'] DEBUG: Config: 9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1 DEBUG: hash_to_tags is null. Not removing tag centos DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', '/runc-root/manifests/ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66'] ls: `/runc-root/manifests/ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66': No such file or directory DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', u'/runc-root/config/9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1'] ls: `/runc-root/config/9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1': No such file or directory DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', u'/runc-root/layers/8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df.sqsh'] ls: `/runc-root/layers/8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df.sqsh': No such file or directory DEBUG: skopeo_dir: /tmp/docker-to-squash/centos:latest INFO: Pulling image: centos:latest DEBUG: command: ['skopeo', 'copy', 'docker://centos:latest', 'dir:/tmp/docker-to-squash/centos:latest'] INFO: Squashifying and uploading layer: 8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', u'/runc-root/layers/8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df.sqsh'] ls: `/runc-root/layers/8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df.sqsh': No such file or directory DEBUG: command: ['sudo', 'tar', '-C', u'/tmp/docker-to-squash/expand_archive_8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df', '--xattrs', "--xattrs-include='*'", '-xzf', u'/tmp/docker-to-squash/centos:latest/8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df'] DEBUG: command: ['sudo', 'find', u'/tmp/docker-to-squash/expand_archive_8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df', '-name', '.wh.*'] DEBUG: command: ['sudo', 'mksquashfs', u'/tmp/docker-to-squash/expand_archive_8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df', u'/tmp/docker-to-squash/centos:latest/8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df.sqsh'] DEBUG: command: ['sudo', 'rm', '-rf', u'/tmp/docker-to-squash/expand_archive_8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', u'/runc-root/layers/8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df.sqsh'] ls: `/runc-root/layers/8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df.sqsh': No such file or directory DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-put', u'/tmp/docker-to-squash/centos:latest/8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df.sqsh', u'/runc-root/layers/8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df.sqsh'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-setrep', '1', u'/runc-root/layers/8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df.sqsh'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-chmod', '444', u'/runc-root/layers/8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df.sqsh'] INFO: Uploaded file /runc-root/layers/8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df.sqsh with replication 1 and permissions 444 DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', u'/runc-root/config/9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1'] ls: `/runc-root/config/9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1': No such file or directory DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-put', u'/tmp/docker-to-squash/centos:latest/9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1', u'/runc-root/config/9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-setrep', '1', u'/runc-root/config/9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-chmod', '444', u'/runc-root/config/9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1'] INFO: Uploaded file /runc-root/config/9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1 with replication 1 and permissions 444 DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-ls', '/runc-root/manifests/ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66'] ls: `/runc-root/manifests/ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66': No such file or directory DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-put', '/tmp/docker-to-squash/centos:latest/manifest.json', '/runc-root/manifests/ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-setrep', '1', '/runc-root/manifests/ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-chmod', '444', '/runc-root/manifests/ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66'] INFO: Uploaded file /runc-root/manifests/ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66 with replication 1 and permissions 444 DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-put', '-f', '/tmp/docker-to-squash/image-tag-to-hash', '/runc-root/image-tag-to-hash'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-setrep', '1', '/runc-root/image-tag-to-hash'] DEBUG: command: ['/hadoop-2.8.6-SNAPSHOT/bin/hadoop', 'fs', '-chmod', '444', '/runc-root/image-tag-to-hash'] DEBUG: command: ['sudo', 'rm', '-rf', '/tmp/docker-to-squash'] [user@foobar sbin]$ hadoop fs -ls / Found 4 items drwxrwx--- - user supergroup 0 2019-08-07 19:35 /home drwxr-xr-x - user supergroup 0 2019-08-08 22:38 /runc-root drwx------ - user supergroup 0 2019-08-07 19:35 /tmp drwx------ - user supergroup 0 2019-08-07 19:35 /user [user@foobar sbin]$ hadoop fs -ls /runc-root/* Found 1 items -r--r--r-- 1 user supergroup 2182 2019-08-08 22:38 /runc-root/config/9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1 -r--r--r-- 1 user supergroup 86 2019-08-08 22:38 /runc-root/image-tag-to-hash Found 1 items -r--r--r-- 1 user supergroup 73625600 2019-08-08 22:38 /runc-root/layers/8ba884070f611d31cb2c42eddb691319dc9facf5e0ec67672fcfa135181ab3df.sqsh Found 1 items -r--r--r-- 1 user supergroup 529 2019-08-08 22:38 /runc-root/manifests/ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66
runCコンテナの起動を試みる前に、通常のYARNコンテナを要求するアプリケーションに対してLCE構成が機能していることを確認してください。LCEを有効にした後に1つ以上のNodeManagerが起動に失敗した場合は、コンテナ実行可能ファイルの所有権またはパーミッションが正しくないことが原因である可能性が高いため、ログを確認して確認してください。
runCコンテナでアプリケーションを実行するには、アプリケーションの環境で次の環境変数を設定します。
環境変数名 | 説明 |
---|---|
YARN_CONTAINER_RUNTIME_TYPE |
アプリケーションがrunCコンテナで起動されるかどうかを決定します。値が「runc」の場合、アプリケーションはrunCコンテナで起動されます。それ以外の場合は、通常のプロセストリコンテナが使用されます。 |
YARN_CONTAINER_RUNTIME_RUNC_IMAGE |
runCコンテナの起動に使用されるイメージ名を指定します。 |
YARN_CONTAINER_RUNTIME_RUNC_CONTAINER_HOSTNAME |
runCコンテナで使用されるホスト名を設定します。 |
YARN_CONTAINER_RUNTIME_RUNC_MOUNTS |
runCコンテナに追加のボリュームマウントを追加します。環境変数の値は、コンマ区切りのマウントリストである必要があります。そのようなマウントはすべて「ソース:宛先:モード」として指定する必要があり、モードは「ro」(読み取り専用)または「rw」(読み書き)で、要求されるアクセスタイプを指定します。どちらも指定されていない場合は、読み書きが想定されます。要求されたマウントは、runc.allowed.ro-mountsとrunc.allowed.rw-mountsで設定された値に基づいて、container-executorによって検証されます。 |
最初の2つは必須です。残りは必要に応じて設定できます。環境変数を通じてコンテナの種類を制御することは、理想的ではありませんが、YARNのrunCサポートを認識していないアプリケーション(MapReduceやSparkなど)でも、アプリケーション環境の設定をサポートすることで、runCの利点を活用できます。
注記コンテナ内の/tmpまたは/var/tmpに何かをマウントすると、ランタイムは機能しません。
runCコンテナで起動されるようにアプリケーションが提出されると、そのアプリケーションは他のYARNアプリケーションとまったく同じように動作します。ログは集約され、関連する履歴サーバーに保存されます。アプリケーションのライフサイクルは、非runCアプリケーションの場合と同じです。
警告この機能を有効にする際には注意が必要です。/、/etc、/run、/homeなど(これらに限定されません)のディレクトリへのアクセスを有効にすることはお勧めできません。ホストに悪影響を与えたり、機密情報を漏洩したりする可能性があります。警告
ホストからのファイルとディレクトリは、runCコンテナ内では一般的に必要であり、runCはコンテナへのマウントを通じてこれらを供給します。例としては、ローカライズされたリソース、Apache Hadoopバイナリ、ソケットなどがあります。
コンテナに何かをマウントするには、以下の設定が必要です。
runc.allowed.ro-mounts
とrunc.allowed.rw-mounts
をマウントを許可する親ディレクトリのリストに設定することで、container-executor.cfgでボリュームホワイトリストを定義する必要があります。管理者によって提供されたホワイトリストは、コンテナにマウントを許可するディレクトリのコンマ区切りリストとして定義されます。ユーザーが提供したソースディレクトリは、指定されたディレクトリと一致するか、その子である必要があります。
ユーザーが提供したマウントリストは、ソース:宛先またはソース:宛先:モードの形式でコンマ区切りリストとして定義されます。ソースはホスト上のファイルまたはディレクトリです。宛先は、ソースがバインドマウントされるコンテナ内のパスです。モードは、ユーザーがマウントに期待するモードを定義し、「ro」(読み取り専用)または「rw」(読み書き)にすることができます。指定しない場合は、「rw」が想定されます。モードには、バインドプロパゲーションオプション(shared、rshared、slave、rslave、private、rprivate)を含めることもできます。その場合、モードはオプション、rw+オプション、またはro+オプションの形式にする必要があります。
次の例は、この機能を使用して、YARNで実行されているコンテナに一般的に必要な/sys/fs/cgroupディレクトリをマウントする方法を示しています。
管理者は、container-executor.cfgでrunc.allowed.ro-mountsを「/sys/fs/cgroup」に設定します。アプリケーションは、読み取り専用モードでホストからコンテナに「/sys/fs/cgroup」をマウントすることを要求できるようになります。
NodeManagerは、yarn-site.xmlのyarn.nodemanager.runtime.linux.runc.default-ro-mount
とyarn.nodemanager.runtime.linux.runc.default-rw-mounts
を介して、コンテナに追加される読み取り専用または読み書きマウントのデフォルトリストを設定するオプションがあります。この例では、yarn.nodemanager.runtime.linux.runc.default-ro-mounts
は/sys/fs/cgroup:/sys/fs/cgroup
に設定されます。
YARNのrunCコンテナサポートは、NodeManagerホストで定義されているユーザーのuid:gid IDを使用してコンテナプロセスを起動します。NodeManagerホストとコンテナ間のユーザー名とグループ名の不一致は、パーミッションの問題、コンテナ起動の失敗、またはセキュリティホールにつながる可能性があります。ホストとコンテナの両方でユーザーとグループの管理を集中化することで、これらのリスクを大幅に軽減できます。YARNでコンテナ化されたアプリケーションを実行する際には、コンテナのプロセスを起動するために使用されるuid:gidペアを理解する必要があります。
uid:gidペアの意味の例として、以下を検討してください。デフォルトでは、非セキュアモードでは、YARNはユーザーnobody
としてプロセスを起動します(ユーザーとしての起動方法については、YARNでのcgroupの使用の一番下の表を参照してください)。CentOSベースのシステムでは、nobody
ユーザーのuidは99
、nobody
グループは99
です。その結果、YARNはuid 99
とgid 99
でrunCを呼び出します。コンテナ内にnobody
ユーザーのuidが99
でない場合、起動が失敗するか、予期しない結果になる可能性があります。
ユーザーとグループの管理に対処する方法はたくさんあります。runCはデフォルトで、コンテナ内の/etc/passwd
(および/etc/shadow
)に対してユーザーを認証します。runCイメージに提供されるデフォルトの/etc/passwd
には、適切なユーザーエントリが含まれていない可能性が高いため、起動に失敗します。ユーザーとグループの管理を集中化することを強くお勧めします。ユーザーとグループの管理に関するいくつかのアプローチを以下に示します。
ユーザーとグループを管理する最も基本的なアプローチは、runCイメージ内のユーザーとグループを変更することです。このアプローチは、すべてのコンテナプロセスが単一の既知のユーザー(たとえばnobody
)として起動される非セキュアモードでのみ有効です。この場合、唯一の要件は、nobodyユーザーとグループのuid:gidペアがホストとコンテナ間で一致する必要があることです。CentOSベースのシステムでは、これはコンテナ内のnobodyユーザーにUID 99
、nobodyグループにGID 99
が必要であることを意味します。
UIDとGIDを変更する1つの方法は、usermod
とgroupmod
を利用することです。以下は、nobodyユーザー/グループに正しいUIDとGIDを設定します。
usermod -u 99 nobody groupmod -g 99 nobody
このアプローチは、ユーザーを追加する柔軟性が低いことを考慮すると、テスト以外では推奨されません。
組織がすでに各システムにローカルユーザーを作成するための自動化を導入している場合、コンテナイメージを直接変更する代わりに、/etc/passwdと/etc/groupをコンテナにバインドマウントする方が適切な場合があります。/etc/passwdと/etc/groupのバインドマウント機能を有効にするには、container-executor.cfg
のrunc.allowed.ro-mounts
を更新して、これらのパスを含めます。runCでこれを機能させるには、「yarn.nodemanager.runtime.linux.runc.default-ro-mounts」に/etc/passwd:/etc/passwd:ro
と/etc/group:/etc/group:ro
を含める必要があります。
このバインドマウントアプローチには、考慮すべきいくつかの課題があります。
このアプローチは、実行中のコンテナを変更する柔軟性が低いことを考慮すると、テスト以外では推奨されません。
ユーザーとグループを一元的に管理できる代替アプローチとして、SSSDがあります。System Security Services Daemon (SSSD)は、LDAPやActive DirectoryなどのさまざまなIDと認証プロバイダーへのアクセスを提供します。
Linux認証の従来のスキーマは次のとおりです。
application -> libpam -> pam_authenticate -> pam_unix.so -> /etc/passwd
ユーザー検索にSSSDを使用する場合、次のようになります。
application -> libpam -> pam_authenticate -> pam_sss.so -> SSSD -> pam_unix.so -> /etc/passwd
SSSDが通信するUNIXソケットをコンテナにバインドマウントできます。これにより、SSSDクライアントサイドライブラリはホスト上で実行されているSSSDに対して認証できるようになります。その結果、ユーザー情報はDockerイメージの/etc/passwdに存在する必要がなくなり、SSSDによってサービスされるようになります。
ホストとコンテナのステップバイステップ設定
# yum -y install sssd-common sssd-proxy
# cat /etc/pam.d/sss_proxy auth required pam_unix.so account required pam_unix.so password required pam_unix.so session required pam_unix.so
# cat /etc/sssd/sssd/conf [sssd] services = nss,pam config_file_version = 2 domains = proxy [nss] [pam] [domain/proxy] id_provider = proxy proxy_lib_name = files proxy_pam_target = sss_proxy
# systemctl start sssd
# getent passwd -s sss localuser
SSSDのUNIXソケットがそこに存在するため、ホストの/var/lib/sss/pipesディレクトリをコンテナにバインドマウントすることが重要です。
-v /var/lib/sss/pipes:/var/lib/sss/pipes:rw
以下の手順はすべてコンテナ自体で実行する必要があります。
sssクライアントライブラリのみをインストールします
# yum -y install sssd-client
passwdおよびgroupデータベースに対してsssが構成されていることを確認します
/etc/nsswitch.conf
アプリケーションがSSSDを呼び出すために使用するPAMサービスを構成します
# cat /etc/pam.d/system-auth #%PAM-1.0 # This file is auto-generated. # User changes will be destroyed the next time authconfig is run. auth required pam_env.so auth sufficient pam_unix.so try_first_pass nullok auth sufficient pam_sss.so forward_pass auth required pam_deny.so account required pam_unix.so account [default=bad success=ok user_unknown=ignore] pam_sss.so account required pam_permit.so password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type= password sufficient pam_unix.so try_first_pass use_authtok nullok sha512 shadow password sufficient pam_sss.so use_authtok password required pam_deny.so session optional pam_keyinit.so revoke session required pam_limits.so -session optional pam_systemd.so session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid session required pam_unix.so session optional pam_sss.so
Dockerイメージを保存し、アプリケーションのベースイメージとして使用します。
YARN環境で起動したDockerイメージをテストします。
$ id uid=5000(localuser) gid=5000(localuser) groups=5000(localuser),1337(hadoop)
この例では、Hadoopが/usr/local/hadoop
にインストールされていることを前提としています。
また、Dockerイメージを圧縮してHDFSにアップロードする必要があります。runCで使用できるイメージに変換する方法については、DockerイメージをrunCイメージに変換するを参照してください。この例では、hadoop-image
という名前のイメージが既に準備されていると仮定します。
さらに、container-executor.cfg
内のrunc.allowed.ro-mounts
が、/usr/local/hadoop,/etc/passwd,/etc/group
ディレクトリを含むように更新されています。
piジョブをrunCコンテナで実行するために提出するには、次のコマンドを実行します。
HADOOP_HOME=/usr/local/hadoop YARN_EXAMPLES_JAR=$HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar MOUNTS="$HADOOP_HOME:$HADOOP_HOME:ro,/etc/passwd:/etc/passwd:ro,/etc/group:/etc/group:ro" IMAGE_ID="hadoop-image" export YARN_CONTAINER_RUNTIME_TYPE=runc export YARN_CONTAINER_RUNTIME_RUNC_IMAGE=$IMAGE_ID export YARN_CONTAINER_RUNTIME_RUNC_MOUNTS=$MOUNTS yarn jar $YARN_EXAMPLES_JAR pi \ -Dmapreduce.map.env.YARN_CONTAINER_RUNTIME_TYPE=runc \ -Dmapreduce.map.env.YARN_CONTAINER_RUNTIME_RUNC_MOUNTS=$MOUNTS \ -Dmapreduce.map.env.YARN_CONTAINER_RUNTIME_RUNC_IMAGE=$IMAGE_ID \ -Dmapreduce.reduce.env.YARN_CONTAINER_RUNTIME_TYPE=runc \ -Dmapreduce.reduce.env.YARN_CONTAINER_RUNTIME_RUNC_MOUNTS=$MOUNTS \ -Dmapreduce.reduce.env.YARN_CONTAINER_RUNTIME_RUNC_IMAGE=$IMAGE_ID \ 1 40000
アプリケーションマスター、マップタスク、およびリデュースタスクは個別に構成されていることに注意してください。この例では、3つすべてにhadoop-image
イメージを使用しています。
この例では、Hadoopが/usr/local/hadoop
に、Sparkが/usr/local/spark
にインストールされていることを前提としています。
また、Dockerイメージを圧縮してHDFSにアップロードする必要があります。runCで使用できるイメージに変換する方法については、DockerイメージをrunCイメージに変換するを参照してください。この例では、hadoop-image
という名前のイメージが既に準備されていると仮定します。
さらに、container-executor.cfg
内のrunc.allowed.ro-mounts
が、/usr/local/hadoop,/etc/passwd,/etc/group
ディレクトリを含むように更新されています。
runCコンテナでSparkシェルを実行するには、次のコマンドを実行します。
HADOOP_HOME=/usr/local/hadoop SPARK_HOME=/usr/local/spark MOUNTS="$HADOOP_HOME:$HADOOP_HOME:ro,/etc/passwd:/etc/passwd:ro,/etc/group:/etc/group:ro" IMAGE_ID="hadoop-image" $SPARK_HOME/bin/spark-shell --master yarn \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=runc \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_RUNC_IMAGE=$IMAGE_ID \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_RUNC_MOUNTS=$MOUNTS \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=runc \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_RUNC_IMAGE=$IMAGE_ID \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_RUNC_MOUNTS=$MOUNTS
アプリケーションマスターとエグゼキュータは個別に構成されていることに注意してください。この例では、両方ともhadoop-image
イメージを使用しています。