1. 容器技术基础:Docker核心概念、镜像与容器、Dockerfile编写、Docker Compose入门
1.1 Docker核心概念:为什么我们需要容器?
说实话,我刚接触容器技术那会儿,也觉得很玄乎。不就是个轻量级虚拟机吗?后来在项目中踩过坑才明白——完全不是一回事。
Docker的核心,说白了就是进程隔离。它利用Linux内核的Namespace和Cgroups技术,让每个应用跑在独立的"沙箱"里。这个沙箱,我们叫它容器。
我个人习惯把容器比作"快递盒":
- 镜像 = 快递盒的设计图纸(只读模板)
- 容器 = 实际打包好的快递(可读写运行实例)
- 仓库 = 快递中转站(镜像存储分发中心)
关键区别:镜像是一个静态文件,容器是它的运行态。你可以在同一台机器上跑10个Nginx容器,它们共享同一个镜像层,但各自独立运行。
1.2 镜像与容器:从拉取到运行
我记得第一次用Docker时,最震撼的就是docker pull的速度。几秒钟就能把整个应用环境拉下来,这在传统运维里简直不敢想。
来看一个最基础的流程:
# 拉取镜像
docker pull nginx:1.21
# 查看本地镜像
docker images
# 运行容器
docker run -d --name my-nginx -p 8080:80 nginx:1.21
# 查看运行中的容器
docker ps
# 进入容器内部
docker exec -it my-nginx bash
这里有个坑,我曾经吃过亏——容器内的进程默认以root运行。这在生产环境是安全隐患。我建议你始终指定用户:
docker run -d --user 1000:1000 nginx:1.21
注意:容器停止后,数据默认会丢失。如果你需要持久化数据,一定要用-v挂载卷或--mount绑定目录。
1.3 Dockerfile编写:从零构建镜像
写Dockerfile就像写菜谱。你得告诉Docker:用什么基础原料、加什么调料、最后怎么装盘。
来看一个我项目中常用的Node.js应用Dockerfile:
# 1. 选择基础镜像
FROM node:18-alpine
# 2. 设置工作目录
WORKDIR /app
# 3. 先复制依赖文件(利用缓存加速)
COPY package*.json ./
# 4. 安装依赖
RUN npm install --production
# 5. 复制源码
COPY . .
# 6. 暴露端口
EXPOSE 3000
# 7. 启动命令
CMD ["node", "server.js"]
为什么先复制package.json再复制源码?因为Docker构建时会缓存每一层。如果源码改了但依赖没变,npm install这层就不会重新执行。嗯,这个小技巧能帮你省下不少构建时间。
我的经验:尽量用alpine版本的基础镜像。它只有5MB左右,比完整版小10倍以上。生产环境能省不少磁盘和网络开销。
1.4 Docker Compose入门:多容器编排
单个容器好办,但真实项目往往需要多个服务配合——比如Web应用+数据库+缓存。你想想看,如果每个都手动docker run,那得多累?
Docker Compose就是来解决这个问题的。它用YAML文件定义整个应用栈:
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
- redis
environment:
- DB_HOST=db
- REDIS_HOST=redis
db:
image: postgres:14-alpine
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: secret
redis:
image: redis:7-alpine
volumes:
pgdata:
启动整个应用栈只需要一条命令:
docker-compose up -d
我曾经在一个微服务项目里,用Compose管理了12个服务。每次启动只需要docker-compose up,所有服务自动按依赖顺序启动。相比以前手动启动每个服务,效率提升了不止一个量级。
核心要点:Compose不是生产环境的编排工具(那是Kubernetes的事),但它对本地开发和CI/CD测试来说,绝对是最佳选择。
1.5 避坑指南:我踩过的那些坑
做容器化这几年,我总结了几条血泪教训:
- 镜像不要太大——我曾经把一个1.5GB的镜像推到仓库,结果同事拉取时等了20分钟。后来改用多阶段构建,缩小到200MB。
- 不要用latest标签——在项目里我坚持用具体版本号,比如
nginx:1.21.6而不是nginx:latest。否则某天基础镜像更新了,你的应用可能莫名其妙挂掉。 - 容器里不要存数据——容器随时可能被销毁重建。数据库这类有状态服务,一定要把数据挂载到宿主机或持久卷上。
- 日志要输出到stdout/stderr——Docker默认收集标准输出作为日志。如果你把日志写到文件里,
docker logs就看不到了。
嗯,这些坑我基本都踩过一遍。现在写Dockerfile时,脑子里会自动过一遍这些检查点。
1.6 本章小结
容器技术的核心就三件事:镜像构建、容器运行、编排管理。Docker让你能快速打包应用,Compose让你能轻松管理多服务。这些都是后续学习Kubernetes的基础。
下一章我们会深入Kubernetes的核心概念。到时候你会发现,很多Docker里的思路在K8s里都能找到对应——只是规模更大、能力更强。
公众号:蓝海资料掘金营,微信deep3321