实验材料,一台centos7是宿主机
内存 2G 就OK IP 192.168.100.102
首先安装 docker服务并托入基础镜像centos7,并 load 载入
我这里是类似绿色版的docker直接使用,安装方法参考我下面这篇博客前面
https://blog.csdn.net/weixin_45308292/article/details/103177112
Docker镜像的创建方法
在Docker使用过程中,进入一个已经定型的容器之后,就可以在容器中操作
,
如果在容器中安装了服务,要把已经安装的服务进行迁移,就需要把环境及搭建的服务生产新的镜像
创建镜像的方法有3种,后面我会依次介绍
1.基于已有镜像创建
主要使用 docker commit 命令 ,实质就是把一个容器运行的程序以环境
打包,生产新的镜像
命令格式
docker commit [选项] 容器ID/名称 仓库名称:[标签]
常用选择
-m: 说明信息
-a: 作者信息
-p:生产过程中停止容器运行
1)创建一个镜像www,并启动
[root@CentOS7-02 ~]# docker create -it --name www centos:latest /bin/bash
9d8b80b1027ecc76c2353ef79f7496ded8d3b1a5f8fb0e6bcfda9a9d015cf946
[root@CentOS7-02 ~]# docker start www
[root@CentOS7-02 ~]# docker ps | grep www
9d8b80b1027e centos:latest "/bin/bash" 11 seconds ago Up 6 seconds www
2)使用docker commit命令创建一个新的镜像
[root@CentOS7-02 ~]# docker commit -m "nihao"
-a "ajbn"
www docker:mycentos
( - m解释 -a 作者信息 :可以随意写, www是 原来的镜像名称 ,
docker: mycentos 是创建的新镜像)
3)这就是一个新的镜像,包含刚刚镜像的环境等
[root@CentOS7-02 ~]# docker images | grep docker
docker mycentos 6ad670cfb719 15 seconds ago 200MB
2.基于本地模板创建
通过导入操作系统模板文件可以生产镜像 ,下面介绍ubuntu模板压缩包
将下载好的压缩包拖入
3.基于Dockerfile创建
(这个是重点)
除了手动生成Docker镜像之外,可以使用Dockerfile自动生成镜像
Docokerfile是由一组指令组成的文件,其中每条指令对应Linux中一条命令
,
Dockerfile程序将读取Dockerfile中的指令生成指定镜像
在编写Dockerfile时,有严格的格式要遵循:
第一行必须使用FROM指令指明所基于的镜像
之后使用MAINTAINER指令说明维护该镜像的作者信息
然后是镜像操作相关指令,如RUN指令,
最后使用CMD指令来指定容器要运行的命令操作
介绍一下本例要用的Dockerfile操作命令
FROM 镜像
指定新镜像所基于的镜像,第一条命令必须为FROM指令,每创建一个镜像就需要一条FROM指令
MAINTAINER 名字
说明新镜像的维护人信息
RUN 命令
在所基于的镜像上执行的命令,并提交到新的镜像中
CMD [“要运行的程序”,“参数1”,“参数2”]
指定启动容器时要运行的命令,Dockerfile只能有一条CMD命令,如果指定多条则只能最后一条被执行
EXPOSE 端口号
指定新镜像加载到Docker时要开启的端口
ADD 源文件/目录目标文件/目录
将源文件复制到目标文件,源文件要和Dockerfile位于相同目录中,或者是一个URL
创建一个新的镜像apache,使用YUM安装好apache服务并设置开机自启
1)宿主机使用http方式发布YUM仓库
因为镜像中不存在yum仓库,需要使用宿主机的yum仓库
[root@CentOS7-02 ~]# yum -y install httpd && systemctl start httpd
(在宿主机中安装 httpd并启动)
[root@CentOS7-02 apache]# cd /var/www/html/ (访问的默认路径)
[root@CentOS7-02 html]# ls
[root@CentOS7-02 html]# mkdir centos7
[root@CentOS7-02 html]# mount /dev/cdrom centos7/
(将光盘挂载到 centos7目录下)
浏览器访问测试,注意看图
2)建立工作目录
[root@CentOS7-02 html]# cd /root/
[root@CentOS7-02 ~]# mkdir apache
3)创建Dockerfile文件
[root@CentOS7-02 ~]# cd apache/
[root@CentOS7-02 apache]# vim Dockerfile
(按照我图下打,我后面有打好的,你可以直接复制 #的行是注释)
#基于的基础镜像centos 就是上面实验的基础镜像
FROM centos
#维护该镜像的用户信息,随意写就行
MAINTAINER The ajbn
#镜像中有许多无用.repo文件,将它们删除,
RUN rm -rf /etc/yum.repos.d/*
#把新的.repo文件上传到镜像当中目录中, 这个.repo文件要和Dockerfile文件位于
#同一个目录,一会去准备
ADD centOS7.repo /etc/yum.repos.d/
#在镜像安装httpd服务
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"]
4)创建.repo文件
[root@CentOS7-02 apache]# pwd
/root/apache
[root@CentOS7-02 apache]# cp /etc/yum.repos.d/centOS7.repo /root/apache/
(复制本地YUM源文件,到当前目录,你们的本地YUM源文件名称要改成和我上面一样,再复制过来)
[root@CentOS7-02 apache]#vim centOS7.repo (改成我如下)
[local]
name=centos7
baseurl=http://192.168.100.102/centos7
enabled=1
gpgcheck=0
5)编写执行脚本内容,
就是刚刚文件中的run.sh
[root@CentOS7-02 apache]# pwd
/root/apache
[root@CentOS7-02 apache]# vim run.sh
#!/bin/bash
rm -rf /run/httpd/*
#清理httpd缓存
exec /usr/sbin/apachectl -D FOREGROUND
#启动apache服务
6)创建测试页面
[root@CentOS7-02 apache]# echo "A J B N"
> index.html
[root@CentOS7-02 apache]# ls
centOS7.repo Dockerfile index.html run.sh
(应该包含了刚刚的Dockerfile中写的,所有文件)
7)使用Dockerfile生成镜像
[root@CentOS7-02 apache]# docker build -t httpd:centos .
( . 表示镜像存放路径为当前路径,不要忘了写不然会报错)
(-t 表示生成新的镜像 名字: 标签)
[root@CentOS7-02 apache]# docker images | grep httpd
httpd centos ce31c48b3340 14 minutes ago 274MB
8)使用新的镜像运行容器
创建一个新的容器 www2 基于上面http:centos的镜像
[root@CentOS7-02 ~]# docker run -d -p 12345:80 --name www2 httpd:centos
c96d0646ec38722a45117659e9df516687639524b0304e1febec293492bf9ba3
(因为容器中的80端口和本地的80端口会冲突
所以把宿主机的 12345端口映射到容器中的80端口)
有时候会出现下面这个报错,
WARNING: IPv4 forwarding is disabled. Networking will not work.
必须在如下配置文件添加一行配置,不然会出错
[root@CentOS7-02 apache]# vim /usr/lib/sysctl.d/00-system.conf
net.ipv4.ip_forward = 1
[root@CentOS7-02 apache]# systemctl restart network
(之后就可以正常访问了)
9) 访问容器中的网页测试
Docker的数据管理
在Docker中,为了方便查看容器内产生的数据或者将多个容器之间的数据共享
管理Docker容器中的数据主要有两种方式:数据卷 和 数据卷容器
数据卷
数据卷是一个供容器使用的特殊目录,位于容器中,可将宿主机的目录挂载到数据卷中, 对数据卷即可做任何操作,且不会影响镜像
从何实现数据在宿主机与容器之间的数据迁移,数据卷的使用类似 linux中的mount操作
1.创建数据卷
[root@CentOS7-02 apache]# docker run -d -v /data1 -v /data2 --name web centos:latest /bin/bash -c "while true;do echo ok;done;"
bdc09d612f9e35f9b25d799b25d03d42e1ebb4a80c65e44ab9d8867881e1fad8
(因为运行的程序不可以结束,要不容器就会关闭,start 也没用有 解释一下-c 中命令的意思,就是一直循环输出 “echo ok” , 但是不会在容器的命令行输出 所以不影响,但是一定要加这个命令容器才会在后台一直启动)
[root@CentOS7-02 apache]# docker ps | grep web
bdc09d612f9e centos:latest "/bin/bash -c 'while…" 6 minutes ago Up 6 minutes web
[root@CentOS7-02 apache]# docker exec -it web /bin/bash
[root@bdc09d612f9e /]# ls (注意看下图)
exit命令退出容器
(上这种创建方式只是创建数据卷,只可以实现宿主机的容量,给容器使用,还不可以实现数据通信)
2.挂载主机目录作为数据卷
使用 -v 选项可以在创建数据卷同时,将宿主机的目录挂载到数据卷上使用,以实现宿主机与容器之间的数据迁移
宿主机的本地路径必须为绝对路径,如果路径不存在,则会自动在本地创建
创建一个新的容器web-1 ,将宿主机的/www 挂载到容器的 /data1 目录上
(容器中的/data1也会自动创建)
[root@CentOS7-02 ~]# docker run -d -v /www:/data1 --name web-1 centos:latest /bin/bash -c "while true;do echo ok;done;"
[root@CentOS7-02 ~]# docker ps | grep web-1
284e2e073f95 centos:latest "/bin/bash -c 'while…" 4 minutes ago Up 4 minutes web-1
在宿主机的/www的目录下,创建几个文件,进入容器中查看
[root@CentOS7-02 ~]# cd /www/
[root@CentOS7-02 www]# mkdir www
[root@CentOS7-02 www]# touch 111
[root@CentOS7-02 www]# ls
111 www
进入容器的 data1 中目录查看
[root@CentOS7-02 www]# docker exec -it web-1 /bin/bash
[root@284e2e073f95 /]# cd /data1/
[root@284e2e073f95 data1]# ls
111 www
#已经同步过来了
[root@284e2e073f95 data1]# exit
(相反在容器中创建,宿主机中也会同步)
数据卷容器
如果需要在容器之间共享一些数据,最简单的方法就是使用数据卷容器
数据卷容器就是一个普通的容器,专门提供数据卷给其他容器挂载使用
但是这个普通容器中必须有数据卷,就是刚刚上面创建的名为web容器那种
在其他容器创建时用 --volumes-from挂载数据卷容器中的数据卷使用
这里使用预先创建好的数据卷容器 web ,就是刚刚创建的 名字为web的容器
web容器中创建的数据卷是 /data1 与 /data2
把这两个数据卷挂载到新的容器,db1当中
[root@CentOS7-02 ~]# docker run -d --volumes-from web --name db1 centos:latest /bin/bash -c "while true;do echo ok;done;"
7c762dfe0134b297575b02d95ae1a33938e797c04287fb10eba274968a294cba
(--name 指定新的容器名称)
进入db1,容器中进入 数据卷容器 /data1中,
[root@CentOS7-02 ~]# docker exec -it db1 /bin/bash
[root@7c762dfe0134 /]# cd /data1/
[root@7c762dfe0134 data1]# ls
[root@7c762dfe0134 data1]# mkdir db 1
[root@7c762dfe0134 data1]# ls
1 db
[root@7c762dfe0134 data1]# exit
进入 web容器中 ,发现数据已经同步了
[root@CentOS7-02 ~]# docker exec -it web /bin/bash
[root@c86432d0fff4 /]# cd /data1/
[root@c86432d0fff4 data1]# ls
1 db
[root@c86432d0fff4 data1]# exit
相反,在web容器/data1,中创建或改动目录也会同步到 db1中
另外 /data2 也是
通过这些机制,即使容器在运行中出现问题,用户也不用担心数据丢失了
Docker网络通信
端口映射
在启动容器的时候,如果不指定对应端口,在容器外部是无法通过网络来访问对应的服务的
Docker提供端口映射机制来将容器内的服务提供给外部网络访问
实质上就是将宿主机的端口映射到容器中,使得外部网络可以访问宿主机端口,访问容器内部服务
实现端口映射,使用run 命令 -P(大写) 命令实现随机映射,Docker会随机映射宿主机端口范围在49000~49900的端口,到容器内部所有开发的网络端口,但范围也不是绝对
[root@CentOS7-02 apache]# docker run -d -P httpd:centos
(这里必须使用前面的这个镜像,因为这个镜像有安装好的 httpd服务,有80端口)
[root@CentOS7-02 apache]# docker ps
(注意看下面的图片)
( 因为这个httpd:centos镜像是我们前面生成的,里面有配置,创建成容器会自动在后台启动,所以不用加 -c 参数了)
在运行 docker run命令使用小写 p 可以指定要映射的端口,
[root@CentOS7-02 apache]# docker run -d -p 999:80 httpd:centos
(把宿主机998端口转换到,容器的80,端口)
[root@CentOS7-02 apache]# docker ps | grep 999
a8645067a286 httpd:centos "/run.sh" 2 minutes ago Up 2 minutes 0.0.0.0:999->80/tcp zealous_lamarr
-P 选项会自动映射容器中所有的端口,而-p需要一个一个的指定
容器互联
容器互联是通过容器的名称在容器间建立一条专门的网络通信隧道从而实现的互联
就是在源容器和接受容器之间建立一条隧道,
接受容器可以看到源容器指定的信息
在运行docker run 命令使用 --link选项实现容器之间的互联通信
– link name: alias
name是要连接的容器名称,alias是这个连接的别名
容器互联是通过容器的名称来进行的, 名称要唯一,也就是创建新的容器的时候是不可以和已经有的容器名称相同
1.创建源容器web1
[root@CentOS7-02 ~]# docker run -d --name web1 centos:latest /bin/bash -c "while true;do echo ok;done;"
(就是一个普通的容器)
2. 创建接受容器
][root@CentOS7-02 ~]# docker run -d --name web2 --link web1:web1~web2 centos:latest /bin/bash -c "while true;do echo ok;done;"
(--link 后的 :前面的web1 是指定源容器 ,:后面的是这个连接的名称可以自定义)
(这个连接名称,在后面测试可以看到)
进入接受容器 web2
[root@CentOS7-02 ~]# docker exec -it web2 /bin/bash
[root@3fa7b09e392c /]# ping web1
( 注意看下图)
此时,可以看到容器web1 与容器 web2 已经建立互联关系,这是在Docker在两个互联的容器之间创建一条安全隧道,而且不需要使用宿主机端口映射,不会暴露端口,提供了安全性