Docker 数据管理与网络通信
一、Docker 镜像的创建
1.基于已有镜像创建
2.基于本地模板创建
3.基于 Dockerfile 创建
二、Docker的数据管理
1.数据卷
1)创建数据卷
2)挂载主机目录作为数据卷
2.数据卷容器
三、Docker的网络通信
1.端口映射
2.容器互联
准备工作:
- 实验所需软件包从这个连接下载:https://pan.baidu.com/s/1CgMBAnFJbrEckyLPe6rmaw
- 提取码:8qf2
安装 Docker 服务:
[root@Docker ~]# ls anaconda-ks.cfg centos7 docker-18.03.1-ce.tgz [root@Docker ~]# tar xf docker-18.03.1-ce.tgz [root@Docker ~]# cp docker/* /usr/bin/ [root@Docker ~]# dockerd &
载入 centos7 镜像:
[root@Docker ~]# docker load < centos7 f972d139738d: Loading layer 208.8MB/208.8MB Loaded image: centos:latest
一、Docker 镜像的创建
Docker 镜像除了是 Docker 的核心技术之外也是应用发布的标准格式。一个完整的 Docker 镜像可以支撑一个 Docker 容器的运行。
- 创建镜像的三种方法:基于已有镜像创建、基于本地模板创建、基于 Dockerfile 创建。
1.基于已有镜像创建
主要使用 docker commit 命令,其实质就是把一个容器里面运行的程序及该程序的运行环境打包起来生成新的镜像。
- 命令格式:docker commit [选项] 容器ID/名称 仓库名称:[标签]
常用选项:
- -m:说明信息
- -a:作者信息
- -p:生成过程中停止容器的运行
1)创建一个容器,并启用
[root@Docker ~]# docker create -it --name www centos:latest /bin/bash [root@Docker ~]# docker start www [root@Docker ~]# docker ps | grep www #如果不显示表示没有启动成功
2)使用 docker commit 命令创建一个新的镜像
[root@Docker ~]# docker commit -m "Hello" -a "zhangsan" www docker:mycentos [root@Docker ~]# docker images | grep docker
2.基于本地模板创建
- 通过导入操作系统模块文件可以生成镜像,模板可以从 OPENVZ 开源项目 下载。
下面介绍的是 ubuntu 模板压缩包,将下载好的压缩包拖入:
[root@Docker ~]# ls anaconda-ks.cfg centos7 docker docker-18.03.1-ce.tgz ubuntu-12.04-x86-minimal.tar.gz [root@Docker ~]# cat ubuntu-12.04-x86-minimal.tar.gz | docker import - ubuntu:v12 [root@Docker ~]# docker images | grep ubuntu
3.基于 Dockerfile 创建
Dockerfile 是由一组指令组成的文件,其中每条指令对应 Linux 中的一条命令,Docker 程序将读取 Dockerfile 中的指令生成指定镜像。Dockerfile 结构大致分为四个部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。
Dockerfile 每行支持一条指令,每条指令可携带多个参数,支持使用以 # 号开头的注释。
在编写 Dockerfile 时,有严格的格式要遵循:
- 第一行必须使用 FROM 指令指明所基于的镜像;
- 之后使用 MAINTAINER 指令说明维护该镜像的作者信息;
- 然后是镜像操作相关指令,如 RUN 指令;
- 最后使用 CMD 指令来指定容器要运行的命令操作。
常用的 Dockerfile 操作指令:
1)创建 Apache 镜像
[root@Docker ~]# yum -y install httpd && systemctl start httpd [root@Docker ~]# cd /var/www/html/ [root@Docker html]# mkdir centos7 [root@Docker html]# mount /dev/cdrom centos7/
使用浏览器访问测试:
2)建立工作目录
[root@Docker html]# cd /root/ [root@Docker ~]# mkdir apache [root@Docker ~]# cd apache/ [root@Docker apache]# vim Dockerfile # 基于 CentOS 基础镜像 FROM centos # 作者信息 MAINTAINER The zhangsan # 删除无用文件 RUN rm -rf /etc/yum.repos.d/* # 上传新的文件到镜像目录 (这个 .repo 文件要和 Dockerfile 文件位于同一个目录) ADD CentOS7.repo /etc/yum.repos.d/ # 安装 Apache 服务 RUN yum -y install httpd # 开启 80 端口 EXPOSE 80 # 复制网址首页到镜像中 ADD index.html /var/www/html/ # 将启动脚本复制到镜像中 ADD run.sh / RUN chmod 755 /run.sh # 配置 Apache 服务开机自启 RUN systemctl enable httpd # 启动容器时执行脚本 CMD ["/run.sh"]
3)创建 .repo 文件
[root@Docker apache]# cat <<END > CentOS7.repo [zhangsan] name=zhangsan baseurl=http://192.168.1.1/centos7 enabled=1 gpgcheck=0 END
4)编写执行脚本内容
[root@Docker apache]# vim run.sh #!/bin/bash rm -rf /run/httpd/* # 清理 HTTP 缓存 exec /usr/sbin/apachectl -D FOREGROUND # 启用 Apache 服务
5)创建测试页面
[root@Docker apache]# echo "This is beijing" > index.html [root@Docker apache]# ls CentOS7.repo Dockerfile index.html run.sh
6)使用 Dockerfile 生成镜像
- -t 表示生成新的镜像 名字: 标签
[root@Docker apache]# docker build -t httpd:centos . [root@Docker apache]# docker images | grep httpd
7)使用新的镜像运行容器
[root@Docker ~]# docker run -d -p 888:80 --name mmm httpd:centos [root@Docker ~]# docker ps | grep mmm
8)访问容器中的网页测试
二、Docker的数据管理
在Docker中,为了方便查看容器内产生的数据或者将多个容器中的数据实现共享,就是涉及到容器的数据管理操作。
- 主要有两种方式:数据卷(Data Volumes)和数据卷容器(Data Volumes Containers)。
1.数据卷
数据卷是一个供容器使用的特殊目录,位于容器中,可将宿主机的目录挂载到数据卷上,对数据卷的修改操作立刻可见,并且更新数据不会影响镜像,从而实现数据在宿主机与容器之间的迁移。数据卷的使用类似 Linux 下对目录进行 mount 操作。
1)创建数据卷
[root@Docker ~]# docker run -itd -v /data1 -v /data2 --name web1 centos:latest [root@Docker ~]# docker ps | grep web1 [root@Docker ~]# docker exec -it web1 /bin/bash [root@941a16b013ae /]# ls
- 注意:上面这种创建方式只是创建数据卷,只可以实现宿主机的容量,给容器使用,还不可以实现数据通信。
2)挂载主机目录作为数据卷
- 使用 -v 选项可以在创建数据卷同时,将宿主机的目录挂载到数据卷上使用,以实现宿主机与容器之间的数据迁移;
- 宿主机的本地路径必须为绝对路径,如果路径不存在,则会在本地自动创建。
创建一个新的容器 web2 ,将宿主机的 /www 目录挂载到容器的 /data1 目录上:
[root@Docker ~]# docker run -itd -v /www:/data1 --name web2 centos:latest [root@Docker ~]# docker ps | grep web2
在宿主机的 /www 的目录下,创建几个文件,并进入容器中查看:
[root@Docker ~]# cd /www/ [root@Docker www]# touch test{1..5}.txt [root@Docker www]# ls
进入容器查看:
[root@Docker www]# docker exec -it web2 /bin/bash [root@c2581b676431 /]# cd /data1/ [root@c2581b676431 data1]# ls
2.数据卷容器
如果需要在容器之间共享一些数据,最简单的方法就是使用数据卷容器。数据卷容器就是一个普通的容器,专门提供数据卷给其他容器挂载使用。
- 使用方法:首先,需要创建一个容器作为数据卷容器,之后在其他容器创建时用 --volumes-from 挂载数据卷容器中的数据卷使用。
- 注意:这里使用预先创建好的数据卷容器 web1 ,就是刚刚创建的名字为 web1 的容器。
web1 容器中创建的数据卷是 /data1 与 /data2;把这两个数据卷挂载到新的容器 db1 当中:
[root@Docker ~]# docker run -itd --volumes-from web1 --name db1 centos:latest [root@Docker ~]# docker ps | grep db1 [root@Docker ~]# docker exec -it db1 /bin/bash [root@37f24ebbdc0b /]# cd /data1/ [root@37f24ebbdc0b data1]# ls [root@37f24ebbdc0b data1]# touch zhangsan{1..3}.txt [root@37f24ebbdc0b data1]# ls zhangsan1.txt zhangsan2.txt zhangsan3.txt [root@37f24ebbdc0b data1]# exit exit [root@Docker ~]# docker exec -it web1 /bin/bash [root@941a16b013ae /]# cd /data1/ [root@941a16b013ae data1]# ls zhangsan1.txt zhangsan2.txt zhangsan3.txt
三、Docker的网络通信
- Docker 提供了映射容器端口到宿主机和容器互联机制来为容器提供网络服务。
1.端口映射
在启动容器的时候,如果不指定对应的端口,在容器外将无法通过网络来访问容器内的服务。
Docker 提供端口映射机制来将容器内的服务提供给外部网络访问,实质上就是将宿主 主机的端口映射到容器中,使得外部网络访问宿主机的端口便可访问容器内的服务。
实现端口映射,使用 run 命令 -P(大写) 命令实现随机映射,Docker 会随机映射宿主机端口范围在 49000~49900 的端口,到容器内部所有开发的网络端口,但范围也不是绝对的。
[root@Docker ~]# docker run -d --name Web1 -P httpd:centos [root@Docker ~]# docker ps | grep Web1
在运行 docker run 命令使用小写 p 可以指定要映射的端口:
[root@Docker ~]# docker run -d --name Web1 -P httpd:centos [root@Docker ~]# docker ps | grep Web1
- 注意:-P 选项会自动映射容器中所有的端口,而 -p 需要一个一个的指定。
现在使用浏览器访问宿主机 IP 加上刚才转化的端口即可访问到容器的 80 端口:
2.容器互联
- 容器互联是通过容器的名称在容器间建立一条专门的网络通信隧道从而实现容器的互联。
- 简单点说,就是会在源容器和接收容器之间建立一条隧道,接收容器可以看到源容器指定的信息。
在运行 docker run 命令使用 --link 选项实现容器之间的互联通信:
- 命令格式: --link name: alias :name 是要连接的容器名称(此名称有唯一性),alias 是这个连接的别名。
1)创建源容器 Apache1
[root@Docker ~]# docker run -itd --name Apache1 centos:latest [root@Docker ~]# docker ps | grep Apache1
2)创建接受容器 Apache2
[root@Docker ~]# docker run -itd --name Apache2 --link Apache1:zhangsan centos:latest [root@Docker ~]# docker ps | grep Apache2 [root@Docker ~]# docker exec -it Apache2 /bin/bash [root@d2ce248898ab /]# ping -c 2 Apache1 [root@d2ce248898ab /]# ping -c 2 zhangsan
- 此时,接收容器和源容器已经建立互联关系,是一个安全隧道,不暴露端口到宿主机,从而避免了暴露端口到外部网络;
- 但是,在 Apache1 中是 ping 不通 Apache2 因为只有接收容器,可以主动发起连接。