学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能干嘛

虚拟化技术

image
虚拟化技术缺点

  1. 资源占用多
  2. 冗余步骤多
  3. 启动很慢

容器化技术

容器化技术不是模拟的完整的操作系统
image
Docker和虚拟机的区别:

  • 虚拟机虚拟出一个硬件,运行一个完整的操作系统,然后在这个系统上安装和运行
  • 容器的应用直接运行在宿主机的内核中,容器自己没有内核,也没有虚拟硬件,所以轻便
  • 容器间相互间隔,每个容器都有自己的文件系统,互不影响

Docker安装

Docker组成

image
镜像(image)
docker镜像就等于是一个模板,可以通过这个模板创建一个或者多个容器(镜像运行起来就是容器),容器提供服务,最终的服务运行在容器里的。

容器(container)
docker利用容器技术,独立运行一个或者一组应用,可以理解为一个简易的Linux系统。

仓库(repository)
存放镜像的地方。仓库分公有仓库和私有仓库。
Docker Hub(默认是国外的),所以很慢,我们要配置国内的阿里云容器服务来镜像加速。

Docker安装

准备环境

  1. 会一点Linux基础
  2. CentOS
  3. 连接远程服务器操作

环境查看

[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/

  1. 卸载旧的版本
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
  1. 需要的安装包
yum install -y yum-utils
  1. 设置镜像仓库(默认是国外的,十分慢,建议使用阿里云的,十分快!)
yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  1. 安装docker
    更新yum软件包索引
yum makecache fast

安装docker

yum install docker-ce docker-ce-cli containerd.io
  1. 启动docker
systemctl start docker
  1. 启动后查看docker信息
docker version
  1. hello-world
docker run hello-world

image
执行完命令后,它说没有找到镜像,去pull远程拉取,然后下载成功
8. 查看这个hello-world 镜像

docker images

image

如果不想玩docker,需要卸载的话,依次执行以下命令

yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
rm -rf /var/lib/containerd

腾讯云镜像加速

配置这个以后,以后会非常快

  1. 执行以下命令,打开 /etc/docker/daemon.json 配置:
vim /etc/docker/daemon.json
  1. 添加以下内容,并保存。
{"registry-mirrors": [ "https://mirror.ccs.tencentyun.com"]
}
  1. 重启 Docker 即可
sudo systemctl restart docker

HelloWorld流程

image

流程分析:
image

底层原理

docker怎么工作的

docker是client-server结构的系统,docker守护进程在主机上运行,通过socket从客户端连接。
docker-server接收docker-client指令,就会执行这个命令
image

docker为啥比虚拟机快

  1. docker有比虚拟机更少的抽象层
    image
    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

[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,
	# 信息量太大......

进入正在运行的容器

我们通常都是后台方式运行容器,如果需要修改配置,是要进入容器里面的

  1. 第一种方法
    命令: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 /]# 
  1. 第二种方法
    命令:docker attach 容器id
    这种方式是直接进入到容器里面,容器正在执行中!
[abiu@VM-0-17-centos root]$ docker attach 82e74af26382

容器内文件拷贝到主机上

命令:docker cp 容器id:容器内路径 目的主机路径
先用命令进入到容器内部:docker attach 容器id
然后执行命令拷贝到主机上就行了,退出容器,在主机上查看

拷贝是一个手动过程,可以使用-v挂载卷的技术,实现文件同步

image

docker的命令是十分多的,上面的都是常用的基本命令,如果只会上面这些命令,连docker的入门都不算。

简单测试使用

安装Nginx

  1. 搜索镜像 docker search nginx 建议去网站搜索 https://registry.hub.docker.com/search?q=nginx&type=image
  2. 拉取镜像 docker pull nginx
  3. 启动容器 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 命令是访问本地容器

端口暴露的概念

image

然后浏览器访问我的3344端口测试一下
118.195.176.3 是我的服务器ip,可以看到测试成功
image

进入容器

[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 ~]$ 

停止以后,肯定是无法访问了
image

安装Tomcat

官方的使用docker run -it --rm tomcat:9.0
说明:之前启动都是后台,停止容器以后,容器还在,--rm 加上以后,一般用来测试时候用的,容器用完就会被删除。刚开始学习阶段不建议这样,测试的时候可以试试。

那就按照正常程序来吧

  1. 下载镜像docker pull tomcat
  2. 启动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端口
image
发现抱错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容器试试

image

安装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状态
image

通过修改配置让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/ 即可
image

我们设置密码,然后选择Local 本地的就可以了

image

进入面板

image
正常我们很少用这个,了解即可。

Docker镜像详解

镜像是什么

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。

所有应用,直接打包成docker镜像,就可以直接跑起来。
如何得到一个镜像:

  • 从远程仓库下载
  • 朋友拷贝给你
  • 自己制作镜像 Dockerfile

镜像加载原理

UnionFS(联合文件系统):Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,Union文件系统是Dokcer镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统加载起来,这样最终的文件系统会包含所有的底层文件和目录

docker的镜像实际上是由一层一层的文件系统构成,这种层级的文件系统UnionFS。
image
主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的linux/unix系统是一样的,包含boot加载器内核。当boot加载完之后整个内核就都在内存中了,此时内存的使用权已经由bootfs交给内核了,此时系统也会卸载bootfs

平时我们安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M

image

对以一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就行,因为底层直接用host和kernel,自己只需要提供rootfs就行。由此可见对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。

分层理解

所有镜像都起始于一个基础镜像,当进行修改或增加新的内容时,就会在当前镜像,创建新的镜像层。就好比windows 里的安全补丁。
image
下载镜像时候加上可选参数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中产生的数据,可以同步到本地。

说白了,就是容器挂载。
image
总结:卷技术就是容器持久化和同步操作。容器间也可以数据共享了。

使用数据卷

方式一:直接使用命令 -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查看容器信息
image
对比刚执行的命令,这就是挂载信息

现在测试:
在容器内部的窗口输入命令,新加一个文件
image

然后在新开窗口切换到目录查看
image

发现了本地目标目录也有一个test.java文件

测试数据同步

先把容器给停了
image

在主机连接窗口修改test.java文件
image

然后再到容器窗口把容器启动起来
image

发现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容器以后,连接测试一下
image
可以看到连接成功,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",
......

往下面找它的一个挂载的信息
image

从而也验证了,那个很长的字符串就是匿名挂载的随机目录

再验证一下那个创建的文件有没有同步过来
执行下面命令切换到指定目录,查看是否有刚刚创建的内容

cd /var/lib/docker/volumes/999613bf974570e05ffcd456fe22147201e2268ecf45e5b0e52cca8dfaf360c7/_data

用Dockerfile挂载非常推荐,因为在使用Dockerfile构建镜像时候如果没有挂载,还有完了以后自己去手动用-v命令去挂载,所以可以直接在Dockerfile文件里的命令挂载。

数据卷容器

就是容器和容器之间数据同步。命令:--volumes-from
和java里的继承是一样的,子类继承父类,就拥有父类的所有东西,
但是,子容器修改数据,也会同步到父容器的!
image
一个容器去同步到父容器,这个容器就有父容器的所有数据了。目的就是和别的容器共享数据。

示例:
启动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]# 

image

Dockerfile

Dockerfile 介绍

Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。

  1. 对于开发人员:可以为开发团队提供一个完全一致的开发环境;
  2. 对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfile文件构建一个新的镜像开始工作了;
  3. 对于运维人员:在部署时,可以实现应用的无缝移植。

构建步骤:

  1. 编写一个dockerfile文件
  2. docker build 构建成为一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub、阿里云镜像仓库)

先了解一件事:

我们在DockerHub上面随便搜索一个镜像,比如搜索centos,它会有很多不同的版本信息
image

然后随便点一个版本的centos,比如centos7这个镜像,它会跳转到一个页面

image

没错,跳到了GitHub的页面,其实说白了,它就是一个Dockerfile,只不过是个功能比较小的镜像,很多都没有,需要的话都是后期我们自己写Dockerfile构建自己想要的镜像。

比如:我们需要一个centos + jdk + tomcat + mysql + redis 的一个环境,那么我们就要自己去制作一个镜像,把这些需要的写道Dockerfile里面

Dockerfile构建

基础知识

  1. 每个保留指令都必须是大写字母
  2. 执行是从上到下顺序执行
  3. # 表示注释
  4. 每个指令都会创建一个新的镜像层并提交

这个图很形象
image

Dockerfile指令

指令 说明
FROM 基础镜像层,一切从这里开始构建
MAINTAINER 镜像是谁写的,姓名 + 邮箱
RUN 镜像构建时候需要运行的命令
ADD 添加内容
WORKIR 镜像的工作目录
VOLUME 挂载目录
EXPOSE 暴露端口,如果不写到时还要手动-p暴露
CMD 指定容器启动时候要做的命令,只有最后一个命令生效,会被替换
ENTRYPOINT 容器启动时候要做的命令,可以追加命令
ONBUILD 构建一个被继承的镜像,就会运行这个命令
COPY 类似ADD,把文件拷贝到镜像中
ENV 构建的时候设置环境变量,就是手动-e
image

测试构建一个centos

参考一下刚刚官网的那个centos镜像
99%的镜像都是从这个基础镜像过来的,FROM scratch,然后配置需要的软件和配置镜像构建。
image

创建一个centos

  1. 编写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]# 
  1. 通过命令构建镜像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]# 
  1. 测试运行
[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镜像

  1. 准备tomcat压缩包 和 jdk压缩包
    image

  2. 编写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文件

  1. 构建镜像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
  1. 启动镜像
[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]# 
  1. 访问测试
    image

  2. 发布项目
    由于做了挂载,直接在本地编写项目就可以发布了。

在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
image

发布自己的镜像

发布到DockerHub

DockerHub

  1. https://hub.docker.com/ 注册自己的账号
  2. 确保这个账号可以登录
  3. 在服务器上提交自己的镜像
    登录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]# 
  1. 登录完以后,提交镜像
    如果直接这样提交,会被拒绝的,就报错了
[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个命名空间
image
再创建容器镜像(在左边镜像仓库里)
image

创建完以后,点击镜像直接进去浏览,会有详细教程步骤。
image
一样的登录:docker login --username=xxxxx 的那一行复制过来直接执行

然后docker pull 镜像名:版本号直接执行就发布了。

发布以后点击左边 [镜像版本] 就可以看到会有一个版本,别人就可以下载
image

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
image
看到三个网络

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充当一个桥梁,连接虚拟网络设备。
简单说明:
image
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个
image
只要删除容器,对应的一对evth也就没了

如果我们的项目,要更换一个数据库,所以连接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的配置
这样是不好的,直接写死了,不建议使用。
image

自定义网络

查看所有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 /]# 

可以看到上面的这个内容:
image
两个容器分配的网络是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通的,那么来考虑下这种情况
image
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打通
image
可以通过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",
	// ......

可以往下找到我们需要看的内容
image
真牛逼,直接把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 /]# 

项目打包成镜像

  1. 创建一个springboot项目,随便写个测试接口,测试项目正常可用
    image
    image
    然后把这个项目打成jar包

  2. 编写Dockerfile
    image
    把jar包和Dockerfile上传到服务器

  3. 打包镜像测试

[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]# 

image

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/
image
结论:

  • 定义、运行多个容器。
  • 需要一个YAML file配置文件
  • 需要个简单的命令
  • 所有的环境都依赖于Compose

三步骤:

  1. Dockerfile包装在任何地方都可以允许
  2. 定义一个服务,写个docker-compose.yml文件
  3. 启动项目,命令: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/

  1. 下载
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目录,查看一下这个目录
image

  1. 授权
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/

第一步

  1. 创建目录
[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]# 
  1. 创建一个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,
然后有个方法,意思就算每次调用这个方法就会自增,
最后就算每次访问这个页面就调用这个方法,会返回一个字符串

  1. 在添加一个文本文件
[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个文件了
image

第四步,构建运行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 ~]# 

相应的,起的服务那个窗口也会有日志信息
image

再来看一下镜像,可以发现有composetest_web,还有redis和python的依赖
image

查看网络规则

composetest_default服务启动以后,会生成一个自己的网络,这一个项目里的内容用的都是同一个网段里面的
image

通过docker network inspect composetest_default命令,查看docker network inspect composetest_default项目的网络细节
image
可以看到,web和redsi都在这个项目的网络里,那么它们就可以通过容器服务名字来访问了

我们再来看一下官方给的那个pyhton脚本:
image
可以发现连接的redis是通过域名访问的,而不是通过ip访问的,如果不是在同一个网络下,通过服务名肯定是ping不通的,这样的作法非常好,如果以后比如redisip变了,可人家是通过服务名访问的,所以脚本文件根本不用动

为什么默认的服务名是 文件名_服务名_数字 ??

停止docker-compose

官网给了几种方法,最简单的就是直接在启动docker-compose服务的那个窗口,Ctrl + C
image

Compose配置文件编写规则

compose里面命令关键字非常的多,但是只要记住规则就还好
官网:https://docs.docker.com/compose/compose-file/compose-file-v3/

一共只有3层:
官方示例:

version: "3.9"		# 版本,没有是不行的
services:		# 服务是核心配置,下面是服务配置
  webapp:
    build: ./dir

# 其他配置,比如:网络、卷、全局规则
volumes:
networks:
configs:

打开官网,看右边有明细的说明用法
image
用的注意依赖关系:
image

compose一键搭建WP博客

到现在位置,我们已经知道compose这么方便,什么都只需要一个compose文件就可以搞定,来跟着官网搭建一个wordpress博客吧,贼简单
https://docs.docker.com/samples/wordpress/

  1. 找个地方创建一个目录my_wordpress,然后进入这个目录
  2. 编辑一个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: {}
  1. 启动项目:docker-compose up
    或者后台启动,这个也是可以后台启动的,加上-d参数:docker-compose up -d

配置文件中写到wordpress的暴露端口是8000,那我们启动后浏览器访问一下:118.195.176.3:8000/当然这是我自己的ip,然后访问成功
image
选择最下面的简体中文,然后填写信息,直接安装,然后登录
image

登录成功进入到博客的后台页面
image

点击正中间的那个查看站点
image

所以现在来说,搭建一个博客真的是有手就行~

测试编写微服务上线

  1. 编写项目微服务
    写个springboot项目吧,加上web和redis依赖
    然后写个测试接口
    image
    配置文件,通过服务名字连接的哦
    image
  2. 编写Dockerfile
    image
  3. 编写docker-compose.yml
    image
  4. 丢到服务器去启动
    在服务器创建两个目录
[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一起丢到服务器
image

然后直接命令docker-compose up启动
image

浏览器访问1次,访问2次,访问3次
image
image
image

遇到一个坑,执行启动命令发现报错,最终发现时打jar包出错,只有4kb的大小,显然是不可能的

如果重新执行命令,最好是docker-compose up --build重新构建

Docker Swarm

CI/CD--Jenkins

posted @ 2021-06-01 10:56  aBiu--  阅读(654)  评论(0编辑  收藏  举报