K8s 教程:从零开始构建和部署容器化应用 – wiki基地

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/hostsC:\Windows\System32\drivers\etc\hosts):

<minikube-ip> k8s-app.example.com

<minikube-ip> 替换为 Minikube 的 IP 地址。

4.4 使用 kubectl 命令部署应用

在包含 deployment.yamlservice.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 有了初步的了解,并可以开始探索更多高级特性。 记住,实践是最好的老师! 祝你学习愉快!

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部