# Linux 容器技术 - Docker、Kubernetes 与容器生态系统详解

URL: https://caijiao.org/linux/advanced/containerization
Source: docs/linux/advanced/containerization.md
Description: 全面介绍Linux容器技术的原理、实现和应用，包括Docker容器基础、镜像管理、容器编排、Kubernetes入门与进阶，以及容器安全与最佳实践。

## 1. 容器技术基础

### 1.1 容器技术概念与原理

容器技术是一种轻量级的虚拟化解决方案，它允许在隔离的环境中运行应用程序，同时共享宿主机的操作系统内核。与传统虚拟机相比，容器具有启动速度快、资源占用少、部署灵活等优势。

容器技术的核心原理包括：

- **命名空间（Namespaces）**：提供进程隔离，使容器内的进程看不到宿主机上的其他进程
- **控制组（Control Groups - cgroups）**：限制和隔离容器对CPU、内存、磁盘I/O等资源的使用
- **联合文件系统（Union File Systems）**：允许容器镜像采用分层结构存储，实现高效的镜像共享和复用
- **容器运行时**：负责容器的创建、启动、停止等生命周期管理

### 1.2 容器与虚拟机比较

| 特性 | 容器 | 虚拟机 |
|------|------|--------|
| 启动时间 | 秒级 | 分钟级 |
| 资源占用 | 低（共享内核） | 高（完整操作系统） |
| 隔离性 | 进程级别 | 硬件级别 |
| 镜像大小 | 通常几MB到几百MB | 通常几GB |
| 性能 | 接近原生 | 有虚拟化开销 |
| 部署密度 | 高（单机可部署数百个） | 低（单机通常几十个） |
| 管理复杂性 | 低 | 高 |

### 1.3 容器技术的优势与应用场景

**优势：**

- **快速部署**：容器可以在几秒钟内启动，大大加速了应用部署和扩展
- **环境一致性**：容器打包了应用及其依赖，可以在开发、测试和生产环境中保持一致
- **资源高效**：相比虚拟机，容器占用更少的CPU、内存和存储资源
- **微服务架构支持**：容器是微服务架构的理想运行环境，可以独立部署和扩展各个服务
- **CI/CD集成**：容器可以与持续集成/持续部署流程无缝集成，实现自动化部署

**应用场景：**

- **微服务架构**：将大型应用拆分为多个独立的微服务，每个服务运行在自己的容器中
- **DevOps实践**：实现开发、测试和生产环境的一致性，简化部署流程
- **多租户环境**：在共享基础设施上安全地隔离不同用户的应用
- **高弹性应用**：快速启动和扩展应用实例，应对流量波动
- **混合云和多云环境**：容器的一致性特性使其可以在不同的云平台和环境中无缝迁移

## 2. Docker容器基础

### 2.1 Docker安装与配置

**在Ubuntu/Debian系统上安装Docker：**

```bash
# 更新apt包索引
sudo apt-get update

# 安装必要的依赖包
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent 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"

# 再次更新apt包索引
sudo apt-get update

# 安装最新版Docker Engine和容器运行时
sudo apt-get install docker-ce docker-ce-cli containerd.io

# 验证Docker是否成功安装
sudo docker run hello-world
```

**在CentOS/RHEL系统上安装Docker：**

```bash
# 安装必要的依赖包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

# 设置Docker仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 安装Docker Engine和容器运行时
sudo yum install docker-ce docker-ce-cli containerd.io

# 启动Docker服务
sudo systemctl start docker

# 设置Docker开机自启
sudo systemctl enable docker

# 验证Docker是否成功安装
sudo docker run hello-world
```

**在macOS上安装Docker Desktop：**

1. 访问 [Docker官方网站](https://www.docker.com/products/docker-desktop) 下载Docker Desktop for Mac
2. 打开下载的.dmg文件并将Docker图标拖到Applications文件夹
3. 从Applications文件夹启动Docker Desktop

**在Windows上安装Docker Desktop：**

1. 访问 [Docker官方网站](https://www.docker.com/products/docker-desktop) 下载Docker Desktop for Windows
2. 运行安装程序并按照向导完成安装
3. 安装完成后，启动Docker Desktop

### 2.2 Docker核心概念

Docker有几个核心概念，理解这些概念对于使用Docker至关重要：

**镜像（Image）：**
Docker镜像是一个只读模板，包含了运行应用所需的所有文件、依赖和配置。镜像采用分层结构存储，可以通过Dockerfile构建。

**容器（Container）：**
容器是镜像的运行实例，可以被创建、启动、停止、删除和暂停。每个容器都是相互隔离的，拥有自己的文件系统、网络和进程空间。

**仓库（Repository）：**
Docker仓库是存储和分发Docker镜像的地方，类似于代码仓库。Docker Hub是官方的公共仓库，用户也可以创建私有仓库。

**Dockerfile：**
Dockerfile是一个包含构建Docker镜像指令的文本文件，通过docker build命令可以从Dockerfile构建镜像。

**Docker Compose：**
Docker Compose是一个工具，用于定义和运行多容器Docker应用。通过docker-compose.yml文件，可以配置应用的服务、网络和卷等。

### 2.3 Docker常用命令

**镜像管理命令：**

```bash
# 拉取镜像
docker pull ubuntu:20.04

# 列出本地镜像
docker images

# 构建镜像
docker build -t myapp:latest .

# 标记镜像
docker tag myapp:latest username/myapp:latest

# 推送镜像到仓库
docker push username/myapp:latest

# 删除镜像
docker rmi myapp:latest

# 导出镜像为tar文件
docker save -o myapp.tar myapp:latest

# 从tar文件导入镜像
docker load -i myapp.tar
```

**容器管理命令：**

```bash
# 运行容器
docker run -d --name mycontainer -p 80:80 nginx

# 列出运行中的容器
docker ps

# 列出所有容器（包括已停止的）
docker ps -a

# 启动容器
docker start mycontainer

# 停止容器
docker stop mycontainer

# 重启容器
docker restart mycontainer

# 查看容器日志
docker logs mycontainer

# 进入容器内部
docker exec -it mycontainer bash

# 复制文件到容器
docker cp file.txt mycontainer:/path/to/destination

# 从容器复制文件
docker cp mycontainer:/path/to/file.txt .

# 删除容器
docker rm mycontainer

# 删除所有已停止的容器
docker container prune
```

**网络管理命令：**

```bash
# 列出网络
docker network ls

# 创建网络
docker network create mynetwork

# 连接容器到网络
docker network connect mynetwork mycontainer

# 断开容器与网络的连接
docker network disconnect mynetwork mycontainer

# 删除网络
docker network rm mynetwork
```

**数据卷管理命令：**

```bash
# 创建数据卷
docker volume create myvolume

# 列出数据卷
docker volume ls

# 查看数据卷详情
docker volume inspect myvolume

# 删除数据卷
docker volume rm myvolume

# 删除未使用的数据卷
docker volume prune
```

### 2.4 Docker镜像构建

Docker镜像可以通过Dockerfile构建，以下是一个基本的Dockerfile示例：

```dockerfile
# 指定基础镜像
FROM node:14-alpine

# 设置工作目录
WORKDIR /app

# 复制package.json和package-lock.json文件
COPY package*.json ./

# 安装依赖
RUN npm install

# 复制应用代码
COPY . .

# 暴露应用端口
EXPOSE 3000

# 设置环境变量
ENV NODE_ENV=production

# 定义启动命令
CMD ["node", "server.js"]
```

构建镜像：

```bash
docker build -t mynodeapp:latest .
```

常用的Dockerfile指令：

- `FROM`：指定基础镜像
- `WORKDIR`：设置工作目录
- `COPY`：复制文件到镜像
- `ADD`：复制文件到镜像（支持URL和自动解压）
- `RUN`：在镜像构建过程中执行命令
- `EXPOSE`：声明容器监听的端口
- `ENV`：设置环境变量
- `ARG`：定义构建参数
- `VOLUME`：创建挂载点
- `CMD`：指定容器启动命令（可以被docker run命令覆盖）
- `ENTRYPOINT`：指定容器入口点（通常不被覆盖）
- `LABEL`：添加元数据标签
- `USER`：设置运行容器的用户
- `HEALTHCHECK`：定义健康检查命令

## 3. Docker网络与存储

### 3.1 Docker网络模式

Docker提供了多种网络模式，适应不同的应用场景：

**bridge模式（默认）：**
默认的网络模式，为容器创建独立的网络命名空间，容器通过虚拟网桥与宿主机通信。

```bash
# 运行容器使用bridge网络
docker run --network bridge nginx
```

**host模式：**
容器共享宿主机的网络命名空间，没有网络隔离，性能最好但隔离性最差。

```bash
# 运行容器使用host网络
docker run --network host nginx
```

**none模式：**
容器有自己的网络命名空间，但没有配置网络接口，完全隔离。

```bash
# 运行容器使用none网络
docker run --network none nginx
```

**container模式：**
共享另一个容器的网络命名空间，两个容器可以通过localhost通信。

```bash
# 先运行一个容器
container_id=$(docker run -d nginx)

# 运行第二个容器，共享第一个容器的网络
docker run --network container:$container_id busybox ping localhost
```

**自定义网络：**
用户可以创建自定义网络，支持多种驱动类型，提供更好的隔离和DNS解析。

```bash
# 创建自定义bridge网络
docker network create mynetwork

# 运行容器使用自定义网络
docker run --network mynetwork nginx
```

### 3.2 Docker存储卷

Docker提供了多种数据持久化方案，其中存储卷是最常用的方式：

**数据卷（Volumes）：**
由Docker管理的存储卷，存储在宿主机的特定目录中，最适合持久化数据。

```bash
# 创建数据卷
docker volume create myvolume

# 挂载数据卷到容器
docker run -d -v myvolume:/data nginx
```

**绑定挂载（Bind mounts）：**
将宿主机的任意目录或文件挂载到容器中，灵活性高但依赖于宿主机的文件系统结构。

```bash
# 挂载宿主机目录到容器
docker run -d -v /host/path:/container/path nginx
```

**tmpfs挂载（tmpfs mounts）：**
数据存储在宿主机的内存中，容器停止后数据丢失，适合临时数据。

```bash
# 使用tmpfs挂载
docker run -d --tmpfs /data nginx
```

### 3.3 Docker Compose网络配置

Docker Compose简化了多容器应用的网络配置：

```yaml
version: '3'
services:
  web:
    image: nginx
    ports:
      - "80:80"
    networks:
      - frontend
      - backend
  db:
    image: postgres
    environment:
      - POSTGRES_PASSWORD=password
    volumes:
      - db_data:/var/lib/postgresql/data
    networks:
      - backend
networks:
  frontend:
  backend:
volumes:
  db_data:
```

启动应用：

```bash
docker-compose up -d
```

在默认情况下，Docker Compose会为应用创建一个自定义网络，同一网络中的服务可以通过服务名相互访问。

## 4. Docker容器编排

### 4.1 Docker Swarm基础

Docker Swarm是Docker原生的容器编排工具，可以将多个Docker主机组成一个集群，实现容器的编排和管理：

**初始化Swarm集群：**

```bash
# 在管理节点上初始化Swarm
docker swarm init --advertise-addr <MANAGER-IP>
```

**加入工作节点：**

```bash
# 在工作节点上运行（命令从管理节点获取）
docker swarm join --token <TOKEN> <MANAGER-IP>:2377
```

**查看节点：**

```bash
# 在管理节点上查看所有节点
docker node ls
```

**部署服务：**

```bash
# 创建服务并设置副本数为3
docker service create --name web --replicas 3 -p 80:80 nginx

# 查看服务状态
docker service ls
docker service ps web

# 扩展服务
docker service scale web=5

# 更新服务
docker service update --image nginx:latest web

# 删除服务
docker service rm web
```

### 4.2 Docker Stack部署

Docker Stack允许通过Compose文件部署多服务应用到Swarm集群：

**docker-compose.yml文件：**

```yaml
version: '3'
services:
  web:
    image: nginx:latest
    deploy:
      replicas: 3
      restart_policy:
        condition: on-failure
    ports:
      - "80:80"
    networks:
      - webnet
  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]
    networks:
      - webnet
networks:
  webnet:
```

**部署Stack：**

```bash
# 部署Stack
docker stack deploy -c docker-compose.yml myapp

# 查看Stack中的服务
docker stack services myapp

# 查看Stack中运行的任务
docker stack ps myapp

# 删除Stack
docker stack rm myapp
```

### 4.3 Kubernetes基础

Kubernetes（简称K8s）是一个开源的容器编排平台，可以自动化容器的部署、扩展和管理。虽然比Docker Swarm复杂，但功能更强大，生态系统更丰富。

**Kubernetes核心概念：**

- **Pod**：Kubernetes的基本部署单元，可以包含一个或多个容器
- **Service**：定义了访问一组Pod的方式，提供负载均衡
- **Deployment**：管理无状态应用的部署，可以自动扩展和更新Pod
- **StatefulSet**：管理有状态应用的部署
- **DaemonSet**：确保每个节点上运行一个Pod副本
- **ConfigMap**：存储非敏感配置数据
- **Secret**：存储敏感数据
- **Volume**：提供数据持久化
- **Namespace**：将集群资源划分为多个虚拟集群

**Minikube安装（本地开发）：**

```bash
# 安装Minikube（单节点Kubernetes集群，用于开发测试）
# 参考官方文档：https://minikube.sigs.k8s.io/docs/start/

# 启动Minikube集群
minikube start

# 检查集群状态
minikube status
```

**kubectl基础命令：**

```bash
# 查看集群信息
kubectl cluster-info

# 查看节点
kubectl get nodes

# 部署应用
kubectl apply -f deployment.yaml

# 查看部署
kubectl get deployments

# 查看Pod
kubectl get pods

# 查看服务
kubectl get services

# 查看日志
kubectl logs <pod-name>

# 进入Pod
kubectl exec -it <pod-name> -- bash
```

## 5. Kubernetes入门与进阶

### 5.1 Kubernetes核心组件

Kubernetes集群由控制平面和工作节点组成：

**控制平面组件：**

- **kube-apiserver**：API服务器，集群的前端接口
- **etcd**：分布式键值存储，保存集群状态
- **kube-scheduler**：调度器，负责将Pod调度到合适的节点
- **kube-controller-manager**：控制器管理器，包含多种控制器
  - 节点控制器：负责监控节点状态
  - 副本控制器：负责维护Pod的副本数量
  - 端点控制器：维护Service和Pod的映射关系
  - 服务账号控制器：管理服务账号和令牌

**工作节点组件：**

- **kubelet**：在每个节点上运行，管理Pod和容器
- **kube-proxy**：网络代理，维护网络规则
- **容器运行时**：负责容器的运行，如Docker、containerd等

### 5.2 Kubernetes资源配置

Kubernetes使用YAML或JSON格式的配置文件定义资源：

**Deployment示例：**

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: "1"
            memory: "1Gi"
          requests:
            cpu: "500m"
            memory: "512Mi"
```

**Service示例：**

```yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
  type: LoadBalancer
```

**ConfigMap示例：**

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  config.json: |
    {
      "api_url": "https://api.example.com",
      "debug": "false",
      "timeout": "30s"
    }
  loglevel: "info"
```

**Secret示例：**

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  username: dXNlcm5hbWU=
  password: cGFzc3dvcmQ=
```

### 5.3 Kubernetes网络模型

Kubernetes网络模型要求：

1. 每个Pod都有一个唯一的IP地址
2. Pod可以通过IP地址相互通信，无需NAT
3. 节点上的代理可以与所有Pod通信

Kubernetes支持多种网络插件，包括：

- **Calico**：基于BGP的网络方案，提供高性能网络和网络策略
- **Flannel**：简单易用的网络方案，适合初学者
- **Cilium**：基于eBPF的高性能网络方案，支持高级网络策略
- **Weave Net**：自配置的网络方案，适合多集群环境

**使用网络插件：**

```bash
# 例如，使用kubectl安装Calico
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
```

### 5.4 Kubernetes存储管理

Kubernetes提供了多种存储选项：

**Volume类型：**

- **emptyDir**：临时卷，Pod删除时数据丢失
- **hostPath**：使用节点上的文件或目录
- **PersistentVolumeClaim**：持久化存储声明，引用PersistentVolume
- **ConfigMap/Secret**：配置和密钥卷
- **云存储卷**：如AWS EBS、GCE PD、Azure Disk等

**PersistentVolume和PersistentVolumeClaim示例：**

**PV定义：**
```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: "/mnt/data"
```

**PVC定义：**
```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
```

**在Pod中使用PVC：**
```yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - mountPath: "/data"
      name: my-storage
  volumes:
  - name: my-storage
    persistentVolumeClaim:
      claimName: my-pvc
```

### 5.5 Kubernetes高级功能

**网络策略：**
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: nginx-policy
spec:
  podSelector:
    matchLabels:
      app: nginx
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 80
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: database
    ports:
    - protocol: TCP
      port: 5432
```

**自动扩缩容：**
```yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-deployment
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
```

**滚动更新：**
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  # ...其余配置
```

## 6. 容器安全

### 6.1 容器安全基础

容器安全是容器化应用中的重要考虑因素，涉及多个层面：

**镜像安全：**
- 使用官方或可信来源的基础镜像
- 定期更新镜像以修复安全漏洞
- 扫描镜像中的安全漏洞
- 最小化镜像大小，减少攻击面

**容器运行时安全：**
- 以非root用户运行容器
- 限制容器的系统调用
- 使用只读文件系统
- 限制容器的资源使用

**网络安全：**
- 使用网络策略限制容器间通信
- 加密容器间的通信
- 避免使用host网络模式
- 使用TLS加密外部流量

**编排平台安全：**
- 限制API服务器访问
- 使用RBAC（基于角色的访问控制）
- 定期审计集群配置
- 保护敏感数据（如Secret）

### 6.2 镜像安全扫描

使用工具扫描Docker镜像中的安全漏洞：

**使用Trivy扫描镜像：**

```bash
# 安装Trivy
sudo apt-get install wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy

# 扫描镜像
trivy image nginx:latest

# 生成HTML报告
trivy image --format html --output report.html nginx:latest
```

**使用Clair扫描镜像：**

```bash
# 使用Docker Compose启动Clair
wget https://raw.githubusercontent.com/quay/clair/master/docker-compose.yaml
docker-compose up -d

# 使用clairctl客户端扫描镜像
clairctl report nginx:latest
```

### 6.3 容器安全最佳实践

**安全的Dockerfile编写：**

```dockerfile
# 使用特定版本标签而非latest
FROM node:14.17.3-alpine

# 创建非root用户
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

# 设置工作目录
WORKDIR /app

# 复制必要文件并安装依赖
COPY package*.json ./
RUN npm ci --only=production

# 复制应用代码
COPY --chown=appuser:appgroup . .

# 以非root用户运行
USER appuser

# 限制容器能力
CAP_DROP: ["ALL"]

# 设置只读文件系统
VOLUME ["/app/data"]

# 暴露应用端口
EXPOSE 3000

# 设置启动命令
CMD ["node", "server.js"]
```

**安全的容器运行：**

```bash
# 以非特权模式运行
docker run --user 1000:1000 nginx

# 限制容器能力
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx

# 使用只读文件系统
docker run --read-only -v /tmp nginx

# 限制资源使用
docker run --memory="512m" --cpus="0.5" nginx

# 启用内容信任
export DOCKER_CONTENT_TRUST=1
```

**Kubernetes安全配置：**

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.19.10
    securityContext:
      runAsNonRoot: true
      runAsUser: 1000
      runAsGroup: 1000
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop: ["ALL"]
        add: ["NET_BIND_SERVICE"]
    resources:
      limits:
        cpu: "500m"
        memory: "512Mi"
      requests:
        cpu: "200m"
        memory: "256Mi"
  securityContext:
    fsGroup: 1000
    supplementalGroups: [1001]
```

## 7. 容器监控与日志管理

### 7.1 容器监控方案

容器监控是确保应用可靠性和性能的关键，可以使用多种工具：

**Prometheus + Grafana：**

```bash
# 使用Helm安装Prometheus和Grafana（在Kubernetes中）
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack
```

**使用cAdvisor监控容器资源使用：**

```bash
# 在Docker中，cAdvisor已集成到Docker Engine中
# 访问 http://localhost:8080/metrics 获取监控指标

# 在独立模式下运行cAdvisor
docker run --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  gcr.io/cadvisor/cadvisor:latest
```

**使用Metrics Server获取Kubernetes资源指标：**

```bash
# 安装Metrics Server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# 查看节点和Pod的资源使用情况
kubectl top nodes
kubectl top pods
```

### 7.2 容器日志管理

容器日志管理对于故障排查和性能监控至关重要：

**Docker日志管理：**

```bash
# 查看容器日志
docker logs mycontainer

# 跟踪日志输出
docker logs -f mycontainer

# 限制日志大小和文件数量（编辑docker daemon.json）
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
```

**Kubernetes日志管理：**

```bash
# 查看Pod日志
kubectl logs mypod

# 查看Pod中特定容器的日志
kubectl logs mypod -c mycontainer

# 跟踪日志输出
kubectl logs -f mypod
```

**使用ELK Stack收集和分析日志：**

```yaml
# 使用Helm安装ELK Stack（在Kubernetes中）
helm repo add elastic https://helm.elastic.co
helm repo update
helm install elasticsearch elastic/elasticsearch --set replicas=1
helm install kibana elastic/kibana --set elasticsearchHosts=http://elasticsearch-master:9200
helm install filebeat elastic/filebeat --set kubernetes.enabled=true
```

### 7.3 性能监控与告警

设置性能监控和告警可以及时发现和解决问题：

**Prometheus告警规则示例：**

```yaml
groups:
- name: container_alerts
  rules:
  - alert: ContainerHighCpuUsage
    expr: sum(rate(container_cpu_usage_seconds_total{container!=""}[5m])) by (pod, container) > 0.8
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High CPU usage ({{ $labels.pod }}/{{ $labels.container }})"
      description: "Container CPU usage is above 80% for 5 minutes.\n  VALUE = {{ $value }}\n  LABELS: {{ $labels }}"
  
  - alert: ContainerHighMemoryUsage
    expr: container_memory_usage_bytes{container!=""} / container_spec_memory_limit_bytes{container!=""} > 0.9
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High memory usage ({{ $labels.pod }}/{{ $labels.container }})"
      description: "Container memory usage is above 90% of limit for 5 minutes.\n  VALUE = {{ $value | humanizePercentage }}\n  LABELS: {{ $labels }}"
```

**Grafana仪表板：**
- 容器资源使用情况仪表板（ID: 8563）
- Kubernetes集群监控仪表板（ID: 10856）
- Docker监控仪表板（ID: 893）

## 8. 容器最佳实践

### 8.1 Dockerfile最佳实践

编写高效、安全的Dockerfile：

1. **使用多阶段构建减小镜像大小**：

```dockerfile
# 构建阶段
FROM node:14-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# 运行阶段
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```

2. **合理排序指令利用构建缓存**：

```dockerfile
FROM node:14-alpine
WORKDIR /app

# 先复制依赖文件并安装，利用缓存
COPY package*.json ./
RUN npm ci

# 再复制代码，这样修改代码不会导致依赖重新安装
COPY . .

# 构建应用
RUN npm run build

EXPOSE 3000
CMD ["npm", "start"]
```

3. **最小化层数**：

```dockerfile
FROM alpine:3.14

# 合并多个RUN命令减少层数
RUN apk --no-cache add nginx php php-fpm && \
    mkdir -p /run/nginx && \
    rm -f /etc/nginx/conf.d/default.conf

COPY nginx.conf /etc/nginx/conf.d/
COPY index.php /var/www/html/

EXPOSE 80
CMD ["sh", "-c", "php-fpm & nginx -g 'daemon off;'\
