在Docker中使用Dockerfile实现ISO文件转化为完整版Centos镜像,并搭建集群数据仓库
在上一篇文章中,我们提到了如何使用Docker官方版本的centos7搭建容器集群并实现同一ip下使用不同端口的ssh远程登录,但是其中遇到了非常多的问题,例如:
官方的centos7过于“简陋”,导致我们运行脚本时因为没有预装依赖包而报错!
这个可太致命了,所以这篇文章教大家如何使用Centos官方ISO文件搭建docker究极完整版镜像,并实现数据仓库搭建
注意了,如果你想在虚拟机上运行docker,本教程仅适合服务器版本的的Ubuntu(点这里下载服务器版本镜像,点击这里查看安装教程)或者是Centos,因为默认桌面版本的Linux系统没有默认启动systemd服务,会导致docker容器内运行centos时无法启动systemctl命令!
1. 创建docker镜像
这里我们使用Dockerfile文件实现镜像的一键创建,并在镜像中预装可能用到的依赖库,让我们的centos达到“基本能用”的程度:
Dcokerfile文件如下,注意这里会用到Cenos官方的ISO文件(点击下载,或者你往下面看)
FROM centos:7.2.1511
COPY CentOS-7-x86_64-DVD-1511.iso /tmp/CentOS-7-x86_64-DVD-1511.iso
RUN yum -y update && \
yum -y install wget && \
yum -y install tar && \
yum -y install bzip2 && \
yum -y install unzip && \
yum -y install net-tools && \
yum -y install tcpdump && \
yum -y install telnet && \
yum -y install vim && \
yum -y install git && \
yum -y install openssh-server && \
yum -y install java-1.8.0-openjdk && \
yum -y install perl && \
yum -y install python && \
yum -y install ruby && \
yum -y install php && \
yum -y install gcc && \
yum -y install make && \
yum -y install autoconf && \
yum -y install automake && \
yum -y install libtool && \
yum -y install libxml2-devel && \
yum -y install libpng-devel && \
yum -y install libjpeg-devel && \
yum -y install freetype-devel && \
yum -y install openssl-devel && \
yum -y install libcurl-devel && \
yum -y install libxslt-devel && \
yum -y install bzip2-devel && \
yum -y install readline-devel && \
yum -y install sqlite-devel && \
yum -y install postgresql-devel && \
yum -y install mariadb-server && \
yum -y install httpd && \
yum -y install vsftpd && \
yum -y install epel-release && \
yum -y install supervisor && \
yum -y install libselinux-utils && \
yum -y install firewalld && \
yum -y install lrzsz && \
yum -y install NetworkManager &&\
yum -y clean all
RUN mkdir -p /var/run/sshd && \
echo 'root:password' | chpasswd && \
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config && \
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config && \
sed -i 's/^#\?UseDNS.*/UseDNS no/' /etc/ssh/sshd_config && \
sed -i 's/^#\?Storage=.*/Storage=persistent/' /etc/systemd/journald.conf && \
systemctl enable mariadb.service && \
systemctl enable httpd.service && \
systemctl enable vsftpd.service && \
systemctl enable sshd.service
EXPOSE 22 80 3306 20 21
CMD ["/usr/sbin/init"]
注意,这里增加了一行
sed -i 's/^#\?Storage=.*/Storage=persistent/' /etc/systemd/journald.conf && \
,用于设置systemd journald的持久化存储。同时,启用了
systemctl enable mariadb.service、
systemctl enable httpd.service、
systemctl enable vsftpd.service
systemctl enable sshd.service
使得容器启动后这些服务会自动启动,这些都是一些网络基础服务。
同时我们的ssh可以自动启动完成,不需要我们额外去配置了
Dockerfile编写完成后我们在文件当前目录下启动如下命令(注意对应ISO文件也应该在当前目录下)
docker build -t mycentos:7.2-iso .# mycentos:7.2-iso可以换成自己的dockerhub上的名称/镜像名称,规范命名才可以上传到仓库里
创建完成之后然后你可以使用如下命令进行查看
dockerps -a
如果你不想写文件,也不想下载ISO,可以到我的docker公开仓库上pull一个已经搭建好了的镜像
docker pull kibety/centos:7.2-iso
#或者mini版本的docker pull kibety/centos:7.2-iso-mini
至此,我们的镜像准备完毕,接下来我们准备搭建centos容器集群了
2. 搭建Centos容器集群
首先创建docker bridge网桥
sudodocker network create MyNetWork
创建网桥可以方便网络管理,并且让容器自动归属于同一网段下
创建三个不同端口的结点容器并加入网桥中
sudodocker run -itd --restart=always --hostname node01 --name Node01 -p 21001:8088 -p 30001:8443 -p 20001:50070 -p 10001:22 -v /data/sda/sharedata:/share --network MyNetWork --privileged=true kibety/centos:7.2-iso /sbin/init
sudodocker run -itd --restart=always --hostname node02 --name Node02 -p 21002:8088 -p 30002:8443 -p 20002:50070 -p 10002:22 -v /data/sda/sharedata:/share --network MyNetWork --privileged=true kibety/centos:7.2-iso /sbin/init
sudodocker run -itd --restart=always --hostname node03 --name Node03 -p 21003:8088 -p 30003:8443 -p 20003:50070 -p 10003:22 -v /data/sda/sharedata:/share --network MyNetWork --privileged=true kibety/centos:7.2-iso /sbin/init
# 参数解释:# -itd# 选项 选项简写 说明# –detach -d 在后台运行容器,并且打印容器id# –interactive -i 即使没有连接,也要保持标准输入保持打开状态,一般与 -t 连用# –tty -t 分配一个伪tty,一般与 -i 连用# --restart=always 机器启动时自启动# --name 容器名称# --hostname 初始化的hostname# -p 10001:22 端口映射 宿主机端口:容器端口这里为22表示容器内ssh端口# --privileged=true 通过特权模式进入docker,不仅可以使用systemctl命令(centos 7系统),还可以开启ssh服务# --network NodeNetWork 将容器结点加入网桥中# 注意:在 Linux Docker中无法使用 systemd(systemctl) 相关命令的原因是 1号进程不是 init ,而是其他例如 /bin/bash ,所以导致缺少相关文件无法运行。(System has not been booted with systemd as init system (PID 1). Can't operat#解决方案:/sbin/init并且--privilaged=true一定要加上
接下来我们进入容器,开始基础配置(开启三个终端)
sudodockerexec -it Node01 /bin/bash
sudodockerexec -it Node02 /bin/bash
sudodockerexec -it Node03 /bin/bash
每台启动passwd来初始化root用户密码(以node01为例)
passwd
查看三个centos容器中的网络配置
ifconfig
在同一个网段下,完美!
接下来我们可以windows上使用docker宿主机的ip(在宿主机中ifconfig或者ip addr查看)与三个容器的22端口映射登录容器,检查是否正常
可以看到正常登录node结点,可以使用windows的terminal或者ssh远程连接容器结点了
至此,结点搭建完毕,下面我们进入数据仓库的搭建工作
3. 数据仓库的环境搭建
在上一步中我们已经创建了3个加入同一网桥中的centos容器结点,所以我们不需要再去修改其ip地址了,这也是docker的优势之一
下面是我们要搭建的集群软件规划,这里采用的教程是b站上的up:哈喽鹏程(在虚拟机上搭建的,讲的非常不错,大家可以去听听)
3.1 自动化脚本准备
首先在Node01上准备自动化脚本
由于脚本只能在hadoop上运行,所以我们先提前在home目录下创建hadoop文件夹,将脚本clone至目录下
[root@node01 ~]# mkdir /home/hadoop/[root@node01 hadoop]# git clone https://github.com/MTlpc/automaticDeploy.git
额…clone失败了,这多半是DNS没有配置正确导致的,没关系,一行代码解决问题(其他结点也运行一下这个代码,以除后患…)
echo"nameserver 8.8.8.8"> /etc/resolv.conf
再次clone,成功!
接着我们使用vim修改hadoop/automaticDeploy/文件夹下的host_ip.txt配置文件。
# vim修改脚本的host_ip配置文件[root@node01 automaticDeploy]# ls
configs.txt frames.txt hadoop host_ip.txt logs.sh README.md systems
[root@node01 automaticDeploy]# vim host_ip.txt
例如我这里的配置(ip可以ifconfig查看各个容器结点的ip,hostname和密码都可以自定义)
172.18.0.2 node01 root HUTB2001
172.18.0.3 node02 root HUTB2001
172.18.0.4 node03 root HUTB2001
给automaticDeploy脚本下的两个目录赋权
[root@node01 automaticDeploy]# chmod +x /home/hadoop/automaticDeploy/hadoop/* /home/hadoop/automaticDeploy//systems/*
安装上传组件(我们的dockerfile中已经安装好了可以不用安装),并将frimes.zip(脚本)安装包使用xshell软件通过rz命令上传
[root@node01 automaticDeploy]# yum install lrzsz -y# 到home目录下rz命令上传安装包,为了xshell防止乱码,建议加入 -be参数[root@node01 home]# rz -be# 在home目录下将frimes.zip脚本解压到我们的automaticDeploy目录下[root@node01 home]# unzip frames.zip -d /home/hadoop/automaticDeploy/
解压完成后我们在其他两个结点也创建/home/hadoop目录,并将node01上的目录通过scp分享至其余结点
# 通过ssh创建node02、node03的目录[root@node01 hadoop]# ssh [email protected] "mkdir /home/hadoop"[root@node01 hadoop]# ssh [email protected] "mkdir /home/hadoop"# 将脚本文件分享给node02、node03[root@node01 hadoop]# scp -r /home/hadoop/automaticDeploy/ [email protected]:/home/hadoop/[root@node01 hadoop]# scp -r /home/hadoop/automaticDeploy/ [email protected]:/home/hadoop/# 如果出现报错bash: scp: command not found,那就yum install openssh-clients安装这个命令,注意node02和03上也要安装此命令
至此,结点脚本准备完毕,接下来运行脚本自动安装程序
3.2 运行脚本
分享完成后,在每个结点的automaticDeploy/system目录下都要启动batchOperate.sh脚本文件
./batchOperate.sh
这个脚本主要是配置免密钥登录、更新yum源、安装jdk、配置host等环境操作
启动脚本完成后再验证一下配置是否成功
# 首先查看是否可以在结点之间免密登录,以node01到node02为例,如果不行那就ssh-copy-id解决问题[root@node01 ~]# ssh node02
Last login: Fri Mar 24 07:57:14 2023 from 172.21.102.10
[root@node02 ~]# exitlogout
测试完成没问题后,每个结点分别进入automaticDeploy/hadoop目录下安装hadoop集群,然后source一下
./installHadoop.sh
source /etc/profile
在Node01节点(主节点)上初始化namenode、启动hadoop集群、查看运行状态
[root@node01 hadoop]# hadoop namenode -format[root@node01 hadoop]# start-all.sh[root@node01 hadoop]# jps# 从节点ndoe02、node03上也看一下
嗯。。。该有的都有了
至此hadoop安装成功,可以在浏览器中使用宿主机ip:20001查看映射到node01上50070端口的hadoop网页端(例如我这里访问地址是:172.21.198.185:20001)
小提示:hadoop的浏览器端口是50070,如果要使用外网访问docker容器中的hadoop,就要在创建容器时添加端口映射至容器内的50070端口,这和ssh映射至22端口是一个道理
安装完成hadoop之后我们首先安装node02的mysql,因为node03上的hive和tez需要依赖mysql
[root@node02]/home/hadoop/automaticDeploy/hadoop# ./installMysql.sh
在运行时会出现卡住的情况。。。。一排查发现(排了两小时。。。):**./installMysql.sh**中下面这条命令卡住了 :
systemctl start mysqld.service
问了一下chatGPT:
好吧,似乎这条命令占用了shell,导致文件下面的命令无法执行,我们自己运行这条命令,然后在./installMysql.sh文件中注释掉这条命令
# 无意间看到sh文件中有sudo命令,虽然我们是root用户,但是没有安装sudo命令,所以先安装一下(三个最好都安装,怕报错555)
yum installsudo# 然后再node02上更新一下mysql(有些东西太古老了)
mysql_upgrade
# 最后,我们再node02上重新运行这个脚本[root@node02]/home/hadoop/automaticDeploy/hadoop# ./installMysql.sh
有冒红(血压上来了…),乍一看没关系,因为我们运行过这个脚本,所以mysql的3306端口被占用了很正常,还是有点害怕,先上mysql看一下databases正不正常
# 密码是DBa2020*[root@node02 hadoop]# mysql -uroot -p# 在mysql中
show database;
一切正常(松了口气。。。。)
node02搞定之后,我们在node03的automaticDeploy/hadoop目录下启动脚本安装hive和tez
# 脚本会自动识别是否可以装其他的库,这里自动把tez和hive一起装了[root@node03 hadoop]# ./installHive.sh
然后会发现有报错,但是都是info信息,ip指向了我们的node02结点,按照b站上作者哈喽鹏程大佬的说法,应该是node02结点的网络或者配置有问题,我们先不管,重启一下node02的网络配置
root@node02 ~]# systemctl restart NetworkManager.service
重启完成后我们继续在ndoe03上安装sqoop,然后source一下
[root@node03 hadoop]# ./installSqoop.sh [root@node03 hadoop]# source /etc/profile
接着我们在三个结点上安装presto、azkaban
[root@node01 hadoop]# ./installPresto.sh[root@node02 hadoop]# ./installPresto.sh[root@node03 hadoop]# ./installPresto.sh
没问题,但是在安装azkaban的时候出现了错误
[root@node01 hadoop]# ./installAzkaban.sh[root@node02 hadoop]# ./installAzkaban.sh[root@node03 hadoop]# ./installAzkaban.sh
网上查了一下发现在执行installAzkaban.sh过程中,无法生成keystore,检查后发现哈喽鹏程大佬的实验环境为中文,而我们使用的是centos7的英文版本,造成无法自动应答密码,地区等信息,从而导致无法拷贝keystore等问题,这里参考了这篇博主的文章来设置中文字符集:
在每个结点下以此执行下面命令修改为中文字符集:
# 安装中文字符集包和环境
yum install -y kde-l10n-Chinese
yum reinstall -y glibc-common
localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8
# 修改字符集配置echo'LANG="zh_CN.UTF-8"'> /etc/locale.conf &&source /etc/locale.conf
echo"export LC_ALL=zh_CN.UTF-8">> /etc/profile &&source /etc/profile
# 最后验证配置是否生效[root@node01 hadoop]# echo $LANG
zh_CN.UTF-8
每个结点的中文字符配置成功后,我们继续完成每个结点的azkaban的安装
可以看到没有问题了!
那么接下来我们在node03安装一个presto的web可视化插件
[root@node03 hadoop]# ./installYanagishima.sh
轻松搞定
到最后我们在每个结点上source一下
source /etc/profile
至此,所有环境搭建完毕,下一篇博客我会带着大家实现一些docker上centos集群数据仓库的实战。大家如果觉得这篇文章有帮助可以多多点赞支持一下。
该版本下其他常用命令
# 重启网络服务
systemctl restart NetworkManager.service
写在最后:
搭建这个docker环境耗费了很多时间才肝出来,其中遇到的bug不计其数,很多次都想要放弃,但是每次看着一个个错误被解决的时候,这种激动的心情支撑着我一步一步继续往下走。所以我也希望大家在遇到很多问题的时候也要尝试着自己找各种方式解决一下,打不败我们的只会让我们更加强大。也许这就是程序员喜欢折腾的乐趣所在。。。。。。
版权归原作者 kibety 所有, 如有侵权,请联系我们删除。