一、简介
1、docker的基本结构是什么,包含哪些组件?
docker的基本机构是c/s模式,即客户端/服务端模式。 由docker客户端和docker守护进程组成。docker客户端通过命令行或其它工具使用docker sdk与docker守护进程通信,发送容器管理请求。docker守护进程接收并处理请求,调用docker引擎执行容器的创建、运行、停止等操作。docker守护进程接收并处理请求,调用docker引擎执行容器的创建、运行、停止等操作。docker引擎还负责与docker仓库交互、搜索、上传镜像。docker仓库是一个存储镜像的服务,可以是公有的或私有的。
2、docker为什么需要存储以及是如何工作的?
docker需要存储是因为容器本身是无状态的,也就是说,容器中的数据在容器停止或删除时会丢失,对于一些需要持久化或共享数据的应用来说是不可接收的。例如数据库、配置文件、日志等等。因此容器提供了存储驱动( overlay2、fuse-overlayfs、btrfs、zfs、vfs、devicemapper)和挂载方式( volumes、bind mounts、tmpfs mounts)来实现容器产生的数据持久化和共享。
3、docker和虚拟机的区别?
- | Docker容器 | 虚拟机 |
---|---|---|
技术原理 | 共享操作系统内核,隔离用户空间 | 模拟硬件和操作系统,隔离整个操作系统 |
资源占用 | 较少的内存和存储空间 | 较多的内存和存储空间 |
启动速度 | 快速启动 | 较慢的启动 |
硬件资源访问 | 直接访问宿主机的硬件资源 | 通过Hypervisor模拟硬件资源 |
运行环境 | 特定的应用程序或服务 | 可以运行不同的操作系统和应用程序 |
灵活性 | 容易部署和迁移 | 较难部署和迁移 |
安全性 | 低一些 | 较高一些 |
二、网络
2.1、网络模式
1、host模式
简单的说,就是使用宿主机的网络配置。
2、bridge模式
bridge是docker中默认的网络模式,此模式会为每一个容器分配Network Namespace、设置ip等,并将主机上的容器连接到一个虚拟网桥上。
3、container模式
指定新创建的容器与一个已经存在的容器共享一个Network Namespace,而不是与宿主机共享。
4、none模式
在这个模式下,docker容器拥有自己的Network Namespace,但是并不会为docker容器进行任何网络配置,也就是说,这个docker容器没有网卡、ip、路由等信息,需要手动为docker容器添加网卡、配置ip等。
2.2、网络原理
Docker网络原理,主要包括: 容器之间通信和容器访问外网。
1、容器之间通信
Docker服务启动后,会生成一个docker0网桥,每起一个容器,docker0网桥会为容器一个可用的ip地址。网桥docker0采用桥接模式,并使用veth-pair技术 (veth-pair就是一对虚拟网络设备接口,成对出现,一端连接着协议,一端彼此相连,正因为这个特性,veth-pair充当一个桥梁,连接各种虚拟网络设备)。这样就使得容器和容器之间是可以相互ping通的。
2、容器访问外网
docker0是虚拟出来的网桥,因此是无法被外部网络访问,所以需要在运行容器时通过-p参数将容器的端口映射到宿主机的端口上。 实际上docker采用NAT的方式,将容器的内部服务端口与宿主机上的某一个端口进行绑定,使得宿主机外部可以将网络报文发送到容器。
这里的关键是NAT,查看宿主机上的iptables规则
iptables -t nat -S
如下图所示:
在NAT表中,有这么一条规则:-A POSTROUTING -s 172.17.0.0/24 ! -o docker0 -j MASQUERAD,其含义就是: 如果docker0网桥收到来自172.17.0.0/24网段外出包,把它交给MASQUERAD处理,而MASQUERAD的处理方式就是将包的源地址替换成宿主机上的ip地址发送出去,做为一次源地址转换(SNAT)。
2.3、容器互联
1、同主机不同网段之间的容器互联
正常情况下,两个不同网段之间的容器是不能相互ping通的,如上图所示,网段为172.17的容器与网段为172.29网段的容器不能互相ping通。
# 使用以下命令连通不在同一个网段下的Docker容器,将容器加入到需要互通的网络中
docker network connect 网络名称 容器名称
使用如下图中所示的命令,就可以
2、跨主机之间的容器互联
在 Docker 中,每个容器都有自己的网络命名空间,这意味着每个容器都拥有自己的IP地址和网络接口。默认情况下,Docker使用桥接网络模式,将容器连接到一个共享网桥。这种方式适用于在单个主机上运行多个容器的情况。然而,在分布式环境中,可能需要将容器连接到不同的主机上,并进行跨主机通信。 为实现跨主机通信,Docker 提供了多种网络连接方式,包括 Overlay 网络、MacVLAN 网络和第三方网络插件。这些网络连接方式可以扩展 Docker 的网络功能,使容器能够在跨主机环境中相互通信。
1、 docker提供了overlay网络驱动,它可以在不同的docker主机之间创建虚拟网络,使得容器可以通过ip和端口进行通信。使用overlay网络,可以将多个docker主机上的容器连接到一个虚拟网络中,并且它们可以像在同一个主机上一样进行通信。使用overlay网络可以在不同主机上创建跨主机的容器连接,便于构建分布式引用或跨多个主机进行负载均衡。要使用overlay网络,需要在每个docker主机上启用swarm模式,并创建一个swarm集群,然后创建一个overlay网络,并将容器加入到该网络中。
2、通过 直接路由的方式的方式实现跨主机的docker容器通信。
3、除了Docker内置的Overlay网络和 MacVLAN 网络,还有许多第三方网络插件可用于实现跨主机通信。这些插件提供了更丰富的网络功能和配置选项。 常见的第三方网络插件包括Calico、Weave、Flannel 、openvswitch等。安装和配置这些网络插件可以参考它们的官方文档。
三、存储
3.1、存储驱动
docker容器使用存储驱动程序来管理容器文件系统和镜像。Docker提供了6种不同的存储驱动程序:overlay2、fuse-overlayfs、btrfs、vfs、vfs、devicemapper。
1、overlay2
overlay2驱动是所有当前指的Linux发行版的首选存储驱动程序,不需要额外的配置。
2、fuse-overlayfs
fuse-overlayfs驱动仅使用于在不支持rootless overlay2的主机上运行rootles docker。在Ubuntu和Debian 10上,是支持rootless overlay2的,因此不需要使用fuse-overlayfs驱动。在这些系统中,overlay2可以直接在rootlesss模式下使用。
3、btrfs and zfs
btrfs and vfs存储驱动程序允许高级选项,例如创建快照,但需要更多的维护和设置。
4、vfs
vfs存储驱动程序用于测试目的,以及不能使用写时复制文件系统的情况,此存储驱动程序性能比较差,通常不建议用于生产环境。
5、devicemapper
devicemapper驱动使用Linux内核体统的设备映射功能,它可以创建逻辑卷来作为容器的文件系统。devicemapper驱动可以提供较高的性能和较强的数据隔离性。
您的操作系统和内核可能不支持每个驱动程序,例如aufs仅在ubuntu和debian上受支持,并且可能需要安装额外的软件包。而btrfs仅在您的操作系统使用btrfs作为存储才受到支持。
Linux发行版 | 推荐存储驱动程序 | 可选择存储驱动程序 |
---|---|---|
Ubuntu | overlay2 | devicemapper、zfs、vfs |
Debian | overlay2 | devicemapper、vfs |
Centos | overlay2 | devicemapper、zfs、vfs |
Fedora | overlay2 | devicemapper、zfs、vfs |
SLES 15 | overlay2 | devicemapper、vfs |
RHEL | overlay2 | devicemapper、vfs |
总结:
1、devicemapper存储驱动程序已弃用,并将在以后的版本中删除,建议devicemapper存储驱动用户迁移到overlay2。
2、vfs存储驱动仅适用于测试目的,生产环境不建议使用。
3、根据您的发行版本,你可能有其它存储驱动程序,例如btrfs,对于这个特定用例可能具有优势,但需要额外的设置和人工维护,因此不推荐用于常见场景。
对于docker来说,后备文件系统是/var/lib/docker所在的文件系统,一些存储驱动程序只用于特定的后备文件系统
Storege driver | Supported backing filesystems |
---|---|
Overlay2 | xfs with ftype=1,ext4 |
fuse-overlayfs | any filesystem |
devicemapper | direct-lvm |
btrfs | btrfs |
zfs | zfs |
vfs | any filesystem |
3.2、挂载方式
docker提供了三种方式将数据从宿主机挂载到docker容器中,分别为:volumes、bind mounts、tmpfs
1、volumes是在宿主机文件系统的一个路径,默认情况下统一的父路径是 /var/lib/docker/volumes/,非Docker进程不能修改这个路径下面的文件,所以说volumes是容器数据持久存储数据最安全的一种方式。
2、bind mounts可以将文件存储在宿主机文件系统的任何路径
3、tmpfs 只存储在宿主机的内存中,不会写入到宿主机文件系统中,不会持久化存储。
四、Dockerfile
这里使用二进制mongodb文件来实现如何构建镜像及创建容器?这里已经提前下载好了mongodb二进制文件。
[root@localhost dockerfile]# ll
total 204564
-rw-r--r--. 1 root root 1123 Aug 7 09:49 Dockerfile
-rw-r--r--. 1 root root 147 Jul 27 2021 mongodb.conf
drwxr-xr-x. 3 root root 91 Jul 27 2021 mongodb-linux-x86_64-rhel70-3.2.22
1、mongodb.conf文件内容如下所示:
vim mongodb.conf
dbpath = /data/usr/mongodb/data
logpath = /data/usr/mongodb/logs/mongodb.log
port = 27017
fork = false
bind_ip=0.0.0.0
auth = true
maxConns=20000
2、Dockerfile文件内容如下所示:
vim Dockerfile
FROM centos:7.6.1810
MAINTAINER dongchengjueshen@lvm.com
RUN yum install nc -y && \
yum install vim -y && \
yum install net-tools -y && \
yum install curl -y
RUN mkdir -p /data/usr
ADD mongodb-linux-x86_64-rhel70-3.2.22 /data/usr/mongodb
RUN mkdir /data/usr/mongodb/{data,logs}
ENV PATH /data/usr/mongodb/bin:$PATH
EXPOSE 27017
WORKDIR /data/usr/mongodb/bin/
COPY mongodb.conf .
CMD /data/usr/mongodb/bin/mongod -f mongodb.conf
3、使用docker build构建镜像
docker build -t mongodb:3.2.22 .
4、docker-compose文件如下所示:
version: '2'
services:
mongodb:
image: mongodb:3.2.22
hostname: mongo-single
container_name: mongo-single
ports:
- 0.0.0.0:17000:27017
healthcheck:
test: ["CMD","nc","-z","localhost","27017"]
interval: 30s
timeout: 10s
retries: 3
volumes:
- "/data/basic-data/mongo-single/data/backup:/data/backup"
- "/data/basic-data/mongo-single/data/restore:/data/restore"
- "/data/basic-data/mongo-single/data/config:/data/config"
- "/data/basic-data/mongo-single/data/db:/data/usr/mongodb/data"
- "/data/basic-data/mongo-single/data/logs:/data/usr/mongodb/logs"
tty: true
restart: always
networks:
- default_bridge
networks:
default_bridge:
external: true
如下图所示::
五、常用命令
1、仓库相关
docker search $KEY_WORD # 查找镜像
docker pull $REGISTRY:$TAG # 获取镜像
docker push $IMAGE_NAME:$IMAGE_TAG # 推送镜像到仓库,需要先登录
docker login $REGISTRY_URL # 登录仓库
docker logout $REGISTRY_URL # 退出仓库
docker info # 显示Docker详细的系统信息,可查看仓库地址
docker --help # 显示Docker的帮助信息
2、容器相关
docker attach $CONTAINER_ID # 启动一个已存在的docker容器
docker stop $CONTAINER_ID # 停止docker容器
docker start $CONTAINER_ID # 启动docker容器
docker restart $CONTAINER_ID # 重启docker容器
docker kill $CONTAINER_ID # 强制关闭docker容器
docker pause $CONTAINER_ID # 暂停容器
docker unpause $CONTAINER_ID # 恢复暂停的容器
docker rename $CONTAINER_ID # 重新命名docker容器
docker rm $CONTAINER_ID # 删除容器
docker logs $CONTAINER_ID # 查看docker容器运行日志,确保正常运行
docker inspect $CONTAINER_ID # 查看container的容器属性,比如ip等等
docker port $CONTAINER_ID # 查看container的端口映射
docker top $CONTAINER_ID # 查看容器中正在运行的进程
docker commit $CONTAINER_ID $NEW_IMAGE_NAME:$NEW_IMAGE_TAG # 将容器保存为镜像
docker ps -a # 查看所有容器
docker stats # 查看容器的资源使用情况
3、镜像相关
docker images # 查看本地镜像
docker rmi $IMAGE_ID # 删除本地镜像
docker inspect $IMAGE_ID # 查看镜像详情
docker save $IMAGE_ID > 文件路径 # 保存镜像为离线文件
docker save -o 文件路径 $IMAGE_ID # 保存镜像为离线文件
docker load < 文件路径 # 加载文件为docker镜像
docker load -i 文件路径 # 加载文件为docker镜像
docker tag $IMAGE_ID $NEW_IMAGE_NAME:$NEW_IMAGE_TAG # 修改镜像TAG
docker run 参数 $IMAGE_ID $CMD # 运行一个镜像
docker history $IMAGE_ID # 显示镜像每层的变更内容
六、防火墙
《Linux运维总结:基于Centos系统使用iptables为docker容器配置防火墙策略》
《Linux运维总结:基于Centos系统使用firewalld为docker容器配置防火墙策略》
总结:整理不易,如果对你有帮助,可否点赞关注一下?
更多详细内容请参考:《Linux运维篇:Linux系统运维指南》