1. 集群密码轮换的整体思路与风险预判
大数据集群跑久了,密码轮换这件事基本躲不掉。不管是安全审计要求、人员变动,还是单纯觉得默认密码太弱想加固,只要动了密码,就不是改一个地方那么简单。我这次处理的是一个典型的ambari + HDP集群,涉及四个关键账号:ambari、hive、root、azkaban。这四个账号分布在不同的层次上,改密码的路径、影响面、回滚难度完全不一样,所以第一步不是急着敲命令,而是先把它们各自扮演的角色理清楚。
ambari账号是 Ambari Server 用来访问自己元数据库的账号,通常库名是ambari,这个账号一旦密码不对,Ambari Server 直接起不来,整个管理界面全挂。hive账号是 Hive Metastore 访问元数据库的账号,库名一般是hive,它挂了影响的是 Hive、Spark SQL、Impala 这些依赖 Metastore 的组件。root是 MySQL 的超级管理员,改它风险最高,因为很多组件的连接配置里可能直接写了 root,或者有定时任务用 root 连库。azkaban是调度系统的元数据库账号,库名通常是azkaban,它挂了影响的是工作流调度。
提示:改密码之前,务必确认当前集群没有正在跑的关键任务,尤其是 Azkaban 上的调度作业。密码切换的瞬间,旧连接会断,新连接如果配置没同步,任务会直接失败。
我一般的做法是先做一张影响面清单,把每个账号对应的配置文件位置、依赖组件、重启顺序列出来。这张表后面会反复用到,因为改密码不是改完就完事,你得知道改完之后要去哪里同步配置、按什么顺序重启服务。
| 账号 | 所属库 | 主要使用方 | 配置文件位置 | 影响组件 |
|---|---|---|---|---|
| ambari | ambari | Ambari Server | /etc/ambari-server/conf/ambari.properties | Ambari Server 本身 |
| hive | hive | Hive Metastore | /etc/hive/conf/hive-site.xml | Hive、Spark、Impala |
| root | mysql | 多组件混用 | 各处连接串 | 不确定,需全局排查 |
| azkaban | azkaban | Azkaban Web/Exec | /opt/azkaban/conf/azkaban.properties | Azkaban 调度 |
这张表是我踩过坑之后总结的,最早有一次我只改了数据库密码,忘了同步hive-site.xml,结果 Hive Metastore 重启后一直连不上,日志里报Access denied,排查了半天才反应过来。所以改密码的本质是“数据库侧改密码 + 应用侧同步配置 + 重启服务”三步走,缺一不可。
还有一个容易被忽略的点:MySQL 的密码认证插件。MySQL 5.7 和 8.0 默认的认证方式不一样,8.0 默认用caching_sha2_password,而一些老版本的 JDBC 驱动或者组件可能只支持mysql_native_password。如果你在 8.0 上改密码时没注意这个,改完之后应用连不上,报的错还不是密码错误,而是认证插件不兼容,很容易误导排查方向。所以改密码前先确认 MySQL 版本和驱动版本,必要时在改密码语句里显式指定认证插件。
另外,root 账号的处理要格外小心。理想情况下,生产集群不应该让任何组件用 root 连库,但现实中很多历史遗留配置就是用了 root。我的建议是,改 root 密码之前,先用grep在整个配置目录里搜一遍,看看哪些地方引用了 root 的连接串。如果发现某个组件确实在用 root,要么改成专用账号,要么确保改密码后同步更新那个配置。这一步偷懒,后面就是无尽的排查。
2. 改密码前的环境确认与备份操作
动手之前,环境确认和备份是保命环节。我见过太多人直接上去就ALTER USER,结果改完发现某个配置文件没备份,回滚都回不去。所以这一节我把改密码前的准备工作拆细一点,确保你每一步都有退路。
2.1 确认 MySQL 版本与当前认证方式
第一步是登录 MySQL,确认版本和现有用户的认证插件。命令很简单:
mysql -uroot -p登录后执行:
SELECT VERSION(); SELECT user, host, plugin FROM mysql.user WHERE user IN ('ambari','hive','root','azkaban');这里重点看plugin字段。如果显示caching_sha2_password,而你的组件驱动比较老,那改密码时就要考虑降级到mysql_native_password。如果显示mysql_native_password,那就保持原样,不要随意升级认证方式,否则可能引发兼容性问题。
注意:
host字段也很关键。有些账号是localhost,有些是%。如果你改密码时没注意 host,可能会出现“改了但连不上”的情况,因为应用连的是%那条记录,而你改的是localhost那条。
2.2 备份 MySQL 用户表与关键配置
MySQL 的用户信息存在mysql.user表里,改之前先导出一份:
mysqldump -uroot -p mysql user > /tmp/mysql_user_backup_$(date +%F).sql这个备份文件在回滚时非常有用。虽然直接恢复mysql.user表不是官方推荐做法,但在紧急情况下,它能帮你快速还原用户和权限信息。
配置文件也要备份。我通常会把涉及到的几个配置文件统一拷到一个备份目录:
mkdir -p /tmp/conf_backup_$(date +%F) cp /etc/ambari-server/conf/ambari.properties /tmp/conf_backup_$(date +%F)/ cp /etc/hive/conf/hive-site.xml /tmp/conf_backup_$(date +%F)/ cp /opt/azkaban/conf/azkaban.properties /tmp/conf_backup_$(date +%F)/别嫌麻烦,这几个文件加起来不到几兆,但真出问题时,它们能帮你省下几个小时甚至一天的排查时间。
2.3 记录当前服务状态与连接测试
改密码前,先确认各个服务当前是正常的,这样改完之后如果出问题,你能明确知道是改密码导致的,而不是原本就有毛病。检查命令:
# Ambari Server 状态 ambari-server status # Hive Metastore 状态 systemctl status hive-metastore # Azkaban 状态 ps -ef | grep azkaban # 测试各账号连接 mysql -uambari -p'旧密码' -e "SELECT 1;" mysql -uhive -p'旧密码' -e "SELECT 1;" mysql -uazkaban -p'旧密码' -e "SELECT 1;"把这些连接测试的结果记下来,改完之后用同样的命令再测一遍,对比结果就能快速判断是否成功。
提示:如果旧密码里有特殊字符,比如
$、!、#,在命令行里要用单引号包起来,否则会被 shell 解释。我遇到过密码里有$导致连接失败的情况,排查半天才发现是 shell 转义问题。
3. 四个账号密码修改的完整实操流程
准备工作做完,接下来就是正式的改密码操作。我按照风险从低到高的顺序来:先改 azkaban,再改 hive,然后改 ambari,最后改 root。这样安排的原因是,azkaban 影响面最小,万一操作有问题,影响可控;root 影响面最大,放在最后,前面几个账号的操作已经帮你验证了流程和配置同步方法。
3.1 修改 azkaban 账号密码
Azkanban 的元数据库账号通常只被 Azkaban 自己使用,影响面相对小。改密码分两步:数据库侧改,应用侧同步。
数据库侧:
ALTER USER 'azkaban'@'%' IDENTIFIED BY 'NewAzkabanPass_2024'; FLUSH PRIVILEGES;如果 azkaban 账号的 host 是localhost,就把%换成localhost。改完之后立刻测试:
mysql -uazkaban -p'NewAzkabanPass_2024' -e "SELECT 1;"应用侧,编辑/opt/azkaban/conf/azkaban.properties,找到:
database.password=旧密码改成新密码。如果 Azkaban 有多个节点,每个节点的配置文件都要改。改完之后重启 Azkaban:
cd /opt/azkaban ./bin/shutdown-all.sh ./bin/start-all.sh重启后检查日志,确认没有数据库连接错误:
tail -f /opt/azkaban/logs/azkaban-webserver.log实操心得:Azkaban 的密码如果包含特殊字符,在
azkaban.properties里不需要额外转义,直接写明文即可。但如果你用的是 Azkaban 的数据库连接池配置,有些版本对特殊字符敏感,建议新密码只用字母、数字和下划线,避免不必要的麻烦。
3.2 修改 hive 账号密码
Hive 账号被 Hive Metastore 使用,影响 Hive、Spark SQL、Impala 等组件。改密码同样分两步。
数据库侧:
ALTER USER 'hive'@'%' IDENTIFIED BY 'NewHivePass_2024'; FLUSH PRIVILEGES;测试连接:
mysql -uhive -p'NewHivePass_2024' -e "SELECT 1;"应用侧,Hive 的连接配置在hive-site.xml里,关键属性是:
<property> <name>javax.jdo.option.ConnectionPassword</name> <value>NewHivePass_2024</value> </property>这个文件在 Hive Metastore 节点上,路径通常是/etc/hive/conf/hive-site.xml。如果你是通过 Ambari 管理的集群,不要直接改文件,因为 Ambari 会在重启服务时用它的配置覆盖你的修改。正确做法是在 Ambari Web UI 里改:
- 进入 Hive 服务页面
- 点击 Configs
- 搜索
ConnectionPassword - 修改为新密码
- 保存并重启 Hive 服务
注意:Ambari 管理下的配置文件,直接改磁盘文件是无效的,重启后会被覆盖。这个坑我踩过,当时改完文件重启,发现密码又变回旧的,排查半天才意识到是 Ambari 在覆盖。
如果你不是通过 Ambari 管理,而是手动部署的 Hive,那就直接改hive-site.xml,然后重启 Hive Metastore:
systemctl restart hive-metastore重启后验证:
beeline -u "jdbc:hive2://localhost:10000/default" -e "SHOW DATABASES;"能正常列出数据库,说明 Metastore 连接正常。
3.3 修改 ambari 账号密码
Ambari 账号是 Ambari Server 访问自己元数据库的账号,改它风险比前两个高,因为 Ambari Server 挂了,整个管理界面就没了。
数据库侧:
ALTER USER 'ambari'@'%' IDENTIFIED BY 'NewAmbariPass_2024'; FLUSH PRIVILEGES;测试连接:
mysql -uambari -p'NewAmbariPass_2024' -e "SELECT 1;"应用侧,Ambari 的连接配置在/etc/ambari-server/conf/ambari.properties,关键属性:
server.jdbc.user.passwd=旧密码但注意,Ambari 的密码不是明文存在这个文件里的,而是存在一个单独的密码文件里,属性是:
server.jdbc.user.passwd=/etc/ambari-server/conf/password.dat这个password.dat文件里存的是加密后的密码。所以你不能直接改ambari.properties,而是要用 Ambari 提供的命令来更新密码:
ambari-server setup -jdbc-db=mysql -jdbc-driver=com.mysql.jdbc.Driver \ -jdbc-url=jdbc:mysql://localhost:3306/ambari \ -jdbc-user=ambari -jdbc-password='NewAmbariPass_2024'这个命令会提示你确认,然后自动更新password.dat。执行完之后重启 Ambari Server:
ambari-server restart重启后检查 Ambari Server 日志:
tail -f /var/log/ambari-server/ambari-server.log确认没有数据库连接错误,然后打开 Ambari Web UI,能正常登录就说明成功了。
实操心得:
ambari-server setup命令在更新 JDBC 密码时,会重新生成password.dat。如果你之前手动改过password.dat,这个命令会覆盖它。所以执行前确保你知道当前的所有 JDBC 配置,避免被重置成默认值。
3.4 修改 root 账号密码
root 账号是风险最高的,因为很多组件可能直接或间接使用 root 连接数据库。改之前,先全局搜索哪些配置文件引用了 root:
grep -r "root" /etc/hive/conf/ /etc/ambari-server/conf/ /opt/azkaban/conf/ 2>/dev/null | grep -i password如果发现某个组件在用 root,先评估能否改成专用账号。如果暂时不能改,那就确保改完 root 密码后同步更新那个配置。
数据库侧:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewRootPass_2024'; FLUSH PRIVILEGES;注意,root 通常有多个 host 记录,比如root@localhost、root@127.0.0.1、root@%。你需要根据实际情况决定改哪个。如果应用是从远程连的,那root@%也要改。
改完之后,立刻测试:
mysql -uroot -p'NewRootPass_2024' -e "SELECT 1;"然后检查所有依赖 root 的组件,同步更新配置并重启。
注意:改 root 密码后,如果你之前配置了
~/.my.cnf或者/root/.my.cnf来自动登录,那些文件里的密码也要同步更新,否则一些脚本会失败。
4. 改完之后的验证与常见问题排查
密码改完不是终点,验证才是。我一般会做三层验证:数据库连接验证、应用服务验证、业务功能验证。这三层都过了,才算真正完成。
4.1 三层验证法确保改密成功
第一层:数据库连接验证。用新密码分别连接四个账号,确认都能正常登录:
mysql -uambari -p'NewAmbariPass_2024' -e "SELECT 1;" mysql -uhive -p'NewHivePass_2024' -e "SELECT 1;" mysql -uazkaban -p'NewAzkabanPass_2024' -e "SELECT 1;" mysql -uroot -p'NewRootPass_2024' -e "SELECT 1;"第二层:应用服务验证。检查各个服务的进程和日志:
# Ambari Server ambari-server status tail -50 /var/log/ambari-server/ambari-server.log # Hive Metastore systemctl status hive-metastore tail -50 /var/log/hive/hive-metastore.log # Azkaban ps -ef | grep azkaban tail -50 /opt/azkaban/logs/azkaban-webserver.log第三层:业务功能验证。实际跑一个查询或任务:
# Hive 查询 beeline -u "jdbc:hive2://localhost:10000/default" -e "SHOW DATABASES;" # Azkaban 任务 # 在 Azkaban Web UI 上手动触发一个简单的工作流三层都通过,基本可以确认改密成功。
4.2 常见报错与排查速查表
改密过程中最常见的报错就是Access denied,但背后的原因可能有好几种。我整理了一张速查表,方便你快速定位。
| 报错信息 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| Access denied for user 'hive'@'localhost' | 密码不对或 host 不匹配 | 检查 mysql.user 表中 hive 的 host 记录 | 确认改的是应用实际使用的 host 记录 |
| Access denied for user 'ambari'@'localhost' (using password: YES) | password.dat 未更新 | 检查 ambari.properties 中 password.dat 路径 | 用 ambari-server setup 重新设置密码 |
| Communications link failure | MySQL 服务未启动或网络不通 | systemctl status mysqld | 启动 MySQL 或检查防火墙 |
| Unknown authentication plugin 'caching_sha2_password' | 驱动不支持 MySQL 8.0 默认认证 | 检查 MySQL 版本和驱动版本 | 改密码时指定IDENTIFIED WITH mysql_native_password |
| Table 'ambari.users' doesn't exist | 连错了数据库 | 检查连接串中的库名 | 确认连接的是正确的库 |
提示:如果报错信息里显示
using password: NO,那说明应用根本没读到密码,问题出在配置文件路径或读取权限上,而不是密码本身。这个细节能帮你快速缩小排查范围。
4.3 回滚方案与应急处理
万一改完出问题,回滚要快。回滚分两步:先把数据库密码改回旧的,再把配置文件改回旧的,然后重启服务。
数据库侧回滚:
ALTER USER 'hive'@'%' IDENTIFIED BY '旧密码'; FLUSH PRIVILEGES;配置侧回滚,用之前备份的文件覆盖:
cp /tmp/conf_backup_日期/hive-site.xml /etc/hive/conf/hive-site.xml然后重启对应服务。如果 Ambari 的密码改错了,导致 Ambari Server 起不来,可以用ambari-server setup重新设置回旧密码。
实操心得:回滚时要注意,如果已经改了好几个账号,回滚也要按相反顺序来。先回滚 root,再回滚 ambari,然后 hive,最后 azkaban。这样能避免回滚过程中某个服务因为依赖的账号还没回滚而报错。
5. 密码管理的长期建议与自动化思路
改完这一轮密码,事情还没完。密码轮换不是一次性的,如果集群还在跑,以后还会遇到。所以这一节我想聊聊长期管理思路,帮你下次改密码时更从容。
5.1 建立密码台账与轮换周期
我建议给每个账号建一个台账,记录账号名、用途、所属库、配置文件位置、上次改密时间、下次计划改密时间。这个台账不用很复杂,一个表格就够了。轮换周期根据安全要求来,一般生产环境建议 90 天到 180 天轮换一次。但要注意,不要所有账号同一天改,否则一旦出问题,影响面太大。可以分批改,比如这周改 azkaban 和 hive,下周改 ambari 和 root。
台账示例:
| 账号 | 用途 | 所属库 | 配置文件 | 上次改密 | 下次改密 |
|---|---|---|---|---|---|
| ambari | Ambari Server 元数据 | ambari | password.dat | 2024-01-15 | 2024-04-15 |
| hive | Hive Metastore 元数据 | hive | hive-site.xml | 2024-01-15 | 2024-04-15 |
| azkaban | Azkaban 元数据 | azkaban | azkaban.properties | 2024-01-15 | 2024-04-15 |
| root | MySQL 管理 | mysql | 各处 | 2024-01-15 | 2024-04-15 |
5.2 用脚本减少重复劳动
如果你管理的集群不止一个,手动改密码效率太低。可以写一个简单的 Shell 脚本,把改密码、更新配置、重启服务串起来。但要注意,脚本里不要硬编码密码,可以用环境变量或者加密的配置文件来传。
一个简化的脚本框架:
#!/bin/bash # 改密脚本框架,实际使用需根据环境调整 NEW_PASS=$1 ACCOUNT=$2 if [ -z "$NEW_PASS" ] || [ -z "$ACCOUNT" ]; then echo "Usage: $0 <new_password> <account>" exit 1 fi # 数据库侧改密 mysql -uroot -p'当前root密码' -e "ALTER USER '$ACCOUNT'@'%' IDENTIFIED BY '$NEW_PASS'; FLUSH PRIVILEGES;" # 根据账号更新对应配置 case $ACCOUNT in hive) sed -i "s|<value>.*</value>| <value>$NEW_PASS</value>|" /etc/hive/conf/hive-site.xml systemctl restart hive-metastore ;; azkaban) sed -i "s|database.password=.*|database.password=$NEW_PASS|" /opt/azkaban/conf/azkaban.properties /opt/azkaban/bin/shutdown-all.sh && /opt/azkaban/bin/start-all.sh ;; *) echo "Account $ACCOUNT not configured in this script" ;; esac这个脚本只是框架,实际使用时要把 root 密码、配置文件路径、重启命令都替换成你环境里的真实值。而且脚本里的密码传递要注意安全,不要直接写在命令行里,因为命令行历史会记录。可以用read -s交互式输入,或者从加密文件读取。
注意:自动化脚本虽然方便,但第一次执行时一定要在测试环境验证。我见过有人直接在生产环境跑脚本,结果 sed 替换把配置文件格式搞乱了,服务起不来。所以脚本上线前,先在测试环境跑一遍,确认没问题再用到生产。
5.3 权限最小化与专用账号
最后说一个治本的建议:尽量让每个组件用专用账号,不要共用 root。这次改密码之所以麻烦,很大一部分原因就是 root 被多个地方引用。如果每个组件都有自己的专用账号,改密码时影响面就小很多,回滚也容易。
具体做法是,给每个组件创建一个独立账号,只授予它需要的库的权限。比如 Hive 只需要hive库的权限,那就只授hive.*,不要给全局权限。这样即使某个账号密码泄露,影响也有限。
CREATE USER 'hive_metastore'@'%' IDENTIFIED BY 'StrongPass_2024'; GRANT ALL PRIVILEGES ON hive.* TO 'hive_metastore'@'%'; FLUSH PRIVILEGES;然后把 Hive 的配置从hive账号改成hive_metastore。这样下次改密码时,只需要改hive_metastore一个账号,不会牵连其他组件。
我个人在实际操作中的体会是,密码轮换这件事,技术难度不高,但细节特别多。每一次改密码,都是一次对集群配置管理水平的检验。配置管理越规范,改密码越轻松;配置管理越乱,改密码越像拆炸弹。所以与其每次改密码时手忙脚乱,不如平时就把账号、配置、台账理清楚。这样不管什么时候需要轮换,都能从容应对。