1、容器技术基础:Docker简介、Docker与传统虚拟化对比、Docker核心概念(镜像、容器、仓库)、Docker安装与配置
1.1 Docker是什么?为什么我们需要它?
说实话,我第一次接触Docker是在2015年。那时候公司有个Java应用,部署起来特别麻烦——环境不一致、依赖冲突、配置混乱。每次新同事入职,光搭开发环境就要折腾一整天。后来引入了Docker,这些问题基本都解决了。
Docker,说白了就是一个容器化引擎。它能把你的应用和它需要的所有依赖(代码、运行时、系统工具、库文件、配置文件)打包成一个标准化的单元,叫做容器。这个容器可以在任何安装了Docker的机器上运行,不管底层是什么操作系统。
你想想看,这解决了什么问题?
- 环境一致性:开发环境、测试环境、生产环境完全一致,再也不会出现「在我机器上能跑啊」这种尴尬情况。
- 快速部署:启动一个容器只需要秒级,比传统虚拟机快得多。
- 资源利用率高:容器共享宿主机内核,不需要像虚拟机那样每个都装一个完整的操作系统。
核心观点:Docker不是虚拟化技术的替代品,而是对虚拟化的一种补充和优化。它更轻量、更灵活、更适合微服务架构。
1.2 Docker与传统虚拟化对比
很多初学者会问:Docker和虚拟机到底有什么区别?我当年也困惑过。这里我画个对比表,一目了然。
| 对比维度 | 传统虚拟机 | Docker容器 |
|---|---|---|
| 启动速度 | 分钟级(需要启动完整OS) | 秒级(共享宿主机内核) |
| 资源占用 | 高(每个VM有完整OS) | 低(共享内核,只包含应用层) |
| 隔离性 | 强(硬件级虚拟化) | 中等(进程级隔离,依赖Linux Namespace) |
| 镜像大小 | GB级别(包含完整OS) | MB级别(只包含应用和依赖) |
| 部署密度 | 一台物理机部署几个VM | 一台物理机部署几十上百个容器 |
| 迁移性 | 较复杂(依赖Hypervisor) | 简单(Dockerfile + 镜像仓库) |
嗯,这里要注意一点:隔离性。虚拟机是硬件级别的隔离,安全性更高。而Docker容器共享宿主机内核,如果内核有漏洞,所有容器都可能受影响。所以生产环境中,我建议不要用Docker跑那些对安全性要求极高的应用,或者配合安全加固措施。
个人经验:我在项目中遇到过这样的情况——用Docker跑数据库。虽然技术上可行,但我不推荐。数据库需要持久化存储、高性能IO,容器化后反而增加了复杂度。除非你用了Kubernetes的StatefulSet和持久卷,否则还是老老实实用虚拟机吧。
1.3 Docker核心概念:镜像、容器、仓库
这三个概念是Docker的基石。我习惯用一个类比来理解:
- 镜像(Image):就像是一个类(Class),是静态的、只读的模板。
- 容器(Container):就像是一个实例(Instance),是镜像运行时的动态实体。
- 仓库(Registry):就像是一个代码仓库(GitHub),用来存储和分发镜像。
1.3.1 镜像(Image)
镜像是Docker的核心产物。它是一个分层结构的文件系统,包含了运行应用所需的一切。你可以通过Dockerfile来定义镜像的构建过程。
举个例子,一个简单的Nginx镜像的Dockerfile:
# 使用官方Nginx镜像作为基础
FROM nginx:alpine
# 复制自定义配置文件
COPY nginx.conf /etc/nginx/nginx.conf
# 复制静态资源
COPY ./html /usr/share/nginx/html
# 暴露端口
EXPOSE 80
# 启动命令
CMD ["nginx", "-g", "daemon off;"]
构建镜像的命令:
docker build -t my-nginx:1.0 .
这里-t是给镜像打标签,my-nginx:1.0表示镜像名和版本号,最后的.表示Dockerfile所在的目录。
避坑指南:我曾经犯过一个错误——把密码硬编码在Dockerfile里。后来镜像被推送到公共仓库,密码就泄露了。记住:永远不要在镜像中存储敏感信息。用环境变量或者Secret管理工具。
1.3.2 容器(Container)
容器是镜像的运行实例。你可以启动、停止、删除、暂停容器。每个容器都是隔离的,有自己的文件系统、网络栈、进程空间。
启动容器的命令:
docker run -d --name my-web -p 8080:80 my-nginx:1.0
参数说明:
-d:后台运行(detached模式)--name:给容器起个名字-p:端口映射,宿主机8080端口映射到容器80端口
查看运行中的容器:
docker ps
进入容器内部:
docker exec -it my-web /bin/sh
嗯,这里有个小技巧:如果容器里没有/bin/sh,可以试试/bin/bash。Alpine镜像默认只有sh。
1.3.3 仓库(Registry)
仓库用来存储和分发镜像。最常用的是Docker Hub(公共仓库),但企业一般会搭建私有仓库,比如Harbor或Nexus。
推送镜像到仓库:
docker tag my-nginx:1.0 myregistry.com/my-nginx:1.0
docker push myregistry.com/my-nginx:1.0
拉取镜像:
docker pull myregistry.com/my-nginx:1.0
个人习惯:我建议团队使用私有仓库,并开启镜像扫描功能。这样可以避免使用有漏洞的基础镜像。另外,镜像命名规范也很重要,比如项目名/服务名:版本号,方便管理。
1.4 Docker安装与配置
安装Docker其实很简单。我以Ubuntu 20.04为例,其他Linux发行版大同小异。
1.4.1 安装Docker Engine
# 更新包索引
sudo apt update
# 安装依赖
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 添加Docker仓库
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# 安装Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
# 启动Docker并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker
# 验证安装
sudo docker --version
1.4.2 配置非root用户运行Docker
默认情况下,运行Docker命令需要sudo。为了方便,可以把当前用户加入docker组:
sudo usermod -aG docker $USER
newgrp docker
然后重新登录,就可以直接运行docker ps了。
安全提醒:把用户加入docker组相当于给了root权限。因为docker组用户可以挂载宿主机目录、执行特权操作。生产环境中,我建议只给运维人员这个权限,普通开发人员不要加。
1.4.3 配置镜像加速器
国内访问Docker Hub比较慢,建议配置镜像加速器。以阿里云为例:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://你的加速器地址.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
验证加速器是否生效:
docker info | grep -A 1 "Registry Mirrors"
1.4.4 验证Docker是否正常工作
运行一个经典的Hello World容器:
docker run hello-world
如果看到类似下面的输出,说明Docker安装成功:
Hello from Docker!
This message shows that your installation appears to be working correctly.
避坑指南:我曾经在CentOS 7上安装Docker时,遇到过overlay2存储驱动的问题。默认的devicemapper性能很差。解决办法是在daemon.json中指定存储驱动:"storage-driver": "overlay2"。现在新版本的Docker默认就是overlay2,但老系统还是要注意。
小结
这一章我们聊了Docker的基本概念:它是什么、和虚拟机的区别、三大核心概念(镜像、容器、仓库),以及如何安装配置。说白了,Docker就是让你的应用「打包带走,随处运行」。下一章我们会深入Dockerfile的编写技巧,到时候我会分享一些我在项目中踩过的坑和优化经验。
记住:容器化不是银弹,但它确实是现代应用部署的最佳实践之一。开始动手吧,装个Docker,跑几个容器试试,你会爱上这种感觉的。