<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Flink on Yarn Kerberos安全認(rèn)證

          共 8548字,需瀏覽 18分鐘

           ·

          2020-12-22 23:10

          點(diǎn)擊上方藍(lán)色字體,選擇“設(shè)為星標(biāo)

          回復(fù)”資源“獲取更多資源

          大數(shù)據(jù)技術(shù)與架構(gòu)
          點(diǎn)擊右側(cè)關(guān)注,大數(shù)據(jù)開發(fā)領(lǐng)域最強(qiáng)公眾號!

          大數(shù)據(jù)真好玩
          點(diǎn)擊右側(cè)關(guān)注,大數(shù)據(jù)真好玩!



          Flink作為新一代的大數(shù)據(jù)處理引擎,其批流一體化的設(shè)計(jì)與出色的流處理性能,在業(yè)界得到了很多頭部公司的青睞。目前運(yùn)行Flink的集群多采用Yarn進(jìn)行資源管理,這是最成熟的方案。Yarn做為Hadoop生態(tài)系統(tǒng)中的工具之一,客戶端通常需要經(jīng)過Kerberos認(rèn)證才能使用Yarn提交或管理任務(wù)。那么Flink任務(wù)是如何提交到帶有Kerberos認(rèn)證的Yarn集群的呢?我們先從Kerberos的原理開始說起,再說如何讓Flink在帶有Kerberos認(rèn)證的Yarn集群上跑起來,知其然知其所以然。

          為什么需要Kerberos

          在Hadoop1.0.0或者CDH3以前,Hadoop集群中的所有節(jié)點(diǎn)幾乎就是裸奔的,主要存在以下安全問題:

          • NameNode與JobTracker上沒有用戶認(rèn)證,用戶可以偽裝成管理員入侵到一個(gè)HDFS 或者M(jìn)apReduce集群上。

          • DataNode上沒有認(rèn)證:Datanode對讀入輸出并沒有認(rèn)證,如果知道block的ID,就可以任意的訪問DataNode上block的數(shù)據(jù)

          • JobTracker上沒有認(rèn)證:可以任意的殺死或更改用戶的jobs,也可以更改JobTracker的工作狀態(tài)

          • 沒有對DataNode與TaskTracker的認(rèn)證:用戶可以偽裝成DataNode與TaskTracker,去接受JobTracker與Namenode的任務(wù)指派。

          為了解決這些問題,kerberos認(rèn)證出現(xiàn)了,它實(shí)現(xiàn)的是機(jī)器級別的安全認(rèn)證。

          kerberos是希臘神話中的三頭狗,地獄之門的守護(hù)者

          其原理是事先將集群中的機(jī)器添加到kerberos數(shù)據(jù)庫中,在數(shù)據(jù)庫中分別產(chǎn)生主機(jī)與各個(gè)節(jié)點(diǎn)的keytab,并將這些keytab分發(fā)到對應(yīng)的節(jié)點(diǎn)上。通過這些keytab文件,節(jié)點(diǎn)可以從數(shù)據(jù)庫中獲得與目標(biāo)節(jié)點(diǎn)通信的密鑰防止身份被冒充。針對Hadoop集群可以解決兩方面的認(rèn)證

          • 解決服務(wù)器到服務(wù)器的認(rèn)證,確保不會(huì)冒充服務(wù)器的情況。集群中的機(jī)器都是是可靠的,有效防止了用戶偽裝成Datanode,Tasktracker,去接受JobTracker,Namenode的任務(wù)指派。

          • 解決client到服務(wù)器的認(rèn)證,防止用戶惡意冒充client提交作業(yè),也無法發(fā)送對于作業(yè)的操作到JobTracker上,即使知道datanode的相關(guān)信息,也無法讀取HDFS上的數(shù)據(jù)。

          對于具體到用戶粒度上的權(quán)限控制,如哪些用戶可以提交某種類型的作業(yè),哪些用戶不能,目前Kerberos還沒有實(shí)現(xiàn),需要有專門的ACL模塊進(jìn)行把控。

          Kerberos認(rèn)證過程

          Kerberos認(rèn)證過程會(huì)涉及以下幾個(gè)基本概念:

          • Principal(安全個(gè)體):被認(rèn)證的個(gè)體,有一個(gè)名字和口令,每個(gè)server都對應(yīng)一個(gè)principal,其格式如下,@前面部分為具體身份,后面的部分稱為REALM。

          component1 / component2 @ REALM
          • KDC(key distribution center ) : 是一個(gè)網(wǎng)絡(luò)服務(wù),提供ticket 和臨時(shí)會(huì)話密鑰。

          • Ticket:一個(gè)記錄,客戶用它來向服務(wù)器證明自己的身份,包括客戶標(biāo)識、會(huì)話密鑰、時(shí)間戳。

          • AS (Authentication Server):認(rèn)證服務(wù)器,率屬于KDC,用于認(rèn)證Client身份。

          • TGS(Ticket Granting Server):許可證服務(wù)器,率屬于KDC。

          事先對集群中確定的機(jī)器由管理員手動(dòng)添加到kerberos數(shù)據(jù)庫中,在KDC上分別產(chǎn)生主機(jī)與各個(gè)節(jié)點(diǎn)的keytab(包含了host和對應(yīng)節(jié)點(diǎn)的名字,還有他們之間的密鑰——Master Key),并將這些keytab分發(fā)到對應(yīng)的節(jié)點(diǎn)上。

          1. AS Exchange

          通過這個(gè)過程,KDC(確切地說是KDC中的Authentication Service)可以實(shí)現(xiàn)對Client身份的確認(rèn),并頒發(fā)給該Client一個(gè)TGT。具體過程如下:

          Client向KDC的Authentication Service發(fā)送Authentication Service Request(KRB_AS_REQ), 為了確保KRB_AS_REQ僅限于自己和KDC知道,Client使用自己的Master Key對KRB_AS_REQ的內(nèi)容進(jìn)行加密。KRB_AS_REQ內(nèi)容主要包括:

          • Pre-authentication data:用于證明自己知道自己聲稱的那個(gè)account的Password,一般是一個(gè)被Client的Master key加密過的Timestamp。

          • Client信息: 可以理解為client的principal。

          • TGS的Server Name。

          AS在接收到的KRB_AS_REQ后從Account Database中提取Client對應(yīng)的Master Key對Pre-authentication data進(jìn)行解密,如果是一個(gè)合法的Timestamp,則可以證明發(fā)送方的確是Client信息中聲稱的那個(gè)人。

          驗(yàn)證通過之后,AS將一份Authentication Service Response(KRB_AS_REP)發(fā)送給請求方。KRB_AS_REQ主要包含兩個(gè)部分:該Client的Master Key加密過的Session Key(SKDC-Client:Logon Session Key)和被自己(KDC)的Master Key加密的TGT。而TGT大體又包含以下的內(nèi)容:

          • Session Key;

          • Client信息:即Client的principal;

          • End time: TGT到期的時(shí)間。

          Client通過自己的Master Key對第一部分解密獲得Session Key之后,利用TGT便可以進(jìn)行Kerberos認(rèn)證的下一步:TGS Exchange。

          2. TGS Exchange

          Client先向TGS發(fā)送Ticket Granting Service Request(KRB_TGS_REQ),其主要內(nèi)容為:

          • 被KDC的Master Key加密的TGT;

          • Authenticator:用于驗(yàn)證確認(rèn)Client提供的那個(gè)TGT是否是AS頒發(fā)給它的,其內(nèi)容為Client信息與Timestamp,并且用Session Key進(jìn)行加密。

          • Client信息;

          • Server信息:Client試圖訪問的Server的Principal。

          TGS收到KRB_TGS_REQ后,先使用他自己的Master Key對TGT進(jìn)行解密,從而獲得Session Key。隨后使用該Session Key解密Authenticator,通過比較Authenticator中的Client InfoSession Ticket中的Client Info從而實(shí)現(xiàn)對Client的驗(yàn)證。

          驗(yàn)證通過向?qū)Ψ桨l(fā)送Ticket Granting Service Response(KRB_TGS_REP)。這個(gè)KRB_TGS_REP有兩部分組成:使用Logon Session Key(SKDC-Client)加密過用于Client和Server認(rèn)證的Session Key(SServer-Client)和使用Server的Master Key進(jìn)行加密的Ticket。該Ticket大體包含以下一些內(nèi)容:

          • Session Key:SServer-Client;

          • Client信息;

          • End time: Ticket的到期時(shí)間。

          Client收到KRB_TGS_REP,使用Logon Session Key(SKDC-Client)解密第一部分后獲得Session Key(SServer-Client)。有了Session Key和Ticket,Client就可以和Server進(jìn)行交互,這時(shí)無須KDC介入了。我們看看 Client是如何使用Ticket與Server怎樣進(jìn)行交互的。

          3. CS(Client/Server )Exchange

          先是Client向Server認(rèn)證自己的身份。這個(gè)過程與TGS Exchange中認(rèn)證的過程類似,Client創(chuàng)建用于證明自己就是Ticket的真正所有者的Authenticator,并使用上一步獲得的Session Key(SServer-Client)進(jìn)行加密,然后將它和Ticket一起作為Application Service Request(KRB_AP_REQ)發(fā)送給Server。

          除了上述兩項(xiàng)內(nèi)容之外,KRB_AP_REQ還包含一個(gè)Flag用于表示Client是否需要進(jìn)行雙向驗(yàn)證(Mutual Authentication)。

          Server接收到KRB_AP_REQ之后,通過自己的Master Key解密Ticket,從而獲得Session Key(SServer-Client)。通過Session Key(SServer-Client)解密Authenticator,進(jìn)而驗(yàn)證對方的身份。驗(yàn)證成功,讓Client訪問需要訪問的資源,否則直接拒絕對方的請求。

          對于需要進(jìn)行雙向驗(yàn)證,Server從Authenticator提取Timestamp,使用Session Key(SServer-Client)進(jìn)行加密,并將其發(fā)送給Client用于Client驗(yàn)證Server的身份。

          Flink on Kerberos Yarn實(shí)現(xiàn)方式

          在客戶端使用Kerberos認(rèn)證來獲取服務(wù)時(shí),需要經(jīng)過三個(gè)步驟:

          • 認(rèn)證:客戶端向認(rèn)證服務(wù)器發(fā)送一條報(bào)文,并獲取一個(gè)含時(shí)間戳的TGT。

          • 授權(quán):客戶端使用TGT向TGS請求一個(gè)服務(wù)Ticket。

          • 服務(wù)請求:客戶端向服務(wù)器出示服務(wù)Ticket,以證實(shí)自己的合法性。

          其關(guān)鍵在于獲取TGT,客戶端有了它就可以申請?jiān)L問服務(wù)。所以第一種方式就是使用

          1. 使用Delegation token

          如果本地安裝了Kerberos客戶端,可以使用kinit命令來獲取TGT,

          • 可以使用密碼來向KDC申請

          kinit wanghuan70
          Password for [email protected]:


          • 也可以直接使用keytab來獲取,keytab文件中包含了密碼的散列值;

          kinit -kt wanghuan70.keytab wanghuan70

          使用klist命令可以查看獲取到的tgt的詳細(xì)信息,包括Client principal、Service principal、位置、有效期等;

          $ klist
          Ticket cache: FILE:/tmp/krb5cc_2124
          Default principal: [email protected]

          Valid starting Expires Service principal
          08/03/2017 09:31:52 08/11/2017 09:31:52 krbtgt/IDC.XXX- [email protected]
          renew until 08/10/2017 09:31:52

          在Flink client上執(zhí)行這一系列操作后,再在Flink配置文件flink-conf.yaml里面添加如下配置

          security.kerberos.login.use-ticket-cache: true

          這時(shí)Flink客戶端就可以像一般情況一樣直接用command向Yarn集群提交任務(wù)了。但是tgt有一個(gè)有效期,通常是一周,過期了就無法使用了,所以這種方式不適合長期任務(wù)。這就有了第二種方式——使用keytab,先獲取token,后臺再啟動(dòng)一個(gè)進(jìn)程定期刷新token。

          2. 使用keytab

          這種方式時(shí)通過客戶端將keytab提交到Hadoop集群,再通過YARN分發(fā)keytab給AM和其他 worker container,具體步驟如下

          • Flink客戶端在提交任務(wù)時(shí),將keytab上傳至HDFS,將其作為AM需要本地化的資源。

          • AM container初始化時(shí)NodeManager將keytab拷貝至container的資源目錄,然后再AM啟動(dòng)時(shí)通過UserGroupInformation.loginUserFromKeytab()來重新認(rèn)證。

          • 當(dāng)AM需要申請其他worker container時(shí),也將 HDFS 上的keytab列為需要本地化的資源,因此worker container也可以仿照AM的認(rèn)證方式進(jìn)行認(rèn)證。

          • 此外AM和container都必須額外實(shí)現(xiàn)一個(gè)線程來定時(shí)刷新TGT。


          任務(wù)運(yùn)行結(jié)束后,集群中的keytab也會(huì)隨container被清理掉。

          使用這種方式的話,F(xiàn)link客戶端需要持有keytab文件,并且在Flink配置文件flink-conf.yaml里面添加如下配置

          security.kerberos.login.keytab: /home/hadoop_runner/hadoop-3.2.1/etc/hadoop/krb5.keytab
          security.kerberos.login.principal: superuser
          security.kerberos.login.contexts: Client

          注意:Flink客戶端進(jìn)行Kerberos認(rèn)證是在加載集群動(dòng)態(tài)配置之前進(jìn)行的,所以需要在flink-conf.yaml文件中位置principal與keytab。在命令行中添加這個(gè)配置參數(shù),實(shí)際還是用客戶端的用戶名作為principal進(jìn)行認(rèn)證,會(huì)報(bào)找不到tgt的錯(cuò)誤。

          設(shè)置Hadoop代理用戶

          出于于安全考慮,很多時(shí)候我們希望客戶端能以某一個(gè)hadoop用戶的身份去運(yùn)提交任務(wù)、訪問hdfs文件,目前實(shí)現(xiàn)方式主要有以下幾種

          • client端root用戶su為joe用戶,再使用joe用戶的名義提交作業(yè),但這種方法前提是客戶端已經(jīng)有joe的token,并且會(huì)造成潛在的權(quán)限濫用風(fēng)險(xiǎn)。

          • 設(shè)置環(huán)境變量或者系統(tǒng)變量HADOOP_USER_NAME,例如希望訪問hdfs文件,并在hdfs中進(jìn)行讀寫操作,可將用戶名設(shè)置為hdfs,因?yàn)樵趆dfs文件系統(tǒng)中hdfs具有最高權(quán)限。這種方法對于帶有Kerberos認(rèn)證的Hadoop集群并不起作用。

           export HADOOP_USER_NAME=hdfs
          • 設(shè)置環(huán)境變量或者系統(tǒng)變量HADOOP_PROXY_USER,即設(shè)置Hadoop代理用戶,因?yàn)閷τ趲в蠯erberos認(rèn)證的集群,都是通過UserGroupInformation進(jìn)行認(rèn)證的,用戶名是由getLoginUser方法獲取的。

              @Public
          @Evolving
          public static synchronized UserGroupInformation getLoginUser() throws IOException {
          if (loginUser == null) {
          loginUserFromSubject((Subject)null);
          }

          return loginUser;
          }


          @Public
          @Evolving
          public static synchronized void loginUserFromSubject(Subject subject) throws IOException {
          ensureInitialized();

          try {
          if (subject == null) {
          subject = new Subject();
          }

          LoginContext login = newLoginContext(authenticationMethod.getLoginAppName(), subject, new UserGroupInformation.HadoopConfiguration());
          login.login();
          UserGroupInformation realUser = new UserGroupInformation(subject);
          realUser.setLogin(login);
          realUser.setAuthenticationMethod(authenticationMethod);
          realUser = new UserGroupInformation(login.getSubject());
          String proxyUser = System.getenv("HADOOP_PROXY_USER");
          if (proxyUser == null) {
          proxyUser = System.getProperty("HADOOP_PROXY_USER");
          }

          loginUser = proxyUser == null ? realUser : createProxyUser(proxyUser, realUser);
          String fileLocation = System.getenv("HADOOP_TOKEN_FILE_LOCATION");
          if (fileLocation != null) {
          Credentials cred = Credentials.readTokenStorageFile(new File(fileLocation), conf);
          loginUser.addCredentials(cred);
          }

          loginUser.spawnAutoRenewalThreadForUserCreds();
          } catch (LoginException var6) {
          LOG.debug("failure to login", var6);
          throw new IOException("failure to login", var6);
          }

          if (LOG.isDebugEnabled()) {
          LOG.debug("UGI loginUser:" + loginUser);
          }

          }

          然而直接在客戶端設(shè)置這個(gè)環(huán)境變量或者Java系統(tǒng)變量是不work的,因?yàn)閷?shí)際訪問Hadoop的Operator是在TaskManager中運(yùn)行的,所以需要將這個(gè)變量傳到運(yùn)行tm的NodeManager中,可以通過在Flink客戶端配置參數(shù)env.ssh.opts或者env.java.opts來實(shí)現(xiàn)。

          env.java.opts: -DHADOOP_PROXY_USER=hdfs # 配置所有Flink進(jìn)程的JVM啟動(dòng)參數(shù)
          env.ssh.opts: export HADOOP_PROXY_USER=hdfs # 啟動(dòng)jm、tm、zookeeper等服務(wù)的額外命令

          也可以通過配置containerized.master.env.與containerized.taskmanager.env.來傳遞環(huán)境變量。

          然而,在目前版本(Flink 1.10)中,如果配置了keytab文件與Principal,F(xiàn)link在后續(xù)中始終會(huì)以該P(yáng)rincipal的名義提交任務(wù),即便配置了HADOOP_PROXY_USER也起不到效果。針對這個(gè)issue,Uber提出了Flink on Yarn Security的改進(jìn)方案,其進(jìn)展詳見Flink-11271。


          版權(quán)聲明:

          本文為大數(shù)據(jù)技術(shù)與架構(gòu)整理,原作者獨(dú)家授權(quán)。未經(jīng)原作者允許轉(zhuǎn)載追究侵權(quán)責(zé)任。
          編輯|冷眼丶
          微信公眾號|import_bigdata


          歡迎點(diǎn)贊+收藏+轉(zhuǎn)發(fā)朋友圈素質(zhì)三連




          文章不錯(cuò)?點(diǎn)個(gè)【在看】吧!??


          瀏覽 88
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲青青操 | 就操在线观看免费视频 | 91三级视频 | 亚洲色婷婷视频 | 成人精品在线观看 |