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(公共仓库),但企业一般会搭建私有仓库,比如HarborNexus

推送镜像到仓库:

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,跑几个容器试试,你会爱上这种感觉的。