Docker学习笔记---通俗易懂
发布日期:2021-05-09 09:24:36 浏览次数:27 分类:原创文章

本文共 45761 字,大约阅读时间需要 152 分钟。




目录






































































Docker


简介


Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的中,然后发布到任何流行的 或 机器上,也可以实现。容器是完全使用机制,相互之间不会有任何接口。


Docker是基于 Go 语言开发的,是一个开源项目。


文档地址:


仓库地址:


虚拟机技术缺点:模拟一个完整的操作系统,资源占用多,步骤冗余,启动慢。


Docker 容器化技术:不是模拟的一个完整的操作系统。运行在宿主机的内核上。每个容器内是互相隔离的,互不影响。


DevOps:开发 运维。


应用更快的交付和部署。


传统:安装各种的jar包,打包发布。


Docker :一键打包镜像发布,测试。


更便捷的升级和扩缩容,项目打包为一个镜像,部署应用就和搭积木一样。


更简单的系统运维,容器化后,开发测试环境都是一致的。


更高效的计算资源利用,Docke是内核级的虚拟化,在一个物理机上可以运行很多的容器。


Docker安装


Docker的基本组成



镜像(image):


就好比是一个模板,可通过这个镜像来创建容器服务,比如 tomcat 镜像--->run--->tomcat01容器,通过这个镜像可以创建多个容器(应用最终在容器中运行)。


容器(container):


Docker利用容器技术,独立运行一个或一组应用,通过镜像创建。


启动,停止,删除,基本命令。


仓库(repository):


存放镜像的地方。仓库分为公有仓库和私有仓库。


安装Docker


环境准备:



  1. 需要会Linux基础

  2. Centos7

  3. 使用Xshell连接远程服务器操作

  4. 已经购买云服务器(以下使用阿里云)


环境查看


#系统内核是3.0以上的[root@zhourui /]# uname -r4.18.0-193.28.1.el8_2.x86_64

#系统版本[root@zhourui /]# cat /etc/os-releaseNAME="CentOS Linux"VERSION="8 (Core)"ID="centos"ID_LIKE="rhel fedora"VERSION_ID="8"PLATFORM_ID="platform:el8"PRETTY_NAME="CentOS Linux 8 (Core)"ANSI_COLOR="0;31"CPE_NAME="cpe:/o:centos:centos:8"HOME_URL="https://www.centos.org/"BUG_REPORT_URL="https://bugs.centos.org/"CENTOS_MANTISBT_PROJECT="CentOS-8"CENTOS_MANTISBT_PROJECT_VERSION="8"REDHAT_SUPPORT_PRODUCT="centos"REDHAT_SUPPORT_PRODUCT_VERSION="8"

安装:参考帮助文档


卸载旧的版本


#卸载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://download.docker.com/linux/centos/docker-ce.repo  #默认的是国外的十分慢#阿里云镜像 (推荐使用)   yum-config-manager \    --add-repo \        http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo    #更新yum软件包索引yun makecache fast    #安装docker  decker-ce社区版的 ee企业版yum install docker-ce docker-ce-cli containerd.io#启动dockersystemctl start docker#查看是否安装成功docker version


#启动 hello-worlddocker run hello-world


#查看下载的hello-world镜像[root@zhourui /]# docker imagesREPOSITORY    TAG       IMAGE ID       CREATED       SIZEhello-world   latest    d1165f221234   2 weeks ago   13.3kB

#卸载dockeryum remove docker-ce docker-ce-cli containerd.io#删除资源rm -rf /var/lib/dockerrm -rf /var/lib/containerd

配置阿里云镜像加速


登录阿里云找到容器服务。



找到容器镜像服务



配置使用


sudo mkdir -p /etc/dockersudo tee /etc/docker/daemon.json <<-'EOF'{  "registry-mirrors": ["https://tk46rux4.mirror.aliyuncs.com"]}EOFsudo systemctl daemon-reloadsudo systemctl restart docker

回顾helloworld流程



流程图



工作原理


Docker是一个Client,Server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问。


DockerServer接收到DockerClient的指令,就会执行这个命令。


Docker为什么比VNM快:


Docker有比虚拟机更少的抽象层。


Docker利用的是宿主机的内核,VM有自己的Guest OS。



新建一个容器的时候,Docker不需要像虚拟机一样新建一个系统内核。利用宿主机的内核,提升了启动速度和系统资源利用率。


Docker的常用命令


帮助命令


docker -version    #显示docker的版本信息docker info		   #docker的详细信息 镜像和容器的数量docker 命令 --help  #万能命令docker --help		#docker的所有命令

命令:官网地址


镜像命令


docker images:查看本机所有镜像


[root@zhourui /]# docker imagesREPOSITORY    TAG       IMAGE ID       CREATED       SIZEhello-world   latest    d1165f221234   2 weeks ago   13.3kB#解释REPOSITORY 镜像的仓库源TAG			镜像的标签IMAGE ID	镜像的 idCREATED		镜像的创建时间SIZE		镜像的大小#可选项  -a, --all             #显示所有的镜像  -q, --quiet           #只显示镜像的id

docker search:搜索镜像


[root@zhourui /]# docker search mysqlNAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATEDmysql                             MySQL is a widely used, open-source relation…   10634     [OK]       mariadb                           MariaDB Server is a high performing open sou…   3990      [OK]       #可选项--filter=STARS=3000		#搜索出来的就是stars大于等于3000的  -f简写[root@zhourui /]# docker search mysql -f=STARS=3000NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATEDmysql     MySQL is a widely used, open-source relation…   10634     [OK]       mariadb   MariaDB Server is a high performing open sou…   3990      [OK] 

docker pull:下载镜像


#下载 docker pull 镜像名 [:tag](可以选版本) 不写版本默认latest最后一个[root@zhourui /]# docker pull mysqlUsing default tag: latestlatest: Pulling from library/mysqla076a628af6f: Pull complete 		#分层下载 docker image核心 联合文件系统 f6c208f3f991: Pull complete 88a9455a9165: Pull complete 406c9b8427c6: Pull complete 7c88599c0b25: Pull complete 25b5c6debdaf: Pull complete 43a5816f1617: Pull complete 1a8c919e89bf: Pull complete 9f3cf4bd1a07: Pull complete 80539cea118d: Pull complete 201b3cad54ce: Pull complete 944ba37e1c06: Pull complete Digest: sha256:feada149cb8ff54eade1336da7c1d080c4a1c7ed82b5e320efb5beebed85ae8c	#签名Status: Downloaded newer image for mysql:latest		docker.io/library/mysql:latest		#真实地址# docker pull mysql# 等价# docker pull docker.io/library/mysql:latest#指定版本下载[root@zhourui /]# docker pull mysql:5.75.7: Pulling from library/mysqla076a628af6f: Already exists 		#共用f6c208f3f991: Already exists 88a9455a9165: Already exists 406c9b8427c6: Already exists 7c88599c0b25: Already exists 25b5c6debdaf: Already exists 43a5816f1617: Already exists 1831ac1245f4: Pull complete 37677b8c1f79: Pull complete 27e4ac3b0f6e: Pull complete 7227baa8c445: Pull complete Digest: sha256:b3d1eff023f698cd433695c9506171f0d08a8f92a0c8063c1a4d9db9a55808dfStatus: Downloaded newer image for mysql:5.7docker.io/library/mysql:5.7[root@zhourui /]# docker imagesREPOSITORY    TAG       IMAGE ID       CREATED        SIZEhello-world   latest    d1165f221234   2 weeks ago    13.3kBmysql         5.7       a70d36bc331a   2 months ago   449MBmysql         latest    c8562eaf9d81   2 months ago   546MB

docker rmi:删除镜像


#删除指定的容器 根据id[root@zhourui /]# docker rmi -f c8562eaf9d81#删除多个镜像[root@zhourui /]# docker rmi -f id1 id2 id3#删除全部容器[root@zhourui /]# docker rmi -f $(docker images -aq)

容器命令


我们有了镜像才可以创建容器,下载一个CentOS镜像来测试学习。


docker pull centos

新建容器并启动


docker run (可选参数) image#参数说明--name=“Name” 	#容器名字 tomcat01 tomcat01 来区分-d 				#后台方式运行-it 			#使用交互方式运行,进入容器查看内容-p 				#指定容器的端口 -p 8080:8080	-p 主机端口:容器端口 (常用)	-p ip:主机端口:容器端口	-p 容器端口	容器端口(不写-p)-p 				#随机指定端口#启动并进入容器[root@zhourui /]# docker run -it centos /bin/bash[root@b728c79b5448 /]# ls   #查看容器内的centos  基础版本 很多的命令不完善bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var[root@b728c79b5448 /]# exit  #退出命令exit[root@zhourui /]# lsbin  boot  dev  etc  home  lib  lib64  media  mnt  opt  patch  proc  root  run  sbin  srv  sys  tmp  usr  var  www

列出所有运行的容器


# docker ps  	#列出所有在运行的容器-a	#列出历史运行过的容器-n=? #显示最近创建的n个容器-q	#列出运行容器的id[root@zhourui /]# docker ps  CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES[root@zhourui /]# docker ps -aCONTAINER ID   IMAGE          COMMAND       CREATED         STATUS                     PORTS     NAMESb728c79b5448   centos         "/bin/bash"   4 minutes ago   Exited (0) 2 minutes ago             relaxed_elbakyan0ce52f9209e4   d1165f221234   "/hello"      5 hours ago     Exited (0) 5 hours ago               intelligent_mirzakhani

退出容器


exit  #容器停止并退出ctrl +P +Q  #按住这三个键 容器不停止退出[root@zhourui /]# docker run -it centos /bin/bash[root@c9797d0b4ba8 /]# [root@zhourui /]# docker psCONTAINER ID   IMAGE     COMMAND       CREATED              STATUS              PORTS     NAMESc9797d0b4ba8   centos    "/bin/bash"   About a minute ago   Up About a minute             inspiring_faraday

删除容器


docker rm 			#删指定id的容器  不能删除正在运行的容器  强制删除 rm -fdocker rm -f $(docker ps -aq) #删除全部的容器docker -a-q|xargs docker rm   #删除全部容器

启动和停止容器的操作


docker start 容器id 		#启动docker restart 容器id		#重启docker stop 容器id		#停止容器docker kill 容器id		#强制停止

常用其它命令


后台启动容器


# docker run -d 容器名  后台启动[root@zhourui /]# docker run -d centos#运行docker ps 发现centos停止了#docker容器使用后台运行,就必须有一个前台进程,docker发现没有应用,就会自动停止

查看日志


docker logs -f -t --tail 10 容器id #打印最近10条日志#编写shell脚本“while true;do echo zhourrrrr;sleep 1;done”[root@zhourui /]# docker run -d centos /bin/bash -c "while true;do echo zhourrrr;sleep 1;done"e79bac46e660abb781dcce7b0dbd3a3a896b573a104fdd9a15db0bbf5331341b[root@zhourui /]# docker psCONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS        PORTS     NAMESe79bac46e660   centos    "/bin/bash -c 'while…"   3 seconds ago   Up 1 second             jolly_sanderson#显示日志-tf  #显示日志 t 时间--tail number #最近的多少条数据[root@zhourui /]# docker logs -f -t --tail 10 e79bac46e660 

查看容器中的进程信息


docker top 容器id


[root@zhourui /]# docker top e79bac46e660UID                 PID                 PPID                C                   STIME               TTY     root                227610              227588              0                   22:36               ?       root                229020              227610              0                   22:45               ?       

查看镜像源数据


docker inspect 容器id


[root@zhourui /]# docker inspect e79bac46e660[    {        "Id": "e79bac46e660abb781dcce7b0dbd3a3a896b573a104fdd9a15db0bbf5331341b",        "Created": "2021-03-21T14:36:07.740342428Z",        "Path": "/bin/bash",        "Args": [            "-c",            "while true;do echo zhourrrr;sleep 1;done"        ],        "State": {            "Status": "running",            "Running": true,            "Paused": false,            "Restarting": false,            "OOMKilled": false,            "Dead": false,            "Pid": 227610,            "ExitCode": 0,            "Error": "",            "StartedAt": "2021-03-21T14:36:08.2053845Z",            "FinishedAt": "0001-01-01T00:00:00Z"        },        .........#省略...     }}

进入当前正在运行的容器


#通常容器都是后台的方式运行的,需要进入容器修改一些配置#命令docker exec -it 容器id bashShell(bin/bash)#测试[root@zhourui /]# docker psCONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES538cddb5e369   centos    "bin/bash -c 'while …"   14 seconds ago   Up 13 seconds             quizzical_wing[root@zhourui /]# docker exec -it 538cddb5e369 bin/bash[root@538cddb5e369 /]# [root@538cddb5e369 /]# lsbin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var[root@538cddb5e369 /]# ps -efUID          PID    PPID  C STIME TTY          TIME CMDroot           1       0  0 11:08 ?        00:00:00 bin/bash -c while true;do echo zzzzzrr;sleep 2;doneroot          66       0  0 11:10 pts/0    00:00:00 bin/bashroot         131       1  0 11:12 ?        00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 2root         132      66  0 11:12 pts/0    00:00:00 ps -ef#方式二docker attach 容器id#测试[root@zhourui /]# docker attach 538cddb5e369zzzzzrrzzzzzrrzzzzzrrzzzzzrr#进去后是正在执行的当前代码,想停止可以新开一个窗口 docker rm -f $(docker ps -aq)# docker exec  进入后打开了一个新的终端,可以在里面操作# docker attach 进入容器正在执行的终端,不会启动新的进程

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


docker cp 容器id:容器内路径 目的主机路径#测试[root@zhourui /]# cd /home[root@zhourui home]# lswww  zhour.java[root@zhourui home]# docker psCONTAINER ID   IMAGE     COMMAND       CREATED              STATUS              PORTS     NAMES44e87620bf99   centos    "/bin/bash"   About a minute ago   Up About a minute             romantic_burnell#进入容器[root@zhourui home]# docker attach 44e87620bf99[root@44e87620bf99 /]# cd /home[root@44e87620bf99 home]# ls#在容器内新建一个文件[root@44e87620bf99 home]# touch zr.java[root@44e87620bf99 home]# lszr.java[root@44e87620bf99 home]# exitexit[root@zhourui home]# docker psCONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES[root@zhourui home]# docker ps -aCONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                     PORTS     NAMES44e87620bf99   centos    "/bin/bash"   3 minutes ago   Exited (0) 6 seconds ago             romantic_burnell#将容器内的文件拷贝到主机上[root@zhourui home]# docker cp 44e87620bf99:/home/zr.java /home[root@zhourui home]# lswww  zhour.java  zr.java[root@zhourui home]##拷贝是一个手动过程,后面学习使用 -v 卷的技术,可以实现自动同步

小结



常用命令




练习部署


部署Nginx



  1. 搜索镜像:docker search nginx


  2. 下载镜像:docker pull nginx


  3. 运行测试:docker run -d --name nginx01 -p 3344:80 nginx (--name:起别名,-p 3344:80 3344是暴露的端口就是宿主机端口 80是nginx默认端口就是容器的端口)

    [root@zhourui home]# docker imagesREPOSITORY    TAG       IMAGE ID       CREATED         SIZEnginx         latest    f6d0b4767a6c   2 months ago    133MBcentos        latest    300e315adb2f   3 months ago    209MBhello-world   latest    bf756fb1ae65   14 months ago   13.3kB#--name:起别名,-p 3344:80 3344是暴露的端口 80是nginx默认端口[root@zhourui home]# docker run -d --name nginx01 -p 3344:80 nginx56b36ad955ca7cf6d80708b20d7ffd1152a0ca974c312df45bfe9e31d0888e0b[root@zhourui home]# docker psCONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                  NAMES56b36ad955ca   nginx     "/docker-entrypoint.…"   7 seconds ago   Up 6 seconds   0.0.0.0:3344->80/tcp   nginx01[root@zhourui home]# curl localhost:3344[root@zhourui home]# docker exec -it nginx01 bin/bashroot@56b36ad955ca:/# whereis nginxnginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginxroot@56b36ad955ca:/# cd /etc/nginxroot@56b36ad955ca:/etc/nginx# lsconf.d	fastcgi_params	koi-utf  koi-win  mime.types  modules  nginx.conf  scgi_params	uwsgi_params  win-utfroot@56b36ad955ca:/etc/nginx# #每次改动nginx的配置文件,都需要进入容器的内部修改,非常麻烦,后面学习数据卷的技术就可以在容器外部修改文件,容器内自动同步。

    访问自己服务器的nginx:




部署Tomcat


#docker hub 官方的使用docker run -it --rm tomcat:9.0#之前练习的启动在后台,停止容器后,容器还在,可以查到。run -it --rm 一般用来测试,用完即删除(容器删除镜像还在)[root@zhourui /]# docker pull tomcat[root@zhourui /]# docker imagesREPOSITORY    TAG       IMAGE ID       CREATED         SIZEtomcat        9.0       040bdb29ab37   2 months ago    649MBtomcat        latest    040bdb29ab37   2 months ago    649MBnginx         latest    f6d0b4767a6c   2 months ago    133MBcentos        latest    300e315adb2f   3 months ago    209MBhello-world   latest    bf756fb1ae65   14 months ago   13.3kB[root@zhourui /]# docker run -d -p 3355:8080 --name tomcat01 tomcat53197d7745a2d7f83f3a45b1f474a189eb7f496b0cf08c9a509a6c390680e347[root@zhourui /]# curl localhost:3355

浏览器测试访问:


#进入容器[root@zhourui /]# docker exec -it tomcat01 /bin/bashroot@53197d7745a2:/usr/local/tomcat# lsBUILDING.txt  CONTRIBUTING.md  LICENSE	NOTICE	README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  native-jni-lib  temp  webapps  webapps.dist  workroot@53197d7745a2:/usr/local/tomcat# cd webappsroot@53197d7745a2:/usr/local/tomcat/webapps# lsroot@53197d7745a2:/usr/local/tomcat/webapps# #发现ll无法使用,ls-al可以使用,命令少了。webapps中是空的,默认的是最小的镜像,不必要的被删除了,保证的是最小可用环境。

如果想要访问,可以复制webapps.dist目录的内容到webapps中


root@53197d7745a2:/usr/local/tomcat/webapps# cd ..root@53197d7745a2:/usr/local/tomcat# cd webapps.distroot@53197d7745a2:/usr/local/tomcat/webapps.dist# lsROOT  docs  examples  host-manager  managerroot@53197d7745a2:/usr/local/tomcat/webapps.dist# cd ..root@53197d7745a2:/usr/local/tomcat# cp -r webapps.dist/* webappsroot@53197d7745a2:/usr/local/tomcat# cd webappsroot@53197d7745a2:/usr/local/tomcat/webapps# lsROOT  docs  examples  host-manager  managerroot@53197d7745a2:/usr/local/tomcat/webapps# 

再次刷新网页访问即可!



部署es+kibana


#es暴漏的端口十分多#es十分耗内存#es的数据一般需要放置到安全目录,挂载。#--net somenetwork  网络配置#启动(启动前停掉其它的容器,防止启动不了)docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2#docker stats 容器id 查看cpu的状态#启动后 发现执行docker ps命令非常卡,因为内存快耗尽。

启动后可以从宝塔上看到自己服务器的内存状态。(也可以使用命令docker stats 容器id 查看cpu,内存的状态)



停掉es


[root@zhourui /]# docker psCONTAINER ID   IMAGE                 COMMAND                  CREATED         STATUS         PORTS                                            NAMES94c6cad2a01d   elasticsearch:7.6.2   "/usr/local/bin/dock…"   5 minutes ago   Up 5 minutes   0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   elasticsearch[root@zhourui /]# docker stop 94c6cad2a01d94c6cad2a01d

这时查看服务器的状态



再次启动,增加内存的配置,修改配置文件,-e 环境配置修改。


docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node"  -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2

可视化



  • portainer(图形化界面管理工具,提供一个面板供操作)


docker run -d -p 9222:9000 \--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer


  • Rancher(CI/CD 持续集成/持续部署时使用)


启动portainer后访问测试:



进入后选择local,点击connect



可以看到镜像,容器等



查看镜像



Docker镜像


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


将应用直接打包为docker镜像,就可以直接跑起来。


如何得到镜像:



  • 从仓库下载

  • 自己制作一个镜像


Docker镜像加载原理


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


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


Docker镜像加载原理:docker镜像实际上是由一层一层的文件系统组成,这种层级的文件系统叫UnionFS(联合文件系统)。


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


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



可以使用docker images看到Centos的镜像非常小。



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


分层理解


下载一个镜像,观察日志输出,可以看到是一层一层的在下载(分层下载,提高了复用性)


使用docker inspect redis,可以看到RootFS


 "RootFS": {            "Type": "layers",            "Layers": [                "sha256:cb42413394c4059335228c137fe884ff3ab8946a014014309676c25e3ac86864",                "sha256:8e14cb7841faede6e42ab797f915c329c22f3b39026f8338c4c75de26e5d4e82",                "sha256:1450b8f0019c829e638ab5c1f3c2674d117517669e41dd2d0409a668e0807e96",                "sha256:f927192cc30cb53065dc266f78ff12dc06651d6eb84088e82be2d98ac47d42a0",                "sha256:a24a292d018421783c491bc72f6601908cb844b17427bac92f0a22f5fd809665",                "sha256:3480f9cdd491225670e9899786128ffe47054b0a5d54c48f6b10623d2f340632"            ]        },

理解:所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,都会在当前的镜像层上,创建新的镜像层。在添加额外的镜像层时,镜像始终保持是当前所有镜像的组合。


特点:


docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常是我们所说的容器层,容器之下都是镜像层。



commit镜像


docker commit #提交容器成为一个新的副本#命令和git类似docker commit -m=“提交描述信息” -a=“作者” 容器id 目标镜像名:[TAG]

测试


#启动一个tomcatdocker run -it -p 8081:8080 tomcat#在新的窗口进入tomcat[root@zhourui /]# docker psCONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS          1fd9b7b4cb3d   tomcat                "catalina.sh run"        28 seconds ago   Up 27 seconds   0.0.0.0:8081->8080/tcp                           [root@zhourui /]# docker exec -it 1fd9b7b4cb3d /bin/bash#官方默认的tomcat的webapps下面没有应用,自己拷贝cp -r webapps.dist/* webapps#提交自己的镜像,以后使用修改过的镜像即可[root@zhourui /]# docker commit -a="zhourr" -m="add webapps" 1fd9b7b4cb3d tomcat02:1.0sha256:1c7804b415ba38099178f63e48444aebec938252632defd16bb35acc71bdabab[root@zhourui /]# docker imagesREPOSITORY            TAG       IMAGE ID       CREATED         SIZEtomcat02              1.0       1c7804b415ba   6 seconds ago   654MBredis                 latest    621ceef7494a   2 months ago    104MBtomcat                9.0       040bdb29ab37   2 months ago    649MBtomcat                latest    040bdb29ab37   2 months ago    649MBnginx                 latest    f6d0b4767a6c   2 months ago    133MBcentos                latest    300e315adb2f   3 months ago    209MBportainer/portainer   latest    62771b0b9b09   8 months ago    79.1MBelasticsearch         7.6.2     f29a1ee41030   12 months ago   791MBhello-world           latest    bf756fb1ae65   14 months ago   13.3kB[root@zhourui /]# 

对容器进行修改后,想保存容器的状态,通过commit来提交,下次就可以使用自己提交的这个镜像了。就好比 vm 的快照功能。


容器数据卷


如果数据在容器中,那么将容器删除,数据就会丢失!需求,数据可持久化!!


MySQL容器删除,数据丢失,需求,MySQL数据可以存储在本地!!


容器之间可以有一个数据共享的技术。Docker容器中产生的数据,同步到本地。


这就是卷技术!将容器内的目录,挂载到主机上。


数据持久化和同步操作,容器间也是可以数据共享的。


使用数据卷


方式一:使用命令来挂载 -v


docker -it -v主机内的目录:容器内的目录#测试[root@zhourui home]# docker run -it -v /home/zrtest:/home centos /bin/bash#启动后使用 docker inspect 容器id 查看

使用 docker inspect 容器id 查看



测试文件的同步



1.停止容器


2.修改宿主机上的文件


3.启动容器,发现文件依旧是同步的



好处:以后修改只需要在本地修改即可,不需要进入容器!


部署MySQL


MySQL的数据持久化问题!


#获取镜像docker pull mysql:5.7#运行容器,数据挂载。安装mysql需要配置密码的,注意!#官方测试连接方法docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag#启动MySQL-d:后台运行-p:端口映射-v:数据卷挂载-e:环境配置--name:容器别名docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7#在本地连接上后创建一个test数据库,查看映射路径是否可以。

在本地使用Navicat测试连接



将容器删除后


[root@zhourui data]# lsauto.cnf    ca.pem           client-key.pem  ibdata1      ib_logfile1  mysql               private_key.pem  server-cert.pem  sysca-key.pem  client-cert.pem  ib_buffer_pool  ib_logfile0  ibtmp1       performance_schema  public_key.pem   server-key.pem   test

可以看到test数据库还在,即挂载到本地的数据卷没有丢失,这就实现了容器数据的持久化。


具名挂载和匿名挂载


#匿名挂载-P(大写P 随机映射端口)-v 容器内路径docker run -d -P --name nginx01 -v /etc/nginx nginx#查看所有的卷的情况[root@zhourui home]# docker volume lsDRIVER    VOLUME NAMElocal     42a60ffb1a9dfcefffdf269e3a08fcb9172a082babe6ea19b864d5f679eb4361local     93e2f2060025965b83b0433b95e29ac325c25fa8684b79a12617438ffe898941local     271ccfa1da7814fa8fceb5b482ce86009f97e29c09dca69bcc594a0d8fabb92a#匿名挂载:这里-v的时候只写了容器内的路径,没有写容器外的路径#具名挂载[root@zhourui home]# docker  run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx3024685007a57eda45820c8c07920cea08b84b7847b86fd97f5f71f7100b8fbd[root@zhourui home]# docker volume lsDRIVER    VOLUME NAMElocal     42a60ffb1a9dfcefffdf269e3a08fcb9172a082babe6ea19b864d5f679eb4361local     93e2f2060025965b83b0433b95e29ac325c25fa8684b79a12617438ffe898941local     271ccfa1da7814fa8fceb5b482ce86009f97e29c09dca69bcc594a0d8fabb92alocal     juming-nginx[root@zhourui home]# #通过-v 卷名:容器内名字#查看卷[root@zhourui home]# docker volume inspect juming-nginx


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


通过具名挂载可以方便的找到我们的卷,大多数情况下都是使用具名挂载。


#如何确定是具名挂载还是匿名挂载,还是指定路径挂载-v 容器内路径  			#匿名挂载-v 卷名:容器内路径 	  #具名挂载-v /宿主机路径:容器内路径  #指定路径挂载

拓展:


 #通过-v 卷名:容器内路径:ro或rw 改变读写权限 ro readonly   #只读 rw readwrite  #可读可写  #一旦设置了容器权限,容器对挂载出来的文件就有限定了 docker  run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx docker  run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx  #只要看到ro,就说明这个文件只能通过宿主机来操作,容器内部是无法操作的!

初识Dockerfile


Dockerfile就是用来构建 docker 镜像的构建文件!命令脚本!


通过这个脚本可以生成镜像。镜像是一层一层的,脚本是一个个的命令,每个命令都是一层。


方式二:


[root@zhourui home]# pwd/home[root@zhourui home]# cd docker-test-volume/[root@zhourui docker-test-volume]# pwd/home/docker-test-volume[root@zhourui docker-test-volume]# vim dockerfile  #创建dockerfile[root@zhourui docker-test-volume]# cat dockerfile  #文件中添加以下内容后查看(文件中内容 指令(大写) 参数)#每个命令就是镜像的一层FROM centosVOLUME ["volume01","volume02"]  #匿名挂载CMD echo "....end...."CMD /bin/bash[root@zhourui docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile -t zhour/centos:1.0 .


#启动自己生成的容器docker run -it 29e054de9dd4 /bin/bash#在volume01中创建文件[root@e224b7ebc0d7 volume01]# ls[root@e224b7ebc0d7 volume01]# touch container.txt[root@e224b7ebc0d7 volume01]# lscontainer.txt[root@e224b7ebc0d7 volume01]# 


查看匿名卷挂载的路径:docker inspect 容器id



进入挂载的路径中查看


[root@zhourui /]# cd /var/lib/docker/volumes/f517ef934bb1d4376751cf0ec11608ed0fd287844436ba62cad973ce0f67dee8/_data[root@zhourui _data]# lscontainer.txt[root@zhourui _data]# 

可以看到文件已经同步!!


这种方式较常使用,通常用于构建自己的镜像。


假设构建镜像时没有挂载卷,需要手动挂载,-v 卷名:容器内路径。


数据卷容器



启动三个容器


#创建docker01[root@zhourui /]# docker run -it --name docker01 29e054de9dd4[root@255f9d13bea7 /]# lsbin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01	volume02#创建docker02[root@zhourui /]# docker run -it --name docker02 --volumes-from docker01 29e054de9dd4[root@861b5d25a8ca /]# lsbin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01	volume02#在docker01的volume01中创建文件[root@zhourui /]# docker attach 255f9d13bea7[root@255f9d13bea7 /]# cd volume01[root@255f9d13bea7 volume01]# ls[root@255f9d13bea7 volume01]# touch docker01#进入docker02的volume01中查看[root@861b5d25a8ca /]# cd volume01[root@861b5d25a8ca volume01]# lsdocker01#创建docker03并在volume01中增加docker03文件[root@zhourui /]# docker run -it --name docker03 --volumes-from docker01 29e054de9dd4[root@7a405584084a /]# cd volume01[root@7a405584084a volume01]# lsdocker01[root@7a405584084a volume01]# touch docker03[root@7a405584084a volume01]# lsdocker01  docker03#在docker01中查看volume01[root@255f9d13bea7 volume01]# lsdocker01  docker03[root@255f9d13bea7 volume01]# 

通过 --volumes-from 可以实现容器间的数据共享!!


可以测试删除掉 docker01 ,再去查看 docker02 和 docker03 ,数据仍然还在。


三个容器之间的文件是相互拷贝的,删掉一个不会丢失数据。


应用:多个 MySQL 或者 Redis 之间实现数据共享!!


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.7docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7#可以实现两个MySQL之间的数据同步

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


通过 -v 将数据持久化到本地,本地的数据是不会删除的。


DockerFile


DockerFile介绍


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


构建步骤:



  1. 编写一个 dockerfile 文件

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

  3. docker run 运行镜像

  4. docker push 发布镜像(dockerHub,阿里云镜像仓库)


查看官方 centos,点击版本会跳转至 GitHUb




很多的官方镜像都是基础包,一些功能没有,我们就需要自己搭建。


DockerFile构建过程


基础知识:



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

  2. 只需顺序从上到下。

  3. , 表示注释。


  4. 每个指令都会创建提交一个新的镜像层。



docker 是面向开发的,发布项目做镜像,就需要编写 dockerfile 文件。


Docker镜像逐渐成为企业交付的标准。


dockerfile :构建文件,定义了一切所需的环境和源代码。


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


docker 容器:容器是镜像运行起来后提供服务的。


DockerFile指令


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


实战测试


Docker Hub 中99%的镜像都是由这个基础镜像 FROM scratch 来配置构建的


FROM scratchADD centos-8-x86_64.tar.xz /LABEL \	org.label-schema.schema-version="1.0" \    org.label-schema.name="CentOS Base Image" \    org.label-schema.vendor="CentOS" \    org.label-schema.license="GPLv2"  \    org.label-schema.build-date="20201204"CMD ["/bin/bash"]

创建一个自己的 CentOS


#编写 dockerfile 的文件[root@zhourui home]# cd dockerfile/[root@zhourui dockerfile]# ls[root@zhourui dockerfile]# vim mydockerfile-centos[root@zhourui dockerfile]# cat mydockerfile-centos FROM centosMAINTAINER zhourr<813794474@qq.com>ENV MYPATH /usr/localWORKDIR $MYPATH  	#进去后的工作目录,进去后 pwd 查看RUN yum -y install vim  	#安装 vimRUN yum -y install net-tools  #安装后可以使用 ifconfig (不安装只能用 ip add)EXPOSE 80CMD echo $MYPATHCMD echo "...end..."CMD /bin/bash#通过这个文件构建镜像-f 构建文件路径-t 镜像名:[tag]最后有个 .[root@zhourui dockerfile]# docker build  -f mydockerfile-centos -t mycentos:0.1 ....Successfully built ddba7ccc7eeeSuccessfully tagged mycentos:0.1#测试运行docker run -it mycentos:0.1

默认的 centos 以下命令无法使用


[root@95c725dda358 /]# pwd/[root@95c725dda358 /]# vimbash: vim: command not found[root@95c725dda358 /]# ifconfigbash: ifconfig: command not found[root@95c725dda358 /]# 

测试运行自己创建的镜像这些命令就可以使用了。



我们可以列出本地镜像的变更历史 docker history 镜像id



CMD和ENTRYPOINT的区别


CMD 		#指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代ENTRYPOINT	#指定这个容器启动的时候要运行的命令,可以追加命令

测试 CMD


[root@zhourui dockerfile]# vim dockerfile-cmd-testFROM centosCMD ["ls","-a"]#构建镜像[root@zhourui dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest .....Successfully built a44c7103184fSuccessfully tagged cmdtest:latest# run 运行,可以看到 ls-a 命令生效[root@zhourui dockerfile]# docker run a44c7103184f....dockerenvbindevetchomelib...#追加一个 l ,希望返回 ls-al[root@zhourui dockerfile]# docker run a44c7103184f -ldocker: 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.#此时报错,因为使用CMD,-l替换了["ls","-a"],-l不是命令,所以报错#需要使用以下完整命令[root@zhourui dockerfile]# docker run a44c7103184f ls -al

测试 ENTRYPOINT


[root@zhourui dockerfile]# vim dockerfile-entrypointFROM centosENTRYPOINT ["ls","-a"][root@zhourui dockerfile]# docker build -f dockerfile-entrypoint -t entrypointtest ....Successfully built 34773b8b0398Successfully tagged entrypointtest:latest[root@zhourui dockerfile]# docker run 34773b8b0398....dockerenvbindevetchomelib...# 添加 -l,是可以直接追加到后面的,ls -a -l[root@zhourui dockerfile]# docker run 34773b8b0398 -ltotal 0drwxr-xr-x   1 root root   6 Mar 27 14:51 .drwxr-xr-x   1 root root   6 Mar 27 14:51 ..-rwxr-xr-x   1 root root   0 Mar 27 14:51 .dockerenvlrwxrwxrwx   1 root root   7 Nov  3 15:22 bin -> usr/bindrwxr-xr-x   5 root root 340 Mar 27 14:51 devdrwxr-xr-x   1 root root  66 Mar 27 14:51 etcdrwxr-xr-x   2 root root   6 Nov  3 15:22 homelrwxrwxrwx   1 root root   7 Nov  3 15:22 lib -> usr/lib

Docker中很多命令都十分相似,需要去对比测试一下,才能发现其中的区别。


实战 Tomcat镜像



  1. 准备镜像文件 tomcat 压缩包,jdk压缩包(放到home/zhour-tar目录下)


  2. 编写 Dockerfile 文件,官方命名:Dockerfile,build的时候会自动寻找这个文件,就不需要 -f 指定了。(在home/zhour-tar目录下,vim Dockerfile),压缩包会自动解压。

    FROM centosMAINTAINER zhourr<813794474@qq.com>COPY readme.txt /usr/local/read.txtADD jdk-8u281-linux-x64.tar.gz /usr/local/ADD apache-tomcat-9.0.44.tar.gz /usr/local/RUN yum -y install vimENV MYPATH /usr/localWORKDIR $MYPATHENV JAVA_HOME /usr/local/jdk1.8.0_281ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarENV CATALINA_HOME /usr/local/apache-tomcat-9.0.44ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.44ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/binEXPOSE 8080CMD /usr/local/apache-tomcat-9.0.44/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.44/bin/logs/catalina.out

  3. 构建镜像

    [root@zhourui zhour-tar]# lsapache-tomcat-9.0.44.tar.gz  Dockerfile  jdk-8u281-linux-x64.tar.gz  readme.txt#构建[root@zhourui zhour-tar]# docker build -t diytomcat .

  4. 启动镜像

    [root@zhourui zhour-tar]# docker run -d -p 3030:8080 --name zhoutomcat -v /home/zhour-tar/test:/usr/local/apache-tomcat-9.0.44/webapps/test -v /home/zhour-tar/tomcatlogs/:/usr/local/apache-tomcat-9.0.44/logs diytomcat

  5. 访问测试


  6. 发布项目(配置了数据卷挂载,直接在容器外编写项目就可以发布了)在test中新建

    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"         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"         id="WebApp_ID" version="3.0"> </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 zhourrr!!</title></head><body>Hello World!<br/><%System.out.println("----my tomcat test----");%></body></html>

  7. 访问http://39.105.48.232:3030/test/


  8. 日志查看,cd /home/zhour-tar/tomcatlogs。cat catalina.out



需要掌握 Dockersfile 的编写!!


发布镜像


在 Docker Hub 上注册账号,在服务器登录后就可以提交自己的镜像了。


[root@zhourui tomcatlogs]# docker login --helpUsage:  docker login [OPTIONS] [SERVER]Log in to a Docker registry.If no server is specified, the default is defined by the daemon.Options:  -p, --password string   Password      --password-stdin    Take the password from stdin  -u, --username string   Username

登录


[root@zhourui tomcatlogs]# docker login -u zhourui88Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json.Configure a credential helper to remove this warning. Seehttps://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded

提交


[root@zhourui tomcatlogs]# docker push diytomcatUsing default tag: latestThe push refers to repository [docker.io/library/diytomcat]e21bfbb06ee5: Preparing 145f6d70801c: Preparing f3ba2f2219d6: Preparing f83a7c49f1e3: Preparing 2653d992f4ef: Preparing denied: requested access to the resource is denied #拒绝#需要增加一个tag[root@zhourui tomcatlogs]# docker tag ea84d80641b1 zhourui88/tomcat:1.0#查看[root@zhourui tomcatlogs]# docker imagesREPOSITORY            TAG       IMAGE ID       CREATED             SIZEdiytomcat             latest    ea84d80641b1   About an hour ago   640MBzhourui88/tomcat        1.0       ea84d80641b1   About an hour ago   640MB#提交[root@zhourui tomcatlogs]# docker push zhourui88/tomcat:1.0


提交的时候镜像也是按层级来提交的!


阿里云服务器



  1. 登录阿里云


  2. 找到容器镜像服务


  3. 创建命名空间


  4. 创建容器镜像


  5. 点击镜像仓库名 zhourui-test 浏览阿里云



#登录[root@zhourui /]#  sudo docker login --username=周锐822 registry.cn-beijing.aliyuncs.com#提交到阿里云,这里没有更改tag,显示上传成功,但是我没有找到镜像[root@zhourui /]# docker push zhourui88/tomcat:1.0The push refers to repository [docker.io/zhourui88/tomcat]e21bfbb06ee5: Layer already exists 145f6d70801c: Layer already exists f3ba2f2219d6: Pushing [==========>                                        ]  77.66MB/356.6MBf83a7c49f1e3: Layer already exists #上传阿里云[root@zhourui /]# sudo docker tag ea84d80641b1 registry.cn-beijing.aliyuncs.com/docker-zhourui/zhourui-test:1.0[root@zhourui /]# docker imagesREPOSITORY                                                     TAG       IMAGE ID       CREATED        diytomcat                                                      latest    ea84d80641b1   3 hours ago         zhourui88/tomcat                                               1.0       ea84d80641b1   3 hours ago     registry.cn-beijing.aliyuncs.com/docker-zhourui/zhourui-test   1.0       ea84d80641b1   3 hours ago     [root@zhourui /]# docker push registry.cn-beijing.aliyuncs.com/docker-zhourui/zhourui-test:1.0

上传后查看



小结



Docker网络


理解 Dockers0


ip addr



#启动容器[root@zhourui /]# docker run -d -P --name tomcat01 tomcat72dee6c91e3f593c69858191014b9d228c6494b0aa049cd1f620350c1c46cd56#查看容器内部网络地址  eth0@if123 ip地址 docker分配的[root@zhourui /]# docker exec -it tomcat01 ip addr1: 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 forever122: eth0@if123: <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#Linux去ping容器的内部[root@zhourui /]# ping 172.17.0.2PING 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.062 ms64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.045 ms

原理:我们每启动一个 docker 容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0.


桥接模式,使用的技术是 evth-pair 技术


这时再输入 ip addr,发现多了一个网卡



再启动一个 tomcat02 发现又多了一个网卡 (docker run -d -P --name tomcat02 tomcat) ipaddr



查看tomcat02 ip addr


[root@zhourui /]# docker exec -it tomcat02 ip addr1: 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 forever124: eth0@if125: <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

可以发现容器的网卡都是一对一对的,【122: eth0@if123】【124: eth0@if125】。


evth-pair:就是一对虚拟设备接口,它们都是成对出现的,一段连着协议,一段彼此相连。


所以,evth-pair就充当一个桥梁,连接各种虚拟网络设备。


测试tomcat01和tomcat02之间能不能ping通:


[root@zhourui /]# docker exec -it tomcat02 ping 172.17.0.2PING 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.091 ms64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.069 ms#可以看到,容器之间是可以通信的

流程图理解



tomcat01 和 tomcat02 是公用一个路由器 docker0 。


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


Docker使用的是 Linux 的桥接,宿主机中是 Docker 容器的网桥(Docker0)



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


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


docker network ls,docker network inspect (桥接network id)可以查看




假设我们想通过容器的名字来ping,而不是通过ip,就需要使用 --link。


[root@zhourui /]# docker exec -it tomcat02 ping tomcat01ping: tomcat01: Name or service not known#通过--link可以解决[root@zhourui /]# docker run -d -P --name tomcat03 --link tomcat02 tomcat131bbb6e180687ff284ef2cabc78f4104dfc5d1018ee1e2f11a5b6e192bdc8bb[root@zhourui /]# docker exec -it tomcat03 ping tomcat02PING 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.101 ms#反向ping[root@zhourui /]# docker exec -it tomcat02 ping tomcat03ping: tomcat03: Name or service not known

docker network ls,docker network inspect (桥接network id)可以查看



--link 使用后,tomcat03在本地配置了tomcat02


[root@zhourui /]# docker exec -it tomcat03 cat /etc/hosts127.0.0.1	localhost::1	localhost ip6-localhost ip6-loopbackfe00::0	ip6-localnetff00::0	ip6-mcastprefixff02::1	ip6-allnodesff02::2	ip6-allrouters172.17.0.3	tomcat02 1fff64acaf04172.17.0.4	131bbb6e1806

本质:在hosts的配置中增加了 tomcat02 的映射。


真实开发中,已经不建议使用 --link 了。


自定义网络,不使用 docker0。docker0不支持容器名连接访问。


自定义网络


查看所有的docker网络


[root@zhourui /]# docker network lsNETWORK ID     NAME      DRIVER    SCOPE25000c3be4a4   bridge    bridge    local  #桥接b518cb3beba9   host      host      localbcd06ce03d47   none      null      local

网络模式


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


none:不配置网络


host:和宿主机共享网络


container:容器内网络联通(局限性很大)


测试:


#直接启动,默认是 --net bridge 的,docker run -d -P --name tomcat01 tomcatdocker run -d -P --name tomcat01 --net bridge tomcat#docker0特点,默认,域名不能访问,--link可以打通连接#自定义网络# --driver bridge# --subnet 192.168.0.0/16 # --gateway 192.168.0.1 [root@zhourui /]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet6219f386e2bfc7f837554de2b011ec1d649d6eaafa617fcf4bdd2d8091cf82b2[root@zhourui /]# docker network lsNETWORK ID     NAME      DRIVER    SCOPE25000c3be4a4   bridge    bridge    localb518cb3beba9   host      host      local6219f386e2bf   mynet     bridge    localbcd06ce03d47   none      null      local

查看自己的网络:docker network inspect mynet



创建两个容器,连上自己的网络


[root@zhourui /]# docker run -d -P --name tomcat-net-01 --net mynet tomcatc638c0cee8dff978e60532b9a1ddac74f10a45bfb6b542bf3fd3079f69ec5515[root@zhourui /]# docker run -d -P --name tomcat-net-02 --net mynet tomcate9aee8d922b19af82f02e9e50b28a301ab10e7eb57828c454cb57b9ac5bdc0ae[root@zhourui /]# docker network inspect mynet[    {        "Name": "mynet",        "Id": "6219f386e2bfc7f837554de2b011ec1d649d6eaafa617fcf4bdd2d8091cf82b2",        "Created": "2021-03-28T17:29:39.571024726+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": {            "c638c0cee8dff978e60532b9a1ddac74f10a45bfb6b542bf3fd3079f69ec5515": {                "Name": "tomcat-net-01",                "EndpointID": "6d4ac08b616e2e33e8fb7a3e8659b5a6ff2e381083572dbe202f7b8598347177",                "MacAddress": "02:42:c0:a8:00:02",                "IPv4Address": "192.168.0.2/16",                "IPv6Address": ""            },            "e9aee8d922b19af82f02e9e50b28a301ab10e7eb57828c454cb57b9ac5bdc0ae": {                "Name": "tomcat-net-02",                "EndpointID": "187733df51f17912e402211643ce7136cbb725d85a0c1045ef7e903471d9f878",                "MacAddress": "02:42:c0:a8:00:03",                "IPv4Address": "192.168.0.3/16",                "IPv6Address": ""            }        },        "Options": {},        "Labels": {}    }]#再次测试 ping 连接[root@zhourui /]# docker exec -it tomcat-net-01 ping 192.168.0.3PING 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.115 ms64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.067 ms64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.068 ms^C--- 192.168.0.3 ping statistics ---3 packets transmitted, 3 received, 0% packet loss, time 67msrtt min/avg/max/mdev = 0.067/0.083/0.115/0.023 ms#不使用 --link。也可以ping名字了[root@zhourui /]# docker exec -it tomcat-net-01 ping tomcat-net-02PING 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.075 ms64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.070 ms64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.086 ms

自定义的网络donker帮我们维护好了关系,推荐使用自定义的网络。


应用:
redis:不同的集群使用不同的网络,保证集群是安全和健康的(192.168.xxx.xxx)


mysql:不同的集群使用不同的网络,保证集群是安全和健康的(192.182.xxx.xxx)


网络联通


创建两个容器在默认的docker0网络下


[root@zhourui /]# docker run -d -P --name tomcat01 tomcat[root@zhourui /]# docker run -d -P --name tomcat02 tomcat

现在就有以下的四个容器在在 docker0 和 mynet 网络下。怎样去打通 tomcat01 连接到 mynet。



通过 --help 查看命令



测试打通 tomcat01 连接到 mynet


[root@zhourui /]# docker network connect mynet tomcat01[root@zhourui /]# docker network inspect mynet#打通之后,tomcat01被放到了 mynet 网络下,#一个容器两个 ip 地址


测试


[root@zhourui /]# docker exec -it tomcat01 ping tomcat-net-01PING 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.092 ms#反向也是可以ping通的[root@zhourui /]# docker exec -it tomcat-net-01 ping tomcat01PING tomcat01 (192.168.0.4) 56(84) bytes of data.64 bytes from tomcat01.mynet (192.168.0.4): icmp_seq=1 ttl=64 time=0.118 ms#tomcat02 是没有连接上 mynet 的[root@zhourui /]# docker exec -it tomcat02 ping tomcat-net-01ping: tomcat-net-01: Name or service not known

结论:如果需要跨网络操作,就需要使用 docker network connect 网络 容器名称 来联通!!


部署Redis集群


#创建redis的网络docker network create redis --subnet 172.38.0.0/16#通过脚本创建6个redis配置for port in $(seq 1 6); \do \mkdir -p /mydata/redis/node-${port}/conftouch /mydata/redis/node-${port}/conf/redis.confcat << EOF >/mydata/redis/node-${port}/conf/redis.confport 6379bind 0.0.0.0cluster-enabled yescluster-config-file nodes.confcluster-node-timeout 5000cluster-announce-ip 172.38.0.1${port}cluster-announce-port 6379cluster-announce-bus-port 16379appendonly yesEOFdonedocker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \-v /mydata/redis/node-${port}/data:/data \-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \#=====================================================================#单个启动docker run -p 6371:6379 -p 16371:16379 --name redis-1 \-v /mydata/redis/node-1/data:/data \-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.confdocker run -p 6372:6379 -p 16372:16379 --name redis-2 \-v /mydata/redis/node-2/data:/data \-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.confdocker run -p 6373:6379 -p 16373:16379 --name redis-3 \-v /mydata/redis/node-3/data:/data \-v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf#创建集群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[root@zhourui /]# docker exec -it redis-1 /bin/sh/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>>> Performing hash slots allocation on 6 nodes...Master[0] -> Slots 0 - 5460Master[1] -> Slots 5461 - 10922Master[2] -> Slots 10923 - 16383Adding replica 172.38.0.15:6379 to 172.38.0.11:6379Adding replica 172.38.0.16:6379 to 172.38.0.12:6379Adding replica 172.38.0.14:6379 to 172.38.0.13:6379M: 1524f57c751c662847b24edb3cf4433e42e11dae 172.38.0.11:6379   slots:[0-5460] (5461 slots) masterM: 3d0a68b584e5935b6174d8b8e0603a14eb246393 172.38.0.12:6379   slots:[5461-10922] (5462 slots) masterM: cce404917b84b790cf39ac1f6dff85c1c080c9a1 172.38.0.13:6379   slots:[10923-16383] (5461 slots) masterS: 2fb9e53fde60fb288e87a8bccf37f2d521c5f5be 172.38.0.14:6379   replicates cce404917b84b790cf39ac1f6dff85c1c080c9a1S: d977bb4c2b2a45bbbeb74cc123bd87dba1acd257 172.38.0.15:6379   replicates 1524f57c751c662847b24edb3cf4433e42e11daeS: 317ccf18aefe00a7a45820b6509bd8c9fc1f7097 172.38.0.16:6379   replicates 3d0a68b584e5935b6174d8b8e0603a14eb246393Can I set the above configuration? (type 'yes' to accept): yes>>> Nodes configuration updated>>> Assign a different config epoch to each node>>> Sending CLUSTER MEET messages to join the clusterWaiting for the cluster to join..>>> Performing Cluster Check (using node 172.38.0.11:6379)M: 1524f57c751c662847b24edb3cf4433e42e11dae 172.38.0.11:6379   slots:[0-5460] (5461 slots) master   1 additional replica(s)M: cce404917b84b790cf39ac1f6dff85c1c080c9a1 172.38.0.13:6379   slots:[10923-16383] (5461 slots) master   1 additional replica(s)M: 3d0a68b584e5935b6174d8b8e0603a14eb246393 172.38.0.12:6379   slots:[5461-10922] (5462 slots) master   1 additional replica(s)S: 317ccf18aefe00a7a45820b6509bd8c9fc1f7097 172.38.0.16:6379   slots: (0 slots) slave   replicates 3d0a68b584e5935b6174d8b8e0603a14eb246393S: d977bb4c2b2a45bbbeb74cc123bd87dba1acd257 172.38.0.15:6379   slots: (0 slots) slave   replicates 1524f57c751c662847b24edb3cf4433e42e11daeS: 2fb9e53fde60fb288e87a8bccf37f2d521c5f5be 172.38.0.14:6379   slots: (0 slots) slave   replicates cce404917b84b790cf39ac1f6dff85c1c080c9a1[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[OK] All 16384 slots covered./data # redis-cli -c127.0.0.1:6379> cluster info127.0.0.1:6379> cluster nodes127.0.0.1:6379> set a b-> Redirected to slot [15495] located at 172.38.0.13:6379OK172.38.0.13:6379> #新建窗口  docker stop redis-3#获取 a 的值127.0.0.1:6379> get a-> Redirected to slot [15495] located at 172.38.0.14:6379"b"


搭建redis集群完成!!


SpringBoot打包Dockers镜像



  1. 构建一个SpringBoot项目

    @RestControllerpublic class HelloController {    @RequestMapping("/hello")    public String hello(){        return "Hello zhour!";    }}

  2. 打包应用,package


  3. 编写dockerfile

    FROM java:8COPY *.jar /app.jarCMD ["---server port 8080---"]EXPOSE 8080ENTRYPOINT ["java","-jar","app.jar"]

  4. 构建镜像(使用 ftp 将文件上传至服务器)

    [root@zhourui idea]# lsdemo-docker-0.0.1-SNAPSHOT.jar  Dockerfile[root@zhourui idea]# docker build -t boottestzr .

  5. 发布运行

    [root@zhourui idea]# docker run -d -P --name ideaboot-web boottestzr

  6. 访问



如需浏览器访问,阿里云开发端口,或者运行时 -p 暴漏已开放的端口即可!!

上一篇:Git学习使用
下一篇:MyBatisPlus入门学习

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2025年04月22日 12时13分14秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

2025大语言模型入门该怎么学?零基础入门到精通,收藏这篇就够了 2023-01-24
2025想做黑客?先来学习 SQL 注入,零基础入门到精通,收藏这篇就够了 2023-01-25
2025最新大模型技术学习过程梳理,零基础入门到精通,收藏这篇就够了 2023-01-25
2025版万字长文入门大语言模型(LLM)零基础入门到精通,收藏这篇就够了 2023-01-25
2025版最新0基础怎么转行网络安全?零基础入门到精通,收藏这篇就够了 2023-01-25
2025版最新Bash Shell入门指南,零基础入门到精通,收藏这篇就够了 2023-01-25
2025版最新C++快速入门(适合小白)零基础入门到精通,收藏这篇就够了 2023-01-25
2025版最新Java教程(非常详细)零基础入门到精通,收藏这篇就够了 2023-01-25
2025版最新LangChain框架快速入门,零基础入门到精通,收藏这篇就够了 2023-01-25
2025版最新Metasploit安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了 2023-01-25
2025版最新Nessus 工具介绍与使用教程,零基础入门到精通,收藏这一篇就够了 2023-01-25
2025版最新wireshark怎么抓包?Wireshark入门指南,零基础入门到精通,收藏这篇就够了 2023-01-25
2025版最新一文彻底搞懂大模型 - Agent(非常详细)零基础入门到精通,收藏这篇就够了 2023-01-25
2025版最新关于HW护网行动的一些知识,零基础入门到精通,收藏这篇就够了 2023-01-25
(建议收藏)2024最新 URL Scheme大全APP跳转界面地址更新中 ios快捷指令快捷方式链接跳转微信小程序必备autojs可用免root (可定制开发和提取URL Scheme 参数提取) 2023-01-25
2025版最新大模型学习路线,零基础入门到精通,收藏这篇就够了 2023-01-25
2025版最新大模型开发流程(非常详细)零基础入门到精通,收藏这一篇就够了 2023-01-25
(大部分安卓手机通用)一加OnePlus Ace3扬声器优化教程 外放直接媲美苹果 2023-01-25
2025版最新大模型微调方法(非常详细)零基础入门到精通,收藏这篇就够了 2023-01-25
2025版最新大模型算法岗位薪资指南,零基础入门到精通,收藏这一篇就够了 2023-01-25