Docker进阶(docker网络、dockerfile、docker-compose、数据卷等操作)

Docker进阶

常见错误解决

dns解析错误
在/etc/resolv.conf
#添加谷歌的dns域名解析地址:
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver localdomain
保存后重启下docker命令:
systemctl restart docker

1.容器数据卷

问题产生:

假设一个容器里有mysql,数据都存在里面,如果删除了容器,那么数据也删除了,删除容器等同于删除了数据库,这是不安全的

需求产生:

容器中有个独立的文件系统存储数据,容器是独立的,与宿主主机是隔离的,要想保持容器的数据不会因为容器的删除而丢失,我们就需要进行容器持久化和同步操作,同时使容器之间的数据进行共享

问题解决:

使用数据卷技术!

2.使用数据卷

#命令docker run -it -v 主机目录i:容器内目录 
#测试
docker run -it -v /home/cesi:/home centos /bin/bash

使用数据卷之后,主机目录和容器内的目录是相互映射的,可以理解为双向绑定,一个目录修改,对应的映射目录也会跟着变化

使用数据卷的好处

1.以后改容器内的文件不需要进入容器,直接在本地的映射文件中修改即可

2.容器删除,主机的目录不会删除

3.不会占用两倍存储

3.MySQL同步数据

#获取镜像
docker pull mysql:8.0.29
#运行容器,需要做数据挂载! #安装启动mysql,需要配置密码
#官方测试:$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#启动我们的mysql:
-d: 后台运行
-p: 端口映射
-v: 数据卷挂载,可以使用多个-v,挂载多个目录
-e: 环境配置(mysql密码)
--name: 容器名字
docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:8.0.30
#启动成功之后,使用Navicate连接成功
	输入主机地址,密码,服务器主机映射端口即可(我这里的映射端口是3310)
#在Navicat中创建一个数据库,查看映射路径多出了一个文件,那就是我们创建的数据库

4.挂载方式

#1.匿名挂载:			  -v 容器内路径
#2.具名挂载(常用):	    -v 卷名:容器内路径
#3.指定路径挂载:  		 -v 宿主机路径:容器内路径
匿名挂载:
docker run -d -P --name nginx01 -v /etc/nginx  nginx
具名挂载:(常用)
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
指定路径挂载:
docker run -d -P --name nginx03 -v /home/nginx:/etc/nginx nginx

拓展

#通过 -v 容器内路径: ro|rw 改变读写权限
ro: readonly		#只读
rw: readwrite		#可读可写
#一旦启动容器的时候给容器设置了权限,我们对容器的操作就有限定了,只能通过外部来修改,而不能在容器内修改
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

#ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的

5.初识Dockerfile

Dockerfile就是用来构建docker镜像的构建文件!命令脚本!

通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层!

手动创建dockerfile01文件:



FROM centos

VOLUME ["volume01","volume02"]

CMD echo "---end---"

CMD /bin/bash

#这里的每行命令都是镜像的一层

创建镜像:

-f:指定docfile文件路径
-t:镜像名字:版本号
最后面的.表示在当前目录下生成镜像
[root@localhost docker-test-volume]# docker build -f dockerfile01 -t yuanboss-centos:2.0 .

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CBNK2WNn-1673519727539)(H:\Soft\Typora\img\image-20220504171338521.png)]

启动自己写的容器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4kf1Nn07-1673519727540)(H:\Soft\Typora\img\image-20220504172001113.png)]

其中的volume01,volume02就是我们生成镜像的时候自动挂载的数据卷,这个卷一定和外部有个同步的目录

这个同步目录通过命令:docker inspect 容器id

找到该容器的元数据中吗Mounts即可查看

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7KsAYmD4-1673519727541)(H:\Soft\Typora\img\image-20220504173923234.png)]

因为dockerfile文件中只写了容器的卷目录,所以是匿名挂载

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VtBtl6qY-1673519727541)(H:\Soft\Typora\img\image-20220504173643804.png)]

以上挂载是在创建镜像的时候就已经挂载好了,如果构建镜像的时候没有挂载,就要启动的时候手动挂载,-v 卷名:容器内路径

6.数据卷容器

实现容器之间的数据共享,通过 –volumes-from 容器名 启动容器

–volumes-from 相当于继承

#命令 docker run -it --name docker02 --volumes-from docker01  镜像名:版本
docker run -it --name docker02 --volumes-from docker01  yuanboss-centos:2.0

数据共享之后,他们有相同的挂载目录在宿主机**/var/lib/docker/volumes**中

结论:容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止

但是一旦持久化到了本地,本地的数据是不会因为容器的删除而删除的

7.DockerFile构建镜像

1.dockerfile介绍

dockerfile是用来构建docker镜像的文件!命令参数脚本!

构建步骤:

1.编写一个dockerfile文件

2.docker build 构建成一个镜像

3.docker run 运行镜像

4.docker push 发布镜像(DockerHub,阿里云镜像仓库)

2.Dockerfile的指令

FROM		#基础镜像,一切从这里开始构建 centos
MAINTAINER  #镜像是谁写的,姓名加邮箱(yuanboss<[email protected]>)
RUN			#镜像构建的时候需要运行的命令
ADD			#步骤:tomcat镜像,tomcat压缩包就是添加的内容
WORKDIR		#镜像的工作目录 /usr/local
VOLUME		#挂载的目录
EXPOSE		#镜像创建的时候,暴露端口配置
CMD			#指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT	#指定这个容器启动的时候要运行的命令,可以直接追加命令
ONBUILD		#当构建一个别继承Dockerfile 这个时候就会运行 ONBUILD 的指令,出发指令
COPY		#类似ADD,将文件拷贝到镜像中
ENV			#构建的时候设置环境变量

3.DockerFile构建过程

构建自己的centos

#1.编写dockerfile的配置文件
[root@localhost dockfile]# cat mydockerfile-centos 
FROM centos:7
MAINTAINER yuanboss<1928627476@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo "----end----"
CMD /bin/bash

#2.通过这个文件构建镜像
#命令docker build -f dockerfile文件路径 -t 镜像名:[tag] 镜像生成的位置
例如以下命令将镜像构建到当前目录下
docker build -f mydockerfile-centos -t mycentos:0.1 .

#3.测试运行

对比:

官方默认的centos

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UEccDa6Z-1673519727542)(H:\Soft\Typora\img\image-20220506161319323.png)]

自己创的centos镜像

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oRsW1xKV-1673519727543)(C:\Users\yuan\AppData\Roaming\Typora\typora-user-images\image-20220506161533991.png)]

我们可以列出镜像在本地变更的历史

#命令
docker history 镜像id

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SqarflIp-1673519727543)(H:\Soft\Typora\img\image-20220506162515218.png)]

所以我们拿到镜像,就可以通过docker history来研究该镜像是如何制作的

4.CMD和ENTRYPOINT的区别

CMD			#指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被代替
ENTRYPOINT  #指定这个容器启动的时候要运行的命令,可以追加命令

测试cmd

#编写dockerfile文件
[root@localhost dockfile]# vim dockerfile-cmd-test 

FROM centos
CMD ["ls","-a"]

#构建镜像
docker build -f dockerfile-cmd-test -t cmdtest .

#run运行,发现ls -a命令生效
[root@localhost dockfile]# docker run -it 93a744bacc5e
.   .dockerenv	dev  home  lib64       media  opt   root  sbin	sys  usr
..  bin		etc  lib   lost+found  mnt    proc  run   srv	tmp  var

#想追加一个命令 -l 将ls -a 变为 ls -al
[root@localhost dockfile]# docker run -it 93a744bacc5e -l
docker: Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.

#使用cmd的情况下, -l替换了CMD ["ls","-a"]命令,-l不是命令,所以报错

#使用完整命令才不报错,如:
[root@localhost dockfile]# docker run -it 93a744bacc5e ls -al

测试entrypoint

#1.编写dockerfile文件
[root@localhost dockfile]# cat dockerfile-cmd-entrypoint 
FROM centos
ENTRYPOINT ["ls","-a"]

#2.构建镜像
[root@localhost dockfile]# docker build -f dockerfile-cmd-entrypoint -t entrypoint-test .

#3.run运行镜像
[root@localhost dockfile]# docker run af74f1ebead4
.
..
.dockerenv
bin
dev
etc
#4.追加一个命令 -l,使ENTRYPOINT ["ls","-a"]变为ENTRYPOINT ["ls","-a","-l"]
[root@localhost dockfile]# docker run af74f1ebead4 -l
total 0
drwxr-xr-x.   1 root root   6 May  6 08:49 .
drwxr-xr-x.   1 root root   6 May  6 08:49 ..
-rwxr-xr-x.   1 root root   0 May  6 08:49 .dockerenv
lrwxrwxrwx.   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x.   5 root root 340 May  6 08:49 dev
drwxr-xr-x.   1 root root  66 May  6 08:49 etc

#5.追加命令后成功运行

5.镜像打包与下载

镜像打包:
当编写完dockerfile之后
可以使用打包命令docker save -o 打包路径/打包后的镜像名 镜像名:
docker save -o ./mypackageimages redis
通过以上命令打包好之后,我们可以在当前路径下面看到我们打包好的mypackageimages文件,注意我们的打包命令中必须要指定我们镜像打包后的名字
打包好之后我们可以把mypackageimages文件传到windows桌面,发送给别人使用或者上传到git

镜像下载:
当我们拿到镜像文件之后,我们需要把镜像文件加载到我们的docker中,可以使用如下命令
docker load -i 镜像文件名
然后通过命令docker images可以查看我们加载的镜像,但是这个时候镜像是没有名字的,我们可以通过以下命令给镜像设置
docker tag 镜像id 自定义镜像名字:镜像版本号

8.实战测试:Tomcat镜像制作

1.准备镜像文件 tomcat压缩包,jdk的压缩包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ihjc7xLK-1673519727544)(H:\Soft\Typora\img\image-20220506171229918.png)]

2.编写dockerfile的文件,官方命名“Dockerfile,build会自动寻找这个文件,就不需要-f指定了!

FROM centos:7
MAINTAINER yuanboss<1928627476@qq.com>

COPY readme.txt /usr/local/readme.txt

ADD jdk-8u301-linux-x64.tar.gz /usr/local
ADD apache-tomcat-9.0.62.tar.gz  /usr/local

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_301
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.62
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.62
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.62/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.62/logs/catalina.out

3.构建镜像

#docker build -t diytomcat .

4.启动镜像

docker run -it -d --name tomcat01 -p 9090:8080 -v /home/tomcat/test:/usr/local/apache-tomcat-9.0.62/webapps/test -v /home/tomcat/tomcatlogs:/usr/local/apache-tomcat-9.0.62/logs diytomcat

5.访问测试

curl localhost:9090

6.发布项目

在挂载的宿主机目录/home/tomcat/test下创建WEB-INF目录,再到该目录下添加以下web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
     http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
     version="4.0">
    
</web-app>

在挂载的宿主机目录/home/tomcat/test下创建index.jsp文件

<%@ page language="java" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>


    
        
        yuanboss
    
    
    Hello World!
<% System.out.println("----yuanboss test web logs----"); %>

7.测试项目是否部署成功

[root@localhost test]# curl localhost:9090/test/
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>yuanboss</title>
    </head>
    <body>
    Hello World!</br>
    
    </body>
</html>

访问成功,项目部署成功

9.发布自己的镜像到DockerHub

1.登录DockerHub

#命令 docker login -u DockerHub注册名
[root@localhost tomcat]# docker login -u yuanboss666
Password: 
Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

2.解决遇到的超时错误

dns解析错误
在/etc/resolv.conf
#添加谷歌的dns域名解析地址:
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver localdomain
保存后重启下docker命令:
systemctl restart docker

配置/etc/resolv.conf文件之后输入docker login命令登录成功,如下:

[root@localhost tomcat]# docker login -u yuanboss666
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

3.push之前先给镜像重命名

# 命令 docker tag 镜像id DockerHub注册名/镜像名称:1.0 

4.开始push

#命令 docker push  DockerHub注册名/镜像名称:1.0 

5.push成功

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WRly7iYh-1673519727544)(H:\Soft\Typora\img\image-20220507164221207.png)]

如图DockerHub所示,已经push到了DockerHub仓库

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hVZ1Pn7u-1673519727545)(H:\Soft\Typora\img\image-20220507165426774.png)]

10.Docker网络

1.原理

理解Docker0网络:服务器安装Docker之后,docker会分配一个docker0网卡,如下图

a.测试ip addr:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DdLyxTeO-1673519727546)(H:\Soft\Typora\img\image-20220508093735960.png)]

b.启动一个容器:

[root@localhost /]# docker run -d -P --name tomcat01 tomcat

c.再次通过ip addr

发现多了一个网卡,如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UffSfnlX-1673519727546)(H:\Soft\Typora\img\image-20220508094922014.png)]

d.进入容器并输入ip addr

[root@localhost /]# docker exec -it tomcat01 ip addr
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ip": executable file not found in $PATH: unknown

以上命令发现容器内没有ip addr,所以可能这个容器没有网络命令,我们可以在容器内通过以下命令安装网络命令:

手动安装这些命令:

#更新apt依赖
apt update

#安装ipaddr
apt install -y iproute2

#安装ifconfig
apt install -y net-tools

#安装ping
apt install -y iputils-ping
批量安装
apt update && apt install -y iproute2 && apt install -y net-tools && apt install -y iputils-ping

e.安装完网络命令后,再次进入同期并且输入ip addr,发现该容器有个网卡和上面的 c步骤 多出来的网卡类似

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4aIzs3Ez-1673519727547)(H:\Soft\Typora\img\image-20220508100334385.png)]

说明服务器和docker容器是相通的,他们之间建立了连接

f.我们再启动一个tomcat02容器

[root@localhost /]# docker run -d -P --name tomcat02 tomcat

g.我们进入容器并且输入ip addr命令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bGEwqk8D-1673519727547)(H:\Soft\Typora\img\image-20220508105332205.png)]

f.退出容器但是不停止,输入ip addr

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0OJo9Abi-1673519727548)(H:\Soft\Typora\img\image-20220508105432795.png)]

发现多出的网卡和 步骤g 类似,再次证明docker启动一个容器,便会给容器分配一个网卡,主机也会多一个与之对应的网卡

#我们发现容器带来的网卡是一对对的,这对网卡是可以通信的,所以说服务器和docker容器是可以通信的

所以我们在linux服务器可以ping通容器的ip,如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w2w7lfF3-1673519727548)(H:\Soft\Typora\img\image-20220508105830741.png)]

当然,在容器内也可以ping通linux服务器的,如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LFOqWWWW-1673519727548)(H:\Soft\Typora\img\image-20220508105947887.png)]

容器与linux服务器之间可以互相通信,是因为veth-pair技术

那么tomcat01容器与tomcat02容器之间可以ping通嘛,当然是可以的,如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4kHuEa9u-1673519727549)(H:\Soft\Typora\img\image-20220508110516295.png)]

为啥容器之间可以互相ping通呢

因为docker0和容器的网卡是相通的,但是容器之间没有直接建立连接,docker0相当于一个路由器,容器是通过路由器的转发,从而间接的连接到其他容器的

结论:

tomcat01和tomcat02是共用一个路由器的,那就是docker0

所有的容器在不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip

小结:

Docker使用的是Linux桥接,宿主机中是一个Docker容器的网桥,docker0
容器之间通信是通过veth-pair转发而连接的
docker容器里面的网络核心:利用linux的虚拟化网络技术,在容器内与docker0分别创建了一个虚拟网卡,通过Veth-pair进行连接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8yv33iVF-1673519727549)(H:\Soft\Typora\img\image-20220508111704162.png)]

Docker中的所有网络接口都是虚拟的,虚拟的转发效率高!

只要容器删除,对应的网桥就没了!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mNeggXFc-1673519727550)(C:\Users\yuan\AppData\Roaming\Typora\typora-user-images\image-20220508123324902.png)]

2.–link

–link可以通过容器名字来ping通容器,不需要知道容器的ip

[root@localhost /]# docker run -d -P --name tomcat03 --link tomcat02 tomcat

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iViVJoxE-1673519727550)(H:\Soft\Typora\img\image-20220508122655923.png)]

其实tomcat03是在hosts文件中配置了tomcat02

[root@localhost /]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.3	tomcat02 4a6aa30726f3  #配置了tomcat02
172.17.0.4	41e5a82503c5

本质探究:–link就是在hosts配置中增加了一个映射

现在玩docker已经不建议使用–link了!

我们现在推荐自定义网络!不适用docker0!

docker0的问题:他不支持容器名连接访问!

3.自定义网络

查看所有的docker网络

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-geK5Z3Or-1673519727550)(H:\Soft\Typora\img\image-20220508124638850.png)]

网络模式

bridge:桥接模式(默认,自己创建的网络也使用桥接模式)

none:不配置网络

host:和宿主机共享网络

除以上三个之外,docker还有提供了container: 容器内网络连通(用的少!局限大!)

测试

#我们直接启动的命令 --net bridge,而这个就是我们的docker0(--net bridge是默认参数)
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat

#docker0特点:默认,通过容器名不能访问, 使用--link可以打通连接,从而通过容器名访问

#我们可以自定义一个网络
# --driver bridge  桥接模式
# --subnet 192.168.0.0/16 子网设置 192.168.0.2-192.168.255.255
# --gateway 192.168.0.1  网关设置
[root@localhost /]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
f52cf61c8ea628b38598904377f2f032cb067e994e1fad47fb955ac897ce6b98

自定义网络之后,查看所有网络:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tRTaKQCK-1673519727551)(H:\Soft\Typora\img\image-20220508131007651.png)]

由图可知自定义网络已经创建成功,查看自己创建的网络信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fGceQalE-1673519727551)(H:\Soft\Typora\img\image-20220508131311898.png)]

用自己创建的网络来启动两个容器,并且使用docker network inspect mynet查看自定义网络信息

[root@localhost /]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
4dc77940bffc05c19e9c22cabfa838768223ec35fc57528b5f0d65020ed6e955
[root@localhost /]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
d030f3eff97643291e130b81e1bb1b3d5f99cf7fa4894f73603681071058fdde
[root@localhost /]# docker network inspect mynet 
[
    {
        "Name": "mynet",
        "Id": "f52cf61c8ea628b38598904377f2f032cb067e994e1fad47fb955ac897ce6b98",
        "Created": "2022-05-08T13:08:59.78722036+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "4dc77940bffc05c19e9c22cabfa838768223ec35fc57528b5f0d65020ed6e955": {
                "Name": "tomcat-net-01",
                "EndpointID": "ff5b0da13874676335ff5c02c9dc8990b795315dccc0845dd44e0f45863975b0",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "d030f3eff97643291e130b81e1bb1b3d5f99cf7fa4894f73603681071058fdde": {
                "Name": "tomcat-net-02",
                "EndpointID": "0a14a7ec16d2141ff0a7d55b62035353dcb870c1f1f6123175517147c10d5ce4",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

再次测试Ping连接


[root@localhost /]# docker exec -it tomcat-net-01 ping 192.168.0.3
ping: socket: Address family not supported by protocol
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.073 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.066 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.050 ms

#现在不使用--link也可以通过容器名字ping通了
[root@localhost /]# docker exec -it tomcat-net-01 ping tomcat-net-02
ping: socket: Address family not supported by protocol
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.053 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.065 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.050 ms

我们自定义的网络docker都已经帮我们维护好了对应的关系,我们一般都使用自定义的网络

使用自定义网络的好处:

redis-不同集群使用不同的网络,保证集群是安全和健康的

mysql-不同集群使用不同的网络,保证集群是安全和健康的

4.网络连通

两个不同网段下的容器是不能ping通的,比如docker0下的tomcat01容器和mynet网络下的tomcat-net-01容器是不能直接ping通的

要想实现不同网段下的容器连通,因为网卡之间是不能打通的,也就是说docker0与mynet网络不能打通,那我们就得将一个容器与另一个容器所属的网络打通,也就是说我们需要将tomcat01与mynet网络打通

查看docker network的帮助命令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z2QIZFY2-1673519727551)(C:\Users\yuan\AppData\Roaming\Typora\typora-user-images\image-20220508134149196.png)]

由图可知,connect命令可以将一个容器连接一个网络

再查看docker network connect的帮助命令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n36PZ6Gm-1673519727551)(H:\Soft\Typora\img\image-20220508134304339.png)]

由图可知,通过以下命令即可实现不同网段的网络与容器的连接

#将mynet网络与tomcat01容器连接
[root@localhost /]# docker network connect mynet tomcat01

连接成功后再进入tomcat01容器查看ip addr命令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H5rI6MzY-1673519727552)(H:\Soft\Typora\img\image-20220508134603218.png)]

发现tomcat01多了一个网卡,也就是连通了自定义mynet网络的网卡

再查看自定义的mynet网络的详细信息

[root@localhost /]# docker network inspect mynet 
[
    {
        "Name": "mynet",
        "Id": "f52cf61c8ea628b38598904377f2f032cb067e994e1fad47fb955ac897ce6b98",
        "Created": "2022-05-08T13:08:59.78722036+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "4dc77940bffc05c19e9c22cabfa838768223ec35fc57528b5f0d65020ed6e955": {
                "Name": "tomcat-net-01",
                "EndpointID": "ff5b0da13874676335ff5c02c9dc8990b795315dccc0845dd44e0f45863975b0",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "d030f3eff97643291e130b81e1bb1b3d5f99cf7fa4894f73603681071058fdde": {
                "Name": "tomcat-net-02",
                "EndpointID": "0a14a7ec16d2141ff0a7d55b62035353dcb870c1f1f6123175517147c10d5ce4",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "dc2e1360b4448a7d931ef174b7ffe056da2a43ef83cb14fc2522052f27e79497": {
                "Name": "tomcat01",
                "EndpointID": "928b0fbab5f388de18bda47cf13814e84a2930ce6626fa9dc5f8d5bfb6b33dbf",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

从容器信息中我们可以看到自定义的mynet网络多了一个tomcat01容器

结论:

通过docker network connect将网络与容器连通后,实质就是给mynet网络配置了一个容器,并且给容器新增了一个自定义的mymet网络的网卡,所以能实现容器与不同网段下的容器ping通

11.docker-compose部署redis+mysql


之前运行一个镜像,需要添加大量的参数,可以通过Docker-Compose编写这些参数。而且Docker-Compose可以帮助我们批量的管理容器。这些信息只需要通过一个docker-compose.yml文件去维护即可。

1 下载并安装Docker-Compose
1.1 下载Docker-Compose

去github官网搜索docker-compose,下载1.24.1版本的Docker-Compose

下载路径:https://github.com/docker/compose/releases/download/1.24.1/docker-compose-Linux-x86_64

1.2 设置权限

需要将DockerCompose文件的名称修改一下,给予DockerCompose文件一个可执行的权限

mv docker-compose-Linux-x86_64 docker-compose
chmod 777 docker-compose

1.3 设置环境变量

为了让docker-compose在任何地方都可以运行,我们需要设置环境变量,输入$PATH我们可以发现环境变量中存在/usr/local/bin路径了,所以我们可以把docker-compose执行文件直接移动到/usr/local/bin路径下面,从而间接的配置好了docker-compose环境变量

2.docker-compose部署 mysql+redis

先创建一个目录,在该目录下创建名为docker-compose.yml的文件(命名必须是这个),然后把下面的yml配置文件内容复制到这个docker-compose.yml文件即可,在该目录下操作docker-compose命令即可完成对配置文件中的容器的操作

#部署redis+mysql
version: '3.1'
services:
  mysql:           # 服务的名称
    restart: always   # 代表只要docker启动,那么这个容器就跟着一起启动
    image: mysql:8.0.30  # 指定镜像路径
    container_name: mysql8-2  # 指定容器名称
    ports:
      - 3306:3306   #  指定端口号的映射
    environment:
      MYSQL_ROOT_PASSWORD: 123456   # 指定MySQL的ROOT用户登录密码
      TZ: Asia/Shanghai        # 指定时区
    volumes:
     - ./mysql/mysql_data:/var/lib/mysql   # 映射数据卷
  tomcat:
    restart: always
    image: redis:6.2.7
    container_name: myredis-2
    ports:
      - 7489:6379
    volumes:
      - ./myredis/redis.conf:/etc/redis/redis.conf
      - ./myredis/data:/data
    command: redis-server /etc/redis/redis.conf

version 字段是表明使用那个版本的compose ,compose 有如下的版本,目前的最新版是 3.7

  • 1
  • 2
  • 2.x
  • 3.x

不同版本的 compose 支持了不同的 docker 版本

3. 使用docker-compose命令管理容器

在使用docker-compose的命令时 ,默认会在当前目录下找docker-compose.yml文件

# 1. 基于docker-compose.yml启动管理的容器
docker-compose up -d

# 2. 关闭并删除容器
docker-compose down

# 3. 开启|关闭|重启已经存在的由docker-compose维护的容器
docker-compose start|stop|restart

# 4. 查看由docker-compose管理的容器
docker-compose ps

# 5. 查看日志
docker-compose logs -f

4 docker-compose配合Dockerfile使用

使用docker-compose.yml文件以及Dockerfile文件在生成自定义镜像的同时启动当前镜像,并且由docker-compose去管理容器

4.1 docker-compose文件

编写docker-compose.yml文件

version: '3.1'
services:
  ssm:
    restart: always
    build:            # 构建自定义镜像
      context: ./      # 指定dockerfile文件的所在路径
      dockerfile: Dockerfile   # 指定Dockerfile文件名称
    image: ssm:1.0.1
    container_name: ssm
    ports:
      - 8085:8080
    environment:
      TZ: Asia/Shanghai
4.2 Dockerfile文件

编写Dockerfile文件

from daocloud.io/library/tomcat:8.5.15-jre8
copy ssm.war /usr/local/tomcat/webapps(这是镜像tomcat中的路径)
4.3 运行

测试效果

# 可以直接启动基于docker-compose.yml以及Dockerfile文件构建的自定义镜像
docker-compose up -d
# 如果自定义镜像不存在,会帮助我们构建出自定义镜像,如果自定义镜像已经存在,会直接运行这个自定义镜像
# 重新构建的话。
# 重新构建自定义镜像
docker-compose build
# 运行当前内容,并重新构建
docker-compose up -d --build

ompose.yml启动管理的容器
docker-compose up -d

2. 关闭并删除容器

docker-compose down

3. 开启|关闭|重启已经存在的由docker-compose维护的容器

docker-compose start|stop|restart

4. 查看由docker-compose管理的容器

docker-compose ps

5. 查看日志

docker-compose logs -f




### 4 docker-compose配合Dockerfile使用

> 使用docker-compose.yml文件以及Dockerfile文件在生成自定义镜像的同时启动当前镜像,并且由docker-compose去管理容器

##### 4.1 docker-compose文件

> 编写docker-compose.yml文件 

```yml
version: '3.1'
services:
  ssm:
    restart: always
    build:            # 构建自定义镜像
      context: ./      # 指定dockerfile文件的所在路径
      dockerfile: Dockerfile   # 指定Dockerfile文件名称
    image: ssm:1.0.1
    container_name: ssm
    ports:
      - 8085:8080
    environment:
      TZ: Asia/Shanghai
4.2 Dockerfile文件

编写Dockerfile文件

from daocloud.io/library/tomcat:8.5.15-jre8
copy ssm.war /usr/local/tomcat/webapps(这是镜像tomcat中的路径)
4.3 运行

测试效果

# 可以直接启动基于docker-compose.yml以及Dockerfile文件构建的自定义镜像
docker-compose up -d
# 如果自定义镜像不存在,会帮助我们构建出自定义镜像,如果自定义镜像已经存在,会直接运行这个自定义镜像
# 重新构建的话。
# 重新构建自定义镜像
docker-compose build
# 运行当前内容,并重新构建
docker-compose up -d --build

你可能感兴趣的:(Java企业开发进阶入门,docker,docker-compose,docker网络,dockerfile镜像,数据卷)