Docke精髓

容器数据卷

什么是容器数据卷
功能:容器的持久化和同步操作 容器之间数据共享的技术!

卷技术:Docker 容器中产生的数据,同步到本地。目录的挂载,将我们容器内的目录,挂载到Linux上面

使用数据卷

方式一: 直接使用命令来挂载 -V

1
2
3
4
5
6
docker run -it -v 主机目录,容器内目录

测试
[root@xxx]# docker run -it -v /home/ceshi:/home centos /bin/bash

启动起来时候我们可以通过 docker inspect 容器id

实战:安装MySQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
获取镜像
docker search mysql
docker pull mysql:5.7

运行容器,需要做数据挂载
安装启动mysql,需要配置密码(注意)
官方测试:docker run -it --network some-network --rm mysql mysql -hsome-mysql -uexample-user -p
运行
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置,设置mysql的密码
--name 容器名字
docker run -d -p 3310:3306 -v /home/mysql.conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=88888888 --name mysql01 mysql:5.7
启动成功之后,可以在Windows本地机测试创建一个数据库,查看我们映射的路径是否OK

假设我们将容器删除

1
2
3
docker rm -f mysql01
docker ps
docker ps -a

回到宿主机查看,发现数据都还在! 我们挂载到本地的数据卷没有丢失,这就实现了容器数据持久化功能。

具名挂载和匿名挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx
查看所有数据卷的情况
docker volume ls

具名挂载(常用)
-v 卷名:容器内路径
[root@163 home]# docker run -d -P --name nginx02 -v juming-nginx:/ect/nginx nginx
a4a6c63e6cbe798790bfee212da7dd56fdb533e5ac150e030a66655fa722168d
[root@163 home]# docker volume ls
DRIVER VOLUME NAME
local juming-nginx

# 所有docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxx/_data

-v /宿主机路径:容器内路径 # 指定路径挂载

拓展:

1
2
3
4
5
6
7
8
# 通过 -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 -y juming-nginx:/etc/nginx:rw nginx

DockerFile

DockerFile就是用来构建docker镜像的构建文件

命令脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mkdir docker-test-volume
ls
pwd
cd docker-test-volume/
pwd

通过下面这个脚本,可以生成镜像,镜像是一层一层的,脚本是一层层的命令,每一个命令都是一层
vim dockerfile1
写入:
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
保存:
ESC :wq

查看dockerfile1
cat dockerfile1
docker build -f /home/docker-test-volume/docekrfile1 -t rich/centos:1.0 .

DockerFile指令

指令 说明
FROM 指定基础镜像
MAINTAINER 镜像是谁写的,姓名+邮箱
RUN 镜像构建的时候需要运行的命令
ADD 将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
WORKDIR 镜像的工作目录
VOLUME 挂载的目录
EXPOSE 暴露端口配置
CMD 指定这个容器启动的时候要运行的命令(只有最后一个会生效,可被替代)
EMTRYPOINT 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD 当构建一个被继承DockerFile,这个时候就会运行ONBUILD的指令,触发指令
COPY 功能类似ADD,但是是不会自动解压文件,也不能访问网络资源
ENV 构建的时候设置环境变量

创建一个自己的centos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1 编写Dockerfile的文件
[root@xxx dockerfile]# cat mydockerfile-centos
FROM centos
MAINTAINER xxx<xxxxxxx@qq.com>

ENV MYPATH /usr/1ocal
WORKDIR SMYPATH

RUN yum -y instal1 vim
RUN yum -y insta11 net-tools

EXPOSE 80

CMD echo SMYPATH
CMD echo "----end----"
CMD /bin/bash

# 2、通过这个文件构建镜像
# 命令 docker build -f dockerfile文件路径 -t 镜像名:[tag] .
Successfu11y built e2bd75cfe070
Successfu11y tagged mycentos :0.1

#查看镜像历史,变更记录docker history 镜像id

实战:Tomcat镜像

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FROM centos
MAINTAINER xxx<xxxxxx @qq.com>
COPY readme.txt /usr/local/readme.txt

ADD jdk-8u11-linux-x64.tar.gz /usr/local/

ADD apache-tomcat-9.0.22.tar.gz /usr/1ocal/

RUN yum -y instal1 vim

ENV MYPATH /usr/local
WORKDIR SMYPATH

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

EXPOSE 8080

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

3.构建镜像

1
docker build -t diytomcat .

4.启动镜像

1
docker run -d -p 9090:8080 --name xuantomcat -v /home/xuan/build/tomcat/test:/usr/local/apache-tomcate-9.0.22/webapps/test/ -v /home/xuan/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.11/logs diytomcat

5.访问测试
6.发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了)

1
2
3
4
5
6
7
<?xml version="1.0”encoding="UTF-8"?>
<web-app xmlns="http://java. sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
</web-app>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>xxxxxxxx</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("welcome");
%>
</body>
</html>

发布镜像到DockerHub

1、地址 https://hub.docker.com/ 注册自己的账号
2、确定这个这账号可以登录
3、在我们服务器上提交自己的镜像

1
2
3
4
5
6
# docker login --help

Options:
-p,--password string Password
--password-stdin Take the password from stdin
-u,--username string Username

4、登录完毕后就可以提交镜像了,就是一步 docker push xxx/diytomcat:1.0(一定要带版本号)

docker tag 镜像id 要改成的名字:标签(1.0…..)

发布镜像到阿里云容器服务

1、登录阿里云
2、找到容器镜像服务
3、创建命名空间
4、创建容器镜像
5、浏览阿里云(参考官方)

Docker网络

理解docker0

1
2
3
4
5
lo:本机回环地址

eth0:阿里云内网地址

docker0:docker0地址
1
2
3
4
5
6
7
8
9
10
11
# [root@kuangshen /]# docker run -d -p --name tomcat01 tomcat
#查看容器的内部网络地址 ip addr, 发现容器启动的时候会得到一个 etho@if262 ip地址,docker分配的![root@kuangshen /]# docker exec -it tomcat01 ip addr
1: 1o: <LOOPBACKUP,LOWER_UP> mtu 65536 gdisc noqueue state UNKNOWN group default glen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
261: etho@if262:<BROADCAST,MULTICAST,UP,LOWER-UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
# linux 可以ping 通 docker 容器内部
1
2
3
4
5
# 我们发现这个容器带来网卡,都是一对对的
# evth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连
# 正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备的
# OpenStac,Docker容器之间的连接,OVS的连接,都是使用 evth-pair 技术
结论:容器和容器之间是可以互相ping通的

网络模型图

image-20230802140826087

结论: tomcat01和tomcat02 是公用的一个路由器,docker0。

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

小结

image-20230802141506485

Docker容器内的所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)

只有容器删除,对应的网桥一对就没有了

1
思考一个场景,我们编写了一个微服务,database url=ip:,项目不重启,数据库ip换掉了,怎样可以用名字来进行访问容器
1
2
3
4
5
6
7
8
# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
#通过--1ink 可以解决了网络连通问题
# docker run -d -p -name tomcat03 --link tomcat02 tomcat
# docker exec -it tomcat03 ping tomcat02(可以ping通)
#反向不可以ping通
# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known

本质探究:-link 就是我们在hosts配置中增加了一个172.18.0.3tomcat02

不建议使用 –link,适合新手用
docker0问题:不支持容器名连接访问

自定义网络

查看所有的docker网络#docker network ls

网络模式

bridge:桥接docker(默认,自己创建也用bridge模式)

none:不配置网络

host:和宿主机共享网络

container:容器网络连通(用的比较少)

1
2
3
4
5
6
7
8
9
10
11
12
13
#我们直接启动的命令 --net bridge,而这个就是docker0
docker run -d -P --name tomcat0l tomcat
docker run -d -P --name tomcat0l --net bridge tomcat
# docker0特点: 默认,域名不能访问,--link可以打通连接!
#我们可以自定义一个网络!
# --driver bridge
--subnet 192.168.0.0/16
# --gateway 192.168.0.1
# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
#直接ping ip 可以ping通
docker exec -it tomcat-net-01 ping 192.168.0.3
#现在不使用--link也可以ping名字
docker exec -it tomcat-net-01 ping tomcat-net-02

网络连通

1
2
3
4
5
6
7
8
9
docker network --help
docker network connect --help
测试打通 tomcat01 - mynet
# docker network connect mynet tomcat01
连通之后就是将 tomcat01 放到了 mynet 网络下
一个容器两个ip地址!
# 阿里云服务:公网ip 私网ip

docker exec -it tomcat01 ping tomcat-net-01//连通

假设要跨网络操作别人,就需要使用docker network connect连通