docker基础

docker基础

1.docker 介绍

docker是什么

docker理念:一次构建封装到处运行

docker:解决了运行环境和配置问题软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。

docker能干嘛

1.之前的虚拟机技术

2.容器虚拟化技术

3.开发/运维

4.企业级

与虚拟机的区别

虚拟机可以在一种操作系统里面运行另一种操作系统,比如在Windows里面运行linux系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对与底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。这类虚拟机完美的运行了另一套系统,能够使应用程序,操作系统和硬件三者之间的逻辑不变。

虚拟机的缺点

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

比较docker和传统虚拟机的不同:
1.传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整的操作系统,在该系统上再运行所需应用进程;
2.而容器内的应用进程直接运行与宿主机的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便;
3.每个容器之间互相隔离,每个容器有自己的文件系统,容器之间进程不会互相影响,能区分计算资源。
docker容器 虚拟机(VM)
操作系统 与宿主机共享OS 宿主机OS上运行虚拟机OS
存储大小 镜像小,便于存储与传输 镜像庞大
运行性能 几乎无额外性能损失 操作系统额外的CPU、内存消耗
移植性 轻便、灵活、适应于linux 笨重,与虚拟化技术耦合度高
硬件亲和性 面向软件开发者 面向硬件运维者
启动速度 快速,秒级 慢,分钟级

为什么用docker

更轻量:基于容器的虚拟化,仅包含业务运行所需的runtime环境,CentOS/Ubuntu基础镜像仅170M;宿主机可部署100-1000个容器

更高效:无操作系统虚拟化开销

计算:轻量,无额外开销
存储:系统盘aufs/dm/overlayfs;数据盘:volume
网络:宿主机网络,NS隔离

更敏捷、更灵活

分层的存储和包管理,devops理念
支持多种网络配置

docker的优势

轻量,秒级的快速启动速度

简单,易用,活跃的社区

标准统一的打包/部署/运行方案

镜像支持增量分发,易于部署

易于构建,良好的REST API ,也很适合自动化测试和持续集成

性能,尤其是内存和IO开销

**docker官网:**http://www.docker.com

**docker中文网站:**https://www.docker-cn.com

2.docker安装

前提说明:支持centos6.5以上版本

docker基本组成:

仓库:是集中存放镜像文件的场所
镜像(image):就是一个只读的模板,镜像可以用来创建docker容器,一个镜像可以创建很多容器。容器运行是需要环境的而镜像就是提供这些环境的。
容器(container):独立运行的一个或一组应用。容器是用镜像创建的运行实例。

总结:

Docker 本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就视乎image镜像文件。只有通过这个镜像文件才能生成Docker容器。image文件可以看做是容器的模板。Docker根据image文件生成容器的实例。同一个image文件,可以生成多个同时运行的容器实例。

image文件生成的容器实例,本身也是一个文件,称为镜像文件
一个容器运行一种服务,当我们需要的时候,就可以通过docker客户端创建一个对应的运行实例,也就是我们的容器
至于仓库,就是放了一推镜像的地方,我们可以把镜像发布到仓库中,需要的时候从仓库中拉下来就可以了

docker 安装:

# 确认你是centos7以上版本,然后安装gcc,gcc-c++
# step 1: 安装必要的一些系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加软件源信息,要确保centos7能上外网
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 3: 更新并安装 Docker-CE
sudo yum makecache fast
sudo yum -y install docker-ce
# Step 4: 开启Docker服务
sudo service docker start

# 解决:需要:container-selinux >= 2:2.74的问题
yum install --setopt=obsoletes=0 \
   docker-ce-17.03.2.ce-1.el7.centos.x86_64 \
   docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch # on a new system with yum repo defined, forcing older version and ignoring obsoletes introduced by 17.06.0

卸载docker:
systemctl stop docker
yum -y remove docker-ce
rm -rf /var/lib/docker

注意:其他注意事项在下面的注释中
# 官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,你可以通过以下方式开启。同理可以开启各种测试版本等。
# vim /etc/yum.repos.d/docker-ce.repo
#   将 [docker-ce-test] 下方的 enabled=0 修改为 enabled=1
#
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# yum list docker-ce.x86_64 --showduplicates | sort -r
#   Loading mirror speeds from cached hostfile
#   Loaded plugins: branch, fastestmirror, langpacks
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            docker-ce-stable
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            @docker-ce-stable
#   docker-ce.x86_64            17.03.0.ce-1.el7.centos            docker-ce-stable
#   Available Packages
# Step2 : 安装指定版本的Docker-CE: (VERSION 例如上面的 17.03.0.ce.1-1.el7.centos)
# sudo yum -y install docker-ce-[VERSION]
# 注意:在某些版本之后,docker-ce安装出现了其他依赖包,如果安装失败的话请关注错误信息。例如 docker-ce 17.03 之后,需要先安装 docker-ce-selinux。
# yum list docker-ce-selinux- --showduplicates | sort -r
# sudo yum -y install docker-ce-selinux-[VERSION]

# 通过经典网络、VPC网络内网安装时,用以下命令替换Step 2中的命令
# 经典网络:
# sudo yum-config-manager --add-repo http://mirrors.aliyuncs.com/docker-ce/linux/centos/docker-ce.repo
# VPC网络:
# sudo yum-config-manager --add-repo http://mirrors.could.aliyuncs.com/docker-ce/linux/centos/docker-ce.repo

阿里云镜像加速

是什么 :https://dev.aliyun.com/search.html
注册一个属于自己的阿里云账户(可复用淘宝账号)
获得加速器地址链接:1.登陆阿里云开发者平台 2.获取加速器地址
配置本机docker运行镜像加速器
重启docker后台服务
linux系统下配置完加速器需要检查是否生效

 配置镜像加速器:
[root@97 ~]# mkdir -p /etc/docker
[root@97 ~]#  tee /etc/docker/daemon.json <<-'EOF'
> {
>   "registry-mirrors": ["https://vrg74rno.mirror.aliyuncs.com"]
> }
> EOF
# 也可以配置网易云镜像加速
{
  "registry-mirrors": ["http://hub-mirror.c.163.com"]
}

[root@97 ~]# systemctl daemon-reload
[root@97 ~]# systemctl restart docker

[root@localhost ~]# docker info	 # 从结果中看到以下内容就ok
Registry Mirrors:
 https://vrg74rno.mirror.aliyuncs.com

docker运行流程图

docker基础_第1张图片

docker的底层原理

docker是怎样工作的:docker是一个CS结构的系统,docker守护进程运行在主机上,然后通过socket连接从客户端访问,守护进程从客户端接收命令并管理运行在主机上的容器。容器,是一个运行时环境,就是我们所说的集装箱

docker为什么比vm快:docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机上的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。

docker基础_第2张图片

3.docker常用命令

帮助命令

docker version  显示docker版本信息
docker info  
docker --help  万能命令

镜像命令

docker images # 列出本地主机上的镜像

选项 :

-a # 列出本地所有的镜像(含中间映像层)

-q # 只显示镜像的ID

–digests # 显示镜像的摘要信息

–no-trunc # 显示完整的镜像信息

[root@97 ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              fce289e99eb9        15 months ago       1.84kB

# REPOSITORY:表示镜像的仓库源
# TAG:镜像的标签
# IMAGE ID:镜像的ID
# CREATED:镜像创建的时间
# SIZE:镜像大小
# -a --all  列出所有镜像
# -q --quiet  只显示镜像的id

同一个仓库源可以有多个tag,代表这个仓库的不同个版本,我们使用 repository:tag 来定义不同的镜像。

docker search # 从http://hup.docker.com网站中查找镜像

语法:

docker search [options]镜像的名字

选项:

–filter=STARS=3000 : 搜索出来的镜像就是STARS大雨3000的

–no-trunc:显示完整的镜像描述

-s :列出收藏数不小于指定值的镜像

–automated:只显示automated build类型的镜像

[root@localhost ~]# docker search mysql --filter=STARS=3000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   10899     [OK]       
mariadb   MariaDB Server is a high performing open sou…   4113      [OK]

[root@97 ~]# docker search -s 1000 nginx
Flag --stars has been deprecated, use --filter=stars=3 instead
NAME    DESCRIPTION      			STARS           OFFICIAL            AUTOMATED
nginx   Official build of Nginx.    12948               [OK]                
jwilder/nginx-proxy   Automated Nginx reverse proxy for docker con…   1768     [OK]       

docker pull # 下载镜像

docker pull tomcat 等价于 docker pull tomcat:latest(可以接版本号)	#冒号后面不接版本号默认下载最新版
[root@97 ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
c499e6d256d6: Pull complete 
74cda408e262: Pull complete 
ffadbd415ab7: Pull complete 
Digest: sha256:282530fcb7cd19f3848c7b611043f82ae4be3781cb00105a1d593d7e6286b596
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[root@97 ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              ed21b7a8aee9        9 days ago          127MB
hello-world         latest              fce289e99eb9        15 months ago       1.84kB
[root@localhost ~]# docker pull mysql:5.7  下载固定版本镜像
5.7: Pulling from library/mysql
69692152171a: Already exists 
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@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
mysql         5.7       2c9028880e58   8 days ago     447MB
mysql         latest    c0cdc95609f1   8 days ago     556MB
hello-world   latest    d1165f221234   2 months ago   13.3kB

docker rmi #删除某个镜像

# 删除单个
docker rmi hello-world:latest	# 后面不跟版本号默认删除的是latest最新的 #后面镜像名和镜像ID都可以
docker rmi -f 2c9028880e58  #根据容器id删除
docker rmi -f hello-world	# -f 强制删除
# 删除多个
docker rmi -f hello-world nginx
# 删除全部
docker rmi -f $(docker images -qa)

容器命令

有镜像才能创建容器,这是根本前提(下载一个centos镜像演示)

docker pull centos

新建并启动镜像

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
OPTIONS 说明:
--name="容器新名字" :为容器指定一个名称
-d:后台运行容器,并返回容器ID,也即启动守护式容器
-i:以交换模式运行容器,通常与 -t 同时使用
-t:为容器重新分配一个伪输入终端,通畅与 -i 同时使用
-P:随机端口映射
-p:指定端口映射,有以下四种格式
ip:hostPort:containerPort  ip:主机端口:容器端口
ip:conrainerPort  ip:容器端口
hostPort:containerPort  主机端口:容器端口
containerPort 容器端口

# 新建容器并启动,会在新的docker里面的centos的/目录下面
[root@localhost ~]# docker run -it centos /bin/bash
[root@e31eeea69e22 /]# ls  # 查看容器内的centos,基础版本,很多命令都不完善
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@e31eeea69e22 /]# exit  #从容器退出到主机
exit

列出当前所有正在运行的容器

[root@97 ~]# docker ps
CONTAINER ID   IMAGE      COMMAND       CREATED      STATUS        PORTS      NAMES
ab9486eb362f   centos   "/bin/bash"  9 minutes ago   Up 9 minutes         musing_lalande

NAME就是 --name指定的别名,没有指定就使用默认NAME

docker ps 常用选项

-a	列出当前所有正在运行的容器和历史上运行过的容器
-l	显示最近创建的容器
-n	显示最近n个创建的容器
-q	静默模式,只显示容器编号
--no-trunc	不截断输出

[root@97 ~]# docker ps -q
ab9486eb362f

退出容器的两种方法

exit 容器停止退出

ctrl+P+Q 容器不停止退出

启动容器

docker start 容器ID或者容器名

[root@97 ~]# docker ps -n 3  显示最近创建的3个容器
CONTAINER ID    IMAGE       COMMAND    CREATED      STATUS        PORTS         NAMES
9edbc71d62bc    cento     "/bin/bash" 5 minutes ago  Exited (0) 5 minutes ago  myctos
ab9486eb362f    centos    "/bin/bash" 4 days ago     Up 4 days             musing_lalande

[root@97 ~]# docker ps  列出正在运行的容器
CONTAINER ID      IMAGE     COMMAND      CREATED      STATUS    PORTS       NAMES
ab9486eb362f      centos   "/bin/bash"   4 days ago   Up 4 days         musing_lalande
[root@97 ~]# docker start 9edbc71d62bc
9edbc71d62bc

[root@97 ~]# docker ps
CONTAINER ID   IMAGE      COMMAND      CREATED        STATUS       PORTS   NAMES
9edbc71d62bc   centos   "/bin/bash"  5 minutes ago   Up 2 seconds          myctos
ab9486eb362f   centos   "/bin/bash"  4 days ago      Up 4 days        musing_lalande

重启容器

docker restart 容器ID或容器名
docker restart 9edbc71d62bc

停止容器

docker stop 容器ID或者容器名

docker stop 9edbc71d62bc

强制停止容器

docker kill 容器ID或容器名

docker kill 9edbc71d62bc

删除已停止的容器

[root@97 ~]# docker stop 9edbc71d62bc
9edbc71d62bc
[root@97 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND     CREATED      STATUS      PORTS         NAMES
ab9486eb362f   centos  "/bin/bash"  4 days ago   Up 4 days            musing_lalande

[root@97 ~]# docker ps -n 2
CONTAINER ID   IMAGE    COMMAND     CREATED          STATUS        PORTS        NAMES
9edbc71d62bc   centos  "/bin/bash"  20 minutes ago   Exited (0) 2 minutes ago   myctos
ab9486eb362f   centos  "/bin/bash"   4 days ago      Up 4 days            musing_lalande
[root@97 ~]# docker rm 9edbc71d62bc  #不能删除正在运行的容器
[root@97 ~]# docker rm ab9486eb362f -f	#删除没有停止的容器加-f强制删除

一次性删除多个容器

docker rm -f $(docker ps -a -q)  #删除所有容器
docker ps -a -q | xargs docker rm  #删除所有容器

启动守护式容器

docker run -d 容器名   #后台启动
[root@97 ~]# docker run -d centos
74558d5b6bfb0034d99d2d675bdbaff8914647d8c463b21e134d63d20e4441d7

[root@97 ~]# docker ps
CONTAINER ID      IMAGE      COMMAND      CREATED      STATUS      PORTS       NAMES

# 问题:然后docker ps 进行查看,发现容器已经退出
  说明:如果不是那些一直挂起的命令(top tail)就是会自动退出的
  重点:docker容器后台运行就必须要有一个前台进程
[root@97 ~]# docker run -d centos /bin/bash -c "while true;do echo zz;sleep 2;done"
ec25dc5cafc03578d963cb129ea9cf0b215b716434019b7d08df93aa3c65a190
[root@97 ~]# docker ps
CONTAINER ID   IMAGE    COMMAND                 CREATED      STATUS   PORTS     NAMES
ec25dc5cafc0   centos  "/bin/bash -c 'while…"  3 seconds ago  Up 3second  bold_goldwasser

查看docker日志

docker logs -f -t --tail 容器ID
-t	是加入时间戳
-f 	是跟随最新的日志打印
--tail 数字 显示最后的多少条
-tf  显示日志
[root@97 ~]# docker logs ec25dc5cafc0
zz
zz
zz
...
[root@97 ~]# docker logs -t -f --tail 3 ec25dc5cafc0  显示指定行数的日志
2020-04-15T09:09:08.290949108Z zz
2020-04-15T09:09:10.293420735Z zz
2020-04-15T09:09:12.296657506Z zz
...

查看容器内运行的进程

docker top 容器ID
[root@localhost ~]# docker top b75a8e22f7cb
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                20116               20095               0                   01:11               pts/0               00:00:00            /bin/bash

查看容器内部细节

docker inspect 容器ID

进入正在运行的容器并以命令交互

docker attach 容器ID		是直接进入容器启动命令终端,不会启动新的进程
docker exec -it 容器ID	是在容器中打开新的终端,并且可以启动新的进程

[root@97 ~]# docker run -it centos
[root@7de493efe07b /]# Ctrl+p+q	#不停止退出

## attach方式进入容器
[root@localhost ~]# docker attach b75a8e22f7cb   
[root@b75a8e22f7cb /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

##exec方式进入容器
[root@localhost ~]# docker exec -it b75a8e22f7cb(容器ID) /bin/bash(进入的命令)
[root@b75a8e22f7cb /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
#exec方式登录可以不进入容器执行命令返回结果,attach方式必须先进去容器然后执行操作

从容器内拷贝文件到主机上

docker cp 容器ID:容器内路径 目的主机路径

[root@localhost ~]# docker attach b75a8e22f7cb
[root@b75a8e22f7cb /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@b75a8e22f7cb /]# cd home/
[root@b75a8e22f7cb home]# touch 123.txt
[root@b75a8e22f7cb home]# ls
123.txt
[root@b75a8e22f7cb home]# exit
exit
[root@localhost ~]# docker cp b75a8e22f7cb:/home/123.txt /home
[root@localhost ~]# ls /home/
123.txt  xiaoxiong

docker命令图片小结

docker基础_第3张图片

docker基础_第4张图片

docker基础_第5张图片

docker部署nginx

[root@localhost ~]# docker search nginx  查看nginx的版本
[root@localhost ~]# docker pull nginx   下载默认最新版本
[root@localhost ~]# docker images  查看下载的镜像
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
nginx         latest    d1a364dc548d   41 hours ago   133MB
hello-world   latest    d1165f221234   2 months ago   13.3kB
centos        latest    300e315adb2f   5 months ago   209MB

#-d 后台运行
#-p 宿主机端口:容器端口

[root@localhost ~]# docker run -d -p 3344:80 nginx
40f4eb339b7dbdd4d8195c85f5a156cf413bc99d373d0eefb1648d3ec479c597
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
40f4eb339b7d   nginx     "/docker-entrypoint.…"   19 seconds ago   Up 11 seconds   0.0.0.0:3344->80/tcp, :::3344->80/tcp   pedantic_chatterjee

[root@localhost ~]# curl localhost:3344  访问到了nginx镜像服务



Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

[root@localhost ~]# docker exec -it 40f4eb339b7d /bin/bash 进入容器 root@40f4eb339b7d:/# cd /etc/nginx/ 容器内的nginx配置文件 root@40f4eb339b7d:/etc/nginx# ls conf.d fastcgi_params mime.types modules nginx.conf scgi_params uwsgi_params

docker安装tomcat

[root@localhost ~]# docker run -it --rm tomcat  --rm常用于测试,用完之后会自动删除
[root@localhost ~]# docker pull tomcat:9.0  普通下载启动
[root@localhost ~]# docker run -d -p 3355:8080 --name tomcat01 tomcat
[root@localhost ~]# docker exec -it tomcat01 /bin/bash  进入tomcat容器
root@5176b49b0442:/usr/local/tomcat# ls   默认webapps里面没有任何东西都是最小化镜像
BUILDING.txt  CONTRIBUTING.md  LICENSE	NOTICE	README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  native-jni-lib  temp  webapps  webapps.dist  work
root@5176b49b0442:/usr/local/tomcat# cp -r webapps.dist/* webapps 现在测试访问就是正常

[root@localhost ~]# docker stats  查看cpu状态


4.docker 可视化

什么portainer?

docker图形化管理工具,提供一个后台面板供我们操作

[root@localhost ~]# docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

测试访问

docker基础_第6张图片

选择本地

docker基础_第7张图片

最终显示面板

docker基础_第8张图片

5.docker 镜像

镜像是什么

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

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

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

docker镜像加载原理

docker的镜像实际上是由一层一层的文件系统组成,这种层级的文件系统UnionFS。

bootfs(boot file system)主要包含BootLoader和kernel,BootLoader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在docker镜像的最底层是bootfs。这一层与我们典型的Linux系统是一样的。包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。

rootfs(root file system),在bootfs之上。包含的就是典型Linux系统中的 /dev,/proc,/bin,/etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

平时我们安装虚拟机中的centos镜像都是好几个G,为什么到docker中才200M左右??

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

分层的镜像

以我们的pull为例,在下载的过程中我们可以看到docker的镜像好想是在一层一层的在下载。

为什么tomcat的镜像会有400多M这么大??

就是因为分层的镜像tomcat需要这些---->kernel–centos–jdk8–tomcat–docker容器

docker为何采用这种分层

最大的一个好处就是—资源共享

比如有多个镜像都从相同的base镜像构建而来,那么宿主机只需要在磁盘上保存一份base镜像,同时内存中也只需加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

docker镜像的特点

docker镜像都是只读的

当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称为“容器层”,"容器层"之下的都叫镜像层。

docker commit

docker commit提交容器副本使之成为一个新镜像

docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的新的镜像名:[标签名]

案例演示

hub上下载tomcat镜像到本地运行,然后故意删除tomcat容器的帮助文档,此时将没有文档的tomcat容器为模板commit一个新的镜像,名为atguigu/tomcat02

# 从hub上下载tomcat镜像到本地并成功运行
[root@97 ~]# docker images tomcat
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
tomcat              latest              e36064f7c6f0        3 weeks ago         528MB

[root@97 ~]# docker run -it -p 8888:8080 tomcat  # 这样就启动了tomcat
-P 主机端口:docker容器端口
-p 随机分配端口
-i 交互
-t 终端
[root@97 ~]# docker run -it -P tomcat
[root@97 ~]# docker ps
CONTAINER ID  IMAGE      COMMAND          CREATED             STATUS      
893b6a90f5fc  tomcat  "catalina.sh run" 54 seconds ago      Up 53 seconds    
     PORTS                        NAMES
0.0.0.0:32768->8080/tcp   recursing_cohen   #(这里可以看到使用-P随机分配的映射端口为32768)
# 此时使用localhost:32768即可访问到tomcat的首页



# 故意删除上一步镜像生产tomcat容器的文档
[root@97 ~]# docker run -it -p 8888:8080 tomcat
[root@97 ~]# docker ps
CONTAINER ID     IMAGE   COMMAND             CREATED             STATUS    
58ff859e46b5     tomca   "catalina.sh run"   21 seconds ago      Up 20 seconds       
PORTS                     NAMES
0.0.0.0:8888->8080/tcp   competent_gates
[root@97 ~]# docker exec -it 58ff859e46b5 /bin/bash
root@58ff859e46b5:/usr/local/tomcat# rm -rf webapps/docs
再次访问localhost:8888的时候文档就没有了


# 也即当前的tomcat运行实例是一个没有文档内容的容器,以它为模板commit一个没有doc的tomcat新镜像atguigu/tomcat02
# -a 提交人
# -m  提交信息
[root@97 ~]# docker commit -a="zzyy" -m="tomcat del docs" 58ff859e46b5 atguigu/tomcat02
sha256:8848761752371b74c6bf4b30348e675565ed51eba918179947340170bd125219

[root@97 ~]# docker images	# 查看新生成的镜像
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
atguigu/tomcat02    latest              884876175237        About a minute ago   528MB
tomcat              latest              e36064f7c6f0        3 weeks ago          528MB

[root@97 ~]# docker rm -f $(docker ps -q)	# 删除所有正在运行的容器
[root@97 ~]# docker run -it -p 8888:8080 atguigu/tomcat02	#此时使用新镜像启动后是没有文档的

6.docker容器数据卷

是什么

在docker容器中运行的数据我们想把它保存下来就会使用卷,类似一个外置的活动硬盘。有点类似我们redis里面的rdb和aof文件。

将运用运行的环境打包形成容器运行,运行可以伴随着容器,但是我们对数据的要求希望是持久化的,容器之间希望有可能共享数据

docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了

为了能保存数据在docker中,我们使用卷。

能干嘛

主要做数据共享和数据持久化的工作

特点:

1.数据卷可在容器之间共享或重用数据

2.卷中的更改可以之间生效

3.数据卷中的更改不会包含在镜像的更新中

4.数据卷的生命周期一致持续到没有容器使用它为止

数据卷添加

直接V命令添加

docker run -it -v /宿主机绝对路径目录:/容器内目录  镜像名
[root@localhost ~]# docker run -it -v /home/ceshi:/home 300e315adb2f /bin/bash
# 会在宿主机生成/home/ceshi目录 在容器内生成/home
[root@3c645ce4260f /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@3c645ce4260f /]# cd home/
[root@3c645ce4260f home]# ls
[root@3c645ce4260f home]# mkdir xiaoxiong
[root@3c645ce4260f home]# exit 
exit
[root@localhost ~]# ls /home/ceshi/
xiaoxiong


# 查看数据是否挂载成功
[root@localhost ~]# docker inspect 3c645ce4260f
...
       "Mounts": [
            {
                "Type": "bind",
                "Source": "/home/ceshi",
                "Destination": "/home",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
...


# 容器和宿主机之间数据共享
[root@localhost ceshi]# touch 222  #宿主机创建文件
[root@localhost ceshi]# ls
123  222  xiaoxiong


[root@be39fe415860 home]# ls  #容器内可以看到创建的文件
123  222  xiaoxiong

[root@be39fe415860 home]# echo "123" > 222  #容器向文件写入内容
[root@be39fe415860 home]# touch 333  #容器内部创建文件


[root@localhost ceshi]# ls    #宿主机同步到了容器内的操作
123  222  333  xiaoxiong
[root@localhost ceshi]# cat 222 
123


# 容器退出后主机修改的内容能否同步?
# 退出容器
[root@be39fe415860 home]# exit
exit

# 宿主机新建文件
[root@localhost ceshi]# touch 555
[root@localhost ceshi]# ls
123  222  333  555  xiaoxiong

# 重新启动容器
[root@localhost ~]# docker start be39fe415860
be39fe415860
[root@localhost ~]# docker attach be39fe415860
[root@be39fe415860 /]# cd home/
[root@be39fe415860 home]# ls        # 即使容器退出后宿主机的数据还是可以实现共享
123  222  333  555  xiaoxiong



# 命令带权限
# ro readonly 只读
# rw readwrite 读写
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro  镜像名
[root@97 ~]# docker run -it -v /Host:/Container:ro centos
[root@30e7325ecd69 /]# 
[root@30e7325ecd69 /]# ls
Container
[root@97 ~]# cd /
[root@97 /]# ls
Host
[root@30e7325ecd69 /]# cd Container/	# 容器中不能往宿主机端增删改
[root@30e7325ecd69 Container]# touch
touch: missing file operand
Try 'touch --help' for more information.

[root@97 /]# cd Host/
[root@97 Host]# echo '123'>abc
[root@30e7325ecd69 Container]# ls	# 而宿主机端可以向容器端进行增删改
abc
[root@30e7325ecd69 Container]# cat abc 
123

备注:docker挂载主机目录docker访问出现cannot open director Permission denied(不能写)

解决办法:在挂载目录后多加一个 --privileged=true

安装mysql

#下载mysql镜像
[root@localhost ~]# docker pull mysql:5.7

#启动mysql镜像,注意mysql启动是要配置密码,需要 -e
-d 后台运行
-v 卷挂载
-p 指定端口
-e 指定密码
--name 容器名字

[root@localhost ~]# 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
3f73f49a4837582c99bd2a04c9e404910619a8ff5be63613d67a210665c92100

#启动成功后用navicat测试连接成功
#可以查看到本机挂载卷已经成功
[root@localhost ~]# cd /home/
[root@localhost home]# ls
mysql  xiaoxiong
[root@localhost home]# cd mysql/
[root@localhost mysql]# ls
conf  data

使用DockerFile添加

# 根目录下新建mydocker文件夹并进入
[root@97 ~]# mkdir /mydocker;cd /mydocker
[root@97 mydocker]# 

# 可在dockerfile中使用volume指令来给进行添加一个或多个数据卷
volume["/dataVolumeContainer","/dataVolumeContainer2","/dataVolumeContainer3"]
出于可移植和分享的考虑,用-v 主机目录:容器目录这种方法不能够直接在Dockerfile中实现,
由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录。

# file构建
[root@97 mydocker]# vim dockerfile
# colume test
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "finished,----------successl"
CMD /bin/bash

# build后生成进行镜像
[root@97 mydocker]# docker build -f /mydocker/dockerfile -t scl/centos .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos
 ---> 470671670cac
Step 2/4 : VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
 ---> [Warning] IPv4 forwarding is disabled. Networking will not work.
 ---> Running in 12f431a99f6c
Removing intermediate container 12f431a99f6c
 ---> 308657d43898
Step 3/4 : CMD echo "finished,----------successl"
 ---> [Warning] IPv4 forwarding is disabled. Networking will not work.
 ---> Running in c629c1e2b363
Removing intermediate container c629c1e2b363
 ---> c1b5b7f00f98
Step 4/4 : CMD /bin/bash
 ---> [Warning] IPv4 forwarding is disabled. Networking will not work.
 ---> Running in 5d73aa21f4fc
Removing intermediate container 5d73aa21f4fc
 ---> a93d209c88ac
Successfully built a93d209c88ac
Successfully tagged scl/centos:latest

[root@97 mydocker]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
scl/centos          latest              a93d209c88ac        36 seconds ago      237MB
tomcat              latest              e36064f7c6f0        4 weeks ago         528MB
nginx               latest              ed21b7a8aee9        4 weeks ago         127MB
centos              latest              470671670cac        3 months ago        237MB

# run容器
[root@97 mydocker]# docker run -it scl/centos
[root@0f4e72a49bee /]# ls
dataVolumeContainer1 	dataVolumeContainer2  	# 这两个目录都自动建好
 

# 通过上述步骤,容器内的卷目录地址已经知道,那么对应的主机目录地址在哪??
[root@97 ~]# docker ps |awk '{print $1}'
CONTAINER
0f4e72a49bee

[root@97 ~]# docker inspect 0f4e72a49bee # 查看主机对应的目录在哪
.....
                "Source": "/var/lib/docker/volumes/df73fe92186bf43daa8a519feb1e50767b86ff4d4ae8ed69bc0bed5e69710d68/_data",
                "Destination": "/dataVolumeContainer1",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "4a52f5f3de14bfc9c96dbac1d2b28416317c84f739d926cb4fe1a4a77ccd6c77",
                "Source": "/var/lib/docker/volumes/4a52f5f3de14bfc9c96dbac1d2b28416317c84f739d926cb4fe1a4a77ccd6c77/_data",
                "Destination": "/dataVolumeContainer2",
.....


# 主机对应默认地址
"/var/lib/docker/volumes/df73fe92186bf43daa8a519feb1e50767b86ff4d4ae8ed69bc0bed5e69710d68/_data"	对应容器	"/dataVolumeContainer1"
"/var/lib/docker/volumes/4a52f5f3de14bfc9c96dbac1d2b28416317c84f739d926cb4fe1a4a77ccd6c77/_data"	对应容器	"/dataVolumeContainer2"、

# 容器创建文件
[root@0f4e72a49bee /]# cd dataVolumeContainer1
[root@0f4e72a49bee dataVolumeContainer1]# touch 1

[root@97 ~]#cd 	/var/lib/docker/volumes/df73fe92186bf43daa8a519feb1e50767b86ff4d4ae8ed69bc0bed5e69710d68/_data
[root@97 _data]# ls		# 有了
1

[root@97 _data]# touch 2 # 主机创建文件
[root@0f4e72a49bee dataVolumeContainer1]# ls	# 容器也有了
1  2

数据卷容器

命名的容器挂载数据卷,其他容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。

# 先启动一个父容器dc01
[root@97 ~]# docker run -it --name dc01 scl/centos
[root@3706d79bd9db /]# ls
dataVolumeContainer1  dataVolumeContainer2
# 在dataVolumeContainer2中新增内容
[root@3706d79bd9db /]# touch dataVolumeContainer2/dc01_add

# dc02/dc03继承自dc01		--volumes-from	dc02/dc03分别在dataVolumeContainer2新增内容
[root@97 ~]# docker run -it --name dc02 --volumes-from dc01 scl/centos
[root@03b967d5c9b5 /]# ls dataVolumeContainer2
dc01_add
[root@03b967d5c9b5 /]# touch dc02_add

[root@97 ~]# docker run -it --name dc03 --volumes-from dc01 scl/centos
[root@e8293577fb4b /]# ls dataVolumeContainer2
dc01_add  dc02_add
[root@e8293577fb4b /]# touch dataVolumeContainer2/dc03_add

# 回到dc01可以看到dc02/dc03的内容都实现共享了
[root@97 ~]# docker attach 3706d79bd9db
[root@3706d79bd9db /]# ls dataVolumeContainer2
dc01_add  dc02_add  dc03_add

# 删除dc01后,dc02修改后dc03可否访问
[root@97 ~]# docker rm -f dc01
dc01
[root@97 ~]# docker ps
CONTAINER ID      IMAGE      ...    NAMES	
e8293577fb4b    scl/centos   ...     dc03
03b967d5c9b5    scl/centos   ...     dc02

[root@97 ~]# docker attach dc02
[root@03b967d5c9b5 /]# touch dataVolumeContainer2/dc02_update

[root@97 ~]# docker attach dc03
[root@e8293577fb4b /]# ls dataVolumeContainer2
dc01_add  dc02_add  dc02_update  dc03_add

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

7.docker容器数据卷

DockerFile介绍

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

构建步骤:

1、编写dockerfile文件

2、docker build 构建成为一个镜像

3、docker run 运行镜像

4、docker push 发布镜像(dockerhub、阿里云镜像仓库)

DockerFile构建过程

基础知识:

1、每个保留关键字(指令)都是必须是大写字母

2、执行从上到下顺序执行

3、#表示注释

4、每一个指令都会创建提交新的镜像层,并提交

docker基础_第9张图片

dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单。

步骤:开发,部署,运维

DockerFile:构建文件,定义了一切的步骤,源代码

Dokcerimages:通过DockerFile构建生成的镜像,最终发布和运行的产品

Docker容器:容器就是镜像运行起来提供服务器

DockerFile指令

FROM        # 基础镜像,一切从这里开始构建
MAINTAINER  # 镜像是谁写的,姓名+邮箱
RUN         # 镜像构建的时候需要运行的命令
ADD         # 步骤:tomcat镜像,这个toncat压缩包,添加内容
WORKDIR     # 镜像的工作目录
VOLUME      # 挂载的目录
EXPOSE      # 暴露端口位置
CMD         # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT  # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD     # 当构建一个被继承 DockerFile 这个时候就会运行 ONBUILD 的指令,触发指令
COPY        # 类似ADD,将我们文件拷贝到镜像中
ENV         # 构建的时候设置环境变量

实战测试

Docker Hub 中99%镜像都是从这个基础镜像过来的 FROM scratch ,然后配置需要的软件和配置来进行的构建

构建一个自己的centos

# 编写dockerfile 文件
[root@localhost dockerfile]# vim mydocker
[root@localhost dockerfile]# cat mydocker 
FROM centos
MAINTAINER xiaoxiong<[email protected]>
ENV MYPATH /usr/local/
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash

# 通过这个文件构建镜像
# -f  文件路径 -t 镜像名
[root@localhost dockerfile]# docker build -f /home/dockerfile/mydocker -t mycentos .
[root@localhost dockerfile]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED              SIZE
mycentos     latest    6de44d190ca2   About a minute ago   295MB
hyc/centos   latest    d414a1d34729   25 hours ago         209MB
mysql        5.7       2c9028880e58   3 weeks ago          447MB
centos       latest    300e315adb2f   5 months ago         209MB


# 测试运行
可以看到直接进入到设置的工作目录
[root@localhost dockerfile]# docker run -it mycentos
[root@e3cae797958b local]# pwd
/usr/local
[root@e3cae797958b local]# ifconfig  原始镜像没有ifconfig命令,通过运行dockerfile添加完成
eth0: flags=4163  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:03  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  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@localhost dockerfile]# docker history 6de44d190ca2
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
6de44d190ca2   7 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/bin…   0B        
6af5c291101b   7 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B        
caf1fba96583   7 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B        
4d7db0c5bb0e   7 minutes ago   /bin/sh -c #(nop)  EXPOSE 80                    0B        
85690a13630a   7 minutes ago   /bin/sh -c yum -y install net-tools             24.8MB    
5879cabc6900   7 minutes ago   /bin/sh -c yum -y install vim                   60.4MB    
4e348730069e   8 minutes ago   /bin/sh -c #(nop) WORKDIR /usr/local/           0B        
6b0443c72f81   8 minutes ago   /bin/sh -c #(nop)  ENV MYPATH=/usr/local/       0B        
8cf95ddf3e4b   8 minutes ago   /bin/sh -c #(nop)  MAINTAINER xiaoxiong<1183…   0B        
300e315adb2f   5 months ago    /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
      5 months ago    /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
      5 months ago    /bin/sh -c #(nop) ADD file:bd7a2aed6ede423b7…   209MB     

CMD 和 ENTRYPOINT 的区别

# 测试CMD
[root@localhost dockerfile]# vim cmddocker
[root@localhost dockerfile]# cat cmddocker 
FROM centos
CMD ["ls","-a"]
[root@localhost dockerfile]# docker build -f cmddocker -t cmdtest .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM centos
 ---> 300e315adb2f
Step 2/2 : CMD ["ls","-a"]
 ---> Running in b30ccb5b0495
Removing intermediate container b30ccb5b0495
 ---> 80290f733761
Successfully built 80290f733761
Successfully tagged cmdtest:latest
[root@localhost dockerfile]# docker run 80290f733761
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 想要追加一个命令 -l  ls -al
[root@localhost dockerfile]# docker run 80290f733761 -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.
ERRO[0001] error waiting for container: context canceled 
# cmd的清理下 -l 替换掉了 ["ls","-a"]命令,所以报错

# 加上全部命令才能执行正确
[root@localhost dockerfile]# docker run 80290f733761 ls -al
total 0
drwxr-xr-x.   1 root root   6 Jun  4 09:23 .
drwxr-xr-x.   1 root root   6 Jun  4 09:23 ..
-rwxr-xr-x.   1 root root   0 Jun  4 09:23 .dockerenv
lrwxrwxrwx.   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x.   5 root root 340 Jun  4 09:23 dev
drwxr-xr-x.   1 root root  66 Jun  4 09:23 etc
drwxr-xr-x.   2 root root   6 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   6 Dec  4 17:37 lost+found
drwxr-xr-x.   2 root root   6 Nov  3  2020 media
drwxr-xr-x.   2 root root   6 Nov  3  2020 mnt
drwxr-xr-x.   2 root root   6 Nov  3  2020 opt
dr-xr-xr-x. 227 root root   0 Jun  4 09:23 proc
dr-xr-x---.   2 root root 162 Dec  4 17:37 root
drwxr-xr-x.  11 root root 163 Dec  4 17:37 run
lrwxrwxrwx.   1 root root   8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x.   2 root root   6 Nov  3  2020 srv
dr-xr-xr-x.  13 root root   0 Jun  4 05:57 sys
drwxrwxrwt.   7 root root 145 Dec  4 17:37 tmp
drwxr-xr-x.  12 root root 144 Dec  4 17:37 usr
drwxr-xr-x.  20 root root 262 Dec  4 17:37 var

# 测试ENTRYPOINT
[root@localhost dockerfile]# vim ENTRYPOINT 
[root@localhost dockerfile]# cat ENTRYPOINT 
FROM centos
ENTRYPOINT ["ls","-a"]
[root@localhost dockerfile]# docker build -f ENTRYPOINT -t entrytest .
Sending build context to Docker daemon  4.096kB
Step 1/2 : FROM centos
 ---> 300e315adb2f
Step 2/2 : ENTRYPOINT ["ls","-a"]
 ---> Running in 065bf907fb0c
Removing intermediate container 065bf907fb0c
 ---> 675384e7bb6d
Successfully built 675384e7bb6d
Successfully tagged entrytest:latest
[root@localhost dockerfile]# docker run 675384e7bb6d
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 我们的追加命令是直接拼接在我们的 ENTRYPOINT命令后面的
[root@localhost dockerfile]# docker run 675384e7bb6d -l
total 0
drwxr-xr-x.   1 root root   6 Jun  4 09:30 .
drwxr-xr-x.   1 root root   6 Jun  4 09:30 ..
-rwxr-xr-x.   1 root root   0 Jun  4 09:30 .dockerenv
lrwxrwxrwx.   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x.   5 root root 340 Jun  4 09:30 dev
drwxr-xr-x.   1 root root  66 Jun  4 09:30 etc
drwxr-xr-x.   2 root root   6 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   6 Dec  4 17:37 lost+found
drwxr-xr-x.   2 root root   6 Nov  3  2020 media
drwxr-xr-x.   2 root root   6 Nov  3  2020 mnt
drwxr-xr-x.   2 root root   6 Nov  3  2020 opt
dr-xr-xr-x. 225 root root   0 Jun  4 09:30 proc
dr-xr-x---.   2 root root 162 Dec  4 17:37 root
drwxr-xr-x.  11 root root 163 Dec  4 17:37 run
lrwxrwxrwx.   1 root root   8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x.   2 root root   6 Nov  3  2020 srv
dr-xr-xr-x.  13 root root   0 Jun  4 05:57 sys
drwxrwxrwt.   7 root root 145 Dec  4 17:37 tmp
drwxr-xr-x.  12 root root 144 Dec  4 17:37 usr
drwxr-xr-x.  20 root root 262 Dec  4 17:37 var


DockerFile制作tomcat镜像

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

[root@localhost daxiong]# ll
total 165956
-rw-r--r--. 1 root root  10914435 Jun  8 23:23 apache-tomcat-9.0.24.tar.gz
-rw-r--r--. 1 root root 159019376 Jun  8 23:24 jdk-8u11-linux-x64.tar.gz

  1. 编写DockerFile文件 官方命名Dockerfile,这样在build的时候就不需要使用 -f 去指定了,build会自动找打DockerFile文件
[root@localhost daxiong]# vim Dockerfile 
[root@localhost daxiong]# cat Dockerfile 
FROM centos
MAINTAINER xiaoxiong<[email protected]>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u11-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.24.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.24
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.24
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080


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

  1. 构建镜像

    [root@localhost daxiong]# docker build -t diytomcat .
    Sending build context to Docker daemon  169.9MB
    Step 1/15 : FROM centos
     ---> 300e315adb2f
    Step 2/15 : MAINTAINER xiaoxiong<[email protected]>
     ---> Using cache
     ---> 8cf95ddf3e4b
    Step 3/15 : COPY readme.txt /usr/local/readme.txt
     ---> d43786c749ea
    Step 4/15 : ADD jdk-8u11-linux-x64.tar.gz /usr/local/
     ---> ee749e44c39c
    Step 5/15 : ADD apache-tomcat-9.0.24.tar.gz /usr/local/
     ---> 0665d76e96b7
    Step 6/15 : RUN yum -y install vim
     ---> Running in dc3bdf4643b1
    Removing intermediate container dc3bdf4643b1
     ---> 4f674c678856
    Step 7/15 : ENV MYPATH /usr/local
     ---> Running in 4b656d7c8769
    Removing intermediate container 4b656d7c8769
     ---> becadde2a554
    Step 8/15 : WORKDIR $MYPATH
     ---> Running in afe4644fa269
    Removing intermediate container afe4644fa269
     ---> bb690e4467ab
    Step 9/15 : ENV JAVA_HOME /usr/local/jdk1.8.0_11
     ---> Running in c4370166557e
    Removing intermediate container c4370166557e
     ---> af93e221766b
    Step 10/15 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
     ---> Running in 7f0b98789bf4
    Removing intermediate container 7f0b98789bf4
     ---> 2eefc03d8460
    Step 11/15 : ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.24
     ---> Running in 53c9933b4712
    Removing intermediate container 53c9933b4712
     ---> e6e538f6f1dc
    Step 12/15 : ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.24
     ---> Running in 912ffad6a62a
    Removing intermediate container 912ffad6a62a
     ---> e63c225dfd7e
    Step 13/15 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
     ---> Running in a3fcabeea9ba
    Removing intermediate container a3fcabeea9ba
     ---> 1ead0d64c3c1
    Step 14/15 : EXPOSE 8080
     ---> Running in 61ffb5d9b9db
    Removing intermediate container 61ffb5d9b9db
     ---> 917960884b18
    Step 15/15 : CMD /usr/local/apache-tomcat-9.0.24/bin/startup.sh && tail -f /usr/local/apache-tomcat-9.0.24/logs/catalina.out
     ---> Running in 6dbe9a9b2187
    Removing intermediate container 6dbe9a9b2187
     ---> db4e7f84c0cb
    Successfully built db4e7f84c0cb
    Successfully tagged diytomcat:latest
    
    [root@localhost daxiong]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
    diytomcat    latest    db4e7f84c0cb   50 seconds ago   609MB
    entrytest    latest    675384e7bb6d   4 days ago       209MB
    cmdtest      latest    80290f733761   4 days ago       209MB
    mycentos     latest    6de44d190ca2   4 days ago       295MB
    hyc/centos   latest    d414a1d34729   5 days ago       209MB
    mysql        5.7       2c9028880e58   3 weeks ago      447MB
    centos       latest    300e315adb2f   6 months ago     209MB
    
    

    4.启动运行

[root@localhost daxiong]# docker run -d --name xiaoxiongtomcat -p 9090:8080 -v /home/test/:/usr/local/apache-tomcat-9.0.24/webapps/test -v /home/tomcatlogs:/usr/local/apache-tomcat-9.0.24/logs db4e7f84c0cb
56109df1592899b90858b32f99addf378db463e2c7851b02eb9965390ba593fd
[root@localhost home]# ls
daxiong  dockerfile  mysql  test  tomcatlogs  xiaoxiong
[root@localhost home]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                       NAMES
56109df15928   db4e7f84c0cb   "/bin/sh -c '/usr/lo…"   37 seconds ago   Up 35 seconds   0.0.0.0:9090->8080/tcp, :::9090->8080/tcp   xiaoxiongtomcat

[root@localhost ~]# docker exec -it 56109df15928 /bin/bash

[root@56109df15928 local]# ls
apache-tomcat-9.0.24  bin  etc	games  include	jdk1.8.0_11  lib  lib64  libexec  readme.txt  sbin  share  src

5.测试访问

网页访问 http://192.168.233.138:9090/

发布项目
因为挂载了test目录在容器内部,我们在本机test目录测试
[root@localhost test]# pwd
/home/test
[root@localhost test]# vim index.jsp
[root@localhost test]# cat index.jsp 


        test page


        <%
            out.println("Hello World");
        %>



网页访问 http://192.168.233.138:9090/test

容器内部
[root@56109df15928 test]# pwd
/usr/local/apache-tomcat-9.0.24/webapps/test
[root@56109df15928 test]# ls
dockerfile  index.jsp

本机的日志存放目录
[root@localhost tomcatlogs]# ls
catalina.2021-06-09.log  catalina.out  host-manager.2021-06-09.log  localhost.2021-06-09.log  localhost_access_log.2021-06-09.txt  manager.2021-06-09.log

容器内部挂载的日志目录,可以看到已经同步过来
[root@56109df15928 logs]# ls -l
total 24
-rw-r-----. 1 root root 6577 Jun  9 07:05 catalina.2021-06-09.log
-rw-r-----. 1 root root 6577 Jun  9 07:05 catalina.out
-rw-r-----. 1 root root    0 Jun  9 07:05 host-manager.2021-06-09.log
-rw-r-----. 1 root root  408 Jun  9 07:05 localhost.2021-06-09.log
-rw-r-----. 1 root root 1138 Jun  9 07:28 localhost_access_log.2021-06-09.txt
-rw-r-----. 1 root root    0 Jun  9 07:05 manager.2021-06-09.log

发布自己的镜像

  • 地址https://hub.docker.com/ 注册自己的账号

  • 登录账号

  • 在服务器上提交镜像

    # docker登录成功
    # -u  dockerhub的用户名
    # -p  dockerhub的密码
    [root@localhost ~]# docker login -u hanyuce
    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
    
    # 增加一个tag
    # 注意:添加tag时必须在前面加上自己的dockerhub的username
    
    [root@localhost ~]# docker tag db4e7f84c0cb hanyuce/tomcat:1.0 
    [root@localhost ~]# docker images
    REPOSITORY         TAG       IMAGE ID       CREATED             SIZE
    hanyuce/tomcat     1.0       db4e7f84c0cb   About an hour ago   609MB
    diytomcat          latest    db4e7f84c0cb   About an hour ago   609MB
    xiaoxiong/tomcat   1.0       db4e7f84c0cb   About an hour ago   609MB
    entrytest          latest    675384e7bb6d   4 days ago          209MB
    cmdtest            latest    80290f733761   4 days ago          209MB
    mycentos           latest    6de44d190ca2   5 days ago          295MB
    hyc/centos         latest    d414a1d34729   6 days ago          209MB
    mysql              5.7       2c9028880e58   4 weeks ago         447MB
    centos             latest    300e315adb2f   6 months ago        209MB
    
    docker push提交
    [root@localhost ~]# docker push hanyuce/tomcat:1.0
    The push refers to repository [docker.io/hanyuce/tomcat]
    66c4d47f398c: Pushed 
    c5061ae4d8de: Pushed 
    fc8271f45427: Pushing [==========================>                        ]  169.6MB/324MB
    20f33d91d61c: Pushed 
    2653d992f4ef: Pushing [==========================================>        ]  179.6MB/209.3MB
    
    
    
阿里云提交镜像
  • 登录账号

  • 在服务器上提交镜像

  • 创建命名空间

  • 创建容器镜像

    阿里云端创建镜像仓库

docker基础_第10张图片

在这里插入图片描述

docker基础_第11张图片

8.Docker网络

理解dokcer0

测试

docker基础_第12张图片

[root@localhost ~]# docker run -d -P --name tomcat01 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:71703331e3e7f8581f2a8206a612dbeedfbc7bb8caeee972eadca1cc4a72e6b1
Status: Downloaded newer image for tomcat:latest
8558d455c168e6d56336bd951fa84e26195d380b9423f0c17b464027db4455db

查看容器的内部网络地址
[root@localhost ~]# docker exec -it tomcat01 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
6: eth0@if7: <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
# 发现docker0的ip和容器内部的IP(docker分配!)相同网段

# 本机ping容器内部ip,发现可以ping通
[root@localhost ~]# 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.390 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.131 ms

原理
我们每启动一个容器,docker都会分配一个ip给容器,我们只要安装了docker就会有一个网卡docker0 桥接模式,使用的技术是evth-pair技术

测试

[root@localhost ~]# ip addr
​```
​```
7: veth49126bf@if6:  mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether f2:01:1d:af:69:e7 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::f001:1dff:feaf:69e7/64 scope link 
       valid_lft forever preferred_lft forever

#再启动一个容器,发现又多了一对网卡
[root@localhost ~]# docker run -it -d -P --name tomcat02 tomcat
498eb04c44ed2f59a619d3d25483930f7f7218b8fe551f55f59bfd3704614969
[root@localhost ~]# ip addr
​```
7: veth49126bf@if6:  mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether f2:01:1d:af:69:e7 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::f001:1dff:feaf:69e7/64 scope link 
       valid_lft forever preferred_lft forever
9: veth3678943@if8:  mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 76:c5:f4:6a:e1:b5 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::74c5:f4ff:fe6a:e1b5/64 scope link 
       valid_lft forever preferred_lft forever

查看容器内部ip
[root@localhost ~]# docker exec -it tomcat02 ip addr
1: lo:  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
8: eth0@if9:  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

# 我们发现这个容器带来的网卡都是一对一对的出现
# Veth-pair 就是一对虚拟设备接口,他们都是成对出现,一段连着协议,一段彼此连接
# 正是因为这个特性, veth-pair 充当一个桥梁,连接各种虚拟网络设备
# openstack、docker容器之间的互连,OVS的连接,都是使用 veth-pair 这个技术
测试一下tomcat01和tomcat02是否能够ping通
[root@localhost ~]# 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.299 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.181 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.181 ms

容器和容器之间是可以互相ping通的
docker网络模型图

docker基础_第13张图片

结论
tomcat01 和 tomcat02 是共用的一个路由器也就是 docker0

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

容器之间的连接都是通过Veth-pair技术来转发的

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

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

docker使用的是linux的桥接,宿主机是docker容器的网桥 docker0

docker基础_第14张图片

–link

容器如何通过服务名来互访问

[root@localhost ~]# docker exec -it tomcat01 ping tomcat02
ping: tomcat02: Name or service not known

# 通过 --link 即可以解决了网络连通问题
[root@localhost ~]# docker run -it -d -P --name tomcat03 --link tomcat02 tomcat
1e60afdf1279e7f2eb48acccd0e28bbcc768a7e4a07e80aa787c8a4f735dbd90
[root@localhost ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.2): icmp_seq=1 ttl=64 time=0.188 ms
64 bytes from tomcat02 (172.17.0.2): icmp_seq=2 ttl=64 time=0.189 ms
64 bytes from tomcat02 (172.17.0.2): icmp_seq=3 ttl=64 time=0.181 ms


通过docker network inspect 查看容器的详细信息
[root@localhost ~]# docker network --help

Usage:  docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.

#查看所有的docker网络
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
437a67861643   bridge    bridge    local
dfa7c4ba6869   host      host      local
daa1705dc87d   none      null      local

[root@localhost ~]# docker network inspect 437a67861643
[
    {
        "Name": "bridge",
        "Id": "437a67861643d43e3b28ca4dac9dc5830ffa16f63f64a196652a0ed13bd10c1a",
        "Created": "2021-06-09T22:55:08.704628274-07:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",    # 这个是我们的docker0
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
 
 
 # 下面则是我们的三个容器信息
        "ConfigOnly": false,
        "Containers": {
            "1e60afdf1279e7f2eb48acccd0e28bbcc768a7e4a07e80aa787c8a4f735dbd90": {
                "Name": "tomcat03",
                "EndpointID": "b7df723d59b0c9257ea1c90133da7074c1563b5473f92b2c693c17576a8779ee",
                "MacAddress": "02:42:ac:11:00:04",
                "IPv4Address": "172.17.0.4/16",
                "IPv6Address": ""
            },
            "498eb04c44ed2f59a619d3d25483930f7f7218b8fe551f55f59bfd3704614969": {
                "Name": "tomcat02",
                "EndpointID": "c42f6ecf852bb46ea8217210acb9064f02f328f2bc86ed52cadb6d194fae455b",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
            "8558d455c168e6d56336bd951fa84e26195d380b9423f0c17b464027db4455db": {
                "Name": "tomcat01",
                "EndpointID": "208dcb34c12230f665fe8edcb15f0d2ab109ca161bd875b14d66da8f16f9ff51",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

其实这个tomcat03就是在本地配置了tomcat02的配置

查看tomcat的hosts文件,发现文件已经配置好了tomcat02
[root@localhost ~]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.2	tomcat02 498eb04c44ed
172.17.0.4	1e60afdf1279

本质探究  --link  就是我们在hosts配置中添加了一个172.0.2 tomcat02 498eb04c44ed
现在docker不建议使用 --link
docker0问题:它不只吃容器名的连接访问

自定义网络

网络模式

[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
7f5e359e1b2e   bridge    bridge    local
dfa7c4ba6869   host      host      local
daa1705dc87d   none      null      local

bridege : 桥接 docker (模式)
none : 不配置网络
host : 和宿主机共享网络
container :容器网络连通(用的少,局限很大)

测试

# 我们直接启动的命令 --net bridge 而这个就是我们的docker0
docker rum -d -P --name tomcat01 tomcat
docker rum -d -P --name tomcat01 --net bridge tomcat

#docker0特点: 默认,域名不能访问  --link可以打通连接

# 我们可以自定义一个网络
# --driver bridge
# --subnet 192.168.0.0/16
# --gateway 192.168.0.1

[root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
74e8849ac17e93f9ffeddd4ad3a98282037dac8d13be03ebfaf06455e62655ed
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
7f5e359e1b2e   bridge    bridge    local
dfa7c4ba6869   host      host      local
74e8849ac17e   mynet     bridge    local
daa1705dc87d   none      null      local

# 查看自己创建的网络信息
[root@localhost ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "74e8849ac17e93f9ffeddd4ad3a98282037dac8d13be03ebfaf06455e62655ed",
        "Created": "2021-06-10T19:42:11.393089746-07: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": {}
    }
]

#启动两个容器,通过--net 到自己创建的网络里面
[root@localhost ~]# docker run -d -P --name tomcat01 --net mynet tomcat
c1afce5d6ac0ab85c90e822caa617dbccaa205a2ed22816f605bc415a5887853
[root@localhost ~]# docker run -d -P --name tomcat02 --net mynet tomcat
5051ab90dbf2466836088bb32ed743376f8f15d65a4966d4724899c93f3416bf
[root@localhost ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "74e8849ac17e93f9ffeddd4ad3a98282037dac8d13be03ebfaf06455e62655ed",
        "Created": "2021-06-10T19:42:11.393089746-07: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": {
            "5051ab90dbf2466836088bb32ed743376f8f15d65a4966d4724899c93f3416bf": {
                "Name": "tomcat02",
                "EndpointID": "ddba10f1596143e470244579da47d8884218a005ffc72cc41d8d10596337cd3e",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "c1afce5d6ac0ab85c90e822caa617dbccaa205a2ed22816f605bc415a5887853": {
                "Name": "tomcat01",
                "EndpointID": "38af76a54af63c869b47adc8cf531623fbb6156aa394a7a6b3cfbe47c9ffcee4",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

#再次测试ping连接
[root@localhost ~]# docker exec -it tomcat01 ping 192.168.0.3
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.264 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.179 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.178 ms

#现在不使用 --link也可以ping 名字
[root@localhost ~]# docker exec -it tomcat01 ping tomcat02
PING tomcat02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.102 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.183 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.271 ms

我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络

网络连通

如图,两个不同网络中的容器,他们之间怎么互连

不同的两个网卡之间是不能连通的,但是容器和网卡是可以连通的

docker基础_第15张图片

创建两个docker0中的网络容器
[root@localhost ~]# docker run -d -P --name tomcat03 tomcat
d65adf3a9229e2f8ee65f8007de094c1e25cf3d4570ea177d1cfa0fd67fa22cc
[root@localhost ~]# docker run -d -P --name tomcat04 tomcat
456d842cae2b5f637b94fc2c7a0932dd2a42f93f908a3ae8f8a4db312380c415
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                                         NAMES
456d842cae2b   tomcat    "catalina.sh run"   51 seconds ago   Up 48 seconds   0.0.0.0:49156->8080/tcp, :::49156->8080/tcp   tomcat04
d65adf3a9229   tomcat    "catalina.sh run"   55 seconds ago   Up 53 seconds   0.0.0.0:49155->8080/tcp, :::49155->8080/tcp   tomcat03
5051ab90dbf2   tomcat    "catalina.sh run"   11 minutes ago   Up 11 minutes   0.0.0.0:49154->8080/tcp, :::49154->8080/tcp   tomcat02
c1afce5d6ac0   tomcat    "catalina.sh run"   11 minutes ago   Up 11 minutes   0.0.0.0:49153->8080/tcp, :::49153->8080/tcp   tomcat01


[root@localhost ~]# docker network --help

Usage:  docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network  # 连接一个容器到一个网络
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.

#测试打通tomcat03 - mynet

# 连通之后就是将tomcat03 放到了 mynet网络下

#实现了一个容器两个ip
[root@localhost ~]# docker network connect mynet tomcat03
[root@localhost ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "74e8849ac17e93f9ffeddd4ad3a98282037dac8d13be03ebfaf06455e62655ed",
        "Created": "2021-06-10T19:42:11.393089746-07: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": {
            "5051ab90dbf2466836088bb32ed743376f8f15d65a4966d4724899c93f3416bf": {
                "Name": "tomcat02",
                "EndpointID": "ddba10f1596143e470244579da47d8884218a005ffc72cc41d8d10596337cd3e",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "c1afce5d6ac0ab85c90e822caa617dbccaa205a2ed22816f605bc415a5887853": {
                "Name": "tomcat01",
                "EndpointID": "38af76a54af63c869b47adc8cf531623fbb6156aa394a7a6b3cfbe47c9ffcee4",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "d65adf3a9229e2f8ee65f8007de094c1e25cf3d4570ea177d1cfa0fd67fa22cc": {
                "Name": "tomcat03",
                "EndpointID": "ab3d4c25bca22a4f45a65ec4443c0d3fe074f1934e5f78252f72f9fbadb4af88",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

#测试发现tomcat03可以ping通tomcat01,tomcat04依旧ping不通tomcat01
[root@localhost ~]# docker exec -it tomcat03 ping tomcat01
PING tomcat01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.385 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.177 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.177 ms
[root@localhost ~]# docker exec -it tomcat04 ping tomcat01
ping: tomcat01: Name or service not known

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

redis集群部署

#创建网卡
[root@localhost ~]# docker network create redis --subnet 172.38.0.0/16
ea81be5dd2d053cf95d93aab7854cfadcc3405d46e81aced0156170f5ac802f4
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
7f5e359e1b2e   bridge    bridge    local
dfa7c4ba6869   host      host      local
74e8849ac17e   mynet     bridge    local
daa1705dc87d   none      null      local
ea81be5dd2d0   redis     bridge    local

#通过脚本创建六个redis配置
[root@localhost ~]# for port in $(seq 1 6);do
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-$port/conf/redis.conf
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1$port
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

[root@localhost ~]# ls /mydata/redis/
node-1  node-2  node-3  node-4  node-5  node-6

# 启动redis容器,通过for循环创建六个redis容器
[root@localhost ~]# for i in `seq 6`;do
> docker run -d --name redis-$i -p 637$i:6379 -p 1637$i:16379 -v /mydata/redis/node-$i/data:/data -v /mydata/redis/node-$i/conf/redis.conf:/etc/redis/redis.conf --net redis --ip 172.38.0.1$i redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
> done
Unable to find image 'redis:5.0.9-alpine3.11' locally
5.0.9-alpine3.11: Pulling from library/redis
cbdbe7a5bc2a: Pull complete 
dc0373118a0d: Pull complete 
cfd369fe6256: Pull complete 
3e45770272d9: Pull complete 
558de8ea3153: Pull complete 
a2c652551612: Pull complete 
Digest: sha256:83a3af36d5e57f2901b4783c313720e5fa3ecf0424ba86ad9775e06a9a5e35d0
Status: Downloaded newer image for redis:5.0.9-alpine3.11
484174c8eb7262c348375fac6ed4bd2c1e880c0e78de491bae5a53cbb2dc90e0
36984c013609ff0a540c1bca0c5a529b1a999091047c4ebfc48c4a308a43824d
5bd87d1d860655492c5a64d5d1eb7738629f4fb4c37e047eed6cc82368fab438
ee344150338e0a2523d2a11e6d88e48a61979b567aea87f57c0a033e340ead3a
4f88be5715b336b170b1f1678a89094f25fc1172da78dae4c191390cce3307de
c9abe1483e9d8b3c40763a58fa561cb2fa54882bf4002a9331bc9d63bd26c456
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS          PORTS                                                                                      NAMES
c9abe1483e9d   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   7 seconds ago    Up 3 seconds    0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp   redis-6
4f88be5715b3   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   9 seconds ago    Up 6 seconds    0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp   redis-5
ee344150338e   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   12 seconds ago   Up 9 seconds    0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp   redis-4
5bd87d1d8606   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   14 seconds ago   Up 11 seconds   0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16373->16379/tcp, :::16373->16379/tcp   redis-3
36984c013609   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   17 seconds ago   Up 14 seconds   0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp   redis-2
484174c8eb72   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   20 seconds ago   Up 16 seconds   0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp   redis-1


# 随便进去一个redis容器
[root@localhost ~]# docker exec -it redis-1 /bin/sh
/data # ls
appendonly.aof  nodes.conf

# 创建集群
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

# 验证集群
/data # redis-cli -c
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:223
cluster_stats_messages_pong_sent:223
cluster_stats_messages_sent:446
cluster_stats_messages_ping_received:218
cluster_stats_messages_pong_received:223
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:446


127.0.0.1:6379> cluster nodes
85fee6379c73e29cc57b3452e0424076b942d758 172.38.0.15:6379@16379 slave bb4a50332c8fe22b99fed66b47398c65f76278d8 0 1623383025473 5 connected
bb4a50332c8fe22b99fed66b47398c65f76278d8 172.38.0.11:6379@16379 myself,master - 0 1623383024000 1 connected 0-5460
f6ef058d999bba4e613662d8af7361c9d7b08213 172.38.0.14:6379@16379 slave a76f24153e225c461efacc0640ce217b079f503a 0 1623383024000 4 connected
a76f24153e225c461efacc0640ce217b079f503a 172.38.0.13:6379@16379 master - 0 1623383025573 3 connected 10923-16383
1b74cfd2b4bca85293ee7524661e78fe75ad8125 172.38.0.16:6379@16379 slave b168b507b21e04a966e20bb17fcab51a8767e94d 0 1623383024565 6 connected
b168b507b21e04a966e20bb17fcab51a8767e94d 172.38.0.12:6379@16379 master - 0 1623383026485 2 connected 5461-10922

# 验证高可用
# set一个值,看到是172.38.0.13(master)处理的
127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK

# 那现在把172.38.0.13这个容器停掉
[root@localhost ~]# docker stop redis-3

# 重新连接后,发现从172.38.0.14(slave) get到了这个值
/data # redis-cli -c
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b"

# 这个时候查看节点信息
# 发现了172.38.0.13:6379@16379 master,fail,之前的172.38.0.13(master)故障转移
# 发现172.38.0.14 从slave变成了master
# redis集群搭建完毕
172.38.0.14:6379> cluster nodes
3e91c0e39f423def2a9cbf0cf1b58d96fe1903c3 172.38.0.16:6379@16379 slave 8d8b328e095a8e77a5e021551ae715f509934cac 0 1619766297101 6 connected
b99032c696586c0de1608350eeeabc8f5dc2c750 172.38.0.14:6379@16379 myself,master - 0 1619766298000 7 connected 10923-16383
e755a2159044c9a4a141c804614fea6a5f0ed9f8 172.38.0.11:6379@16379 master - 0 1619766299416 1 connected 0-5460
8d8b328e095a8e77a5e021551ae715f509934cac 172.38.0.12:6379@16379 master - 0 1619766298000 2 connected 5461-10922
5c6fe8c46f32b1add603dd407722c03b7784383b 172.38.0.15:6379@16379 slave e755a2159044c9a4a141c804614fea6a5f0ed9f8 0 1619766299000 5 connected
a10c9f0e389d8add55d609ebabb4c190229d9a1a 172.38.0.13:6379@16379 master,fail - 1619766136592 1619766136089 3 connected




你可能感兴趣的:(docker基础)