一、Data Lake Analytics介紹
資料湖(Data Lake)是時下大資料行業熱門的概念:
https://en.wikipedia.org/wiki/Data_lake。基于資料湖做分析,可以不用做任何ETL、資料搬遷等前置過程,實作跨各種異構資料源進行大資料關聯分析,進而極大的節省成本和提升使用者體驗。
阿裡雲資料湖分析産品Data Lake Analytics(簡稱DLA):
https://www.aliyun.com/product/datalakeanalytics産品文檔:
https://help.aliyun.com/product/70174.html下圖是DLA的簡易架構(__MPP計算引擎+存儲計算分離+彈性高可用+異構資料集源等)__:
二、自建賬号
目前DLA是以MySQL協定方式對外提供服務,使用者需要通過JDBC連接配接,連到DLA服務。DLA内部的賬号和密碼是獨立自建的(與RAM不同),對應的賬号和密碼資訊,在使用者開通DLA服務時以站内信、郵件、短信等方式通知您。
可能您會疑惑,為什麼DLA不是以RAM或AK賬号做認證和授權,而需要自建賬号。在這裡,做一些簡單的介紹:
- DLA是資料庫,在用戶端建立連接配接(需要認證)、通路庫、表、字段(需要鑒權)時,大量跨服務通路RAM系統,會給RAM系統造成很大壓力,且可能會影響DLA服務延時;
- DLA是資料庫,需要相容MySQL權限模型,庫、表、字段等領域對象很難一一映射到RAM體系;同時RAM下的資源對象的權限粒度可粗可細,且更多偏向于管理資料生命周期而非詳細資料層面的權限;
- 使用者習慣的Grant、Revoke、Show grants等邏輯,都是直接和傳統資料庫的庫、表、字段一一映射。
- 參考了阿裡雲上及業界雲服務平台上其他資料庫産品的設計,存在一樣的考量;
目前DLA賬号體系與RAM賬号體系的關系:
三、三種賬号模型
- Root/Service賬号:RAM主賬号在某個Region内開通DLA服務時,系統會自動建立第一個DLA賬戶,并以站内信、短信、郵件方式通知RAM主賬号,Root賬号隻有一個,不能删除;
- User/子賬号:由RAM主賬号後續在Console上建立的新的DLA的User賬号(注意,不是由Root賬号建立的),雲賬号使用者可以建立、删除User賬号,也可以為其修改密碼等;
- Product賬号:其他雲産品(比如DBS)與DLA互動時,由使用者在RAM中為該雲産品授權過,由DLA自動産生并派發給雲産品的賬号;
- Root賬号和User賬号,關聯的RAM uid都是對應的雲賬号,進而Root和User賬号都有機會通路雲賬号所有的資源(當然,這都是在授權管理之内);
四、賬号實測操作
a)開通服務并初始化服務
找到服務:
購買:
開通完成,點選進入控制台:
為不同的Region初始化服務:
初始化完成,得到一個Root賬号:
重新回到首頁:
https://openanalytics.console.aliyun.com/overview,設定服務通路點:
配置服務通路點
b)連接配接資料庫并通過認證
連接配接DLA服務,并進入服務
##連接配接DLA服務,賬号和密碼都在您的收件箱内,服務通路點則在服務頁面
[root]# mysql -u<您的dla使用者名> -p<您的dla密碼> -h<您的dla服務通路點> -P10000
## 進入DLA服務,開始測試之旅
mysql> show databases;
Empty set (0.09 sec)
到此,我們已經完成了服務開通過程,并認證和連接配接成功。
c)建立子賬号,并連接配接資料庫
連接配接DLA服務,并進入服務,也能正常工作了:
五、權限模型
DLA中有兩層權限驗證機制,確定您的資料被安全通路:
- DLA層授權和校驗校驗,基于MySQL文法而定義和實作(Grant: https://dev.mysql.com/doc/refman/5.7/en/grant.html 、Revoke: https://dev.mysql.com/doc/refman/5.7/en/revoke.html 、Show Grants: https://dev.mysql.com/doc/refman/5.7/en/show-grants.html )
- 資料源和RAM層授權和校驗,基于RAM的的通路控制而實作(比如OSS、TableStore等雲原生産品): https://help.aliyun.com/product/28625.html ,或者基于資料源本身的權限校驗(比如RDS,是自建賬号,因而也有自建權限系統)
- 使用者的SQL發送到DLA,做完DLA的權限校驗後,再轉發到後端資料源層,執行RAM層和資料源的權限校驗,最後再真正通路到使用者的資料;
a)DLA層校驗原理
DLA是根據使用者操作對象的範圍“從大到小”驗證的,從Global級(全局權限),到Schema級,再到Table級,最後到Column級(目前不支援)一層層驗證權限。任何一層有權限校驗成功,到最後一層也沒權限時校驗失敗:
b)DLA層授權方法
基本上參考了MySQL的Grant/Revoke/Show Grants文法來實作:
##grant相關
GRANT {SELECT | SHOW | ALTER | DROP | CREATE | INSERT | UPDATE | DELETE | GRANT OPTION | ALL | ALL PRIVILEGES | USAGE }
ON {* | *.* | xxDb.* | xxDb.yyTable | yyTable }
TO { oa_1234546 | 'oa_123456' | 'oa_123456'@'1.2.3.4'}
[with grant option]
##revoke相關
REVOKE {SELECT | SHOW | ALTER | DROP | CREATE | INSERT | UPDATE | DELETE |GRANT OPTION | ALL | ALL PRIVILEGES | USAGE}
ON {* | *.* | xxDb.* | xxDb.yyTable | yyTable }
FROM { oa_1234546 | 'oa_123456' | 'oa_123456'@'1.2.3.4'}
##show grants相關
SHOW GRANTS
[for [ current_user | current_user() | oa_123456 | 'oa_123456' | 'oa_123456'@'localhost'] ]
相關關鍵資訊說明:
- 授權人:
- 隻能由DLA的root賬号給其他非Root賬号授權;
- 暫時不支援非Root賬号給其他賬号授權;
- 不能跨雲賬号授權和回收權限;
- privilege清單:
- 可以用','連接配接在一起,比如SELECT,DELETE,UPDATE,INSERT,...
- 有ALL或ALL PRIVILEGES就會全部授權或者全部回收,無視其他的Privilege;但一定要注意,grant option這個權限本身,不包含在ALL中,必須顯式授權或者回收
- 暫時不支援其他類型的授權;
- SELECT是為Query授權;
- SHOW為show、use指令授權(這裡與mysql的邏輯差異比較大);
- ALTER為alter或其他變更型的ddl授權;
- CREATE為create型的ddl授權;
- DROP為drop型的ddl授權;
- INSERT為insert型的dml授權;
- UPDATE為update型的dml授權;
- DELETE為delete型的dml授權;
- GRANT OPTION為dcl授權(grant和revoke相關);可以在Privilege中指定GRANT OPTION,也可以通過語句片段with grant option來做grant 授權;
- USAGE其實啥也沒有,表示為空;
- ResourceType中:
- * 表示目前連接配接使用了某個庫xxDB,然後針對xxDB做授權,庫級别權限;
- . 表示所有庫的所有表授權,Global級别權限;
- xxDb.* 表示針對xxDB這個庫做授權,庫級别權限;
- xxDb.yyTable 表示針對xxDB庫的xxTable做授權,表級别權限;
- yyTable 表示目前連接配接使用了某個庫xxDB,針對xxDB庫的xxTable做授權,表級别權限;
- 暫時不支援字段級别的授權;
- 被授權使用者定義:
- 直接寫使用者名:oa_123456
- 使用者字元串來表示:'oa_123456'
- 即使寫了ip、host資訊,也不會用于連接配接的白名單校驗;
- 隻有相同雲賬号下的Root使用者才能為别人show grants;
- 不能跨不同uid執行show grant
- 必須有show權限和grant權限才能執行show grants,或者為本人執行__;__
- SHOW GRANTS FOR 'jeffrey'@'localhost':目前不支援ip位址;
c)DLA與RAM間權限映射
因為DLA中的子賬号與RAM中的子賬号并不是一一對應,因而RAM中資源的權限和DLA中庫表的權限也不是自然映射的,而是需要在DLA中以特殊定義的方式來做資源的映射和權限的隔離。
目前DLA中授權機關是Schema級别的,也就意味着如果Root賬号給某個User賬号授權了一個庫的權限,那這個User賬号能夠通路這個庫下所有的表,也就意味着能夠通路該庫映射到RAM上所有的資源,這些通路并不受RAM的子賬号權限控制。
比如,我們看一個典型的建庫語句(假設使用者已經可以在DLA中建立相關的庫):
CREATE DATABASE db_name
with dbproperties (
CATALOG = 'ots',
LOCATION = 'https://test-hangzhou.ots.aliyuncs.com',
INSTANCE = 'test'
)
如果Root賬号給某個User賬後執行Grant操作後,該User賬号就可以通路這個庫:
grant all on db_name.* to xxx_s1519122757;
上述過程都假設雲賬号的系統角色授權已經完成,下一節我們介紹首先如何完成系統角色授權,進而允許DLA通路你在其他雲産品中的資料。
d)系統角色授權
系統角色授權是指:使用者給DLA授權,允許DLA通路使用者相關雲服務裡的資料,進而實作DLA關聯分析使用者資料的目标,或者通過DLA實作ETL,将資料回流到使用者的庫。具體過程可以參考:
https://help.aliyun.com/document_detail/53478.htmle)跨賬号通路
DLA支援跨賬号,允許A使用者在DLA上,連接配接B使用者的OSS上的資料進行分析計算,不過這需要做一些操作,後續文檔會以圖形化的方式來介紹和引導使用者:
六、權限實測操作(以TableStore為案例)
a)準備TableStore的庫表
我們來到OTS的首頁,
https://ots.console.aliyun.com/index,建立希望DLA做分析的庫和表:
庫建完後,去建表
插入一行資料
b)開通TableStore給DLA的雲服務角色授權
關于通路控制和角色授權等資訊,請參考:
回到DLA首頁:
點選同意授權:
授權完成之後的狀态:
檢視角色授權已經成功:
c)在DLA中建立庫和表,關聯TableStore庫和表
我們重新回到DLA Root賬号(oa_xxx),通過JDBC協定連接配接到DLA(賬号資訊、DLA通路點、JDBC連接配接方式,請參考前面文檔)
╰─○ mysql -u<您的DLA Root賬号> -p<您的DLA Root賬号的密碼> -h<您的DLA-jdbc通路點> -P10000
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 194631
Server version: 5.6.40-log Source distribution
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
開始建立庫,去關聯TableStore中的執行個體:
mysql> select user();
+----------------+
| user() |
+----------------+
| oa_xxxxxxxxxxx |
+----------------+
1 row in set (0.08 sec)
mysql> show databases; Empty set (0.02 sec)
mysql> create database ots_account_test
with dbproperties(
catalog = 'ots',
location = 'https://account-test.cn-shanghai.ots-internal.aliyuncs.com',
instance = 'account-test'
) comment 'test account and privileges';
Query OK, 0 rows affected (0.10 sec)
mysql> show databases;
+------------------+
| Database |
+------------------+
| ots_account_test |
+------------------+
1 row in set (0.01 sec)
mysql> show create database ots_account_test;
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database |
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ots_account_test | CREATE DATABASE `ots_account_test`
WITH DBPROPERTIES (
catalog = 'ots',
location = 'https://account-test.cn-shanghai.ots-internal.aliyuncs.com',
instance = 'account-test'
)
COMMENT 'test account and privileges' |
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.03 sec)
開始建立表,去關聯TableStore中的表,并查詢資料(結果與OTS中的結果一緻):
mysql> use ots_account_test;
Database changed
mysql> show tables;
Empty set (0.03 sec)
mysql> create external table account_test (
-> pk1 int not null primary key,
-> name varchar(20)
-> );
Query OK, 0 rows affected (0.15 sec)
mysql> show create table account_test;
+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| account_test | CREATE EXTERNAL TABLE `account_test` (
`pk1` int NOT NULL COMMENT '',
`name` varchar(20) NULL COMMENT '',
PRIMARY KEY (`pk1`)
)
COMMENT '' |
+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.04 sec)
mysql> select * from account_test;
+------+--------------+
| pk1 | name |
+------+--------------+
| 123 | account-test |
+------+--------------+
1 row in set (1.61 sec)
至此,我們已經成功完成了資料關聯并實作資料查詢的過程!!
d)把庫和表授權給子賬号來通路
上訴都是Root賬号在操作,從前面的分析可知,Root賬号是可以操作對應雲賬号所有的雲資源的,但是DLA的User賬号卻不行,必須通過Root賬号給User賬号Grant權限,DLA才能允許某個User賬号通路對應的庫和表:
切換到User賬号/子賬号連接配接頁面,此時看不到任何庫表:
mysql> select user();
+------------------------+
| user() |
+------------------------+
| test_sxxxxxxxxxxxxxxxx |
+------------------------+
1 row in set (0.14 sec)
mysql> show databases;
Empty set (0.02 sec)
mysql> show grants ;
+------------------------------------------------+
| Grants for test_sxxxxxxxxxxxxxxxx |
+------------------------------------------------+
| GRANT USAGE ON *.* TO 'test_sxxxxxxxxxxxxxxxx' |
+------------------------------------------------+
1 row in set (0.03 sec)
切換Root賬号連接配接頁面,我們給前面的賬号授權:
mysql> select user();
+------------------------+
| user() |
+------------------------+
| oa_xxxxxxxxxxx |
+------------------------+
1 row in set (0.14 sec)
mysql> show grants for test_sxxxxxxxxxxxxxxxx;
+---------------------------------------------------------------+
| Grants for test_sxxxxxxxxxxxxxxxx |
+---------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'test_sxxxxxxxxxxxxxxxx' |
+---------------------------------------------------------------+
1 rows in set (0.02 sec)
mysql> grant all on ots_account_test.* to test_sxxxxxxxxxxxxxxxx;
Query OK, 0 rows affected (0.05 sec)
mysql> show grants for test_sxxxxxxxxxxxxxxxx;
+---------------------------------------------------------------+
| Grants for test_sxxxxxxxxxxxxxxxx |
+---------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'test_sxxxxxxxxxxxxxxxx' |
| GRANT ALL ON `ots_account_test`.* TO 'test_sxxxxxxxxxxxxxxxx' |
+---------------------------------------------------------------+
2 rows in set (0.03 sec)
切換User賬号連接配接頁面,重新查詢看看,已經有權限了,并且可以讀取資料:
mysql> select user();
+------------------------+
| user() |
+------------------------+
| test_sxxxxxxxxxxxxxxxx |
+------------------------+
1 row in set (0.14 sec)
mysql> show grants ;
+---------------------------------------------------------------+
| Grants for test_sxxxxxxxxxxxxxxxx |
+---------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'test_sxxxxxxxxxxxxxxxx' |
| GRANT ALL ON `ots_account_test`.* TO 'test_sxxxxxxxxxxxxxxxx' |
+---------------------------------------------------------------+
2 rows in set (0.02 sec)
mysql> show databases;
+------------------+
| Database |
+------------------+
| ots_account_test |
+------------------+
1 row in set (0.02 sec)
mysql> select * from ots_account_test.account_test;
+------+--------------+
| pk1 | name |
+------+--------------+
| 123 | account-test |
+------+--------------+
1 row in set (0.43 sec)
至此,子賬号授權通路就可以了!
e)支援跨賬号通路
一般情況,使用者大部分使用DLA的場景是,雲賬号A使用DLA通路雲賬号A在其他雲産品中的資料,從前面的分析可以知道,隻要使用者在DLA的console上選擇具體的資料源(比如TableStore)給DLA做系統角色授權之後,就可以打通資料源,建立庫表和查詢資料了。
但是,還有一種場景是:雲賬号A使用DLA來通路雲賬号B在其他雲産品(以下以TableStore)中的資料,這需要專門的角色授權才能正常運作:
假設上述測試賬号對應的雲賬号為A,下面就以TableStore和另一個雲賬号B(DLA另一個真實的測試雲賬号)作為案例,示範B賬号給A賬号針對TableStore中某個instance做跨賬号授權,并且A在DLA中完成查詢的過程。
首先,需要到B賬号内,在"通路控制(
https://ram.console.aliyun.com)"中建立一個跨賬号授權的角色:
選擇一個“服務角色”,選擇一個合适的模闆,快速建立:
重新回到角色管理頁面,找到這個角色做修改(修改成支援DLA的模闆):
跨賬号的角色建立和修改完成,開始做“角色授權政策”的配置,這裡我們以TableStore為例,其他資料源類似:
跨賬号角色定義,以及角色授權都操作完成,我們開始進入DLA的實際測試,首先檢視雲賬号B的TableStore中的instance和table的情況:
重新使用雲賬号A的DLA Root賬号,通過MySQL-cli連接配接到DLA,然後連接配接和通路雲賬号B的資料:
mysql> select user();
+----------------+
| user() |
+----------------+
| oa_xxxxxxxxxxx |
+----------------+
1 row in set (0.06 sec)
mysql> show databases;
+------------------+
| Database |
+------------------+
| ots_account_test |
+------------------+
1 row in set (0.24 sec)
mysql> create database ots_cross_account_test
with dbproperties(
catalog = 'ots',
location = 'https://test-sh.cn-shanghai.ots-internal.aliyuncs.com', --雲賬号B的TableStore instance
instance = 'test-sh',
cross_account_accessing_arn= 'acs:ram::1013xxxxxx:role/test-cross-account-accessing-role' --雲賬号B為雲賬号A@雲服務DLA的跨賬号角色授權時的Arn資訊
);
Query OK, 0 rows affected (0.14 sec)
mysql> show databases ;
+------------------------+
| Database |
+------------------------+
| ots_account_test |
| ots_cross_account_test |
+------------------------+
2 rows in set (0.18 sec)
mysql> show create database ots_cross_account_test;
+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database |
+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ots_cross_account_test | CREATE DATABASE `ots_cross_account_test`
WITH DBPROPERTIES (
catalog = 'ots',
location = 'https://test-sh.cn-shanghai.ots-internal.aliyuncs.com',
instance = 'test-sh',
cross_account_accessing_arn = 'acs:ram::1013xxxxxx:role/test-cross-account-accessing-role'
)
COMMENT '' |
+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.19 sec)
mysql> use ots_cross_account_test;
Database changed
mysql> show tables;
Empty set (0.19 sec)
mysql> create external table test_table1 (
id1 int not null primary key,
col1 int
);
Query OK, 0 rows affected (0.31 sec)
mysql> show tables;
+-------------+
| Table_Name |
+-------------+
| test_table1 |
+-------------+
1 row in set (0.20 sec)
mysql> show create table test_table1;
+-------------+--------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------+--------------------------------------------------------------------------------------------------------------------------------------+
| test_table1 | CREATE EXTERNAL TABLE `test_table1` (
`id1` int NOT NULL COMMENT '',
`col1` int NULL COMMENT '',
PRIMARY KEY (`id1`)
)
COMMENT '' |
+-------------+--------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.20 sec)
mysql> select * from test_table1;
+--------+------+
| id1 | col1 |
+--------+------+
| 0 | -111 |
| 111111 | 111 |
+--------+------+
2 rows in set (1.29 sec)
順便提醒一下,普通的建庫流程中是不需要
cross_account_accessing_arn
參數的,意味着預設是雲賬号自己給自己開通了DLA通路雲服務的權限,而有了
cross_account_accessing_arn
參數,就表示跨賬号服務的開啟,這個DLA中的庫以及庫下面的表,都有了跨賬号通路的權限!!
到這裡,我們跨賬号通路的全過程就完成啦!!如果你希望連接配接OSS等雲服務,你也可以按照上述流程操作一遍!!