hive.server2.enable.doAs
の設定によって何がどう変わるかよく分からなかったので Apache Bigtop を使って調べてみました。
hive.server2.enable.doAs
だと長くて煩雑なので以下では適宜 doAs と略しています。
先にまとめ。調べた結果を基に書いていますが、厳密な裏付けはありません(ソースを読んで調べたりはしていません)。
hadoop.proxyuser.〜
で設定するhive.server2.enable.doAs
が false の場合、なりすましを行わず、-n
オプションで指定するhive.server2.enable.doAs
で設定しているのは要するに何なのかということで言えば、「Hadoop の proxy user 機能を利用するかどうか」と思ってよさそうな挙動でした。なので、利用する場合は proxy user についても知る必要があります。
※1 Apache Hadoop 2.8.5 – Proxy user - Superusers Acting On Behalf Of Other Users によれば、ホストによる指定、グループによる指定、ユーザによる指定を組み合わせて指定できるようです。
Bigtop は下記の時点の master を使っています。
34e0bd7182c713b16dce9a4bdc803c8ed7fb9eb3
Thu Jun 11 09:01:26 2020 +0000
Setting Up HiveServer2 - Apache Hive - Apache Software Foundation
Impersonation By default HiveServer2 performs the query processing as the user who submitted the query. But if the following parameter is set to false, the query will run as the user that the hiveserver2 process runs as. hive.server2.enable.doAs – Impersonate the connected user, default true.
impersonate は「なりすます」という意味。エラーメッセージでも出てきます。
設定を変えてプロビジョニングしなおすのを繰り返すやり方だと時間がかかってしまうので、Bigtop のリポジトリをクローンしたディレクトリを2つ用意して true/false それぞれの設定にします。
デフォルトでは true なので、false の方のディレクトリのみ hive-site.xml
を修正。
--- a/bigtop-deploy/puppet/modules/hadoop_hive/templates/hive-site.xml
+++ b/bigtop-deploy/puppet/modules/hadoop_hive/templates/hive-site.xml
@@ -81,7 +81,7 @@
<property>
<name>hive.server2.enable.doAs</name>
- <value>true</value>
+ <value>false</value>
</property>
<property>
config_centos-7.yaml
を修正して Hive コンポーネントを追加。
--- a/provisioner/docker/config_centos-7.yaml
+++ b/provisioner/docker/config_centos-7.yaml
@@ -19,6 +19,6 @@ docker:
repo: "http://repos.bigtop.apache.org/releases/1.4.0/centos/7/$basearch"
distro: centos
-components: [hdfs, yarn, mapreduce]
+components: [hdfs, yarn, mapreduce, hive]
enable_local_repo: false
smoke_test_components: [hdfs, yarn, mapreduce]
設定の変更はこれだけ。
単一ノードで create します。
time ./docker-hadoop.sh -C config_centos-7.yaml --create 1
これで Hadoop と Hive が使えるようになります。Bigtop すばらしい……ありがたや……。
コンテナに入る。
./docker-hadoop.sh --exec 1 bash
以下、コンテナ内の作業。
testuser というユーザがすでに存在しているので、そっちにスイッチします。
(こういう用途で使うために用意されているものなのか分かっていませんが、とりあえず一般ユーザのつもりで使います)
su - testuser
beeline で hiverserver2 に接続
beeline -u "jdbc:hive2://localhost:10000"
Error: Could not open client transport with JDBC Uri:
jdbc:hive2://localhost:10000: Failed to open new session:
java.lang.RuntimeException:
org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.authorize.AuthorizationException):
User: hive is not allowed to impersonate anonymous (state=08S01,code=0)
この場合は -n
オプションでユーザ名を指定すると接続できるようになります。
beeline -u "jdbc:hive2://localhost:10000" -n testuser
ちなみに、Bigtop の既定の設定では hiveserver2 は hive ユーザで実行されますが、hiveserver2 を root ユーザで実行すると次のようなメッセージになります。
User: root is not allowed to impersonate anonymous (state=08S01,code=0)
^^^^
ここが変わる
「hiveserver2 の実行ユーザが他のユーザになりすます」ということが試みられているようです。
OSに存在しないユーザ名を指定した場合
beeline -u "jdbc:hive2://localhost:10000" -n nobody
doAs=false の場合、 -n
オプションによる指定はいずれにせよ無視されるということでしょうか。
$ beeline -u "jdbc:hive2://localhost:10000" -n testuser
create database test_db1;
=> 成功する
$ hdfs dfs -ls /user/hive/warehouse
Found 1 items
drwxrwxrwx - testuser hadoop 0 2020-06-27 05:38 /user/hive/warehouse/test_db1.db
所有者=testuser でデータベースのディレクトリが作られました。
一応 -n testuser
を付けてみます。
$ beeline -u "jdbc:hive2://localhost:10000" -n testuser
create database test_db1;
=> 成功する
$ hdfs dfs -ls /user/hive/warehouse
Found 1 items
drwxrwxrwx - hive hadoop 0 2020-06-27 05:41 /user/hive/warehouse/test_db1.db
やはり -n
の指定は無視され、所有者=hive でディレクトリが作られました。
$ beeline -u "jdbc:hive2://localhost:10000" -n testuser
use test_db1;
create table test1 (name string);
insert into test1 values ('foo'), ('bar');
Error: org.apache.hive.service.cli.HiveSQLException: Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask. Permission denied: user=testuser, access=WRITE, inode="/user":hdfs:hadoop:drwxr-xr-x
insert 時に /user
のパーミッションで怒られました。
ちなみに test1
テーブルは 所有者=testuser で作られています。
$ hdfs dfs -ls /user/hive/warehouse/test_db1.db
Found 1 items
drwxrwxrwx - testuser hadoop 0 2020-06-27 09:48 /user/hive/warehouse/test_db1.db/test1
hdfs:///user
に実行権限を付けて再度 insert。
# sudo -u hdfs hdfs dfs -chmod 777 /user
$ beeline -u "jdbc:hive2://localhost:10000" -n testuser
use test_db1;
insert into test1 values ('foo'), ('bar');
今度は成功しました。
$ hdfs dfs -ls /user/hive/warehouse/test_db1.db/test1
Found 1 items
-rwxrwxrwx 3 testuser hadoop 8 2020-06-27 09:55 /user/hive/warehouse/test_db1.db/test1/000000_0
$ hdfs dfs -text /user/hive/warehouse/test_db1.db/test1/000000_0
foo
bar
データは所有者=testuser で作られています。
$ beeline -u "jdbc:hive2://localhost:10000" -n testuser
use test_db1;
create table test1 (name string);
insert into test1 values ('foo'), ('bar');
こちらはエラーになりませんでした。
$ hdfs dfs -ls /user/hive/warehouse/test_db1.db
Found 1 items
drwxrwxrwx - hive hadoop 0 2020-06-27 09:58 /user/hive/warehouse/test_db1.db/test1
$ hdfs dfs -ls /user/hive/warehouse/test_db1.db/test1
Found 1 items
-rwxrwxrwx 3 hive hadoop 8 2020-06-27 09:58 /user/hive/warehouse/test_db1.db/test1/000000_0
テーブルのディレクトリとデータは所有者=hive で作られています。
table_ext
というテーブルを作り、/user/testuser
の下にデータを置くことにします。
$ hdfs dfs -ls /user
...
drwx------ - testuser hadoop 0 2020-06-27 09:54 /user/testuser
...
beeline -u "jdbc:hive2://localhost:10000" -n testuser
use test_db1;
create external table table_ext (name string)
location '/user/testuser/table_ext/';
insert into table table_ext values ('foo'), ('bar');
$ hdfs dfs -ls /user/testuser/
Found 2 items
drwx------ - testuser hadoop 0 2020-06-27 10:22 /user/testuser/.staging
drwx------ - testuser hadoop 0 2020-06-27 10:22 /user/testuser/table_ext
$ hdfs dfs -ls /user/testuser/table_ext
Found 1 items
-rwx------ 3 testuser hadoop 8 2020-06-27 10:22 /user/testuser/table_ext/000000_0
$ hdfs dfs -text /user/testuser/table_ext/000000_0
foo
bar
こちらは hdfs:///user/testuser/
ディレクトリが存在しなかったので、hdfs:///tmp/
の下にデータを置くことにします。
beeline -u "jdbc:hive2://localhost:10000" -n testuser
use test_db1;
create external table table_ext (name string)
location '/tmp/table_ext/';
insert into table table_ext values ('foo'), ('bar');
$ hdfs dfs -ls /tmp/
Found 3 items
drwxrwxrwx - mapred mapred 0 2020-06-27 04:55 /tmp/hadoop-yarn
drwx-wx-wx - hive hadoop 0 2020-06-27 04:56 /tmp/hive
drwxrwxrwt - hive hadoop 0 2020-06-27 10:29 /tmp/table_ext
$ hdfs dfs -ls /tmp/table_ext
Found 1 items
-rwxrwxrwt 3 hive hadoop 8 2020-06-27 10:29 /tmp/table_ext/000000_0
$ hdfs dfs -text /tmp/table_ext/000000_0
foo
bar
doAs=false の場合の挙動はなんとなく分かってきましたが、doAs=true の場合のOSのユーザとの関係がよく分からないので、こんどはそこを調べてみます。
Hadoop の proxy user というしくみが関わっているようだったので、次の3パターンでどうなるか試します。
user_os
: OS のユーザのみ存在user_proxyuser
: proxy user の設定のみuser_both
: OS のユーザが存在し、かつ proxy user の設定もあり
データの配置場所が変わるだけだと思われたので外部テーブルについては省略。
設定ファイルを修正。下記は master からの差分です。Puppet に詳しくないので、 testuser を grep したりして当たりを付けて適当に修正しました。
--- a/bigtop-deploy/puppet/manifests/cluster.pp
+++ b/bigtop-deploy/puppet/manifests/cluster.pp
@@ -159,7 +159,7 @@ $roles_map = {
class hadoop_cluster_node (
$hadoop_security_authentication = hiera("hadoop::hadoop_security_authentication", "simple"),
- $bigtop_real_users = [ 'jenkins', 'testuser', 'hudson' ],
+ $bigtop_real_users = [ 'jenkins', 'testuser', 'hudson', 'user_os', 'user_both' ],
$cluster_components = ["all"]
) {
--- a/bigtop-deploy/puppet/modules/hadoop/manifests/init.pp
+++ b/bigtop-deploy/puppet/modules/hadoop/manifests/init.pp
@@ -20,7 +20,7 @@ class hadoop ($hadoop_security_authentication = "simple",
$hadoop_storage_dirs = split($::hadoop_storage_dirs, ";"),
$proxyusers = {
oozie => { groups => 'hudson,testuser,root,hadoop,jenkins,oozie,hive,httpfs,users', hosts => "*" },
- hive => { groups => 'hudson,testuser,root,hadoop,jenkins,oozie,hive,httpfs,users', hosts => "*" },
+ hive => { groups => 'hudson,testuser,user_both,user_proxyuser,root,hadoop,jenkins,oozie,hive,httpfs,users', hosts => "*" },
httpfs => { groups => 'hudson,testuser,root,hadoop,jenkins,oozie,hive,httpfs,users', hosts => "*" } },
$generate_secrets = false,
$kms_host = undef,
--- a/provisioner/docker/config_centos-7.yaml
+++ b/provisioner/docker/config_centos-7.yaml
@@ -19,6 +19,6 @@ docker:
repo: "http://repos.bigtop.apache.org/releases/1.4.0/centos/7/$basearch"
distro: centos
-components: [hdfs, yarn, mapreduce]
+components: [hdfs, yarn, mapreduce, hive]
enable_local_repo: false
smoke_test_components: [hdfs, yarn, mapreduce]
あと、調査1のときと同様に hdfs:///user
のパーミッションを変更しておきます。
# hdfs dfs -ls / | grep /user
drwxr-xr-x - hdfs hadoop 0 2020-06-28 03:13 /user
# sudo -u hdfs hdfs dfs -chmod 777 /user
# su - user_os
$ beeline -u "jdbc:hive2://localhost:10000" -n user_os
Error: Could not open client transport with JDBC Uri: jdbc:hive2://localhost:10000: Failed to open new session: java.lang.RuntimeException: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.authorize.AuthorizationException): User: hive is not allowed to impersonate user_os (state=08S01,code=0)
接続できない。
testuser を使います。
# su - testuser
$ beeline -u "jdbc:hive2://localhost:10000" -n user_proxyuser
Error: Could not open client transport with JDBC Uri: jdbc:hive2://localhost:10000: Failed to open new session: java.lang.RuntimeException: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.authorize.AuthorizationException): User: hive is not allowed to impersonate user_proxyuser (state=08S01,code=0)
接続できない。
# su - user_both
$ beeline -u "jdbc:hive2://localhost:10000" -n user_both
create database user_both_db;
use user_both_db;
create table table1 (name string);
insert into table1 values ('foo'), ('bar');
insert まで成功しました。
$ hdfs dfs -ls /user/hive/warehouse/
Found 1 items
drwxrwxrwx - user_both hadoop 0 2020-06-28 03:19 /user/hive/warehouse/user_both_db.db
$ hdfs dfs -ls /user/hive/warehouse/user_both_db.db/
Found 1 items
drwxrwxrwx - user_both hadoop 0 2020-06-28 03:22 /user/hive/warehouse/user_both_db.db/table1
$ hdfs dfs -ls /user/hive/warehouse/user_both_db.db/table1
Found 1 items
-rwxrwxrwx 3 user_both hadoop 8 2020-06-28 03:22 /user/hive/warehouse/user_both_db.db/table1/000000_0
それぞれ user_both
で作られています。testuser と同等の操作ができるようです。
user_os の場合接続の時点で失敗しましたが、user_os を proxy user で設定されているグループに所属させるとどうでしょうか。ためしに users
というグループでやってみます。
# id user_os
uid=1000(user_os) gid=1000(user_os) groups=1000(user_os)
# gpasswd -a user_os users
Adding user user_os to group users
# id user_os
uid=1000(user_os) gid=1000(user_os) groups=1000(user_os),100(users)
# su - user_os
$ beeline -u "jdbc:hive2://localhost:10000" -n user_os
=> OK
接続できました。insert までやってみます。
create database user_os_db;
use user_os_db;
create table table1 (name string);
insert into table1 values ('foo'), ('bar');
$ hdfs dfs -ls /user/hive/warehouse/
Found 2 items
drwxrwxrwx - user_both hadoop 0 2020-06-28 03:19 /user/hive/warehouse/user_both_db.db
drwxrwxrwx - user_os hadoop 0 2020-06-28 03:37 /user/hive/warehouse/user_os_db.db
$ hdfs dfs -ls /user/hive/warehouse/user_os_db.db/
Found 1 items
drwxrwxrwx - user_os hadoop 0 2020-06-28 03:37 /user/hive/warehouse/user_os_db.db/table1
$ hdfs dfs -ls /user/hive/warehouse/user_os_db.db/table1
Found 1 items
-rwxrwxrwx 3 user_os hadoop 8 2020-06-28 03:37 /user/hive/warehouse/user_os_db.db/table1/000000_0
所有者=user_os で作られました。なるほど。
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント