比较docker和虚拟机的区别,可以从以下几个方面来阐述:
**隔离级别不同。**虚拟机提供硬件级别资源隔离(操作系统),docker容器通过容器技术实现应用层级别的隔离(进程)。
**资源占用不同。**虚拟机运行完整操作系统,需要占用较多CPU、内存、磁盘等物理资源。而docker容器共享宿主机内核,占用更少资源。
**启动速度不同。**虚拟机启动过程需要启动完整操作系统,通常需要数分钟。而docker容器启动只需启动应用,可以实现秒级启动。
**系统支持不同。**虚拟机可以运行不同内核的操作系统,docker容器与内核版本相关。
**移植性不同。**虚拟机可以直接在多种虚拟化平台上迁移。而docker容器移植性较差,与环境相关性更大。
**管理维护不同。**docker基于容器,更轻量级,维护更方便。虚拟机管理和移植复杂度较高。
总体来说,两者有不同的使用场景。如果需要完全隔离而且方便移植,虚拟机更合适。如果要快速部署应用环境,则docker容器更为适合。
在容器化部署中,选择Docker而不是虚拟机的主要原因有以下几点:
**Docker更轻量级,资源占用少。**相比虚拟机模拟整套硬件,Docker能节省大量CPU、内存、存储资源。
**Docker启动速度更快。**基于容器实现秒级启动,而虚拟机启动整个操作系统需要几分钟。
**Docker部署灵活,支持水平扩展。**可以通过docker-compose批量管理容器,实现快速扩容。
**Docker支持微服务与DevOps。**组件化的容器适合微服务架构,可以快速持续交付和部署。
**Docker镜像可移植性好。**将应用环境打包到镜像中,可以一致迁移到不同环境中。
**Docker易于维护更新。**用新版本镜像替换就可以实现应用更新,简单快速。
所以简单来说,Docker对资源的高效利用率,以及快速部署和持续交付的优势,使其更适合像Web应用、微服务和DevOps流水线这样的场景。
有以下几类场景更适合选择虚拟机而不是Docker进行部署:
- **需要完整操作系统隔离的场景。**虚拟机可以提供硬件级别的强隔离,比如多租户场景下隔离客户工作负载。
- **需要跨平台和混合云部署的场景。**虚拟机镜像可以直接在公有云、私有云和混合云环境中运行。
- **对安全性要求极高的场景。**虚拟机通过硬件虚拟化隔离提供更强的安全防护。
- **需要不同操作系统发行版和内核的场景。**虚拟机可以运行不同的guest OS,Docker容器与主机OS内核绑定。
- **对稳定性和一致性要求高的传统应用。**这类应用移植到Docker可能需要重新设计和测试。
- **资源充足而运维能力有限的场景。**虚拟机管理和运维更简单,无需精通容器技术。
所以简单来说,虚拟机对硬件虚拟化和跨平台强隔离、安全性和稳定性要求高的场合更为适合。Docker更适合云原生应用和微服务架构。
虚拟机和Docker在性能和资源利用方面主要有以下几点差异:
**存储空间利用率差异大。**虚拟机镜像包含整个操作系统,一般几GB大小。Docker镜像只包含运行应用所需库和配置,通常MB到几百MB。
**内存占用差异大。**虚拟机最小配置也需要分配1-2GB内存。Docker容器可以只占用应用所需内存,可以控制在MB级别。
**CPU利用率差异。**虚拟机单核心利用不高,需要模拟硬件。Docker直接利用宿主机CPU,可以实现更高的核心使用率。
**启动时间差异。**虚拟机启动需要几分钟。Docker容器启动可以秒级实现。
**扩容灵活性差异。**虚拟机扩容受硬件资源限制。Docker基于容器,可以轻松实现快速弹性扩容。
**资源分配差异。**虚拟机资源预分配并且不灵活。Docker可以根据实时需求调度资源。
总体上,Docker的轻量级设计使其在资源利用效率、扩展性和调度性能上都优于传统虚拟机。这对高密度部署和业务弹性缩放带来很大好处。
通过Namespace 命名空间—》进行隔离
通过Cgrep —》进行资源限制
- PID Namespace:隔离进程ID,每个容器都有自己的进程ID空间。–>进程命名空间
- NET Namespace:隔离网络接口,每个容器都有自己的网络空间。–>网络命名空间
- IPC Namespace:隔离System V IPC和POSIX message queues,每个容器都有自己的IPC空间。类似于管道的作用。
- MNT Namespace:隔离文件系统挂载点,每个容器都有自己的文件系统。
- UTS Namespace:隔离hostname和domainname,每个容器都有自己的hostname。和时间相关。
- user Namespace: 用户命名空间。
**容器:**运行镜像的地方,在操作系统里本质上就是启动一个进程来运行镜像,将镜像里的软件在一个隔离的环境里运行---->相当于给每个花瓶装到一个观光的那种玻璃隔离框
镜像:包含了一个微型操作系统
+业务核心代码
+其他依赖软件的软件单元
image=micro OS + app code + 其他库
仓库:网上存放镜像
的地方,docker官方提供了,阿里云也提供
镜像的集市
镜像是别人做出来上传到仓库里的
看日志的
[root@docker-1 ~]# docker logs my-go
root@ca2c341f0475:/go# docker pull redis
bash: docker: command not found
root@ca2c341f0475:/go# exit
exit
[root@docker-1 ~]#
docker cp 命令用于在 Docker 容器和本地文件系统之间复制文件或目录。基本语法如下:
docker cp [选项] 容器ID:容器路径 本地路径 docker cp [选项] 本地路径 容器ID:容器路径
一些常用示例:
- 从容器复制文件到本地
docker cp mycontainer:/opt/test.txt /data/test.txt
- 从本地复制文件到容器
docker cp /data/test.txt mycontainer:/opt/
- 递归复制容器目录到本地
docker cp mycontainer:/opt/. /data
docker cp也支持一些选项参数:
- -a:归档模式,复制文件属性及链接信息
- -L:总是跟随源链接
- -p:保留文件权限及属性信息
以上就是 docker cp 命令的常见用法,可以方便地在容器和本地文件系统之间复制文件。
试一下
[root@docker-1 ~] docker cp test.txt sc-mysql-3:/tmp
Successfully copied 2.05kB to sc-mysql-3:/tmp
[root@docker-1 ~]#
[root@docker-1 ~] docker start sc-mysql-3
sc-mysql-3
[root@docker-1 ~] docker exec -it sc-mysql-3 bash
bash-4.2# cd /tmp
bash-4.2# ls
test.txt
bash-4.2# cat test.txt
haahaha
sfa
sdfsgag
bash-4.2#
save -o 是导出,静态导出
[root@localhost ~] docker save -o cadvisor.tar + 镜像名字
动态导出:docker export -o
o是output
i是input
load是导入 -i
[root@localhost docker] docker load -i cadvisor.tar
Docker Volume 常用命令及参数简述如下:
docker volume create
创建一个数据卷
docker volume create [选项]
选项:
docker volume inspect
显示一个或多个数据卷的信息
docker volume inspect [选项] 数据卷名
docker volume ls
列出所有数据卷
docker volume ls [选项]
docker volume prune
删除未使用的数据卷
docker volume rm
删除指定的数据卷
此外,在 docker run 命令中可以通过 -v 参数来创建和挂载数据卷。
这些是 Docker Volume 相关的主要命令,通过这些命令可以便捷地管理数据卷。
好的,这里举几个Docker Volume命令使用的例子:
docker volume create --name data_vol
docker volume inspect data_vol
docker volume ls
docker run -v data_vol:/data ubuntu
将data_vol挂载到容器内/data目录
docker volume rm data_vol
docker volume prune
以上就是一些常见的示例,包括创建、查看、列出、挂载和删除Volume的示例。这些命令配合使用可以便捷地管理数据卷。
[root@docker-1 volumes] docker volume create xie '创建卷'
xie
[root@docker-1 volumes] docker volume ls
DRIVER VOLUME NAME
local 87e38c019186eff45190b0767c95ca6d8af255f88292d0254af03c696139ca34
local 293e693c1ba0264c31632ba2af120660e4abc0fb09246dbca3bab7973dca7090
local 953abcd2432ee62358527d5865c9ad8fe73b8fb3def82a39c8cee84a850ec3d1
local a2b0573256268ba172932b7c861ac27cf0422a539ccc0bd8e705290321f8665a
local ac5af551b963ac9242efde3db8cb2159b22875fbfb9a50a7bd71421974090619
local d245e1f710c4ae8153fce2a630f5ef94cce3ac9ffa0e9a7d35a2072d1e50110e
local xie
[root@docker-1 volumes]#
[root@docker-1 volumes] pwd
/var/lib/docker/volumes
[root@docker-1 volumes] ls
xie
[root@docker-1 volumes]#
[root@docker-1 volumes] docker volume inspect xie '看卷的详细信息'
[
{
"CreatedAt": "2024-01-31T16:47:31+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/xie/_data", '挂载'--->宿主机的里的位置
"Name": "xie",
"Options": null,
"Scope": "local"
}
]
[root@docker-1 volumes]#
[root@docker-1 volumes] docker run -d \
> --name devtest \
> --mount source=myvol2,target=/app \
> nginx:latest
f930b469045f3e7c3c0fb8ec99aa6694ad24aa3e94d5f27bcd0358a9d3b04571
[root@docker-1 volumes] docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f930b469045f nginx:latest "/docker-entrypoint.…" 6 seconds ago Up 5 seconds 80/tcp devtest
-d
:在后台运行容器--name
:为容器命名--mount
:使用mount语法挂载source
:数据卷的名称,默认没有的话,docker会自动帮忙新建target
:容器内的挂载点
[root@docker-1 volumes] docker exec -it devtest bash
root@f930b469045f:/# pwd
/
root@f930b469045f:/# ls
app bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@f930b469045f:/# cd app
root@f930b469045f:/app# mkdir longyi
root@f930b469045f:/app# ls
longyi
root@f930b469045f:/app# exit
exit
[root@docker-1 volumes] cd /var/lib/docker/volumes/myvol2/_data/
[root@docker-1 _data]# ls
longyi
[root@docker-1 _data]#
在nginx的容器内的卷新建文件,宿主机里边的挂载点也会相应的做出改变
宿主机是真正的源头,把源头删了 容器里边也没有了
[root@docker-1 _data] docker run -d --name devtest2 --mount source=myvol2,target=/app nginx:latest
0560f3b35bffc921cd86b01e6878cb936ba2dfb6e373300a11d839d71e991963
[root@docker-1 _data] docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0560f3b35bff nginx:latest "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 80/tcp devtest2
f930b469045f nginx:latest "/docker-entrypoint.…" 29 minutes ago Up 29 minutes 80/tcp devtest
[root@docker-1 _data]# pwd
/var/lib/docker/volumes/myvol2/_data
[root@docker-1 _data]# mkdir sc
[root@docker-1 _data] docker exec -it devtest bash
root@f930b469045f:/# cd /app
root@f930b469045f:/app# ls
longyi sc
root@f930b469045f:/app# exit
exit
[root@docker-1 _data] docker exec -it devtest2 bash
root@0560f3b35bff:/# cd /app/
root@0560f3b35bff:/app# ls
longyi sc
root@0560f3b35bff:/app# mkdir hui
root@0560f3b35bff:/app# exit
exit
[root@docker-1 _data] docker exec -it devtest bash
root@f930b469045f:/# cd /app/
root@f930b469045f:/app# ls
hui longyi sc
root@f930b469045f:/app#
用相同的卷解决了两个进程之间通信的问题
-v操作
[root@docker-1 _data] docker run -d \
> --name devtest3 \
> -v myvol2:/app \
> nginx:latest
952638341afc76bae529a94532fc0cc41c6cfcd368828521c9c806f90ac07dab
[root@docker-1 _data]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
952638341afc nginx:latest "/docker-entrypoint.…" 11 seconds ago Up 10 seconds 80/tcp devtest3
0560f3b35bff nginx:latest "/docker-entrypoint.…" 6 minutes ago Up 6 minutes 80/tcp devtest2
f930b469045f nginx:latest "/docker-entrypoint.…" 36 minutes ago Up 36 minutes 80/tcp devtest
[root@docker-1 _data] docker inspect devtest3
"Mounts": [ `看详细信息`
{
"Type": "volume",
"Name": "myvol2",
"Source": "/var/lib/docker/volumes/myvol2/_data",
"Destination": "/app",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
基础设施即服务,Infrastructure as a Service
提供卖服务器给其他的客户的服务 --》阿里云、腾讯云、AWS、华为云等
IaaS提供虚拟化的计算资源作为服务。这些服务通常包括虚拟服务器、存储和网络资源。用户可以通过互联网访问这些资源,并根据自己的需求进行扩展。IaaS提供了一种灵活、按需求缩放的计算环境,用户可以按实际使用量付费。
IaaS的关键特点是:
- 提供原始的、未配置的计算资源。
- 用户可以完全控制操作系统、存储和部署的应用程序。
- 灵活性高,可以根据需要选择配置。
平台即服务,Platform-as-a-Service
把服务器平台作为一种服务提供的商业模式。PaaS实际上是指将软件研发的平台作为一种服务,以SaaS的模式提交给用户。因此,PaaS也是SaaS模式的一种应用。
买平台给别人使用的,平台里有很多的软件
区块链平台、存储的平台、cdn等
PaaS提供了除了基础计算资源外的附加服务,这些服务通常包括操作系统、数据库管理系统、开发工具等,以支持应用程序的快速开发和部署。PaaS提供了一个预配置的平台,用户可以在其上构建、测试、部署和管理应用程序。
PaaS的关键特点是:
- 提供了一套完整的开发和部署平台。
- 用户不需要管理基础设施,可以专注于应用开发。
- 常常包括多种服务和API,如数据库、消息队列和存储服务。
软件即服务,Software-as-a-Service
软件即服务,应用模式是基于互联网提供软件服务。如daydao是PaaS平台,但是里面提供的HR、CRM、OA等产品服务属于SaaS。
卖软件给其他的人使用
SaaS是一种将应用程序作为服务提供给用户的模式,用户可以通过互联网使用这些应用程序,而不需要安装在本地设备上。SaaS提供商负责应用程序的维护、升级和安全性。用户通常通过订阅模式支付服务费用。
SaaS的关键特点是:
- 应用程序完全托管在云端。
- 用户通过网络访问应用程序,通常是通过网页浏览器。
- 提供商负责软件的所有技术细节,包括维护和升级。
后端即服务 Backend as a Service
BaaS是为移动和Web应用程序开发者提供的一种云服务模式,它允许开发者将后端应用程序逻辑和服务外包给第三方服务提供商。BaaS提供了一系列后端云解决方案,如数据库管理、用户身份验证、云存储和服务器端逻辑,这样开发者可以更专注于前端开发。
BaaS的关键特点是:
- 提供了易于使用的API和工具,用于构建丰富的应用程序后端。
- 集成了多种服务,如推送通知、社交媒体集成等。
- 开发者不需要深入了解服务器端的复杂性或进行大量的后端开发工作。
这些服务模式的主要区别在于它们提供的抽象级别不同,以及用户需要管理的计算资源和服务的范围。IaaS提供了最基础的计算组件,而PaaS提供了额外的平台服务,SaaS则提供了完整的应用程序,而BaaS专注于后端服务。随着云计算的发展,这些模式使得企业和开发者能够更加灵活和高效地构建、部署和管理应用程序。
一朵云里边有很多小水珠,小水珠可以漂浮在空中,小水珠一遇到灰尘就形成了大的水珠,就会变成雨
小水珠:服务器
说白了云计算就是 小水珠集群
集群: 很多集群合并在一起
**云原生: 就是与容器、k8s、Prometheus、etcd相关的技术 ** ----》现在一个容器就是小水珠
微服务: 微小的服务—》背后是容器
微服务(Microservices)是一种软件架构风格,它主张将一个单一的应用程序开发为一套小的、相互独立的服务组合。-----》和容器技术不谋而合 每个软件在一个容器里跑,在容器里跑的程序就叫微服务!
容器运行时软件: docker、containerd
能帮助我们去运行和启动容器的软件
k8s --》containerd
发展趋势:物理机–》虚拟化–》云计算–》云服务–》容器–》云原生
swarm
是docker官方推出的一个容器集群管理软件—》容器编排软件
k8s
是云原生基金会推出的一个容器集群管理软件 —》更加好用
[root@docker-1 ~] docker network ls
NETWORK ID NAME DRIVER SCOPE
4a7781731430 bridge bridge local
731d8ae7f85d host host local
f7f1dfaafbe0 none null local
[root@docker-1 ~]#
Docker网络模式 | 配置 | 说明 | |||
---|---|---|---|---|---|
hsot | –net=host | 容器和宿主机共享Network namespace。 | |||
container | –net=container:NAME_or_ID | 容器和另外一个容器共享Network namespace。 kubernetes中的pod就是多个容器共享一个Network namespace。 | |||
none | –net=none | 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。 | |||
bridge | –net=bridge | (默认为该模式) |
Docker容器的网络主要有以下几种类型:
- bridge网络
默认的网络模式。在宿主机上创建docker0网桥,启动的容器会连接到docker0网桥,并分配IP。容器之间可以通过网桥互联。
- host网络
容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
- container网络
使用另一个容器的网络命名空间,共享IP、端口范围等。多个容器可以公用一个容器的网路栈。
- None网络
容器没有网卡,没有IP,不能联网。但是可以在两个容器之间使用链接来通信。
- overlay网络
在多个Docker宿主机上创建一个分布式的网络,支持跨Docker主机的容器互联。用于支持Swarm集群。
此外,还可以使用自定义的网桥、Macvlan等方式进行高级网络配置,以实现特定的网络拓扑或者需求。
在bridge模式下,docker会虚拟一个交换机,然后这个交换机连接宿主机的lan口。
详细来说,在Docker的bridge网络模式下,是这样实现的:
Docker服务会在宿主机上创建一个名为docker0的网络桥。
这个docker0桥会被分配一个私有网段的IP地址,比如172.17.0.1/16。
Docker启动新的容器时,会将容器的虚拟网卡连接到docker0这个桥上。
连接到同一个docker0桥上的容器可以互通,它们位于同一个物理网络中。
docker0桥再通过宿主机的物理网卡连接到外部网络。外部网络可以访问这些容器。
所以,可以将docker0桥理解为一个虚拟的二层交换机,然后这个交换机利用宿主机的网络连接到外界。
通过这种机制,容器可以获得自己的网络栈,但又与宿主机在同一个物理网络中。
container:
bridge:
none:
[root@fengdeyong ~] docker network create -d bridge hunan
[root@fengdeyong ~] docker create -p 7788:6379 --name longyi-1 --network hunan redis
[root@docker-1 ~] docker network ls
NETWORK ID NAME DRIVER SCOPE
4a7781731430 bridge bridge local
731d8ae7f85d host host local
f7f1dfaafbe0 none null local
[root@docker-1 ~]#
1.查看docker里有哪些网络类型,对应的命名空间
[root@docker-1 ~] docker network ls
NETWORK ID NAME DRIVER SCOPE
4a7781731430 bridge bridge local
731d8ae7f85d host host local
f7f1dfaafbe0 none null local
[root@docker-1 ~]#
2.创建一个网络的命名空间叫sc
[root@docker-1 ~] docker network create -d bridge sc
d37528ef067b18fed668ab645af9f256f5558f3c823c4e91cea90dcfd576d053
[root@docker-1 ~]#
docker network create
:创建一个 Docker 网络-d bridge
:指定使用 bridge 网络驱动程序,这是默认的类型sc
:自定义网络的名称,这里我指定的是 sc
3.创建2个centos7的容器,使用sc这个网络命名空间
[root@docker-1 ~] docker pull centos:7
7: Pulling from library/centos
2d473b07cdd5: Pull complete
Digest: sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987
Status: Downloaded newer image for centos:7
docker.io/library/centos:7
[root@docker-1 ~] docker run -it --name test1 --network sc centos:7 bash
[root@564763757ec0 /]# exit
exit
[root@docker-1 ~] docker run -it --name test2 --network sc centos:7 bash
[root@81e224adb19c /]#
4.进入创建容器里面,查看下ip地址,互相ping下
[root@81e224adb19c ~] ip addr
inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
[root@81e224adb19c ~]#
[root@564763757ec0 /] ip addr
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
[root@564763757ec0 /]#
[root@564763757ec0 /] ping 172.18.0.3
PING 172.18.0.3 (172.18.0.3) 56(84) bytes of data.
64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.060 ms
64 bytes from 172.18.0.3: icmp_seq=2 ttl=64 time=0.058 ms
64 bytes from 172.18.0.3: icmp_seq=3 ttl=64 time=0.055 ms
64 bytes from 172.18.0.3: icmp_seq=4 ttl=64 time=0.054 ms
^C
--- 172.18.0.3 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 0.054/0.056/0.060/0.009 ms
[root@564763757ec0 /]#
看ip的简单方法
[root@docker-1 ~] docker network inspect sc
"Containers": {
"564763757ec04fd40fb4abad2e74c7346b4d9e3cfb3fedd440300152bf0fa097": {
"Name": "test1",
"EndpointID": "e8a70c7b405c7343e466b6c76d05b712f0c1304e24df61c755e054bf0524ed1d",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"81e224adb19c3491abb12938bb8d318fa782a762dbfc09eff5ac883c9b534fd2": {
"Name": "test2",
"EndpointID": "9b115e9d6eff1e92a749f692347900efce96bef9d9e440d5c14b8086c19f351c",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
5.创建一个使用默认的命名空间的容器,名字自己定义
[root@docker-1 ~] docker run -it -d --name test3 centos:7 bash
cf4746b47e42c41fec8b969ef96a7f11e2d9def16460b6dc3bac8780e49b1f3e
[root@docker-1 ~] docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cf4746b47e42 centos:7 "bash" 4 seconds ago Up 3 seconds test3
81e224adb19c centos:7 "bash" 8 minutes ago Up 4 minutes test2
564763757ec0 centos:7 "bash" 8 minutes ago Up 4 minutes test1
938d53c057a1 mysql:5.7.43 "docker-entrypoint.s…" 17 hours ago Up 2 hours 33060/tcp, 0.0.0.0:3308->3306/tcp, :::3308->3306/tcp sc-mysql-3
[root@docker-1 ~]#
6.进入新创建容器,ping使用sc网络命名空间的容器,看是否可以ping通?
[root@cf4746b47e42 /] ping 172.18.0.3
PING 172.18.0.3 (172.18.0.3) 56(84) bytes of data.
^C
--- 172.18.0.3 ping statistics ---
13 packets transmitted, 0 received, 100% packet loss, time 12014ms
拼不通的,默认的容器ip是 172.17.0.3 sc的是 172.18.0.2和 172.18.0.3,网段都不一样
**Overlay网络是Docker的一种网络类型,它允许多个Docker守护进程主机创建一个分布式的网络。**其主要特性如下:
Overlay网络可以跨多个Docker主机和Cluster实现容器间通信。Overlay将多个Docker守护进程连接成一个统一的网络。
Overlay网络利用 vxlan 隧道技术封装容器数据包,然后通过主机间路由转发来实现容器间通信。这种机制类似VPN。
容器IP地址段独立于主机IP地址段,并且可以重叠,不同宿主机上的容器IP可以位于相同网段。
Overlay网络提供了容器级的可见性与安全性。每个容器都拥有自己独立的IP和MAC地址。
Overlay网络需要一个密钥值管理网络加密,以及一个分布式存储服务保存网络状态和配置。一般通过 consul、etcd 或 zookeeper 提供。
Overlay网络驱动一般用于 Docker Swarm 等集群环境中,也可以通过一些第三方插件应用到 Kubernetes中。
综上,Overlay网络解决了 Docker 跨主机容器通信的问题,是实现大规模容器云平台的重要网络基础。
实现跨主机的docker容器之间的通信
容器的数据通过数组机的网络的数据发送出去
**VXLAN(Virtual eXtensible Local Area Network) 是 Overlay 网络的底层隧道技术。**通过将虚拟网络中的数据帧封装在实际物理网络中的报文中进行传输。具体实现方式为:
将虚拟网络的数据帧添加VXLAN首部后,封装在物理网络中的UDP报文中,然后以传统网路络的通信方式传送该UDP报文,到达目的主机后,去掉物理网络报文的头部信息以及VXLAN首部,将报文交付给目的终端。整个通信过程目的终端不会感知到物理网络的存在。
**VXLAN(Virtual eXtensible Local Area Network) 是 Overlay 网络的底层隧道技术。**它的主要工作原理如下:
封装层:Docker 容器发送的 Layer 2 数据包被封装成 UDP 数据包,成为 VXLAN 的载荷。
隧道传输:VXLAN 利用 UDP 隧道在物理网络上转发封装的数据包,允许数据包传输跨物理网络。
VTEP: 虚拟隧道端点(VTEP)负责封装和解封装 VXLAN 数据包。其中发送端 VTEP 封装数据包,接收端 VTEP 拆包并转发到容器。
VNI:VXLAN 网络标识(VNI)用于逻辑隔离 overlay 网络。overlay 内的主机和容器具有相同的 VNI。
内存表:记录 MAC-IP 和 VTEP 的映射关系。用于在overlay网络内部正确转发数据包。
所以,VXLAN 提供了一个二层的隧道,通过 UDP 封装实现了 overlay 网络上容器的数据平面传输。容器之间的通信被逻辑隔离和封装,跨主机转发。
封装图:
容器产生的数据帧—》vxlan协议里作为数据+vxlan首部
这个图片展示了Docker Overlay网络的工作原理。主要包含以下几个部分:
两个Docker主机(Docker Host A和Host B)。它们分别有自己的物理接口eth0,IP为10.0.0.1和10.0.0.2。
在每台主机上创建一个Overlay网络(net1、net2),网段为172.16.0.0/24。
在该Overlay上启动的容器c1和c2。它们分配到的IP为172.16.0.2和172.16.0.3。
Overlay网络通过vxlan设备和UDP端口实现容器数据包的隧道转发。
c1和c2之间的数据包通过UDP端口4789封装转发,实现了跨Host A和Host B的容器通信。
外部网络通过Host A和Host B的物理端口eth0访问Overlay中的容器。
所以这张图展示了基于Docker Overlay网络的跨主机容器通信原理,其中关键是利用vxlan和UDP端口打通多个主机上的容器网络。
四个宿主机,都启了docker 他们之间通过Overlay网络可以实现容器之间的跨主机通信。
- 在每台宿主机上创建一个Overlay网络,选取相同的子网段,例如172.16.0.0/16。
- Overlay会在每台宿主机上创建一个vxlan设备,端口为UDP 4789。
- 启动容器时连接到该Overlay网络。IP会分配在172.16.0.0/16段内。
- 容器发送的数据包,会被vxlan设备截取,封装成UDP数据包,发送到其他宿主机。
- 其他宿主机上的vxlan设备接收并解析数据包,转交到目标容器。
这样,位于Overlay子网的容器就实现了跨Docker主机的直接通信。
其中的载体是vxlan设备和UDP隧道。宿主机之间也无需特殊配置即可实现Overlay互联。这实现了Docker的跨主机容器联网。
lay是层的意思
lay 层: 应用层–》传输层–》网络层–》数据链路层—》物理层
over lay 是超过层,跨越这些层再封装
vlan----》隔离网络的作用
VLAN 的一些常见作用如下:
- 将物理网段划分为不同的逻辑网段,隔离广播域,控制广播风暴的影响范围。
- 可以在不同的物理位置创建逻辑上的局域网,通过路由和中继连接。
- 可以进行权限和安全控制,每个 VLAN 内部实施自身的安全策略和访问控制规则。
- 可以对网络资源进行划分,每个 VLAN 内的用户只能访问指定的服务器、存储等资源。
- 可以减少设备接口数量和网络搭建成本。通过 VLAN 内部可以访问全部资源。
所以,VLAN 的关键效果就是在二层网络上进行逻辑隔离。相比物理网段,它更灵活、便宜,也利于网络安全防护。这与 Docker Overlay 网络在理念上是类似的,只不过技术实现机制不同。
VLAN 主要作用就是对二层局域网进行隔离与划分。
VXLAN 和 VLAN 是两个工作在不同层次的技术。
VLAN 是二层技术,用于逻辑隔离二层网络中的广播域,通过在帧中添加标签实现。
VXLAN 是三层技术,将二层以太网帧封装在 UDP 隧道中,实现了二层数据可以透明地跨三层网络转发。
两者主要的差异有:
- VLAN 受限于物理网络大小,VXLAN 可以扩展更大规模。
- VLAN 是二层隔离,VXLAN 属于三层的 overlay 虚拟网络。
- VXLAN 基于隧道工作,可以跨物理网络实现逻辑网络。
所以 VXLAN 并不是 VLAN 的直接升级,而是采用了叠加隧道的思想实现更大范围的二层逻辑网络。
在 Docker 中,容器网络常用 VXLAN 实现 overlay 容器网络,并不会直接使用 VLAN 技术。
所以两者没有直接的升级关系,只是概念和手段有一定相似之处。
容器相当于宿主机上的一个进程,可以理解为寄生虫
容器产生数据包,这是应用层的数据
Overlay 网络中的 VXLAN 模块会截取容器的数据包,进行封装(在传输层上增加 UDP 头)
封装后的 VXLAN 包发送到宿主机的网络层,根据路由表判断应该发往哪个宿主机
数据包进入宿主机的传输层,最终通过物理网络发送给目标宿主机
目标宿主机接收到数据包后,反向过程发送到目标容器
数据包就是通过容器->宿主机传输层->网络层->物理层 这样的链路发送出去的。最后一层细节我补充清楚了。
[root@docker-1 ~] ps aux|grep containerd-shim
root 1957 0.0 0.3 720304 12872 ? Sl 09:02 0:01 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 938d53c057a172472fdde927f25d89c709e467d19eceebe2923d31f2e2907627 -address /run/containerd/containerd.sock
root 2855 0.0 0.3 720048 13476 ? Sl 10:43 0:01 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 564763757ec04fd40fb4abad2e74c7346b4d9e3cfb3fedd440300152bf0fa097 -address /run/containerd/containerd.sock
root 2966 0.0 0.3 720304 13120 ? Sl 10:43 0:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 81e224adb19c3491abb12938bb8d318fa782a762dbfc09eff5ac883c9b534fd2 -address /run/containerd/containerd.sock
root 3189 0.0 0.3 720048 13852 ? Sl 10:47 0:01 /usr/bin/containerd-shim-runc-v2 -namespace moby -id cf4746b47e42c41fec8b969ef96a7f11e2d9def16460b6dc3bac8780e49b1f3e -address /run/containerd/containerd.sock
root 3589 0.0 0.0 112828 980 pts/0 S+ 15:38 0:00 grep --color=auto containerd-shim
[root@docker-1 ~] ps aux|grep containerd-shim|wc -l
5
[root@docker-1 ~]#
数据持久化就是说—》数据的保存问题
保存到磁盘中
停止 Docker 容器的常用方法有以下几种:
- docker stop:正常停止方式,会发送 SIGTERM 信号给容器内应用,然后等待一段时间(默认10秒)让应用程序安全退出。例如:
docker stop my_container
- docker kill:强制直接停止容器,发送 SIGKILL 信号,不给应用程序时间退出。例如:
docker kill my_container
- docker container stop:功能与 docker stop 相同,新的命令结构。例如:
docker container stop my_container
docker rm -f:直接删除一个运行中的容器,容器被删除后会停止运行。
重启docker服务
杀死容器的进程号
[root@docker-1 ~] ps aux|grep containerd-shim root 1957 0.0 0.3 720304 12904 ? Sl 09:02 0:01 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 938d53c057a172472fdde927f25d89c709e467d19eceebe2923d31f2e2907627 -address /run/containerd/containerd.sock root 2855 0.0 0.3 720048 13508 ? Sl 10:43 0:01 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 564763757ec04fd40fb4abad2e74c7346b4d9e3cfb3fedd440300152bf0fa097 -address /run/containerd/containerd.sock root 2966 0.0 0.3 720304 13120 ? Sl 10:43 0:01 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 81e224adb19c3491abb12938bb8d318fa782a762dbfc09eff5ac883c9b534fd2 -address /run/containerd/containerd.sock root 3189 0.0 0.3 720048 13820 ? Sl 10:47 0:01 /usr/bin/containerd-shim-runc-v2 -namespace moby -id cf4746b47e42c41fec8b969ef96a7f11e2d9def16460b6dc3bac8780e49b1f3e -address /run/containerd/containerd.sock root 3619 0.0 0.0 112828 980 pts/0 S+ 16:02 0:00 grep --color=auto containerd-shim [root@docker-1 ~]# 找到id对应的进程号杀死他 kill -9 + 进程号
此外,可以通过设置容器的重启策略,在容器内应用退出后,自动停止容器而不是重启。
综上,对于想正常停止容器,推荐使用 docker stop;想快速停止,使用docker kill。
读书破万卷
---->知识的载体卷—》存储数据
storage—》存储
这幅图展示了Docker数据卷的工作原理,主要包含以下几个要点:
数据卷(Data Volume)是一个可供容器使用的特殊目录,由Docker管理,用于保存状态化数据。
数据卷可以绕过联合文件系统,直接与宿主机目录关联,实现数据持久化存储。
容器使用数据卷的好处是,数据保存在宿主机上,容器删除数据也不会丢失。
多个容器可以共享同一个数据卷,实现容器间数据共享。
数据卷生命周期独立于容器,容器启动/退出数据卷依然保存,实现应用状态的可靠存储。
数据卷内容会遮盖容器内的目录,实现与容器内部解耦。
所以,这幅图主要展示了Docker的数据卷机制,以及与容器目录的关系,解释了为什么数据卷可以可靠保存容器数据。
一个容器本质上就是一个进程
[root@docker-1 volumes] docker volume ls
DRIVER VOLUME NAME
local 87e38c019186eff45190b0767c95ca6d8af255f88292d0254af03c696139ca34
local 293e693c1ba0264c31632ba2af120660e4abc0fb09246dbca3bab7973dca7090
local 953abcd2432ee62358527d5865c9ad8fe73b8fb3def82a39c8cee84a850ec3d1
local a2b0573256268ba172932b7c861ac27cf0422a539ccc0bd8e705290321f8665a
local ac5af551b963ac9242efde3db8cb2159b22875fbfb9a50a7bd71421974090619
local d245e1f710c4ae8153fce2a630f5ef94cce3ac9ffa0e9a7d35a2072d1e50110e
[root@docker-1 volumes]#
**不会丢失数据。**正常停止容器使用的是docker stop命令,这只会发送SIGTERM信号给容器内应用进程,允许其安全退出。而容器使用的数据卷(volumes)是独立保存的,不会因为容器的停止而丢失或者删除,数据仍然被保留在宿主机文件系统中。
不会丢失会存放到/var/lib/docker/volumes/:
[root@docker-1 ~] cd /var/lib/docker/volumes/
[root@docker-1 volumes]# ls
293e693c1ba0264c31632ba2af120660e4abc0fb09246dbca3bab7973dca7090
87e38c019186eff45190b0767c95ca6d8af255f88292d0254af03c696139ca34
953abcd2432ee62358527d5865c9ad8fe73b8fb3def82a39c8cee84a850ec3d1
a2b0573256268ba172932b7c861ac27cf0422a539ccc0bd8e705290321f8665a
ac5af551b963ac9242efde3db8cb2159b22875fbfb9a50a7bd71421974090619
backingFsBlockDev
d245e1f710c4ae8153fce2a630f5ef94cce3ac9ffa0e9a7d35a2072d1e50110e
metadata.db
[root@docker-1 volumes]#
有两种主要方法:
(1)**使用数据卷(volumes)。**可以在docker run的时候,通过-v参数将宿主机的一个目录挂载到容器内部的一个目录,实现双向绑定。容器内部目录的数据变化会同步到宿主机目录。
(2)**使用docker cp命令手动复制。**可以将文件从运行中的容器内复制到宿主机指定目录,也可以反向从宿主机复制到容器内。
在运行容器时使用-v
参数来创建一个数据卷或绑定挂载:
docker run -v /path/in/host:/path/in/container -d your_image
使用docker cp
命令来在容器和宿主机之间复制文件。例如:
docker cp your_container:/path/in/container /path/in/host
这将会把容器的/path/in/container
文件或目录复制到宿主机的/path/in/host
常用的几种方法包括:
(1) 使用docker cp命令在容器和宿主机手动复制文件数据。
(2) 在docker run的时候挂载宿主机目录到容器内部,实现宿主机目录和容器目录的双向绑定,数据会双向同步。
(3) 设置数据卷,并挂载到多个容器内,实现容器间数据共享。
(4) 利用Dockerfile COPY指令或配置Dockerfile时的ADD指令,在构建镜像时将文件拷贝到镜像里,运行时可通过挂载使用。
可以使用docker restart命令重启容器,重新加载配置文件的变更。对于一些应用,可能需要进入容器内部,手动重新加载/启动服务,比如执行source命令重新读取配置文件等。
1.创建一个卷: sanchuang,在sanchuang卷里创建一个index.html首页文件,内容welcome to sanchuang
2.创建2个容器名字自己定义:rose-1 rose-2,启动nginx,使用sanchuang这个卷
3.测试访问
访问两个不同的容器,看到相同的内容(因为他们挂载相同的卷)
[root@docker-1 myvol2] docker volume create sanchuang
sanchuang
[root@docker-1 myvol2] cd /var/lib/docker/volumes/sanchuang/_data
[root@docker-1 _data] ls
[root@docker-1 _data] echo "welcome to sanchaung" >>index.html
[root@docker-1 _data] cat index.html
welcome to sanchaung
[root@docker-1 _data]#
[root@docker-1 _data] docker run -d --name li-nginx-1 -p 5080:80 -v sanchuang:/usr/share/nginx/html/ nginx
b6d347477abe4b43f14e4428dc4613b6a8b39e2afb5bf0f264e648d669579fbd
[root@docker-1 _data] docker run -d --name li-nginx-2 -p 5081:80 -v sanchuang:/usr/share/nginx/html/ nginx
33efd6cf8022ab6dba350790342b94ae0a01e434311f47f5999284d866ce8ec2
[root@docker-1 _data]#
[root@docker-1 _data] docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
33efd6cf8022 nginx "/docker-entrypoint.…" 31 seconds ago Up 31 seconds 0.0.0.0:5081->80/tcp, :::5081->80/tcp li-nginx-2
b6d347477abe nginx "/docker-entrypoint.…" 39 seconds ago Up 38 seconds 0.0.0.0:5080->80/tcp, :::5080->80/tcp li-nginx-1
[root@docker-1 _data] echo "welcome to changsha" >>index.html
[root@docker-1 _data] curl 192.168.153.166:5080
welcome to sanchaung
welcome to changsha
[root@docker-1 _data] curl 192.168.153.166:5081
welcome to sanchaung
welcome to changsha
[root@docker-1 _data]#
为什么一定要绑定到:/usr/share/nginx/html/
因为这个文件夹是nginx 存放网页的目录