干过大数据平台运维的人应该都清楚CDH系列里5.14.0算是一个承上启下的版本它保留了传统Hadoop发行版的成熟度又兼容了Spark 2、Kafka等常见生态组件。很多老项目到现在还在用这个版本所以开工之前的环境准备如果偷懒后面Cloudera Manager的安装一定会卡在莫名其妙的地方。这篇文章就是系列第一篇专门把环境准备阶段的所有细节摊开讲适合正在搭测试集群的、或者第一次从零接触CDH的同学也是给我自己留一份能直接照做的步骤清单。1. 整体部署思路与版本选型1.1 版本选型背后的考量CDH 5.14.0对应的Cloudera Manager版本也是5.14.0。之所以很多人盯着这个版本不放主要是它支持的HDFS、YARN、Hive、Impala等组件的功能已经相对完善而且对硬件的要求不像后面CDH 6那么激进。不过我要提醒一句CDH 5.x系列已经不再更新如果你只是学习或维护老系统5.14.0完全够用如果是全新生产项目建议优先评估新版本。部署方式上我推荐用Cloudera Manager的Parcel方式安装。Parcel本质上就是一个打包好的二进制分发文件Cloudera Manager可以通过它自动分发和安装所有组件省去手工逐个rpm安装的麻烦。在线安装虽然简单但国内网络环境不稳定而且后续如果需要在多台机器上重复安装下载流量也很大。所以我建议一律走离线Parcel安装这也是环境准备阶段需要做的事情。1.2 集群规划与资源评估先规划节点。以最小可用的3节点集群为例角色分配如下节点标识主机名规划核心角色节点1cdh-masterCloudera Manager Server、NameNode、ResourceManager、HBase Master节点2cdh-node01DataNode、NodeManager、JournalNode节点3cdh-node02DataNode、NodeManager、JournalNode、SecondaryNameNode这是最简单的规划适用于4到8个数据盘、总内存64GB左右的小集群。如果你只有一台16GB内存的物理机也可以把三个节点做成虚拟机但至少要为Cloudera Manager Server预留4GB内存否则后续服务启动会崩溃。磁盘方面不要把所有数据堆在系统盘上。系统盘建议单独用一块SSD或HDD数据盘单独划分。HDFS的DataNode数据目录和数据盘直接对应不要使用LVM再去动态扩展虽然能用但遇到磁盘故障时处理起来很麻烦。1.3 操作系统与JDK兼容性CDH 5.14.0官方支持的操作系统包括RHEL 7系列和CentOS 7系列。我的建议是直接用CentOS 7.6或7.7版本太老如7.0会出现内核和网卡驱动的问题版本太新如7.9则需要额外注意内核与CDH自带组件库的兼容性。我实测CentOS 7.9跑CDH5.14.0也没什么大问题但为了少踩坑还是推荐用官网上明确列出的版本。JDK必须用1.8而且我更推荐Oracle JDK不要用OpenJDK。虽然OpenJDK在部分测试场景下能跑但Cloudera Manager在检测Java版本时可能会挑三拣四后续执行一些脚本时会出现莫名其妙的ClassNotFound异常。这个选择不是为了炫技只是为了少排查几个问题。2. 操作系统安装与基础环境初始化2.1 磁盘分区与挂载策略安装CentOS时不要使用默认的自动分区手动分区更有把握。我习惯把系统盘划成三个分区/boot给1GBswap根据内存情况分配剩下的给/。数据盘则单独分区并挂载到/data目录后面所有大数据组件的数据目录都放在/data下。分区之后记录磁盘的UUID写入/etc/fstab保证重启后依然能正确挂载。一个常见的坑是用设备名/dev/sdb写fstab但设备名在重启后可能变化导致挂载失败。正确做法是通过blkid查看UUID然后用UUID挂载blkid /dev/sdb得到类似UUIDabc-123...的输出后再编辑/etc/fstabecho UUIDabc-123... /data ext4 defaults 0 0 /etc/fstab mount -a df -h数据盘建议直接用ext4格式化虽然xfs性能不错但Cloudera的某些官方文档和脚本对ext4的兼容性更好尤其是在部署Kudu这类对文件系统敏感的服务时。格式化命令mkfs.ext4 /dev/sdb1如果你拿到的是整块未分区的盘可以先用parted或fdisk分区再格式化。2.2 主机名与hosts配置主机名规划必须提前统一。我见过有人把主机名写成cdh01.xxx.com也见过带下划线的主机名这些都是隐患。主机名不要使用下划线Cloudera Manager的很多脚本在做DNS解析时会把下划线当作非法字符。统一设置主机名hostnamectl set-hostname cdh-master然后编辑/etc/hosts把集群所有节点的IP和主机名都填进去而不是只写本机192.168.10.10 cdh-master 192.168.10.11 cdh-node01 192.168.10.12 cdh-node02这也是环境准备里最容易忽略的一项。如果后续发现Cloudera Manager Agent无法和Server通信九成都是因为Agent所在节点解析不了Server的主机名。最后把/etc/hosts同步到所有节点。不要使用主机名代替监听地址Cloudera Manager虽然支持但多网卡环境下很容易出现网络绑定错乱。2.3 关闭防火墙与SELinux关闭防火墙是内网集群部署的默认操作。不是说防火墙不重要而是大数据组件的端口数量非常庞大既有HDFS的8020、9820也有YARN的8088、8030还有Cloudera Manager动态分配的端口。如果一个个去配置防火墙策略维护成本很高而且容易漏配。内网环境可以通过物理网络隔离来保障安全因此最简单的方式就是关闭系统防火墙。systemctl stop firewalld systemctl disable firewalld systemctl status firewalldSELinux同样要关闭或者至少设置为permissive模式。SELinux对文件访问控制非常严格Cloudera Manager生成的进程经常因为SELinux阻断NFS或HDFS目录访问而失败。修改/etc/selinux/configsed -i s/SELINUXenforcing/SELINUXdisabled/ /etc/selinux/config修改后必须重启才能彻底生效。如果你想临时验证效果可以先用setenforce 0但重启后仍然需要确认配置已改。2.4 系统内核参数与文件句柄优化打开文件描述符的限制必须提前调大。大数据组件会一次性打开大量文件默认的1024远远不够。我习惯设置成65535也有人设置成1048576看你的集群压力。修改/etc/security/limits.conf* soft nofile 65535 * hard nofile 65535 * soft nproc 131072 * hard nproc 131072如果是root用户还需要额外加一段root soft nofile 65535 root hard nofile 65535 root soft nproc 131072 root hard nproc 131072修改完重新登录或ulimit -n验证。还有一个官方文档里明确要求做的优化是关闭透明大页。内存碎片对Hadoop这类常驻进程影响很大提前关掉能避免许多性能毛刺。执行命令echo never /sys/kernel/mm/transparent_hugepage/enabled echo never /sys/kernel/mm/transparent_hugepage/defrag但这只是临时的重启后会失效。需要写入/etc/rc.local并赋予执行权限echo echo never /sys/kernel/mm/transparent_hugepage/enabled /etc/rc.local echo echo never /sys/kernel/mm/transparent_hugepage/defrag /etc/rc.local chmod x /etc/rc.local另外建议把vm.swappiness调低避免系统过多使用swap交换分区。修改/etc/sysctl.confvm.swappiness1 sysctl -p注意透明大页的判断可以通过cat /sys/kernel/mm/transparent_hugepage/enabled查看输出中[never]表示已关闭。如果显示[always]说明还没生效。3. JDK与基础依赖准备3.1 JDK版本与安装包选择上一节说了要用Oracle JDK 1.8具体版本建议选择8u202或更早版本。为什么强调这个因为较新的JDK 8u211之后虽然还在1.8大版本范围内但授权协议变了而且Cloudera官方自带的一些组件在旧版本上经过充分测试随便跨版本容易出现意外。安装方式可以选择rpm包或tar.gz包。rpm包安装简单但会散落文件到各目录卸载不干净。tar.gz包便于统一管理环境我推荐用后者。先把下载好的jdk-8u202-linux-x64.tar.gz上传到/opt/目录解压并重命名cd /opt tar zxf jdk-8u202-linux-x64.tar.gz mv /opt/jdk1.8.0_202 /opt/jdk8然后配置环境变量在/etc/profile末尾追加export JAVA_HOME/opt/jdk8 export PATH$JAVA_HOME/bin:$PATH export CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar执行source /etc/profile并验证java -version输出类似java version 1.8.0_202 Java(TM) SE Runtime Environment (build 1.8.0_202-b08) Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)注意JAVA_HOME一定不要设置到/etc/alternatives/java这种软链路径Cloudera Manager脚本会去解析真实路径但如果软链被其他模块变更后面就会出问题。3.2 补齐基础系统依赖Cloudera Manager安装过程中需要用到python、perl、rpm、yum等基础工具CentOS 7最小安装通常够用但有些依赖包不会带上。建议执行一次yum -y install net-tools vim wget curl lsof psmisc openssh-clients ntp其中openssh-clients是必须的因为Agent分发和部分巡检脚本要通过ssh执行。ntp是下一步配置时间同步要用的提前安装能省事。有些环境还会缺libaio如果后续要装MySQL数据库作为元数据库这个库是不可少的。可以通过yum install libaio -y提前准备好。4. 时间同步服务配置4.1 NTP服务架构与选型Hadoop集群对时间同步要求极高。如果节点间时间偏差超过几十秒HDFS写入就会报错Kerberos认证也会出现问题。我见过最坑的情况是只有一个节点时间不对导致NameNode安全模式一直无法退出。规划上小型集群可以让所有节点向同一个NTP服务器同步该服务器可以是公司内网已有的NTP服务也可以指定其中一台节点作为NTP server。如果完全无外网就需要手动在master节点上配置一个本地NTP时间源。4.2 NTP服务端配置假设以cdh-master为NTP server先编辑/etc/ntp.confrestrict default nomodify notrap nopeer noquery restrict 192.168.10.0 mask 255.255.255.0 nomodify notrap server 127.127.1.0 fudge 127.127.1.0 stratum 10这里的192.168.10.0替换成你所在集群的内网网段。restrict配置允许同一网段内的节点查询时间。然后启动服务systemctl restart ntpd systemctl enable ntpd4.3 NTP客户端配置其他节点在/etc/ntp.conf中配置一个内网server地址server cdh-master prefer添加后执行ntpdate cdh-master systemctl restart ntpd ntpq -pntpq -p的输出中如果出现时间源列表说明同步正常。排错时常用ntpstat如果显示synchronised to NTP server就说明已经完成同步。实用建议在正式安装Cloudera Manager之前先在所有节点执行一遍ntpdate -u cdh-master手动同步然后启动ntpd可以避免集群初始化时因时间差过大而拒绝连接。5. SSH免密登录与网络环境核查5.1 配置集群互信Cloudera Manager安装时虽然不需要你手动做全部节点的SSH免密但在后续调试和巡检时如果你要登录每个节点执行命令免密必不可少。另外某些安装脚本会试图通过SSH下发命令提前配好互信能让很多操作自动化。在cdh-master上生成密钥ssh-keygen -t rsa -b 2048 -N -f ~/.ssh/id_rsa然后把公钥拷贝到所有节点ssh-copy-id rootcdh-node01 ssh-copy-id rootcdh-node02测试一条命令ssh cdh-node01 date这里有一个小问题如果你使用的是root用户CentOS 7默认/etc/ssh/sshd_config是允许root登录的。如果你改为专用用户部署则需要确保该用户有sudo权限并且Cloudera Manager的安装账号具备免密权限。5.2 网络端口连通性Cloudera Manager Server默认端口是7180Agent与Server通信的端口是9000。除此之外HDFS NameNode使用8020或9820DataNode使用50010、50020YARN ResourceManager使用8088、8030。这些端口必须在整个集群范围内互通。快速测试端口连通性nc -vz cdh-master 7180 nc -vz cdh-node01 9000另外非常容易被忽略的是主机名解析顺序。检查/etc/nsswitch.conf确认hosts一行优先使用files而不是dns。这样即使内网DNS暂时出问题也不会影响集群节点间的主机名解析。6. Cloudera Manager安装包与Parcel包准备6.1 下载清单与版本匹配Cloudera Manager 5.14.0和CDH 5.14.0必须严格匹配。下载的时候注意看清操作系统是el7不要下成el6。完整需要准备的文件有Cloudera Manager的RPM包5.14.0对应的daemons、server、agent等CDH版本对应的Parcel文件manifest.json清单文件MySQL JDBC驱动包后续配置元数据库时会用到如果你有内网yum源可以把Cloudera Manager的RPM包托管到内网在每台节点上配置一个本地repo文件。如果没有可以手动把rpm包放到一个目录再用yum localinstall安装。6.2 制作Cloudera Manager本地Yum源先把所有Cloudera Manager相关的RPM包放到/repo/cm目录mkdir -p /repo/cm cp cloudera-manager-daemons*.rpm /repo/cm/ cp cloudera-manager-server*.rpm /repo/cm/ cp cloudera-manager-agent*.rpm /repo/cm/安装createrepo并生成元数据yum install -y createrepo createrepo /repo/cm然后创建repo文件/etc/yum.repos.d/cloudera-manager.repo[cloudera-manager] namecloudera-manager baseurlfile:///repo/cm enabled1 gpgcheck0之后在所有节点上都可以直接yum install cloudera-manager-daemons cloudera-manager-agent为什么不直接rpm -ivh因为rpm安装时如果缺少依赖需要手动找包特别麻烦。yum可以自动处理依赖这才是环境准备阶段正确该做的事。6.3 Parcel包放置与校验CDH的Parcel文件名类似CDH-5.14.0-1.cdh5.14.0.p0.3-el7.parcel。注意后缀是el7如果下载成trusty或el6Cloudera Manager在识别操作系统时就会报错。Parcel文件需要放到Cloudera Manager Server的/opt/cloudera/parcel-repo目录下同时把manifest.json也放进去。mkdir -p /opt/cloudera/parcel-repo cp CDH-5.14.0-1.cdh5.14.0.p0.3-el7.parcel /opt/cloudera/parcel-repo/ cp manifest.json /opt/cloudera/parcel-repo/ chown -R cloudera-scm:cloudera-scm /opt/cloudera/parcel-repo然后校验文件的SHA-256值是否和manifest.json中记录的一致sha256sum /opt/cloudera/parcel-repo/CDH-5.14.0-1.cdh5.14.0.p0.3-el7.parcel如果不一致安装时Cloudera Manager会直接提示校验失败这时候不需要重新下载先检查你是不是把文件放在中文路径下或者传输工具是不是开了文本模式把文件改坏了。注意Parcel文件不要解压不要重命名不要改目录属主。如果后面在Cloudera Manager的“主机”页面看不到Parcel多半就是属主或者路径不对。6.4 数据库MySQL与JDBC驱动准备CDH的Cloudera Manager和Hive等服务都需要元数据库推荐使用MySQL 5.7。环境准备阶段需要把MySQL安装好创建好后续要用的库和账号。我这里只提一下MySQL的安装思路因为具体细节会放在系列后文展开。先安装MySQL的源或直接下载对应RPM包yum localinstall -y mysql57-community-release-el7.rpm yum install -y mysql-community-server systemctl start mysqld然后将MySQL JDBC驱动拷贝到Cloudera Manager Server和Agent对应的目录。这个驱动包文件名通常为mysql-connector-java-5.1.47.jar一定要放到/usr/share/java/目录并改名成mysql-connector-java.jar否则Cloudera Manager的脚本找不到驱动。mkdir -p /usr/share/java cp mysql-connector-java-5.1.47.jar /usr/share/java/mysql-connector-java.jar chmod 644 /usr/share/java/mysql-connector-java.jar7. 常见问题与避坑指南7.1 报错“Java not found”或“Unsupported Java version”多半是JAVA_HOME没配好或者用的是OpenJDK。先检查which java是不是指向了/opt/jdk8/bin/java再确认echo $JAVA_HOME是否有值。不要忘记在/etc/profile配置后重新登录Shell。如果确实要使用OpenJDK请选择与Cloudera官方文档匹配的版本不要随便用最新的OpenJDK 1.8。7.2 时间不同步导致NodeManager注册失败现象是Cloudera Manager页面上能显示主机但启动NodeManager时一直注册失败。排查时先看/var/log/hadoop-yarn/yarn-yarn-nodemanager-*.log里面大概率有类似KeeperErrorCode ConnectionLoss或者时钟偏大的报错。解决办法就是回到第4节重新做一次所有节点的时间同步。7.3 主机内存过低导致Agent服务长期无法启动Cloudera Manager Agent虽然本身占用内存不大但装完CDH后NameNode和ResourceManager都会在同一台物理机上如果物理机内存低于8GB就会出现大量OOM。这只是环境准备阶段需要明白的底线别拿1GB的小虚拟机硬撑。7.4 防火墙不是完全关闭导致的端口不可达很多系统在安装的时候自定义开启了某些端口但是Cloudera Manager动态使用的一部分端口可能会被防火墙拦截。使用firewall-cmd手动放行端口也可以但我还是那句话内网集群关掉防火墙是最省心的。如果公司安全制度不允许关闭必须保留防火墙至少要把常用端口列表整理出来并确保Agent与Server之间的9000端口绝对放行。7.5 Parcel无法分发到AgentParcel文件放到Server后Cloudera Manager会要求把Parcel分发到所有Agent节点这依赖网络带宽和磁盘空间。如果分发过程中一直失败检查Agent节点上/opt/cloudera/parcels目录是否有空间并且Server上的/opt/cloudera/parcel-repo目录是否设置了正确的属主。权限错了就一定会失败。8. 环境验收清单环境准备做到位之后我会习惯用一套简单的检查清单确认所有项目都通过。分享给大家检查项验证命令通过标准防火墙systemctl status firewalldinactive (dead)SELinuxgetenforceDisabledHosts解析ping cdh-node01能ping通且显示正确IPSSH免密ssh cdh-node01 date输出节点当前时间时间同步ntpq -p存在时间源且偏移不大磁盘空间df -h / /data两者剩余空间充足JDK版本java -version输出1.8.0_202文件描述符ulimit -n输出65535Parcel校验sha256sum ...与manifest一致跑完这一遍清单基本就能保证后续Cloudera Manager的安装不踩环境的雷。我在实际操作中的体会是环境准备阶段多花一个小时后面安装和调优的时候能省出好几个小时的排查时间。尤其是Parcel校验和NTP这两项卡住过太多人。下一篇文章里我会继续写Cloudera Manager Server和Agent的安装步骤到时候直接基于这套环境去做就行。