2、容器化技术基础:Docker基本概念与架构归纳总结输出为HTML正文内容片段
2.1 Docker到底是什么?
说到Docker,其实很多人第一次接触时都会有点懵。它到底是个虚拟机,还是个啥?
我个人习惯这么理解:Docker是一个“轻量级的集装箱系统”。你想想看,传统虚拟机就像搬家时租了个大卡车,你得先把整个房子(操作系统)搬进去,然后再放你的家具(应用)。而Docker呢,它就像一个个标准化的集装箱,只装你需要的家具和最基本的“生活必需品”(运行时环境)。
我在项目中遇到过这种情况:同一个Java应用,在开发环境跑得好好的,一到测试环境就报错。最后发现是测试环境的系统库版本和开发环境不一样。用了Docker之后,这种问题基本绝迹了。为什么?因为Docker把应用和它依赖的环境打包在了一起,走到哪儿都一样。
2.2 Docker的三大核心概念
要搞懂Docker,得先弄明白它的三个核心部件:镜像(Image)、容器(Container)、仓库(Repository)。这三者就像炒菜用的菜谱、做好的菜和菜市场。
2.2.1 镜像(Image)
镜像是一个只读的模板,里面包含了运行某个应用所需要的所有东西——代码、运行时、库、环境变量、配置文件。嗯,你可以把它理解成一套完整的“安装盘”。
举个例子,我们做国密算法部署,需要一个支持SM2、SM3、SM4算法的OpenSSL环境。你就可以做一个自定义镜像,把这个环境固化下来。
# 一个简单的Dockerfile示例
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y openssl
COPY ./gmssl /opt/gmssl
ENV PATH="/opt/gmssl/bin:${PATH}"
镜像有个特点:它是分层构建的。每一层都是只读的,而且可以被多个镜像共享。我记得有一次,团队里好几个人都在用同一个基础镜像,因为分层机制,每个人的构建速度都很快。
2.2.2 容器(Container)
容器是镜像的运行实例。镜像你不动它,它就是一个静态文件。但当你用Docker运行一个镜像时,Docker会在镜像层之上创建一个可写层,这时候就变成了一个活生生的“容器”。
你可以把容器想象成一个轻量级的、隔离的“小房间”。每个房间都有自己的文件系统、网络、进程空间,彼此互不干扰。我在项目中经常同时跑多个容器,一个跑国密签名服务,一个跑SM4加解密服务,它们各自独立,互不影响。
2.2.3 仓库(Repository)
仓库是存放镜像的地方。你可以把本地做好的镜像推送到远程仓库,也可以从仓库拉取别人做好的镜像。
Docker Hub是最大的公共仓库。但一般来说,企业级应用,尤其是涉及国密算法的项目,我建议用私有仓库。比如Harbor或阿里云的容器镜像服务。安全第一嘛。
| 概念 | 类比 | 特点 |
|---|---|---|
| 镜像 | 菜谱 | 只读、可复用、分层构建 |
| 容器 | 做好的菜 | 可写、可启停、隔离运行 |
| 仓库 | 菜市场 | 存储、分发、版本管理 |
2.3 Docker的架构本质
Docker使用的是C/S(客户端/服务器)架构。说白了,你敲的docker run、docker build这些命令,都是客户端在向Docker守护进程(Docker Daemon)发请求。
这里我画了一张架构图,把主要组件和它们之间的关系梳理了一下。你看看就明白了。
2.4 Docker的隔离机制:Namespaces与Cgroups
很多朋友会问:“Docker里的进程跟宿主机上的其他进程真的完全隔离吗?” 答案是:在大部分维度上是的,但并非100%像虚拟机那样严丝合缝。
Docker实现隔离靠的是操作系统底层的两个关键技术:
- Namespaces(命名空间):用来做“看不着”的隔离。进程在各自的Namespace里,只能看到自己的进程、网络、文件系统、用户,看不到外面的世界。
- Cgroups(控制组):用来做“抢不到”的限制。我限制你最多用1个CPU核心、512MB内存,你就算跑死也不能用更多。我在项目中遇到过容器内存泄漏,就是因为没设置内存限制,结果容器把宿主机的内存吃光了。
2.5 Docker网络与数据管理
这一块我跟不少新手讲过,其实没那么复杂。你只要记住两个核心:网络怎么通,数据怎么存。
2.5.1 网络模式
Docker默认提供了几种网络模式:
| 网络模式 | 特点 | 适用场景 |
|---|---|---|
| bridge | 默认模式,容器通过虚拟网卡连接到网桥 | 单机容器间通信 |
| host | 容器直接使用宿主机网络,不隔离 | 对网络性能要求极高的场景 |
| none | 无网络,完全隔离 | 安全敏感型容器 |
| overlay | 跨宿主机容器通信,用于Swarm集群 | 多机部署的国密服务集群 |
我个人习惯,在开发环境用bridge模式就够了。生产环境如果涉及微服务之间的国密认证交互,我建议研究一下overlay网络,让多个宿主机上的国密容器能通过内部虚拟网络通信,安全且高效。
2.5.2 数据持久化
容器有一个特点:它会消亡。当你把容器删了,里面生成的数据也就没了。这显然不符合国密算法的部署需求——你总不能让签名密钥随容器一起消失吧?
解决方案就是挂载数据卷(Volume)。有两种方式:
- bind mount:把宿主机的某个目录直接映射到容器里。简单直接,但跟宿主机耦合度高。
- volume:由Docker管理的数据卷。更推荐,因为它是持久的、可迁移的。我在做国密容器部署时,习惯把密钥文件、日志、数据库文件都放在volume里,这样即使容器重建,数据也还在。
# 创建一个数据卷
docker volume create gmssl-keys
# 挂载数据卷到容器
docker run -d --name gmssl-server \
-v gmssl-keys:/etc/gmssl/keys \
-p 443:443 \
my-gmssl-image:latest
2.6 避坑指南:我刚学Docker时的几个教训
最后,分享几个我踩过的坑,希望能帮你少走弯路。
- 别用latest标签上生产环境。我曾经偷懒一直用
latest,结果有一次基础镜像更新了,部署上去容器直接起不来。后来我强制团队使用具体版本号,比如v1.2.3。 - 容器里不要跑多进程。一个容器最好只跑一个进程。比如你要用国密Nginx,那就单独一个容器跑Nginx,不要再把SM4加解密模块也塞进去。否则出了问题不好排查。
- 定期清理无用的镜像和容器。我见过有人磁盘空间被
none镜像吃光了。养成习惯,可以用docker system prune -f定期清理。 - 安全组和防火墙要仔细配置。Docker默认会修改iptables规则,如果不小心,可能会把宿主机暴露出去。尤其是国密相关的端口,一定要严格控制。
好,关于Docker的核心概念和架构,我们就先聊到这里。吃透这些,后面的实战部署才能顺风顺水。