文章目录
一、容器数据卷
什么是容器数据卷
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
MySQL,容器删除了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!
使用容器数据卷
方式一 :直接使用命令挂载 -v
-v, --volume list Bind mount a volume
docker run -it -v 主机目录:容器内目录 -p 主机端口:容器内端口
➜ ~ docker run -it -v /home/ceshi:/home centos /bin/bash
#通过 docker inspect 容器id 查看
测试文件的同步
部署MySQL
思考:MySQL的数据持久化的问题
# 获取mysql镜像
docker pull mysql:5.7
# 运行容器,需要做数据挂载 #安装启动mysql,需要配置密码的,这是要注意点!
# 参考官网hub
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#启动我们得
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
-- 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:5.7
# 启动成功之后,我们在本地使用sqlyog来测试一下
# sqlyog-连接到服务器的3306--和容器内的3306映射
# 在本地测试创建一个数据库,查看一下我们映射的路径是否ok!
具名挂载和匿名挂载
# 匿名挂载
-v 容器内路径!
docker run -d -P --name nginx01 -v /etc/nginx nginx
# 查看所有的volume的情况
➜ ~ docker volume ls
DRIVER VOLUME NAME
local 33ae588fae6d34f511a769948f0d3d123c9d45c442ac7728cb85599c2657e50d
local
# 这里发现,这种就是匿名挂载,我们在 -v只写了容器内的路径,没有写容器外的路劲!
# 具名挂载
➜ ~ docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
➜ ~ docker volume ls
DRIVER VOLUME NAME
local juming-nginx
# 通过 -v 卷名:容器内路径
# 查看一下这个卷
所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxx/_data
下
如果指定了目录,docker volume ls 是查看不到的
# 三种挂载: 匿名挂载、具名挂载、指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载 docker volume ls 是查看不到的
拓展:
# 通过 -v 容器内路径: ro rw 改变读写权限
ro #readonly 只读
rw #readwrite 可读可写
docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx
docker run -d -P --name nginx05 -v juming:/etc/nginx:rw nginx
# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!
初识Dockerfile
Dockerfile 就是用来构建docker镜像的构建文件!命令脚本!先体验一下!
通过这个脚本可以生成镜像,镜像
# 创建一个dockerfile文件,名字可以随便 建议Dockerfile
# 文件中的内容 指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
#这里的每个命令,就是镜像的一层!
通过build命令生成自己的镜像
docker build -f /home/docker/Dockerfile -t qgc/centos:1.0 .
启动自己的镜像
docker run -it fd34365e9c93 /bin/bash
ls -al
发现根目录下已经创建出了挂载的两个目录
上面的目录一定和外面的Linux有同步,我们使用下面的命令查找
docker inspect 5068ef623f7c
可以看到对应的地址
数据卷容器
多个MySQL同步数据!命名的容器挂载数据卷!
--volumes-from list Mount volumes from the specified container(s)
# 启动刚才创建的容器
[root@VM-4-3-centos docker]# docker run -it --name centos01 qgc/centos:1.0
[root@dbb156c63573 /]# ls -al
drwxr-xr-x 2 root root 4096 May 11 2019 srv
dr-xr-xr-x 13 root root 0 Oct 19 03:10 sys
drwxrwxrwt 7 root root 4096 Aug 9 21:40 tmp
drwxr-xr-x 12 root root 4096 Aug 9 21:40 usr
drwxr-xr-x 20 root root 4096 Aug 9 21:40 var
drwxr-xr-x 2 root root 4096 Oct 21 08:19 volume01
drwxr-xr-x 2 root root 4096 Oct 21 08:19 volume02
# 再次启动容器,并设置同步刚才的centos01
[root@VM-4-3-centos docker]# docker run -it --name cnetos02 --volumes-from centos01 qgc/centos:1.0
[root@d273d216f66d /]# ls -al
drwxr-xr-x 2 root root 4096 May 11 2019 srv
dr-xr-xr-x 13 root root 0 Oct 19 03:10 sys
drwxrwxrwt 7 root root 4096 Aug 9 21:40 tmp
drwxr-xr-x 12 root root 4096 Aug 9 21:40 usr
drwxr-xr-x 20 root root 4096 Aug 9 21:40 var
drwxr-xr-x 2 root root 4096 Oct 21 08:19 volume01
drwxr-xr-x 2 root root 4096 Oct 21 08:19 volume02
# 在volume01里面创建hello.java 发现在刚刚启动的cnetos01里面也会同步到
# 测试:可以删除docker01,查看一下docker02和docker03是否可以访问这个文件
# 测试依旧可以访问
多个mysql实现数据共享
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:5.7
docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
# 这个时候,可以实现两个容器数据同步!
二、DockerFile
DockerFile介绍
dockerfile
是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
1、 编写一个dockerfile文件
2、 docker build 构建称为一个镜像
3、 docker run运行镜像
4、 docker push发布镜像(DockerHub 、阿里云仓库)
点击后跳到一个Dockerfile
很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像!
DockerFile构建过程
基础知识:
1、每个保留关键字(指令)都是必须是大写字母
2、执行从上到下顺序
3、#
表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交!
Dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成企业交付的标准,必须要掌握!
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行产品。
Docker容器:容器就是镜像运行起来提供服务。
DockerFile的指令
FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的, 姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 保留端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承 DockerFile 这个时候就会运行ONBUILD的指令,触发指令。
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量!
实战测试
创建一个自己的centos
# 1.编写Dockerfile文件
vim mydockerfile-centos
FROM centos
MAINTAINER cheng<1204598429@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 文件路径 -t 镜像名:[tag] .
docker build -f mydockerfile-centos -t mycentos:0.1 .
测试运行
CMD 和 ENTRYPOINT区别
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
# 编写dockerfile文件
$ vim dockerfile-test-cmd
FROM centos
CMD ["ls","-a"]
# 构建镜像
$ docker build -f dockerfile-test-cmd -t cmd-test:0.1 .
# 运行镜像
$ docker run cmd-test:0.1
.
..
.dockerenv
bin
dev
# 想追加一个命令 -l 成为ls -al
$ docker run cmd-test:0.1 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\":
executable file not found in $PATH": unknown.
ERRO[0000] error waiting for container: context canceled
# cmd的情况下 -l 替换了CMD["ls","-l"]。 -l 不是命令所以报错
# 编写dockerfile文件
$ vim dockerfile-test-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]
$ docker run entrypoint-test:0.1
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found ...
# 我们的命令,是直接拼接在我们得ENTRYPOINT命令后面的
$ docker run entrypoint-test:0.1 -l
total 56
drwxr-xr-x 1 root root 4096 May 16 06:32 .
drwxr-xr-x 1 root root 4096 May 16 06:32 ..
-rwxr-xr-x 1 root root 0 May 16 06:32 .dockerenv
lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x 5 root root 340 May 16 06:32 dev
drwxr-xr-x 1 root root 4096 May 16 06:32 etc
drwxr-xr-x 2 root root 4096 May 11 2019 home
lrwxrwxrwx 1 root root 7 May 11 2019 lib -> usr/lib
lrwxrwxrwx 1 root root 9 May 11 2019 lib64 -> usr/lib64 ....
实战:Tomcat镜像
-
准备镜像
准备
tomcat
和jdk
到当前目录,编写README
-
编写
Dockerfile
,官方建议使用Dockerfile
命名,这样编译的时候就不需要使用-f
里指定了FROM centos MAINTAINER qgc<1519059197@qq.com> COPY README.txt /usr/local/README ADD jdk-8u241-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-8.5.59.tar.gz /usr/local/ RUN yum -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_241 ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.59 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib EXPOSE 8080 CMD /usr/local/apache-tomcat-8.5.59/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.59/logs/catalina.out
-
构建镜像
# 因为dockerfile命名使用默认命名 因此不用使用-f 指定文件 docker build -t mytomcat:1.0
-
启动镜像
docker run -d -p 8080:8080 --name tomcat01 -v /home/tomcat/test:/usr/local/apache-tomcat-9.0.35/webapps/test -v /home/tomcatlogs/:/usr/local/apache-tomcat-9.0.35/logs mytomcat:0.1
发布自己的镜像
发布到docker hub上
-
地址 https://hub.docker.com/
-
确定这个账号可以登录
-
登录
$ docker login --help Usage: docker login [OPTIONS] [SERVER] Log in to a Docker registry. If no server is specified, the default is defined by the daemon. Options: -p, --password string Password --password-stdin Take the password from stdin -u, --username string Username
-
提交 push镜像
docker push mytomcat:0.1 # 会发现push不上去,因为如果没有前缀的话默认是push到 官方的library # 解决方法 # 第一种 build的时候添加你的dockerhub用户名,然后在push就可以放到自己的仓库了 $ docker build -t chengcoder/mytomcat:0.1 . # 第二种 使用docker tag #然后再次push $ docker tag 容器id chengcoder/mytomcat:1.0 #然后再次push
发布到阿里云上
# 官网教程很详细
https://cr.console.aliyun.com/repository/
三、Docker网络
理解Docker 0
-
使用
ip addr
发现有三个网卡,如下图所示 -
docker
网络是如何处理网络访问的# 测试 运行一个tomcat $ docker run -d --name tomcat01 tomcat $ ip addr
启动tomcat后,我们发现多了一个网卡
$ docker exec -it 容器id $ ip addr # 查看容器内部网络地址 发现容器启动的时候会得到一个 eth0@if155 ip地址,docker分配!
# 思考? linux能不能ping通容器内部! 可以 容器内部可以ping通外界吗? 可以! $ ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.069 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.074 ms
-
原理
1.我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要按照了docker,就会有一个docker0桥接模式,使用的技术是veth-pair技术! https://www.cnblogs.com/bakari/p/10613710.html 2.再启动一个容器 docker run -d tomcat
# 我们发现这个容器带来网卡,都是一对对的
# veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连
# 正因为有这个特性 veth-pair 充当一个桥梁,连接各种虚拟网络设备的
# OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
-
测试
tomcat1
和tomcat2
能否ping
通测试能够
ping
通 -
结论
tomcat01和tomcat02公用一个路由器,docker0。
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip。
link网络互连(不推荐)
[root@VM-4-3-centos ~] docker run -d --name tomcat01 tomcat
07179bd39e6f93dc178d4b3f84900a831e9817828cc54b31ae08a2322dc1444c
# 使用--link进行连接
[root@VM-4-3-centos ~] docker run -d --name tomcat02 --link tomcat01 tomcat
00818ea2b09c928d23e43e988dbd5782090a677d3bc9f9c407663c979c3215e0
# 进入到tomcat02中 ping tomcat01
[root@VM-4-3-centos ~] docker exec -it 00818ea2b09c /bin/bash
# 直接使用服务名可以进行ping通
root@00818ea2b09c:/usr/local/tomcat ping tomcat01
PING tomcat01 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.059 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=3 ttl=64 time=0.089 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=4 ttl=64 time=0.081 ms
原理
发现直接将
tomcat01
的地址加入到了tomcat02
的hosts
文件下
自定义网络
docker network
connect -- Connect a container to a network
create -- Creates a new network with a name specified by the
disconnect -- Disconnects a container from a network
inspect -- Displays detailed information on a network
ls -- Lists all the networks created by the user
prune -- Remove all unused networks
rm -- Deletes one or more networks
查看所有的docker网络
[root@VM-4-3-centos ~] docker network ls
NETWORK ID NAME DRIVER SCOPE
f8aa204ff74a bridge bridge local
e50d86126bf8 host host local
971011f54ea2 none null local
网络模式
bridge :桥接 docker(默认,自己创建也是用bridge模式)
none :不配置网络,一般不用
host :和所主机共享网络
container :容器网络连通(用得少!局限很大)
# 我们直接启动的命令 --net bridge,而这个就是我们得docker0
# bridge就是docker0
$ docker run -d -P --name tomcat01 tomcat
等价于 => docker run -d -P --name tomcat01 --net bridge tomcat
创建网络
# docker0,特点:默认,域名不能访问。 --link可以打通连接,但是很麻烦!
# 我们可以 自定义一个网络
$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
使用自定义的网络创建容器
# 创建tomcat01 和 tomcat02
[root@VM-4-3-centos ~]# docker run -d --name tomcat01 --net mynet tomcat
b77e9a5ba3488c9db0c69b15ad0d3b2b8b80182390597b0a095d7674abc4d289
[root@VM-4-3-centos ~]# docker run -d --name tomcat02 --net mynet tomcat
4ede6afd56d95736d8dc35087c11a64c4925bd3150bdcba9da93ab03dad25961
# 进入tomcat01 并ping tomcat02
[root@VM-4-3-centos ~] docker exec -it b77e9a5ba348 /bin/bash
root@b77e9a5ba348:/usr/local/tomcat ping tomcat02
PING tomcat02 (192.168.0.4) 56(84) bytes of data.
64 bytes from tomcat02.mynet (192.168.0.4): icmp_seq=1 ttl=64 time=0.095 ms
64 bytes from tomcat02.mynet (192.168.0.4): icmp_seq=2 ttl=64 time=0.069 ms
64 bytes from tomcat02.mynet (192.168.0.4): icmp_seq=3 ttl=64 time=0.071 ms
在自定义的网络下,服务可以互相ping通,不用使用–link
我们自定义的网络docker当我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis创建一个网络 -不同的集群使用不同的网络,保证集群是安全和健康的
mysql创建一个网络 -不同的集群使用不同的网络,保证集群是安全和健康的
网络连通
命令:
# 将tomcat02加入到mynet中去
docker network connect mynet tomcat02
实现
# 创建一个自定义网络
[root@VM-4-3-centos ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
1cabf3f8261f68afc397b30667a66ee22fc349bb258618f9cb5c1dec26bfb7e8
# tomcat01使用自定义网络启动
[root@VM-4-3-centos ~]# docker run -d --name tomcat01 --net mynet tomcat
3de288f7cd62370339a8c3d0618f78738ed0865dc39bd91cbf01f55e84824f57
# tomcat02使用默认的网络启动
[root@VM-4-3-centos ~]# docker run -d --name tomcat02 tomcat
15bd0cd50b6e13e7b779b3988e234481b7335b9d1f81c239ba399f9b02fa181f
# 将tomcat02加入到mynet中去
[root@VM-4-3-centos ~]# docker network connect mynet tomcat02
# 进入tomcat01发现可以ping通 tomcat02
[root@VM-4-3-centos ~]# docker exec -it tomcat01 /bin/bash
root@3de288f7cd62:/usr/local/tomcat# ping tomcat02
PING tomcat02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.074 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.087 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.100 ms
SpringBoot微服务打包Docker镜像
-
构建SpringBoot项目
-
打包运行
mvn package
- 编写dockerfile
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
- 构建镜像
# 1.复制jar和DockerFIle到服务器
# 2.构建镜像
$ docker build -t xxxxx:xx .
- 构建镜像
# 1.复制jar和DockerFIle到服务器
# 2.构建镜像
$ docker build -t xxxxx:xx .
- 发布运行
以后我们使用了Docker之后,给别人交付就是一个镜像即可!