大数据运维综合实践课堂笔记

课程笔记教师版

https://www.wolai.com/ptxibaMET7CiA4PMQMRgwU

第一课时开始2021.8.30


虚拟化技术 docker

三个概念

镜像(Image)

  • 模板,提前设计好的与各种相关环境的环境

  • 镜像就是创建容器的模板

容器(Container)

  • 运行环境、就是一个完整的操作系统

  • 容器与容器之间做到了完全的隔离(沙箱)

仓库(Repository)

  • 存放各种镜像的地方,可以上传下载
  • 远程仓库:dockerHub、本地仓库
  • 每个仓库都可以包含多个标签(Tag),每个标签对应一个镜像
  • 通常每个仓艰苦会包含同一个软件不同版本的镜像,可以通过仓库名:标签的格式来指定镜像

环境准备

###配置静态ip

###安装Docker

卸载旧版本

旧版本的多克被称为或。如果安装了这些,则卸载它们以及相关的依赖关系。docker``docker-engine

1
2
3
4
5
6
7
8
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine

安装

  • 更新yum源

    1
    sudo yum update
  • 安装 yum-utils 及devicemapper驱动

    1
    yum install -y yum-utils device-mapper-persistent-data lvm2
  • 设置yum源

    1
    yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  • 安装Docker

    1
    yum install docker-ce -y
  • 启动Docker

    1
    systemctl start docker
  • 检查docker是否正确安装

    1
    docker run hello-world
  • 正确安装输出如下:


第二课时开始2021.8.31


Docker使用

docker run -i ubuntu /bin/echo “hello world”

1
docker run -i ubuntu /bin/echo "hello world"
  • run:运行一个容器
  • ubuntu:指定要运行的镜像,Docker首先从本地主机上查找镜像是否存在,如果不存在,Docker就会从镜像仓库Docker Hub下载符合的公共镜像。
  • /bin/echo “hello world”:在启动的容器中执行的命令。

docker run -i -t ubuntu /bin/bash

1
docker run -i -t -d ubuntu /bin/bash
  • -t:在新容器内指定一个伪终端或终端。
  • -i:允许你对容器内的标准输入(STDIN)进行交互
  • -d 后台启动容器,不会进入容器

常用操作

exit或CTRL+D来退出容器

docker ps 来查看运行的容器

  • CONTAINER ID:容器ID
  • IMAGE:使用的镜像
  • COMMAND:启动容器时运行的命令
  • CREATED:容器的创建时间
  • STATUS:容器的状态
    • Created(已创建)
    • Restarting(重启中)
    • Running 或 Up(运行中)
    • Removing(迁移中)
    • Paused(暂停)
    • Exited(停止)
    • Dead(死亡)
  • PORTS:容器的端口信息和使用的连接类型(tcp/udp)
  • NAMES:自动分配的容器名称

进入、退出容器

1
2
3
4
进入:docker attach DockerID
docker exec
退出:exit
推荐使用docker exec命令进入容器,退出容器终端时,不会导致容器停止

删除容器

1
2
docker ps #列出正在运行的容器 |-a 全部容器
docker rm ID # 删除对应ID的容器(需先停止)| -f 强制删除

镜像操作

列出本地主机上的镜像

1
docker images 

  • REPOSITORY:表示镜像的仓库源
  • TAG:镜像的标签
  • IMAGE ID:镜像ID
  • CREATED:镜像创建时间
  • SIZE:镜像大小

获取一个新的镜像

1
docker pull ubuntu:13.10

查找镜像

1
docker search hadoop

第三课时开始 2021.9.1


容器链接

网络端口映射

1
docker run -d -p 80:5000 training/webapp python app.py
  • -p:指定端口映射,5000容器内部端口,80容器向外暴露的端口(本机的80端口映射到容器的5000端口)
  • 浏览器打开IP:80输出如下

指定容器绑定网络地址

1
docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
  • 可以通过访问127.0.0.1:5001来访问容器的5001端口

问题

无法访问127.0.0.1:5001

问题分析

127.0.0.1应该是虚拟机的IP,在主机访问127.0.0.1定位到了主机,而不是虚拟机的127地址

5001端口正在占用说明容器没问题

问题解决

  • 127.0.0.1 为本机地址,外网不能访问
  • 0.0.0.0 为外网可以访问的地址
  1. 虚拟机的127 5001端口映射出去 (暂时没有找到访问方法)

  2. 直接在虚拟机中访问127.0.0.1:5001

返回了hello world 说明指定ip成功

问题原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
localhost、127.0.0.10.0.0.0和本机IP的区别
localhost
localhost其实是域名,一般windows系统默认将localhost指向127.0.0.1,但是localhost并不等于127.0.0.1,localhost指向的IP地址是可以配置的

127.0.0.1
首先我们要先知道一个概念,凡是以127开头的IP地址,都是回环地址(Loop back address),其所在的回环接口一般被理解为虚拟网卡,并不是真正的路由器接口。

所谓的回环地址,通俗的讲,就是我们在主机上发送给127开头的IP地址的数据包会被发送的主机自己接收,根本传不出去,外部设备也无法通过回环地址访问到本机。

小说明:正常的数据包会从IP层进入链路层,然后发送到网络上;而给回环地址发送数据包,数据包会直接被发送主机的IP层获取,后面就没有链路层他们啥事了。

127.0.0.1作为{127}集合中的一员,当然也是个回环地址。只不过127.0.0.1经常被默认配置为localhost的IP地址。
一般会通过ping 127.0.0.1来测试某台机器上的网络设备是否工作正常。

0.0.0.0
首先,0.0.0.0是不能被ping通的。在服务器中,0.0.0.0并不是一个真实的的IP地址,它表示本机中所有的IPV4地址。监听0.0.0.0的端口,就是监听本机中所有IP的端口。

小例子剧场(帮助理解本机IP、127.0.0.10.0.0.0
现在有两台pc在同一个局域网内,分别为pc1与pc2,pc1上有一个网卡,IP地址为192.168.10.128

pc1中sever监听127.0.0.1,则pc1中的client可以连上127.0.0.1192.168.10.128连不上;而pc2中client都连不上。
pc1中sever监听192.168.10.128,则pc1中的client可以连上192.168.10.128127.0.0.1连不上;而pc2中client能连上192.168.10.128
pc1中sever监听0.0.0.0,则pc1中的client可以连上127.0.0.1192.168.10.128,pc2中的client能连上192.168.10.128

容器命名

1
docker run -d -P --name runoob training/webapp python app.py

新建网络

1
docker network create -d bridge test-net
  • 新建一个桥接(bridge)网络,命名为test-net

问题

1
2
3
Error response from daemon: Failed to Setup IP tables: Unable to enable SKIP DNAT rule:  (iptables failed: iptables --wait -t nat -I DOCKER -i br-139fb34fcc94 -j RETURN: iptables: No chain/target/match by that name.
(exit status 1))

解决

1
2
3
关闭防火墙之后docker需要重启,执行以下命令重启docker即可:

systemctl restart docker

连接容器

  • 新建一个名为test1,镜像为ubuntu,并连接到网络test-net的容器
    1
    docker run -itd --name test1 --network test-net ubuntu /bin/bash
  • 新建一个名为test2,镜像为ubuntu,并连接到网络test-net的容器
    1
    docker run -itd --name test2 --network test-net ubuntu /bin/bash

  • 进入容器test1

    1
    docker exec -it test1 /bin/bash
    • 安装ping

      1
      2
      3
      4
      5
      apt-get update
      apt-get install iputils-ping

      如果安装失败,先设置apt源
      参考:https://blog.csdn.net/annita2019/article/details/104743157/
    • ping test2

      1
      ping test2

配置dns

在宿主机的 /etc/docker/daemon.json文件中增加以下内容来设置全部容器的dns(若不存在daemon.json文件需要新建)

1
{ "dns" : [ "114.114.114.114", "8.8.8.8" ] }

设置后,启动容器的 DNS 会自动配置为 114.114.114.114 和 8.8.8.8。

配置完,需要重启 docker 才能生效。

查看容器的 DNS 是否生效可以使用以下命令,它会输出容器的 DNS 信息:

1
docker run -it --rm  ubuntu  cat etc/resolv.conf

Dockerfile

什么是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存放目录下执行构建动作

在当前目录下新建名为dockerfile的文件

文件内容如下

1
2
FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html

执行命令构建镜像

1
docker build -t nginx:v3 . #注意后面的.为上下文路径

  • 红框为自己构建的镜像,蓝框为拉取的公共镜像

启动镜像

1
docker run -itd -p 80:80 {IMAGE ID}

提示:乱码是因为网页内容的编码格式不对

上下文路径

是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。

如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。

注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。

docker 文件指令详解

COPY

复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
COPY [–chown=:] <源路径1>… <目标路径>

[–chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。

源路径可以为通配符格式
目标路径无需创建好,如无目标路径则自行创建
COPY hom* /mydir/
COPY hom?.txt /mydir/

ADD

ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:

  • ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
  • ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
  • 如果想原封不动的复制tar文件到容器下,需使用copy

CMD

类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:

  • CMD 在docker run 时运行。
  • RUN 是在 docker build。

作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。

*ENV

设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
ENV ENV = =
实例
ENV NODE_VERSION 7.2.0

ARG

构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。

练习

要求

配置一个能用jdk的dockerfile镜像

答案

1
111doickd

docker compose安装

什么是docker compose

Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

YAML

本节参考https://www.runoob.com/w3cnote/yaml-intro.html

基本语法

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进不允许使用tab,只允许使用空格
  • 所进的空格数不重要,只要相同的层级的元素左对齐即可
  • 表示注释

数据类型

YAML支持以下几种数据类型:

  • 对象:键值对的集合,又称为映射(mapping)/哈希(hashes)/字典(dictionary)
  • 数组:一组按次序排列的值,又称为序列(sequence)/列表(list)
  • 纯量(scalars):单个的、不可再分的值

YAML对象

对象键值对使用冒号结构表示 key: value,冒号后面要加一个空格。
也可以使用 **key:{key1: value1, key2: value2, …}**。
还可以使用缩进表示层级关系;

1
2
key: child-key: value
child-key2: value2

YAML数组

以 - 开头的行表示构成一个数组:

  • A
  • B
  • C

YAML 支持多维数组,可以使用行内表示:
key: [value1, value2, …]
数据结构的子成员是一个数组,则可以在该项下面缩进一个空格。

  • A
  • B
  • C

例子
companies:

1
2
3
4
5
6
7
8
- 
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}]

纯量

纯量是最基本的,不可再分的值,包括:

  • 字符串
  • 布尔值
  • 整数
  • 浮点数
  • Null
  • 时间
  • 日期

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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连接,最后使用+代表时区

引用

& 锚点和 * 别名,可以用来引用:

1
2
3
4
5
6
7
8
9
10
11
defaults: &defaults
adapter: postgres
host: localhost

development:
database: myapp_development
<<: *defaults

test:
database: myapp_test
<<: *defaults

相当于

1
2
3
4
5
6
7
8
9
10
11
12
13
defaults:
adapter: postgres
host: localhost

development:
database: myapp_development
adapter: postgres
host: localhost

test:
database: myapp_test
adapter: postgres
host: localhost

& 用来建立锚点(defaults),**<<** 表示合并到当前数据,***** 用来引用锚点。

Compose 使用的三个步骤

  • 使用 Dockerfile 定义应用程序的环境。
  • 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
  • 最后,执行 docker-compose up 命令来启动并运行整个应用程序。

    compose安装

    curl -L “https://get.daocloud.io/docker/compose/releases/download/1.12.0/docker-compose-(uname−s)−(uname -s)-(uname−s)−(uname -m)” -o /usr/local/bin/docker-compose
    下载并安装
    chmod +x /usr/local/bin/docker-compose
    更改权限可执行

    测试安装是否成功

    docker-compose -version
    docker-compose version 1.12.0, build b31ff33

yml 配置指令

version

指定本 yml 的写法格式(格式的版本)

services

服务列表,用数组形式展现,每个服务可为一个容器

image

指定服务所用镜像

container_name

指定容器名字,而非默认

restart

  • no:是默认的重启策略,在任何情况下都不会重启容器。
  • always:容器总是重新启动。(docker重启时)
  • on-failure:在容器非正常退出时(退出状态非0),才会重启容器。
  • unless-stopped:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器

networks

配置容器连接的网络,引用顶级 networks 下的条目

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
自定义扩展网卡

实例

1
2
3
4
5
6
    networks:
     extnetwork:   #自定义网络名称
     ipam:  #ip地址管理
     config:   #配置信息
     - subnet: 172.20.0.0/24  #网段管理
     gateway: 172.20.0.1   #网关地址

ipv4_address

为服务的容器指定一个静态ip地址

1
2
3
networks:
hadoop-hdfs:
ipv4_address: 172.25.1.100

ports

映射端口
实例

1
2
3
   ports:
- "50070:50070"
- "9000:9000"

extra_hosts

添加主机名的标签,就是往/etc/hosts文件中添加一些记录

1
2
3
4
5
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"

docker-compose 构建停止启动命令

1
2
3
4
5
6
构建docekr-compose集群
docker-compose up
停止docker-compose集群
docker-compose stop
启动doceker-compose集群
docker-compose start

docker安装hadoop

构建基础环境镜像

拉取ubuntu:14.04镜像

1
docker pull ubuntu:14.04

创建虚拟nat网卡

1
docker network create -d bridge baseEnv-net

下载sources.list及ssh_config

1
2
3
宿主机中
wget web.wanqqq29.cn/sources.list
wget web.wanqqq29.cn/ssh_config

编写dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
** 旧版本(免密登录、ssh无效) **
FROM ubuntu:14.04
RUN mv /etc/apt/sources.list /etc/apt/sources.bak
COPY files/sources.list /etc/apt/
RUN apt-get update && \
apt-get install openssh-server openssh-client -y && \
mv /etc/ssh/ssh_config /etc/ssh/ssh_config.bak
COPY files/ssh_config /etc/ssh/
RUN mkdir -p /var/run/sshd && \
echo 'root:root' | chpasswd && \
cd /root
CMD /var/run/sshd -D

**最终版本**
FROM ubuntu:14.04

RUN mv /etc/apt/sources.list /etc/apt/sources.bak

COPY files/sources.list /etc/apt/

RUN apt-get update && \
apt-get install openssh-server openssh-client -y && \
mv /etc/ssh/ssh_config /etc/ssh/ssh_config.bak
mkdir -p /var/run/sshd && \
echo 'root:root' | chpasswd

RUN mkdir /root/.ssh && ssh-keygen -q -P '' -t dsa -f /root/.ssh/id_dsa && \
cat /root/.ssh/id_dsa.pub >> /root/.ssh/authorized_keys

COPY files/ssh_config /etc/ssh/



EXPOSE 22
WORKDIR /root

CMD /usr/sbin/sshd -D


** RUN层优化 **
FROM ubuntu:14.04

RUN mv /etc/apt/sources.list /etc/apt/sources.bak

COPY files/sources.list /etc/apt/

RUN apt-get update && \
apt-get install openssh-server openssh-client -y && \
mv /etc/ssh/ssh_config /etc/ssh/ssh_config.bak && \
mkdir -p /var/run/sshd && \
echo 'root:root' | chpasswd && \
mkdir /root/.ssh && ssh-keygen -q -P '' -t dsa -f /root/.ssh/id_dsa && \
cat /root/.ssh/id_dsa.pub >> /root/.ssh/authorized_keys && \
apt-get clean && rm -rf /var/lib/apt/lists/*

COPY files/ssh_config /etc/ssh/

EXPOSE 22
WORKDIR /root
CMD /usr/sbin/sshd -D

优化空间

1
2
3
apt-get clean && rm -rf /var/lib/apt/lists/* 
删除apt-get缓存
v2比v1 小了25M

构建镜像

1
docker build -t ubuntu-ssh:v1 .

创建容器

1
2
docker run -itd --name baseEnv1 --network baseEnv-net ubuntu-ssh:v1 
docker run -itd --name baseEnv2 --network baseEnv-net ubuntu-ssh:v1

测试是否免密登录

查看ip

1
2
docker inspect {name}
172.19.0.2/3

进入容器

1
2
3
docker exec -it baseEnv1 /bin/bash
ssh root@localhost
ssh root@{baseEnv2.IP}

问题

1. ssh服务起不来

1
2
3
4
5
6
7
```
CMD /var/run/sshd -D
sudo service ssh start
无效
```

启动容器后,ssh登录22端口拒绝

通过ps -e |grep ssh命令查看ssh进程没起来

- 问题分析
  • 没有暴露22端口

    启动容器时添加了 /bin/bash 替换了最后的CMD 导致Dockerfile中的CMD被替代掉

- 问题解决
  • 暴露端口EXPOSE 22
  • 去掉/bin/bash

2.免密登录配置不成功

- 问题分析
  • 在刚开始的dockerfile中,没有配置免密登录
  • 配置免密登录后修改root密码
  • 免密登录需要多次交互操作
- 问题解决
  • 修改root密码放在配置免密前

  • 减少交互操作配置免密登录

  • ```shell
    ssh-keygen -q -P ‘’ -t dsa -f /root/.ssh/id_dsa
    -q -P ‘’ 取消密码确认操作
    -f 指定生成地址

配置JDK

因为Hadoop、Zookeeper、Spark依赖于JVM,因此本模块功能为构建JDK镜像作为Hadoop、Zookeeper和Spark的基础镜像。

设计思路

1
2
3
4
1)采用2.1中构建的ubuntu-ssh:v1作为基础镜像
2)将jdk-8u231-linux-x64.tar.gz(也可采用其他版本,建议1.8JDK)复制并解压到/root/tool目录下,为了精简镜像,解压完成后需要将jdk-8u231-linux-x64.tar.gz删除。
3)配置Java的环境变量
4)通过docker build构jdk:v1镜像

编写dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FROM ubuntu-ssh:v1

RUN mkdir -p /root/tool

COPY files/jdk.tar.gz /root/

RUN tar -zxvf /root/jdk.tar.gz -C /root/tool/ && \
mv /root/tool/jdk1.8.0_231 /root/tool/java && \
rm -rf /root/jdk.tar.gz

ENV JAVA_HOME=/root/tool/java
ENV PATH=$JAVA_HOME/bin:$PATH

CMD /usr/sbin/sshd -d

构建镜像

1
docker build -t ubuntu-jdk:v1 .

创建容器

1
2
docker run -itd --name jdkEnv1 --network baseEnv-net ubuntu-jdk:v1 
docker run -itd --name jdkEnv2 --network baseEnv-net ubuntu-jdk:v1

测试是否成功

1
2
docker exec -it jdkEnv1 /bin/bash
java -version /java /javac

Hadoop部署

集群规划

hdfs集群规划

容器主机名/容器名 容器IP(网络名称hadoop-hdfs) 节点进程 容器启动镜像
hadoop-nn 172.25.1.100 NameNode、SecondaryNameNode namenode:v1
hadoop-dn1 172.25.1.101 DataNode datanode:v1
hadoop-dn2 172.25.1.102 DataNode datanode:v1
hadoop-dn3 172.25.1.103 DataNode datanode:v1

yarn集群规划

容器主机名/容器名 容器IP(网络名称hadoop-yarn) 节点进程 容器启动镜像
hadoop-rm 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镜像。

构建hadoopBase镜像

基础步骤

1
2
3
4
5
6
7
12.2中构建的ubuntu-jdk:v1作为基础镜像
2)将hadoop-2.7.6.tar.gz(可采用其他版本)复制到容器的/root目录下并解压至/root/tools目录下,为了精简镜像,需要将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/目录中
** 需要修改hadoop-env.sh中JAVA_HOME的路径为/root/tool/java
6)通过docker-build构建hadoop-base:v1镜像

编写dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
FROM ubuntu-jdk:v1

COPY files/hadoop-2.7.6.tar.gz /root

RUN tar -zxvf /root/hadoop-2.7.6.tar.gz -C /root/tool && \
mv /root/tool/hadoop-2.7.6 /root/tool/hadoop && \
rm -rf /root/hadoop-2.7.6.tar.gz && \
mkdir -p /root/hdfs/namenode && \
mkdir -p /root/hdfs/datanode && \
mkdir -p /root/tool/hadoop/logs

ENV HADOOP_HOME=/root/tool/hadoop
ENV PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH

COPY files/config/* /tmp/

RUN mv /tmp/hadoop-env.sh $HADOOP_HOME/etc/hadoop/hadoop-env.sh && \
mv /tmp/hdfs-site.xml $HADOOP_HOME/etc/hadoop/hdfs-site.xml && \
mv /tmp/core-site.xml $HADOOP_HOME/etc/hadoop/core-site.xml && \
mv /tmp/mapred-site.xml $HADOOP_HOME/etc/hadoop/mapred-site.xml && \
mv /tmp/yarn-site.xml $HADOOP_HOME/etc/hadoop/yarn-site.xml && \
apt-get clean && rm -rf /var/lib/apt/lists/*

启动镜像验证

1
2
3
docker run -itd --name hadoopBase1 --network baseEnv-net hadoop-base:v1
docker exec -it hadoopBase1 /bin/bash
hadoop

namenode镜像

基础步骤
1
2
3
4
5
6
7
(1)构建的hadoop-base: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镜像
sh文件
1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh

hadoop namenode -format


echo '启动namenode'
/root/tool/hadoop/sbin/hadoop-daemon.sh start namenode

echo '启动ssh服务'
/usr/sbin/sshd -D

编写dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FROM hadoop-base:v1

COPY files/* /root/

RUN mv /root/slaves $HADOOP_HOME/etc/hadoop/slaves && \
hadoop namenode -format

VOLUME /root/hdfs

EXPOSE 50070
EXPOSE 9000

RUN chmod +x run.sh

CMD sh run.sh

构建镜像
1
docker build -t namenode:v1 .
验证
1
2
3
docker run -itd --name namenode1 --network baseEnv-net namenode:v1 
docker exec -it namenode1 /bin/bash
jps

datanode镜像

基础步骤

1
2
3
4
(1)构建的hadoop-base:v1作为基础镜像
(2)将run.sh(启动datanode和sshd的脚本)复制到/root下并添加执行权限
(3)指定容器启动运行run.sh脚本
(4)通过docker-build构建datanode:v1镜像

sh文件

1
2
3
4
5
6
7
#!/bin/sh

echo '启动datanode'
/root/tool/hadoop/sbin/hadoop-daemon.sh start datanode

echo '启动ssh服务'
/usr/sbin/sshd -D

dockerfile

1
2
3
4
5
6
7
8
FROM hadoop-base:v1

COPY files/* /root/

RUN mv /root/slaves $HADOOP_HOME/etc/hadoop/slaves && \
chmod +x run.sh

CMD sh run.sh

构建镜像

1
docker build -t datanode:v1 .

验证

1
2
3
docker run -itd --name datanode1 --network baseEnv-net datanode:v1 
docker exec -it datanode1 /bin/bash
jps

resourcemanager镜像

基础步骤

1
2
3
4
5
(1)构建的hadoop-bash:v1作为基础镜像
(2)将run.sh(启动resourcemanager和sshd的脚本)复制到/root下并添加执行权限
(3)暴露端口8080
(4)指定容器启动运行run.sh脚本
(5)通过docker-build构建resourcemanager:v1镜像

sh文件

1
2
3
4
5
6
7
#!/bin/sh

echo '启动resourcemanager'
/root/tool/hadoop/sbin/yarn-daemon.sh start resourcemanager

echo '启动ssh服务'
/usr/sbin/sshd -D

dockerfile 文件

1
2
3
4
5
6
7
8
9
10
11
FROM hadoop-base:v1

COPY files/* /root/

RUN mv /root/slaves $HADOOP_HOME/etc/hadoop/slaves

RUN chmod +x run.sh

EXPOSE 8080

CMD sh run.sh

构建镜像

1
docker build -t resourcemanager:v1 .

验证

1
2
3
docker run -itd --name resourcemanager1 --network baseEnv-net resourcemanager:v1 
docker exec -it resourcemanager1 /bin/bash
jps

nodemanager镜像

基础步骤

1
2
3
4
(1)构建的hadoop-bash:v1作为基础镜像
(2)将run.sh(启动nodemanager和sshd的脚本)复制到/root下并添加执行权限
(3)指定容器启动运行run.sh脚本
(4)通过docker-build构建node:v1镜像

sh文件

1
2
3
4
5
6
7
#!/bin/sh

echo '启动resourcemanager'
/root/tool/hadoop/sbin/yarn-daemon.sh start nodemanager

echo '启动ssh服务'
/usr/sbin/sshd -D

dockerfile 文件

1
2
3
4
5
6
7
8
9
FROM hadoop-base:v1

COPY files/* /root/

RUN mv /root/slaves $HADOOP_HOME/etc/hadoop/slaves

RUN chmod +x run.sh

CMD sh run.sh

构建镜像

1
docker build -t nodemanager:v1 .

验证

1
2
3
docker run -itd --name nodemanager1 --network baseEnv-net nodemanager:v1 
docker exec -it nodemanager1 /bin/bash
jps

hdfs容器化部署

部署步骤

1
2
3
4
5
6
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实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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

启动

1
2
在docker-compose.yml同级目录下执行
docker-compose up

yarn容器化部署

部署步骤

1
2
3
4
5
6
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:8088),查看每个节点的运行状态。

docker-compose.yml实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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:8080
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: nodemamager: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: datanode: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: datanode: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


启动

1
2
在docker-compose.yml同级目录下执行
docker-compose up

验证

后台启动docker-compose (screen命令)

补充说明

Screen 是一款由GNU计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换。GNU Screen可以看作是窗口管理器的命令行界面版本。它提供了统一的管理多个会话的界面和相应的功能。

会话恢复

只要Screen本身没有终止,在其内部运行的会话都可以恢复。这一点对于远程登录的用户特别有用——即使网络连接中断,用户也不会失去对已经打开的命令行会话的控制。只要再次登录到主机上执行screen -r就可以恢复会话的运行。同样在暂时离开的时候,也可以执行分离命令detach,在保证里面的程序正常运行的情况下让Screen挂起(切换到后台)。这一点和图形界面下的VNC很相似。

多窗口

在Screen环境下,所有的会话都独立的运行,并拥有各自的编号、输入、输出和窗口缓存。用户可以通过快捷键在不同的窗口下切换,并可以自由的重定向各个窗口的输入和输出。Screen实现了基本的文本操作,如复制粘贴等;还提供了类似滚动条的功能,可以查看窗口状况的历史记录。窗口还可以被分区和命名,还可以监视后台窗口的活动。 会话共享 Screen可以让一个或多个用户从不同终端多次登录一个会话,并共享会话的所有特性(比如可以看到完全相同的输出)。它同时提供了窗口访问权限的机制,可以对窗口进行密码保护。

GNU’s Screen 官方站点:http://www.gnu.org/software/screen/

常用screen参数

1
2
3
4
5
screen -S yourname -> 新建一个叫yourname的session
screen -ls -> 列出当前所有的session
screen -r yourname -> 回到yourname这个session
screen -d yourname -> 远程detach某个session
screen -d -r yourname -> 结束当前session并回到yourname这个session

在每个screen session 下,所有命令都以 ctrl+a(C-a) 开始。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
C-a ? -> 显示所有键绑定信息
C-a c -> 创建一个新的运行shell的窗口并切换到该窗口
C-a n -> Next,切换到下一个 window
C-a p -> Previous,切换到前一个 window
C-a 0..9 -> 切换到第 0..9 个 window
Ctrl+a [Space] -> 由视窗0循序切换到视窗9
C-a C-a -> 在两个最近使用的 window 间切换
C-a x -> 锁住当前的 window,需用用户密码解锁
C-a d -> detach,暂时离开当前session,将目前的 screen session (可能含有多个 windows) 丢到后台执行,并会回到还没进 screen 时的状态,此时在 screen session 里,每个 window 内运行的 process (无论是前台/后台)都在继续执行,即使 logout 也不影响。
C-a z -> 把当前session放到后台执行,用 shell 的 fg 命令则可回去。
C-a w -> 显示所有窗口列表
C-a t -> time,显示当前时间,和系统的 load
C-a k -> kill window,强行关闭当前的 window
C-a -> 进入 copy mode,在 copy mode 下可以回滚、搜索、复制就像用使用 [vi 一样
C-b Backward,PageUp
C-f Forward,PageDown
H(大写) High,将光标移至左上角
L Low,将光标移至左下角
0 移到行首
$ 行末
w forward one word,以字为单位往前移
b backward one word,以字为单位往后移
Space 第一次按为标记区起点,第二次按为终点
Esc 结束 copy mode
C-a ] -> paste,把刚刚在 copy mode 选定的内容贴上

使用 screen

安装screen

流行的Linux发行版(例如Red Hat Enterprise Linux)通常会自带screen实用程序,如果没有的话,可以从GNU screen的官方网站下载。

1
2
3
4
[root@TS-DEV ~]# yum install screen
[root@TS-DEV ~]# rpm -qa|grep screen
screen-4.0.3-4.el5
[root@TS-DEV ~]#

创建一个新的窗口

安装完成后,直接敲命令screen就可以启动它。但是这样启动的screen会话没有名字,实践上推荐为每个screen会话取一个名字,方便分辨:

1
[root@TS-DEV ~]# screen -S david 

screen启动后,会创建第一个窗口,也就是窗口No. 0,并在其中打开一个系统默认的shell,一般都会是bash。所以你敲入命令screen之后,会立刻又返回到命令提示符,仿佛什么也没有发生似的,其实你已经进入Screen的世界了。当然,也可以在screen命令之后加入你喜欢的参数,使之直接打开你指定的程序,例如:

1
[root@TS-DEV ~]# screen vi david.txt

screen创建一个执行vi david.txt的单窗口会话,退出vi 将退出该窗口/会话。

应用

1
2
3
4
5
6
screen -S hdfs 	#建立一个名为hdfs的终端窗口
ctrl+a d #将当前窗口放到后台
screen -S yarn #建立一个名为yarn的终端窗口
ctrl+a d #将当前窗口放到后台
screen -R hdfs #将名为hdfs的窗口恢复
screen -R yarn #将名为yarn的窗口恢复

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
3
4
5
6
7
8
9
12.2中构建的jdk1.8:v1作为基础镜像
2)将zookeeper-3.4.12.tar.gz(可采用其他版本)复制到容器的/root目录下并解压至/root/apps目录下,为了精简镜像,需要将zookeeper-3.4.12.tar.gz删除。
3)配置Zookeeper环境变量,并定义zk_ID变量(docker-compose运行时传递参数到zk_ID,并写入到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实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
FROM ubuntu-jdk:v1

COPY files/zookeeper-3.4.12.tar.gz /root/

RUN tar -zxvf /root/zookeeper-3.4.12.tar.gz -C /root/tool/ && \
mv /root/tool/zookeeper-3.4.12 /root/tool/zookeeper && \
rm -rf /root/zookeeper-3.4.12.tar.gz && \
mkdir -p /root/data/zookeeper

ENV ZOOKEEPER_HOME=/root/tool/zookeeper
ENV PATH=$PATH:$ZOOKEEPER_HOME/bin:$PATH

VOLUME /root/data/zookeeper

EXPOSE 2181

COPY /files/conf/zoo.cfg /root/tool/zookeeper/conf/
COPY /files/conf/start-zk.sh /root/

CMD sh start-zk.sh

docker-compose

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
version: '3'
services:
zk1:
image: zookeeper:v1
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'
environment:
zk_ID: 1

zk2:
image: zookeeper:v1
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'
environment:
zk_ID: 2

zk3:
image: zookeeper:v1
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'
environment:
zk_ID: 3

networks:
zk-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.26.1.0/24

sh

1
2
3
4
5
6
7
8
9
#!/bin/bash

echo $zk_ID > /root/data/zookeeper/myid
echo $zk_ID

echo "启动zookeeper"
zkServer.sh start
echo "启动ssh服务"
/usr/sbin/sshd -D

所需命令

1
2
3
4
5
6
# 构建镜像
docker build -t zookeeper:v1 .
# compose集群启动
docker-compose up
# 查看zookeeper状态
zkServer.sh status

问题

1.myid文件的赋值

- dockerfile与docker-compose联动,生成三个镜像
  • 在dockerfile文件中声明ARG:MYID
  • 在dockerfile文件中把MYID赋值给myid文件
  • 在docker-compose文件中 新建镜像 分别赋值MYID
- docker-compose与sh联动,生成一个镜像
  • 在docker-compose文件中 声明environment:zk_ID
  • 在sh文件中赋值给myid文件

docker安装spark

什么是spark

Spark最初由美国加州伯克利大学的AMP实验室于2009年开发,Spark是一种通用的大数据计算框架,是基于RDD(弹性分布式数据集)的一种计算模型。通俗讲就是可以分布式处理大量极数据的,将大量集数据先拆分,分别进行计算,然后再将计算后的结果进行合并。

ApacheSpark的功能

快速 - 使用最先进的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-worker:v1

设计与实现思路

spark-master/worker镜像

基础步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
12.2中构建的jdk1.8:v1作为基础镜像
2)将spark-2.3.4.tar.gz(可采用其他版本)复制到容器的/root目录下并解压至/root/tool目录下,为了精简镜像,需要将spark-2.3.4.tar.gz删除。
3)配置Spark环境变量
**ARG变量复制master和worker的配置**
- dockerfile中 ARG conf_hosts
- docker-compose.yml中
- args:
conf_hosts: conf-master
4)将配置文件(指导老师讲解配置文件并提供给学生)复制的/tmp/目录下,并在/tmp/下移动到$SPARK_HOME/conf/目录中
5)创建 /root/apps/spark/logs目录(spark启动时的日志文件输出到本目录下)
6)将run.sh(启动master和historyserver服务)复制到/root下并添加执行权限
7)暴露80807077端口
8)指定容器启动时运行run.sh脚本

dockerfile实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
FROM ubuntu-jdk:v1

COPY files/spark-2.3.4.tar.gz /root/

RUN apt-get install curl -y && \
tar -zxvf /root/spark-2.3.4.tar.gz -C /root/tool/ && \
mv /root/tool/spark-2.3.4-bin-hadoop2.7 /root/tool/spark && \
rm -rf /root/spark-2.3.4.tar.gz && \
mkdir -p /root/tool/spark/logs

ENV SPARK_HOME=/root/tool/spark
ENV PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin:$PATH

ARG conf_hosts
COPY files/${conf_hosts}/conf/* /tmp/
RUN mv /tmp/spark-env.sh /root/tool/spark/conf/spark-env.sh && \
mv /tmp/spark-defaults.conf /root/tool/spark/conf/spark-defaults.conf && \
mv /tmp/slaves /root/tool/spark/slaves && \
mv /tmp/run.sh /root/run.sh

EXPOSE 8080
EXPOSE 7077

RUN chmod +x /root/run.sh

CMD ["/root/run.sh"]

docker-compose实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
version: '3'
services:
spark-master1:
build:
context: /root/00_dockerfile/04_spark
dockerfile: /root/00_dockerfile/04_spark/dockerfile
args:
conf_hosts: conf-master
container_name: spark-master1
hostname: spark-master1
restart: always
networks:
spark-network:
ipv4_address: 172.27.1.100
ports:
- 8080:8080
- 7077:7077
extra_hosts:
- 'spark-master1:172.27.1.100'
- 'spark-master2:172.27.1.101'
- 'spark-worker1:172.27.1.102'
- 'spark-worker2:172.27.1.103'
- 'spark-worker3:172.27.1.104'

spark-master2:
build:
context: /root/00_dockerfile/04_spark
dockerfile: /root/00_dockerfile/04_spark/dockerfile
args:
conf_hosts: conf-master
container_name: spark-master2
hostname: spark-master2
restart: always
networks:
spark-network:
ipv4_address: 172.27.1.101
ports:
- 8081:8080
- 7078:7077
extra_hosts:
- 'spark-master1:172.27.1.100'
- 'spark-master2:172.27.1.101'
- 'spark-worker1:172.27.1.102'
- 'spark-worker2:172.27.1.103'
- 'spark-worker3:172.27.1.104'

spark-worker2:
build:
context: /root/00_dockerfile/04_spark
dockerfile: /root/00_dockerfile/04_spark/dockerfile
args:
conf_hosts: conf-worker
container_name: spark-worker2
hostname: spark-worker2
restart: always
networks:
spark-network:
ipv4_address: 172.27.1.103
extra_hosts:
- 'spark-master1:172.27.1.100'
- 'spark-master2:172.27.1.101'
- 'spark-worker1:172.27.1.102'
- 'spark-worker2:172.27.1.103'
- 'spark-worker3:172.27.1.104'

spark-worker1:
build:
context: /root/00_dockerfile/04_spark
dockerfile: /root/00_dockerfile/04_spark/dockerfile
args:
conf_hosts: conf-worker
container_name: spark-worker1
hostname: spark-worker1
restart: always
networks:
spark-network:
ipv4_address: 172.27.1.102
extra_hosts:
- 'spark-master1:172.27.1.100'
- 'spark-master2:172.27.1.101'
- 'spark-worker1:172.27.1.102'
- 'spark-worker2:172.27.1.103'
- 'spark-worker3:172.27.1.104'

spark-worker3:
build:
context: /root/00_dockerfile/04_spark
dockerfile: /root/00_dockerfile/04_spark/dockerfile
args:
conf_hosts: conf-worker
container_name: spark-worker3
hostname: spark-worker3
restart: always
networks:
spark-network:
ipv4_address: 172.27.1.104
extra_hosts:
- 'spark-master1:172.27.1.100'
- 'spark-master2:172.27.1.101'
- 'spark-worker1:172.27.1.102'
- 'spark-worker2:172.27.1.103'
- 'spark-worker3:172.27.1.104'


networks:
spark-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.27.1.0/24

问题

- 端口占用问题

  • 原因:
    • docker-compose.yml中 master1和master2重复开放了8080和7077端口
  • 解决:
    • master2开放8081和7078

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!