Docker了解

1 阅读4分钟

什么是Docker?

Docker是一个开源的容器化平台,它允许开发者将应用程序及其依赖环境打包成一个轻量级、可移植的容器。与传统的虚拟机不同,Docker容器直接运行在宿主机的操作系统内核上,无需额外的操作系统层,因此启动更快、资源占用更少。

核心概念

  • 镜像(Image):只读模板,包含运行应用所需的代码、库、环境配置等
  • 容器(Container):镜像的运行实例,是独立、隔离的进程空间
  • 仓库(Registry):存储镜像的地方,如Docker Hub
  • Dockerfile:文本文件,定义如何构建镜像

为什么选择Docker?

1. 环境一致性

"在我机器上能跑,为什么到服务器就不行?"——这个经典问题在Docker时代得到解决。通过容器化,开发、测试、生产环境完全一致,避免了因环境差异导致的bug。

2. 快速部署与扩展

容器启动仅需秒级,远快于虚拟机。结合编排工具(如Kubernetes),可以实现应用的快速水平扩展和滚动更新。

3. 资源高效利用

多个容器共享宿主机内核,内存和CPU占用更少,同一台服务器可以运行更多应用实例。

4. 隔离与安全

每个容器拥有独立的文件系统、网络和进程空间,应用之间互不干扰,安全性更高。

快速开始:你的第一个Docker容器

安装Docker

以Ubuntu系统为例:

# 更新包索引
sudo apt-get update

# 安装必要依赖
sudo apt-get install 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-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

# 验证安装
sudo docker run hello-world

运行第一个容器

# 拉取Nginx镜像
docker pull nginx:latest

# 运行Nginx容器
docker run -d -p 80:80 --name my-nginx nginx

# 查看运行中的容器
docker ps

# 访问服务
curl http://localhost

Dockerfile实战:构建自定义镜像

创建一个简单的Node.js应用并容器化:

项目结构

my-app/
├── app.js
├── package.json
└── Dockerfile

app.js

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello Docker!')
})

app.listen(port, () => {
  console.log(`App listening on port ${port}`)
})

package.json

{
  "name": "my-app",
  "version": "1.0.0",
  "main": "app.js",
  "dependencies": {
    "express": "^4.18.2"
  }
}

Dockerfile

# 使用Node.js官方镜像作为基础镜像
FROM node:18-alpine

# 设置工作目录
WORKDIR /app

# 复制package.json和package-lock.json
COPY package*.json ./

# 安装依赖
RUN npm install

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

# 启动应用
CMD ["node", "app.js"]

构建和运行

# 构建镜像
docker build -t my-node-app .

# 运行容器
docker run -d -p 3000:3000 --name my-app my-node-app

# 测试应用
curl http://localhost:3000

Docker常用命令速查

命令说明示例
docker pull拉取镜像docker pull nginx
docker images列出本地镜像docker images
docker run运行容器docker run -d nginx
docker ps查看运行中的容器docker ps -a
docker stop停止容器docker stop container_id
docker rm删除容器docker rm container_id
docker rmi删除镜像docker rmi image_id
docker logs查看容器日志docker logs container_id
docker exec进入容器docker exec -it container_id /bin/bash
docker build构建镜像docker build -t my-image .

数据持久化:Volume与Bind Mount

容器默认是"无状态"的,重启后数据会丢失。为了持久化数据,Docker提供了两种方式:

1. Volume(推荐)

# 创建volume
docker volume create my-volume

# 运行容器并挂载volume
docker run -d -v my-volume:/data --name my-container nginx

# 查看volume
docker volume ls

2. Bind Mount(主机目录挂载)

# 将主机目录挂载到容器
docker run -d -v /host/path:/container/path nginx

网络管理

Docker提供多种网络模式:

  • bridge:默认模式,容器通过虚拟网桥通信
  • host:容器直接使用主机网络
  • none:无网络
  • 自定义网络:创建隔离的网络环境
# 创建自定义网络
docker network create my-network

# 运行容器并加入网络
docker run -d --network my-network --name app1 nginx
docker run -d --network my-network --name app2 nginx

# 容器间可以通过容器名通信
docker exec app1 ping app2

Docker Compose:多容器编排

对于复杂的多容器应用,使用Docker Compose可以简化管理:

docker-compose.yml

version: '3.8'
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
  app:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      - redis
  redis:
    image: redis:alpine

启动服务

# 启动所有服务
docker-compose up -d

# 停止服务
docker-compose down

生产环境最佳实践

1. 使用多阶段构建

减少镜像体积,提高安全性:

# 构建阶段
FROM node:18 AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build

# 生产阶段
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY package*.json ./
RUN npm install --production
EXPOSE 3000
CMD ["node", "dist/app.js"]

2. 使用非root用户运行

FROM node:18-alpine
RUN addgroup -g 1000 nodeuser && adduser -u 1000 -G nodeuser -s /bin/sh -D nodeuser
USER nodeuser
# ... 其他指令

3. 设置资源限制

# 限制内存和CPU
docker run -d --memory=512m --cpus=1 nginx

4. 使用.dockerignore文件

避免将不必要的文件复制到镜像中,加快构建速度:

node_modules
.git
*.log
.env