本文是笔者学习容器云部署与应用课程后的一课一得总结,结合课程理论与实操练习,从容器云基础概念出发,梳理了 Docker 镜像构建、容器编排、Kubernetes 集群部署与应用上线的完整流程,并记录了实操过程中的踩坑与优化心得,希望能给同样入门容器云的同学提供参考。


一、前言:为什么要学习容器云?

在学习容器云之前,我对 “部署应用” 的认知还停留在 “服务器装环境、上传代码、配置依赖、启动服务” 的传统模式里。这种方式的痛点非常明显:

  • 环境不一致:本地开发能跑,到测试 / 生产环境就因为依赖版本、系统配置差异报错,也就是经典的 “在我电脑上能跑” 问题;
  • 部署效率低:新服务器部署一个应用要花几小时装依赖、配置环境,扩容更是麻烦;
  • 资源浪费:传统虚拟机部署每个应用都要占用独立的操作系统资源,硬件利用率低;
  • 运维复杂:多应用、多实例的管理、扩缩容、故障恢复全靠人工,效率低还容易出错。

而容器云技术,正是为了解决这些问题而生的。本次课程从 Docker 容器技术入门,延伸到 Kubernetes 容器编排,让我从 0 到 1 完成了容器化应用的构建、部署与管理,也对 “容器化” 的价值有了更深刻的理解。


二、容器云核心基础概念梳理

2.1 容器是什么?和虚拟机有什么区别?

很多新手容易把容器和虚拟机搞混,这里我整理了两者的核心区别:

表格

特性虚拟机(VM)容器(Container)
隔离方式硬件级隔离,每个 VM 有独立的操作系统内核操作系统级隔离,共享宿主机内核,通过 Namespace 和 Cgroups 实现资源隔离
资源占用每个 VM 都要运行完整的操作系统,占用 GB 级内存 / 磁盘仅运行应用及其依赖,占用 MB 级资源,启动速度秒级
启动速度分钟级(启动操作系统)秒级(直接启动容器进程)
移植性依赖宿主机虚拟化平台,镜像体积大,移植成本高镜像包含所有依赖,一次构建、到处运行,移植成本极低

简单来说,容器是打包了应用代码、运行时、依赖库、配置文件的标准化单元,它不包含完整的操作系统,所以更轻量、启动更快、资源利用率更高。

2.2 容器云是什么?Docker 和 K8s 的角色分工

很多同学会把 Docker、K8s、容器云混为一谈,其实它们的定位是不同的:

  • Docker:是容器技术的实现之一,提供了容器的创建、运行、镜像构建等基础能力,相当于 “容器的 runtime 工具”,解决了单个容器的打包与运行问题;
  • Kubernetes(简称 K8s):是容器编排平台,解决大规模容器集群的管理问题,比如多容器调度、自动扩缩容、故障自愈、负载均衡等,相当于 “容器集群的操作系统”;
  • 容器云:是基于容器技术构建的云原生平台,结合了容器 runtime、编排、网络、存储、监控等能力,为应用提供标准化的部署、运行与运维环境,是一套完整的解决方案。

三、Docker 实操:从镜像构建到容器运行

这部分是本次课程的实操重点,我以 CentOS 7 为例,完成了从 Docker 安装到自定义镜像构建、多容器编排的完整流程。

3.1 Docker 安装与基础配置

1. 安装 Docker(CentOS 7)

bash

运行

# 卸载旧版本Docker
yum remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine

# 安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2

# 添加阿里云Docker YUM源(国内推荐,速度更快)
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 安装Docker CE
yum install -y docker-ce docker-ce-cli containerd.io

# 启动Docker并设置开机自启
systemctl start docker
systemctl enable docker

# 验证安装是否成功(会输出Docker版本信息)
docker --version
docker run hello-world
2. 配置 Docker 镜像加速器(必做,否则拉取镜像很慢)

编辑/etc/docker/daemon.json文件,添加阿里云镜像加速器(需注册阿里云账号获取专属加速器地址):

bash

运行

cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": ["https://xxxxxx.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

# 重启Docker生效配置
systemctl daemon-reload
systemctl restart docker

3.2 镜像操作:拉取、构建与推送

1. 拉取公共镜像

从 Docker Hub 拉取官方 Nginx 和 MySQL 镜像:

bash

运行

# 拉取指定版本的Nginx镜像
docker pull nginx:1.25-alpine

# 拉取MySQL 8.0镜像
docker pull mysql:8.0

# 查看本地镜像列表
docker images
2. 构建自定义镜像:Python Flask 应用 Docker 化

这里我写了一个简单的 Python Flask 应用,然后通过 Dockerfile 构建镜像,实现 “一次构建,到处运行”。

第一步:编写 Flask 应用代码(app.py)

python

运行

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello, Container Cloud! This is my first Dockerized Flask App."

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

第二步:编写 Dockerfile

dockerfile

# 基础镜像:使用轻量级的Python 3.9 slim镜像,减少镜像体积
FROM python:3.9-slim

# 设置工作目录
WORKDIR /app

# 复制requirements.txt到容器中
COPY requirements.txt .

# 安装Python依赖(--no-cache-dir减少镜像体积)
RUN pip install --no-cache-dir -r requirements.txt

# 复制应用代码到容器中
COPY app.py .

# 暴露容器端口
EXPOSE 5000

# 容器启动命令
CMD ["python", "app.py"]

requirements.txt 文件

txt

flask==2.3.3

第三步:构建镜像并运行容器

bash

运行

# 构建镜像,命名为flask-app:v1
docker build -t flask-app:v1 .

# 运行容器,映射宿主机8080端口到容器5000端口
docker run -d -p 8080:5000 --name flask-demo flask-app:v1

# 访问测试:curl宿主机IP:8080,会输出Hello, Container Cloud!
curl localhost:8080

💡 小贴士:构建镜像时尽量使用alpineslim版本的基础镜像,避免使用完整的操作系统镜像,可以大幅减少镜像体积(比如 python:3.9-slim 只有几百 MB,而 python:3.9 完整版有几 GB)。

3. 推送镜像到阿里云镜像服务(私有仓库)

为了后续在 K8s 中使用自定义镜像,我把构建好的镜像推送到了阿里云镜像服务:

bash

运行

# 登录阿里云镜像仓库
docker login --username=你的阿里云账号  registry.cn-hangzhou.aliyuncs.com

# 给镜像打标签(格式:registry地址/命名空间/仓库名:标签)
docker tag flask-app:v1 registry.cn-hangzhou.aliyuncs.com/你的命名空间/flask-app:v1

# 推送镜像到仓库
docker push registry.cn-hangzhou.aliyuncs.com/你的命名空间/flask-app:v1

3.3 容器操作与数据持久化

容器默认是无状态的,容器删除后数据会丢失,所以关键数据必须挂载到宿主机或外部存储实现持久化。这里以 MySQL 容器为例,演示数据卷挂载:

bash

运行

# 创建宿主机数据目录
mkdir -p /data/mysql

# 运行MySQL容器,挂载数据目录、配置文件和日志目录
docker run -d \
  --name mysql-demo \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -v /data/mysql:/var/lib/mysql \
  -v /etc/mysql/conf.d:/etc/mysql/conf.d \
  mysql:8.0

# 验证数据持久化:删除容器后,重新运行容器并挂载同一个目录,数据不会丢失
docker stop mysql-demo
docker rm mysql-demo
# 重新运行容器,挂载同一个/data/mysql目录,之前创建的数据库依然存在

3.4 Docker Compose:多容器应用编排

手动运行多个容器时,需要逐个配置端口、依赖、网络,非常麻烦,Docker Compose 可以通过 YAML 文件定义多容器应用的配置,一键启动 / 停止所有服务。这里我用 Docker Compose 部署了一个 WordPress+MySQL 的博客应用:

docker-compose.yml 文件

yaml

version: '3.8'

services:
  db:
    image: mysql:8.0
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: wordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress

volumes:
  db_data:

启动与管理应用

bash

运行

# 启动所有服务(后台运行)
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看服务日志
docker-compose logs -f wordpress

# 停止并删除服务(包括容器、网络,不删除数据卷)
docker-compose down

访问宿主机 IP:8000,就能看到 WordPress 的安装界面,整个部署过程只需要一条命令,非常方便。


四、Kubernetes 基础:单节点集群部署与应用上线

Docker 解决了单个容器的运行问题,但大规模容器集群的管理(比如自动扩缩容、故障自愈、负载均衡)需要 Kubernetes 来实现。本次课程我用 Minikube 搭建了单节点 K8s 集群,完成了应用的部署与测试。

4.1 Minikube 安装与启动(适合本地学习)

bash

运行

# 安装kubectl(K8s命令行工具)
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
mv kubectl /usr/local/bin/

# 安装Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
chmod +x minikube-linux-amd64
mv minikube-linux-amd64 /usr/local/bin/minikube

# 启动Minikube(使用Docker作为驱动,国内用户推荐配置镜像源)
minikube start --driver=docker --image-mirror-country=cn --kubernetes-version=v1.28.3

# 验证集群状态
kubectl cluster-info
kubectl get nodes

4.2 K8s 核心概念快速理解

  • Pod:K8s 中最小的调度单元,一个 Pod 可以包含一个或多个容器(比如应用容器 + 日志采集容器),Pod 共享网络和存储资源;
  • Deployment:负责管理 Pod 的副本,比如定义运行 3 个 Nginx Pod 副本,当某个 Pod 故障时,Deployment 会自动创建新的 Pod 替换它,实现故障自愈;
  • Service:为一组 Pod 提供统一的访问入口,实现负载均衡,支持 ClusterIP(集群内访问)、NodePort(宿主机端口访问)、LoadBalancer(云厂商负载均衡)等类型;
  • Namespace:集群内的资源隔离单元,可以用来划分不同的环境(比如 dev、test、prod)。

4.3 部署 Nginx 应用到 K8s 集群

1. 编写 Deployment 配置文件(nginx-deployment.yaml)

yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3 # 运行3个Nginx Pod副本
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25-alpine
        ports:
        - containerPort: 80
2. 编写 Service 配置文件(nginx-service.yaml)

yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx # 匹配Deployment中Pod的标签
  type: NodePort # 暴露为宿主机端口访问
  ports:
    - protocol: TCP
      port: 80 # Service的端口
      targetPort: 80 # Pod的端口
      nodePort: 30080 # 宿主机端口(范围30000-32767)
3. 部署应用并验证

bash

运行

# 应用Deployment配置
kubectl apply -f nginx-deployment.yaml

# 应用Service配置
kubectl apply -f nginx-service.yaml

# 查看Pod状态(确保所有Pod处于Running状态)
kubectl get pods -o wide

# 查看Service状态
kubectl get svc

# 访问测试:通过Minikube节点IP+NodePort访问Nginx
minikube ip # 获取Minikube节点IP
curl http://$(minikube ip):30080

4.4 部署自定义 Flask 应用到 K8s

把之前推送到阿里云镜像仓库的 Flask 应用部署到 K8s 集群,这里我把镜像设为公开的,直接拉取:

flask-deployment.yaml

yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: flask-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: flask
  template:
    metadata:
      labels:
        app: flask
    spec:
      containers:
      - name: flask-app
        image: registry.cn-hangzhou.aliyuncs.com/你的命名空间/flask-app:v1
        ports:
        - containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
  name: flask-service
spec:
  selector:
    app: flask
  type: NodePort
  ports:
    - port: 5000
      targetPort: 5000
      nodePort: 30081

部署并访问:

bash

运行

kubectl apply -f flask-deployment.yaml
kubectl get pods
curl http://$(minikube ip):30081

五、实操踩坑与优化心得(一课一得核心)

这部分是我在实操过程中遇到的问题和解决方法,也是本次课程最大的收获:

坑 1:Docker 容器启动后马上退出

  • 现象:运行容器后,docker ps看不到容器,docker ps -a显示容器状态为 Exited;
  • 原因:容器的主进程退出了,比如 Python 应用后台运行、Nginx 以 daemon 模式运行,容器会认为进程结束而退出;
  • 解决方法:让容器的主进程在前台运行。比如 Nginx 启动时加上-g 'daemon off;',Python 应用不要用&后台运行,直接前台启动。

坑 2:K8s 的 Pod 一直处于 Pending 状态

  • 现象:Pod 状态为 Pending,kubectl describe pod显示调度失败;
  • 原因:集群资源不足(CPU / 内存不够)、没有匹配的节点标签、镜像拉取失败;
  • 解决方法:用kubectl describe pod <pod-name>查看事件日志,根据提示排查问题,比如 Minikube 启动时分配更多内存,或者使用国内镜像源。

坑 3:Docker 镜像体积过大,拉取速度慢

  • 现象:构建的镜像有几 GB,推送到仓库和拉取都很慢;
  • 优化方法
    1. 使用轻量级基础镜像(alpine/slim);
    2. 多阶段构建:把构建过程和运行环境分开,比如用 Go/Python 构建应用,只把可执行文件复制到运行镜像中;
    3. 清理构建缓存:比如apt-get cleanpip install --no-cache-dir
    4. 合并 RUN 指令:减少镜像层数(Docker 镜像分层存储,每个 RUN 指令会生成一个新层)。

心得 1:容器化不是 “银弹”

不是所有应用都适合容器化,比如小型单体应用,用 Docker Compose 部署就足够了,没必要上 K8s;容器化的核心价值在于标准化和编排,适合微服务、云原生架构的应用。

心得 2:理解概念比敲命令更重要

刚开始学的时候,我只会跟着教程敲命令,遇到问题就懵了。后来才明白,只有理解了 Namespace、Cgroups、Pod、Deployment 这些概念的本质,才能快速定位问题,而不是只会复制粘贴命令。

心得 3:镜像安全很重要

不要使用来源不明的公共镜像,尽量自己构建镜像;不要在镜像中存放敏感信息(比如密码、密钥),可以用 K8s 的 Secret 或 ConfigMap 来管理配置;定期更新镜像的基础镜像,修复安全漏洞。


六、容器云的应用场景与未来学习方向

6.1 容器云的典型应用场景

  1. 微服务部署:把单体应用拆分成多个微服务,每个微服务打包成容器,独立部署、升级、扩缩容;
  2. CI/CD 集成:容器镜像作为 CI/CD 的交付产物,实现 “构建一次,到处部署”,简化发布流程;
  3. 弹性伸缩:根据业务流量自动调整容器实例数量,比如电商大促时自动扩容,流量低峰时缩容,节省资源;
  4. 混合 / 多云部署:容器镜像不依赖底层基础设施,可以轻松在公有云、私有云、本地数据中心之间迁移;
  5. DevOps 实践:开发、测试、生产环境都使用相同的容器镜像,消除环境差异,实现开发运维一体化。

6.2 后续学习方向

本次课程只是入门了容器云的基础,后续我打算深入学习:

  • K8s 的高级特性:Ingress、持久化存储(PV/PVC)、StatefulSet(有状态应用部署)、监控告警(Prometheus+Grafana);
  • CI/CD 工具与容器集成:Jenkins、GitLab CI,实现代码提交后自动构建镜像、部署到 K8s;
  • 容器安全:镜像扫描、容器运行时安全、RBAC 权限控制;
  • 云原生生态:服务网格(Istio)、无服务器架构(Knative)等。

七、总结

通过本次容器云部署与应用课程的学习和实操,我从一个 “只会手动部署应用” 的新手,掌握了 Docker 容器化、Kubernetes 基础编排的核心技能,也深刻体会到了容器云技术在解决环境一致性、提升部署效率、简化运维管理方面的巨大价值。

“一课一得” 的核心不在于学会多少命令,而在于理解技术背后的设计思想,以及解决实际问题的能力。在后续的学习和实践中,我会继续深入云原生领域,把学到的知识应用到实际项目中,真正做到学以致用。

AI辅助:http://www.doubao.com

写文章-CSDN创作中心

更多推荐