文章目录
一、Docker 与虚拟机的区别?
传统虚拟机:
- 资源占用多、冗余步骤多、启动慢。
- 虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
Docker:
- 容器化技术,项目代码带上环境配置打包成镜像,上传到镜像仓库,下载镜像即可运行,不再需要复杂环境配置;
- Docker 容器内的应用直接运行在宿主机上,容器是没有内核的,也没有虚拟硬件;
- 每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响。
二、Docker 术语
- 镜像(image)
镜像是一些软件和配置环境的整体打包。 - 容器(container)
容器是一个精简的 Linux 系统,是通过镜像运行起来的实例,镜像运行起来就是容器。 - 仓库(repository)
仓库类似于 Github,我们写好的代码会提交到 Github 上面进行保存和管理,方便在其他人也能下载代码。镜像仓库也是类似的,制作好的镜像,就把它放到镜像仓库,方便其他人直接用镜像部署。
总结:
镜像是存在硬盘上的东西,镜像运行起来,就形成一个容器,容器才是真正跑起来的程序。只不过在 Docker 中,我们可以进入容器,做一些操作,然后再把容器中的改动提交形成一个新的镜像。
三、Docker 安装与卸载
1. 安装
- 环境要求:Linux 内核3.0以上,查看命令如下:
## uname 显示系统信息 -r (kernel-release) 显示操作系统发行编号:
uname -r
## cat(concatenate)命令用于连接文件并打印到标准输出设备上,(查看文件)。
cat /etc/os-release
- 卸载旧版本(无,则忽略)
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://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 更新软件包索引
yum makecache fast
- 安装 docker (docker-ce 为社区版,docker-ee 为企业版)
yum install docker-ce docker-ce-cli containerd.io
注意:版本为 centos 8 时执行上述命令时会报错,说的是 containerd.io >= 1.2.2-3,
解决方法:
(1).降低 docker 版本(不推荐)
(2).更新 containerd.io 版本(不降低 docker 版本)
## 更新 containerd.io 版本
wget https://download.docker.com/linux/centos/7/x86_64/edge/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm #下载安装包
yum install -y containerd.io-1.2.6-3.3.el7.x86_64.rpm #yum安装
yum install docker-ce docker-ce-cli containerd.io #重新安装 docker
- 启动docker
systemctl start docker #启动docker
docker version #查看版本,是否安装成功
2. 卸载
yum remove docker-ce docker-ce-cli containerd.io #卸载依赖
rm -rf /var/lib/docker/ #删除资源 /var/lib/docker docker的默认工作路径
3. 镜像加速(阿里云)
四、Docker 的run流程 和 Docker原理
1. run 流程
2. docker 原理
docker 是一个Client-Server 结构的系统,Docker 的守护进程运行在主机上,通过Socket从客户端访问。DockerServer接收到 Docker-Client 的指令,就会执行命令。
六、Docker 的常用命令
Docker 命令官方文档:https://docs.docker.com/reference/,这里整理一下常用的命令。
1. 帮助命令
docker version # 显示docker的版本信息
docker info # 显示docker的系统信息,包括镜像和容器的数量
docker --help # 帮助命令
2. 镜像命令
## 获取镜像
docker pull [选项] [Docker Registry 地址[:端口号]/] 仓库名[:标签] #下载镜像,
## 案例讲解
[root@localhost ~]# docker pull mysql
Using default tag: latest #如果不写tag,默认就是latest(最新版本)
latest: Pulling from library/mysql
a076a628af6f: 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
## 列出镜像
docker images #查看所有顶层镜像
#解释: REPOSITORY 镜像仓库源 TAG 镜像标签 IMAGE ID 镜像的ID CREATED 镜像创建时间 SIZE 镜像大小
#可选项 -a, --all 列出所有选项 -q, --quiet 只显示镜像的ID
docker images ls -a #查看中间层在内的所有镜象
docker images ls --digests #查看镜象摘要
docker images ls ubuntu:18.04 #查看指定仓库名和标签的镜像
docker images ls -f since=ubuntu:18.04 #查看某个位置之后的镜像
docker images ls -f before=ubuntu:18.04 #查看某个位置之前的镜像
docker iamges ls -q #查询ID
docker system df #查看镜像、容器、数据卷
## 删除镜像
docker image rm [选项] <镜像1>[<镜像2>......] #镜像 可以是短ID 镜像长ID 镜象名 镜象摘要
docker rmi -f #rm:删除,i:image
docker rmi -f $(docker images -q) #删除所有镜像
## 保存现场,慎用
docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]] #保存为镜象,选项:--author "作者名" --message "信息"
docker search #搜索镜像
#可选项 通过搜索来过滤
--filter=STARS=3000 搜索出来的镜像是STARS > 3000
## 提交镜像
docker commit -m="提交的描述信息" -a="作者“ 容器ID 目标镜像名:[TAG]
3. 容器命令
## 新建容器并启动
docker run [可选参数] 镜像 # 新建容器并启动,此时会新键容器
#参数说明
--name="Name" #容器名字 tomcat01 tomcat02 用来区分容器
--d #后台方式运行
-it #使用交互方式运行,进入容器查看内容
-p #指定容器的端口 -p 8080(宿主机):8080(容器)
-P(大写) #随机指定端口
## 实战启动centos
docker run -it centos /bin/bash # /bin/bash centos 中bin目录中bash 命令
exit #容器停止并退出
ctrl + P + Q #容器不停止退出
## 列出所有的运行容器
docker ps #列出所有当前正在运行的容器
#参数说明
-a #列出所有当前正运行的容器+历史运行的容器
-n=[数字] #显示最近创建的容器,数字代表显示多少数量
-q #只显示容器的编号
## 删除容器
docker rm 容器id #删除指定id的容器,注意和 rmi 的区别,不能删除正在运行的容器,如果要强制删除 rm -rf
-f 容器id 或 $(docker ps -aq) # 删除指定的容器或全部删除(包括历史信息)
docker ps -a -q|xargs docker rm # 删除所有的容器
##启动和停止容器的操作
docker start 容器id # 启动容器,根据容器 id 来运行,此时不会新键容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前容器
4. 常用其他命令
## 后台启动容器
docker run -d 镜像名
#注意:docker 容器会使用后台运行,必须要有一个前台进程,docker 发现没有应用,就会自动停止
##查看日志
docker logs #查看日志
-tf #显示全部日志 ,f带上时间
--tail n #显示n条日志
##查看容器中进程信息
docker top 容器id
##查看镜像的元数据
docker inspect 容器id
[
{
"Id": "402b59baed1a6d2c7ef0b5122be2ea0f8f061313ceb4ad960504b02ac3208834",
"Created": "2021-04-07T04:59:00.2247648Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 11098,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-04-07T04:59:00.8697568Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55",
"ResolvConfPath": "/var/lib/docker/containers/402b59baed1a6d2c7ef0b5122be2ea0f8f061313ceb4ad960504b02ac3208834/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/402b59baed1a6d2c7ef0b5122be2ea0f8f061313ceb4ad960504b02ac3208834/hostname",
"HostsPath": "/var/lib/docker/containers/402b59baed1a6d2c7ef0b5122be2ea0f8f061313ceb4ad960504b02ac3208834/hosts",
"LogPath": "/var/lib/docker/containers/402b59baed1a6d2c7ef0b5122be2ea0f8f061313ceb4ad960504b02ac3208834/402b59baed1a6d2c7ef0b5122be2ea0f8f061313ceb4ad960504b02ac3208834-json.log",
"Name": "/great_hofstadter",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "host",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/d4dbf6618ebafc6950487efd5458fd784e3a8423c3b12aca514759861d1daae5-init/diff:/var/lib/docker/overlay2/ae81f222a7e5772d14c3d07719ab760b93d2d6c30288dba30ecd9fd0d4f0ccda/diff",
"MergedDir": "/var/lib/docker/overlay2/d4dbf6618ebafc6950487efd5458fd784e3a8423c3b12aca514759861d1daae5/merged",
"UpperDir": "/var/lib/docker/overlay2/d4dbf6618ebafc6950487efd5458fd784e3a8423c3b12aca514759861d1daae5/diff",
"WorkDir": "/var/lib/docker/overlay2/d4dbf6618ebafc6950487efd5458fd784e3a8423c3b12aca514759861d1daae5/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "402b59baed1a",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": true,
"OpenStdin": true,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"Image": "centos",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.label-schema.build-date": "20201204",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "75c18c71ec50f8665e307be8b8fa172828e721771ea3eed3d36282799c6f8301",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/75c18c71ec50",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "775b1bc8cc03ce57512a1fa8707dbca1117bc5c27803da6af523090e29d9de9c",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "677eb02c7aba4fafca56a7980ccffaa0d47bdd3049c5a1942afc78c75abb690b",
"EndpointID": "775b1bc8cc03ce57512a1fa8707dbca1117bc5c27803da6af523090e29d9de9c",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
]
## 进入当前正在运行的容器,
docker exec -it 容器id bashshell #进入当前容器后开启一个新的终端,可以在里面操作(常用)
docker attach 容器id #进入容器正在执行的终端
## 拷贝容器内文件到宿主机
docker cp 容器id:容器内路径 宿主机目的路径
5. 可视化(平时不用)
- portainer(先用这个)
docker run -d -p 8088:9000 \
--restart=always -V /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
七、Docker 镜像细解
1. 镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有的内容,包括代码、运行库、环境变量和配置文件。
镜像来源:1.从远程仓库下载;2.朋友拷贝给你;3.自己制作一个镜像 DockerFile
2. Docker 镜像加载原理
UnionFs(联合文件系统)
UniosFS(联合文件系统):Union 文件系统(UniionFS)是一层分层,轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。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 就是各种不同的操作系统发行版,比如 Ubuntu,Centos 等等
分层理解
优势:资源共享
查看镜你分层的方式可以通过 docker image inspect 。
理解:所有 Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层上,创建新的镜像层。
八、容器数据卷
1. 什么是容器数据卷
容器的持久化和同步操作,容器间也是可以数据共享。
2.容器数据卷命令
docker volume
create #创建一个volume
inspect [卷名] #查看卷名的详细信息
ls #列表所有卷
prune #移除未使用的数据卷
rm #移除一个或多个数据卷,不能移除被容器使用的数据卷。
3. 使用容器数据卷
## 直接使用命令来挂载 -v
docker run -it -v 主机目录:容器目录
4. 实战:安装MySQL
## 获取镜像
docker pull msyql:5.7
## 官方安装: docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_PASSWORD=123456 --home mysql01 mysql
## 数据持久化
5. 具名挂载 各 匿名挂载
## 匿名挂载 -v只写容器路径
docker run -d -P --name 容器命名 -v 容器内路径
## 具名挂载
docker run -d -P --name 容器命名 -v 卷名:容器内路径
## 如何确定是具名挂载还匿名挂载,还是指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径::容器内路径 #指定路径挂载
## 拓展
# 通过 -v 容器内路径:[ro/rw] 改变读写权限
ro readonly #只读,说明这个路径只能通过宿主机来操作,容器内部无法操作
rw readwrite #读写
# 设置了容器权限,容器对我们的挂载出来的内容就有限定了
docker run -d -P nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P nginx02 -v juming-nignx:/etc/nginx:rw nginx
九、Dockerfile
概念:dockerfile 是用来构建 docker 镜像的构建文件,命令脚本
实战:通过脚本生成镜像,镜象是一层一层的,脚本一个个的命令,每个命令都是一层的
## 1.编写一个dockerfile文件
vi dockerfile01
#dockerfile01文件内容
FORM centos
VOLUME ["volume01","volume02"]
CMD echo "---end---"
CMD /bin/bash
## 2.构建一个镜像
docker build -f dokcerfile02 -t centos2:2.3 .
## 3.docker fun 运行镜像
## 4.docker push 发布镜像(DockerHub 、阿里云镜像他库)
1. Dockerfile 构建过程
基础知识
- 每个保留关键字(指令)都是必须是大写字母
- 执行从上到下顺序执行
- 表示注释
- 每个指令都会创建提交一个新的镜像层,并提交
dockerfile 是面向开发的,我们以后要发布项目,做镜像,就要编写dockfile 文件,这个文件十分简单!
Docker 镜像逐渐成为企业交付的标准,必须掌握!
步骤:开发,部署,运维。。。 缺一不可
DockFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile 构建生成的镜像,最终发布程和运行的产品
Docker:容器就是镜像运行起来提供服务器
2. Dockerfile 指令
FROM #指定基础镜像
MAINTAINER #镜像维护者:姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD #COPY文件,会自动解压。步骤:tomcat镜像,这个tomcat压缩包,添加内容
WORKDIR #镜像的工作目录
VOLUME #挂载的目录
EXPOST #保留端口配置
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定这个容器启动的时候要运行命令,可以追加命令
ONBUILD #当构建一个被继承 DockerFile 这个时候就会运行 ONBUTLD 的指令,触发指令
COPY #类似ADD,将我们文件拷贝到镜像中
ENV #构建的时候设置环镜变量!
3. 实战测试
目标:创建一个自己的centos
##1. 编写Dockerfile的文件
FROM centos
MAINTAINER wang<1558924235@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUM yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "----end-----"
CMD /bin/bash
##2. 通过这个文件构建镜像
docker build -f dockerfile文件路径 -t 镜像名:tag .
4. CMD 和 ENTRYPOINT 区别
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定这个容器启动的时候要运行命令,可以追加命令
容器与容器之间的共之前共享存储
docker run -it --name 容器名 --volumes-from 容器名 镜像名:tag
实战:mysql 实现数据库共享
docker run -d -p 3312:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 mysql
docker run -d -p 3313:3306 -e MYSQL_ROOT_PASSWORD=1234567 --name mysql03 --volumes-from mysql02 mysql
实战:Tomcat 镜像
- 准备镜像文件 tomcat 压缩包,jdk压缩包!
- 编写 dockerfile 文件,官方命名 Dockerfile ,build 会自动寻找这个文件,就不需要 -f 指定了
FROM centos
MAINTAINER wang<1558924235@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-16_linux-aarch64_bin.tar.gz /usr/local/
ADD apache-tomcat-9.0.33.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/lib:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /url/local/apache-tomcat-9.0.22/bin/logs/catalina.out
- 构建镜像
docker build -t diytomcat .
- 启动镜像
- 访问测试
- 发布项目
发布自己的镜像
1.地址 https://hub.docker.com/ 注册自己的帐号!
2.在我们服务器上提交自己的镜像
docker login
-u #用户名
-p #密码
- 提交自己的镜像
docker push
阿里云镜像发布
- 登录阿里云
- 找到容器镜像服务
- 创建命名空间
- 建容器镜像
- 参考阿里云镜像说明
小结
十、Docker 网络
1. 理解 Docker0
[root@localhost build]# ip addr
## lo 本机回环地址
## eth0 内网地址
## docker0 docker生成的地址
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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_U P> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:08:e5:69 brd ff:ff:ff:ff:ff:ff
inet 43.226.145.126/21 brd 43.226.151.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::215:5dff:fe08:e569/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:d0:10:f6:fd brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:d0ff:fe10:f6fd/64 scope link
valid_lft forever preferred_lft forever
三个问题
- docker 是如何处理容器网络访问的
docker run -d -P --name tomcat01 tomcat
#查看容器的内部网络地址 ip addr ,容器会有一个 eth0@if105 ip地址 docker分配的
[root@localhost /]# docker exec -it tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
104: eth0@if105: <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 通 docker 容器内部
[root@localhost /]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.190 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.131 ms
原理:
- 我们每启动一个 docker容器 ,docker 就会给 docker容器 分配一个IP,我们只要安装了 docker,就会有一个网卡 docker0 桥接模式,使用的技术是 evth-pair技术!
#再次测试 ip addr
[root@localhost /]# 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:08:e5:69 brd ff:ff:ff:ff:ff:ff
inet 43.226.145.126/21 brd 43.226.151.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::215:5dff:fe08:e569/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:d0:10:f6:fd brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:d0ff:fe10:f6fd/64 scope link
valid_lft forever preferred_lft forever
105: vethcdd5754@if104: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether f2:5b:6d:12:3f:c1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::f05b:6dff:fe12:3fc1/64 scope link
valid_lft forever preferred_lft forever
我们发现这个容器还来网卡,都是一对对的
evth-pair 就是一对虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连
正因为这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备的
openstac,Docker 容器之间的连接,OVS 的连接,都是使用 evth-pair 技术
所有的容器不指定网络的情况下,都是 docker0 路由的,docker 会给我们的容器分配一个默认的可用IP
2. --link
场景:我们编写一个微服务,database url = ip;,项目不重启,数据库IP换掉了,我们希望可以处理这个问,可以名字来进行访问客户端。
docker exec -it tomcat02 ping tomcat01
>ping: tomcat01: Name or service not know
#如何解决,通过 --link 可以解决网络连通问题
dokcer run -d -P --name tomcat03 --link tomcat02 tomcat
docker exec -it tomcat03 ping tomcat02
>可以ping通
##本质上是hosts配置中增加
3. 自定义网络
- 容器互联
##查看所有 Docker 网络
docker network ls
网络模式
bridge:桥接 docker(默认)
none: 不配置网络
host:和宿主机共享网络
containner:容器网络连通(用的少,局限很大)
- 测试
##我们真接启动命令 --net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 --net bridge tomcat
#docker0特点,默认,域名不能访问,--link 可以打通连接!
# 我们可以自定义一个自己的网络
# --driver bridge
# --subnet 192.168.0.0/16
# --getway 192.168.0.1
docker network create --driver bridge --subnet 192.168.0.0/16 --getway 192.168.0.1 mynet
## 查看所有网络
docker network ls
## 查看自己创建的网络
docker network inspect mynet
## 创建容器,连接自己的网络
docker run -d -P --name tomcat-net-01 --net mynet tomcat
docker run -d -P --name tomcat-net-02 --net mynet tomcat
## 查看自己的网络
docker network inpect mynet
## ping
docker exec -it tomcat-net-01 ping 192.168.0.3
== docker exec -it tomcat-net-01 ping tomcat-net-02 ##现在不使用 --link 也可以 ping 名字
我们自定义的网络,docker 都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络。
好处:
redis - 不同的集群使用不同的网络,保证集群是安全和健康的
mysql - 不同的集群使用不同的网络,保证集群是安全和健康的
4. 网络连通
docker network conncet [OPTIONS] NETWORK CONTAINER
测试打通 tomcat01 mynet
docker network connect mynet tomcat01
连能之后就是将 tomcat01 放到了 mynet 网络下
一个容器两个ip地址
阿里云服务: 公网ip 私网ip
实站:部署Redis集群
# 创建网卡
docker network create redis --subnet 172.38.0.0/16
# 通过脚本创建六个 redis 配置
for port in $(seq 1 6);\
do \
mkdir -p /mydata/redis/node-$(port)/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
##通过脚本起动6个redis
docker run -p 637${port}:6379 -p1637${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 -alipine3.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
## docker 搭建redis 集群完成
我们使用了docker 之后,所有的技术都会慢慢的变提简单起来!
SpringBoot 微服务打包 Docker 镜像
- 构建 springboot 项目
- 打包应用
- 编写dockerfile
- 构建镜像
- 发布运行
待续
Docker Compose
Docker Swarm
CI/CD 之 Jenkins