学Docker跟着这篇文章做一遍就能精通
Docker概述
Docker为什么会出现?
一个产品会有两套环境,开发、上线。
经常会出现的问题:我在我的电脑上可以运行! 版本更新导致服务不可用!这样就对开发的考验很大。
解决办法:开发学运维 或 运维学开发。所以现在的开发除了后台,还要会前端,还要会运维,当然了,这样的话工资也会高一点哦,为了更好的生活努力吧骚年
但是环境配置很麻烦,每个机器都要部署,费时费力。比如发布一个项目,项目打成jar包,然后需要redis,mysql,jdk。。。等等。但是如果把jar包和这些环境搞成一整套的呢?就是说项目带上环境一起安装打包,那么Docker就是很好的选择。
传统:开发给运维一个jar,运维来做。
现在:开发打包部署上线,一套流程做完!
Docker的历史
2010年Docker 公司位于旧金山,由法裔美籍开发者和企业家 Solumon Hykes 创立,Docker 公司起初是一家名为 dotCloud 的平台即服务(Platform-as-a-Service, PaaS)提供商。
底层技术上,dotCloud 平台利用了 Linux 容器技术。为了方便创建和管理这些容器,dotCloud 开发了一套内部工具,之后被命名为“Docker”。Docker就是这样诞生的!
Docker刚诞生时候,没有引起行业注意,刚开始的小公司活不下去,面临倒闭,于是2013年把开源,越来越多的人发现Docker的优点,于是就火了。2014年4月,Docker发布!
为啥Docker这么火?因为十分轻巧。最开始我们都是使用虚拟机,这玩意非常占用内存,安装过虚拟机的哥们应该都知道。虚拟机和Docker都是虚拟化技术,并且Docker是容器技术。
什么是虚拟化
在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部份是不受现有资源的架设方式,地域或物理组态所限制。一般所指的虚拟化资源包括计算能力和资料存储。
在实际的生产环境中,虚拟化技术主要用来解决高性能的物理硬件产能过剩和老的旧的硬件产能过低的重组重用,透明化底层物理硬件,从而最大化的利用物理硬件 对资源充分利用
虚拟化技术种类很多,例如:软件虚拟化、硬件虚拟化、内存虚拟化、网络虚拟化(vip)、桌面虚拟化、服务虚拟化、虚拟机等等。
Docker能干嘛
虚拟化技术
虚拟化技术缺点:
- 资源占用多
- 冗余步骤多
- 启动很慢
容器化技术
容器化技术不是模拟的完整的操作系统
Docker和虚拟机的区别:
- 虚拟机虚拟出一个硬件,运行一个完整的操作系统,然后在这个系统上安装和运行
- 容器的应用直接运行在宿主机的内核中,容器自己没有内核,也没有虚拟硬件,所以轻便
- 容器间相互间隔,每个容器都有自己的文件系统,互不影响
Docker安装
Docker组成
镜像(image):
docker镜像就等于是一个模板,可以通过这个模板创建一个或者多个容器(镜像运行起来就是容器),容器提供服务,最终的服务运行在容器里的。
容器(container):
docker利用容器技术,独立运行一个或者一组应用,可以理解为一个简易的Linux系统。
仓库(repository):
存放镜像的地方。仓库分公有仓库和私有仓库。
Docker Hub(默认是国外的),所以很慢,我们要配置国内的阿里云容器服务来镜像加速。
Docker安装
准备环境
- 会一点Linux基础
- CentOS
- 连接远程服务器操作
环境查看
[abiu@VM-0-17-centos ~]$ uname -r
3.10.0-1160.11.1.el7.x86_64
[abiu@VM-0-17-centos ~]$ cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
[abiu@VM-0-17-centos ~]$
我的是腾讯云,可以看到内核是3.10以上的,以及系统版本
安装
帮助文档:https://docs.docker.com/engine/install/centos/
- 卸载旧的版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
- 需要的安装包
yum install -y yum-utils
- 设置镜像仓库(默认是国外的,十分慢,建议使用阿里云的,十分快!)
yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 安装docker
更新yum软件包索引
yum makecache fast
安装docker
yum install docker-ce docker-ce-cli containerd.io
- 启动docker
systemctl start docker
- 启动后查看docker信息
docker version
- hello-world
docker run hello-world
执行完命令后,它说没有找到镜像,去pull远程拉取,然后下载成功
8. 查看这个hello-world 镜像
docker images
如果不想玩docker,需要卸载的话,依次执行以下命令
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
腾讯云镜像加速
配置这个以后,以后会非常快
- 执行以下命令,打开 /etc/docker/daemon.json 配置:
vim /etc/docker/daemon.json
- 添加以下内容,并保存。
{"registry-mirrors": [ "https://mirror.ccs.tencentyun.com"]
}
- 重启 Docker 即可
sudo systemctl restart docker
HelloWorld流程
流程分析:
底层原理
docker怎么工作的
docker是client-server结构的系统,docker守护进程在主机上运行,通过socket从客户端连接。
docker-server接收docker-client指令,就会执行这个命令
docker为啥比虚拟机快
- docker有比虚拟机更少的抽象层
2.docker利用宿主机的内核,VM需要Guest OS,docker启动时候不需要像虚拟机那样加载一个操作系统内核,避免引导性操作。docker利用宿主机的操作系统,省略了复杂的过程。
Docker常用命令
帮助命令
docker version # 显示版本信息
docker info # 显示系统信息
systemctl start docker # 启动docker
systemctl stop docker # 停止docker
systemctl restart docker # 重启docker
systemctl status docker # 查看docker状态
systemctl enable docker # 开机启动
docker 命令 --help 帮助命令
帮助文档地址:https://docs.docker.com/reference/
镜像命令
查看镜像:docker images
[root@VM-0-17-centos abiu]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 2 months ago 13.3kB
[root@VM-0-17-centos abiu]#
解释:
REPOSITORY: 镜像仓库
TAG: 镜像标签
IMAGE ID: 镜像id
CREATED: 镜像创建时间
SIZE: 镜像的大小
可选项:docker images --help
[root@VM-0-17-centos abiu]# docker images --help
Usage: docker images [OPTIONS] [REPOSITORY[:TAG]]
List images
Options:
-a, --all Show all images (default hides intermediate images)
--digests Show digests
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print images using a Go template
--no-trunc Don't truncate output
-q, --quiet Only show image IDs
[root@VM-0-17-centos abiu]#
解释:
-a, --all 列出所有镜像
-q, --quiet 只显示镜像id
搜索镜像:docker search
[root@VM-0-17-centos abiu]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10903 [OK]
mariadb MariaDB Server is a high performing open sou… 4115 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 809 [OK]
可选项,通过搜索来过滤
--filter=STARS=9000 搜索出来的就一定是大于9000的
[root@VM-0-17-centos abiu]# docker search mysql --filter=STARS=9000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10903 [OK]
[root@VM-0-17-centos abiu]#
拉取下载镜像:docker pull
使用时候后面带上要下载的镜像,比如:
[root@VM-0-17-centos abiu]# docker pull mysql
Using default tag: latest # 如果mysql后面不带上版本号,默认下载就是最新版本
latest: Pulling from library/mysql
69692152171a: Pull complete # 分层下载
1651b0be3df3: Pull complete
951da7386bc8: Pull complete
0f86c95aa242: Pull complete
37ba2d8bd4fe: Pull complete
6d278bb05e94: Pull complete
497efbd93a3e: Pull complete
f7fddf10c2c2: Pull complete
16415d159dfb: Pull complete
0e530ffc6b73: Pull complete
b0a4a1a77178: Pull complete
cd90f92aa9ef: Pull complete
Digest: sha256:d50098d7fcb25b1fcb24e2d3247cae3fc55815d64fec640dc395840f8fa80969 # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址
[root@VM-0-17-centos abiu]#
指定版本下载:
[root@VM-0-17-centos abiu]# docker pull mysql:5.7
5.7: Pulling from library/mysql
69692152171a: Already exists # 因为刚刚下载过mysql了,所以重复的内容不会下载,显示存在了
1651b0be3df3: Already exists
951da7386bc8: Already exists
0f86c95aa242: Already exists
37ba2d8bd4fe: Already exists
6d278bb05e94: Already exists
497efbd93a3e: Already exists
a023ae82eef5: Pull complete # 正式下载需要下载的东西
e76c35f20ee7: Pull complete
e887524d2ef9: Pull complete
ccb65627e1c3: Pull complete
Digest: sha256:a682e3c78fc5bd941e9db080b4796c75f69a28a8cad65677c23f7a9f18ba21fa
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
[root@VM-0-17-centos abiu]#
所以现在有两个mysql的镜像:
[abiu@VM-0-17-centos root]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 2c9028880e58 10 days ago 447MB
mysql latest c0cdc95609f1 10 days ago 556MB
hello-world latest d1165f221234 2 months ago 13.3kB
[abiu@VM-0-17-centos root]$
删除镜像:docker rmi
docker rmi 后面带上镜像id
[abiu@VM-0-17-centos root]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 2c9028880e58 10 days ago 447MB
mysql latest c0cdc95609f1 10 days ago 556MB
hello-world latest d1165f221234 2 months ago 13.3kB
[abiu@VM-0-17-centos root]$ docker rmi -f 2c9028880e58
Untagged: mysql:5.7
Untagged: mysql@sha256:a682e3c78fc5bd941e9db080b4796c75f69a28a8cad65677c23f7a9f18ba21fa
Deleted: sha256:2c9028880e5814e8923c278d7e2059f9066d56608a21cd3f83a01e3337bacd68
Deleted: sha256:c49c5c776f1bc87cdfff451ef39ce16a1ef45829e10203f4d9a153a6889ec15e
Deleted: sha256:8345316eca77700e62470611446529113579712a787d356e5c8656a41c244aee
Deleted: sha256:8ae51b87111404bd3e3bde4115ea2fe3fd2bb2cf67158460423c361a24df156b
Deleted: sha256:9d5afda6f6dcf8dd59aef5c02099f1d3b3b0c9ae4f2bb7a61627613e8cdfe562
[abiu@VM-0-17-centos root]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest c0cdc95609f1 10 days ago 556MB
hello-world latest d1165f221234 2 months ago 13.3kB
[abiu@VM-0-17-centos root]$
删除多个镜像:docker rmi -f 镜像id,镜像id,镜像id。。。
删除所有镜像:docker rmi -f $(docker images -aq)
容器命令
同理,docker run --help
查看启动容器的所有命令提示文档
创建启动容器常用参数:
docker run [可选参数] image名称
#常用参数说明
--name="tomcat01" # 给要启动的容器起个名字,tomcat01,tomcat02,来区分容器
-d # 后台方式启动
-it # 使用交互方式运行,进入容器查看内容
-p # 指定容器端口,-p 8080:8080
# 多个写法:-p ip:主机端口:容器端口
# -p 主机端口:容器端口
# -p 容器端口
# 容器端口
-P # 随机给容器一个端口
docker container update --restart=always 【容器名字】 # 设置容器开机启动
启动容器示例:刚刚玩镜像时候,把所有镜像都删了,所以现在下载一个CentOS镜像启动吧docker pull centos
[abiu@VM-0-17-centos root]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 300e315adb2f 5 months ago 209MB
[abiu@VM-0-17-centos root]$ docker run -it centos /bin/bash # 启动容器,-it参数表示并进入容器
[root@64c6000ba2d9 /]# ls # 可以看到路径明显不一样,所以查看一下,这些都是容器里的centos目录
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@64c6000ba2d9 /]# exit # 退出容器,exit命令
exit
[abiu@VM-0-17-centos root]$ ls # 很明显路径又回来了
spark-2.4.3-bin-hadoop2.7.tgz ZooInspector.zip
[abiu@VM-0-17-centos root]$
查看容器
docker ps [可选参数]
# 常用参数:
# 不加可选参数的话,只显示正在运行的容器
# -a # a就是all的意思,列出正在运行 和 历史记录运行的容器
# -n=? # 显示最近创建的容器,比如:docker pa -n=1 表示最近创建的一个容器
# -q # 只显示出容器的编号
# -f status=exited # 查看停止的容器
[abiu@VM-0-17-centos root]$ docker ps # 可以看到,之前启动过的centos容器和hello-world容器都显示出来了
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[abiu@VM-0-17-centos root]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
64c6000ba2d9 centos "/bin/bash" 9 minutes ago Exited (0) 9 minutes ago boring_shannon
4e997389bd3c d1165f221234 "/hello" 5 hours ago Exited (0) 5 hours ago adoring_boyd
[abiu@VM-0-17-centos root]$
退出容器
exit # 容器直接停止并退出容器
Ctrl + P + Q # 3个快捷键按下,容器不停止,然后退出容器
删除容器
docker rm 容器id # 删除指定容器, 注意:正在运行的容器不能删除!
docker rm -f $(docker ps -aq) # 删除所有容器
docker ps -a -q|xargs docker rm # 也可以通过管道方式删除所有容器
启动和停止容器
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止正在运行的容器
docker kill 容器id # 强制停止运行的容器,直接杀掉
其他常用命令
后台启动容器
docker run -d images名称
会有一个坑,-d 后台运行容器时候,发现立刻停止了,因为它是后台运行的,不是前台运行的(比如-it),所以容器启动后发现没有提供的服务,就立马停止了
查看日志
docker logs -tf 5ce451541782 # 显示所有日志信息
docker logs -tf --tail 10 5ce451541782 # 显示10条日志信息
# 参数说明:
# # -tf # 显示日志
# # --taill number # 显示日志条数
查看容器进程信息
命令:docker top 容器id
[abiu@VM-0-17-centos root]$ docker top 82e74af26382
UID PID PPID C STIME TTY TIME CMD
root 4733 4714 0 22:40 pts/0 00:00:00 /bin/bash
[abiu@VM-0-17-centos root]$
查看容器元数据
命令:docker inspect 容器id
[abiu@VM-0-17-centos root]$ docker inspect 82e74af26382
[
{
"Id": "82e74af263823a6edb9d12ad5bc2fbd5bd5afaa02c863f947d023c3394417df8",
"Created": "2021-05-22T14:40:49.788085672Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
# 信息量太大......
进入正在运行的容器
我们通常都是后台方式运行容器,如果需要修改配置,是要进入容器里面的
- 第一种方法
命令:docker exec -it 容器id /bin/bash
[abiu@VM-0-17-centos root]$ docker exec -it 82e74af26382 /bin/bash
[root@82e74af26382 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@82e74af26382 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 14:40 pts/0 00:00:00 /bin/bash
root 19 0 0 14:54 pts/1 00:00:00 /bin/bash
root 35 19 0 14:55 pts/1 00:00:00 ps -ef
[root@82e74af26382 /]#
- 第二种方法
命令:docker attach 容器id
这种方式是直接进入到容器里面,容器正在执行中!
[abiu@VM-0-17-centos root]$ docker attach 82e74af26382
容器内文件拷贝到主机上
命令:docker cp 容器id:容器内路径 目的主机路径
先用命令进入到容器内部:docker attach 容器id
然后执行命令拷贝到主机上就行了,退出容器,在主机上查看
拷贝是一个手动过程,可以使用-v
挂载卷的技术,实现文件同步
docker的命令是十分多的,上面的都是常用的基本命令,如果只会上面这些命令,连docker的入门都不算。
简单测试使用
安装Nginx
- 搜索镜像
docker search nginx
建议去网站搜索 https://registry.hub.docker.com/search?q=nginx&type=image - 拉取镜像
docker pull nginx
- 启动容器
docker run -d --name nginx01 -p 3344:80 nginx
启动完以后,我们本机查看是否启动成功
[abiu@VM-0-17-centos ~]$ docker images # 先查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 300e315adb2f 5 months ago 209MB
[abiu@VM-0-17-centos ~]$ docker pull nginx # 拉取镜像
Using default tag: latest
latest: Pulling from library/nginx
69692152171a: Pull complete
49f7d34d62c1: Pull complete
5f97dc5d71ab: Pull complete
cfcd0711b93a: Pull complete
be6172d7651b: Pull complete
de9813870342: Pull complete
Digest: sha256:df13abe416e37eb3db4722840dd479b00ba193ac6606e7902331dcea50f4f1f2
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[abiu@VM-0-17-centos ~]$ docker images # 再次查看,确定nginx镜像拉取成功
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f0b8a9a54136 10 days ago 133MB
centos latest 300e315adb2f 5 months ago 209MB
[abiu@VM-0-17-centos ~]$ docker run -d --name nginx01 -p 3344:80 nginx # 启动容器
b51505e55b49726cfdc80ccc5f3dd20530657a9d8811304689b5fe823205bdcd
[abiu@VM-0-17-centos ~]$ docker ps # 查看容器,启动成功了
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b51505e55b49 nginx "/docker-entrypoint.…" 12 seconds ago Up 11 seconds 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
[abiu@VM-0-17-centos ~]$ curl localhost:3344 # 本机访问nginx
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[abiu@VM-0-17-centos ~]$
curl
命令是访问本地容器
端口暴露的概念
然后浏览器访问我的3344端口测试一下
118.195.176.3 是我的服务器ip,可以看到测试成功
进入容器
[abiu@VM-0-17-centos ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b51505e55b49 nginx "/docker-entrypoint.…" 12 minutes ago Up 12 minutes 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
[abiu@VM-0-17-centos ~]$ docker exec -it nginx01 /bin/bash # 进入容器
root@b51505e55b49:/# whereis nginx # 看是否有nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@b51505e55b49:/# cd /etc/nginx/ # 切换指定目录
root@b51505e55b49:/etc/nginx# ls
conf.d koi-utf mime.types nginx.conf uwsgi_params
fastcgi_params koi-win modules scgi_params win-utf
root@b51505e55b49:/etc/nginx#
测试停止容器
[abiu@VM-0-17-centos ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b51505e55b49 nginx "/docker-entrypoint.…" 15 minutes ago Up 15 minutes 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
[abiu@VM-0-17-centos ~]$ docker stop b51505e55b49
b51505e55b49
[abiu@VM-0-17-centos ~]$
停止以后,肯定是无法访问了
安装Tomcat
官方的使用docker run -it --rm tomcat:9.0
说明:之前启动都是后台,停止容器以后,容器还在,--rm
加上以后,一般用来测试时候用的,容器用完就会被删除。刚开始学习阶段不建议这样,测试的时候可以试试。
那就按照正常程序来吧
- 下载镜像
docker pull tomcat
- 启动tomcat
docker run -d -p 3355:8080 --name tomcat01 tomcat
[abiu@VM-0-17-centos ~]$ docker pull tomcat
Using default tag: latest
latest: Pulling from library/tomcat
Digest: sha256:10842dab06b5e52233ad977d4689522d4fbaa9c21e6df387d7a530e02316fb45
Status: Downloaded newer image for tomcat:latest
docker.io/library/tomcat:latest
[abiu@VM-0-17-centos ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat 9.0 c43a65faae57 9 days ago 667MB
tomcat latest c43a65faae57 9 days ago 667MB
nginx latest f0b8a9a54136 10 days ago 133MB
centos latest 300e315adb2f 5 months ago 209MB
[abiu@VM-0-17-centos ~]$ docker run -d -p 3355:8080 --name tomcat01 tomcat
b3e61706439c0b7d10a461ed75b10eab36817451d141ad0e5493cc9ef74533c4
[abiu@VM-0-17-centos ~]$
启动成功后,我们浏览器访问一下映射的3355端口
发现抱错404,其他证明已经访问成功了,但为啥报错404,自己可以验证一下
[abiu@VM-0-17-centos ~]$ docker exec -it tomcat01 /bin/bash # 进入到容器内部
root@b3e61706439c:/usr/local/tomcat# ls -al # 查看一下,找到webapps目录
total 172
drwxr-xr-x 1 root root 4096 May 13 18:38 .
drwxr-xr-x 1 root root 4096 May 13 05:25 ..
-rw-r--r-- 1 root root 18949 May 8 17:35 BUILDING.txt
-rw-r--r-- 1 root root 5644 May 8 17:35 CONTRIBUTING.md
-rw-r--r-- 1 root root 57092 May 8 17:35 LICENSE
-rw-r--r-- 1 root root 2333 May 8 17:35 NOTICE
-rw-r--r-- 1 root root 3372 May 8 17:35 README.md
-rw-r--r-- 1 root root 6898 May 8 17:35 RELEASE-NOTES
-rw-r--r-- 1 root root 16507 May 8 17:35 RUNNING.txt
drwxr-xr-x 2 root root 4096 May 13 18:39 bin
drwxr-xr-x 1 root root 4096 May 23 07:09 conf
drwxr-xr-x 2 root root 4096 May 13 18:38 lib
drwxrwxrwx 1 root root 4096 May 23 07:09 logs
drwxr-xr-x 2 root root 4096 May 13 18:38 native-jni-lib
drwxrwxrwx 2 root root 4096 May 13 18:38 temp
drwxr-xr-x 2 root root 4096 May 13 18:38 webapps
drwxr-xr-x 7 root root 4096 May 8 17:35 webapps.dist
drwxrwxrwx 2 root root 4096 May 8 17:35 work
root@b3e61706439c:/usr/local/tomcat# cd webapps # 进入到webapps目录
root@b3e61706439c:/usr/local/tomcat/webapps# ls # 查看发现webapps目录里面啥也没有
root@b3e61706439c:/usr/local/tomcat/webapps#
这下就知道为啥了,因为镜像下载时候是最小资源,所以有一些是被阉割了。因为webapps目录时空的,所以访问不到资源
可以发现有一个webapps.dist
root@b3e61706439c:/usr/local/tomcat/webapps# cd ..
root@b3e61706439c:/usr/local/tomcat# ls # 可以看到webapps.dist 目录
BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist
CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work
root@b3e61706439c:/usr/local/tomcat# cd webapps.dist/ # 进入这个目录
root@b3e61706439c:/usr/local/tomcat/webapps.dist# ls # 发现有东西的
ROOT docs examples host-manager manager
root@b3e61706439c:/usr/local/tomcat/webapps.dist# cd ..
root@b3e61706439c:/usr/local/tomcat# cp -r webapps.dist/* webapps # 把webapps.dist目录的资源拷贝到webapps
root@b3e61706439c:/usr/local/tomcat# cd webapps # 切换到webapps
root@b3e61706439c:/usr/local/tomcat/webapps# ls # 看到拷贝成功
ROOT docs examples host-manager manager
root@b3e61706439c:/usr/local/tomcat/webapps#
现在我们可以再次访问tomcat容器试试
安装ES + Kibana
es 暴露的端口很多,十分耗内存,es 的数据一般需要放置到安全目录(挂载)
启动命令:docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discoverey.type=single-node" elasticsearch:7.6.2
启动以后,非常耗内存,非常的卡!因为我的服务器是1核2g的
为了想玩es,还是想试试。。。
等了好长时间,终于好了,建议你们安装es时候,把其他容器全都停了
[abiu@VM-0-17-centos ~]$ docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discoverey.type=single-node" elasticsearch:7.6.2
Unable to find image 'elasticsearch:7.6.2' locally
7.6.2: Pulling from library/elasticsearch
ab5ef0e58194: Pull complete # 开始下载镜像
c4d1ca5c8a25: Pull complete
941a3cc8e7b8: Pull complete
43ec483d9618: Pull complete
c486fd200684: Pull complete
1b960df074b2: Pull complete
1719d48d6823: Pull complete
Digest: sha256:1b09dbd93085a1e7bca34830e77d2981521a7210e11f11eda997add1c12711fa
Status: Downloaded newer image for elasticsearch:7.6.2
28da00bd7864ffc8e22bd38d9429b5b7962a4e239755bea7d254f9f857f3635f # 启动成功
[abiu@VM-0-17-centos ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
28da00bd7864 elasticsearch:7.6.2 "/usr/local/bin/dock…" 14 seconds ago Up 13 seconds 0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 0.0.0.0:9300->9300/tcp, :::9300->9300/tcp elasticsearch
[abiu@VM-0-17-centos ~]$
可以通过命令docker stats
查看一下当前docker状态
通过修改配置让es变得小一些-e
命令加上
[abiu@VM-0-17-centos ~]$ docker run -d --name elasticsearch03 -p 9200:9200 -p 9300:9300 -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
9a711d194ec891dc1674d5dace82e7d3de9aa56e8bbe420dd294f0ec53fb580b
[abiu@VM-0-17-centos ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9a711d194ec8 elasticsearch:7.6.2 "/usr/local/bin/dock…" 3 seconds ago Up 2 seconds 0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 0.0.0.0:9300->9300/tcp, :::9300->9300/tcp elasticsearch03
[abiu@VM-0-17-centos ~]$
Portainer 可视化面板
什么是portainer?
Docker图形化界面管理工具。提供一个后台面板供我们操作。
执行命令:
docker run -d -p 8088:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
示例:
[abiu@VM-0-17-centos ~]$ docker run -d -p 8088:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
Unable to find image 'portainer/portainer:latest' locally
latest: Pulling from portainer/portainer
94cfa856b2b1: Pull complete
49d59ee0881a: Pull complete
a2300fd28637: Pull complete
Digest: sha256:fb45b43738646048a0a0cc74fcee2865b69efde857e710126084ee5de9be0f3f
Status: Downloaded newer image for portainer/portainer:latest
e16f81d106c4802dfe66d541e071c33fbde4cf8183623d1594c53d792dadf8d0
[abiu@VM-0-17-centos ~]$
访问测试
浏览器访问:http://118.195.176.3:8088/ 即可
我们设置密码,然后选择Local 本地的就可以了
进入面板
正常我们很少用这个,了解即可。
Docker镜像详解
镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
所有应用,直接打包成docker镜像,就可以直接跑起来。
如何得到一个镜像:
- 从远程仓库下载
- 朋友拷贝给你
- 自己制作镜像 Dockerfile
镜像加载原理
UnionFS(联合文件系统):Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,Union文件系统是Dokcer镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统加载起来,这样最终的文件系统会包含所有的底层文件和目录
docker的镜像实际上是由一层一层的文件系统构成,这种层级的文件系统UnionFS。
主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的linux/unix系统是一样的,包含boot加载器内核。当boot加载完之后整个内核就都在内存中了,此时内存的使用权已经由bootfs交给内核了,此时系统也会卸载bootfs
平时我们安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M
对以一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就行,因为底层直接用host和kernel,自己只需要提供rootfs就行。由此可见对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。
分层理解
所有镜像都起始于一个基础镜像,当进行修改或增加新的内容时,就会在当前镜像,创建新的镜像层。就好比windows 里的安全补丁。
下载镜像时候加上可选参数inspect
可以完整的看到分层步骤
commit镜像
命令:docker commit -m="提交的描述信息" -a="作者" 镜像名:TAG版本标签
测试:
和上面安装tomcat一样,启动tomcat容器以后,
[abiu@VM-0-17-centos ~]$ docker run -it -p 8080:8080 tomcat
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/openjdk-11
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
23-May-2021 15:01:12.566 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name: Apache Tomcat/9.0.46
// ......
为了方便学习,再重新打开一个命令窗口,进入到容器里,
查看webapps目录是空的
把webapps.dist 目录里的拷贝到webapps 目录下
再次查看webapps目录
然后退出容器
提交这个修改过的镜像容器
查看镜像
root@2c41fe33cedf:/usr/local/tomcat# cp -r webapps.dist/* webapps # 把webapps.dist 目录里的拷贝到webapps 目录下
root@2c41fe33cedf:/usr/local/tomcat# cd webapps
root@2c41fe33cedf:/usr/local/tomcat/webapps# ls 再次查看webapps目录
ROOT docs examples host-manager manager
root@2c41fe33cedf:/usr/local/tomcat/webapps# cd ..
root@2c41fe33cedf:/usr/local/tomcat# exit # 然后退出容器
exit
[abiu@VM-0-17-centos ~]$ docker commit -a="abiu" -m="add webapps app" b3e61706439c tomcat02:1.0 # 提交这个修改过的镜像容器
sha256:beb6fd53ed52c8e767e88052abe3df7214ca3998c08850ecd8c1477b5bbf0add
[abiu@VM-0-17-centos ~]$ docker images # 查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat02 1.0 beb6fd53ed52 24 seconds ago 672MB
tomcat 9.0 c43a65faae57 9 days ago 667MB
tomcat latest c43a65faae57 9 days ago 667MB
nginx latest f0b8a9a54136 11 days ago 133MB
portainer/portainer latest 580c0e4e98b0 2 months ago 79.1MB
centos latest 300e315adb2f 5 months ago 209MB
elasticsearch 7.6.2 f29a1ee41030 14 months ago 791MB
[abiu@VM-0-17-centos ~]$
查看镜像发现tomcat02 比 tomcat 稍微大了一点,因为我往里面加了一些内容嘛,这个tomcat02 就是刚刚提交的镜像。
到此为止,只能算了解了一点docker,根本达不到精通,屁都不是,还要坚持继续学其他的。
《三体》中的一句话:弱小和无知不是生存的障碍,傲慢才是。
容器数据卷
什么是容器数据卷
docker的理念:把应用和环境打包成一个镜像。
那数据呢?如果数据都在容器中,容器删除,数据就会丢失。现在问题来了:数据怎么持久化
比如有一个mysql容器被删了,那就是删库跑路。现在最大的需求是:mysql数据可以存在本地
所以容器之间要有一个数据共享技术,那就是容器数据卷,docker中产生的数据,可以同步到本地。
说白了,就是容器挂载。
总结:卷技术就是容器持久化和同步操作。容器间也可以数据共享了。
使用数据卷
方式一:直接使用命令 -v
docker run -it -v 主机目录:容器内目录
测试:
执行命令
[abiu@VM-0-17-centos ~]$ docker run -it -v /home/ceshicentos:/home centos /bin/bash
[root@3504b975b51b /]#
再打开一个窗口,查看本地的/home目录
[abiu@VM-0-17-centos ~]$ cd /
[abiu@VM-0-17-centos /]$ cd home/
[abiu@VM-0-17-centos home]$ ls
abiu ceshicentos
[abiu@VM-0-17-centos home]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3504b975b51b centos "/bin/bash" About a minute ago Up About a minute bold_euclid
[abiu@VM-0-17-centos home]$ docker inspect 3504b975b51b
[
{
"Id": "3504b975b51bf26299226c8d1acd5d11a88f605d4a0a88f663447dac1181dfd7",
"Created": "2021-05-24T11:20:39.062030099Z",
然后用inspect查看容器信息
对比刚执行的命令,这就是挂载信息
现在测试:
在容器内部的窗口输入命令,新加一个文件
然后在新开窗口切换到目录查看
发现了本地目标目录也有一个test.java文件
测试数据同步
先把容器给停了
在主机连接窗口修改test.java文件
然后再到容器窗口把容器启动起来
发现test.java文件数据发生改变
说明它是双向的一个过程,不管在哪边操作,另一遍数据都会发生变化。
我们修改只需要在本地修改就可以了。
示例:安装MySql
问题:mysql数据持久化问题。
[abiu@VM-0-17-centos ~]$ docker pull mysql:5.7 # 下载mysql5.7镜像
5.7: Pulling from library/mysql
69692152171a: Already exists
1651b0be3df3: Pull complete
951da7386bc8: Pull complete
0f86c95aa242: Pull complete
37ba2d8bd4fe: Pull complete
6d278bb05e94: Pull complete
497efbd93a3e: Pull complete
a023ae82eef5: Pull complete
e76c35f20ee7: Pull complete
e887524d2ef9: Pull complete
ccb65627e1c3: Pull complete
Digest: sha256:a682e3c78fc5bd941e9db080b4796c75f69a28a8cad65677c23f7a9f18ba21fa
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
[abiu@VM-0-17-centos ~]$ 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=123456 --name mysql01 mysql:5.7 # 启动mysql容器,挂载了两个,一个是配置文件,一个是数据, /etc/mysql/conf.d 就是mysql默认配置文件路径,/var/lib/mysql 就是mysql默认数据存放路径
abc0e4885cb5fce012288a87e2330716aebab32b9163ed90effa24cfc55d217a # 启动成功
[abiu@VM-0-17-centos ~]$
启动mysql容器以后,连接测试一下
可以看到连接成功,3310和容器内的3306连接上了。
然后创建一个表test,再去查看容器里是否有相同数据
[abiu@VM-0-17-centos ~]$ cd /home
[abiu@VM-0-17-centos home]$ ls
abiu ceshicentos mysql
[abiu@VM-0-17-centos home]$ cd mysql
[abiu@VM-0-17-centos mysql]$ ls # 挂载的两个都在服务器显示了
conf data
[abiu@VM-0-17-centos mysql]$ cd data # 查看是否有数据
[abiu@VM-0-17-centos data]$ ls # 查看都是mysql默认最初始的数据
auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem
ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys
ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem
[abiu@VM-0-17-centos data]$ ls # mysql客户端新创建一个表test,查看是否同步更新到数据,
auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem
ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys
ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem test
[abiu@VM-0-17-centos data]$
测试删除容器以后,数据是否还在
[abiu@VM-0-17-centos data]$ docker rm -f mysql01 # 把mysql容器直接删了
mysql01
[abiu@VM-0-17-centos data]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[abiu@VM-0-17-centos data]$ ls # 查看数据还在
auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem
ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys
ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem test
可以发现,就是把容器删了,挂载的数据还是存在的,没有丢失。
具名挂载和匿名挂载
具名挂载,如:docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d --name mysql01 mysql:5.7
匿名挂载:docker run -d -P --name nginx01 -v /etc/nginx nginx
-P
大写的P表示随机端口,匿名挂载就是不指定数据挂载到那里的目录
测试一下匿名挂载
[abiu@VM-0-17-centos data]$ docker run -d -P --name nginx01 -v /ect/nginx nginx # 匿名挂载,只写了容器内的路径
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
69692152171a: Pull complete
49f7d34d62c1: Pull complete
5f97dc5d71ab: Pull complete
cfcd0711b93a: Pull complete
be6172d7651b: Pull complete
de9813870342: Pull complete
Digest: sha256:df13abe416e37eb3db4722840dd479b00ba193ac6606e7902331dcea50f4f1f2
Status: Downloaded newer image for nginx:latest
dbf850d08375c3dd21564f54c41f1a3dbeee1ddfb0e13a386e0b9f2d7617c1c9
[abiu@VM-0-17-centos data]$ docker volume ls # 查看挂载信息,发现是这个样子的,这其实都是真实存在的目录
DRIVER VOLUME NAME
local 47f8f24fa0bf4e04b8c1c8f80845802f59a198cc33d056d10b6cac4fdf202706
local aee59c4d11677790a69f4b2c96c8c9a2632e5ca3f3885ac772f5c9cbdc38cdf2
local portainer_data
[abiu@VM-0-17-centos data]$
为了明白,再搞一个具名挂载
[abiu@VM-0-17-centos data]$ docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx # 再启动一个,这次写具体名字
09b670d131d3337881d7b966888e9a191108e57c28b7ddd75fb432ea630b4285
[abiu@VM-0-17-centos data]$ docker volume ls # 查看挂载信息
DRIVER VOLUME NAME
local 47f8f24fa0bf4e04b8c1c8f80845802f59a198cc33d056d10b6cac4fdf202706
local aee59c4d11677790a69f4b2c96c8c9a2632e5ca3f3885ac772f5c9cbdc38cdf2
local juming-nginx # 刚刚起的具名挂载名字,匿名挂载是看不到名字的
local portainer_data
[abiu@VM-0-17-centos data]$
由于这次的具名挂载没有写/跟目录,所以到底挂载到了哪里?
[abiu@VM-0-17-centos ~]$ docker volume inspect juming-nginx # 通过命令查看具名挂载目录
[
{
"CreatedAt": "2021-05-25T21:49:23+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data", # 所有的docker容器内挂载的没有指定目录的话,都在/var/lib/docker/volumes目录下
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
[abiu@VM-0-17-centos ~]$
来看一下这个挂载的路径
[root@VM-0-17-centos docker]# cd /var/lib/docker/
[root@VM-0-17-centos docker]# ls
buildkit containers image network overlay2 plugins runtimes swarm tmp trust volumes
[root@VM-0-17-centos docker]# cd volumes/
[root@VM-0-17-centos volumes]# ls
47f8f24fa0bf4e04b8c1c8f80845802f59a198cc33d056d10b6cac4fdf202706 backingFsBlockDev metadata.db
aee59c4d11677790a69f4b2c96c8c9a2632e5ca3f3885ac772f5c9cbdc38cdf2 juming-nginx portainer_data
[root@VM-0-17-centos volumes]# cd juming-nginx/
[root@VM-0-17-centos juming-nginx]# ls
_data
[root@VM-0-17-centos juming-nginx]# cd _data/
[root@VM-0-17-centos _data]# ls
conf.d koi-utf mime.types nginx.conf uwsgi_params
fastcgi_params koi-win modules scgi_params win-utf
区分是不是具名还是匿名挂载,或者是指定路径挂载
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载
ro 和 rw
# ro readonly 只读
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
# readwrite 可读可写
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
这个就是挂载时候设置了权限,ro 就是只读,rw 就是可读可写(默认的就是rw),如果设置了ro 权限,就不可以更改了,只能从主机(虚拟机)上面更改,容器内部是无法操作的
使用Dockerfile挂载
Dockerfile就是来构建docker镜像的构建文件,这个文件里面都是脚本命令。
通过脚本生存镜像,镜像是一层一层的,脚本命令是一个一个的,每个命令都是一层。
[root@VM-0-17-centos _data]# cd /home # 切到home目录
[root@VM-0-17-centos home]# ls
abiu ceshicentos mysql
[root@VM-0-17-centos home]# mkdir docker-test-volume # 新建一个文件夹
[root@VM-0-17-centos home]# ls
abiu ceshicentos docker-test-volume mysql
[root@VM-0-17-centos home]# pwd
/home
[root@VM-0-17-centos home]# cd docker-test-volume/ 进入到新建的文件夹
[root@VM-0-17-centos docker-test-volume]# pwd
/home/docker-test-volume
[root@VM-0-17-centos docker-test-volume]# vim Dockerfile # 创建一个Dockerfile
[root@VM-0-17-centos docker-test-volume]# cat Dockerfile # 这个Dockerfile里面写了什么,可以看一下
FROM centos # 相当于构建一个centos镜像
VOLUME ["volume01","volume02"] # 创建镜像时候,就去挂载,这是挂载命令,执行了容器目录,等于是匿名挂载
CMD echo "====end====="
CMD /bin/bash
[root@VM-0-17-centos docker-test-volume]# docker build -f Dockerfile -t abiu/centos . # 构建这个Dockerfile
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
latest: Pulling from library/centos
7a0437f04f83: Pull complete
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
---> 300e315adb2f
Step 2/4 : VOLUME ["volume01","volume02"]
---> Running in f9ff9b1ccfdb
Removing intermediate container f9ff9b1ccfdb
---> 0c1a95633408
Step 3/4 : CMD echo "====end====="
---> Running in 56d38278f6af
Removing intermediate container 56d38278f6af
---> 2d6e3120f24d
Step 4/4 : CMD /bin/bash
---> Running in abd6f1f461cc
Removing intermediate container abd6f1f461cc
---> d792c53d4b67
Successfully built d792c53d4b67
Successfully tagged abiu/centos:latest
[root@VM-0-17-centos docker-test-volume]# docker images # 构建成功以后,查看镜像,找下刚刚用Dockerfile构建的镜像有没有成功
REPOSITORY TAG IMAGE ID CREATED SIZE
abiu/centos latest d792c53d4b67 4 minutes ago 209MB
nginx latest f0b8a9a54136 13 days ago 133MB
centos latest 300e315adb2f 5 months ago 209MB
[root@VM-0-17-centos docker-test-volume]# docker run -it abiu/centos /bin/bash # 交互模式启动这个自己构建的镜像
[root@00207eb227fb /]# ls -l 发现进入到这个容器内部了,然后查看一下
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 May 25 14:31 dev
drwxr-xr-x 1 root root 4096 May 25 14:31 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Dec 4 17:37 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 132 root root 0 May 25 14:31 proc
dr-xr-x--- 2 root root 4096 Dec 4 17:37 root
drwxr-xr-x 11 root root 4096 Dec 4 17:37 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 May 18 13:37 sys
drwxrwxrwt 7 root root 4096 Dec 4 17:37 tmp
drwxr-xr-x 12 root root 4096 Dec 4 17:37 usr
drwxr-xr-x 20 root root 4096 Dec 4 17:37 var
drwxr-xr-x 2 root root 4096 May 25 14:31 volume01 # 这两个目录就是生成镜像时候自动挂载的数据卷目录
drwxr-xr-x 2 root root 4096 May 25 14:31 volume02
[root@00207eb227fb /]#
上面可以看到挂载的容器里的目录,既然是挂载,那在容器外面服务器上肯定有对应挂载的目录
那就来验证一下
[root@06aee0c82e50 /]# cd volume01 # 进入到容器内挂载的目录
[root@06aee0c82e50 volume01]# ls
[root@06aee0c82e50 volume01]# touch container.txt # 新建一个文件
[root@06aee0c82e50 volume01]# ls
container.txt
[root@06aee0c82e50 volume01]#
然后新开一个命令窗口,到我们的服务器上查找挂载对应的目录
[root@VM-0-17-centos ~]# docker ps # 查看刚刚启动的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
06aee0c82e50 abiu/centos "/bin/bash" About a minute ago Up About a minute xenodochial_albattani
09b670d131d3 nginx "/docker-entrypoint.…" 49 minutes ago Up 49 minutes 0.0.0.0:49154->80/tcp, :::49154->80/tcp nginx02
dbf850d08375 nginx "/docker-entrypoint.…" 55 minutes ago Up 55 minutes 0.0.0.0:49153->80/tcp, :::49153->80/tcp nginx01
[root@VM-0-17-centos ~]# docker inspect 06aee0c82e50 # 查看这个容器具体信息
[
{
"Id": "06aee0c82e50e33cb98561b939fbf247f2f91b2a030b0c6a5cefd659737f705c",
"Created": "2021-05-25T14:37:15.530825098Z",
......
往下面找它的一个挂载的信息
从而也验证了,那个很长的字符串就是匿名挂载的随机目录
再验证一下那个创建的文件有没有同步过来
执行下面命令切换到指定目录,查看是否有刚刚创建的内容
cd /var/lib/docker/volumes/999613bf974570e05ffcd456fe22147201e2268ecf45e5b0e52cca8dfaf360c7/_data
用Dockerfile挂载非常推荐,因为在使用Dockerfile构建镜像时候如果没有挂载,还有完了以后自己去手动用-v
命令去挂载,所以可以直接在Dockerfile文件里的命令挂载。
数据卷容器
就是容器和容器之间数据同步。命令:--volumes-from
和java里的继承是一样的,子类继承父类,就拥有父类的所有东西,
但是,子容器修改数据,也会同步到父容器的!
一个容器去同步到父容器,这个容器就有父容器的所有数据了。目的就是和别的容器共享数据。
示例:
启动3个容器,就用自己构建的那个centos镜像就可以
[root@VM-0-17-centos /]# docker run -it --name docker01 abiu/centos # -it交互方式启动容器,容器name是docker01
[root@c46017d35701 /]# ls # 看到进入容器内部,查看文件
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
[root@c46017d35701 /]# ls -l # 查看文件,可以看到挂载的那两个目录
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 May 25 14:56 dev
drwxr-xr-x 1 root root 4096 May 25 14:56 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Dec 4 17:37 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 135 root root 0 May 25 14:56 proc
dr-xr-x--- 2 root root 4096 Dec 4 17:37 root
drwxr-xr-x 11 root root 4096 Dec 4 17:37 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 May 18 13:37 sys
drwxrwxrwt 7 root root 4096 Dec 4 17:37 tmp
drwxr-xr-x 12 root root 4096 Dec 4 17:37 usr
drwxr-xr-x 20 root root 4096 Dec 4 17:37 var
drwxr-xr-x 2 root root 4096 May 25 14:56 volume01
drwxr-xr-x 2 root root 4096 May 25 14:56 volume02
[root@c46017d35701 /]#
同样的方法,再启动两个容器,起名字docker02,docker03
Ctrl + q + p
快捷键,不停止容器退出容器
[root@VM-0-17-centos /]# docker run -it --name docker02 --volumes-from docker01 abiu/centos # 用--volumes-from命令去共享刚才启动的docker01容器,这个启动的容器时docker02
[root@33998a4e4288 /]# ls -l # 查看这个docker02
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 May 25 15:03 dev
drwxr-xr-x 1 root root 4096 May 25 15:03 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Dec 4 17:37 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 139 root root 0 May 25 15:03 proc
dr-xr-x--- 2 root root 4096 Dec 4 17:37 root
drwxr-xr-x 11 root root 4096 Dec 4 17:37 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 May 18 13:37 sys
drwxrwxrwt 7 root root 4096 Dec 4 17:37 tmp
drwxr-xr-x 12 root root 4096 Dec 4 17:37 usr
drwxr-xr-x 20 root root 4096 Dec 4 17:37 var
drwxr-xr-x 2 root root 4096 May 25 14:56 volume01
drwxr-xr-x 2 root root 4096 May 25 14:56 volume02
[root@33998a4e4288 /]# cd volume01 # 进入docker02容器的这个目录
[root@33998a4e4288 volume01]# ls # 现在查看是没有文件的
[root@33998a4e4288 volume01]# ls # 把docker01容器新建文件以后,这个再查看,就发现了两个文件,具体看下面命令
01 docker
[root@33998a4e4288 volume01]#
刚刚docker02查看volume01文件啥也没有的时候,我又新开了一个窗口,进入到事先启动了的docker01容器,如下:
[root@VM-0-17-centos /]# docker ps # 查看docker01的容器id
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
33998a4e4288 abiu/centos "/bin/sh -c /bin/bash" 15 seconds ago Up 14 seconds docker02
c46017d35701 abiu/centos "/bin/sh -c /bin/bash" 7 minutes ago Up 7 minutes docker01
[root@VM-0-17-centos /]# docker attach c46017d35701 # 进入到docker01容器
[root@c46017d35701 /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 May 25 14:56 dev
drwxr-xr-x 1 root root 4096 May 25 14:56 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Dec 4 17:37 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 139 root root 0 May 25 14:56 proc
dr-xr-x--- 2 root root 4096 Dec 4 17:37 root
drwxr-xr-x 11 root root 4096 Dec 4 17:37 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 May 18 13:37 sys
drwxrwxrwt 7 root root 4096 Dec 4 17:37 tmp
drwxr-xr-x 12 root root 4096 Dec 4 17:37 usr
drwxr-xr-x 20 root root 4096 Dec 4 17:37 var
drwxr-xr-x 2 root root 4096 May 25 15:06 volume01
drwxr-xr-x 2 root root 4096 May 25 14:56 volume02
[root@c46017d35701 /]# cd volume01 # 进到这个目录
[root@c46017d35701 volume01]# ls # 先查看也是啥也没有
[root@c46017d35701 volume01]# touch docker 01 # 这里着急打错命令了,结果过了个空格,变成创建了两个文件
[root@c46017d35701 volume01]# ls # docker02查看创建成功了,所以docker01容器去再次查看,发现也有同样的数据了
01 docker
[root@c46017d35701 volume01]#
再来验证一下子容器修改内容,会不会同步到父容器
[root@33998a4e4288 volume01]# [root@VM-0-17-centos /]# # Ctrl + q + p 快捷键退出docker02
[root@VM-0-17-centos /]# docker run -it --name docker03 --volumes-from docker01 abiu/centos # 启动一个docker03
[root@9949ba159eaf /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 May 25 15:22 dev
drwxr-xr-x 1 root root 4096 May 25 15:22 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Dec 4 17:37 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 142 root root 0 May 25 15:22 proc
dr-xr-x--- 2 root root 4096 Dec 4 17:37 root
drwxr-xr-x 11 root root 4096 Dec 4 17:37 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 May 18 13:37 sys
drwxrwxrwt 7 root root 4096 Dec 4 17:37 tmp
drwxr-xr-x 12 root root 4096 Dec 4 17:37 usr
drwxr-xr-x 20 root root 4096 Dec 4 17:37 var
drwxr-xr-x 2 root root 4096 May 25 15:07 volume01
drwxr-xr-x 2 root root 4096 May 25 14:56 volume02
[root@9949ba159eaf /]# cd volume01
[root@9949ba159eaf volume01]# ls
01 docker
[root@9949ba159eaf volume01]# touch docker03 # 在这个目录再新加一个文件docker03
[root@9949ba159eaf volume01]# ls
01 docker docker03
[root@9949ba159eaf volume01]#
然后再切回到docker01容器的窗口,查看对应的目录,是否数据同步了
[root@c46017d35701 volume01]# ls
01 docker
[root@c46017d35701 volume01]# ls
01 docker docker03
[root@c46017d35701 volume01]#
所以只要通过--volumes-from
命令,就可以共享容器间的数据
测试停掉并删除一个容器,看数据是否会丢失
[root@9949ba159eaf volume01]# exit # 把docker03容器退出停掉
exit
[root@VM-0-17-centos /]# docker ps # 查看只有两个容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
33998a4e4288 abiu/centos "/bin/sh -c /bin/bash" 24 minutes ago Up 24 minutes docker02
c46017d35701 abiu/centos "/bin/sh -c /bin/bash" 31 minutes ago Up 31 minutes docker01
[root@VM-0-17-centos /]# docker ps -a # 查看docker03容器id
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9949ba159eaf abiu/centos "/bin/sh -c /bin/bash" 6 minutes ago Exited (0) 14 seconds ago docker03
33998a4e4288 abiu/centos "/bin/sh -c /bin/bash" 24 minutes ago Up 24 minutes docker02
c46017d35701 abiu/centos "/bin/sh -c /bin/bash" 31 minutes ago Up 31 minutes docker01
06aee0c82e50 abiu/centos "/bin/bash" 51 minutes ago Exited (0) 34 minutes ago xenodochial_albattani
00207eb227fb abiu/centos "/bin/bash" 57 minutes ago Exited (0) 51 minutes ago agitated_ardinghelli
09b670d131d3 nginx "/docker-entrypoint.…" 2 hours ago Exited (0) 33 minutes ago nginx02
dbf850d08375 nginx "/docker-entrypoint.…" 2 hours ago Exited (0) 33 minutes ago nginx01
[root@VM-0-17-centos /]# docker rm 9949ba159eaf # docker03容器id直接给删除
9949ba159eaf
[root@VM-0-17-centos /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
33998a4e4288 abiu/centos "/bin/sh -c /bin/bash" 25 minutes ago Up 25 minutes docker02
c46017d35701 abiu/centos "/bin/sh -c /bin/bash" 32 minutes ago Up 32 minutes docker01
06aee0c82e50 abiu/centos "/bin/bash" 52 minutes ago Exited (0) 34 minutes ago xenodochial_albattani
00207eb227fb abiu/centos "/bin/bash" 57 minutes ago Exited (0) 52 minutes ago agitated_ardinghelli
09b670d131d3 nginx "/docker-entrypoint.…" 2 hours ago Exited (0) 33 minutes ago nginx02
dbf850d08375 nginx "/docker-entrypoint.…" 2 hours ago Exited (0) 33 minutes ago nginx01
[root@VM-0-17-centos /]#
再切回到docker01容器,查看数据还在
[root@c46017d35701 volume01]# ls
01 docker
[root@c46017d35701 volume01]# ls
01 docker docker03
[root@c46017d35701 volume01]# ls # 查看两次,数据还在
01 docker docker03
[root@c46017d35701 volume01]# ls
01 docker docker03
[root@c46017d35701 volume01]#
Dockerfile
Dockerfile 介绍
Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。
- 对于开发人员:可以为开发团队提供一个完全一致的开发环境;
- 对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfile文件构建一个新的镜像开始工作了;
- 对于运维人员:在部署时,可以实现应用的无缝移植。
构建步骤:
- 编写一个dockerfile文件
- docker build 构建成为一个镜像
- docker run 运行镜像
- docker push 发布镜像(DockerHub、阿里云镜像仓库)
先了解一件事:
我们在DockerHub上面随便搜索一个镜像,比如搜索centos,它会有很多不同的版本信息
然后随便点一个版本的centos,比如centos7这个镜像,它会跳转到一个页面
没错,跳到了GitHub的页面,其实说白了,它就是一个Dockerfile,只不过是个功能比较小的镜像,很多都没有,需要的话都是后期我们自己写Dockerfile构建自己想要的镜像。
比如:我们需要一个centos + jdk + tomcat + mysql + redis 的一个环境,那么我们就要自己去制作一个镜像,把这些需要的写道Dockerfile里面
Dockerfile构建
基础知识
- 每个保留指令都必须是大写字母
- 执行是从上到下顺序执行
#
表示注释- 每个指令都会创建一个新的镜像层并提交
这个图很形象
Dockerfile指令
指令 | 说明 |
---|---|
FROM | 基础镜像层,一切从这里开始构建 |
MAINTAINER | 镜像是谁写的,姓名 + 邮箱 |
RUN | 镜像构建时候需要运行的命令 |
ADD | 添加内容 |
WORKIR | 镜像的工作目录 |
VOLUME | 挂载目录 |
EXPOSE | 暴露端口,如果不写到时还要手动-p暴露 |
CMD | 指定容器启动时候要做的命令,只有最后一个命令生效,会被替换 |
ENTRYPOINT | 容器启动时候要做的命令,可以追加命令 |
ONBUILD | 构建一个被继承的镜像,就会运行这个命令 |
COPY | 类似ADD,把文件拷贝到镜像中 |
ENV | 构建的时候设置环境变量,就是手动-e |
测试构建一个centos
参考一下刚刚官网的那个centos镜像
99%的镜像都是从这个基础镜像过来的,FROM scratch,然后配置需要的软件和配置镜像构建。
创建一个centos
- 编写Dockerfile
[root@VM-0-17-centos home]# mkdir dockerfile # 在home目录创建目录
[root@VM-0-17-centos home]# ls
abiu ceshicentos dockerfile docker-test-volume mysql
[root@VM-0-17-centos home]# cd dockerfile/
[root@VM-0-17-centos dockerfile]# ls
[root@VM-0-17-centos dockerfile]# vim mydockerfile-centos # 编写一个dockerfile
[root@VM-0-17-centos dockerfile]# cat mydockerfile-centos # 看看dockerfile内容
FROM centos # 基于centos
MAINTAINER abiu<1162734840@qq.com> # 作者信息
ENV MYPATH /usr/local # 配置环境变量
WORKDIR $MYPATH # 工作目录是环境变量目录
RUN yum -y install vim # 安装vim命令,因为docker的centos都是简化版的,没有vim命令,不信的话去进入原生的docker里的centos容器试一下
RUN yum -y install net-tools # ifconfig命令
EXPOSE 80 # 暴露端口
CMD echo $MYPATH # 执行打印环境变量路径
CMD echo "====end======" # 打印end
CMD /bin/bash # 启动以后进入哪个命令行
[root@VM-0-17-centos dockerfile]#
- 通过命令构建镜像
docker build -f dockerfile文件名 -t 镜像名:版本号 .
构建后的信息有点长
[root@VM-0-17-centos dockerfile]# docker build -f mydockerfile-centos -t mycentos:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/10 : FROM centos # 去找centos镜像
---> 300e315adb2f
Step 2/10 : MAINTAINER abiu<1162734840@qq.com>
---> Running in bf3a49e66c59
Removing intermediate container bf3a49e66c59
---> d6d94a98c9ca
Step 3/10 : ENV MYPATH /usr/local
---> Running in 42757546a560
Removing intermediate container 42757546a560
---> d004b3268702
Step 4/10 : WORKDIR $MYPATH
---> Running in c597680f294e
Removing intermediate container c597680f294e
---> 67d37409928b
Step 5/10 : RUN yum -y install vim # 安装vim命令
---> Running in 3e159993946d
CentOS Linux 8 - AppStream 1.4 MB/s | 6.3 MB 00:04
CentOS Linux 8 - BaseOS 1.8 MB/s | 2.3 MB 00:01
CentOS Linux 8 - Extras 16 kB/s | 9.6 kB 00:00
Dependencies resolved.
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
vim-enhanced x86_64 2:8.0.1763-15.el8 appstream 1.4 M
Installing dependencies:
gpm-libs x86_64 1.20.7-15.el8 appstream 39 k
vim-common x86_64 2:8.0.1763-15.el8 appstream 6.3 M
vim-filesystem noarch 2:8.0.1763-15.el8 appstream 48 k
which x86_64 2.21-12.el8 baseos 49 k
Transaction Summary
================================================================================
Install 5 Packages
Total download size: 7.8 M
Installed size: 30 M
Downloading Packages:
(1/5): gpm-libs-1.20.7-15.el8.x86_64.rpm 37 kB/s | 39 kB 00:01
(2/5): vim-filesystem-8.0.1763-15.el8.noarch.rp 2.2 MB/s | 48 kB 00:00
(3/5): vim-enhanced-8.0.1763-15.el8.x86_64.rpm 1.1 MB/s | 1.4 MB 00:01
(4/5): which-2.21-12.el8.x86_64.rpm 173 kB/s | 49 kB 00:00
(5/5): vim-common-8.0.1763-15.el8.x86_64.rpm 3.0 MB/s | 6.3 MB 00:02
--------------------------------------------------------------------------------
Total 2.6 MB/s | 7.8 MB 00:02
warning: /var/cache/dnf/appstream-02e86d1c976ab532/packages/gpm-libs-1.20.7-15.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
CentOS Linux 8 - AppStream 1.6 MB/s | 1.6 kB 00:00
Importing GPG key 0x8483C65D:
Userid : "CentOS (CentOS Official Signing Key) <security@centos.org>"
Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : which-2.21-12.el8.x86_64 1/5
Installing : vim-filesystem-2:8.0.1763-15.el8.noarch 2/5
Installing : vim-common-2:8.0.1763-15.el8.x86_64 3/5
Installing : gpm-libs-1.20.7-15.el8.x86_64 4/5
Running scriptlet: gpm-libs-1.20.7-15.el8.x86_64 4/5
Installing : vim-enhanced-2:8.0.1763-15.el8.x86_64 5/5
Running scriptlet: vim-enhanced-2:8.0.1763-15.el8.x86_64 5/5
Running scriptlet: vim-common-2:8.0.1763-15.el8.x86_64 5/5
Verifying : gpm-libs-1.20.7-15.el8.x86_64 1/5
Verifying : vim-common-2:8.0.1763-15.el8.x86_64 2/5
Verifying : vim-enhanced-2:8.0.1763-15.el8.x86_64 3/5
Verifying : vim-filesystem-2:8.0.1763-15.el8.noarch 4/5
Verifying : which-2.21-12.el8.x86_64 5/5
Installed:
gpm-libs-1.20.7-15.el8.x86_64 vim-common-2:8.0.1763-15.el8.x86_64
vim-enhanced-2:8.0.1763-15.el8.x86_64 vim-filesystem-2:8.0.1763-15.el8.noarch
which-2.21-12.el8.x86_64
Complete!
Removing intermediate container 3e159993946d
---> aad2fab4ccf2
Step 6/10 : RUN yum -y install net-tools # 安装ifconfig命令
---> Running in 6964fce7b1be
Last metadata expiration check: 0:00:09 ago on Wed May 26 14:23:47 2021.
Dependencies resolved.
================================================================================
Package Architecture Version Repository Size
================================================================================
Installing:
net-tools x86_64 2.0-0.52.20160912git.el8 baseos 322 k
Transaction Summary
================================================================================
Install 1 Package
Total download size: 322 k
Installed size: 942 k
Downloading Packages:
net-tools-2.0-0.52.20160912git.el8.x86_64.rpm 766 kB/s | 322 kB 00:00
--------------------------------------------------------------------------------
Total 336 kB/s | 322 kB 00:00
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : net-tools-2.0-0.52.20160912git.el8.x86_64 1/1
Running scriptlet: net-tools-2.0-0.52.20160912git.el8.x86_64 1/1
Verifying : net-tools-2.0-0.52.20160912git.el8.x86_64 1/1
Installed:
net-tools-2.0-0.52.20160912git.el8.x86_64
Complete!
Removing intermediate container 6964fce7b1be
---> 1e7b0e49baf0
Step 7/10 : EXPOSE 80 # 暴露80端口
---> Running in 2cea6f50dee9
Removing intermediate container 2cea6f50dee9
---> 65560e2af35b
Step 8/10 : CMD echo $MYPATH # 打印环境变量配置
---> Running in 13b10c7c5f3a
Removing intermediate container 13b10c7c5f3a
---> 19565d9670a9
Step 9/10 : CMD echo "====end======" # 打印end
---> Running in 3742f008903d
Removing intermediate container 3742f008903d
---> 02b6fd1d75ba
Step 10/10 : CMD /bin/bash # 执行到/bin/bash镜像当前目录
---> Running in 37f9467989ae
Removing intermediate container 37f9467989ae
---> b35bf7574ee0
Successfully built b35bf7574ee0
Successfully tagged mycentos:1.0
[root@VM-0-17-centos dockerfile]#
- 测试运行
[root@VM-0-17-centos dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 1.0 7b6629671831 19 seconds ago 291MB
abiu/centos latest d792c53d4b67 24 hours ago 209MB
nginx latest f0b8a9a54136 2 weeks ago 133MB
centos latest 300e315adb2f 5 months ago 209MB
[root@VM-0-17-centos dockerfile]# docker run -it mycentos:1.0 # 启动自己构建的镜像
[root@878c9b515a76 local]# pwd # 默认进入到工作目录
/usr/local
[root@878c9b515a76 local]# ifconfig # ifconfig命令可以用
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.4 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:04 txqueuelen 0 (Ethernet)
RX packets 8 bytes 656 (656.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@878c9b515a76 local]#
对比一下docker里原生的centos镜像
[root@VM-0-17-centos /]# docker run -it centos # 启动原生的centos
[root@049184cdbb69 /]# pwd # 默认是根目录
/
[root@049184cdbb69 /]# vim # 没有vim命令
bash: vim: command not found
[root@049184cdbb69 /]# ifconfig # 没有ifconfig命令
bash: ifconfig: command not found
[root@049184cdbb69 /]# exit
exit
[root@VM-0-17-centos /]#
通过history查看镜像的历史,构建过程
[root@VM-0-17-centos /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 1.0 7b6629671831 33 minutes ago 291MB
abiu/centos latest d792c53d4b67 25 hours ago 209MB
nginx latest f0b8a9a54136 2 weeks ago 133MB
centos latest 300e315adb2f 5 months ago 209MB
[root@VM-0-17-centos /]# docker history 7b6629671831
IMAGE CREATED CREATED BY SIZE COMMENT
7b6629671831 33 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
d89565ffc298 33 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
7de05c658f3e 33 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
dc09b2557a52 33 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
b94e1c3ca848 33 minutes ago /bin/sh -c yum -y install net-tools 23.3MB
a6803051b4cc 33 minutes ago /bin/sh -c yum -y install vim 58MB
bfb7f3489b39 34 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B
811230e462c9 34 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B
63871011852f 34 minutes ago /bin/sh -c #(nop) MAINTAINER abiu<116273484… 0B
300e315adb2f 5 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 5 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 5 months ago /bin/sh -c #(nop) ADD file:bd7a2aed6ede423b7… 209MB
[root@VM-0-17-centos /]#
所以可以通过history
命令查看一个镜像是怎么做的
CMD 和 ENTRYPOINT 区别
COPY 类似ADD,把文件拷贝到镜像中
ENTRYPOINT 容器启动时候要做的命令,可以追加命令
测试cmd
[root@VM-0-17-centos dockerfile]# vim dockerfile-cmd-test # 编写测试cmd的文件
[root@VM-0-17-centos dockerfile]# cat dockerfile-cmd-test
FROM centos # 查看一下,编写的很简单,就两行
CMD ["ls","-a"]
[root@VM-0-17-centos dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest . # 构建镜像
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos
---> 300e315adb2f
Step 2/2 : CMD ["ls","-a"]
---> Running in 078dea88147e
Removing intermediate container 078dea88147e
---> 0f208fb1c52e
Successfully built 0f208fb1c52e
Successfully tagged cmdtest:latest
[root@VM-0-17-centos dockerfile]# docker images # 找刚刚构建的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
cmdtest latest 0f208fb1c52e 29 seconds ago 209MB
mycentos 1.0 7b6629671831 22 hours ago 291MB
abiu/centos latest d792c53d4b67 46 hours ago 209MB
nginx latest f0b8a9a54136 2 weeks ago 133MB
centos latest 300e315adb2f 5 months ago 209MB
[root@VM-0-17-centos dockerfile]# docker run 0f208fb1c52e # 运行一下,执行成功,ls -a 命令生效,显示所有目录
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
[root@VM-0-17-centos dockerfile]#
既然这个镜像构建好了,来测一下cmd命令,看是否会被替换
[root@VM-0-17-centos dockerfile]# docker run 0f208fb1c52e -l # 追加一个-l命令,发现报错,疑问-l把cmd里的ls -a命令给替换了,-l不是命令,所以报错
docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
[root@VM-0-17-centos dockerfile]# docker run 0f208fb1c52e ls -al # 用ls -al正确的命令替换,发现确实没问题的
total 56
drwxr-xr-x 1 root root 4096 May 27 12:30 .
drwxr-xr-x 1 root root 4096 May 27 12:30 ..
-rwxr-xr-x 1 root root 0 May 27 12:30 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 340 May 27 12:30 dev
drwxr-xr-x 1 root root 4096 May 27 12:30 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Dec 4 17:37 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 126 root root 0 May 27 12:30 proc
dr-xr-x--- 2 root root 4096 Dec 4 17:37 root
drwxr-xr-x 11 root root 4096 Dec 4 17:37 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 May 18 13:37 sys
drwxrwxrwt 7 root root 4096 Dec 4 17:37 tmp
drwxr-xr-x 12 root root 4096 Dec 4 17:37 usr
drwxr-xr-x 20 root root 4096 Dec 4 17:37 var
[root@VM-0-17-centos dockerfile]#
测试ENTRYPOINT
[root@VM-0-17-centos dockerfile]# vim dockerfile-entrypoint-test # 编写测试文件
[root@VM-0-17-centos dockerfile]# cat dockerfile-entrypoint-test # 查看一下,和刚刚cmd的测试一样
FROM centos
ENTRYPOINT ["ls","-a"]
[root@VM-0-17-centos dockerfile]# docker build -f dockerfile-entrypoint-test -t entrypoint-test . # 构建镜像
Sending build context to Docker daemon 4.096kB
Step 1/2 : FROM centos
---> 300e315adb2f
Step 2/2 : ENTRYPOINT ["ls","-a"]
---> Running in 3f961da5b222
Removing intermediate container 3f961da5b222
---> 5b9cfe128f0e
Successfully built 5b9cfe128f0e
Successfully tagged entrypoint-test:latest
[root@VM-0-17-centos dockerfile]# docker images # 这里可以发现,一般构建成功后,镜像id会跟在Successfully built 的后面显示
REPOSITORY TAG IMAGE ID CREATED SIZE
entrypoint-test latest 5b9cfe128f0e 19 seconds ago 209MB
cmdtest latest 0f208fb1c52e 13 minutes ago 209MB
mycentos 1.0 7b6629671831 22 hours ago 291MB
abiu/centos latest d792c53d4b67 46 hours ago 209MB
nginx latest f0b8a9a54136 2 weeks ago 133MB
centos latest 300e315adb2f 5 months ago 209MB
[root@VM-0-17-centos dockerfile]# docker run 5b9cfe128f0e # 运行镜像,这里和刚刚cmd那个是一模一样的正常操作
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
[root@VM-0-17-centos dockerfile]# docker run 5b9cfe128f0e -l # 这里追加-l命令后,是可以正常执行的,因为它是追加在ENTRYPOINT命令的后面了,就等于是ls -a -l 命令
total 56
drwxr-xr-x 1 root root 4096 May 27 12:35 .
drwxr-xr-x 1 root root 4096 May 27 12:35 ..
-rwxr-xr-x 1 root root 0 May 27 12:35 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 340 May 27 12:35 dev
drwxr-xr-x 1 root root 4096 May 27 12:35 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Dec 4 17:37 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 120 root root 0 May 27 12:35 proc
dr-xr-x--- 2 root root 4096 Dec 4 17:37 root
drwxr-xr-x 11 root root 4096 Dec 4 17:37 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 May 18 13:37 sys
drwxrwxrwt 7 root root 4096 Dec 4 17:37 tmp
drwxr-xr-x 12 root root 4096 Dec 4 17:37 usr
drwxr-xr-x 20 root root 4096 Dec 4 17:37 var
[root@VM-0-17-centos dockerfile]#
docker中有很多命令很相似,需要了解它们的区别,最好的办法就算对比,然后测试
构建一个Tomcat镜像
-
准备tomcat压缩包 和 jdk压缩包
-
编写
Dockerfile
官网推荐名字就叫Dockerfile,这样每次构建就不用使用-f
命令去寻找,会自己找Dockerfile
Dockerfile内容如下
FROM centos
MAINTAINER abiu<1162734840@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u211-linux-x64.tar.gz /usr/local/ # 把两个压缩包添加到工作目录,ADD命令会自动解压的
ADD apache-tomcat-8.5.34.tar.gz /usr/local/
RUN yum -y install vim # 安装一个vim命令
ENV MYPATH /usr/local # 配置路径
WORKDIR $MYPATH # 工作目录
ENV JAVA_HOME /usr/local/jdk1.8 # 配置jdk和tomcat的环境变量
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.34
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.34
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080 # 暴露端口
CMD /usr/local/apache-tomcat-8.5.34/bin/startup.sh && tail -F /url/local/apache-tomcat-8.5.34/bin/logs/catalina.out # 添加启动命令
再建一个空的 readme.txt文件
- 构建镜像
docker build -t diytomcat .
[root@VM-0-17-centos tomcat]# docker build -t diytomcat .
Sending build context to Docker daemon 204.6MB
Step 1/15 : FROM centos
---> 300e315adb2f
Step 2/15 : MAINTAINER abiu<1162734840@qq.com>
---> Using cache
---> 63871011852f
Step 3/15 : COPY readme.txt /usr/local/readme.txt
---> ad4758754d4c
Step 4/15 : ADD jdk-8u211-linux-x64.tar.gz /usr/local/
---> 7638ced11277
Step 5/15 : ADD apache-tomcat-8.5.34.tar.gz /usr/local/
---> 5f31edb639aa
Step 6/15 : RUN yum -y install vim
// 内容太长......
Step 15/15 : CMD /usr/local/apache-tomcat-8.5.34/bin/startup.sh && tail -F /url/local/apache-tomcat-8.5.34/bin/logs/catalina.out
---> Running in 0be558f08476
Removing intermediate container 0be558f08476
---> 18db1b59c93c
Successfully built 18db1b59c93c
Successfully tagged diytomcat:latest
- 启动镜像
[root@VM-0-17-centos tomcat]# docker images # 查看构建的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
diytomcat latest 18db1b59c93c 9 minutes ago 688MB
entrypoint-test latest 5b9cfe128f0e 56 minutes ago 209MB
cmdtest latest 0f208fb1c52e About an hour ago 209MB
mycentos 1.0 7b6629671831 23 hours ago 291MB
abiu/centos latest d792c53d4b67 47 hours ago 209MB
nginx latest f0b8a9a54136 2 weeks ago 133MB
centos latest 300e315adb2f 5 months ago 209MB
[root@VM-0-17-centos tomcat]# docker run -d -p 9090:8080 --name abiutomcat01 -v /home/abiu/build/tomcat/test:/usr/local/apache-tomcat-8.5.34/webapps/test -v /home/abiu/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-8.5.34/logs diytomcat 启动镜像,挂载了test和日志文件
651b59a92b662b1faa3b0d975714577651c01e8aaedb60510652a2f2bbe25c51
[root@VM-0-17-centos tomcat]# docker exec -it 651b59a92b66 /bin/bash # 启动后进入容器内部
[root@651b59a92b66 local]# ls
apache-tomcat-8.5.34 etc include lib libexec sbin src
bin games jdk1.8.0_211 lib64 readme.txt share
[root@651b59a92b66 local]# pwd # 默认进入的就算工作目录
/usr/local
[root@651b59a92b66 local]# ls -l
total 52
drwxr-xr-x 1 root root 4096 May 27 13:21 apache-tomcat-8.5.34
drwxr-xr-x 2 root root 4096 Nov 3 2020 bin
drwxr-xr-x 2 root root 4096 Nov 3 2020 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 games
drwxr-xr-x 2 root root 4096 Nov 3 2020 include
drwxr-xr-x 7 10 143 4096 Apr 2 2019 jdk1.8.0_211
drwxr-xr-x 2 root root 4096 Nov 3 2020 lib
drwxr-xr-x 3 root root 4096 Dec 4 17:37 lib64
drwxr-xr-x 2 root root 4096 Nov 3 2020 libexec
-rw-r--r-- 1 root root 0 May 27 13:21 readme.txt
drwxr-xr-x 2 root root 4096 Nov 3 2020 sbin
drwxr-xr-x 5 root root 4096 Dec 4 17:37 share
drwxr-xr-x 2 root root 4096 Nov 3 2020 src
[root@651b59a92b66 local]#
-
访问测试
-
发布项目
由于做了挂载,直接在本地编写项目就可以发布了。
在tomcat的test目录下新建一个WEB-INF目录,然后创建web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
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>
再创建一个index.jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("=========my test web logs========");
%>
</body>
</html>
然后访问:ip + 9090/test
发布自己的镜像
发布到DockerHub
DockerHub
- 在 https://hub.docker.com/ 注册自己的账号
- 确保这个账号可以登录
- 在服务器上提交自己的镜像
登录dockerHub,不然怎么提交,提交到哪里?
[root@VM-0-17-centos tomcat]# docker login -u biao1162734840
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 # 登录成功
[root@VM-0-17-centos tomcat]#
- 登录完以后,提交镜像
如果直接这样提交,会被拒绝的,就报错了
[root@VM-0-17-centos tomcat]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
diytomcat latest f13553afc356 10 minutes ago 684MB
entrypoint-test latest 5b9cfe128f0e 2 hours ago 209MB
cmdtest latest 0f208fb1c52e 2 hours ago 209MB
mycentos 1.0 7b6629671831 24 hours ago 291MB
abiu/centos latest d792c53d4b67 2 days ago 209MB
nginx latest f0b8a9a54136 2 weeks ago 133MB
centos latest 300e315adb2f 5 months ago 209MB
[root@VM-0-17-centos tomcat]# docker push nginx
Using default tag: latest
The push refers to repository [docker.io/library/nginx]
f0f30197ccf9: Layer already exists
eeb14ff930d4: Layer already exists
c9732df61184: Layer already exists
4b8db2d7f35a: Layer already exists
431f409d4c5a: Layer already exists
02c055ef67f5: Layer already exists
errors:
denied: requested access to the resource is denied
unauthorized: authentication required
[root@VM-0-17-centos tomcat]#
尝试加一个版本号试试
[root@VM-0-17-centos tomcat]# docker tag f0b8a9a54136 abiu/nginx:1.0 # 给nginx镜像加个tag
[root@VM-0-17-centos tomcat]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
diytomcat latest f13553afc356 17 minutes ago 684MB
entrypoint-test latest 5b9cfe128f0e 2 hours ago 209MB
cmdtest latest 0f208fb1c52e 3 hours ago 209MB
mycentos 1.0 7b6629671831 24 hours ago 291MB
abiu/centos latest d792c53d4b67 2 days ago 209MB
abiu/nginx 1.0 f0b8a9a54136 2 weeks ago 133MB # 可以看到新加了一个镜像
nginx latest f0b8a9a54136 2 weeks ago 133MB
centos latest 300e315adb2f 5 months ago 209MB
[root@VM-0-17-centos tomcat]# docker push abiu/nginx:1.0 # 再次提交,带上版本号
The push refers to repository [docker.io/abiu/nginx]
f0f30197ccf9: Preparing
eeb14ff930d4: Preparing
c9732df61184: Preparing
4b8db2d7f35a: Preparing
431f409d4c5a: Preparing
02c055ef67f5: Waiting
发布到阿里云
登录阿里云,找到容器服务,创建命名空间,
1个账号只能创建3个命名空间
再创建容器镜像(在左边镜像仓库里)
创建完以后,点击镜像直接进去浏览,会有详细教程步骤。
一样的登录:docker login --username=xxxxx 的那一行复制过来直接执行
然后docker pull 镜像名:版本号
直接执行就发布了。
发布以后点击左边 [镜像版本] 就可以看到会有一个版本,别人就可以下载
Docker网络
了解Docker0
为了方便理解,我先把所有镜像和容器全部删除了
卸载:systemctl stop docker
重装阿里云镜像:yum -y remove docker-ce docker-ce-cli containerd.io
安装阿里云镜像以后,把docker 目录都给移除掉:rm -rf /var/lib/docker
先卸载旧版本软件包:
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
再安装需要的软件包:yum install -y yum-utils
设置镜像仓库(使用国内的):yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新一下,不然不是最新的docker: yum makecache fast
安装docker:yum install docker-ce docker-ce-cli containerd.io
安装Docker 的CE,cli,IO(三个核心):yum install docker-ce docker-ce-cli containerd.io
启动:systemctl start docker
使用docker 的hello-world 测试: docker run hello-world
打开 /etc/docker/daemon.json 配置:vim /etc/docker/daemon.json
添加以下内容,并保存:
{
"registry-mirrors": [ "https://mirror.ccs.tencentyun.com"]
}
重启 Docker:sudo systemctl restart docker
测试
查看ip地址命令ip addr
看到三个网络
docker 是怎么处理容器网络访问的?
测试第一个
[root@VM-0-17-centos /]# docker run -d -P --name tomcat01 tomcat # 测试启动一个tomcat
Unable to find image 'tomcat:latest' locally
latest: Pulling from library/tomcat
d960726af2be: Pull complete
e8d62473a22d: Pull complete
8962bc0fad55: Pull complete
65d943ee54c1: Pull complete
da20b77f10ac: Pull complete
8669a096f083: Pull complete
e0c0a5e9ce88: Pull complete
f7f46169d747: Pull complete
42d8171e56e6: Pull complete
774078a3f8bb: Pull complete
Digest: sha256:2c1e400da16a5fceb6615a92cd3de8ba34a71ef726167e902ab0e72e24021da6
Status: Downloaded newer image for tomcat:latest
87beab2c8ed570ca07b9548657bd0aba52c069eb14c09ce214282263a5f1cf96
[root@VM-0-17-centos /]# docker exec -it tomcat01 ip addr # 后面加上ip addr,就是查看容器内部ip,可以这样追加命令执行的
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 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
100: eth0@if101: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@VM-0-17-centos /]#
可以看到查看到容器内部有两个网卡
docker启动的时候,可以看到,有个eth0
这个东西,这个是docker给容器分配的,每个容器都有这么一个地址。
其实可以在linux上面ping通docker的容器里面的
[root@VM-0-17-centos /]# ping 172.17.0.2 # 去ping一下docker容器的地址,可以看到是能ping通的
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.058 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.032 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.036 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.039 ms
^C
--- 172.17.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.032/0.041/0.058/0.011 ms
[root@VM-0-17-centos /]#
原理
我们可以看这个172.17.0.2,这就和路由器原理一样,比如家里的路由器是192.168.0.1,就是路由器的地址,那么你用手机连wifi,就是02的ip,用平板再连wifi,就是03,。。。以此类推
所以每启动一个docker容器,docker就会给容器分配一个ip,那我们只有安装了docker,就会有一个网卡,就是docker0,这是桥接模式,使用的技术是evth-pair技术
服务器启动一个容器后,再次查看网卡
[root@VM-0-17-centos /]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:46:d9:b3 brd ff:ff:ff:ff:ff:ff
inet 10.206.0.17/20 brd 10.206.15.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe46:d9b3/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:94:9e:8e:e8 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:94ff:fe9e:8ee8/64 scope link
valid_lft forever preferred_lft forever
101: veth9901fec@if100: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether d2:01:83:b8:4c:85 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::d001:83ff:feb8:4c85/64 scope link
valid_lft forever preferred_lft forever
[root@VM-0-17-centos /]#
可以看到,服务器上启动一个容器后,多了一个101: veth9901fec@if100:这么个东西,之前没有容器启动时候,只有1.2.3.这三个网卡
我们可以发现的是,容器内也有101: veth9901fec@if100:,是这么的相似
# 下面是容器内的
100: eth0@if101: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# 下面是刚刚查看服务器网卡的
101: veth9901fec@if100: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether d2:01:83:b8:4c:85 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::d001:83ff:feb8:4c85/64 scope link
valid_lft forever preferred_lft forever
测试第二次
我们可以再次启动一个容器,然后查看服务器网卡
[root@VM-0-17-centos /]# docker run -d -P --name tomcat02 tomcat # 再启动一个tomcat容器
9e56040f98113bc9084bd41e23965dd5444523666670f015a0cd9e040721702b
[root@VM-0-17-centos /]# ip addr # 查看服务器网卡
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:46:d9:b3 brd ff:ff:ff:ff:ff:ff
inet 10.206.0.17/20 brd 10.206.15.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe46:d9b3/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:94:9e:8e:e8 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:94ff:fe9e:8ee8/64 scope link
valid_lft forever preferred_lft forever
101: veth9901fec@if100: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether d2:01:83:b8:4c:85 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::d001:83ff:feb8:4c85/64 scope link
valid_lft forever preferred_lft forever
103: veth59a412f@if102: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 52:78:0e:5d:47:b1 brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::5078:eff:fe5d:47b1/64 scope link
valid_lft forever preferred_lft forever
[root@VM-0-17-centos /]#
可以看到多出了一个 103: veth59a412f@if102: ,好玩吧?
我们查看这个tomcat02容器里面的ip
[root@VM-0-17-centos /]# docker exec -it tomcat02 ip addr # 查看tomcat02的ip
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 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
102: eth0@if103: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@VM-0-17-centos /]#
意料之中,tomcat02的ip是172.17.0.3,tomcat02的ip也有对应的102: eth0@if103:
这种一对一对的网卡技术,就是evth-pair技术,它们都是成对出现的,一端连着协议,一端彼此相连。
因为有这个技术,evth-pair充当一个桥梁,连接虚拟网络设备。
简单说明:
OpenStac、Docker容器连接、OVS连接,都是使用的evth-pair技术。
测试两个容器是否可以ping通
使用tomcat02 去ping tomcat01
刚刚已经知道,tomcat02的ip是172.17.0.3,tomcat01的ip是172.17.0.2
[root@VM-0-17-centos /]# docker exec -it tomcat02 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.079 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.037 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.046 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.045 ms
^C
--- 172.17.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 6ms
rtt min/avg/max/mdev = 0.037/0.051/0.079/0.018 ms
[root@VM-0-17-centos /]#
可以看到,确实可以ping通,所以得出结论:容器和容器之间可以ping通
简单原理图:
tomcat01和tomcat02共用同一个路由器,那就是docker0
不指定网络的情况下,都是docker0路由的,它会给容器分配默认的ip
最多可以分配大概65535个
只要删除容器,对应的一对evth也就没了
--link
如果我们的项目,要更换一个数据库,所以连接ip要变,但是不想重启项目,怎么解决这个问题?也就是说如果可以通过名字访问服务器
先来测试一下
[root@VM-0-17-centos /]# docker exec -it tomcat02 ping tomcat01 # 可以看到,直接通过名字tomcat01来ping,ping不通的
ping: tomcat01: Name or service not known
[root@VM-0-17-centos /]#
--link命令可以解决:
[root@VM-0-17-centos /]# docker run -d -P --name tomcat03 --link tomcat02 tomcat # 启动一个tomcat03的时候,加上命令--link,ping通tomcat02
c52a81c37f82a9166095dbf261b54672296b0ade40a749ab9fdd03ef3fa8737e
[root@VM-0-17-centos /]# docker exec -it tomcat03 ping tomcat02 # 测试tomcat03去ping通tomcat02,就可以ping通了
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.040 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.043 ms
^C
--- tomcat02 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.040/0.051/0.072/0.016 ms
[root@VM-0-17-centos /]#
虽然ping通了,先别高兴的太早。
反过来tomcat02可以ping通tomcat03吗,我大概率的可以猜到,肯定不行
[root@VM-0-17-centos /]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
[root@VM-0-17-centos /]#
探究
查看tomcat03容器里面的hosts文件,可以发现直接把tomcat02给通过ip配置到了hosts文件里,所以可以ping通,--link就是在hosts配置中增加一个绑定ip的配置
这样是不好的,直接写死了,不建议使用。
自定义网络
查看所有docker网络
[root@VM-0-17-centos /]# docker network ls
NETWORK ID NAME DRIVER SCOPE
e99a82e1c4f0 bridge bridge local
9883346cfda1 host host local
cbf451bab0ea none null local
[root@VM-0-17-centos /]#
- bridge 就是docker0网络,桥接方式的,也是默认的
- none 就是不配置网络
- host 和宿主机共享网络
测试
其实每次启动容器的时候都有一个默认的命令:--net bridge
这个是默认的,所以平常不怎么肉眼看到,就算不加这个命令,也是生效的,bridge就算docker0
如:
docker run -d -P --name tomcat01 --net bridge tomcat
示例:
[root@VM-0-17-centos /]# docker rm -f $(docker ps -aq) # 把容器都给删除,确保docker没有其他容器的网络,方便测试
c52a81c37f82
9e56040f9811
87beab2c8ed5
[root@VM-0-17-centos /]# ip addr # 确认查看,服务器现在只有这三个网络了
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:46:d9:b3 brd ff:ff:ff:ff:ff:ff
inet 10.206.0.17/20 brd 10.206.15.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe46:d9b3/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:94:9e:8e:e8 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:94ff:fe9e:8ee8/64 scope link
valid_lft forever preferred_lft forever
[root@VM-0-17-centos /]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet # 创建一个自定义的网络
4d1d798a13de706ba1b262e6bd5851fba2ceff1c020a0c9ced1accbd0920fb4a
[root@VM-0-17-centos /]# docker network ls # 查看,确实创建好了
NETWORK ID NAME DRIVER SCOPE
e99a82e1c4f0 bridge bridge local
9883346cfda1 host host local
4d1d798a13de mynet bridge local
cbf451bab0ea none null local
[root@VM-0-17-centos /]#
命令说明:
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
- --driver bridge 默认的,其实这个不写也可以的
- --subnet 192.168.0.0/16 设置网段,这个配置就是:192.168.0.2 到 192.168.255.255,就是65535个
- --gateway 192.168.0.1 设置路由器网络
既然自定义的网络创建好了,来查看一下吧
[root@VM-0-17-centos /]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "4d1d798a13de706ba1b262e6bd5851fba2ceff1c020a0c9ced1accbd0920fb4a",
"Created": "2021-05-29T00:37:30.283847557+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": {},
"Options": {},
"Labels": {}
}
]
[root@VM-0-17-centos /]#
确实没有毛病,那就使用以下自定义网络
[root@VM-0-17-centos /]# docker run -d --name tomcat-net-01 --net mynet tomcat # 启动两个容器,使用mynet这个网络
d562f6913d9ad001be71bcaa11f3c394ac1097b6a16a7c7bb3d3c20a5ad58010
[root@VM-0-17-centos /]# docker run -d --name tomcat-net-02 --net mynet tomcat
085fadbdb58d2f7cc26055e32559d543f0ea9fa78db4f4294aa55d2cb32b3349
[root@VM-0-17-centos /]# docker network inspect mynet # 启动完两个容器以后,再来查看一下mynet
[
{
"Name": "mynet",
"Id": "4d1d798a13de706ba1b262e6bd5851fba2ceff1c020a0c9ced1accbd0920fb4a",
"Created": "2021-05-29T00:37:30.283847557+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": {
"085fadbdb58d2f7cc26055e32559d543f0ea9fa78db4f4294aa55d2cb32b3349": {
"Name": "tomcat-net-02",
"EndpointID": "b4ad8673c13b15d7f738d9223029be849958faa72f7ce58584146fc1ee9212e6",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"d562f6913d9ad001be71bcaa11f3c394ac1097b6a16a7c7bb3d3c20a5ad58010": {
"Name": "tomcat-net-01",
"EndpointID": "8f5e09ed205a221cca6e8892e2ff1a3aa4624e716378cf07dd045aa777520bcf",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
[root@VM-0-17-centos /]#
可以看到上面的这个内容:
两个容器分配的网络是192.168.0.3 和 192.168.0.3
使用容器名字ping通网络
上面看到了,自定义的网络创建好了,我们直接来试试这个自定义网络能不能ping通容器间的网络
自定义的网络是直接可以通过容器名字ping通的,自定义的网络很完善
[root@VM-0-17-centos /]# docker exec -it tomcat-net-01 ping 192.168.0.3 # 和之前一样通过ip让tomcat-net-01pingtomcat-net-02,肯定是没问题的
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.045 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.046 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.042 ms
^C
--- 192.168.0.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.042/0.044/0.046/0.005 ms
[root@VM-0-17-centos /]# docker exec -it tomcat-net-01 ping tomcat-net-02 # 然后通过容器名字来ping,发现也是可以ping通的!不使用--link命令也可以ping通了
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.034 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.046 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.046 ms
^C
--- tomcat-net-02 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2ms
rtt min/avg/max/mdev = 0.034/0.042/0.046/0.005 ms
[root@VM-0-17-centos /]#
我们自定义的网络docker已经帮我们维护好了对应的关系,docker自己的默认网络是不行的,所以推荐自定义使用网络
网络连通
基于上面的网络知识能知道自定义的网络是可以直接通过容器名字ping通的,那么来考虑下这种情况
docker0的tomcat-01能不能直接去ping通mynet的tomcat-net-01??
试一试?
[root@VM-0-17-centos /]# docker run -d -it --name tomcat01 tomcat # 启动两个基于docker0网络的tomcat容器
e18d1888872890dec00e5f4677aa37dd4d76d6974664bf3e4cb3c1a60ae9b3da
[root@VM-0-17-centos /]# docker run -d -it --name tomcat02 tomcat
132f1ab45c8072465089f3ba7dcae98ce6bf5bca8273041f40c94a54fa41d106
[root@VM-0-17-centos /]# docker ps # 可以看到这四个容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
132f1ab45c80 tomcat "catalina.sh run" 6 seconds ago Up 5 seconds 8080/tcp tomcat02
e18d18888728 tomcat "catalina.sh run" 10 seconds ago Up 9 seconds 8080/tcp tomcat01
085fadbdb58d tomcat "catalina.sh run" 17 minutes ago Up 17 minutes 8080/tcp tomcat-net-02
d562f6913d9a tomcat "catalina.sh run" 17 minutes ago Up 17 minutes 8080/tcp tomcat-net-01
[root@VM-0-17-centos /]# docker exec -it tomcat01 ping tomcat-net-01 # 很明显,这样根本无法ping通
ping: tomcat-net-01: Name or service not known
[root@VM-0-17-centos /]#
正确的方法应该是这样:
tomcat01去和mynet打通
可以通过connect命令直接把网络和容器打通
[root@VM-0-17-centos /]# docker network connect mynet tomcat01 # 执行connect命令
[root@VM-0-17-centos /]# docker network inspect mynet # 执行完connect命令没有提示,来看一下mynet网络的文件
[
{
"Name": "mynet",
"Id": "4d1d798a13de706ba1b262e6bd5851fba2ceff1c020a0c9ced1accbd0920fb4a",
"Created": "2021-05-29T00:37:30.283847557+08:00",
"Scope": "local",
// ......
可以往下找到我们需要看的内容
真牛逼,直接把tomcat01放到mynet网络了,就这样直接打通了。
一个容器两个ip,两个ip当然也都可以访问。
现在可以再试一下,tomcat01是否可以ping通tomcat-net-01
[root@VM-0-17-centos /]# docker exec -it tomcat01 ping tomcat-net-01 # 测试确实可以连通了
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.051 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.042 ms
^C
--- tomcat-net-01 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1ms
rtt min/avg/max/mdev = 0.042/0.046/0.051/0.008 ms
[root@VM-0-17-centos /]# docker exec -it tomcat02 ping tomcat-net-01 # 因为tomcat02没有连通mynet,所以肯定不能ping通
ping: tomcat-net-01: Name or service not known
[root@VM-0-17-centos /]#
项目打包成镜像
-
创建一个springboot项目,随便写个测试接口,测试项目正常可用
然后把这个项目打成jar包 -
编写Dockerfile
把jar包和Dockerfile上传到服务器 -
打包镜像测试
[root@VM-0-17-centos conf]# cd /home # 到home目录下
[root@VM-0-17-centos home]# ls
abiu ceshicentos dockerfile docker-test-volume mysql
[root@VM-0-17-centos home]# mkdir idea # 新建一个目录
[root@VM-0-17-centos home]# cd idea/
[root@VM-0-17-centos idea]# ll # 查看Dockerfile和jar包上传成功
总用量 17188
-rw-r--r-- 1 root root 17593149 5月 29 16:26 demo-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root 120 5月 29 16:25 Dockerfile
[root@VM-0-17-centos idea]# docker build -t abiu666 . # 执行构建镜像命令,别忘记最后还有个点 .
Sending build context to Docker daemon 17.6MB
Step 1/5 : FROM java:8
8: Pulling from library/java
5040bd298390: Pull complete
fce5728aad85: Pull complete
76610ec20bf5: Pull complete
60170fec2151: Pull complete
e98f73de8f0d: Pull complete
11f7af24ed9c: Pull complete
49e2d6393f32: Pull complete
bb9cdec9c7f3: Pull complete
Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d
Status: Downloaded newer image for java:8
---> d23bdf5b1b1b
Step 2/5 : COPY *.jar /app.jar
---> 43b0ad951883
Step 3/5 : CMD ["--server.port=8080"]
---> Running in e95ae597eb6e
Removing intermediate container e95ae597eb6e
---> cb2f714697dc
Step 4/5 : EXPOSE 8080
---> Running in b69707c9de44
Removing intermediate container b69707c9de44
---> a18566323d80
Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]
---> Running in ee1689172d8c
Removing intermediate container ee1689172d8c
---> 0c3bfc91b397
Successfully built 0c3bfc91b397
Successfully tagged abiu666:latest
[root@VM-0-17-centos idea]# docker images # 打包镜像成功后,查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
abiu666 latest 0c3bfc91b397 10 seconds ago 661MB
java 8 d23bdf5b1b1b 4 years ago 643MB
[root@VM-0-17-centos idea]# docker run -d -P --name abiu-springboot-web abiu666 # 运行容器
56248042e829dbb2bed199f96583d97f4175f4ffdb427dda827ce37a1efb3d22
[root@VM-0-17-centos idea]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
56248042e829 abiu666 "java -jar /app.jar …" 22 seconds ago Up 21 seconds 0.0.0.0:49158->8080/tcp, :::49158->8080/tcp abiu-springboot-web
[root@VM-0-17-centos idea]# curl localhost:49158/hello # 本地访问测试
hello[root@VM-0-17-centos idea]#
Docker Compose
为了方便学习,把docker 先都给卸载干净
- 卸载:
systemctl stop docker
- 重装阿里云镜像:
yum -y remove docker-ce docker-ce-cli containerd.io
- 安装阿里云镜像以后,把docker 目录都给移除掉:
rm -rf /var/lib/docker
卸载完以后,docker的命令就没有了,然后再安装:
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
再安装需要的软件包:
yum install -y yum-utils
设置镜像仓库(使用国内的):
yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新一下,不然不是最新的docker
yum makecache fast
安装Docker 的CE,cli,IO(三个核心)
yum install docker-ce docker-ce-cli containerd.io
启动docker
systemctl start docker
然后使用docker 的hello-world 测试
docker run hello-world
配置云镜像加速
- 打开 /etc/docker/daemon.json 配置:
vim /etc/docker/daemon.json
- 添加以下内容,并保存。
{"registry-mirrors": [ "https://mirror.ccs.tencentyun.com"]
}
- 重启 Docker 即可
sudo systemctl restart docker
Docker Compose简介
之前说的每次构建项目镜像都要写个Dockerfile,然后build,最后run,这还只能操作单个容器,其实挺麻烦的。
比如公司里现在都是微服务,如果有100个微服务,每个服务模块都要这样操作,听且这100个微服务都还存在依赖关系,都要手动去启动,太麻烦了。
Docker Compose可以轻松高效的管理容器,定义运行多个容器。
官方介绍
地址:https://docs.docker.com/compose/
结论:
- 定义、运行多个容器。
- 需要一个YAML file配置文件
- 需要个简单的命令
- 所有的环境都依赖于Compose
三步骤:
- Dockerfile包装在任何地方都可以允许
- 定义一个服务,写个docker-compose.yml文件
- 启动项目,命令:
docker-compose up
作用:批量容器编排。
个人理解
Compose 是Docker 官方的开源项目,需要安装才可以用。
Dockerfile 让程序在任何地方都可以运行。
官方给的docker-compose.Yml示例
version: "3.9" # optional since v1.27.0
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
简单看一下,services肯定就里面放的就算服务,这个示例有两个服务,一个web,一个redis,
这个web服务里有links到redis,所以这个服务肯定先启动redis镜像,然后在启动web应用,这个文件一但运行起来,这个应用就和redis同时运行起来了。而之前的时候都是一个一个服务去run运行的。
compose概念
services:容器、应用。
一个项目就是一组关联的容器。
安装compose
官方地址:https://docs.docker.com/compose/install/
- 下载
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
通过命令可以看到下载到了/usr/local/bin
目录,查看一下这个目录
- 授权
sudo chmod +x /usr/local/bin/docker-compose
我们现在已经在这个目录了,直接执行这个命令就好了
[root@VM-0-17-centos bin]# sudo chmod +x docker-compose
[root@VM-0-17-centos bin]# docker-compose version
docker-compose version 1.29.2, build 5becea4c
docker-py version: 5.0.0
CPython version: 3.7.10
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
[root@VM-0-17-centos bin]#
查看版本号,可以看到安装成功
体验compose
官网地址:https://docs.docker.com/compose/gettingstarted/
第一步
- 创建目录
[root@VM-0-17-centos bin]# cd /home
[root@VM-0-17-centos home]# mkdir composetest
[root@VM-0-17-centos home]# cd composetest/
[root@VM-0-17-centos composetest]# ls
[root@VM-0-17-centos composetest]#
- 创建一个python文件,然后把官网的脚本添加进去
[root@VM-0-17-centos composetest]# vim app.py
[root@VM-0-17-centos composetest]# cat app.py
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
[root@VM-0-17-centos composetest]#
通过这个python脚本大概能看出,时间,redis,
然后导入一个Flask框架,
然后用了reids缓存cache,
然后有个方法,意思就算每次调用这个方法就会自增,
最后就算每次访问这个页面就调用这个方法,会返回一个字符串
- 在添加一个文本文件
[root@VM-0-17-centos composetest]# vim requirements.txt
[root@VM-0-17-centos composetest]# cat requirements.txt
flask
redis
[root@VM-0-17-centos composetest]#
第二步,创建Dockerfile
[root@VM-0-17-centos composetest]# vim Dockerfile
[root@VM-0-17-centos composetest]# cat Dockerfile
# syntax=docker/dockerfile:1
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
[root@VM-0-17-centos composetest]#
第三步,在compose定义一个服务
先创建一个docker-compose.yml,然后跟着官网把内容粘进去
[root@VM-0-17-centos composetest]# vim docker-compose.yml
[root@VM-0-17-centos composetest]# cat docker-compose.yml
version: "3.9"
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
[root@VM-0-17-centos composetest]#
到此为止,composetest目录下一共有4个文件了
第四步,构建运行compose
命令:docker-compose up
执行过程可能会很长,启动以后,我们重新打开一个窗口,会看到一个起了两个服务容器,redis和web
[root@VM-0-17-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ff5d6d3d5674 redis:alpine "docker-entrypoint.s…" 24 minutes ago Up 24 minutes 6379/tcp composetest_redis_1
9d14221ba7fc composetest_web "flask run" 24 minutes ago Up 24 minutes 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp composetest_web_1
访问curl localhost:5000
我们每访问一次,访问的计数就会+1
[root@VM-0-17-centos ~]# curl localhost:5000
Hello World! I have been seen 1 times.
# ......
[root@VM-0-17-centos ~]# curl localhost:5000
Hello World! I have been seen 4 times.
[root@VM-0-17-centos ~]# curl localhost:5000
Hello World! I have been seen 5 times.
[root@VM-0-17-centos ~]# curl localhost:5000
Hello World! I have been seen 6 times.
[root@VM-0-17-centos ~]# curl localhost:5000
Hello World! I have been seen 7 times.
[root@VM-0-17-centos ~]#
相应的,起的服务那个窗口也会有日志信息
再来看一下镜像,可以发现有composetest_web,还有redis和python的依赖
查看网络规则
composetest_default服务启动以后,会生成一个自己的网络,这一个项目里的内容用的都是同一个网段里面的
通过docker network inspect composetest_default
命令,查看docker network inspect composetest_default项目的网络细节
可以看到,web和redsi都在这个项目的网络里,那么它们就可以通过容器服务名字来访问了
我们再来看一下官方给的那个pyhton脚本:
可以发现连接的redis是通过域名访问的,而不是通过ip访问的,如果不是在同一个网络下,通过服务名肯定是ping不通的,这样的作法非常好,如果以后比如redisip变了,可人家是通过服务名访问的,所以脚本文件根本不用动
为什么默认的服务名是 文件名_服务名_数字 ??
停止docker-compose
官网给了几种方法,最简单的就是直接在启动docker-compose服务的那个窗口,Ctrl + C
Compose配置文件编写规则
compose里面命令关键字非常的多,但是只要记住规则就还好
官网:https://docs.docker.com/compose/compose-file/compose-file-v3/
一共只有3层:
官方示例:
version: "3.9" # 版本,没有是不行的
services: # 服务是核心配置,下面是服务配置
webapp:
build: ./dir
# 其他配置,比如:网络、卷、全局规则
volumes:
networks:
configs:
打开官网,看右边有明细的说明用法
用的注意依赖关系:
compose一键搭建WP博客
到现在位置,我们已经知道compose这么方便,什么都只需要一个compose文件就可以搞定,来跟着官网搭建一个wordpress博客吧,贼简单
https://docs.docker.com/samples/wordpress/
- 找个地方创建一个目录my_wordpress,然后进入这个目录
- 编辑一个docker-compose.yml文件,把官网的给全部粘过来
version: "3.9"
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
- 启动项目:
docker-compose up
或者后台启动,这个也是可以后台启动的,加上-d参数:docker-compose up -d
配置文件中写到wordpress的暴露端口是8000,那我们启动后浏览器访问一下:118.195.176.3:8000/
当然这是我自己的ip,然后访问成功
选择最下面的简体中文,然后填写信息,直接安装,然后登录
登录成功进入到博客的后台页面
点击正中间的那个查看站点
所以现在来说,搭建一个博客真的是有手就行~
测试编写微服务上线
- 编写项目微服务
写个springboot项目吧,加上web和redis依赖
然后写个测试接口
配置文件,通过服务名字连接的哦
- 编写Dockerfile
- 编写docker-compose.yml
- 丢到服务器去启动
在服务器创建两个目录
[root@VM-0-17-centos my_wordpress]# cd /home
[root@VM-0-17-centos home]# mkdir abiuapp
[root@VM-0-17-centos home]# cd abiuapp/
把项目打成jar包,和Dockerfile、docker-compose一起丢到服务器
然后直接命令docker-compose up
启动
浏览器访问1次,访问2次,访问3次
遇到一个坑,执行启动命令发现报错,最终发现时打jar包出错,只有4kb的大小,显然是不可能的
如果重新执行命令,最好是docker-compose up --build
重新构建