上一份工作主要負責大資料平臺的建設,在這個過程中積累了一些Hadoop生態元件的搭建和使用筆記,由於時間關係,不打算去修改其中的錯別字和排版問題,直接釋出原始筆記。
前置條件
我所在的叢集有三臺服務其,對應的host分別為master,slave1,slave2。hadoop服務的安裝分部為
機器host | 元件情況 |
---|---|
master | namenode、datanode、journalnode、resourcemanager、nodemanager、jobhistoryserver |
slave1 | namenode、datanode、journalnode、resourcemanager、nodemanager |
slave2 | datanode、journalnode、nodemanager |
kerberos相關
首先我們要安裝好kerberos,kerberos的安裝搭建參考連結
https://www.cnblogs.com/niceshot/p/13216455.html
給hadoop各元件建立kerberos賬號
進入kerberos的admin.local後,依次執行下述命令
//元件web服務的princial
addprinc -randkey HTTP/master@TEST.COM
addprinc -randkey HTTP/slave1@TEST.COM
addprinc -randkey HTTP/slave2@TEST.COM
//namenode的princial
addprinc -randkey nn/master@TEST.COM
addprinc -randkey nn/slave1@TEST.COM
//datanode的princial
addprinc -randkey dn/master@TEST.COM
addprinc -randkey dn/slave1@TEST.COM
addprinc -randkey dn/slave2@TEST.COM
//journalnode的princial
addprinc -randkey jn/master@TEST.COM
addprinc -randkey jn/slave1@TEST.COM
addprinc -randkey jn/slave2@TEST.COM
//resourcemanager 的princial
addprinc -randkey rm/master@TEST.COM
addprinc -randkey rm/slave1@TEST.COM
//nodemanager的principal
addprinc -randkey nm/master@TEST.COM
addprinc -randkey nm/slave1@TEST.COM
addprinc -randkey nm/slave2@TEST.COM
//job hisotry server的princial
addprinc -randkey jhs/master@TEST.COM
將這些賬號做成keytab
同樣是在admin.local中,將上述賬號認證資訊做成keytab
ktadd -k /opt/keytab_store/http.service.keytab HTTP/master@TEST.COM
ktadd -k /opt/keytab_store/http.service.keytab HTTP/slave1@TEST.COM
ktadd -k /opt/keytab_store/http.service.keytab HTTP/slave2@TEST.COM
ktadd -k /opt/keytab_store/nn.service.keytab nn/master@TEST.COM
ktadd -k /opt/keytab_store/nn.service.keytab nn/slave1@TEST.COM
ktadd -k /opt/keytab_store/dn.service.keytab dn/master@TEST.COM
ktadd -k /opt/keytab_store/dn.service.keytab dn/slave1@TEST.COM
ktadd -k /opt/keytab_store/dn.service.keytab dn/slave2@TEST.COM
ktadd -k /opt/keytab_store/jn.service.keytab jn/master@TEST.COM
ktadd -k /opt/keytab_store/jn.service.keytab jn/slave1@TEST.COM
ktadd -k /opt/keytab_store/jn.service.keytab jn/slave2@TEST.COM
ktadd -k /opt/keytab_store/rm.service.keytab rm/master@TEST.COM
ktadd -k /opt/keytab_store/rm.service.keytab rm/slave1@TEST.COM
ktadd -k /opt/keytab_store/nm.service.keytab nm/master@TEST.COM
ktadd -k /opt/keytab_store/nm.service.keytab nm/slave1@TEST.COM
ktadd -k /opt/keytab_store/nm.service.keytab nm/slave2@TEST.COM
ktadd -k /opt/keytab_store/jhs.service.keytab jhs/master@TEST.COM
多個賬號可以做到一個keytab中去,上述的命令做了多個檔案,不同元件角色的單獨放到了一個keytab檔案中。其實內部網路,可以把所有的hadoop相關元件做成一個大的keytab檔案,降低配置複雜性。
將上述的keytab檔案,分發到叢集所有機器
core-site.xml
關鍵配置
<property>
<name>hadoop.security.authentication</name>
<value>kerberos</value>
</property>
<property>
<name>hadoop.security.authorization</name>
<value>true</value>
</property>
<property>
<name>hadoop.security.auth_to_local</name>
<value>
RULE:[2:$1/$2@$0]([ndj]n/.*@TEST.COM)s/.*/hdfs/
RULE:[2:$1/$2@$0]([rn]m/.*@TEST.COM)s/.*/yarn/
RULE:[2:$1/$2@$0](jhs/.*@TEST.COM)s/.*/mapred/
DEFAULT
</value>
</property>
上述配置的意思是 在整個叢集中費用kerberos作為安全認證和授權,
hadoop.security.auth_to_local 配置元件之間互訪時被訪問的服務,如何從訪問的Principal中抽取出實際的使用者。大致規則以第一行為例,表示將namenode, 和datanode ,journalnode的principal 對映成為hdfs的user
而最終的default是上述規則都不匹配時的預設規則,預設規則會直接從principal中提取第一個斜槓前面的資訊作為user。比如test/xxhost@DOMIAN.COM 會被識別成明為test的user
HDFS
<property>
<name>dfs.block.access.token.enable</name>
<value>true</value>
</property>
<property>
<name>dfs.namenode.kerberos.principal</name>
<value>nn/_HOST@TEST.COM</value>
</property>
<property>
<name>dfs.namenode.keytab.file</name>
<value>/opt/keytab_store/nn.service.keytab</value>
</property>
<property>
<name>dfs.namenode.kerberos.internal.spnego.principal</name>
<value>${dfs.web.authentication.kerberos.principal}</value>
</property>
<property>
<name>dfs.journalnode.kerberos.principal</name>
<value>jn/_HOST@TEST.COM</value>
</property>
<property>
<name>dfs.journalnode.keytab.file</name>
<value>/opt/keytab_store/jn.service.keytab</value>
</property>
<property>
<name>dfs.journalnode.kerberos.internal.spnego.principal</name>
<value>${dfs.web.authentication.kerberos.principal}</value>
</property>
<property>
<name>dfs.datanode.kerberos.principal</name>
<value>dn/_HOST@TEST.COM</value>
</property>
<property>
<name>dfs.datanode.keytab.file</name>
<value>/opt/keytab_store/dn.service.keytab</value>
</property>
<property>
<name>dfs.web.authentication.kerberos.principal</name>
<value>HTTP/_HOST@TEST.COM</value>
</property>
<property>
<name>dfs.web.authentication.kerberos.keytab</name>
<value>/opt/keytab_store/http.service.keytab</value>
</property>
<property>
<name>dfs.http.policy</name>
<value>HTTPS_ONLY</value>
</property>
<property>
<name>dfs.data.transfer.protection</name>
<value>authentication</value>
</property>
其中大體配置是配置各元件使用的principal是什麼。其中的_HOST相當於語法糖,hadoop會根據本機hostname,替換該配置,從而實現不同機器相同配置檔案的目的
datanode的安全配置
由於datanode資料傳輸走的不是rpc,而是http。所以datanode無法使用kerberos的方式進行認證。為了解決這個問題,有兩種方式的配置,來實現datanode資料傳輸的安全性
- JSVC
- TLS/SSL
JSVC方式的大體原理是使用JSVC工具,讓datanode能夠使用特權埠啟動,所謂特權埠是指1024以下的埠,這種安全配置假定攻擊者無法獲取root許可權,所以也就無法操作datanode來實現。hadoop 2.6.0以前,只能使用這種方式,配置較為複雜,不在這裡贅述。hadoop 2.6.0以後引入了SASL方式,通過TLS/SSL來實現資料的安全傳輸,下面介紹這種方式
證書生成和安裝
TLS/SSL相關原理見文件 ,這裡貼上地址
首先保證機器上已經安裝好了openssl。下面是詳細的配置。核心思想是,做一個私有的CA,然後通過這個私有的CA證書給所有的其它證書籤名,通過將私有CA的證書安裝到各機器的信任區裡,實現一個各機器間的TLS/SSL通訊
然後在叢集中隨便找一臺機器,先生成CA證書,這裡在Master這臺機器上操作
openssl req -new -x509 -keyout ca_private.key -out ca_cert -days 9999 -subj '/C=CN/ST=chengdu/L=chengdu/O=bigdata/OU=bigdata/CN=master'
將上述的CA私鑰跟更要證書拷貝到各個機器。然後再各機器上做如下操作,當然如果我們在生成證書時,用的密碼完全一樣也可以在一個機器上做,最後把相關的keystore和truststore分發到所有的機器。
//生成自己的公私祕鑰對
keytool -keystore keystore -alias localhost -validity 9999 -genkey -keyalg RSA -keysize 2048 -dname "CN=slave2, OU=bigdata, O=bigdata, L=chengdu, ST=chengdu, C=CN"
//將上述的CA公鑰證書匯入本機的信任區truststore
keytool -keystore truststore -alias CARoot -import -file ca_cert
//將上述的CA公鑰匯入本機的keystore中
keytool -keystore keystore -alias CARoot -import -file ca_cert
//將本機的公鑰證書匯出
keytool -certreq -alias localhost -keystore keystore -file local_cert
//對CA私鑰,對本機的公鑰證書進行簽名
openssl x509 -req -CA hd_ca_cert -CAkey ca_private.key -in local_cert -out local_cert_signed -days 9999 -CAcreateserial
//將簽名後的證書匯入的自己的Keystore
keytool -keystore keystore -alias localhost -import -file local_cert_signed
hdfs-site.xml的重點配置
配置dfs.http.policy
的value為HTTPS_ONLY
配置dfs.data.transfer.protection
的value為authentication
、 integrity
、 privacy
任意一種。一般內部叢集用authentication即可
- authentication ,只認證簽名
- integrity 除了認證簽名外,還驗證資料是否被篡改
- privacy,資料除了上述的認證和完整性驗證之外還要加密傳輸
ssl-client.xml 和 ssl-server.xml配置
hadoop在在跟core-site.xml同級目錄下一般有ssl-client.xml.example和ssl-server.xml.example兩個模板檔案,我們可以直接去掉template來後作為配置檔案來配置。他們是用來配置當前元件作為服務端時,自己的證書kestore位置,和作為客戶端時,自己的信任證書truststore位置
ssl-client.xml配置如下
<configuration>
<property>
<name>ssl.client.truststore.location</name>
<value>/opt/ssl_store/truststore</value>
<description>Truststore to be used by clients like distcp. Must be
specified.
</description>
</property>
<property>
<name>ssl.client.truststore.password</name>
<value>123456</value>
<description>Optional. Default value is "".
</description>
</property>
<property>
<name>ssl.client.truststore.type</name>
<value>jks</value>
<description>Optional. The keystore file format, default value is "jks".
</description>
</property>
<property>
<name>ssl.client.truststore.reload.interval</name>
<value>10000</value>
<description>Truststore reload check interval, in milliseconds.
Default value is 10000 (10 seconds).
</description>
</property>
<property>
<name>ssl.client.keystore.location</name>
<value>/opt/ssl_store/keystore</value>
<description>Keystore to be used by clients like distcp. Must be
specified.
</description>
</property>
<property>
<name>ssl.client.keystore.password</name>
<value>123456</value>
<description>Optional. Default value is "".
</description>
</property>
<property>
<name>ssl.client.keystore.keypassword</name>
<value>123456</value>
<description>Optional. Default value is "".
</description>
</property>
<property>
<name>ssl.client.keystore.type</name>
<value>jks</value>
<description>Optional. The keystore file format, default value is "jks".
</description>
</property>
</configuration>
ssl-server.xml
<property>
<name>ssl.server.keystore.password</name>
<value>123456</value>
<description>Must be specified.
</description>
</property>
<property>
<name>ssl.server.keystore.keypassword</name>
<value>123456</value>
<description>Must be specified.
</description>
</property>
<property>
<name>ssl.server.keystore.type</name>
<value>jks</value>
<description>Optional. The keystore file format, default value is "jks".
</description>
</property>
<property>
<name>ssl.server.exclude.cipher.list</name>
<value>TLS_ECDHE_RSA_WITH_RC4_128_SHA,SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
SSL_RSA_WITH_DES_CBC_SHA,SSL_DHE_RSA_WITH_DES_CBC_SHA,
SSL_RSA_EXPORT_WITH_RC4_40_MD5,SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
SSL_RSA_WITH_RC4_128_MD5</value>
<description>Optional. The weak security cipher suites that you want excluded
from SSL communication.</description>
</property>
</configuration>
上述配置的123456是我們在做證書時使用的密碼
yarn
整體配置
<property>
<name>yarn.resourcemanager.principal</name>
<value>rm/_HOST@TEST.COM</value>
</property>
<property>
<name>yarn.resourcemanager.keytab</name>
<value>/opt/keytab_store/rm.service.keytab</value>
</property>
<property>
<name>yarn.nodemanager.principal</name>
<value>nm/_HOST@TEST.COM</value>
</property>
<property>
<name>yarn.nodemanager.keytab</name>
<value>/opt/keytab_store/nm.service.keytab</value>
</property>
<property>
<!--安全叢集必須使用下面的LinuxContainerExecutor-->
<name>yarn.nodemanager.container-executor.class</name>
<value>org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor</value>
</property>
<property>
<name>yarn.nodemanager.linux-container-executor.group</name>
<value>hadoop</value>
</property>
<property>
<name>yarn.nodemanager.linux-container-executor.path</name>
<value>/opt/hadoop-3.1.3/bin/container-executor</value>
</property>
container-executor
build LinuxContainerExecutor
上述yarn.nodemanager.linux-container-executor.path指定了LinuxContainerExecutor對應的可執行檔案container-executor的路徑。
hadoop發行包在bin路徑下,一般就已經有這個檔案了。
這個檔案執行需要一個配置,container-executor.cfg 。其預設載入的是$HADOOP_HOME/etc/hadoop/container-executor.cfg這個路徑的配置檔案。
但由於這個路徑本身又有hadoop的其它配置檔案,而container-executor又要求container-executor.cfg所在路徑所有層級許可權都只能root訪問。這會導致我們其其它元件啟動出現各種奇奇古怪的問題。
所以我們需要另外指定container-executor.cfg檔案的位置。但問題是container-executor這個二進位制檔案在構建時,已經寫死了檔案路徑。如果我們需要重指定配置檔案路徑,需要重新打包container-executor。構建步驟為
- 首先下載同版本的hadoop原始碼
- 進入到原始碼包的路徑
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager
- 使用命令
mvn package -DskipTests=true -Dcontainer-executor.conf.dir=/etc/hadoop/
構建,container-executor.conf.dir引數即指定新的container-executor.cfg檔案路徑 - 構建完成後,在構建路徑下的
target/native/target/usr/local/bin
路徑即可找到新構建的container-executor,將其拷貝到$HADOOP_HOME/bin下,替換原來的程式即可
配置container-executor.cfg
在/etc/hadoop/中,建立container-executor.cfg,其配置內容如下
yarn.nodemanager.linux-container-executor.group=hadoop
banned.users=hdfs,yarn,mapred,bin
min.user.id=1000
allowed.system.users=
feature.tc.enabled=false
注意配置每行不要有空格,yarn.nodemanager.linux-container-executor.group這個配置值同yarn-site.xml中的一致
總結許可權配置需要配置的項
檔案許可權修改
chown root:hadoop /opt/hadoop-3.1.3/bin/container-executor
chmod 6050 /opt/hadoop-3.1.3/bin/container-executor
chown root:hadoop /etc/hadoop/container-executor.cfg
chmod 400 /etc/hadoop/container-executor.cfg
假設在yarn-site.xml的中yarn.nodemanager.local-dirs 配置 路徑為/home/var/data/hadoop/nodemanager/data
yarn.nodemanager.log-dirs配置路徑為 /home/var/data/hadoop/nodemanager/log,還需要做以下許可權配置
chown yarn:hadoop /home/var/data/hadoop/nodemanager/data
chown yarn:hadoop /home/var/data/hadoop/nodemanager/log
chmod 755 /home/var/data/hadoop/nodemanager/data
chmod 755 /home/var/data/hadoop/nodemanager/log
mapreduce
<property>
<name>mapreduce.jobhistory.keytab</name>
<value>/opt/keytab_store/jhs.service.keytab</value>
</property>
<property>
<name>mapreduce.jobhistory.principal</name>
<value>jhs/_HOST@TEST.COM</value>
</property>
啟動
配置完後,按原來的方式啟動即可。只是由於hdfs開起了SSL/TLS ,其原來的9870埠,變成了9871, 且需要通過https訪問。比如我們這地址為:https://master:9871
參考資料
https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SecureMode.html
https://secfree.github.io/blog/2015/07/01/sasl-data-transfer-protocol.html
https://blog.csdn.net/picway/article/details/74299086
https://developer.aliyun.com/article/245586
https://makeling.github.io/bigdata/dcb921f7.html
https://makeling.github.io/bigdata/39395030.html
http://secfree.github.io/blog/2015/06/25/yarn-container-executor-traps.html
歡迎關注我的個人公眾號"西北偏北UP",記錄程式碼人生,行業思考,科技評論