轉載自 JavaChen Blog,作者:JavaChen
原文鏈接地址:http://blog.javachen.com/2014/11/04/config-kerberos-in-cdh-hdfs.html
轉載自 小黑的博客
原文鏈接地址:http://www.xiaohei.info/2016/09/01/cdh-install-kerberos-ldap-sentry/
參考上面兩篇基本配置,添加了部分配置
本文主要記錄 CDH 集群上集成 Kerberos 的過程,包括 Kerberos 的安裝和 CDH 相關配置修改說明。
一、安裝Kerberos
1. 整體說明
軟件版本
操作系統:CentOs 6.8
CDH版本:Hadoop 2.6.0-cdh5.9.0
JDK版本:jdk1.7.0_67-cloudera
運行用戶:root集群主機角色劃分
sunmvm20 作為master節點,安裝kerberos Server
其他節點作為slave節點,安裝kerberos client
2. 配置host
添加主機名到 /etc/hosts 文件中。
$ cat /etc/hosts
127.0.0.1 localhost
192.168.1.20 sunmvm20
192.168.1.26 sunmvm26
192.168.1.27 sunmvm27
192.168.1.28 sunmvm28
注意:hostname 請使用小寫,要不然在集成 kerberos 時會出現一些錯誤。
3. 安裝 Kerberos
在 sunmvm20 上安裝 krb5、krb5-server 和 krb5-client。
yum install krb5-server -y
# klist等命令找不大時執行下面安裝
yum install -y krb5-server krb5-workstation pam_krb5
在其他節點安裝 krb5-devel、krb5-workstation
$ ssh sunmvm26 "yum install krb5-devel krb5-workstation -y"
$ ssh sunmvm27 "yum install krb5-devel krb5-workstation -y"
$ ssh sunmvm28 "yum install krb5-devel krb5-workstation -y"
4. 修改配置文件
kdc 服務涉及到三個配置文件:
- /etc/krb5.conf
- /var/kerberos/krb5kdc/kdc.conf
- /var/kerberos/krb5kdc/kadm5.acl
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 = 0HKJ.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]
0HKJ.COM = {
kdc = sunmvm20
admin_server = sunmvm20
}
[domain_realm]
.0hkj.com = 0HKJ.COM
ohkj.com = 0HKJ.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]:可以設定一些針對特定應用的配置,覆蓋默認配置。
2)修改 /var/kerberos/krb5kdc/kdc.conf ,該文件包含 Kerberos 的配置信息。例如,KDC 的位置,Kerbero 的 admin 的realms 等。需要所有使用的 Kerberos 的機器上的配置文件都同步。這里僅列舉需要的基本配置。詳細介紹參考:krb5conf
[kdcdefaults]
kdc_ports = 88
kdc_tcp_ports = 88
[realms]
0HKJ.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
}
說明:
- 0HKJ.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。
關于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的加密方式錯誤。
3)為了能夠不直接訪問 KDC 控制臺而從 Kerberos 數據庫添加和刪除主體,請對 Kerberos 管理服務器指示允許哪些主體執行哪些操作。通過創建 /var/lib/kerberos/krb5kdc/kadm5.acl 完成此操作。
$ cat /var/kerberos/krb5kdc/kadm5.acl
內容如下:
*/admin@0HKJ.COM *
表示principal的名字的第二部分如果是admin,那么該principal就擁有管理員權限
5. 同步配置文件
將 kdc 中的 /etc/krb5.conf 拷貝到集群中其他服務器即可。
$ scp /etc/krb5.conf sunmvm26:/etc/krb5.conf
$ scp /etc/krb5.conf sunmvm27:/etc/krb5.conf
$ scp /etc/krb5.conf sunmvm28:/etc/krb5.conf
6. 創建數據庫
在 sunmvm20 上運行初始化數據庫命令。其中 -r 指定對應 realm。
$ kdb5_util create -r 0HKJ.COM -s
出現 Loading random data 的時候另開個終端執行點消耗CPU的命令如 cat /dev/sda > /dev/urandom 可以加快隨機數采集。該命令會在 /var/kerberos/krb5kdc/ 目錄下創建 principal 數據庫。
如果遇到數據庫已經存在的提示,可以把 /var/kerberos/krb5kdc/ 目錄下的 principal 的相關文件都刪除掉。默認的數據庫名字都是 principal。可以使用 -d指定數據庫名字。
7. 啟動Kerberos服務
在 sunmvm20 節點上運行:
$ chkconfig --level 35 krb5kdc on
$ chkconfig --level 35 kadmin on
$ service krb5kdc start
$ service kadmin start
8. 創建 kerberos 管理員
關于 kerberos 的管理,可以使用 kadmin.local 或 kadmin,至于使用哪個,取決于賬戶和訪問權限:
如果有訪問 kdc 服務器的 root 權限,但是沒有 kerberos admin 賬戶,使用 kadmin.local
如果沒有訪問 kdc 服務器的 root 權限,但是用 kerberos admin 賬戶,使用 kadmin
在 sunmvm20 上創建遠程管理的管理員:手動輸入兩次密碼
$ kadmin.local -q "addprinc root/admin"
- 也可以不用手動輸入密碼
$ echo -e "root\nroot" | 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
9. 測試 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"
二、CDH啟用Kerberos
CM中的操作
在CM的界面上點擊啟用Kerberos,啟用的時候需要確認幾個事情:
1.KDC已經安裝好并且正在運行
2.將KDC配置為允許renewable tickets with non-zerolifetime(在之前修改kdc.conf文件的時候已經添加了kdc_tcp_ports、max_life和max_renewable_life這個三個選項)
3.在Cloudera Manager Server上安裝openldap-clients
4.為Cloudera Manager創建一個principal,使其能夠有權限在KDC中創建其他的principals,就是上面創建的Kerberos管理員賬號
上述確認完了之后點擊continue,進入下一頁進行配置,要注意的是:這里的『Kerberos Encryption Types』必須跟KDC實際支持的加密類型匹配即 /etc/krb5.conf 中的default_tgs_enctypes、default_tkt_enctypes和permitted_enctypes三個選項的值對應起來,不然會出現集群服務無法認證通過的情況。
填 aes256-cts
點擊continue,進入下一頁,這一頁中可以不勾選『Manage krb5.conf through Cloudera Manager』注意,如果勾選了這個選項就可以通過CM的管理界面來部署krb5.conf,但是實際操作過程中發現有些配置仍然需要手動修改該文件并同步。
點擊continue,進入下一頁,輸入Cloudera Manager Principal的管理員賬號和密碼,注意輸入賬號的時候要使用@前要使用全稱,root/admin。
點擊continue,進入下一頁,導入KDC Account Manager Credentials。
點擊continue,進入下一頁,restart cluster并且enable Kerberos。
之后CM會自動重啟集群服務,啟動之后會會提示Kerberos已啟用。
在CM上啟用Kerberos的過程中,CM會自動做以下的事情:
1.集群中有多少個節點,每個賬戶都會生成對應個數的principal,格式為username/hostname@OHKJ.COM,例如hdfs/hadoop-10-0-8-124@OHKJ.COM。使用如下命令來查看:
kadmin.local -q "list_principals"
2.為每個對應的principal創建keytab
3.部署keytab文件到指定的節點中
keytab是包含principals和加密principal key的文件,keytab文件對于每個host是唯一的,因為key中包含hostname,keytab文件用于不需要人工交互和保存純文本密碼,實現到kerberos上驗證一個主機上的principal。啟用之后訪問集群的所有資源都需要使用相應的賬號來訪問,否則會無法通過Kerberos的authenticatin
4.在每個服務的配置文件中加入有關Kerberos的配置,其中包括Zookeeper服務所需要的jaas.conf和keytab文件都會自動設定并讀取,如果用戶仍然手動修改了Zookeeper的服務,要確保這兩個文件的路徑和內容正確性。
創建HDFS超級用戶
此時直接用CM生成的principal訪問HDFS會失敗,因為那些自動生成的principal的密碼是隨機的,用戶并不知道,而通過命令行的方式訪問HDFS需要先使用kinit來登錄并獲得ticket,所以使用kinit hdfs/hadoop-10-0-8-124@XIAOHEI.INFO需要輸入密碼的時候無法繼續。用戶可以通過創建一個hdfs@0HKJ.COM的principal并記住密碼從命令行中訪問HDFS。登錄之后就可以通過認證并訪問HDFS,默認hdfs用戶是超級用戶。
kadmin.local -q "addprinc hdfs"
kinit hdfs@0HKJ.COM
為每個用戶創建principal
當集群運行Kerberos后,每一個Hadoop user都必須有一個principal或者keytab來獲取Kerberos credentials(即使用密碼的方式或者使用keytab驗證的方式)這樣才能訪問集群并使用Hadoop的服務。也就是說,如果Hadoop集群存在一個名為hdfs@0HKJ.COM的principal那么在集群的每一個節點上應該存在一個名為hdfs的Linux用戶。同時,在HDFS中的目錄/user要存在相應的用戶目錄(即/user/hdfs),且該目錄的owner和group都要是hdfs
一般來說,Hadoop user會對應集群中的每個服務,即一個服務對應一個user。例如impala服務對應用戶impala。
至此,集群上的服務都啟用了Kerberos的安全認證
三、驗證Kerberos在集群上是否正常工作
1.確認HDFS可以正常使用
登錄到某一個節點后,切換到hdfs用戶,然后用kinit來獲取credentials
現在用hadoop hdfs -ls /
應該能正常輸出結果
用kdestroy銷毀credentials后,再使用hadoop hdfs -ls /
會發現報錯
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
四、集群集成Kerberos過程中遇到的坑
hdfs用戶提交mr作業無法運行
INFO mapreduce.Job: Job job_1442654915965_0002 failed with state FAILED due to: Application application_1442654915965_0002 failed 2 times due to AM Container for appattempt_1442654915965_0002_000002 exited with exitCode: -1000 due to: Application application_1442654915965_0002 initialization failed (exitCode=255) with output: Requested user hdfs is not whitelisted and has id 496,which is below the minimum allowed 1000
原因:
Linux user 的 user id 要大于等于1000,否則會無法提交Job。例如,如果以hdfs(id為490)的身份提交一個job,就會看到以上的錯誤信息
解決方法:
1.使用命令 usermod -u 修改一個用戶的user id
2.修改Clouder關于這個該項的設置,Yarn->配置->min.user.id修改為合適的值,當前為0
提交mr作業時可以運行但是有錯誤信息
INFO mapreduce.Job: Job job_1442722429197_0001 failed with state FAILED due to: Application application_1442722429197_0001 failed 2 times due to AM Container for appattempt_1442722429197_0001_000002 exited with exitCode: -1000 due to: Application application_1442722429197_0001 initialization failed (exitCode=255) with output: Requested user hdfs is banned
原因:
hdfs用戶被禁止運行 YARN container,yarn的設置中將hdfs用戶禁用了
解決方法:
修改Clouder關于這個該項的設置,Yarn->配置->banned.users 將hdfs用戶移除
YARN job運行時無法創建緩存目錄
異常信息:
main : user is hdfs
main : requested yarn user is hdfs
Can’t create directory /data/data/yarn/nm/usercache/hdfs/appcache/application_1442724165689_0005 - Permission denied
原因:
該緩存目錄在集群進入Kerberos狀態前就已經存在了。例如當我們還沒為集群Kerberos支持的時候,就用該用戶跑過YARN應用
解決方法:
在每一個NodeManager節點上刪除該用戶的緩存目錄,對于用戶hdfs,是/data/data/yarn/nm/usercache/hdfs