Docker 支持 64 位版本 CentOS 7,并且要求内核版本不低于 3.10
1. 前提操作
查看内核版本号:
uname -r
如果有旧版本可以使用如下命令卸载:
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2.使用yum安装
更新yum源:
sudo yum update
安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
设置yum源:
yum-config-manager --add-repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
可以查看所有仓库中所有docker版本,并选择特定版本安装:
yum list docker-ce --showduplicates | sort -r
3.安装docker
sudo yum install docker-ce
#由于repo中默认只开启stable仓库,故这里安装的是最新稳定版17.12.0
启动docker:
systemctl start docker
通过运行 hello-world 映像来验证是否正确安装了 Docker Engine-Community:
docker run hello-world
4.docker使用
其他命令:
启动:
docker start (name)
停止:
docker stop (name)
删除:
docker rm (name)
使用:
docker run ubuntu /bin/echo "hello world"
验证结果:
dockerDocker 的二进制执行文件
run: 运行一个容器。
ubuntu 指定要运行的镜像,Docker 首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像
/bin/echo "Hello world":
/bin/echo “Hello world”: 在启动的容器里执行的命令
docker run -i -t ubuntu /bin/bash
-t: 在新容器内指定一个伪终端或终端。
-i: 允许你对容器内的标准输入 (STDIN) 进行交互
常用操作
运行 exit 命令或者使用 CTRL+D 来退出容器
通过 docker ps 来查看运行的容器
CONTAINER ID: 容器 ID。
IMAGE: 使用的镜像。
COMMAND: 启动容器时运行的命令。
CREATED: 容器的创建时间。
STATUS: 容器状态。
状态有7种:
- created(已创建)
- restarting(重启中)
- running 或 Up(运行中)
- removing(迁移中)
- paused(暂停)
- exited(停止)
- dead(死亡)
PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
NAMES: 自动分配的容器名称。
删除所有容器:
docker rm -f $(docker ps -aq)
后台运行容器
docker run -itd --name ubuntu-test ubuntu /bin/bash
加了 -d 参数默认不会进入容器
进入容器
docker attach 1b6ded0882e6
推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止。
docker exec -it 1b6ded0882e6 /bin/bash
使用 docker stop命令来停止容器
docker stop 1b6ded0882e6
启动所有容器
docker start $(docker ps -a | awk '{ print $1}' | tail -n +2)
关闭所有容器
docker stop $(docker ps -a | awk '{ print $1}' | tail -n +2)
删除所有容器
docker rm $(docker ps -a | awk '{ print $1}' | tail -n +2)
删除所有镜像(慎用)
docker rmi $(docker images | awk '{print $3}' |tail -n +2)
5.镜像操作
列出本地主机上的镜像
docker images
-
REPOSITORY:表示镜像的仓库源
-
TAG:镜像的标签
-
IMAGE ID:镜像ID
-
CREATED:镜像创建时间
-
SIZE:镜像大小
获取一个新的镜像
docker pull ubuntu:13.10
查找镜像(模糊查询)
docker search hadoop
6.容器连接
网络端口映射
docker run -d -p 5000:5000 training/webapp python app.py
- -P :是容器内部端口随机映射到主机的高端口。
- -p : 是容器内部端口绑定到指定的主机端口。
制定容器绑定网络地址
指定容器绑定的网络地址
docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
可以通过访问 127.0.0.1:5001 来访问容器的 5000 端口
容器命名
docker run -d -P --name runoob training/webapp python app.py
新建网络
docker network create -d bridge test-net
连接容器
新建一个容器命名为test1,镜像为ubuntu,并连接到网络test-net
docker run -itd --name test1 --network test-net ubuntu /bin/bash
再新建一个容器命名为test2,镜像为ubuntu,并连接到网络test-net
docker run -itd --name test2 --network test-net ubuntu /bin/bash
进入容器test1
docker exec -it test1 /bin/bash
若能ping通则网络无问题
若无ping,则可以安装
apt-get update
apt install iputils-ping
配置DNS
在宿主机的 /etc/docker/daemon.json 文件中增加以下内容来设置全部容器的 DNS:
{ "dns" : [ "114.114.114.114", "8.8.8.8" ] }
设置后,启动容器的 DNS 会自动配置为 114.114.114.114 和 8.8.8.8。
配置完,需要重启 docker 才能生效。
查看容器的 DNS 是否生效可以使用以下命令,它会输出容器的 DNS 信息:
docker run -it --rm ubuntu cat etc/resolv.conf
7.dockerfile
什么是dockerfile
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了构建镜像所需的指令和说明。
FROM 和 RUN 指令
FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
RUN:用于执行后面跟着的命令行命令。
RUN命令格式
普通shell 格式,终端的普通命令
exec格式,RUN [“可执行文件”, “参数1”, “参数2”]
例:RUN ["./test.php", “dev”, “offline”] 等价于 RUN ./test.php dev offline
构建镜像
再dockerfile存放目录下执行构建动作
1、在当前目录下新建名为dockerfile的文件
FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html
2、执行命令构建镜像
docker build -t nginx:v3 .
其中的.为上下文路径,
上下文路径
是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。
如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。
注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。
8.docker文件指令详解
COPY
复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
COPY [--chown=<user>:<group>] <源路径1>... <目标路径>
[–chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。
源路径可以为通配符格式
目标路径无需创建好,如无目标路径则自行创建
COPY hom* /mydir/
COPY hom?.txt /mydir/
ADD
ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:
1.ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
2.ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
CMD
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
1.CMD 在docker run 时运行。
2.RUN 是在 docker build。
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
ENV
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
实例:
ENV NODE_VERSION 7.2.0
ARG
构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
9.docker compose安装
什么是docker compose
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
YAML
本节参考:https://www.runoob.com/w3cnote/yaml-intro.html
基本语法
1.大小写敏感
2.使用缩进表示层级关系
3.缩进不允许使用tab,只允许空格
4.缩进的空格数不重要,只要相同层级的元素左对齐即可
5.’#'表示注释
数据类型
YAML 支持以下几种数据类型:
1.对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
2.数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
3.纯量(scalars):单个的、不可再分的值
YAML 对象
对象键值对使用冒号结构表示 key: value,冒号后面要加一个空格。
也可以使用 key:{key1: value1, key2: value2, …}。
还可以使用缩进表示层级关系;
key: child-key: value
child-key2: value2
YAML 数组
以 - 开头的行表示构成一个数组:
- A
- B
- C
YAML 支持多维数组,可以使用行内表示:
key: [value1, value2, …]
数据结构的子成员是一个数组,则可以在该项下面缩进一个空格。
-
- A
- B
- C
例子
companies:
-
id:1
name: company1
price: 200W
-
id:2
name: company2
price: 500W
意思是 companies 属性是一个数组,每一个数组元素又是由 id、name、price 三个属性构成。
数组也可以使用流式(flow)的方式表示:
companies: [{id: 1,name: company1,price: 200W},{id: 2,name: company2,price: 500W}]
纯量
纯量是最基本的,不可再分的值,包括:
1.字符串
2.布尔值
3.整数
4.浮点数
5.Null
6.时间
7.日期
实例:
boolean:
- TRUE #true,True都可以
- FALSE #false,False都可以
float:
- 3.14
- 6.8523015e+5 #可以使用科学计数法
int:
- 123
- 0b1010_0111_0100_1010_1110 #二进制表示
null:
nodeName: 'node'
parent: ~ #使用~表示null
string:
- 哈哈
- 'Hello world' #可以使用双引号或者单引号包裹特殊字符
- newline
newline2 #字符串可以拆成多行,每一行会被转化成一个空格
date:
- 2018-02-17 #日期必须使用ISO 8601格式,即yyyy-MM-dd
datetime:
- 2018-02-17T15:02:31+08:00 #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区
引用
& 锚点和 * 别名,可以用来引用:
defaults: &defaults
adapter: postgres
host: localhost
development:
database: myapp_development
<<: *defaults
test:
database: myapp_test
<<: *defaults
相当于
defaults:
adapter: postgres
host: localhost
development:
database: myapp_development
adapter: postgres
host: localhost
test:
database: myapp_test
adapter: postgres
host: localhost
& 用来建立锚点(defaults),<< 表示合并到当前数据,***** 用来引用锚点。
Compose 使用的三个步骤
1.使用 Dockerfile 定义应用程序的环境。
2.使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
3.最后,执行 docker-compose up 命令来启动并运行整个应用程序。
compose安装
下载并安装
curl -L "https://get.daocloud.io/docker/compose/releases/download/1.12.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
更改权限可执行
chmod +x /usr/local/bin/docker-compose
测试安装是否成功
docker-compose -version
升级:
pip install --upgrade backports.ssl_match_hostname
10.yml 配置指令
version
指定本 yml 的写法格式(格式的版本)
services
服务列表,用数组形式展现,每个服务可为一个容器
image
指定服务所用镜像
container_name
指定容器名字,而非默认
restart
1.no:是默认的重启策略,在任何情况下都不会重启容器。
2.always:容器总是重新启动。(docker重启时)
3.on-failure:在容器非正常退出时(退出状态非0),才会重启容器。
4.unless-stopped:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
networks
配置容器连接的网络,引用顶级 networks 下的条目
实例
services:
some-service:
networks:
some-network:
aliases:
- alias1
other-network:
aliases:
- alias2
ports:
- "50070:50070"
- "9000:9000"
extra_hosts:
- "hadoop-nn:172.25.1.100"
- "hadoop-dn1:172.25.1.101"
- "hadoop-dn2:172.25.1.102"
- "hadoop-dn3:172.25.1.103"
networks:
some-network:
# Use a custom driver
driver: custom-driver-1
自定义扩展网卡
实例
networks:
extnetwork: #自定义网络名称
ipam: #ip地址管理
config: #配置信息
- subnet: 172.20.0.0/24 #网段管理
gateway: 172.20.0.1 #网关地址
ipv4_address
为服务的容器指定一个静态 IP 地址
networks:
hadoop-hdfs:
ipv4_address: 172.25.1.100
ports
映射端口
实例
ports:
- "50070:50070"
- "9000:9000"
extra_hosts
添加主机名的标签,就是往 /etc/hosts 文件中添加一些记录
extra_hosts:
- "hadoop-nn:172.25.1.100"
- "hadoop-dn1:172.25.1.101"
- "hadoop-dn2:172.25.1.102"
- "hadoop-dn3:172.25.1.103"
11.docker安装hadoop
dockerfile建立两个容器实现ssh免密登陆
构建基础环境步骤
(1)为了精简镜像,所以基础镜像采用ubuntu:14.04
(2)ubuntu:14.04中apt下载非常慢,因此将/etc/apt/sources.list中更换为阿里云源,内容如下:
deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
(3)基础镜像中未安装ssh服务,需要安装openssh-server和openssh-client服务
(4)生成免密登录秘钥,并配置为当前容器可免密登录自己(因为之后我们创建的所有的容器都是基于该镜像,因此设置了可免密登录自己即是各容器直接可免密登录,这是Docker给我们带来的一个非常方便的设计)
(5)在/ect/ssh目录下添加ssh_config文件,文件内容如下:
Host localhost
StrictHostKeyChecking no
Host 0.0.0.0
StrictHostKeyChecking no
Host hadoop-*
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
Host spark-*
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
Host zk-*
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
(6)创建ssh服务启动目录/var/run/sshd
(7)修改root用户密码为root,并将工作目录切换为/root
echo "root:root" | chpasswd
(8)指定容器启动时运行的命令为后台启动sshd服务
(9)通过docker build构建ubuntu-ssh:v1镜像
dockerfile代码:
FROM ubuntu:14.04
MAINTAINER zhang
ADD sources.list /etc/apt
RUN apt-get update && \
apt-get install openssh-server openssh-client -y
RUN mkdir -p /var/run/sshd
RUN echo 'root:root' | chpasswd
RUN mkdir /root/.ssh && ssh-keygen -q -P '' -t dsa -f /root/.ssh/id_dsa
RUN cat /root/.ssh/id_dsa.pub >> /root/.ssh/authorized_keys
ADD ssh_config /etc/ssh
EXPOSE 22
WORKDIR /root
CMD /usr/sbin/sshd -D
执行并生成镜像
docker build -t ubuntu-ssh:v1 .
验证:
制作jdk镜像
设计思路
(1)采用2.1中构建的ubuntu-ssh:v1作为基础镜像
(2)将jdk-8u231-linux-x64.tar.gz(也可采用其他版本,建议1.8JDK)复制并解压到/root/apps目录下,为了精简镜像,解压完成后需要将jdk-8u231-linux-x64.tar.gz删除。
(3)配置Java的环境变量
(4)通过docker build构jdk1.8:v1镜像
dockerfile代码:(压缩包和dockerfile在一起)
FROM ubuntu-ssh:v1
MAINTAINER zhang
RUN mkdir -p /root/apps
COPY jdk-8u231-linux-x64.tar.gz /root
RUN tar -zxvf jdk-8u231-linux-x64.tar.gz -C apps/ &&\
mv /root/apps/jdk1.8.0_231 /root/apps/java &&\
rm -f jdk-8u231-linux-x64.tar.gz
ENV JAVA_HOME=/root/apps/java
ENV PATH=$JAVA_HOME/bin:$PATH
CMD /usr/sbin/sshd -D
构建jdk8镜像:
查看镜像:
运行镜像、容器及验证java安装:
hadoop部署
hdfs集群规划
容器主机名/容器名 | 容器IP(网络名称hadoop-hdfs) | 节点进程 | 容器启动镜像 |
---|---|---|---|
hadoop-nn | 172.25.1.100 | NameNode、SecondaryNameNode | namenode:v1 |
hadoop-dn1 | 172.25.1.101 | DataNode | namenode:v1 |
hadoop-dn2 | 172.25.1.102 | DataNode | datanode:v1 |
hadoop-dn3 | 172.25.1.103 | DataNode | datanode:v1 |
yarn集群规划
容器主机名/容器名 | 容器IP(网络名称hadoop-yarn) | 节点进程 | 容器启动镜像 |
---|---|---|---|
hadoop-rn | 172.24.1.100 | ResourceManager | resourcemanager:v1 |
hadoop-nm1 | 172.24.1.101 | NodeManager | nodemanager:v1 |
hadoop-nm2 | 172.24.1.102 | NodeManager | nodemanager:v1 |
hadoop-nm3 | 172.24.1.103 | NodeManager | nodemanager:v1 |
设计思路
当容器启动时,需要启动hdfs的所有进程,因此设计为需要定义namenode和datanode两个镜像文件。因为hdfs和yarn的需要的配置文件相同,因此先自定义一个hadoop-base的基础镜像,然后再分别构建namenode、datanode、resourcemanager和nodemanager镜像。
构建hadoop-base镜像
设计思路
(1)2.2中构建的jdk1.8:v1作为基础镜像
(2)将hadoop-2.7.6.tar.gz(可采用其他版本)复制到容器的/root目录下并解压至/root/apps目录下,为了精简镜像,需要将hadoop-2.7.6.tar.gz删除。
(3)创建/root/hdfs/namenode、/root/hdfs/datanode(hdfs-site.xml指定目录)和/root/apps/hadoop/logs(启动namenode时产生的日志文件保存在该目录下)目录
(4)配置Hadoop环境变量
(5)将配置文件复制的/tmp/目录下,并在/tmp/下移动到$HADOOP_HOME/etc/hadoop/目录中
(8)通过docker-build构建hadoop-bash:v1镜像
dockerfile代码:
FROM jdk8:v1.0
MAINTAINER zhang
COPY hadoop-2.7.6.tar.gz /root
RUN tar -zxvf hadoop-2.7.6.tar.gz -C apps/ &&\
mv /root/apps/hadoop-2.7.6 /root/apps/hadoop && \
rm -f hadoop-2.7.6.tar.gz &&\
mkdir -p /root/hdfs && \
mkdir -p /root/hdfs/namenode &&\
mkdir -p /root/hdfs/datanode && \
mkdir -p /root/apps/hadoop/logs
ENV HADOOP_HOME=/root/apps/hadoop
ENV PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
COPY config /tmp/config
RUN cp -r /tmp/config/* $HADOOP_HOME/etc/hadoop/
构建镜像:
docker build -t hadoop-base:v1 .
查看镜像:
构造容器及验证:
构建namenode镜像
设计思路
(1)构建的hadoop-bash:v1作为基础镜像
(2)namenode节点需要格式化,因此运行hadoop namenode –format命令
(3)将run.sh(启动namenode和sshd的脚本)复制到/root下并添加执行权限
(3)指定数据卷/root/hdfs
(4)暴露端口50070和9000
(5)指定容器启动运行run.sh脚本
(6)通过docker-build构建namenode:v1镜像
dockerfile代码:
FROM hadoop-base:v1
MAINTAINER zhang
COPY slaves /tmp/
RUN mv /tmp/slaves $HADOOP_HOME/etc/hadoop/slaves
COPY run.sh /root/
RUN hdfs namenode -format
RUN chmod +x /root/run.sh
VOLUME /root/hdfs
EXPOSE 50070
EXPOSE 9000
CMD sh run.sh
构建镜像:
docker build -t namenode:v1 .
构建datanode镜像
设计思路
(1)构建的hadoop-bash:v1作为基础镜像
(2)将run.sh(启动datanode和sshd的脚本)复制到/root下并添加执行权限
(3)指定容器启动运行run.sh脚本
(4)通过docker-build构建datanode:v1镜像
dockerfile代码:
FROM hadoop-base:v1
COPY slaves /tmp/
RUN mv /tmp/slaves $HADOOP_HOME/etc/hadoop/slaves
COPY run.sh /root/
RUN chmod +x /root/run.sh
CMD /root/run.sh
构建镜像:
docker build -t datanode:v1 .
构建resourcemanager镜像
设计思路
(1)构建的hadoop-bash:v1作为基础镜像
(2)将run.sh(启动resourcemanager和sshd的脚本)复制到/root下并添加执行权限
(3)暴露端口8080
(4)指定容器启动运行run.sh脚本
(5)通过docker-build构建resourcemanager:v1镜像
dockerfile代码:
FROM hadoop-base:v1
COPY slaves /tmp/
RUN mv /tmp/slaves $HADOOP_HOME/etc/hadoop/slaves
COPY run.sh /root/
RUN chmod +x /root/run.sh
EXPOSE 8080
CMD /root/run.sh
构建镜像:
docker build -t resourcemanager:v1 .
构建nodemanager镜像
设计思路
(1)构建的hadoop-bash:v1作为基础镜像
(2)将run.sh(启动nodemanager和sshd的脚本)复制到/root下并添加执行权限
(3)指定容器启动运行run.sh脚本
(4)通过docker-build构建nodemanager:v1镜像
dockerfile代码:
FROM hadoop-base:v1
COPY slaves /tmp/
RUN mv /tmp/slaves $HADOOP_HOME/etc/hadoop/slaves
COPY run.sh /root/
RUN chmod +x /root/run.sh
CMD /root/run.sh
构建镜像:
docker build -t nodemanager:v1 .
hdfs容器化部署
部署步骤:
(1)创建docker-compose.yml文件
(2)指定docker-compose版本为3(也可以采用2)
(3)定义名称为hadoop-hdfs的网络,网络驱动指定为bridge,subnet为172.25.1.0/24,网关为172.25.1.1
(4)分别指定hadoop-nn、hadooo-dn1、hadoop-dn2、hadoop-dn3服务,每个服务的重启策略为always,network采用hadoop-hdfs,并添加容器主机名和ip映射,hadoop-nn服务将50070和9000端口映射到DockerHost的50070和9000端口
(5)通过docker-compose up –d启动hdfs服务。
(6)通过WebUI方式测试(浏览器中输入DockerHOST的IP:50070),查看每个节点的运行状态。
docker-compose.yml实例
version: "3"
services:
hadoop-nn:
image: namenode:v1
container_name: hadoop-nn
hostname: hadoop-nn
restart: always
networks:
hadoop-hdfs:
ipv4_address: 172.25.1.100
ports:
- "50070:50070"
- "9000:9000"
extra_hosts:
- "hadoop-nn:172.25.1.100"
- "hadoop-dn1:172.25.1.101"
- "hadoop-dn2:172.25.1.102"
- "hadoop-dn3:172.25.1.103"
hadoop-dn1:
image: datanode:v1
container_name: hadoop-dn1
hostname: hadoop-dn1
restart: always
networks:
hadoop-hdfs:
ipv4_address: 172.25.1.101
extra_hosts:
- "hadoop-nn:172.25.1.100"
- "hadoop-dn1:172.25.1.101"
- "hadoop-dn2:172.25.1.102"
- "hadoop-dn3:172.25.1.103"
hadoop-dn2:
image: datanode:v1
container_name: hadoop-dn2
hostname: hadoop-dn2
restart: always
networks:
hadoop-hdfs:
ipv4_address: 172.25.1.102
extra_hosts:
- "hadoop-nn:172.25.1.100"
- "hadoop-dn1:172.25.1.101"
- "hadoop-dn2:172.25.1.102"
- "hadoop-dn3:172.25.1.103"
hadoop-dn3:
image: datanode:v1
container_name: hadoop-dn3
hostname: hadoop-dn3
restart: always
networks:
hadoop-hdfs:
ipv4_address: 172.25.1.103
extra_hosts:
- "hadoop-nn:172.25.1.100"
- "hadoop-dn1:172.25.1.101"
- "hadoop-dn2:172.25.1.102"
- "hadoop-dn3:172.25.1.103"
networks:
hadoop-hdfs:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.25.1.0/24
启动:
docker-compose up
验证:
YARN容器化部署
部署步骤
(1)创建docker-compose.yml文件
(2)指定docker-compose版本为3(也可以采用2)
(3)定义名称为hadoop-yarn的网络,网络驱动指定为bridge,subnet为172.24.1.0/24,网关为172.24.1.1
(4)分别指定hadoop-rm、hadooo-nm1、hadoop-nm2、hadoop-nm3服务,每个服务的重启策略为always,network采用hadoop-yarn,并添加容器主机名和ip映射,hadoop-rm服务将8080端口映射到DockerHost的8088端口
(5)通过docker-compose up –d启动yarn服务。
(6)通过WebUI方式测试(浏览器中输入DockerHOST的IP:8080),查看每个节点的运行状态。
docker-compose.yml实例
version: "3"
services:
hadoop-rm:
image: resourcemanager:v1
container_name: hadoop-rm
hostname: hadoop-rm
restart: always
networks:
hadoop-yarn:
ipv4_address: 172.24.1.100
ports:
- "8080:8088"
extra_hosts:
- "hadoop-rm:172.24.1.100"
- "hadoop-nm1:172.24.1.101"
- "hadoop-nm2:172.24.1.102"
- "hadoop-nm3:172.24.1.103"
hadoop-nm1:
image: nodemanager:v1
container_name: hadoop-nm1
hostname: hadoop-nm1
restart: always
networks:
hadoop-yarn:
ipv4_address: 172.24.1.101
extra_hosts:
- "hadoop-rm:172.24.1.100"
- "hadoop-nm1:172.24.1.101"
- "hadoop-nm2:172.24.1.102"
- "hadoop-nm3:172.24.1.103"
hadoop-nm2:
image: nodemanager:v1
container_name: hadoop-nm2
hostname: hadoop-nm2
restart: always
networks:
hadoop-yarn:
ipv4_address: 172.24.1.102
extra_hosts:
- "hadoop-rm:172.24.1.100"
- "hadoop-nm1:172.24.1.101"
- "hadoop-nm2:172.24.1.102"
- "hadoop-nm3:172.24.1.103"
hadoop-nm3:
image: nodemanager:v1
container_name: hadoop-nm3
hostname: hadoop-nm3
restart: always
networks:
hadoop-yarn:
ipv4_address: 172.24.1.103
extra_hosts:
- "hadoop-rm:172.24.1.100"
- "hadoop-nm1:172.24.1.101"
- "hadoop-nm2:172.24.1.102"
- "hadoop-nm3:172.24.1.103"
networks:
hadoop-yarn:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.24.1.0/24
启动:
docker-compose up
验证:
12.docker安装zookeeper
什么是zookeeper
zookeeper实际上是yahoo开发的,用于分布式中一致性处理的框架。最初其作为研发Hadoop时的副产品。由于分布式系统中一致性处理较为困难,其他的分布式系统没有必要费劲重复造轮子,故随后的分布式系统中大量应用了zookeeper,以至于zookeeper成为了各种分布式系统的基础组件,其地位之重要,可想而知。著名的hadoop、kafka、dubbo 都是基于zookeeper而构建。
官网:http://zookeeper.apache.org/
集群规划
容器主机名/容器名 | 容器IP(网络名称zk-network) |
---|---|
zk1 | 172.26.1.101 |
zk2 | 172.26.1.102 |
zk3 | 172.26.1.103 |
镜像启动操作
实现思路
(1)2.2中构建的jdk1.8:v1作为基础镜像
(2)将zookeeper-3.4.12.tar.gz(可采用其他版本)复制到容器的/root目录下并解压至/root/apps目录下,为了精简镜像,需要将zookeeper-3.4.12.tar.gz删除。
(3)配置Zookeeper环境变量,并定义MYID变量(docker-compose运行时传递参数到MYID,并写入到zookeeper的datadir中的myid文件中)
(4)将配置文件复制的/tmp/目录下,并在/tmp/下移动到$ZOOKEEPER_HOME/conf /目录中
(5)将start-zk.sh(启动zookeeper和sshd服务)复制到/root下并添加执行权限
(6)创建zoo.conf配置文件中指定的datadir目录
(7)指定/root/data/zookeeper为数据卷
(8)暴露2181端口
(9)指定容器启动时运行start-zk.sh脚本
dockerfile实例
FROM jdk8:v1.0
MAINTAINER zhang
COPY zookeeper-3.4.12.tar.gz /root
RUN tar -zxvf zookeeper-3.4.12.tar.gz -C /root/apps/ && \
mv /root/apps/zookeeper-3.4.12 /root/apps/zookeeper && \
rm -f zookeeper-3.4.12.tar.gz
ENV ZOOKEEPER_HOME=/root/apps/zookeeper
ENV PATH=$ZOOKEEPER_HOME/bin:$PATH
ARG MYID
COPY conf/* /tmp/
RUN mv /tmp/zoo.cfg ${ZOOKEEPER_HOME}/conf/zoo.cfg && \
mv /tmp/start-zk.sh /root/start-zk.sh
RUN chmod +x /root/start-zk.sh
RUN mkdir -p /root/data/zookeeper && echo ${MYID} > /root/data/zookeeper/myid
EXPOSE 2181
CMD /root/start-zk.sh
容器化部署
实现思路
(1)创建docker-compose.yml文件
(2)指定docker-compose版本为3(也可以采用2)
(3)定义名称为zk-network的网络,网络驱动指定为bridge,subnet为172.26.1.0/24,网关为172.26.1.1
(4)分别指定zk1、zk2、zk3,每个服务的重启策略为always,network采用zk-network,并添加容器主机名和ip映射,每个容器都要映射端口到当前DockerHost主机中,为了避免端口冲突,所以主机中的端口分别采用2181、2182和2183
(5)通过docker-compose up –d启动zookeeper服务。
docker-compose.yml实例
version: "3"
services:
zk1:
build:
context: /root/dockerfile/zookeeper/
dockerfile: /root/dockerfile/zookeeper/dockerfile
args:
MYID: 1
container_name: zk1
hostname: zk1
restart: always
networks:
zk-network:
ipv4_address: 172.26.1.101
ports:
- "2181:2181"
extra_hosts:
- "zk1:172.26.1.101"
- "zk2:172.26.1.102"
- "zk3:172.26.1.103"
zk2:
build:
context: /root/dockerfile/zookeeper/
dockerfile: /root/dockerfile/zookeeper/dockerfile
args:
MYID: 2
container_name: zk2
hostname: zk2
restart: always
networks:
zk-network:
ipv4_address: 172.26.1.102
ports:
- "2182:2181"
extra_hosts:
- "zk1:172.26.1.101"
- "zk2:172.26.1.102"
- "zk3:172.26.1.103"
zk3:
build:
context: /root/dockerfile/zookeeper/
dockerfile: /root/dockerfile/zookeeper/dockerfile
args:
MYID: 3
container_name: zk3
hostname: zk3
restart: always
networks:
zk-network:
ipv4_address: 172.26.1.103
ports:
- "2183:2181"
extra_hosts:
- "zk1:172.26.1.101"
- "zk2:172.26.1.102"
- "zk3:172.26.1.103"
networks:
zk-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.26.1.0/24
运行yml并创建镜像:
docker-compose up --build
查看镜像、运行容器及验证:
出现的问题
[Warning] IPv4 forwarding is disabled. Networking will not work.
解决方法:
在docker的宿主机中更改以下
[root@localhost ~]# vi /usr/lib/sysctl.d/00-system.conf
添加如下代码:
net.ipv4.ip_forward=1
重启network服务
# systemctl restart network
docker安装Spark
什么是Spark
Spark最初由美国加州伯克利大学的AMP实验室于2009年开发,Spark是一种通用的大数据计算框架,是基于RDD(弹性分布式数据集)的一种计算模型。通俗讲就是可以分布式处理大量极数据的,将大量集数据先拆分,分别进行计算,然后再将计算后的结果进行合并。
Apache Spark的功能
快速 - 使用最先进的DAG调度程序,查询优化器和物理执行引擎,为批处理和流数据提供高性能。
易于使用 - 它有助于使用Java,Scala,Python,R和SQL编写应用程序。它还提供80多个高级运算符。
通用性 - 它提供了一系列库,包括SQL和DataFrames,用于机器学习的MLlib,GraphX和Spark Streaming。
轻量级 - 它是一种轻型统一分析引擎,用于大规模数据处理。
无处不在 - 它可以轻松运行在Hadoop,Apache Mesos,Kubernetes,独立或云端。
集群规划
容器主机名/容器名 | 容器IP(网络名称spark-network) | 节点进程 | 容器启动镜像 |
---|---|---|---|
spark-master1 | 172.27.1.100 | master、HistoryServer | spark-master:v1 |
spark-master2 | 172.27.1.120 | master | spark-master:v1 |
spark-worker1 | 172.27.1.101 | worker | spark-worker:v1 |
spark-worker2 | 172.27.1.102 | worker | spark-worker:v1 |
spark-worker3 | 172.27.1.103 | worker | spark-master:v1 |
设计与实现思路
spark-master镜像
基础步骤
(1)2.2中构建的jdk1.8:v1作为基础镜像
(2)将spark-2.3.4.tar.gz(可采用其他版本)复制到容器的/root目录下并解压至/root/apps目录下,为了精简镜像,需要将spark-2.3.4.tar.gz删除。
(3)配置Spark环境变量
(4)将配置文件(指导老师讲解配置文件并提供给学生)复制的/tmp/目录下,并在/tmp/下移动到$SPARK_HOME/conf/目录中
(5)创建 /root/apps/spark/logs目录(spark启动时的日志文件输出到本目录下)
(6)将run.sh(启动master和historyserver服务)复制到/root下并添加执行权限
(7)暴露8080和7077端口
(8)指定容器启动时运行run.sh脚本
dockerfile实例
FROM jdk8:v1.0
COPY spark-2.3.4.tar.gz /root
RUN tar -zxvf spark-2.3.4.tar.gz -C apps/ && \
mv /root/apps/spark-2.3.4-bin-hadoop2.7 /root/apps/spark && \
rm -rf /root/spark-2.3.4.tar.gz
ENV SPARK_HOME=/root/apps/spark
ENV PATH=$SPARK_HOME/bin:$SPARK_HOME/sbin:$PATH
COPY conf/* /tmp/
RUN mv /tmp/spark-env.sh $SPARK_HOME/conf/spark-env.sh && \
mv /tmp/slaves $SPARK_HOME/conf/slaves && \
mv /tmp/spark-defaults.conf $SPARK_HOME/conf/spark-defaults.conf && \
mv /tmp/run.sh /root/run.sh
RUN chmod +x /root/run.sh
RUN mkdir -p /root/apps/spark/logs
EXPOSE 8080 7077
CMD /root/run.sh
docker build -t spark-master:v1 .
spark-worker镜像
基础步骤
(1)2.2中构建的jdk1.8:v1作为基础镜像
(2)将spark-2.3.4.tar.gz(可采用其他版本)复制到容器的/root目录下并解压至/root/apps目录下,为了精简镜像,需要将spark-2.3.4.tar.gz删除。
(3)配置Spark环境变量
(4)将配置文件(指导老师讲解配置文件并提供给学生)复制的/tmp/目录下,并在/tmp/下移动到$SPARK_HOME/conf/目录中
(5)创建 /root/apps/spark/logs目录(spark启动时的日志文件输出到本目录下)
(6)将run.sh(启动worker,因为现在有两个master节点,所以需要启动worker时需要判断哪个节点的master时主节点)复制到/root下并添加执行权限,
(7)指定容器启动时运行run.sh脚本
dockerfile实例
FROM jdk8:v1.0
RUN apt-get install curl -y
COPY spark-2.3.4.tar.gz /root
RUN tar -zxvf spark-2.3.4.tar.gz -C apps/ && \
mv /root/apps/spark-2.3.4-bin-hadoop2.7 /root/apps/spark && \
rm -rf /root/spark-2.3.4.tar.gz
ENV SPARK_HOME=/root/apps/spark
ENV PATH=$SPARK_HOME/bin:$SPARK_HOME/sbin:$PATH
COPY conf/* /tmp/
RUN mv /tmp/spark-env.sh $SPARK_HOME/conf/spark-env.sh && \
mv /tmp/slaves $SPARK_HOME/conf/slaves && \
mv /tmp/spark-defaults.conf $SPARK_HOME/conf/spark-defaults.conf && \
mv /tmp/run.sh /root/run.sh
RUN chmod +x /root/run.sh
RUN mkdir -p /root/apps/spark/logs
CMD /root/run.sh
docker build -t spark-worker:v1 .
出现的问题
构建镜像时出现以下爆红,但是不影响构建镜像。
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
dpkg-preconfigure: unable to re-open stdin:
解决方法:
在docker file中增加一句(在apt-get install 的前面):
ENV DEBIAN_FRONTEND noninteractive
部署安装
基础步骤
(1)先在HDFS中创建spark-history的目录(spark-default中指定的historyserver保存数据的目录)
(2)创建docker-compose.yml文件
(3)指定docker-compose版本为3(也可以采用2)
(4)定义名称为spark-network的网络,网络驱动指定为bridge,subnet为172.27.1.0/24,网关为172.27.1.1
(5)分别指定spark-master1、spark-master2、spark-worker1,spark-worker2、 spark-worker3服务,每个服务的重启策略为always,network采用spark-network,并添加容器主机名和ip映射,spark-master1、spark-master2将8080和7077端口映射到Docker主机的8080和7077端口。
(6)通过docker-compose up –d启动Spark服务。
docker-compose.yml实例
version: "3"
services:
spark-master1:
image: spark-master:v1
container_name: spark-master1
hostname: spark-master1
restart: always
networks:
spark-network:
ipv4_address: 172.27.1.100
ports:
- "8081:8080"
- "7078:7077"
extra_hosts:
- "spark-master1:172.27.1.100"
- "spark-master2:172.27.1.120"
- "spark-worker1:172.27.1.101"
- "spark-worker2:172.27.1.102"
- "spark-worker3:172.27.1.103"
spark-master2:
image: spark-master:v1
container_name: spark-master2
hostname: spark-master2
restart: always
networks:
spark-network:
ipv4_address: 172.27.1.120
ports:
- "8080:8080"
- "7077:7077"
extra_hosts:
- "spark-master1:172.27.1.100"
- "spark-master2:172.27.1.120"
- "spark-worker1:172.27.1.101"
- "spark-worker2:172.27.1.102"
- "spark-worker3:172.27.1.103"
spark-worker1:
image: spark-worker:v1
container_name: spark-worker1
hostname: spark-worker1
restart: always
networks:
spark-network:
ipv4_address: 172.27.1.101
extra_hosts:
- "spark-master1:172.27.1.100"
- "spark-master2:172.27.1.120"
- "spark-worker1:172.27.1.101"
- "spark-worker2:172.27.1.102"
- "spark-worker3:172.27.1.103"
spark-worker2:
image: spark-worker:v1
container_name: spark-worker2
hostname: spark-worker2
restart: always
networks:
spark-network:
ipv4_address: 172.27.1.102
extra_hosts:
- "spark-master1:172.27.1.100"
- "spark-master2:172.27.1.120"
- "spark-worker1:172.27.1.101"
- "spark-worker2:172.27.1.102"
- "spark-worker3:172.27.1.103"
spark-worker3:
image: spark-worker:v1
container_name: spark-worker3
hostname: spark-worker3
restart: always
networks:
spark-network:
ipv4_address: 172.27.1.103
extra_hosts:
- "spark-master1:172.27.1.100"
- "spark-master2:172.27.1.120"
- "spark-worker1:172.27.1.101"
- "spark-worker2:172.27.1.102"
- "spark-worker3:172.27.1.103"
networks:
spark-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.27.1.0/24