我是靠谱客的博主 敏感悟空,这篇文章主要介绍Docker学习笔记Doker概述Docker安装Docker镜像容器数据卷初始DockerFileDocker网络SpringBoot微服务打包Docker镜像总结,现在分享给大家,希望可以做个参考。

文章目录

  • Doker概述
    • Docker为什么会出现
    • Docker简介
    • Docker的基本组成
  • Docker安装
    • 帮助命令
    • 镜像命令
    • 容器命令
    • 可视化
  • Docker镜像
    • 镜像是什么
    • Docker镜像加载原理
  • 容器数据卷
    • 使用数据卷
    • 安装MySQL
    • 具名和匿名挂载
  • 初始DockerFile
    • 数据卷容器
    • DockerFile介绍
    • DockerFile构建过程
    • DockerFile的指令
    • 自定义Tomcat镜像
    • 发布自己的镜像
  • Docker网络
    • 理解Docker0
    • --link
    • 自定义网络
    • 网络连通
    • 实战:部署Redis集群
  • SpringBoot微服务打包Docker镜像
  • **总结**

Doker概述

Docker为什么会出现

任何一个东西的产生都是有原因的,那么Docker的出现也不例外。举个栗子:一款产品从开发到上线,一般是有两套环境的,即开发人员的本地的应用环境和配置和项目上线后运维的部署环境。那么很容易产生一种问题:版本更新导致服务不可用,这对于运维人员来说考验巨大,毕竟环境配置是十分麻烦的一件事,比如每台机器都要配置jdk,hadoop集群,redis集群等等,费时又费力。(小声bb:我是大数据专业的,我的基本所有专业课有一半的时间都是水在搭建集群环境!!!)

而Docker就很好的解决了这个问题,传统的过程通俗点来说就是开发打个jar包过来,然后环境部署配置就由运维来做;现在有了docker项目打包部署一套流程做完,或者可以理解为有了docker,在打包项目的时候可以把环境连(镜像)同打包,只需要到Docker仓库下载发布的镜像,直接运行程序即可,十分的nice。

Docker简介

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

这些都是官方文档中所描述的,听起来比较高大上,就我的理解来看它与传统的虚拟机的区别就是:它虚拟的不是一个完整的操作系统,容器中的应用直接运行在宿主机的内核,容器是没有自己的内核的,也没有虚拟硬件,所以相比传统的虚拟机更轻便,并且每个容器间是隔离的,每个容器都有自己的文件系统,互不影响。

Docker的基本组成

镜像(image):docker的镜像就好比一个模板,可以通过这个模板来创建容器服务。通过这个镜像可以创建多个容器(最终项目或服务运行就是在容器中的)。

容器(container):docker利用容器技术,独立运行一个或一组应用,通过镜像来创建。这里我是简单的把它理解成一个简易的“轻量”操作系统。

仓库(repository):仓库就是存放镜像的地方,分为公有和私有。同maven仓库的概念一样。

Docker安装

要求:Linux内核3.8以上,Centos7,通过MobaXterm连接到服务。

复制代码
1
2
3
[root@node1 ~]# uname -r 3.10.0-1062.el7.x86_64

系统版本

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@node1 ~]# cat /etc/os-release NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:centos:centos:7" HOME_URL="https://www.centos.org/" BUG_REPORT_URL="https://bugs.centos.org/" CENTOS_MANTISBT_PROJECT="CentOS-7" CENTOS_MANTISBT_PROJECT_VERSION="7" REDHAT_SUPPORT_PRODUCT="centos" REDHAT_SUPPORT_PRODUCT_VERSION="7"
复制代码
1
2
3
4
5
6
7
8
9
10
#卸载旧版本 yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine

下载需要的安装包

复制代码
1
2
yum install -y yum-utils

设置镜像仓库

这里需要注意,默认的是使用的国外的镜像源,特别慢,推荐使用阿里或者清华的镜像源。

复制代码
1
2
3
4
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

更新yum软件包索引

复制代码
1
2
yum makecache fast

安装docker相关的依赖

这里我们选的是docker-ce 社区版

复制代码
1
2
3
yum install docker-ce docker-ce-cli containerd.io

启动docker

复制代码
1
2
systemctl start docker测试验证helloworld

测试

复制代码
1
2
docker run hello-world

帮助命令

万能命令

复制代码
1
2
docker --help
复制代码
1
2
3
4
5
6
7
8
9
#系统常用命令 #查看内存占用情况 docker stats #docker环境信息 docker info | version #查看容器或镜像信息 docker inspect

镜像命令

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#查看自己服务器中docker 镜像列表 docker images #搜索镜像 docker search 镜像名 docker search --filter=STARS=9000 mysql 搜索 STARS >9000的 mysql 镜像 #拉取镜像 不加tag(版本号) 即拉取docker仓库中 该镜像的最新版本latest 加:tag 则是拉取指定版本 docker pull 镜像名 docker pull 镜像名:tag #运行镜像 docker run 镜像名 docker run 镜像名:Tag #删除镜像 当前镜像没有被任何容器使用才可以删除 #删除一个 docker rmi -f 镜像名/镜像ID #删除多个 其镜像ID或镜像用用空格隔开即可 docker rmi -f 镜像名/镜像ID 镜像名/镜像ID 镜像名/镜像ID #删除全部镜像 -a 意思为显示全部, -q 意思为只显示ID docker rmi -f $(docker images -aq) ...........

容器命令

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#可以通过run 镜像 来构建 自己的容器实例 #可以加参数 -d 后台运行(守护式运行) -p 手动端口映射 -P 随机分配端口 -v 卷挂载 可以设置多个 -e 环境配置 --name 容器名 -it 表示 与容器进行交互式启动 /bin/bash 交互路径 ...... docker run -it -d --name 要取得别名 镜像名:Tag /bin/bash #查看正在运行容器列表 docker ps #查看所有容器 -----包含正在运行 和已停止的 docker ps -a #停止容器 docker stop 容器名/容器ID #启动容器 docker start 容器名/容器ID #重启容器 docker restart 容器名/容器ID #kill 容器 docker kill 容器ID/容器名 #删除一个容器 docker rm -f 容器名/容器ID #删除多个容器 空格隔开要删除的容器名或容器ID docker rm -f 容器名/容器ID 容器名/容器ID 容器名/容器ID #删除全部容器 docker rm -f $(docker ps -aq) #进入容器的方式1 docker exec -it 容器名/容器ID /bin/bash #进入容器的方式2 docker attach 容器名/容器ID #从容器退出 #-----直接退出 未添加 -d(持久化运行容器) 时 执行此参数 容器会被关闭 exit # 优雅提出 --- 无论是否添加-d 参数 执行此命令容器都不会被关闭 Ctrl + p + q #查看容器日志 docker logs -f --tail=要查看末尾多少行 默认all 容器ID .........

可视化

portainer

官方提供的一个docker可视化工具,也是一个镜像,启动后指定端口,然后在windows下访问,即可使用可视化工具管理docker资源。

复制代码
1
2
3
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var /run/docker.sock --privilegedtrue portainer /portainer

可视化页面访问url: http://39.108.122.21:8088/#/dashboard
在这里插入图片描述

Docker镜像

镜像是什么

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

Docker镜像加载原理

UnionFS (联合文件系统)

UnionFS (联合文件系统):Union文件系统( UnionFS )是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtualfilesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性∶一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

Docker镜像加载原理

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS.
bootis(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
roots (root file system),在bootfs之上。包含的就是典型Linux系统中的/dev,/proc, /bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu , Centos等等。

容器数据卷

使用数据卷

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

复制代码
1
2
3
4
5
6
7
docker run -it -v 主机目录:容器内目录 #测试 [root@along ~]# docker run -it -v /home/test01:/home centos /bin/bash #启动后通过docker inspect 容器id 查看

结果:
在这里插入图片描述

再次测试

1.停止容器

2.宿主机修改文件

3.启动容器

4.容器内数据依旧是同步的

双向同步

在这里插入图片描述

好处:我们以后修改只需要再本地修改,容器内会自动同步。

安装MySQL

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#获取镜像 [root@along ~]# docker pull mysql:5.7 #运行容器,需要做数据挂载! 安装启动mysql需要配置密码 注意! #官方测试 $ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag #自己启动 -d 后台运行 -p 端口映射 -v 卷挂载 可以设置多个 -e 环境配置 --name 容器名 [root@along ~]# docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=228228 --name mysql01 mysql:5.7 #启动成功后,再本地使用sqlyog来连接测试一下 #sqlyog-连接到服务器的3306 -- 3306和容器内的3306映射

假设我们将容器删除,发现我们挂载到本地的数据卷依旧没有丢失
在这里插入图片描述
这就实现了容器数据持久化功能!

具名和匿名挂载

复制代码
1
2
3
4
5
6
7
8
9
10
11
#匿名挂载 -v 容器内路径 [root@along /]# docker run -d -P --name nginx -v /etc/nginx nginx #查看所有的挂载情况 [root@along /]# docker volume ls #具名挂载 -v 卷名:容器内路径 [root@along /]# docker run -d -P --name nginx02 -v nginx-vol:/etc/nginx nginx

-v 只写了容器内路径,没写容器外路径,默认指定了挂载目录。
在这里插入图片描述
-v 卷名:容器内路径
在这里插入图片描述

复制代码
1
2
3
#查看卷 [root@along /]# docker volume inspect nginx-vol

在这里插入图片描述

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

我们通过具名挂载可以方便的找到我们的一个卷,大多数情况在使用的具名挂载

例如:nginx的配置文件挂载到Linux下
在这里插入图片描述

#如何确定是具名挂载还是匿名挂载,还是指定路径挂载?

  • -v 容器内路径 #匿名挂载
  • -v 卷名:容器内路径 #具名挂载
  • -v /宿主机路径::容器内路径 #指定路径挂载!
复制代码
1
2
3
4
5
6
#通过-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

初始DockerFile

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

通过一个脚本生成镜像!

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
#创建一个dockerfile文件(指令全部大写) FROM centos VOLUME ["volume01","volume02"] CMD echo "----end-----" CMD /bin/bash #通过dockerfile构建镜像的命令 #-f 指定路径的dockerfile #-t 生成的目标镜像的信息 [root@along docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile1 -t along/centos:1.0 .

结果:这就是我们自己生成的镜像
在这里插入图片描述

进入我们通过dockerfile创建的镜像,查看:
在这里插入图片描述

我们在容器内的volume01新建一个test.txt文件,然后在本地的挂载路径查看是否同步!

复制代码
1
2
[root@along /]# docker inspect 容器id

在这里插入图片描述

我们到指定的本地路径下查看,是否也同步创建test.txt文件
在这里插入图片描述

数据卷容器

多个mysql同步数据
在这里插入图片描述

复制代码
1
2
3
4
5
#使用自己构建的镜像启动一个容器 [root@along /]# docker run -it --name docker01 along/centos:1.0 #使用同一个镜像启动一个新的容器并挂载到之前启动的容器 [root@along /]# docker run -it --name docker02 --volumes-from docker01 along/centos:1.0

这样两个容器之间可以进行数据共享

复制代码
1
2
3
4
5
[root@kuangshen home]# docker run -d -p 3310:3306 -v /etc/mysq1/conf.d -v /var/1ib/mysq1 -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 [root@kuangshen home]# docker run -d -p 3310:3306 -e MYSQL_RO0T_PASSWORD=123456 --name mysq102 --volumes-form mys q101 mysq1:5.7 #这个时候,可以实现两个容器数据同步!

DockerFile介绍

构建步骤:

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

打开Docker Hub官网,搜索centos,选择一个版本点击进入,会跳转到GitHub:
在这里插入图片描述

很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像官方既然可以制作镜像,那我们也可以!

DockerFile构建过程

基础知识∶

  1. 每个保留关键字(指令)都是必须是大写字母
  2. 执行从上到下顺序执行
  3. #表示注释
  4. 每一个指令都会创建提交一个新的镜像层,并提交!|
    在这里插入图片描述

dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!Docker镜像逐渐成为企业交付的标准,必须要掌握!I
步骤:

  • DockerFile :构建文件,定义了一切的步骤,源代码
  • Dockerlmages :通过DockerFile构建生成的镜像,最终发布和运行的产品!
  • DockerContainer︰容器就是镜像运行起来的服务

DockerFile的指令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2iegRadW-1623069955030)(image-20210521164756161.png)]

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
FROM #基础镜像 MAINTAINER #镜像是谁写的 姓名+邮箱 RUN #镜像构建时需要运行的命令 ADD #添加内容 WORKDIR #镜像的工作目录 VOLUME #挂载的目录 EXPOSE #暴露端口配置(在启动时就不用使用-p指定) CMD #指定容器启动时需要运行的命令,只有最后一个会生效,可被替代 ENTRYPOINT #指定容器启动时要运行的命令,可以追加命令 ONBUILD #当构建一个被继承DockerFile这个时候会运行,ONBUILD的指令 触发指令 COPY #类似ADD,将我们文件拷贝到镜像中 ENV #构建的时候设置环境变量
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#创建一个自己的centos镜像 #1.编写dockefile文件 [root@along dockerfile]# cat mydockerfile-centos FROM centos MAINTAINER along<2238595207@qq.com> 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 #2.构建(坑:新建一个文件夹dockerfile,在该目录下编写dockerfile文件,并且在该目录下执行构建命令。否则系统会提示找不到上下文。) [root@along dockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 .

在这里插入图片描述
在这里插入图片描述

查看:刚刚的镜像已经构建成功
在这里插入图片描述

启动我们自己构建的镜像,发现我们新增的命令都已经安装了:
在这里插入图片描述

测试CMD和ENTRYPOINT
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

自定义Tomcat镜像

  1. 准备镜像文件tomcat压缩包和jdk压缩包,然后新建一个Dockerfile文件

  2. 编写Dockerfile文件,官方命名Dockerfile。build时会自动寻找这个文件,不用-f指定

    复制代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    FROM centos MAINTAINER along<2238595207@qq.com> COPY readme.txt /usr/local/readme.txt ADD jdk-8u251-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-9.0.46.tar.gz /usr/local/ RUN yum -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_251 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.46 ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.46 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-9.0.46/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.46/bin/logs/catalina.out
  3. 构建镜像

    复制代码
    1
    2
    [root@along tomcat]# docker build -t diytomcat .
  4. 启动容器

    复制代码
    1
    2
    [root@along tomcat]# docker run -d -p 9090:8080 --name alongtomcat -v /tomcat/test:/usr/local/apache-tomcat-9.0.46/webapps/test -v /tomcat/tomcatlogs:/usr/local/apache-tomcat-9.0.46/logs diytomcat
  5. 测试访问

    复制代码
    1
    2
    3
    #容器内访问 [root@along ~]# curl localhost:9090
  6. 外部访问,直接输入IP+端口号即可访问,注意需要在阿里云配置安全组开放对应的端口

  7. 因为做了卷挂载,所以我们发布项目只需要在本地的tomcat/test目录下编写即可发布。

发布自己的镜像

  1. 现在Docker Hub官网注册自己的账号

  2. 登录Doker

    复制代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [root@along ~]# docker login --help Usage: 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
  3. 登录成功

在这里插入图片描述

  1. 在服务器上提交自己的镜像

    复制代码
    1
    2
    3
    4
    5
    6
    7
    #注意:如果镜像无法提交,那么就给镜像加一个标签 [root@along ~]# docker tag ceffc54fa152 along1844/helloalong:1.0 [root@along ~]# docker push along1844/helloalong:1.0 # along1844是docker hub的账户名

在这里插入图片描述

Docker网络

理解Docker0

在这里插入图片描述

复制代码
1
2
#问题: docker是如何处理容器网络访问的?
复制代码
1
2
3
4
5
6
7
8
9
10
11
# 查看容器的内部网络地址ip addr,发现容器启动的时候会得到一个eth0@if262 ip地址,docker分配的! [root@along ~]# docker exec -it tomcat-test 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 24: eth0@if25: <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

在这里插入图片描述

复制代码
1
2
# ??? 思考:Linux能否ping通容器内部??

在这里插入图片描述

原理:

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

    再次测试ip addr:
    在这里插入图片描述

    再启动一个容器查看:
    在这里插入图片描述

    复制代码
    1
    2
    3
    #发现Linux下又多了一对网卡,通过启动容器新增的网卡都是一对的! #evth-pair技术 就是一对虚拟设备接口,它们成对出现,一端连着协议,一端彼此相连

    测试:启动两个容器,测试能否在一个容器中ping通另一个容器?

    复制代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #启动tomcat-test [root@along ~]# docker exec -it tomcat-test 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 24: eth0@if25: <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 #启动tomcat-test1 [root@along ~]# docker exec -it tomcat-test1 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 26: eth0@if27: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever # 进入tomcat-test [root@along ~]# docker exec -it tomcat-test /bin/bash #tomcat-test 中ping tomcat-test1 root@0f64f7f99b2f:/usr/local/tomcat# ping 172.17.0.4 PING 172.17.0.4 (172.17.0.4) 56(84) bytes of data. 64 bytes from 172.17.0.4: icmp_seq=1 ttl=64 time=0.124 ms 64 bytes from 172.17.0.4: icmp_seq=2 ttl=64 time=0.081 ms 64 bytes from 172.17.0.4: icmp_seq=3 ttl=64 time=0.083 ms 64 bytes from 172.17.0.4: icmp_seq=4 ttl=64 time=0.077 ms 64 bytes from 172.17.0.4: icmp_seq=5 ttl=64 time=0.078 ms ^C --- 172.17.0.4 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 86ms rtt min/avg/max/mdev = 0.077/0.088/0.124/0.020 ms

在这里插入图片描述

ok,可以发现在tomcat-test容器中可以ping通tomcat-test1容器

结论:容器与容器之间可以相互ping通

原因:处于docker0的同一路由下,即在同一个网段,172.17.0.1?但是实际原理并不是这样?

实际上是这样的:
在这里插入图片描述

结论:tomcat01和tomcat02是公用的一个路由器,docker0。
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用IP
在这里插入图片描述

Docker使用的是Linux的桥接,宿主机中是一个Docker容器的网桥docker0

只要容器删除,对应的网桥对也会删除。
在这里插入图片描述

–link

在这里插入图片描述

测试:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#启动tomcat01 [root@along ~]# docker run -it -d -P --name tomcat01 tomcat f4a76f569523d08eff05797c2d293320dd0759d9a27345277858f03885e7c500 #启动tomcat02 [root@along ~]# docker run -it -d -P --name tomcat02 tomcat c8d7b647f8580c3f06100543ce75b208c3de6ef11e3efbf99ae1e7bf0cc503ab #通过容器名 tomcat01 ping 不通 tomcat02 [root@along ~]# docker exec -it tomcat01 ping tomcat02 ping: tomcat02: Name or service not known #启动tomcat03 --link tomcat02 [root@along ~]# docker run -it -d -P --name tomcat03 --link tomcat02 tomcat 13a297ffef72e8f9ee85f92795513501de64a648d10b39dbd35c639112680d73 #再次测试 tomcat03 可以ping 通tomcat02 [root@along ~]# docker exec -it tomcat03 ping tomcat02 PING tomcat02 (172.17.0.4) 56(84) bytes of data. 64 bytes from tomcat02 (172.17.0.4): icmp_seq=1 ttl=64 time=0.119 ms 64 bytes from tomcat02 (172.17.0.4): icmp_seq=2 ttl=64 time=0.077 ms 64 bytes from tomcat02 (172.17.0.4): icmp_seq=3 ttl=64 time=0.081 ms ^C --- tomcat02 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 82ms rtt min/avg/max/mdev = 0.077/0.092/0.119/0.020 ms #反向ping 不能ping通 未配置 [root@along ~]# docker exec -it tomcat02 ping tomcat03 ping: tomcat03: Name or service not known
复制代码
1
2
[root@along ~]# docker network inspect 8984975b83a0

在这里插入图片描述

复制代码
1
2
# 进入tomcat03容器查看/etc/hosts文件[root@along ~]# docker exec -it tomcat03 cat /etc/hosts

可以发现tomcat03的hosts文件中配置了tomcat02的ip映射,所以可以ping通
在这里插入图片描述

复制代码
1
2
# 对比:查看tomcat02的hosts文件中没有配置tomcat03的ip映射,所以tomcat02无法ping通tomcat03

–link 单向绑定
在这里插入图片描述

自定义网络

查看所有doker网络
在这里插入图片描述

网络模式

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

none:不配置网络

host:和宿主机共享网络

container:容器网络连通!(局限大,使用较少)

测试

复制代码
1
2
3
4
5
# 之前我们直接启动容器 默认加了--net bridge参数 这个就是docker0 docker run -d -P --name tomcat01 tomcat docker run -d -P --name tomcat01 --net bridge tomcat #docker0 默认域名不能访问
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
# 我们可以自定义一个网络 --driver bridge #桥接模式 --subnet 192.168.0.0/24 #子网掩码 --gateway 192.168.0.1 #网关 [root@along ~]# docker network create --driver bridge --subnet 192.168.0.0/24 --gateway 192.168.0.1 mynet ae99296ea19bd29e03f3095764cca05f2f797a7b83d19f216e56b14bfee266d9 [root@along ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 8984975b83a0 bridge bridge local 5954083546bc host host local ae99296ea19b mynet bridge local 59f0a22f01c7 none null local
复制代码
1
2
3
#查看自己创建的网络 [root@along ~]# docker network inspect mynet

在这里插入图片描述

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# 这个时候我们就可以在自定义的网络中启动容器, # 前面说到 --net(network) # 默认是指定的docker0路由,这里换成我们自己的路由即可。 # 在mynet网络下创建两个容器 [root@along ~]# docker run -it -d -P --name tomcat01 --network mynet tomcat 80f44b9f653d975b7459f92ceb10cb660f78fb84d5958728d18b100b17c3613a [root@along ~]# docker run -it -d -P --name tomcat02 --network mynet tomcat 9c16a6d18b9a3252e15df72e4ddc2019a5dfc9531819cc0de9bbab5dd2bb57bf # 再次查看mynet的信息,发现新增了tomct01和tomcat02的相关信息 [root@along ~]# docker network inspect mynet [ { "Name": "mynet", "Id": "ae99296ea19bd29e03f3095764cca05f2f797a7b83d19f216e56b14bfee266d9", "Created": "2021-05-23T11:10:06.462688205+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.0.0/24", "Gateway": "192.168.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "80f44b9f653d975b7459f92ceb10cb660f78fb84d5958728d18b100b17c3613a": { "Name": "tomcat01", "EndpointID": "f7ec4e478f4996abca298d64af4bd61eac6972b321a45e3b34ba6f812f4802ff", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/24", "IPv6Address": "" }, "9c16a6d18b9a3252e15df72e4ddc2019a5dfc9531819cc0de9bbab5dd2bb57bf": { "Name": "tomcat02", "EndpointID": "004d86cdd7120c02916c9e14a138ae751faf628bc5a5a21b4517e07ee9d1e4b8", "MacAddress": "02:42:c0:a8:00:03", "IPv4Address": "192.168.0.3/24", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]

在这里插入图片描述

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 这样两个容器都在自己配置的网络下,无论通过ip还是容器名都可以ping通! # 测试 [root@along ~]# 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.106 ms 64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.089 ms 64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.077 ms 64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=4 ttl=64 time=0.083 ms ^C --- tomcat02 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 76ms rtt min/avg/max/mdev = 0.077/0.088/0.106/0.015 ms [root@along ~]# docker exec -it tomcat02 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.068 ms 64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.078 ms 64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.083 ms ^C --- tomcat01 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 29ms rtt min/avg/max/mdev = 0.068/0.076/0.083/0.009 ms [root@along ~]# docker exec -it tomcat02 ping 192.168.0.2 PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data. 64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=4.28 ms 64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.089 ms 64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=0.081 ms ^C --- 192.168.0.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 40ms rtt min/avg/max/mdev = 0.081/1.484/4.283/1.979 ms [root@along ~]# 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.097 ms 64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.078 ms 64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.086 ms ^C --- 192.168.0.3 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 31ms rtt min/avg/max/mdev = 0.078/0.087/0.097/0.007 ms
复制代码
1
2
# 思考 我们通常搭建集群时,如redis,mysql集群,我们会把redis集群和mysql集群分别部署在不同的网段下,保证集群的安全性,docker如何实现?

网络连通

在这里插入图片描述

**问题:**在我们自定义的网络mynet下有两个容器tomcat-net-01,tomcat-net-02,在系统默认的docker0网络下有两个容器tomcat-01,tomcat-02,tomcat-01/02想直接ping通tomcat-net-01/02是不现实的,只能让tomcat-01先连接到mynet,然后再ping tomcat-net-01/02
在这里插入图片描述
在这里插入图片描述

测试

复制代码
1
2
3
4
5
6
#把 tomcat-01 连接到 mynet [root@along ~]# docker network connect mynet tomcat-01 # 再查看mynet中的信息, 发现多了一个容器tomcat-01 , # 并且分配了该网段下的ip [root@along ~]# docker network inspect mynet

在这里插入图片描述

复制代码
1
2
3
4
5
# 这样tomcat-01也被加到mynet网段下了, # 那么毫无疑问,现在tomcat01是可以ping通tomcat-01的 # 说明:这样tomcat-01就有两个ip,mynet和docker0各有一个ip # 理解:类似于阿里云服务,一个公网ip,一个私网ip

在这里插入图片描述

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

实战:部署Redis集群

在这里插入图片描述

复制代码
1
2
3
4
5
# 先创建一个redis的网段 [root@along ~]# docker network create redis --subnet 172.38.0.0/16 # 查看该网段的信息 [root@along ~]# docker network inspect redis

在这里插入图片描述

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 编写shell脚本来自动编辑redis-cli配置 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 port 6379 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

在这里插入图片描述

启动容器

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[root@along /]# 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.conf [root@along /]# docker 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.conf [root@along /]# docker 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 [root@along /]# docker run -p 6374:6379 -p 16374:16379 --name redis-4 -v /mydata/redis/node-4/data:/data -v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf [root@along /]# docker run -p 6375:6379 -p 16375:16379 --name redis-5 -v /mydata/redis/node-5/data:/data -v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf [root@along /]# docker run -p 6376:6379 -p 16376:16379 --name redis-6 -v /mydata/redis/node-6/data:/data -v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf #也可以通过脚本一次性启动6个容器 docker 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 done

查看启动的redis容器
在这里插入图片描述

复制代码
1
2
3
4
5
6
7
8
9
#进入容器,启动集群 [root@along ~]# 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.1 4:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1 ############ redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.1 4:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

在这里插入图片描述

启动成功:
在这里插入图片描述

复制代码
1
2
3
# 连接到redis客户端 127.0.0.1:6379> CLUSTER INFO

在这里插入图片描述

复制代码
1
2
3
# 查看所有集群所有节点信息 127.0.0.1:6379> CLUSTER NODES

在这里插入图片描述

复制代码
1
2
3
4
5
# 测试 # 设置一个k-v 发现是由redis-3来处理的 # 手动停掉redis-3容器 [root@along ~]# docker stop redis-3

在这里插入图片描述

复制代码
1
2
# 再次get k 看能否得到v

在这里插入图片描述

复制代码
1
2
3
# 可以发现即使手动宕机redis-3,它的从机redis-4也能接替它进行服务 # 查看节点信息 redis-4取代redis-3成为主节点

在这里插入图片描述

复制代码
1
2
# 重新启动redis-3容器,再次进入redis客户端查看集群的节点信息,发现经过重新选举后,redis-4成为主节点,而刚重新启动的redis-3成为了redis-4的从机

在这里插入图片描述

SpringBoot微服务打包Docker镜像

  1. 构建SpringBoot项目

    • 在idea中创建一个springboot项目 helloworld
      在这里插入图片描述
  2. 打包应用

    • package 打成一个jar包
      在这里插入图片描述
  3. 编写Dockerfile

    • 在idea中下载docker插件

    • 编写Dockerfile

在这里插入图片描述

  1. 构建镜像

    • 把jar包和Dockerfile都上传到虚拟机的本地目录

    • 通过build构建
      在这里插入图片描述

      通过构建的镜像运行容器,查看结果:
      在这里插入图片描述

  2. 发布运行

总结

所有笔记时在B站自学kaungshen的Docker视频过程中,自己动手实践整理出来的,目前是对docker有了一个大致的了解。

docker的进阶,如:Docker Compose,Docker Compose,CI/CD之Jenkins等,目前
还在学习中,这里也是非常感谢kuangshen能出这么细致的教程,让我这个小白也能上手。

如果感兴趣的话可以去康康,狂神的Docker进阶篇
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DKBTFTSC-1623069955058)(image-20210522182307861.png)]
在这里插入图片描述

最后

以上就是敏感悟空最近收集整理的关于Docker学习笔记Doker概述Docker安装Docker镜像容器数据卷初始DockerFileDocker网络SpringBoot微服务打包Docker镜像总结的全部内容,更多相关Docker学习笔记Doker概述Docker安装Docker镜像容器数据卷初始DockerFileDocker网络SpringBoot微服务打包Docker镜像总结内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(113)

评论列表共有 0 条评论

立即
投稿
返回
顶部