容器与编排 (Containers & Orchestration)
一、容器概述
什么是容器
容器:在操作系统层面虚拟化,共享内核的轻量级"虚拟机"
- 进程级隔离
- 共享宿主机 OS
- 比 VM 启动快、体积小
- 主流实现:Docker、containerd、CRI-O、Podman
容器 vs 虚拟机
| 维度 | 容器 | 虚拟机 |
|---|---|---|
| 启动 | 毫秒-秒 | 秒-分钟 |
| 大小 | MB | GB |
| 性能 | 接近原生 | 接近原生(2-5% 损耗) |
| 隔离 | 进程级(较弱) | 系统级(强) |
| 启动密度 | 100-1000/机 | 10-50/机 |
| OS | 共享宿主 | 独立 OS |
| 镜像 | 几 MB-几 GB | 几 GB-几 TB |
| 适用 | 微服务、CI/CD | 多 OS、强隔离 |
容器发展史
2000s - chroot, FreeBSD Jails
2008 - LXC (Linux Containers)
2013 - Docker 出现(基于 LXC)
2014 - Rocket、rkt
2015 - Kubernetes 1.0
2015 - CNCF 成立
2016+ - 容器编排大战
2018+ - K8s 成为事实标准
2020s - 云原生, eBPF, 服务网格
二、容器底层技术
1. Linux 内核特性
容器是基于Linux 内核的进程隔离机制,不是真正的"容器"。
关键技术: - Namespaces: 资源隔离(进程、网络、文件系统等) - Cgroups: 资源限制(CPU、内存、IO) - Union FS: 镜像分层(ausfs、overlay2) - Capabilities: 权限细分
详见 02-层次结构.md 第九节 (虚拟化与容器时代的层次结构)
2. Namespaces
| 类型 | 隔离内容 |
|---|---|
| PID | 进程 ID |
| Network | 网络 |
| Mount | 文件系统挂载 |
| UTS | 主机名 |
| IPC | 进程间通信 |
| User | 用户和组 |
| Cgroup | cgroup 根 |
| Time | 时钟 (Linux 5.6+) |
查看进程的命名空间:
ls -l /proc/$$/ns/
readlink /proc/$$/ns/pid
创建命名空间:
unshare -p -n -m -f bash # 新的 PID + Network + Mount + Fork
nsenter -t PID -p -n -m bash # 进入已存在的命名空间
3. Cgroups (v1 vs v2)
Cgroup v1:每个资源独立挂载点
- /sys/fs/cgroup/cpu/
- /sys/fs/cgroup/memory/
- /sys/fs/cgroup/blkio/
Cgroup v2 (统一层次):
- /sys/fs/cgroup/cgroup.subtree_control
- 启用控制器: echo "+cpu +memory" > cgroup.subtree_control
cgroup 操作:
# 创 cgroup
mkdir /sys/fs/cgroup/myapp
# 限制 CPU
echo 100000 > /sys/fs/cgroup/myapp/cpu.max # 100ms / 100ms = 1 核
# 限制内存
echo 1G > /sys/fs/cgroup/myapp/memory.max
# 限制 IO
echo "253:0 1048576" > /sys/fs/cgroup/myapp/io.max # 1MB/s
# 加进程
echo 1234 > /sys/fs/cgroup/myapp/cgroup.procs
4. 联合文件系统 (Union FS)
Union FS:多个目录"叠加"成一个,只读层 + 可写层
驱动: - aufs: 旧版 Docker 默认 - overlay2: 现代推荐 - btrfs / zfs: 高端选择 - vfs: 不支持分层(慢)
镜像分层:
Layer 4 (可写) <- 容器运行时修改
Layer 3 (只读) <- RUN 命令
Layer 2 (只读) <- apt-get install
Layer 1 (只读) <- COPY ./app
Layer 0 (只读) <- FROM ubuntu
三、Docker
1. Docker 架构
Docker Client (CLI)
↓ REST API
Docker Daemon (dockerd)
↓
containerd → runC → 容器
↓
Linux 内核 (Namespaces, Cgroups, Union FS)
2. Docker 安装
# RHEL/CentOS
yum install docker
systemctl enable --now docker
# Debian/Ubuntu
apt install docker.io
systemctl enable --now docker
# 验证
docker --version
docker run hello-world
3. Docker 命令速查
# 镜像
docker search nginx # 搜索
docker pull nginx:latest # 拉取
docker images # 列表
docker rmi nginx # 删除
docker tag nginx mynginx:1.0 # 标签
docker save -o n.tar nginx # 导出
docker load -i n.tar # 导入
docker image prune # 清理悬空镜像
docker image ls --digests # 显示 digest
# 容器
docker run nginx # 启动(前台)
docker run -d nginx # 后台
docker run -it ubuntu bash # 交互
docker run -p 80:80 nginx # 端口映射
docker run -v /data:/data nginx # 挂载卷
docker run --name web nginx # 命名
docker run --rm nginx # 退出后删除
docker run --network host nginx # host 网络
docker run --restart always nginx # 自动重启
docker ps # 看运行
docker ps -a # 全部
docker logs nginx # 日志
docker exec -it nginx bash # 进入
docker stop nginx # 优雅停
docker kill nginx # 强制停
docker restart nginx
docker rm nginx # 删除
docker rm -f nginx # 强制删
docker top nginx # 进程
docker stats nginx # 资源
docker inspect nginx # 详细信息
docker port nginx # 端口
docker diff nginx # 改了哪些文件
docker cp file nginx:/path # 拷贝
# 网络
docker network ls
docker network create mynet
docker network inspect mynet
docker network connect mynet nginx
docker network disconnect mynet nginx
# 卷
docker volume ls
docker volume create myvol
docker volume rm myvol
docker volume inspect myvol
# 系统
docker system df # 占用
docker system prune # 清理
docker system info # 信息
4. Dockerfile 详解
Dockerfile 指令:
| 指令 | 作用 |
|---|---|
| FROM | 基础镜像 |
| LABEL | 标签 |
| ENV | 环境变量 |
| ARG | 构建参数 |
| WORKDIR | 工作目录 |
| USER | 用户 |
| VOLUME | 数据卷 |
| EXPOSE | 暴露端口 |
| COPY | 复制文件(本地) |
| ADD | 复制文件(支持 URL、tar) |
| RUN | 执行命令 |
| CMD | 容器启动命令(可被覆盖) |
| ENTRYPOINT | 入口点 |
| ONBUILD | 镜像作为基础镜像时触发 |
| STOPSIGNAL | 停止信号 |
| HEALTHCHECK | 健康检查 |
| SHELL | 默认 shell |
示例 (Node.js 应用):
# 多阶段构建
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 运行时镜像
FROM node:20-alpine
LABEL maintainer="alice@example.com"
ENV NODE_ENV=production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY package*.json ./
RUN npm ci --only=production
USER node
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/index.js"]
最佳实践: - 基础镜像用 alpine / distroless - 多阶段构建减小镜像 - 不用 root 运行 - 不在 Dockerfile 存密钥 - 用 .dockerignore - 合并 RUN 命令 - 利用层缓存
5. 镜像仓库
# 登录
docker login
docker login registry.example.com
docker login -u user registry.example.com
# tag
docker tag myapp:v1 registry.example.com/myapp:v1
# push
docker push registry.example.com/myapp:v1
# pull
docker pull registry.example.com/myapp:v1
镜像仓库: - Docker Hub: 官方 - GitHub Container Registry: ghcr.io - GitLab Container Registry: registry.gitlab.com - Harbor: 企业级 - Quay: Red Hat - AWS ECR / GCP Artifact Registry / Azure ACR
6. Docker Compose
docker-compose.yml 示例:
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html:ro
networks:
- frontend
depends_on:
- api
restart: always
environment:
- NGINX_HOST=example.com
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 3s
retries: 3
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
api:
build: ./api
image: myapi:v1
ports:
- "8080:8080"
environment:
- DB_HOST=db
networks:
- frontend
- backend
depends_on:
- db
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- backend
environment:
- POSTGRES_PASSWORD=secret
redis:
image: redis:7-alpine
networks:
- backend
volumes:
pgdata:
networks:
frontend:
backend:
docker compose up -d # 启动
docker compose down # 停止
docker compose ps # 状态
docker compose logs -f # 日志
docker compose exec web sh # 进入
docker compose build # 构建
7. Docker 调试
# 查容器信息
docker inspect web
# 进程
docker top web
# 资源
docker stats # 实时
docker stats --no-stream # 一次
# 日志
docker logs web
docker logs --tail 100 -f web
# 事件
docker events
# 进入调试
docker exec -it web sh
docker exec -u root -it web bash
8. Docker 安全
# 用普通用户
USER 1000
# 只读根文件系统
docker run --read-only nginx
# 限制能力
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx
# 禁用特权
docker run --security-opt no-new-privileges nginx
# 限制资源
docker run --cpus 0.5 --memory 512m nginx
# 用安全选项
docker run --security-opt seccomp=profile.json nginx
docker run --security-opt apparmor=docker-default nginx
# 镜像扫描
docker scan myapp
trivy image myapp
# 内容信任 (DCT)
export DOCKER_CONTENT_TRUST=1
四、容器生态
1. 容器运行时 (Runtime)
| 运行时 | 特点 |
|---|---|
| runc | 标准的 OCI 运行时 |
| containerd | 工业级,K8s 默认 |
| CRI-O | K8s 备用,Red Hat 推崇 |
| Podman | 守护进程可无,Red Hat 出品 |
| crun | C 实现,更快,Red Hat 8+ |
| Kata | 轻量 VM,强隔离 |
| gVisor | 用户态内核,沙箱 |
2. 容器工具
- buildah: 镜像构建
- skopeo: 镜像复制
- podman: 容器管理(无 daemon)
- buildkit: 下一代构建
- dive: 看镜像层
- crane: 操作镜像
3. 镜像工具
# buildah
buildah from alpine
buildah run alpine apk add curl
buildah commit myapp myapp:1.0
# skopeo
skopeo inspect docker://nginx
skopeo copy docker://src docker://dst
# dive
dive myapp:1.0
五、Kubernetes (K8s)
1. 什么是 K8s
Kubernetes (K8s):Google 开源的容器编排平台
- 自动化部署、扩缩容、运维
- 跨主机容器管理
- 服务发现、负载均衡
- 自愈能力
- 滚动更新、回滚
2. 架构
┌─────────────── Master/Control Plane ───────────────┐
│ ┌──────┐ ┌──────┐ ┌─────────┐ ┌─────────┐ ┌─────┐ │
│ │ API │ │Sched │ │ Controller│ │ etcd │ │ CM │ │
│ │Server│ │uler │ │ Manager │ │ KV │ │ │ │
│ └──┬───┘ └──┬───┘ └─────────┘ └─────────┘ └─────┘ │
└─────┼────────┼─────────────────────────────────────────┘
│ │
▼ ▼
┌──────── Worker Node ─────────┐
│ ┌────┐ ┌────┐ ┌────┐ │
│ │kubelet│ │kube-proxy│ │ │
│ └────┘ └────┘ └────┘ │
│ ┌───Container Runtime──┐ │
│ │ ┌──┐ ┌──┐ ┌──┐ │ │
│ │ │P1│ │P2│ │P3│ ... │ │
│ │ └──┘ └──┘ └──┘ │ │
│ └──────────────────────┘ │
└──────────────────────────────┘
3. 核心概念
(1) Pod
Pod:K8s 最小部署单位,1+ 个共享网络的容器
- 共享 PID、Network、IPC
- 共享存储卷
- 同一调度单元
- 同一生命周期
apiVersion: v1
kind: Pod
metadata:
name: myapp
labels:
app: myapp
spec:
containers:
- name: web
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3
periodSeconds: 3
readinessProbe:
httpGet:
path: /
port: 80
(2) Deployment
Deployment:Pod 的副本管理
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.25
ports:
- containerPort: 80
(3) Service
Service:为一组 Pod 提供稳定访问入口
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
type: ClusterIP # ClusterIP / NodePort / LoadBalancer / ExternalName
类型: - ClusterIP: 默认,仅集群内 - NodePort: 每个 Node 暴露端口 - LoadBalancer: 云 LB - ExternalName: CNAME
(4) Ingress
Ingress:HTTP/HTTPS 路由
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
tls:
- hosts:
- example.com
secretName: web-tls
(5) ConfigMap & Secret
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-config
data:
DB_HOST: db
DB_PORT: "5432"
---
apiVersion: v1
kind: Secret
metadata:
name: myapp-secret
type: Opaque
data:
# base64 编码
DB_PASSWORD: c2VjcmV0
stringData:
# 明文,会自动 base64
API_KEY: secret-api-key
(6) Volume
spec:
containers:
- name: web
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: my-pvc
PV / PVC / StorageClass:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 10Gi
storageClassName: standard
(7) Namespace
Namespace:虚拟集群,资源隔离
kubectl get ns
kubectl create ns dev
kubectl config set-context --current --namespace=dev
默认 namespace: - default - kube-system (系统组件) - kube-public - kube-node-lease
(8) StatefulSet
StatefulSet:有状态应用,稳定网络标识
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: db
spec:
serviceName: db
replicas: 3
selector:
matchLabels:
app: db
template:
metadata:
labels:
app: db
spec:
containers:
- name: db
image: postgres:16
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 10Gi
(9) DaemonSet
DaemonSet:每个 Node 跑一个 Pod
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
containers:
- name: exporter
image: prom/node-exporter
ports:
- containerPort: 9100
hostNetwork: true
(10) Job & CronJob
Job:一次性任务
apiVersion: batch/v1
kind: Job
metadata:
name: backup
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: backup:latest
CronJob:定时任务
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup
spec:
schedule: "0 2 * * *"
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: backup:latest
4. kubectl 命令
# 节点
kubectl get nodes
kubectl describe node node1
kubectl drain node1 # 维护前
kubectl uncordon node1 # 恢复
kubectl cordon node1 # 暂停调度
# Pod
kubectl get pods
kubectl get pods -A # 所有 namespace
kubectl get pods -o wide # 看 IP、Node
kubectl get pods -l app=web # 按 label
kubectl get pod mypod -o yaml # yaml 格式
kubectl describe pod mypod
kubectl logs mypod
kubectl logs -f mypod # 跟踪
kubectl logs mypod -c web # 特定容器
kubectl exec -it mypod bash
kubectl cp file mypod:/path # 拷贝
kubectl delete pod mypod
# Deployment
kubectl get deploy
kubectl scale deploy web --replicas=5
kubectl rollout status deploy web
kubectl rollout history deploy web
kubectl rollout undo deploy web # 回滚
kubectl rollout undo deploy web --to-revision=2
kubectl set image deploy web web=nginx:1.26
kubectl autoscale deploy web --min=2 --max=10 --cpu-percent=80
# Service
kubectl get svc
kubectl expose deploy web --port=80 --type=NodePort
kubectl get endpoints web
# 上下文
kubectl config get-contexts
kubectl config use-context prod
kubectl config set-context --current --namespace=dev
# 应用管理
kubectl apply -f deployment.yaml
kubectl apply -f ./manifests/
kubectl delete -f deployment.yaml
kubectl diff -f deployment.yaml # 看 diff
# 编辑
kubectl edit deploy web # 编辑
kubectl scale deploy web --replicas=5
kubectl patch deploy web -p '{"spec":{"replicas":10}}'
kubectl label pod mypod env=prod # 加 label
kubectl annotate pod mypod note=important
# 看资源
kubectl top nodes
kubectl top pods
# 调试
kubectl describe pod mypod
kubectl get events --sort-by=.metadata.creationTimestamp
kubectl logs -p mypod # 上一个实例
# 端口转发
kubectl port-forward pod/mypod 8080:80
kubectl port-forward svc/web 8080:80
# 进入容器
kubectl exec -it mypod -- bash
kubectl debug -it mypod --image=alpine # 临时调试容器
# 配置文件
kubectl apply -k ./kustomize/
5. K8s 架构组件
控制平面 (Control Plane)
- kube-apiserver: API 入口
- etcd: 分布式 KV 存储
- kube-scheduler: Pod 调度
- kube-controller-manager: 控制器
- cloud-controller-manager: 云厂商集成
Worker 节点
- kubelet: 节点 agent
- kube-proxy: 网络代理
- container runtime: 容器运行时 (containerd, CRI-O)
关键插件
- CNI: 网络(Flannel, Calico, Cilium)
- CSI: 存储
- CRI: 容器运行时
- DNS: CoreDNS
6. K8s 网络模型
- 每个 Pod 有独立 IP
- Pod 之间可以直接通信(无 NAT)
- 节点和 Pod 可以通信
- 容器间共享网络(同一 Pod)
CNI 插件: - Flannel: 简单 overlay - Calico: BGP, 网络策略 - Cilium: eBPF, 高性能 - Weave: 简单
7. K8s 安装
工具: - kubeadm: 官方 - kops: AWS - kubespary / kubespray: 通用 - Rancher (k3s / RKE2): 轻量 - Minikube / Kind: 本地开发
kubeadm 安装:
# 初始化 Master
kubeadm init --pod-network-cidr=10.244.0.0/16
# 配置 kubectl
mkdir -p $HOME/.kube
sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config
# 安装网络插件
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
# 加入 Worker
kubeadm join master:6443 --token xxx --discovery-token-ca-cert-hash yyy
8. K8s 实用操作
# HPA
kubectl autoscale deploy web --min=2 --max=10 --cpu-percent=80
# VPA (垂直扩缩)
# 需要 metrics-server + VPA
# 资源限制
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
# 健康检查
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
# 节点亲和
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values: [node1, node2]
# Pod 反亲和
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
app: web
# 污点容忍
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
六、容器网络
1. 网络模式
- Bridge (Docker 默认): 容器间隔离
- Host: 共享主机网络
- None: 无网络
- Container: 共享其他容器
- Overlay: 跨主机
- Macvlan: 物理网卡虚拟
2. K8s 网络
- Pod-to-Pod: CNI 负责
- Pod-to-Service: kube-proxy + iptables/IPVS
- External-to-Service: Ingress / LoadBalancer
3. CNI 插件
Calico: - BGP 路由 - 网络策略 - 高性能 - 企业首选
Cilium: - eBPF - 高性能 - 可观测性 - 云原生首选
Flannel: - 简单 - VXLAN - K8s 入门首选
七、容器存储
1. Docker Volume
- bind mount: 主机目录
- tmpfs: 内存
- named volume: 命名卷
- anonymous volume: 匿名卷(临时)
2. K8s 存储
- emptyDir: Pod 内临时
- hostPath: 主机路径
- PV/PVC: 持久卷
- StorageClass: 动态供给
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
fsType: ext4
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
3. CSI 驱动
云厂商的 CSI: - AWS EBS - GCP Persistent Disk - Azure Disk - 阿里云盘 - 腾讯云 CBS
分布式存储: - Rook-Ceph - Longhorn - OpenEBS - MinIO
八、容器安全
1. 镜像安全
- Trivy: 多平台
- Clair: Quay
- Snyk: 商业
- Docker Scout: 官方
- Anchore: 商业
trivy image myapp:1.0
trivy fs /path
trivy k8s cluster
2. 运行时安全
- Falco: CNCF,运行时入侵检测
- Tracee: eBPF-based
- Aqua: 商业
- Sysdig Secure: 商业
# Falco 规则示例
- rule: Unexpected process in container
desc: Detect unexpected process
condition: >
spawned_process and container and
not proc.name in (allowed_procs)
output: Unexpected process
3. 镜像签名
- Docker Content Trust (DCT)
- Cosign (Sigstore)
- Notary v2
# Cosign
cosign sign --key cosign.key myapp:1.0
cosign verify --key cosign.pub myapp:1.0
4. K8s 安全
- Pod Security Standards: privileged / baseline / restricted
- Network Policies: 网络隔离
- RBAC: 权限控制
- OPA / Kyverno: 策略引擎
# Network Policy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
九、容器注册中心 (Registry)
1. 主流 Registry
- Docker Hub: 公共
- Harbor: 企业级开源
- GitHub Container Registry: ghcr.io
- GitLab Container Registry
- Quay: Red Hat
- AWS ECR / GCP GAR / Azure ACR
- 阿里云 ACR / 腾讯云 TCR
- 华为云 SWR
2. Harbor
- 开源、企业级
- 镜像复制
- 漏洞扫描 (Trivy)
- 镜像签名
- 项目 / 用户管理
- Webhook
# 登录
docker login harbor.example.com
# Push
docker push harbor.example.com/myproject/myapp:1.0
# Pull
docker pull harbor.example.com/myproject/myapp:1.0
十、Podman
1. Podman vs Docker
- 无守护进程: 不需要 dockerd
- rootless: 普通用户跑容器
- systemd 集成: 容易管理
- OCI 兼容: 标准
- 兼容 docker CLI:
alias docker=podman
# 装
yum install podman
# 类似 docker
podman run -d nginx
podman ps
podman images
podman build -t myapp .
podman-compose up -d # 类似 docker compose
# rootless
podman unshare cat /proc/self/uid
十一、容器化最佳实践
1. 镜像
- 小镜像: alpine、distroless
- 多阶段构建: 减小镜像
- 不存密钥
- .dockerignore
- 固定版本: 不
latest - 定期更新
2. 容器
- 单进程: 一个容器一个主进程
- 不存状态: 容器是无状态的
- 配置外部化: 用环境变量、ConfigMap
- 健康检查: 加探针
- 资源限制: requests + limits
- 不用 root
- 只读根文件系统
3. K8s 部署
- 声明式: 用 YAML
- GitOps: 仓库管理
- 滚动更新: maxSurge=1, maxUnavailable=0
- 蓝绿 / 金丝雀: 渐进发布
- HPA / VPA / Cluster Autoscaler
- Network Policies
- RBAC
- 资源限制
十二、容器监控
1. cAdvisor (Container Advisor)
- 容器资源监控
- K8s 默认集成
- 暴露 :4194 端口
2. Prometheus + Grafana
# Prometheus Operator
helm install prometheus prometheus-community/kube-prometheus-stack
3. 商业方案
- Datadog: 全栈
- New Relic: APM
- Dynatrace: 自动发现
- Splunk: 日志
十三、容器 vs 虚拟化
| 维度 | 容器 | 虚拟机 |
|---|---|---|
| 启动 | 毫秒-秒 | 秒-分钟 |
| 镜像 | MB | GB |
| 性能 | 接近原生 | 接近原生 |
| 隔离 | 进程级 | 系统级 |
| OS | 共享 | 独立 |
| 启动密度 | 100-1000/机 | 10-50/机 |
| 适用 | 微服务 | 多 OS |
互补使用: - VM 跑 K8s - 容器跑微服务 - Kata Containers: 容器 + VM 强隔离 - gVisor: 沙箱
十四、核心要点速记
- 容器 = 进程隔离(Namespaces + Cgroups + Union FS)
- Docker = 容器运行时 + 镜像管理
- containerd = K8s 默认运行时
- K8s = 容器编排事实标准
- Pod = K8s 最小单位,共享网络
- Deployment = 无状态 Pod 副本
- StatefulSet = 有状态
- DaemonSet = 每 Node 跑一个
- Service = 稳定的访问入口
- Ingress = HTTP/HTTPS 路由
- ConfigMap / Secret = 配置
- HPA = 自动水平扩缩
- PV/PVC = 持久卷
- kubectl apply -f = 声明式
- kubectl get pods -A = 看所有
- kubectl logs -f = 跟踪
- kubectl exec -it = 进入
- kubectl port-forward = 端口转发
- kubectl rollout undo = 回滚
- kubectl describe = 排查
- Namespaces: 进程/网络/挂载/UTS/IPC/User
- Cgroups v2: 统一 /sys/fs/cgroup/
- Overlay2 = 现代联合 FS
- Virtio = 容器内推荐驱动
- CNI = 容器网络 (Calico/Cilium/Flannel)
- CSI = 容器存储
- Falco = 运行时安全
- Trivy = 镜像扫描
- Cosign = 镜像签名
- GitOps = 仓库即真理
- 多阶段构建 = 减小镜像
- 不存密钥 = 用 Secret/环境变量
- alpine / distroless = 小镜像
- 不用 root = USER 1000
- 资源限制 = requests + limits
- 健康检查 = liveness + readiness
- 镜像标签 = 用版本号,不 latest