Docker入门教程2

Docker入门教程2

镜像高级操作

本章在第4章的基础上, 介绍镜像高级操作

创建镜像

创建镜像的方法主要有2种:

  • 基于已有容器创建。
  • 基于Dockerfile文件创建

基于已有容器创建

docker commit -m 'add new file : a.txt' -a 'daydayup' 9fa new_centos:1.0

说明:

  1. -m 提交信息
  2. -a 作者
  3. 9fa 旧有的容器
  4. new_centos:1.0 新的镜像

基于Dockerfile 创建

基于 Dockerfile 创建是最常见的方式。 Dockerfile 是一个文本文件, 利用给定的指令描述基于某个父镜像创建新镜像的过程。

下面使用Dockerfile创建一个基于centos的java开发环境:

  1. 把jdk安装转包copy到 /home/daydayup 目录下

cd ~

cp jdk-8u212-linux-x64.tar.gz ./

  1. 在/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 在镜像中设置环境变量
  1. 创建镜像, 并等待创建成功

docker build -t centos_java8:1.0 .

说明:

  1. -t 指明镜像名字和标签
  2. . 表示Dockfile所在目录
  3. 测试镜像是否可以正常工作

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服务

创建镜像

  • Dockerfile:

# 设置继承镜像

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

注意:

  1. 通过ip地址我们在宿主机或者容器之间可以访问到对方

  1. 当是172.17.0.2 等这些ip地址不能固定, 每次启动容器的时候有可能会变化, 如果组建集群的话很不方便.

自定义bridge网络, 实现容器间通讯

docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过“容器名”通信。使用默认的bridge网络,不能通过DNS server实现通过容器名通信,但是使用自定义bridge网络可以做到通过容器名互相通信。

  1. 创建自定义bridge网络, 网络名daydayup

docker network create --driver bridge daydayup

  1. 删除hadoop102和hadoop103容器

docker rm -f hadoop102

docker rm -f hadoop103

  1. 新建并启动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

  1. 进入daydayup102, 测试是否可以ping通daydayup103

教学模式下网络搭建

为了节省资源, 假设我们所有容器都在hadoop102主机创建和启动, 则我们必须满足下面的网络互通情况:

目前情况:

  1. windows系统和hadoop102互通已经完成
  2. 容器和hadoop102也可以互相访问
  3. 容器间也可以自由访问
  4. 容器访问windows访问不到!!!
  5. windows访问容器也访问不到, 但是可以通过端口映射解决.(如果端口过多, 映射不方便)
  6. 容器ip地址最好还是固定的

如何解决前面网络不通的情况?

让容器使用桥接模式(vmware中的桥接), 与hadoop102处于同一个网段就可以解决了. 使用pipework工具可以满足我们的需求!

安装pipwork和brctl工具

  1. 在宿主(hadoop102)上安装git(如果已经安装, 跳过该步骤)

sudo yum install -y git

  1. 下载pipework

git clone https://github.com/jpetazzo/pipework.git

  1. 把pipework脚本添加到path中

sudo cp pipework/pipework /usr/bin/

  1. 安装brctl工具

sudo yum install bridge-utils

配置网络

删除原来的容器: daydayup102和daydayup103

docker rm -f $(docker ps -aq) # 删除所有容器, 慎用!!!

  1. 在宿主机上实现桥接网络

我的宿主机信息:

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

说明:

  1. sudo brctl addbr br0; 添加网桥 br0
  2. sudo ip link set dev br0 up 启动网桥br0
  3. sudo ip addr del 192.168.14.112/24 dev eth0 ; 给eth0去掉ip, 如果是ens33需要换成ens33
  4. sudo ip addr add 192.168.14.112/24 dev br0 ; 给网桥分配ip(就使用刚才eth0去掉的ip)
  5. sudo brctl addif br0 eth0 ; 把eth0 搭在br0上
  6. sudo ip route add default via 192.168.14.1 dev br0 给br0添加新的路由(根据虚拟机网关自己指定)
  7. 需要注意中间会断网, 所以需要放置在一条语句执行

  1. 创建两个容器

docker run -d --name daydayup202 centos_java8_sshd:1.0

docker run -d --name daydayup203 centos_java8_sshd:1.0

  1. 给两个容器添加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

说明:

  1. br0网桥名
  2. daydayup202 容器名
  3. 192.168.14.202/24 容器ip 24是指的掩码
  4. 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

  • 执行脚本:build_all.sh 根据提示构建需要的镜像和容器
  • 执行脚本: contains.sh start启动容器 每次启动容器后 ssh相应容器即可正常操作使用

如果设置开机自启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登录.

像在虚拟机中操作一样进行操作就可以了

但是需要注意的是, 容器中用到的一些工具没有了, 如果使用, 可以在制作镜像的时候安装好, 也可以启动容器之后安装

posted @ 2023-02-07 20:27  LEEPINE  阅读(47)  评论(0编辑  收藏  举报