K8s 教程:从零开始构建和部署容器化应用
Kubernetes (K8s) 已经成为容器编排领域的领导者,它提供了一种自动化部署、扩展和管理容器化应用的方式。无论你是开发者、运维工程师还是架构师,掌握 Kubernetes 都能显著提高你的工作效率,并帮助你构建更可靠、更具弹性的应用程序。
本教程将带你从零开始,逐步了解 Kubernetes 的基本概念,并通过一个实际的例子——一个简单的 Web 应用——来演示如何构建、容器化、并最终部署到 Kubernetes 集群。我们将涵盖以下内容:
1. Kubernetes 基础概念
- 1.1 什么是容器化和 Kubernetes?
- 1.2 Kubernetes 的核心组件
- 1.2.1 Pods
- 1.2.2 Deployments
- 1.2.3 Services
- 1.2.4 Namespaces
- 1.2.5 Ingress
- 1.3 Kubernetes 控制平面
- 1.3.1 API Server
- 1.3.2 etcd
- 1.3.3 Scheduler
- 1.3.4 Controller Manager
- 1.4 Kubernetes 工作节点
- 1.4.1 Kubelet
- 1.4.2 Kube-proxy
- 1.4.3 Container Runtime (Docker, containerd)
2. 环境准备
- 2.1 安装 Minikube (本地 Kubernetes 集群)
- 2.2 安装 kubectl (Kubernetes 命令行工具)
3. 构建容器化应用
- 3.1 创建一个简单的 Web 应用 (Python Flask 示例)
- 3.2 编写 Dockerfile
- 3.3 构建 Docker 镜像
- 3.4 将 Docker 镜像推送到 Docker Hub (或其他镜像仓库)
4. 部署到 Kubernetes
- 4.1 编写 Kubernetes Deployment YAML 文件
- 4.2 编写 Kubernetes Service YAML 文件
- 4.3 编写 Kubernetes Ingress YAML 文件 (可选,用于外部访问)
- 4.4 使用 kubectl 命令部署应用
- 4.5 验证应用部署
5. 高级特性 (可选)
- 5.1 滚动更新
- 5.2 水平自动伸缩 (HPA)
- 5.3 健康检查 (Readiness/Liveness Probes)
- 5.4 ConfigMaps 和 Secrets
1. Kubernetes 基础概念
1.1 什么是容器化和 Kubernetes?
-
容器化: 是一种将应用程序及其所有依赖项(如库、系统工具、代码和运行时)打包成一个独立、可移植的单元的过程。 Docker 是目前最流行的容器化技术。容器化应用程序具有以下优点:
- 隔离性: 容器之间相互隔离,避免了依赖冲突。
- 可移植性: 容器可以在不同的环境中运行,无需修改代码。
- 效率: 容器比虚拟机更轻量级,启动速度更快,资源占用更少。
-
Kubernetes (K8s): 是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。 简单来说,Kubernetes 就像一个操作系统,但它不是运行在物理机上,而是运行在容器之上,负责管理容器的生命周期、资源分配、服务发现、负载均衡等。
1.2 Kubernetes 的核心组件
-
1.2.1 Pods: Kubernetes 中最小的可部署单元。 一个 Pod 可以包含一个或多个容器,这些容器共享网络和存储资源,并且总是部署在同一个节点上。可以将 Pod 视为一个逻辑单元,表示一个应用程序的实例。
-
1.2.2 Deployments: 用于管理 Pod 的生命周期。 Deployment 负责创建、更新和删除 Pod,并确保集群中始终运行指定数量的 Pod 副本。如果 Pod 发生故障,Deployment 会自动创建一个新的 Pod 来替换它。
-
1.2.3 Services: 用于公开应用程序。 Service 提供了一个稳定的 IP 地址和端口号,客户端可以通过这个地址和端口号访问应用程序,而无需关心底层 Pod 的具体位置。 Service 可以实现负载均衡,将流量分发到多个 Pod 上。
-
1.2.4 Namespaces: 用于隔离资源。 Namespace 提供了一种逻辑隔离机制,可以将集群中的资源划分成多个独立的命名空间,每个命名空间可以拥有自己的 Pod、Deployment、Service 等资源。 Namespaces 可以帮助你组织和管理大型 Kubernetes 集群。
-
1.2.5 Ingress: 用于管理外部访问。 Ingress 允许你通过域名或路径将外部流量路由到集群中的 Service。 Ingress 通常与 Ingress Controller 配合使用,Ingress Controller 负责监听 Ingress 资源的变更,并配置相应的负载均衡器(如 Nginx、HAProxy)来实现流量路由。
1.3 Kubernetes 控制平面
控制平面是 Kubernetes 集群的核心,负责管理和协调集群中的所有资源。它包含以下几个关键组件:
-
1.3.1 API Server: Kubernetes 的前端接口。 所有的客户端(包括 kubectl)都通过 API Server 与 Kubernetes 集群进行交互。 API Server 接收客户端的请求,验证权限,并将请求存储到 etcd 中。
-
1.3.2 etcd: 一个分布式键值存储系统,用于存储 Kubernetes 集群的所有配置数据和状态信息。 etcd 是 Kubernetes 的大脑,它存储了所有关于 Pod、Deployment、Service 等资源的信息。
-
1.3.3 Scheduler: 负责将 Pod 调度到合适的节点上。 Scheduler 会根据 Pod 的资源需求、节点的资源利用率、亲和性和反亲和性等因素,选择一个最佳的节点来运行 Pod。
-
1.3.4 Controller Manager: 负责管理 Kubernetes 集群中的各种控制器。 控制器是 Kubernetes 的核心组件,它们负责监控集群的状态,并采取相应的行动来维持期望的状态。例如,Deployment Controller 负责确保集群中运行指定数量的 Pod 副本。
1.4 Kubernetes 工作节点
工作节点是运行容器化应用程序的地方。每个工作节点都运行以下几个组件:
-
1.4.1 Kubelet: 运行在每个节点上的代理程序。 Kubelet 负责从 API Server 接收 Pod 的定义,并启动容器。 它还会定期报告节点的状态给 API Server。
-
1.4.2 Kube-proxy: 一个网络代理程序,负责实现 Service 的负载均衡。 Kube-proxy 通过配置 iptables 或 IPVS 规则,将流量路由到合适的 Pod 上。
-
1.4.3 Container Runtime (Docker, containerd): 负责运行容器的软件。 Docker 是最流行的容器运行时,但 Kubernetes 也支持其他容器运行时,如 containerd 和 CRI-O。
2. 环境准备
2.1 安装 Minikube (本地 Kubernetes 集群)
Minikube 是一个轻量级的 Kubernetes 实现,可以在本地计算机上创建一个单节点的 Kubernetes 集群。 它非常适合用于学习和开发。
你可以从 Minikube 官方网站下载并安装适合你操作系统的版本: https://minikube.sigs.k8s.io/docs/start/
安装完成后,使用以下命令启动 Minikube:
bash
minikube start
2.2 安装 kubectl (Kubernetes 命令行工具)
kubectl 是 Kubernetes 的命令行工具,用于与 Kubernetes 集群进行交互。 你可以使用 kubectl 命令来部署应用程序、管理资源、查看日志等。
你可以从 Kubernetes 官方网站下载并安装 kubectl: https://kubernetes.io/docs/tasks/tools/
安装完成后,配置 kubectl 连接到 Minikube 集群:
bash
kubectl config use-context minikube
3. 构建容器化应用
3.1 创建一个简单的 Web 应用 (Python Flask 示例)
创建一个名为 app.py
的 Python 文件,包含以下代码:
“`python
from flask import Flask
app = Flask(name)
@app.route(“/”)
def hello():
return “Hello, Kubernetes!”
if name == “main“:
app.run(host=”0.0.0.0”, port=5000)
“`
这个简单的 Flask 应用将在 5000 端口上监听,并在根路径 “/” 上返回 “Hello, Kubernetes!”。
3.2 编写 Dockerfile
创建一个名为 Dockerfile
的文件,包含以下内容:
“`dockerfile
FROM python:3.9-slim-buster
WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY app.py app.py
EXPOSE 5000
CMD [“python”, “app.py”]
“`
这个 Dockerfile 的作用是:
FROM python:3.9-slim-buster
: 基于 Python 3.9 slim-buster 镜像构建。WORKDIR /app
: 设置工作目录为 /app。COPY requirements.txt requirements.txt
: 复制 requirements.txt 文件到 /app 目录。RUN pip install -r requirements.txt
: 安装 requirements.txt 中定义的依赖项。COPY app.py app.py
: 复制 app.py 文件到 /app 目录。EXPOSE 5000
: 声明应用程序监听 5000 端口。CMD ["python", "app.py"]
: 运行 app.py 文件。
如果你的应用程序有依赖项,创建一个 requirements.txt
文件,并将依赖项列在其中。 例如:
Flask==2.0.1
3.3 构建 Docker 镜像
在包含 Dockerfile
的目录下,运行以下命令构建 Docker 镜像:
bash
docker build -t your-dockerhub-username/k8s-app:latest .
将 your-dockerhub-username
替换为你的 Docker Hub 用户名。
3.4 将 Docker 镜像推送到 Docker Hub (或其他镜像仓库)
登录到 Docker Hub:
bash
docker login
输入你的 Docker Hub 用户名和密码。
推送 Docker 镜像到 Docker Hub:
bash
docker push your-dockerhub-username/k8s-app:latest
4. 部署到 Kubernetes
4.1 编写 Kubernetes Deployment YAML 文件
创建一个名为 deployment.yaml
的文件,包含以下内容:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: k8s-app
template:
metadata:
labels:
app: k8s-app
spec:
containers:
- name: k8s-app
image: your-dockerhub-username/k8s-app:latest
ports:
- containerPort: 5000
这个 Deployment YAML 文件的作用是:
apiVersion: apps/v1
: 指定 API 版本。kind: Deployment
: 指定资源类型为 Deployment。metadata.name: k8s-app-deployment
: 指定 Deployment 的名称。spec.replicas: 3
: 指定运行 3 个 Pod 副本。spec.selector.matchLabels.app: k8s-app
: 指定 Deployment 管理的 Pod 的标签。spec.template.metadata.labels.app: k8s-app
: 指定 Pod 的标签。spec.template.spec.containers.name: k8s-app
: 指定容器的名称。spec.template.spec.containers.image: your-dockerhub-username/k8s-app:latest
: 指定容器使用的 Docker 镜像。spec.template.spec.containers.ports.containerPort: 5000
: 指定容器监听的端口号。
4.2 编写 Kubernetes Service YAML 文件
创建一个名为 service.yaml
的文件,包含以下内容:
yaml
apiVersion: v1
kind: Service
metadata:
name: k8s-app-service
spec:
selector:
app: k8s-app
ports:
- protocol: TCP
port: 80
targetPort: 5000
type: LoadBalancer
这个 Service YAML 文件的作用是:
apiVersion: v1
: 指定 API 版本。kind: Service
: 指定资源类型为 Service。metadata.name: k8s-app-service
: 指定 Service 的名称。spec.selector.app: k8s-app
: 指定 Service 选择的 Pod 的标签。spec.ports.protocol: TCP
: 指定协议为 TCP。spec.ports.port: 80
: 指定 Service 的端口号。spec.ports.targetPort: 5000
: 指定 Pod 的端口号。spec.type: LoadBalancer
: 指定 Service 类型为 LoadBalancer。 在 Minikube 中,LoadBalancer 类型会自动创建一个 NodePort Service。
4.3 编写 Kubernetes Ingress YAML 文件 (可选,用于外部访问)
创建一个名为 ingress.yaml
的文件,包含以下内容:
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: k8s-app-ingress
spec:
rules:
- host: k8s-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: k8s-app-service
port:
number: 80
这个 Ingress YAML 文件的作用是:
apiVersion: networking.k8s.io/v1
: 指定 API 版本。kind: Ingress
: 指定资源类型为 Ingress。metadata.name: k8s-app-ingress
: 指定 Ingress 的名称。spec.rules[0].host: k8s-app.example.com
: 指定 Ingress 的主机名。spec.rules[0].http.paths[0].path: /
: 指定 Ingress 的路径。spec.rules[0].http.paths[0].pathType: Prefix
: 指定路径类型为 Prefix。spec.rules[0].http.paths[0].backend.service.name: k8s-app-service
: 指定后端 Service 的名称。spec.rules[0].http.paths[0].backend.service.port.number: 80
: 指定后端 Service 的端口号。
注意: 使用 Ingress 需要先安装 Ingress Controller。 在 Minikube 中,可以使用以下命令安装 Ingress Controller:
bash
minikube addons enable ingress
还需要配置本地 DNS,将 k8s-app.example.com
指向 Minikube 的 IP 地址。 你可以使用以下命令获取 Minikube 的 IP 地址:
bash
minikube ip
然后,将以下内容添加到你的 hosts 文件(通常位于 /etc/hosts
或 C:\Windows\System32\drivers\etc\hosts
):
<minikube-ip> k8s-app.example.com
将 <minikube-ip>
替换为 Minikube 的 IP 地址。
4.4 使用 kubectl 命令部署应用
在包含 deployment.yaml
和 service.yaml
的目录下,运行以下命令部署应用:
bash
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
如果使用了 Ingress,运行以下命令部署 Ingress:
bash
kubectl apply -f ingress.yaml
4.5 验证应用部署
使用以下命令查看 Pod 的状态:
bash
kubectl get pods
确保所有的 Pod 都处于 Running
状态。
使用以下命令查看 Service 的状态:
bash
kubectl get service k8s-app-service
如果 Service 类型为 LoadBalancer,会显示一个外部 IP 地址。
如果没有使用 Ingress,可以使用 NodePort Service 的方式访问应用程序。 使用以下命令获取 NodePort:
bash
kubectl describe service k8s-app-service | grep NodePort
然后,在浏览器中访问 http://<minikube-ip>:<nodeport>
。
如果使用了 Ingress,可以在浏览器中访问 http://k8s-app.example.com
。
你应该能看到 “Hello, Kubernetes!”。
5. 高级特性 (可选)
5.1 滚动更新
可以使用以下命令更新 Deployment 的 Docker 镜像:
bash
kubectl set image deployment/k8s-app-deployment k8s-app=your-dockerhub-username/k8s-app:new-tag
Kubernetes 会自动进行滚动更新,逐步替换旧的 Pod 为新的 Pod,而不会中断服务。
5.2 水平自动伸缩 (HPA)
可以使用 Horizontal Pod Autoscaler (HPA) 根据 CPU 利用率自动调整 Pod 的数量。
5.3 健康检查 (Readiness/Liveness Probes)
可以使用 Readiness 和 Liveness Probes 来检查应用程序的健康状况。 Readiness Probe 用于判断应用程序是否准备好接收流量,Liveness Probe 用于判断应用程序是否需要重启。
5.4 ConfigMaps 和 Secrets
可以使用 ConfigMaps 来存储配置信息,Secrets 来存储敏感信息,例如密码和 API 密钥。
总结
本教程提供了一个 Kubernetes 入门的完整指南,涵盖了 Kubernetes 的基本概念,以及如何构建、容器化和部署应用程序到 Kubernetes 集群。通过实践这个简单的例子,你应该对 Kubernetes 有了初步的了解,并可以开始探索更多高级特性。 记住,实践是最好的老师! 祝你学习愉快!