1. 前言
本文基本上參考自:CDH集成Kerberos配置
增加了一些說明。
1.1. 軟件版本
操作系統:Centos 7.5 和 Red Hat Enterprise Linux Server release 7.4
CDH版本:Hadoop 2.6.0-cdh5.13.0
JDK版本:1.8u144
運行用戶:root
為什么有兩個系統呢?因為先在我們公司的集群嘗試了,然后再到客戶那邊安裝。
1.2. 集群角色划分
我們的測試集群命名很簡單,每個節點的hostname類似master和slaver1、slaver2……。
一個master節點,安裝kerberos Server;
其他節點作為slave節點,安裝kerberos client;
cloudera manager server 在的節點,安裝openldap-clients。
安裝前主機之間是互通的,這個應該安裝完cloudera就知道了。
我在master節點寫了一個分發執行命令的腳本,類似以下:
#!/usr/bin/bash if [ "$#" == "1" ]; then for num in 2 3 4 5 6 do echo "connecting to slaver${num} and excute commands" ssh root@slaver${num} $1 echo -e "slaver${num} done \n" done else echo "usage: $0 'command'" fi
還有一個分發文件的腳本:
!/usr/bin/bash if [ "$#" == "2" ]; then for num in 2 3 4 5 6 do echo -e "\nscp file $1 to slaver${num}:$2" scp -r $1 root@slaver${num}:$2 done else echo "usage: $0 from_file to_file"
2. 安裝kerberos
2.1. 安裝krb5-server和krb5-clinent
在master上安裝krb5、krb5-server 和 krb5-client。
yum install krb5-server -y # klist等命令找不大時執行下面安裝 yum install -y krb5-server krb5-workstation pam_krb
其中,在redhat系統的時候,會出現klist找不到的情況,所以都安裝一下免得麻煩;
分發命令,在其他節點安裝krb5-devel、krb5-workstation
./bro_command.sh "yum install krb5-devel krb5-workstation -y"
2.2. 修改配置文件
kdc 服務涉及到三個配置文件:
- /etc/krb5.conf
- /var/kerberos/krb5kdc/kdc.conf
- /var/kerberos/krb5kdc/kadm5.acl
2.2.1. 編輯配置文件 /etc/krb5.conf
[logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] default_realm = EXAMPLE.COM dns_lookup_realm = false dns_lookup_kdc = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true default_tgs_enctypes = aes256-cts-hmac-sha1-96 default_tkt_enctypes = aes256-cts-hmac-sha1-96 permitted_enctypes = aes256-cts-hmac-sha1-96 clockskew = 120 udp_preference_limit = 1 [realms] EXAMPLE.COM = { kdc = master admin_server = master } [domain_realm] .example.com = EXAMPLE.COM example.com = EXAMPLE.COM
說明:
- [logging]:表示 server 端的日志的打印位置
- [libdefaults]:每種連接的默認配置,需要注意以下幾個關鍵的小配置
- default_realm = 0HKJ.COM:設置 Kerberos 應用程序的默認領域。如果您有多個領域,只需向 [realms] 節添加其他的語句。
- ticket_lifetime: 表明憑證生效的時限,一般為24小時。
- renew_lifetime: 表明憑證最長可以被延期的時限,一般為一個禮拜。當憑證過期之后,對安全認證的服務的后續訪問則會失敗。
- clockskew:時鍾偏差是不完全符合主機系統時鍾的票據時戳的容差,超過此容差將不接受此票據。通常,將時鍾扭斜設置為 300 秒(5 分鍾)。這意味着從服務器的角度看,票證的時間戳與它的偏差可以是在前后 5 分鍾內。
- udp_preference_limit= 1:禁止使用 udp 可以防止一個 Hadoop 中的錯誤
- [realms]:列舉使用的 realm。
- kdc:代表要 kdc 的位置。格式是 機器:端口
- admin_server:代表 admin 的位置。格式是 機器:端口
- default_domain:代表默認的域名
- [appdefaults]:可以設定一些針對特定應用的配置,覆蓋默認配置。
這個相比默認的配置增改了比較多東西,特別是一些默認加密方式的設置:
default_tgs_enctypes = aes256-cts-hmac-sha1-96 default_tkt_enctypes = aes256-cts-hmac-sha1-96 permitted_enctypes = aes256-cts-hmac-sha1-96
加密的東西會有小坑,下面統一講。
2.2.2. 修改 /var/kerberos/krb5kdc/kdc.conf
該文件包含 Kerberos 的配置信息。例如,KDC 的位置,Kerbero 的 admin 的realms 等。需要所有使用的 Kerberos 的機器上的配置文件都同步。這里僅列舉需要的基本配置。詳細介紹參考krb5conf部分。
[kdcdefaults] kdc_ports = 88 kdc_tcp_ports = 88 [realms] EXAMPLE.COM = { #master_key_type = aes256-cts acl_file = /var/kerberos/krb5kdc/kadm5.acl dict_file = /usr/share/dict/words max_renewable_life = 7d max_life = 1d admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal default_principal_flags = +renewable, +forwardable }
同樣修改和增加了一些東西,尤其可以看到default_principal_flags部分,大概是為了解決到hue的定時更新憑證的問題。
- EXAMPLE.COM: 是設定的 realms。名字隨意。Kerberos 可以支持多個 realms,會增加復雜度。大小寫敏感,一般為了識別使用全部大寫。這個 realms 跟機器的 host 沒有大關系。
- master_key_type:和 supported_enctypes 默認使用 aes256-cts。JAVA 使用 aes256-cts 驗證方式需要安裝 JCE 包,見下面的說明。為了簡便,你可以不使用 aes256-cts 算法,這樣就不需要安裝 JCE 。
- acl_file:標注了 admin 的用戶權限,需要用戶自己創建。文件格式是:Kerberos_principal permissions [target_principal] [restrictions]
- supported_enctypes:支持的校驗方式。
- admin_keytab:KDC 進行校驗的 keytab。
2.2.3. 關於加密方式
原文中提到了AES-256的一段描述:
對於使用 centos5. 6 及以上的系統,默認使用 AES-256 來加密的。這就需要集群中的所有節點上安裝 JCE,如果你使用的是 JDK1.6 ,則到Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE 6 頁面下載,如果是 JDK1.7,則到 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE 7 下載。下載的文件是一個 zip 包,解開后,將里面的兩個文件放到下面的目錄中:$JAVA_HOME/jre/lib/security.
上面這一步一定要做,否則會報zk,namenode等不支持默認tkt的加密方式錯誤。
看了這個,因為我的版本是jdk1.8,所以在$JAVA_HOME/jre/lib/security 路徑找了一下,是存在兩個jar包的:
- local_policy.jar
- US_export_policy.jar
詭異的是,我兩次安裝都遇到了編碼問題,有一次應該是Activity Monitor 報錯:
ERROR Main
Failed to start Firehose
java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.io.IOException: Login failure for hue/$server1@ANYTHING.COM from keytab cmon.keytab
...
Caused by: KrbException: no supported default etypes for default_tkt_enctypes
然后我自己搗鼓了一下,去官網下載了這個包:Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 Download;
然后備份了一下原來jre目錄下的文件,用下載的兩個包覆蓋過去,然后重啟krb5-server的兩個服務,后面重啟又可以了。
所以開不開aes256-cts算法要按照自己的情況去定,而且這個決定跟后面集成到cdh中有聯系。
2.2.4. 修改配置/var/kerberos/krb5kdc/kadm5.acl
*/admin@EXAMPLE.COM *
表示principal的名字的第二部分如果是admin,那么該principal就擁有管理員權限。
2.3. 同步配置文件
將master的/etc/krb5.conf分發到其他slaver:
./scp_to_hosts.sh /etc/krb5.conf /etc/krb5.conf
2.4. 創建數據庫
在master上運行初始化數據庫命令,其中-r 指定對應 realm。
kdb5_util create -r EXAMPLE.COM –s
如果遇到數據庫已經存在的提示,可以把 /var/kerberos/krb5kdc/ 目錄下的 principal 的相關文件都刪除掉。默認的數據庫名字都是 principal。可以使用 -d指定數據庫名字。
2.5. 啟動kerberos服務
# 啟動服務:
systemctl restart krb5kdc
systemctl restart kadmin
# 開機自動重啟:
systemctl enable krb5kdc
systemctl enable kadmin
2.6. 創建 kerberos 管理員
關於 kerberos 的管理,可以使用 kadmin.local 或 kadmin,至於使用哪個,取決於賬戶和訪問權限:
如果有訪問 kdc 服務器的 root 權限,但是沒有 kerberos admin 賬戶,使用 kadmin.local;
如果沒有訪問 kdc 服務器的 root 權限,但是用 kerberos admin 賬戶,使用 kadmin在master上創建遠程管理的管理員;
kadmin.local -q "addprinc root/admin"
輸入密碼。
抽取密鑰並將其儲存在本地 keytab 文件 /etc/krb5.keytab 中。這個文件由超級用戶擁有,所以必須是 root 用戶才能在 kadmin shell 中執行以下命令:
kadmin.local -q "ktadd kadmin/admin" # 查看生成的keytab klist -k /etc/krb5.keytab
2.7. 測試kerberos
# 列出Kerberos中的所有認證用戶,即principals kadmin.local -q "list_principals" # 添加認證用戶,需要輸入密碼 kadmin.local -q "addprinc user1" # 使用該用戶登錄,獲取身份認證,需要輸入密碼 kinit user1 # 查看當前用戶的認證信息ticket klist # 更新ticket kinit -R # 銷毀當前的ticket kdestroy # 刪除認證用戶 kadmin.local -q "delprinc user1"
2.8. CM節點安裝額外組件
在cloudera manager server 所在節點安裝額外的組件:
yum -y install openldap-clients
這個在原博客中博主忘記了。
3. Cloudera配置kerboros
3.1. 配置前確認
- KDC已經安裝好並且正在運行
- 將KDC配置為允許renewable tickets with non-zerolifetime(在之前修改kdc.conf文件的時候已經添加了kdc_tcp_ports、max_life和max_renewable_life這個三個選項)
- 在Cloudera Manager Server上安裝openldap-clients
- 為Cloudera Manager創建一個principal,使其能夠有權限在KDC中創建其他的principals,就是上面創建的Kerberos管理員賬號
3.2. cloudera配置kerboros
進入Cloudera Manager,集群,操作,啟用kerberos:
選擇“啟用Kerberos”。
確保如下列出的所有檢查項都已完成,全部勾選,繼續。
點擊“繼續”,配置相關的KDC信息,包括類型、KDC服務器、KDC Realm、加密類型以及待創建的Service Principal(hdfs,yarn,,hbase,hive等)的更新生命期等。
我的例子中,
KDC類型:MIT KDC
kerberos安全領域:EXAMPLE.COM
KDC server主機:master
KDC Admin Server Host: master
這個界面有個選項,kerboros加密類型,需要和KDC實際支持的加密類型匹配即 /etc/krb5.conf 中的default_tgs_enctypes、default_tkt_enctypes和permitted_enctypes三個選項的值對應起來,不然會出現集群服務無法認證通過的情況。
填 aes256-cts 繼續。
KRB5配置,不建議讓Cloudera Manager來管理krb5.conf, 不勾選,點擊“繼續”。
KDC Account Manager 憑據,輸入Cloudera Manager的Kerbers管理員賬號,一定得和之前創建的賬號一致,點擊“繼續”。
Kerberos主體,默認就好,繼續。
配置端口,勾選准備好重啟集群,繼續。
集群重啟完成,點擊“繼續”。
點擊“繼續”,點擊“完成”,至此已成功啟用Kerberos。
不過一般不會那么順利的了,我大部分遇到的是加密算法的問題。
4. 其他
4.1. 在CM上啟用Kerberos的過程中,CM自動執行的事情
4.1.1. 生成賬號對應的principle
集群中有多少個節點,每個賬戶都會生成對應個數的principal,格式為username/hostname@EXAMPLE.COM,例如hdfs/slaver1@EXAMPLE.COM。使用如下命令來查看:
kadmin.local -q "list_principals"
4.1.2. 為每個對應的principal創建keytab
4.1.3. 部署keytab文件到指定的節點中
keytab是包含principals和加密principal key的文件,keytab文件對於每個host是唯一的,因為key中包含hostname,keytab文件用於不需要人工交互和保存純文本密碼,實現到kerberos上驗證一個主機上的principal。啟用之后訪問集群的所有資源都需要使用相應的賬號來訪問,否則會無法通過Kerberos的authenticatin
4.1.4.在每個服務的配置文件中加入有關Kerberos的配置
其中包括Zookeeper服務所需要的jaas.conf和keytab文件都會自動設定並讀取,如果用戶仍然手動修改了Zookeeper的服務,要確保這兩個文件的路徑和內容正確性。
4.2. 創建HDFS超級用戶
此時直接用CM生成的principal訪問HDFS會失敗,因為那些自動生成的principal的密碼是隨機的,用戶並不知道,而通過命令行的方式訪問HDFS需要先使用kinit來登錄並獲得ticket,所以使用kinit hdfs/slaver1@EXAMPLE 需要輸入密碼的時候無法繼續。用戶可以通過創建一個hdfs@EXAMPLE.COM的principal並記住密碼從命令行中訪問HDFS。登錄之后就可以通過認證並訪問HDFS,默認hdfs用戶是超級用戶。
kadmin.local -q "addprinc hdfs" kinit hdfs@EXAMPLE.COM
4.3. 為每個用戶創建principal
當集群運行Kerberos后,每一個Hadoop user都必須有一個principal或者keytab來獲取Kerberos credentials(即使用密碼的方式或者使用keytab驗證的方式)這樣才能訪問集群並使用Hadoop的服務。也就是說,如果Hadoop集群存在一個名為hdfs@EXAMPLE.COM的principal那么在集群的每一個節點上應該存在一個名為hdfs的Linux用戶。同時,在HDFS中的目錄/user要存在相應的用戶目錄(即/user/hdfs),且該目錄的owner和group都要是hdfs
一般來說,Hadoop user會對應集群中的每個服務,即一個服務對應一個user。例如impala服務對應用戶impala。
至此,集群上的服務都啟用了Kerberos的安全認證。
4.4. 驗證Kerberos在集群上是否正常工作
4.4.1.確認HDFS可以正常使用
登錄到某一個節點后,切換到hdfs用戶,然后用kinit來獲取credentials
現在用hadoop hdfs -ls /應該能正常輸出結果
用kdestroy銷毀credentials后,再使用hadoop hdfs -ls /會發現報錯。
4.4.2. 確認可以正常提交MapReduce job
獲取了hdfs的證書后,提交一個PI程序,如果能正常提交並成功運行,則說明Kerberized Hadoop cluster在正常工作。
hadoop jar /opt/cloudera/parcels/CDH-5.9.0-1.cdh5.9.0.p0.23/lib/hadoop-mapreduce/hadoop-mapreduce-examples-2.6.0-cdh5.9.0.jar pi 2 2
5. 預留坑位
6. 參考
如何在Redhat7.3的CDH5.14中啟用Kerberos
(完)