容器是一种轻量级的虚拟化技术,它将应用程序及其依赖(库、二进制文件、配置文件等)打包在一个独立的单元中,可以在任何支持容器运行时的环境中一致地运行。
Docker官网:https://www.docker.com/
与传统虚拟机相比,容器具有以下特点:
容器和虚拟机是两种不同的虚拟化技术,它们有以下主要区别:
特性 | 容器 | 虚拟机 |
---|---|---|
虚拟化级别 | 操作系统级虚拟化 | 硬件级虚拟化 |
内核 | 共享主机内核 | 每个VM有独立内核 |
资源开销 | 轻量级,MB级别 | 重量级,GB级别 |
启动时间 | 秒级 | 分钟级 |
隔离性 | 进程级隔离 | 完全隔离 |
安全性 | 相对较低 | 较高 |
性能 | 接近原生 | 有一定损耗 |
操作系统支持 | 限于主机内核兼容的OS | 几乎任何OS |
Linux容器技术基于以下几个核心内核特性:
命名空间提供了进程隔离的基础,Linux内核支持以下几种命名空间:
Cgroups允许限制和监控进程组使用的资源,包括:
联合文件系统允许将多个目录层叠在一起,形成一个统一的视图,是容器镜像分层存储的基础:
Seccomp限制容器内进程可以使用的系统调用,减少攻击面:
# 示例:使用seccomp配置文件启动容器
docker run --security-opt seccomp=/path/to/seccomp.json nginx
Linux Capabilities将传统的超级用户权限分解为更细粒度的权限集合,容器可以只获得必要的权限:
# 示例:移除所有能力并只添加必要的能力
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx
Docker是最流行的容器平台,它简化了容器的创建、部署和管理。
Docker采用客户端-服务器架构,主要组件包括:
在不同Linux发行版上安装Docker:
# 更新包索引
sudo apt update
# 安装依赖
sudo apt 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"
# 更新包索引
sudo apt update
# 安装Docker
sudo apt install docker-ce docker-ce-cli containerd.io
# 启动Docker服务
sudo systemctl start docker
sudo systemctl enable docker
# 验证安装
sudo docker run hello-world
# 安装依赖
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
sudo yum install docker-ce docker-ce-cli containerd.io
# 启动Docker服务
sudo systemctl start docker
sudo systemctl enable docker
# 验证安装
sudo docker run hello-world
# 安装依赖
sudo dnf -y install dnf-plugins-core
# 添加Docker仓库
sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
# 安装Docker
sudo dnf install docker-ce docker-ce-cli containerd.io
# 启动Docker服务
sudo systemctl start docker
sudo systemctl enable docker
# 验证安装
sudo docker run hello-world
# 搜索镜像
docker search nginx
# 拉取镜像
docker pull nginx:latest
# 列出本地镜像
docker images
# 删除镜像
docker rmi nginx:latest
# 构建镜像
docker build -t myapp:1.0 .
# 保存镜像到文件
docker save -o nginx.tar nginx:latest
# 从文件加载镜像
docker load -i nginx.tar
# 标记镜像
docker tag nginx:latest myregistry.com/nginx:v1
# 创建并启动容器
docker run -d --name webserver -p 80:80 nginx
# 列出运行中的容器
docker ps
# 列出所有容器(包括已停止的)
docker ps -a
# 启动/停止/重启容器
docker start webserver
docker stop webserver
docker restart webserver
# 删除容器
docker rm webserver
# 进入容器
docker exec -it webserver bash
# 查看容器日志
docker logs webserver
# 查看容器详细信息
docker inspect webserver
# 查看容器资源使用情况
docker stats webserver
# 创建数据卷
docker volume create mydata
# 列出数据卷
docker volume ls
# 查看数据卷详情
docker volume inspect mydata
# 删除数据卷
docker volume rm mydata
# 使用数据卷挂载
docker run -d --name db -v mydata:/var/lib/mysql mysql:5.7
# 使用主机目录挂载
docker run -d --name web -v /host/path:/container/path nginx
# 创建网络
docker network create mynetwork
# 列出网络
docker network ls
# 查看网络详情
docker network inspect mynetwork
# 删除网络
docker network rm mynetwork
# 连接容器到网络
docker network connect mynetwork webserver
# 断开容器与网络的连接
docker network disconnect mynetwork webserver
# 使用特定网络启动容器
docker run -d --name db --network mynetwork mysql:5.7
Dockerfile是构建Docker镜像的脚本,包含一系列指令和参数。
# 基础镜像
FROM ubuntu:20.04
# 维护者信息
LABEL maintainer="[email protected]"
# 设置工作目录
WORKDIR /app
# 复制文件
COPY . .
ADD https://example.com/file.tar.gz /app/
# 运行命令
RUN apt-get update && \
apt-get install -y python3 python3-pip && \
pip3 install -r requirements.txt && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 设置环境变量
ENV NODE_ENV=production \
PORT=3000
# 暴露端口
EXPOSE 3000
# 定义卷
VOLUME ["/data"]
# 设置用户
USER nobody
# 健康检查
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost:3000/ || exit 1
# 入口点
ENTRYPOINT ["python3"]
# 默认命令
CMD ["app.py"]
# 构建阶段
FROM node:14 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 生产阶段
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
# 不推荐
RUN apt-get update
RUN apt-get install -y package1
RUN apt-get install -y package2
RUN apt-get clean
# 推荐
RUN apt-get update && \
apt-get install -y package1 package2 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# .dockerignore示例
node_modules
npm-debug.log
Dockerfile
.git
.gitignore
README.md
# 不推荐
FROM ubuntu
# 推荐
FROM ubuntu:20.04
# 使用轻量级基础镜像
FROM alpine:3.14
# 安装必要的包并清理
RUN apk add --no-cache python3 py3-pip
Docker Compose是一个用于定义和运行多容器Docker应用的工具。
# 下载Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 添加执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 验证安装
docker-compose --version
version: '3'
services:
web:
build: ./web
ports:
- "80:80"
depends_on:
- db
environment:
- DATABASE_URL=postgres://postgres:password@db:5432/mydb
volumes:
- ./web:/code
networks:
- frontend
- backend
db:
image: postgres:13
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_DB=mydb
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- backend
redis:
image: redis:6
networks:
- backend
networks:
frontend:
backend:
volumes:
postgres_data:
# 启动服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看服务日志
docker-compose logs
# 停止服务
docker-compose stop
# 启动服务
docker-compose start
# 重启服务
docker-compose restart
# 停止并删除容器、网络
docker-compose down
# 停止并删除容器、网络、卷
docker-compose down -v
# 构建或重建服务
docker-compose build
# 执行命令
docker-compose exec web bash
# 查看配置
docker-compose config
Kubernetes(K8s)是一个开源的容器编排平台,用于自动化容器的部署、扩展和管理。
Kubernetes集群由以下组件组成:
控制平面组件:
节点组件:
Minikube是一个工具,可以在本地运行Kubernetes:
# 安装Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# 安装kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# 启动Minikube
minikube start
# 验证安装
kubectl get nodes
Pod是Kubernetes中最小的可部署单元,可以包含一个或多个容器:
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
# 创建Pod
kubectl apply -f pod.yaml
# 查看Pod
kubectl get pods
# 查看Pod详情
kubectl describe pod nginx-pod
# 删除Pod
kubectl delete pod nginx-pod
Deployment提供了Pod的声明式更新和扩展能力:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
# 创建Deployment
kubectl apply -f deployment.yaml
# 查看Deployment
kubectl get deployments
# 扩展Deployment
kubectl scale deployment nginx-deployment --replicas=5
# 更新Deployment
kubectl set image deployment/nginx-deployment nginx=nginx:1.20
# 查看更新状态
kubectl rollout status deployment/nginx-deployment
# 回滚更新
kubectl rollout undo deployment/nginx-deployment
Service定义了Pod的访问方式:
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: ClusterIP # 可选值:ClusterIP, NodePort, LoadBalancer, ExternalName
# 创建Service
kubectl apply -f service.yaml
# 查看Service
kubectl get services
# 查看Service详情
kubectl describe service nginx-service
# 删除Service
kubectl delete service nginx-service
ConfigMap用于存储非敏感配置,Secret用于存储敏感信息:
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
environment=production
log_level=info
database.properties: |
host=db.example.com
port=5432
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
username: YWRtaW4= # base64编码的"admin"
password: cGFzc3dvcmQ= # base64编码的"password"
# 创建ConfigMap和Secret
kubectl apply -f configmap.yaml
kubectl apply -f secret.yaml
# 在Pod中使用ConfigMap
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: config-volume
mountPath: /etc/config
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: log_level
volumes:
- name: config-volume
configMap:
name: app-config
# 在Pod中使用Secret
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: app-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
key: password
PV提供了存储资源,PVC是对PV的请求:
# pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-volume
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /data/pv0001
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
# 在Pod中使用PVC
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: data-volume
mountPath: /data
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: pv-claim
Helm是Kubernetes的包管理器,简化了应用的部署和管理:
# 安装Helm
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
# 添加仓库
helm repo add stable https://charts.helm.sh/stable
# 更新仓库
helm repo update
# 搜索Chart
helm search repo nginx
# 安装Chart
helm install my-nginx stable/nginx
# 查看已安装的Release
helm list
# 升级Release
helm upgrade my-nginx stable/nginx --set replicaCount=3
# 回滚Release
helm rollback my-nginx 1
# 卸载Release
helm uninstall my-nginx
# 创建自己的Chart
helm create mychart
容器安全是容器技术应用中的重要考虑因素。
使用最小基础镜像:
定期更新镜像:
不要以root用户运行容器:
# 在Dockerfile中创建非root用户
RUN adduser -D appuser
USER appuser
限制容器资源:
# 限制CPU和内存
docker run --cpus=0.5 --memory=512m nginx
使用只读文件系统:
# 使用只读文件系统,只有特定目录可写
docker run --read-only --tmpfs /tmp nginx
使用安全扫描工具:
实施网络分段:
使用安全计算模式(seccomp):
# 使用seccomp配置文件
docker run --security-opt seccomp=/path/to/seccomp.json nginx
限制容器能力(capabilities):
# 移除所有能力并只添加必要的能力
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx
使用内容信任和镜像签名:
# 启用Docker内容信任
export DOCKER_CONTENT_TRUST=1
docker push myregistry.com/myimage:1.0
Docker Bench for Security:
# 运行Docker安全基准测试
docker run --net host --pid host --userns host --cap-add audit_control \
-v /var/lib:/var/lib \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/lib/systemd:/usr/lib/systemd \
-v /etc:/etc --label docker_bench_security \
docker/docker-bench-security
Trivy:
# 安装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
Falco:
# 安装Falco
curl -s https://falco.org/repo/falcosecurity-3672BA8F.asc | apt-key add -
echo "deb https://download.falco.org/packages/deb stable main" | tee -a /etc/apt/sources.list.d/falcosecurity.list
apt-get update -y
apt-get install -y falco
# 启动Falco
systemctl start falco
容器网络是容器技术的重要组成部分,它使容器能够相互通信以及与外部世界通信。
Docker支持多种网络模式:
Bridge网络:默认网络模式,容器通过网桥连接。
# 创建自定义桥接网络
docker network create --driver bridge my-bridge-network
# 使用自定义网络启动容器
docker run --network my-bridge-network nginx
Host网络:容器使用主机的网络命名空间。
# 使用host网络启动容器
docker run --network host nginx
None网络:容器没有网络接口。
# 使用none网络启动容器
docker run --network none nginx
Overlay网络:用于Docker Swarm中的多主机通信。
# 创建overlay网络
docker network create --driver overlay my-overlay-network