Docker的学习(中)

Docker的学习(中),第1张

Docker的学习(中) Docker的学习(中)

此教程基于【编程不良人】2021年最新Docker容器技术&Docker-Compose实战教程,哔哩哔哩链接:https://www.bilibili.com/video/BV1ZT4y1K75K?p=1

官方文档地址:https://docs.docker.com/get-started/

中文文档地址:https://vuepress.mirror.docker-practice.com/

11.Docker的镜像原理

通过使用联合文件系统(UnionFS),使用资源共享,当我们本地仓库的镜像越来越多时,发现下载会越来越快,因为很多下载所需要的文件我们本地都已经存在了

12.Docker中的网络通信机制以及网桥的使用

当 Docker 启动时,会自动在主机上创建一个 docker0 虚拟网桥(现在改为了bridge网桥),实际上是 Linux 的一个 bridge,可以理解为一个软件交换机。它会在挂载到它的网口之间进行转发。

同时,Docker 随机分配一个本地未占用的私有网段(在 RFC1918 (opens new window)中定义)中的一个地址给 docker0 接口。比如典型的 172.17.42.1,掩码为 255.255.0.0。此后启动的容器内的网口也会自动分配一个同一网段(172.17.0.0/16)的地址。

当创建一个 Docker 容器的时候,容器会创建了一对 veth pair 接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0(网卡,在CenttOS7和CentOS8中改为了ens33);另一端在本地并被挂载到 docker0 网桥(现在改为了bridge网桥),名称以 veth 开头(例如 vethAQI2QT)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。

中文文档地址:https://vuepress.mirror.docker-practice.com/advanced_network/

如我们运行一个tomcat容器,并进入tomcat容器查看内部细节

我们发现network默认就挂载在bridge网桥上,且桥上的网关地址为172.17.0.1,ip地址为172.17.0.2

我们继续运行一个tomcat容器,

因为他们都在一个网桥上(172.17.0.1),又在同一个网段,所以可以互相访问,在03上ping 02,在ping的时候,eth0会转向给VET1,而VET1和VET2在一个网桥上,VET2就能接收到,而VET2就能装给02,所以就能ping通02

我们通过172.17.0.3去访问172.17.0.2,我们进入ip为172.17.0.3的容器,并输入curl http:172.17.0.2 进行抓取数据,

发现数据已经抓取过来

疑问:我们运行的所有容器都在一个默认的网桥(bridge)上,会存在什么问题?

如果某些容器频繁与其他容器发送数据的交互,会对某些未产生交互的容器的带宽产生影响,因为他们都在一个网桥上。所以,我们在实际的应用中,每一个应用都应该拥有自己的一个网桥。

网桥的使用

查看所存在的网桥:docker network ls

查看网桥的所有命令 docker network 相当于 docker network --help

创建网桥:docker create 网桥名字 或 docker create -d 网桥的类型(一般都为bridge)网桥名称

之后查看运行的tomcat容器细节(docker inspect 容器名字|容器id),发现网桥、网关、网段对比默认的bridge网桥都发送了变化

同时会将容器的名字与容器ip地址进行映射,就相当于给ip取了一个别名,为容器的名字就是ip,所以我们与其他容器发生交互时还可以用容器名字进行取代ip的形式,因为我们的ip地址是会变化的(ip地址也可以固定),如我们输入 curl tomcat01(容器名字)表示抓取tomcat01容器的内容

一旦我们启动容器时指定了网桥之后,就可以在任何这个网桥关联的容器中使用容器的名字(或ip地址)与其他容器进行交互

我们运行一个容器时如果指定的网桥不存在,则网桥不能自动创建,会报错,必须先创建网桥

查看网桥详细:docker inspect 网桥名字

docker inspect不仅能看容器的信息,我们还可以查看网桥的信息,如我们输入 docker inspect 网桥名字,他会展示网桥的信息,其中就包括了该网桥上所运行的容器

删除网桥: docker network rm 网桥名字

13.Docker中的数据卷

我们前面已经了解到自定义数据卷目录和自动创建数据卷目录的基本使用,我们知道如果我们创建的是自定义数据卷目录,则对宿主机目录内容的变动会直接影响到容器中对应目录,同时容器中对应目录的变动也会影响我们宿主机。我们想要宿主机的变动影响容器,但并不希望容器的变动会影响到我们宿主机。我们可以在映射时多加 :ro ,表示容器只能读,不能写

扩展:镜像是只读的,容器才可写

查看所有的数据卷:docker volume ls

查看某个数据卷的细节:docker volume inspect 卷名

创建数据卷: docker volume create 卷名

当启动容器是创建的数据卷不存在时,docker会自动创建

删除没有使用的数据卷: docker volume

删除指定的数据卷: docker volume rm 卷名

14.Docker的核心架构

15.Docker安装mysql服务

1.启动mysql,指定mysql名字,端口映射,指定数据卷,指定环境变量(必须),后台运行

docker run --name mysql -p 3306:3306 -v mysqldata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:tag

其中-e表示指定环境变量,MYSQL_ROOT_PASSWORD即mysql镜像内部定义的一个环境变量,表示给root用户指定密码,-d表示后台运行,–name表示给运行的容器起名字,-p表示端口映射,-v表示指定数据卷,通过dockerhub中mysql的使用我们可以知道,mysql镜像默认把数据放在/var/lib/mysql中

注意:如果我们不指定数据卷的话,当我们把mysql容器删除之后,我们mysql容器中的数据就会全部消失,所以,我们必须指定数据卷,这样即使我们直接把容器删除,其mysql容器的数据还是会存在在我们的宿主机中,我们只需要指定这个数据卷再启动一个mysql容器就可以恢复全部的数据,如

之后,我们使用navicat连接启动的这个数据库并在其中新建一个数据库test,数据库中新建一张表t_user,

我们将mysql容器停止并删除所有的容器(运行的和非运行的),也可以删除指定的容器: docker rm -f 容器名称 或 容器id

之后我们在重新启动mysql容器,并指定mysqldata数据卷,此时已经有mysqldata这个数据卷,所以docker会将mysqldata数据卷映射的宿主机目录中的所有文件加载入启动的mysql容器,即加载入/var/lib/mysql ,再次使用navicat连接启动的容器,发现还是存在test这个数据库

注意: 如果是本地中没有mysqldata数据卷,则会默认将启动的mysql容器中的数据复制到新建的mysqldata数据卷所对应的宿主机目录中

1.启动mysql,指定mysql名字,端口映射,指定数据卷,指定环境变量(必须),后台运行,以配置文件启动

通过dockerhub中mysql的使用我们可以知道,

我们运行tomcat容器并进入到其配置文件目录,

之后我们可以使用自动创建数据卷模式进行映射这个配置文件目录,之后我们对这个数据卷所映射的宿主机目录的更改可以直接影响到mysql容器

此处需要注意的是我们启动的两个mysql服务的数据不能映射相同的数据卷,不然会报错(通过docker log -f 容器名称|容器id),所以需要修改mysqldata数据卷为其他的数据卷

16.Docker安装tomcat服务

需要注意的是如果我们修改了tomcat配置文件的端口,虽然容器已经改了,但是我们一刚开始运行的容器的命令指定的端口映射并不能更改,所以建议我们重启容器

17.Docker安装redis服务

开启redis持久化,一旦开启持久化之后,持久化生成的aof文件会被放入容器的/data目录

docker run --name reids -p 6379:6379 -d  -v redisdata:/data redis:5.0.10 redis-server --appendonly yes 

我们启动redis容器并开启持久化,

之后使用RDM(redis管理工具)进行连接linux,之后添加一条简单的数据

之后进入redisdata数据卷映射的宿主机目录查看持久化文件appendonly.aof,发现已经同步了我们刚刚添加的数据

以配置文件启动redis

由于redis镜像内部并不含有redis配置文件,他的配置都在redis-server指令中,所以需要我们去redis官网寻找redis的配置文件

我们前往redis官网,https://redis.io/

之后寻找对应的redis版本,由于此处我们使用的为redis5.0.10版本,所以我们去找reids5的版本进行下载(大版本号对应上就行),

下载之后,提取redis.conf配置文件并上传到我们的linux系统

我们查看dockerhub中docker对redis的介绍,

所以我们输入

docker run --name reids -p 6379:6379 -d  -v /myredis/conf:/usr/local/etc/redis redis:5.0.10 redis-server /usr/local/etc/redis/redis.conf 

进行启动redis容器,但是我们使用RDM进行连接redis,发现并不能连接成功

这是因为redis的配置文件中bind为127.0.0.1,即只可以本地进行访问,所以我们需要修改redis的配置文件,我们打开redis.conf文件进行更改

之后重启容器,再次访问,发现已经可以连接上redis

18.Docker安装ElasticSearch服务

es中的持久化方案

elasticsearch容器的所有数据都在 /usr/share/elasticsearch/data下,配置信息在 /usr/share/elasticsearch/config下,插件在/usr/share/elasticsearch/plugins目录下,所以我们输入

docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -v esdata:/usr/share/elasticsearch/data -v esconfig: /usr/share/elasticsearch/config -v esplugins:/usr/share/elasticsearch/plugins elasticsearch:6.8.0 

进行启动elasticsearch(也可以直接将/usr/share/elasticsearch直接进行映射,这样就不用写这么多个数据卷)

我们可以将ik分词器放到esplugins数据卷下,首先进入到esplugins数据卷所对应的宿主机目录下,之后生成ik分词器,并创建目录ik,将ik分词器移动到ik目录下

之后使用unzip命令进行解压ik分词器,之后可以将原先的ik分词器(zip格式的)删除掉,输入 rm -rf 文件名 即可

之后重启elasticsearch容器(docker restart 容器名称|容器id),并输入docker logs -f 容器名称|容器id查看elasticsearch的实时日志

通过浏览器访问发现已经成功启动elasticsearch

ES的9200端口和9300端口

elasticsearch的

​ 9200端口是ES节点与外部通讯使用的端口。它是http协议的RESTful接口(各种CRUD *** 作都是走的该端口,如查询:http://localhost:9200/user/_search)。
​ 9300端口是ES节点之间通讯使用的端口。它是tcp通讯端口,集群间和TCPclient都走的它。(java程序中使用ES时,在配置文件中要配置该端口)

Docker安装kibana服务并连接到ES

在安装kibana服务时需要注意,kibana的版本需要与安装的elasticsearch服务版本严格保持一致

1.启动kibana时连接到elasticsearch:

docker run -d --name kibana -p 5601:5601 -e ELASTICSEARCH_URL=你的linux系统ip地址:9200 kibana:6.8.0

之后进入kibana管理界面,编写相关测试代码,发现能 *** 作我们的elasticsearch,则证明我们连接elasticsearch服务成功

2.kibana加载配置文件启动

docker run -d --name kibana -p 5601:5601 -v kibanaconfig:/usr/share/kibana/config kibana:6.8.0

此处我们使用自动创建数据卷的方式,表示将elasticsearch中的/usr/share/kibana/config下的配置文件复制到kibanaconfig数据卷中

之后我们可以在配置文件中编辑相关信息,如配置连接的elasticsearch服务的地址

之后重启kibana容器(docker restart 容器名字|容器id)即可。

19.Dockerfile简介

DockerFile构建镜像原理

首先我们在某个目录进行构建镜像的 *** 作,docker会将dockerfile所在的目录作为上下文目录,同时将dockerfile文件一起发送给docker server,docker会根据dockerfile文件的命令依次执行,每执行一个命令都会生成一个镜像层(每一个镜像层都会放在docker的缓存区中,当我们之后再次构建镜像时,如果dockerfile中前面的命令并没有改变,则docker可以直接使用缓存区中的镜像缓存进行构建,省去了再次构建的时间),最终全部执行完毕生成一个最终的镜像。如果我们不需要这个缓存,可以在构建的时候加上命令 --no-cache 表示不用docker的缓存。

Dockerfile的保留命令

20.Dockerfile的语法(一)

FROM命令

我们首先在一个目录中创建一个Dockerfile,输入vim Dockerfile(也可以取其他的名字),之后在Dockerfile中简单书写一句代码:FROM centos:7 ,表示我的这个镜像基于centos7镜像进行构建,之后构建镜像,我们输入 docker bulid -t mycentos7:01 . ,表示我们基于当前这个目录作为上下文目录进行构建镜像,mycentos7:01 表示构建的镜像名称和版本, .表示当前目录,

我们执行构建命令,发现构建镜像很慢,这是因为docker会将我们这个目录的所有文件都作为镜像构建所需要的依赖,他会将这个目录下的所有文件进行构建,所以我们最好将dockerfile放在一个独立的目录(移动命令:mv 要移动的文件 移动到的文件目录)

之后我们将dockerfile移动到一个独立的目录(移动命令:mv 要移动的文件 移动到的文件目录),并执行构建命令,之后运行我们构建的镜像,发现我们构建的镜像一启动都结束了,这是因为我们运行的是一个centos系统,它在运行后发现系统并没有任何服务在运行就自动结束了

我们可以在运行容器的时候就进行centos7系统的命令界面,这样centos7容器就不会一运行就自动停止了(当我们退出命令终端的时候他也会被关闭,即输入exit),我们输入docker run -it centos:7 。在原始的centos7系统中,一些命令是没有的(如vim命令),需要我们自行安装。我们输入 yum install -y vim 即可安装vim命令

RUN命令

但是我们想要在构建镜像的时候就安装一些常用的命令,我们可以书写dockerfile文件,我们输入 RUN yum install -y vim 或 RUN ["yum","install","-y ","vim"] ,之后重新构建镜像,之后运行镜像即可使用vim命令

EXPOSE命令

之后我们通过dockerfiml构建镜像还需要对外暴露接口,不然是无法通过-p命令进行端口的映射的

我们再次构建应用,发现并没有了下载vim的过程,这是因为docker的镜像缓存的原因(需要前面的指令并未发生改变)

WORKDIR命令

我们启动centos7容器并进入终端交互模式时发现我们默认进入的是 / (根目录),我们可以修改默认进入的目录,我们继续书写dockerfile文件,workdir可以书写多个,其中如果我们书写了相对路径,则与之前的路径相对

进入的目录为/data/bb

COPY命令

首先我们在dockerfile所在的目录输入 touch aa.txt 新建一个aa.txt文件,之后vim aa.txt ,书写一句话i love docker ,之后继续书写dockerfile,

注意:aa.txt并不一定要在dockerfile所在的目录,也可以是其他的目录,但是为了方便,我们一般放在与dockerfile相同的目录下,因为docker在构建镜像时会将dockerfile所在的目录作为上下文目录,将这个目录下的所有文件作为构建镜像的依赖

重新构建镜像,

ADD命令

首先我们在dockerfile所在的目录输入 touch bb.txt 新建一个bb.txt文件,之后echo "i am bb.txt" >> bb.txt 表示将i am bb.txt这句话输出到bb.txt中,之后继续书写dockerfile,

之后启动容器,发现/data/bb目录下存在了bb.txt,同时add命令也可以使用url的方式,即我们可以使用url的方式指定文件的位置。以tomcat为例,首先我们复制tomcat的下载链接地址

之后在dockerfile中粘贴下载链接

重新构建镜像,发现已经把tomcat下载下来。

之后启动容器

但是并没有帮助我们解压tomcat,我们可以使用 wget url 的方式将资源下载到本地,需安装wget(yum install wget)

打开dockerfile,继续书写代码

之后重新构建镜像,启动容器,发现已经帮我们解压了

之后我们继续编写dockerfile文件,将解压的tomcat移动到tomcat目录下并进入tomcat目录

重新构建并启动容器,结果如下

VOLUME命令

定义容器时可以挂载到宿主机的目录

21.Dockerfile的语法(二) ENV命令

用来为构建镜像设置环境变量,这个值将出现在构建阶段中所有后续指令的环境中,如我们在启动mysql时的命令:

docker run --name mysql -p 3306:3306 -v mysqldata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:tag

MYSQL_ROOT_PASSWORD即mysql镜像内部定义的一个环境变量,表示给root用户指定密码,

ENTRYPOINT命令

用于设置容器启动后的第一个命令,这对一个容器来说往往是固定的,ENTRYPOINT指令可以写多个

如我们想要监听centos系统的BUILDING.TXT日志文件的增长,打开dockerfile文件书写代码,ENTRYPOINT tail -f BUILDING.txt

之后构建镜像,启动容器,因为这个 *** 作会一直运行,即centos7容器不会一启动就结束,所以我们不用再启动容器的时候就进入命令终端,我们直接运行这个镜像即可

CMD指令

用于设置容器启动的第一个命令的默认参数,这对一个容器来说可以是变化的,CMD指令可以写多个,但是以最后一个为准,其他的会被覆盖掉,所以CMD指令一般只写一个,而ENTRYPOINT指令可以写多个

我们继续书写dockerfile,写上 CMD ls /data/bb/tomcat 表示展示/data/bb/tomcat目录下的文件

之后构建应用并启动容器,发现我们可以覆盖掉dockerfile文件中的CMD命令

CMD和ENTRYPOINT指令的区别

ENTRYPOINT不能覆盖指令,如我们修改dockerfile的内容

构建镜像,启动容器,发现我们并不能像CMD指令一样对指令进行覆盖,而是需要通过 --entrypoint=ls ,之后再指定要查看的目录进行查看

所以我们一般用ENTRYPOINT来写固定的命令,用CMD来进行传参,同时他们可以一起配合使用。

构建镜像,启动容器,

所以,我们如果想要运行我们的项目,就可以这样进行配置,我们默认运行ems.jar,如果你想运行你的项目,直接在启动容器时加上你的项目名即可

22.Dockerfile构建springboot应用

运行容器后,浏览器访问项目,

但是这种方法对于我们的项目有多个依赖(如redis、elasticsearch)的时候,我们还需要对每一个依赖服务进行依次启动,我们使用docker compose可以解决这些问题。

23.Ideal连接docker插件、远程SFTP 连接docker插件

首先打开ideal,进入设置界面,

安装docker插件后重启ideal,之后新建dockerfile文件即可

连接远程SFTP

在ideal中点击tools,

继续

继续

之后会把我们所有的文件读取过来,

我们也可以指定只读某个目录

之后就可以在ideal中编辑文件了

喜欢请关注我

至此,我们的Docker的学习(中)就讲解完毕了,下篇我们将讲解Docker Compose以及Docker可视化工具Portainer的使用。喜欢我的话可以关注我的微信公众号 我爱学习呀嘻嘻 ,不定期分享各类资源哦。

Docker的学习(上)

Docker的学习(下)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5712379.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存