在Docker中使用Dockerfile实现ISO文件转化为完整版Centos镜像,并搭建集群数据仓库

Posted kibety

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Docker中使用Dockerfile实现ISO文件转化为完整版Centos镜像,并搭建集群数据仓库相关的知识,希望对你有一定的参考价值。

在Docker中使用Dockerfile实现ISO文件转化为完整版Centos镜像,并搭建集群数据仓库


在上一篇文章中,我们提到了如何使用Docker官方版本的centos7搭建容器集群并实现同一ip下使用不同端口的ssh远程登录,但是其中遇到了非常多的问题,例如:

官方的centos7过于“简陋”,导致我们运行脚本时因为没有预装依赖包而报错!

这个可太致命了,所以这篇文章教大家如何使用Centos官方ISO文件搭建docker究极完整版镜像,并实现数据仓库搭建

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上的名称/镜像名称,规范命名才可以上传到仓库里
创建完成之后然后你可以使用如下命令进行查看
docker ps -a
如果你不想写文件,也不想下载ISO,可以到我的docker公开仓库上pull一个已经搭建好了的镜像
docker pull kibety/centos:7.2-iso
至此,我们的镜像准备完毕,接下来我们准备搭建centos容器集群了

2. 搭建Centos容器集群

首先创建docker bridge网桥
sudo docker network create NodeNetWork

创建网桥可以方便网络管理,并且让容器自动归属于同一网段下

创建三个不同端口的结点容器并加入网桥中
sudo docker run -itd --restart=always  --hostname node01 --name Node01 -p 30001:8443 -p 40001:50070 -p 50001:22 -v /data/sda/sharedata:/share --network NodeNetWork --privileged=true kibety/centos:7.2-iso /sbin/init

sudo docker run -itd --restart=always  --hostname node02 --name Node02 -p 30002:8443 -p 40002:50070 -p 50002:22 -v /data/sda/sharedata:/share --network NodeNetWork --privileged=true kibety/centos:7.2-iso /sbin/init

sudo docker run -itd --restart=always  --hostname node03 --name Node03 -p 30003:8443 -p 40003:50070 -p 50003:22 -v /data/sda/sharedata:/share --network NodeNetWork --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 50001: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一定要加上
接下来我们进入容器,开始基础配置(开启三个终端)
sudo docker exec -it Node01 /bin/bash

sudo docker exec -it Node02 /bin/bash

sudo docker exec -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 root@172.18.0.3 "mkdir /home/hadoop"
[root@node01 hadoop]# ssh root@172.18.0.4 "mkdir /home/hadoop"

# 将脚本文件分享给node02、node03
[root@node01 hadoop]# scp -r /home/hadoop/automaticDeploy/ root@172.18.0.3:/home/hadoop/
[root@node01 hadoop]# scp -r /home/hadoop/automaticDeploy/ root@172.18.0.4:/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 ~]# exit
logout
测试完成没问题后,每个结点分别进入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:40001查看映射到node01上50070端口的hadoop网页端(例如我这里访问地址是:172.21.198.185:40001)

小提示: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 install sudo 

# 然后再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不计其数,很多次都想要放弃,但是每次看着一个个错误被解决的时候,这种激动的心情支撑着我一步一步继续往下走。所以我也希望大家在遇到很多问题的时候也要尝试着自己找各种方式解决一下,打不败我们的只会让我们更加强大。也许这就是程序员喜欢折腾的乐趣所在。。。。。。

黑马三Docker镜像制作 & Dockerfile

一、Docker镜像原理

思考:

  • Docker 镜像本质是什么?
    是一个分层文件系统
  • Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个G?
    centos的iso镜像文件包含bootfs和rootfs,而docker的centos镜像复用操作系统的bootfs,只有rootfs和其他镜像层。
  • Docker 中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB?
    由于docker中镜像是分层的,tomcat虽然只有70多MB,但他需要依赖于父镜像和基础镜像,所以整个对外暴露的tomcat镜像大小500多MB。

1.1、操作系统组成部分

进程调度子系统、进程通信子系统、内存管理子系统、设备管理子系统、文件管理子系统、网络通信子系统、作业控制子系统
Linux文件系统由bootfs和rootfs两部分组成

  • bootfs:包含 bootloader(引导加载程序)和 kernel(内核)
  • rootfs:root文件系统,包含的就是典型Linux系统中的/dev/proc/bin/etc等标准目录和文件
  • 不同的Linux发行版,bootfs基本一样,而rootfs不同,如ubuntu、centos等
  • Docker镜像是由特殊的文件系统叠加而成
  • 最底端是 bootfs,并使用宿主机的bootfs
  • 第二层是 root文件系统rootfs,称为base image
  • 然后再往上可以叠加其他的镜像文件
  • 统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。
  • 一个镜像可以放在另一个镜像的上面。位于下面的镜像称为父镜像,最底部的镜像成为基础镜像。
  • 当从一个镜像启动容器时,Docker会在最顶层加载一个读写文件系统作为容器

二、镜像制作

Docker镜像如何制作?

  1. 容器转为镜像
    docker commit 容器id 镜像名称:版本号

    docker save -o 压缩文件名称 镜像名称:版本号

    docker load -i 压缩文件名称

三、Dockerfile

3.1、概念

  • Dockerfile 是一个文本文件
  • 包含了一条条的指令
  • 每一条指令构建一层,基于基础镜像,最终构建出一个新的镜像
  • 对于开发人员:可以为开发团队提供一个完全一致的开发环境
  • 对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfile文件,构建一个新的镜像开始工作了
  • 对于运维人员:在部署时,可以实现应用的无缝移植

Dochub网址:https://hub.docker.com

关键字作用备注
FROM指定父镜像指定dockerfile基于那个image构建
MAINTAINER作者信息用来标明这个dockerfile谁写的
LABEL标签用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看
RUN执行命令执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN [“command” , “param1”,“param2”]
CMD容器启动命令提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD [“command” , “param1”,“param2”]
ENTRYPOINT入口一般在制作一些执行就关闭的容器中会使用
COPY复制文件build的时候复制文件到image中
ADD添加文件build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务
ENV环境变量指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value
ARG构建参数构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数
VOLUME定义外部可以挂载的数据卷指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME [“目录”]
EXPOSE暴露端口定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp
WORKDIR工作目录指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径
USER指定执行用户指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户
HEALTHCHECK健康检查指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制
ONBUILD触发器当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大
STOPSIGNAL发送信号量到宿主机该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。
SHELL指定执行脚本的shell指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell

3.2、案例:自定义centos7镜像

要求:

  1. 默认登录路径为 /usr
  2. 可以使用vim

实现步骤

  1. 定义父镜像:FROM centos:7
  2. 定义作者信息:MAINTAINER bitaotaobitaotao@163.com
  3. 执行安装vim命令: RUN yum install -y vim
  4. 定义默认的工作目录:WORKDIR /usr
  5. 定义容器启动执行的命令:CMD /bin/bash
  6. 通过dockerfile构建镜像:docker bulid –f dockerfile文件路径 –t 镜像名称:版本

3.3、案例:定义dockerfile、发布spring boot项目

实现步骤:

  1. 定义父镜像:FROM java:8
  2. 定义作者信息:MAINTAINER bitaotao bitaotao@163.com
  3. 将jar包添加到容器: ADD springboot.jar app.jar
  4. 定义容器启动执行的命令:CMD java –jar app.jar
  5. 通过dockerfile构建镜像:docker bulid –f dockerfile文件路径 –t 镜像名称:版本

以上是关于在Docker中使用Dockerfile实现ISO文件转化为完整版Centos镜像,并搭建集群数据仓库的主要内容,如果未能解决你的问题,请参考以下文章

黑马三Docker镜像制作 & Dockerfile

docker--学习笔记最后附dockerfile--nginx实例

dockerfile的作用

docker如何制作自己的镜像

三天入门 Docker - 第二天:Dockerfile 基本介绍与使用

Docker的安装和使用及dockerfile简单使用