文章目录
- 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
2yum install -y yum-utils
设置镜像仓库
这里需要注意,默认的是使用的国外的镜像源,特别慢,推荐使用阿里或者清华的镜像源。
1
2
3
4yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新yum软件包索引
1
2yum makecache fast
安装docker相关的依赖
这里我们选的是docker-ce 社区版
1
2
3yum install docker-ce docker-ce-cli containerd.io
启动docker
1
2systemctl start docker测试验证helloworld
测试
1
2docker run hello-world
帮助命令
万能命令
1
2docker --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
3docker 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
7docker 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介绍
构建步骤:
- 编写一个dockerfile文件
- docker build构建成为一个镜像
- docker run运行镜像
- docker push 发布镜像(DockerHub、阿里云镜像仓库!)
打开Docker Hub官网,搜索centos,选择一个版本点击进入,会跳转到GitHub:
很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像官方既然可以制作镜像,那我们也可以!
DockerFile构建过程
基础知识∶
- 每个保留关键字(指令)都是必须是大写字母
- 执行从上到下顺序执行
- #表示注释
- 每一个指令都会创建提交一个新的镜像层,并提交!|
dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!Docker镜像逐渐成为企业交付的标准,必须要掌握!I
步骤:
- DockerFile :构建文件,定义了一切的步骤,源代码
- Dockerlmages :通过DockerFile构建生成的镜像,最终发布和运行的产品!
- DockerContainer︰容器就是镜像运行起来的服务
DockerFile的指令
1
2
3
4
5
6
7
8
9
10
11
12
13FROM #基础镜像 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镜像
-
准备镜像文件tomcat压缩包和jdk压缩包,然后新建一个Dockerfile文件
-
编写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
23FROM 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
-
构建镜像
复制代码1
2[root@along tomcat]# docker build -t diytomcat .
-
启动容器
复制代码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
-
测试访问
复制代码1
2
3#容器内访问 [root@along ~]# curl localhost:9090
-
外部访问,直接输入IP+端口号即可访问,注意需要在阿里云配置安全组开放对应的端口
-
因为做了卷挂载,所以我们发布项目只需要在本地的tomcat/test目录下编写即可发布。
发布自己的镜像
-
现在Docker Hub官网注册自己的账号
-
登录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
-
登录成功
-
在服务器上提交自己的镜像
复制代码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通容器内部??
原理:
-
我们每启动一个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镜像
-
构建SpringBoot项目
- 在idea中创建一个springboot项目 helloworld
- 在idea中创建一个springboot项目 helloworld
-
打包应用
- package 打成一个jar包
- package 打成一个jar包
-
编写Dockerfile
-
在idea中下载docker插件
-
编写Dockerfile
-
-
构建镜像
-
把jar包和Dockerfile都上传到虚拟机的本地目录
-
通过build构建
通过构建的镜像运行容器,查看结果:
-
-
发布运行
总结
所有笔记时在B站自学kaungshen的Docker视频过程中,自己动手实践整理出来的,目前是对docker有了一个大致的了解。
docker的进阶,如:Docker Compose,Docker Compose,CI/CD之Jenkins等,目前
还在学习中,这里也是非常感谢kuangshen能出这么细致的教程,让我这个小白也能上手。
如果感兴趣的话可以去康康,狂神的Docker进阶篇
最后
以上就是敏感悟空最近收集整理的关于Docker学习笔记Doker概述Docker安装Docker镜像容器数据卷初始DockerFileDocker网络SpringBoot微服务打包Docker镜像总结的全部内容,更多相关Docker学习笔记Doker概述Docker安装Docker镜像容器数据卷初始DockerFileDocker网络SpringBoot微服务打包Docker镜像总结内容请搜索靠谱客的其他文章。
发表评论 取消回复