云原生技术栈与容器化

🏷️ L2 📊 intermediate ⏱️ 40分钟 🏷️ 云原生,Docker,Kubernetes,容器化,Helm,CI/CD,前沿

好的,各位学员,大家好!欢迎来到今天的进阶课程。我是你们的讲师。在接下来的40分钟里,我们将深入探讨“云原生技术栈与容器化”这个主题,帮助大家从理论走向实战,掌握现代云应用的核心构建方法。

---

# 云原生技术栈与容器化

一、概述

为什么要学习这个主题?

在当今的软件开发领域,业务迭代速度要求越来越快,系统规模越来越大,传统的“单体应用 + 物理/虚拟机部署”模式已经捉襟见肘。云原生正是为了解决这些问题而生。

学完本课程能做什么?

完成本次学习后,你将具备以下能力:

1. 独立容器化应用:能够熟练编写Dockerfile,将任何应用打包成标准化的Docker镜像。 2. 管理Kubernetes核心资源:能使用YAML文件定义并管理Pod、Service、Deployment等核心对象,实现应用的部署和对外暴露。 3. 搭建CI/CD流水线:能够设计并实现一套从代码提交到自动构建、测试、部署的自动化流程。 4. 进行基础的监控与排错:能够配置基本的监控和日志收集,并利用Kubernetes命令排查常见问题。 5. 理解服务网格价值:了解Istio等工具如何解决微服务通信的复杂性问题,为后续深入学习打下基础。

适合人群和前置知识要求

---

二、核心知识点

模块一:Docker容器化实践 - 从“运行”到“构建”

原理讲解:Docker通过镜像(Image)和容器(Container)实现应用与环境的解耦。镜像是一个只读的模板,包含了运行应用所需的一切(代码、运行时、库、环境变量、配置文件)。容器是镜像的运行实例。

核心对比虚拟机 vs 容器。虚拟机虚拟化硬件,每个VM包含完整的操作系统,资源占用大、启动慢。容器虚拟化操作系统内核,共享宿主机内核,资源占用小、启动秒级。

实战示例:为一个简单的Python Flask应用编写Dockerfile。


# 1. 指定基础镜像,使用轻量级的Python 3.9-slim
FROM python:3.9-slim

# 2. 设置工作目录 WORKDIR /app

# 3. 将依赖文件复制到镜像中 COPY requirements.txt .

# 4. 安装Python依赖 RUN pip install --no-cache-dir -r requirements.txt

# 5. 将当前目录下的所有源代码复制到工作目录 COPY . .

# 6. 声明容器运行时监听的端口 EXPOSE 5000

# 7. 指定容器启动时执行的命令 CMD ["python", "app.py"]


关键命令


# 构建镜像
docker build -t my-flask-app:v1 .
# 运行容器,映射宿主机8080端口到容器5000端口
docker run -d -p 8080:5000 --name my-app my-flask-app:v1

模块二:Kubernetes核心概念 - 你的“容器编排操作系统”

原理讲解:Kubernetes (K8s) 是一个自动化容器操作的开源平台。它负责容器的部署、伸缩和管理。核心思想是声明式管理:你告诉K8s你想要的最终状态(例如“运行5个Nginx实例”),K8s会持续工作,确保实际状态与期望状态一致。

核心概念

  • **Pod**:K8s中最小的部署单元,通常包含一个或多个紧密相关的容器(如应用容器 + Sidecar日志收集容器)。Pod内的容器共享网络和存储卷。
  • **Service**:为一组Pod提供稳定的网络访问入口,实现服务发现和负载均衡。即使Pod的IP发生变化,Service的IP或DNS名称保持不变。
  • **Deployment**:负责管理Pod的声明式更新和回滚。你可以通过Deployment描述应用的期望状态(如副本数、镜像版本),Deployment Controller会控制ReplicaSet来实现。

实战示例:部署一个Nginx服务。


# 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.21 ports:
  • containerPort: 80
--- # service.yaml apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: nginx ports:
  • protocol: TCP
port: 80 # Service端口 targetPort: 80 # Pod端口 type: ClusterIP # 集群内部访问

模块三:Helm包管理 - K8s的“apt-get/yum”

原理讲解:Kubernetes应用通常由多个YAML文件(Deployment, Service, ConfigMap, Secret等)组成。Helm将这一整套资源打包成一个Chart,并提供模板化(Template)功能,让你可以通过简单的参数化配置,为不同环境(开发、测试、生产)生成不同的YAML。

核心概念

  • **Chart**:一个Helm包,包含一个应用的所有K8s资源定义模板和默认值。
  • **Release**:一个Chart在K8s集群中的一次运行实例。你可以使用同一个Chart,通过不同配置部署出多个Release。

实战示例:使用Helm安装一个WordPress。


# 1. 添加Bitnami仓库
helm repo add bitnami https://charts.bitnami.com/bitnami

# 2. 更新仓库 helm repo update

# 3. 安装WordPress,并自定义参数 helm install my-wordpress bitnami/wordpress \ --set wordpressUsername=admin \ --set wordpressPassword=password123 \ --set service.type=NodePort

# 4. 查看已安装的Release helm list


模块四:CI/CD流水线与监控日志

原理讲解

  • **CI/CD**:持续集成/持续部署。CI指频繁地将代码合并到主干,并自动进行构建和测试。CD指在CI通过后,自动将应用部署到目标环境。常见工具链:GitLab CI, Jenkins, GitHub Actions。
  • **监控**:核心是**Prometheus + Grafana**组合。Prometheus负责采集指标数据(如CPU、内存、请求数),Grafana负责可视化展示。
  • **日志**:核心是**EFK/ELK** (Elasticsearch, Filebeat/Fluentd, Kibana) 或 **Loki**。Filebeat/Fluentd负责从各节点收集容器日志,发送到Elasticsearch/Loki存储,Kibana/Grafana用于搜索和分析。

实战示例:一个简化的GitLab CI流水线。


# .gitlab-ci.yml
stages:
  • build
  • test
  • deploy

build-job: stage: build script:

  • docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
  • docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

test-job: stage: test script:

  • echo "Running unit tests..."

deploy-staging: stage: deploy script:

  • kubectl set image deployment/my-app my-app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n staging
environment: name: staging only:
  • main

---

三、实操步骤

目标:将一个简单的“Hello World”应用从零部署到Kubernetes集群。

前置条件:已安装Docker、kubectl、minikube(用于本地测试)或拥有一个K8s集群。

步骤1:准备应用与Docker镜像

1. 创建一个 app 目录,并在其中创建 app.pyrequirements.txt

  • `app.py`:

from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello, Cloud Native!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)

  • `requirements.txt`:

Flask==2.3.2

2.  在该目录下创建 Dockerfile (内容见模块一)。
3.  构建并推送镜像

docker build -t my-hello-app:v1 .
# 如果需要推送到远程仓库,请先docker login
# docker tag my-hello-app:v1 your-dockerhub-username/my-hello-app:v1
# docker push your-dockerhub-username/my-hello-app:v1

步骤2:创建Kubernetes部署资源

1. 创建一个 deployment.yaml 文件:


apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-deployment
spec:
replicas: 2
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
spec:
containers:
  • name: hello-app
image: my-hello-app:v1 # 如果是远程仓库,替换为 your-dockerhub-username/my-hello-app:v1 ports:
  • containerPort: 5000

2.  创建一个 service.yaml 文件:

apiVersion: v1
kind: Service
metadata:
name: hello-service
spec:
selector:
app: hello
ports:
  • protocol: TCP
port: 80 targetPort: 5000 type: NodePort # 在Minikube中方便访问

步骤3:部署到Kubernetes

1. 启动Minikube (如果使用本地环境):


minikube start

2.  应用YAML文件

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

3.  验证部署

kubectl get pods -l app=hello  # 查看Pod状态,应显示2个Running
kubectl get service hello-service # 查看Service状态

4.  访问应用

# 获取Minikube的访问URL
minikube service hello-service --url

打开浏览器访问返回的URL,你应该能看到 Hello, Cloud Native!

---

四、常见问题与故障排查

问题1:Pod状态一直为 Pending

  • **原因**:通常是因为集群资源不足(如CPU、内存),或无法调度到合适的节点。
  • **排查**:
1. kubectl describe pod <pod-name> 查看Events部分,寻找失败原因。 2. kubectl get nodes 查看节点资源使用情况 (kubectl top nodes)。 3. 检查是否有节点污点(Taints)与Pod容忍度(Tolerations)不匹配。

问题2:Pod状态为 CrashLoopBackOff

  • **原因**:容器启动后立即崩溃,K8s反复重启,导致进入回退状态。
  • **排查**:
1. kubectl logs <pod-name> 查看容器日志,这是最直接的方法。 2. kubectl logs <pod-name> --previous 查看上次崩溃的日志。 3. 进入容器内部调试:kubectl exec -it <pod-name> -- /bin/sh,检查进程、配置文件等。

问题3:Service无法访问(Connection refused

  • **原因**:Service的 `selector` 没匹配到任何Pod,或者Pod的端口标签不匹配。
  • **排查**:
1. kubectl describe service <service-name> 查看 Endpoints 字段。如果为空,说明没有后端Pod被选中。 2. 检查Service的 selector 和Pod的 labels 是否一致。 3. kubectl get pods --show-labels 查看Pod的标签。

问题4:镜像拉取失败(ImagePullBackOff

  • **原因**:镜像名称错误、标签不存在、私有仓库认证失败。
  • **排查**:
1. kubectl describe pod <pod-name> 查看Events,会明确提示是 ErrImagePullImagePullBackOff,并给出错误原因。 2. 检查YAML中的 image 字段。 3. 如果是私有仓库,确认是否创建了 imagePullSecrets

---

五、总结与扩展

重点知识回顾

1. 容器化是基石:Docker让应用和环境标准化,是云原生的“乐高积木”。 2. K8s是编排核心:Pod是最小单元,Deployment管理生命周期,Service提供稳定网络入口。声明式API是K8s的精髓。 3. Helm是组合工具:通过Chart管理复杂应用,实现参数化部署和环境隔离。 4. CI/CD是效率引擎:自动化从代码到部署的流程,是DevOps实践的关键一环。 5. 可观测性是保障:监控(Metrics)和日志(Logging)是理解系统状态、快速定位问题的眼睛。

实战中的最佳实践建议

  • **镜像构建**:优先选择Alpine等小型基础镜像;利用多阶段构建(Multi-stage builds)减小镜像体积;使用 `.dockerignore` 文件排除无用文件。
  • **资源声明**:始终为Pod设置 `resources.requests` 和 `resources.limits`,避免资源争抢。
  • **配置管理**:将配置(如数据库地址)和敏感信息(如密码)分别放入ConfigMap和Secret中管理,不要硬编码在镜像里。
  • **健康检查**:为Pod配置 `livenessProbe` (存活探针) 和 `readinessProbe` (就绪探针),让K8s自动管理Pod的健康状态和流量接入。
  • **命名空间隔离**:使用Namespace(如 `dev`, `staging`, `prod`)隔离不同环境的应用。

推荐进一步学习的方向和资源

  • **深入学习Kubernetes**:CNCF官方CKAD/CKA认证课程、Kubernetes官方文档。
  • **服务网格(Service Mesh)**:学习Istio,理解流量管理、安全、可观测性在微服务层面的实现。
  • **云原生存储**:了解Rook、Longhorn等云原生存储解决方案。
  • **Serverless**:学习Knative,探索在K8s上实现无服务器架构。
  • **GitOps**:学习ArgoCD或Flux,实现以Git仓库为单一事实来源的声明式部署。

今天的课程到这里就结束了。希望大家能将今天学到的知识应用到实际工作中,开始你的云原生之旅。谢谢大家!

在博海学习网开始学习 →