Background
- docker原理
- docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问。
- docker核心三大组件:
image
–镜像、container
-容器、repository
-仓库。- docker使用的cpu、内存以及系统内核等资源都是直接使用宿主物理机的硬件,所以docker的性能比虚拟机高。
- docker容器的本质是宿主机上的一个进程。通过namespace实现了资源隔离,通过cgroups实现了资源限制,通过写时复制机制(copy-on-write)实现了高效的文件操作。
- docker可以对哪些资源进行隔离:1、文件系统;2、网络(network);3、进程间的通信;4、针对权限的用户和用户组;5、进程内的pid和宿主机的pid;6、主机名与域名等。
- docker网络
Docker是一种轻量级容器化技术,允许通过隔离OS级的虚拟化方式在一个操作系统上运行多个应用。网络是Docker中的一个非常重要的组件,它允许容器之间进行通信和联网访问。本文主要介绍Docker网络的基础知识以及在容器化部署java程序时的应用。
1、docker网络类型
docker网络有三个基本要素:网络类型、网络驱动和网络配置。
- bridge
这个是默认的网络类型,建立在宿主机的网络接口之上。 - host
这种网络类型,直接使用宿主机的网络栈,容器和宿主机共享网络栈。 - overlay
这种网络类型可以跨越多个Docker守护进程,通过内置的DNS服务,允许容器之间跨主机进行通信。 - macvlan
这种方式可以让容器拥有自己的MAC地址,从而可以直接与物理网络中的设备进行通信。
适用环境:希望容器能够直接与物理网络接口进行通信,或希望每个容器具有独立的 IP 地址的场景。
创建方法:使用docker network create
命令并选择--driver macvlan
参数来创建 Macvlan 网络。
Macvlan是一个新的尝试,是真正的网络虚拟化技术的转折点。Linux实现非常轻量级,因为与传统的Linux Bridge隔离相比,它们只是简单地与一个Linux以太网接口或子接口相关联,以实现网络之间的分离和与物理网络的连接。
Macvlan提供了许多独特的功能,并有充足的空间进一步创新与各种模式。这些方法的两个高级优点是绕过Linux网桥的正面性能以及移动部件少的简单性。删除传统上驻留在Docker主机NIC和容器接口之间的网桥留下了一个非常简单的设置,包括容器接口,直接连接到Docker主机接口。由于在这些情况下没有端口映射,因此可以轻松访问外部服务。
- 创建MACVLAN网络:
docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=eth0 my-macvlan-network
- 在MACVLAN网络上启动容器:
docker run -d --name my-container --network my-macvlan-network my-image
2、docker网络驱动
docker支持多种网络驱动程序,每种网络驱动的实现方式都不同。下面列出了docker支持的网络驱动程序。
1、bridge驱动:此驱动为docker的默认设置,docker安装时会创建一个名为 docker0 的Linux bridge,新建的容器会自动桥接到这个接口。但与外界通信使用NAT,增加了通信的复杂性,在复杂场景下使用会有诸多限制。每个容器启动后会通过DHCP自动获取一个IP地址,容器间可以通过 IP 地址相互通信,但是容器重启IP会发生变化。
2、host驱动:使用这种驱动的时候,Docker容器和宿主机共用同一个network namespace,使用宿主机的网卡、IP和端口等信息。但是,容器其他方面,如文件系统、进程列表等还是和宿主机隔离的。host模式不存在虚拟化网络带来的额外性能负担。但是host驱动也降低了容器与容器之间、容器与宿主机之间网络层面的隔离性,引起网络资源的竞争与冲突。容器的网络配置与宿主机相同,可以通过宿主机的 IP 地址直接访问容器。
3、overlay驱动:此驱动采用IETF标准的VXLAN方式,并且是VXLAN中被普遍认为最适合大规模的云计算虚拟化环境的SDN controller模式。在使用的过程中,需要一个额外的配置存储服务, 还需要在启动docker daemon的的时候额外添加参数来指定所使用的配置存储服务地址。overlay指的就是在物理网络层上再搭建一层网络,通过某种技术再构建一张相同的逻辑网络。需要互相通信的容器链接到相同的逻辑网络就可以通过容器名称互相通信。
4、remote驱动:这个驱动实际上并未做真正的网络服务实现,而是调用了用户自行实现的网络驱动插件,使libnetwork实现了驱动的可插件化。
5、null驱动:使用这种驱动的时候,Docker容器拥有自己的network namespace,但是并不为Docker容器进行任何网络配置。也就是说,这个Docker容器除了network namespace自带的loopback网卡外,没有其他任何网卡、IP、路由等信息,需要用户为Docker容器添加网卡、配置IP等。这种模式如果不进行特定的配置是无法正常使用的,但是优点也非常明显,它给了用户最大的自由度来自定义容器的网络环境。
每个网络类型都具有自己的特点和适用场景,根据实际需求选择合适的网络创建方法非常重要。此外,还有其他网络驱动和网络插件可供选择,以满足不同环境的需求,例如 Calico、Weave 等。
3、docker网络配置
docker网络配置官方文档:https://docs.docker.com/reference/cli/docker/network
- docker安装后会自动创建3种网络:bridge、host、none
# 查看命令
docker network ls
- 创建一个自定义的Docker网络
docker network create yunlu
- 将容器连接到一个已存在的Docker网络
# 第一种方式,my-container容器已经启动了
docker network connect yunlu my-container
# 第二种方式,my-container容器启动时通过 `--network yunlu` 或 `--net=yunlu`连接自定义网络
docker run -d --restart=always --name my-container --network yunlu -p 8080:8080 -v $(pwd):/app -w /app yunlu/openjdk:1.8-alpine java -Duser.timezone=GMT+08 -Dfile.encoding=utf-8 -Dspring.config.location=/app/application.yml -jar /app/app.jar
- 查看一个Docker网络的详细信息
docker network inspect yunlu
- 查看一个Docker网络下的所有容器
docker network inspect --format='{{.Containers}}' yunlu
- 删除一个已存在的Docker网络
docker network rm yunlu
4、docker容器网络配置
我们可以在容器启动时通过 --network yunlu
或 --net=yunlu
连接自定义网络。bridge 网络是 docker 默认的网络类型,当创建容器时,如果不指定网络类型,则会自动创建一个桥接网络并将容器连接到该网络上。
- 查看某个容器的网络信息
# 第一种方式
docker inspect my-container | grep "NetworkMode"
# 第二种方式
docker inspect --format='{{.HostConfig.NetworkMode}}' my-container
5、容器化部署java程序
实现目标
容器化部署一个java程序huhang-server,该程序用到mysql、redis等服务,这些服务也是采用容器化部署。
两种实现思路
- huhang-server部署时网络使用host模式,mysql、redis等服务容器化部署时把所需端口映射出来供huhang-server使用;
- 使用自定义网络模式,先创建一个自定义网络yunlu,然后mysql、redis等服务所有容器都加入自定义网络yunlu,huhang-server也加入自定义网络yunlu,然后通过容器名称去访问mysql、redis等服务。
容器化部署java程序的两种方式:
- 对于一些简单的单体项目,可以使用 docker run 命令可以直接在命令行中运行容器,无需事先构建镜像;
- 如果项目较为复杂,涉及多个组件和配置,或者需要在不同环境中部署,建议使用 Dockerfile 构建自定义镜像。这样可以更好地管理和复用代码,并确保在不同环境中的一致性。