Docker入门教程2
Docker入门教程2
镜像高级操作
本章在第4章的基础上, 介绍镜像高级操作
创建镜像
创建镜像的方法主要有2种:
- 基于已有容器创建。
- 基于Dockerfile文件创建
基于已有容器创建
docker commit -m 'add new file : a.txt' -a 'daydayup' 9fa new_centos:1.0
说明:
- -m 提交信息
- -a 作者
- 9fa 旧有的容器
- new_centos:1.0 新的镜像
基于Dockerfile 创建
基于 Dockerfile 创建是最常见的方式。 Dockerfile 是一个文本文件, 利用给定的指令描述基于某个父镜像创建新镜像的过程。
下面使用Dockerfile创建一个基于centos的java开发环境:
- 把jdk安装转包copy到 /home/daydayup 目录下
cd ~
cp jdk-8u212-linux-x64.tar.gz ./
- 在/home/daydayup上创建Dockerfile文件 (-p 父目录)
vim Dockerfile
FROM centos:7.5.1804
RUN mkdir -p /opt/software
RUN mkdir -p /opt/module
COPY jdk-8u212-linux-x64.tar.gz /opt/software/
RUN tar -zxvf /opt/software/jdk-8u212-linux-x64.tar.gz -C /opt/module
RUN rm -rf /opt/software/jdk-8u212-linux-x64.tar.gz
ENV JAVA_HOME=/opt/module/jdk1.8.0_212
ENV PATH=$JAVA_HOME/bin:$PATH
说明:
- 每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
- 第一条FROM,指定使用哪个镜像源
- RUN 指令告诉docker 在镜像内执行命令,安装了什么。。。
- COPY 是把文件copy到镜像中. 源文件必须是相对路径不能是绝对路径
- ENV 在镜像中设置环境变量
- 创建镜像, 并等待创建成功
docker build -t centos_java8:1.0 .
说明:
- -t 指明镜像名字和标签
- . 表示Dockfile所在目录
- 测试镜像是否可以正常工作
docker run centos_java8:1.0 java -version
保存和加载镜像
使用保存和加载功能可以把本机的镜像发给其他人使用
保存镜像
docker save -o daydayup_centos_java8.tar centos_java8:1.0
加载镜像
把刚刚保存的镜像发给别人(hadoop103), 然后加载导入.
docker load -i daydayup_centos_java8.tar
为镜像添加ssh服务
很多镜像是不带ssh服务的, 管理镜像非常的不方便, 本章介绍如何给镜像添加ssh服务
创建镜像
# 设置继承镜像
FROM centos_java8:1.0
# 提供作者信息
MAINTAINER daydayup_lzc (lizhenchao@daydayup.com)
# 更换国内阿里云yum源
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
RUN sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
RUN yum makecache
# 安装sshd
RUN yum install -y openssh-server openssh-clients
RUN sed -i '/^HostKey/'d /etc/ssh/sshd_config
RUN echo 'HostKey /etc/ssh/ssh_host_rsa_key'>>/etc/ssh/sshd_config
# 生成 ssh-key
RUN ssh-keygen -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key
# 更改 root 用户登录密码为
RUN echo 'root:aaaaaa' | chpasswd
# 开放 22 端口
EXPOSE 22
# 镜像运行时启动sshd
RUN mkdir -p /opt
RUN echo '#!/bin/bash' >> /opt/run.sh
RUN echo '/usr/sbin/sshd -D' >> /opt/run.sh
RUN chmod +x /opt/run.sh
CMD ["/opt/run.sh"]
- 构建
docker build -t centos_java8_sshd:1.0 ./
运行容器, 测试镜像
docker run -d -p 2222:22 centos_java8_sshd:1.0
说明: 把容器的22端口映射到宿主机器的2222端口, 这样通过ssh连接宿主机器的2222端口就可以连接到容器了.
ssh root@192.168.14.112 -p 2222
端口映射与容器互联
端口映射
在启动容器的时候,如果不指定对应参数,在容器外部是无法通过网络来访问容器内的 网络应用和服务的。
使用 -p 来指定映射规则: 3000:22 表示宿主的3000映射到容器的22端口, 使用多次 -p 可以映射多个端口.
docker run -d -p 2222:22 -p 8888:80 centos_java8_sshd:1.0
查看容器端口绑定情况:
docker port 9b2e0f3478ff
容器互相访问
端口映射并不是唯一把 docker 连接到另一个容器的方法。
docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。
docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息。
容器命名
创建容器的时候, Docker会自动为容器分配一个随机的名字.我们也可以指定一个好记的名字, 方便容器间的互联.
docker run -d --name hadoop102 centos_java8_sshd:1.0
说明:
- --name 参数给容器起一个名字
docker的网络
docker还会给我们创建三个网络:bridge/host/none。我们可以通过network ls命令查看当前宿主机中所有的docker网络。
其中,网桥bridge模式是在实际项目中常用的。接下来,以交互模式启动两个centos_java8_sshd 容器。在没有指定相关网络的情况下,容器都会连接到默认的bridge网络.
创建两个容器: hadoo102和hadoop103, 检查bridge网络情况. 可以看到他们的ip地址.
docker run -d --name hadoop102 centos_java8_sshd:1.0
docker run -d --name hadoop103 centos_java8_sshd:1.0
docker network inspect bridge
注意:
- 通过ip地址我们在宿主机或者容器之间可以访问到对方
- 当是172.17.0.2 等这些ip地址不能固定, 每次启动容器的时候有可能会变化, 如果组建集群的话很不方便.
自定义bridge网络, 实现容器间通讯
docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过“容器名”通信。使用默认的bridge网络,不能通过DNS server实现通过容器名通信,但是使用自定义bridge网络可以做到通过容器名互相通信。
- 创建自定义bridge网络, 网络名daydayup
docker network create --driver bridge daydayup
- 删除hadoop102和hadoop103容器
docker rm -f hadoop102
docker rm -f hadoop103
- 新建并启动hadoop102和hadoop103容器, 并加入到daydayup网络
docker run -d --name daydayup102 --network daydayup centos_java8_sshd:1.0
docker run -d --name daydayup103 --network daydayup centos_java8_sshd:1.0
- 进入daydayup102, 测试是否可以ping通daydayup103
教学模式下网络搭建
为了节省资源, 假设我们所有容器都在hadoop102主机创建和启动, 则我们必须满足下面的网络互通情况:
目前情况:
- windows系统和hadoop102互通已经完成
- 容器和hadoop102也可以互相访问
- 容器间也可以自由访问
- 容器访问windows访问不到!!!
- windows访问容器也访问不到, 但是可以通过端口映射解决.(如果端口过多, 映射不方便)
- 容器ip地址最好还是固定的
如何解决前面网络不通的情况?
让容器使用桥接模式(vmware中的桥接), 与hadoop102处于同一个网段就可以解决了. 使用pipework工具可以满足我们的需求!
安装pipwork和brctl工具
- 在宿主(hadoop102)上安装git(如果已经安装, 跳过该步骤)
sudo yum install -y git
- 下载pipework
git clone https://github.com/jpetazzo/pipework.git
- 把pipework脚本添加到path中
sudo cp pipework/pipework /usr/bin/
- 安装brctl工具
sudo yum install bridge-utils
配置网络
删除原来的容器: daydayup102和daydayup103
docker rm -f $(docker ps -aq) # 删除所有容器, 慎用!!!
- 在宿主机上实现桥接网络
我的宿主机信息:
eth0: 192.168.14.112
网关: 192.168.14.1
DNS: 114.114.114.114
在宿主机上(hadoop102)执行如下命令:
sudo brctl addbr br0; \
sudo ip link set dev br0 up; \
sudo ip addr del 192.168.14.112/24 dev eth0 ; \
sudo ip addr add 192.168.14.112/24 dev br0 ; \
sudo brctl addif br0 eth0 ; \
sudo ip route add default via 192.168.14.1 dev br0
说明:
- sudo brctl addbr br0; 添加网桥 br0
- sudo ip link set dev br0 up 启动网桥br0
- sudo ip addr del 192.168.14.112/24 dev eth0 ; 给eth0去掉ip, 如果是ens33需要换成ens33
- sudo ip addr add 192.168.14.112/24 dev br0 ; 给网桥分配ip(就使用刚才eth0去掉的ip)
- sudo brctl addif br0 eth0 ; 把eth0 搭在br0上
- sudo ip route add default via 192.168.14.1 dev br0 给br0添加新的路由(根据虚拟机网关自己指定)
- 需要注意中间会断网, 所以需要放置在一条语句执行
- 创建两个容器
docker run -d --name daydayup202 centos_java8_sshd:1.0
docker run -d --name daydayup203 centos_java8_sshd:1.0
- 给两个容器添加ip,并搭在br0上
sudo pipework br0 daydayup202 192.168.14.202/24@192.168.14.1
sudo pipework br0 daydayup203 192.168.14.203/24@192.168.14.1
说明:
- br0网桥名
- daydayup202 容器名
- 192.168.14.202/24 容器ip 24是指的掩码
- 192.168.14.1 网关地址(根据自己的虚拟机来实际指定)
测试网络是否OK
进入 daydayup202
ssh root@192.168.14.202
最后说明
我们前面的网桥搭建方案和容器ip分配方案都是临时临时生效, 当虚拟机重启或者容器重启之后会失效, 可以放入脚本中, 统一执行.故每次启动容器需要执行此命令。
vim /home/daydayup/bin/docker.sh
# 启动容器
docker start daydayup202
docker start daydayup203
# 搭建网桥
sudo brctl addbr br0; \
sudo ip link set dev br0 up; \
sudo ip addr del 192.168.14.112/24 dev eth0 ; \
sudo ip addr add 192.168.14.112/24 dev br0 ; \
sudo brctl addif br0 eth0 ; \
sudo ip route add default via 192.168.14.1 dev br0
sleep 5
# 给容器配置ip和网关
sudo pipework br0 daydayup202 192.168.14.202/24@192.168.14.1
sudo pipework br0 daydayup203 192.168.14.203/24@192.168.14.1
使用docker搭建集群
理论上来说, 每个容器应该只运行一个应用, 但是考虑到实际情况, 我们仍然采用前面学习的虚拟机中集权搭建方案, 用一个容器替换原来的一个虚拟机.
在3个容器中运行原来所有的集群分布式方案.
集群规划
我们集群需要3台虚拟机, 每台虚拟机配置略有不同, 我们只做3个镜像, 每个镜像对应集群中一台虚拟机
准备工作
把所有需要用的文件提前准备好.
制作镜像和创建容器
各个Dockerfile文件和脚本具体内容见清单
手动启动Docker服务:sudo systemctl start docker
开机自启Docker服务sudo systemctl enable docker.service
如果设置开机自启contains.sh脚本 的start命令 可以添加如下操作:
1、增加rc.local可执行权限
chmod +x /etc/rc.d/rc.local
2、在里面添加命令即可
sudo vim /etc/rc.d/rc.local
bash /home/daydayup/docker_images/docker_bigdata/contains.sh start
如果需要每次点开会话窗口都能直接到Hadoop162可以直接创建新的Hadoop162会话
详细说明参考: Readme.md
测试镜像
容器集群启动成功之后, 使用ssh登录.
像在虚拟机中操作一样进行操作就可以了
但是需要注意的是, 容器中用到的一些工具没有了, 如果使用, 可以在制作镜像的时候安装好, 也可以启动容器之后安装