Kubernetes 教程:容器编排平台详解

1. 什么是 Kubernetes?

Kubernetes(简称 K8s)是一个开源的容器编排平台,用于自动化容器的部署、扩展和管理。它由 Google 设计并捐赠给 Cloud Native Computing Foundation(CNCF)管理,是目前最流行的容器编排解决方案。

1.1 核心概念

  • Pod:Kubernetes 中最小的部署单元,包含一个或多个容器。
  • Deployment:管理 Pod 的副本,确保指定数量的 Pod 运行。
  • Service:为 Pod 提供稳定的网络访问方式。
  • Namespace:用于在集群中创建隔离的资源组。
  • Node:集群中的工作机器,可以是物理机或虚拟机。
  • Cluster:由一组 Node 组成的 Kubernetes 集群。
  • Control Plane:集群的控制中心,包含 API Server、Scheduler、Controller Manager 等组件。
  • etcd:分布式键值存储,用于存储集群配置和状态。

1.2 核心特性

  • 自动扩缩容:根据负载自动调整 Pod 数量。
  • 服务发现和负载均衡:为 Pod 提供稳定的网络访问和负载均衡。
  • 存储编排:自动挂载存储卷,支持多种存储系统。
  • 自动修复:当 Pod 失败时自动重启或替换。
  • 滚动更新:无缝更新应用,零 downtime。
  • Secret 和配置管理:安全管理敏感信息和配置。
  • 批量执行:支持一次性任务和定时任务。

1.3 适用场景

  • 微服务架构:管理大量微服务的部署和扩展。
  • 高可用性应用:确保应用持续运行,即使在节点故障时。
  • 弹性伸缩:根据流量自动调整资源。
  • 多环境部署:在不同环境中一致部署应用。
  • 混合云和多云:在不同云提供商和本地环境中运行应用。

2. 安装和配置

2.1 本地开发环境

2.1.1 Minikube

Minikube 是一个用于在本地运行单节点 Kubernetes 集群的工具,适合开发和测试:

# 安装 Minikube(Windows)
choco install minikube

# 安装 Minikube(macOS)
brew install minikube

# 安装 Minikube(Linux)
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# 启动 Minikube
minikube start

# 验证集群状态
kubectl cluster-info

2.1.2 Kind

Kind(Kubernetes IN Docker)是一个使用 Docker 容器运行本地 Kubernetes 集群的工具:

# 安装 Kind
brew install kind  # macOS
choco install kind  # Windows

# 创建集群
kind create cluster

# 验证集群状态
kubectl cluster-info

2.2 生产环境

2.2.1 Kubeadm

Kubeadm 是官方推荐的用于创建生产级 Kubernetes 集群的工具:

# 在所有节点上安装 Docker 或 Containerd
# 安装 kubeadm、kubelet 和 kubectl
apt-get update && apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get update
apt-get install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl

# 在主节点上初始化集群
sudo kubeadm init --pod-network-cidr=10.244.0.0/16

# 配置 kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 安装网络插件
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

# 加入工作节点
# 在主节点上运行 kubeadm token create --print-join-command 获取加入命令
# 在工作节点上运行获取的命令

2.2.2 托管 Kubernetes 服务

各大云提供商都提供托管的 Kubernetes 服务:

  • Amazon EKS:Amazon Elastic Kubernetes Service
  • Azure AKS:Azure Kubernetes Service
  • Google GKE:Google Kubernetes Engine
  • 阿里云 ACK:Alibaba Cloud Container Service for Kubernetes
  • 腾讯云 TKE:Tencent Kubernetes Engine

2.3 配置 kubectl

kubectl 是 Kubernetes 的命令行工具,用于与集群交互:

# 安装 kubectl(Windows)
choco install kubernetes-cli

# 安装 kubectl(macOS)
brew install kubectl

# 安装 kubectl(Linux)
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl

# 验证安装
kubectl version --client

3. 基本使用

3.1 部署应用

# 使用 kubectl create 部署应用
kubectl create deployment nginx --image=nginx

# 暴露服务
kubectl expose deployment nginx --port=80 --type=NodePort

# 查看服务
kubectl get services

# 查看 Pod
kubectl get pods

# 查看部署
kubectl get deployments

3.2 使用 YAML 文件部署

创建一个 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.14.2
        ports:
        - containerPort: 80
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
  type: NodePort
# 应用部署文件
kubectl apply -f nginx-deployment.yaml

# 应用服务文件
kubectl apply -f nginx-service.yaml

# 查看所有资源
kubectl get all

3.3 扩缩容应用

# 手动扩缩容
kubectl scale deployment nginx-deployment --replicas=5

# 查看状态
kubectl get deployments

# 自动扩缩容
kubectl autoscale deployment nginx-deployment --min=2 --max=10 --cpu-percent=80

# 查看 HPA
kubectl get hpa

3.4 滚动更新

# 滚动更新镜像
kubectl set image deployment nginx-deployment nginx=nginx:1.16.1

# 查看滚动更新状态
kubectl rollout status deployment nginx-deployment

# 回滚更新
kubectl rollout undo deployment nginx-deployment

# 查看历史版本
kubectl rollout history deployment nginx-deployment

3.5 配置管理

3.5.1 ConfigMap

# 创建 ConfigMap
kubectl create configmap app-config --from-literal=DB_HOST=localhost --from-literal=DB_PORT=5432

# 查看 ConfigMap
kubectl get configmap

# 查看 ConfigMap 详情
kubectl describe configmap app-config

3.5.2 Secret

# 创建 Secret
kubectl create secret generic app-secret --from-literal=DB_USER=admin --from-literal=DB_PASSWORD=secret

# 查看 Secret
kubectl get secret

# 查看 Secret 详情
kubectl describe secret app-secret

4. 高级功能

4.1 存储管理

4.1.1 持久卷(Persistent Volume)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"

4.1.2 持久卷声明(Persistent Volume Claim)

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

4.1.3 在 Pod 中使用持久卷

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx
    volumeMounts:
    - mountPath: "/usr/share/nginx/html"
      name: my-volume
  volumes:
  - name: my-volume
    persistentVolumeClaim:
      claimName: my-pvc

4.2 网络策略

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
spec:
  podSelector:
    matchLabels:
      app: backend
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080

4.3 资源配额

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: default
spec:
  hard:
    pods: "10"
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi

4.4 命名空间

# 创建命名空间
kubectl create namespace development

# 在命名空间中部署应用
kubectl apply -f nginx-deployment.yaml -n development

# 查看命名空间中的资源
kubectl get pods -n development

# 切换默认命名空间
kubectl config set-context --current --namespace=development

5. 实用案例

5.1 部署一个简单的 Node.js 应用

场景:在 Kubernetes 集群中部署一个简单的 Node.js Express 应用。

步骤

  1. 创建应用代码
// app.js
const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello Kubernetes!');
});

app.listen(port, () => {
  console.log(`App listening at http://localhost:${port}`);
});
// package.json
{
  "name": "k8s-node-app",
  "version": "1.0.0",
  "description": "Node.js app on Kubernetes",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "^4.17.1"
  }
}
  1. 创建 Dockerfile
FROM node:14-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
  1. 构建和推送镜像
# 构建镜像
docker build -t your-dockerhub-username/node-app:v1 .

# 推送镜像
docker push your-dockerhub-username/node-app:v1
  1. 创建 Kubernetes 部署文件
# node-app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-app-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: node-app
  template:
    metadata:
      labels:
        app: node-app
    spec:
      containers:
      - name: node-app
        image: your-dockerhub-username/node-app:v1
        ports:
        - containerPort: 3000
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "200m"
            memory: "256Mi"
# node-app-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: node-app-service
spec:
  selector:
    app: node-app
  ports:
  - port: 80
    targetPort: 3000
  type: LoadBalancer
  1. 部署应用
kubectl apply -f node-app-deployment.yaml
kubectl apply -f node-app-service.yaml
  1. 查看部署状态
kubectl get all
  1. 测试应用

对于 Minikube:

minikube service node-app-service

对于云提供商的托管 Kubernetes 服务,获取负载均衡器的外部 IP:

kubectl get services

然后在浏览器中访问该 IP,应该看到 "Hello Kubernetes!"。

5.2 使用 Helm 部署应用

场景:使用 Helm 包管理器部署一个复杂的应用(如 WordPress)。

步骤

  1. 安装 Helm
# 安装 Helm(Windows)
choco install kubernetes-helm

# 安装 Helm(macOS)
brew install helm

# 安装 Helm(Linux)
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
  1. 添加 Helm 仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
  1. 更新 Helm 仓库
helm repo update
  1. 部署 WordPress
helm install my-wordpress bitnami/wordpress
  1. 查看部署状态
helm status my-wordpress
kubectl get all
  1. 获取 WordPress 访问信息
echo Username: user

echo Password: $(kubectl get secret my-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode)

echo External IP: $(kubectl get service my-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}")
  1. 测试应用

在浏览器中访问获取的外部 IP,使用获取的用户名和密码登录 WordPress。

  1. 删除部署
helm uninstall my-wordpress

6. 代码示例

6.1 基本部署示例

node-app-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-app-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: node-app
  template:
    metadata:
      labels:
        app: node-app
    spec:
      containers:
      - name: node-app
        image: your-dockerhub-username/node-app:v1
        ports:
        - containerPort: 3000
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "200m"
            memory: "256Mi"

node-app-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: node-app-service
spec:
  selector:
    app: node-app
  ports:
  - port: 80
    targetPort: 3000
  type: LoadBalancer

部署命令

kubectl apply -f node-app-deployment.yaml
kubectl apply -f node-app-service.yaml
kubectl get all

6.2 使用 ConfigMap 和 Secret

app-config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DB_HOST: "db"
  DB_PORT: "5432"
  DB_NAME: "myapp"

app-secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  DB_USER: YWRtaW4=
  DB_PASSWORD: c2VjcmV0

node-app-with-config.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-app-with-config
spec:
  replicas: 2
  selector:
    matchLabels:
      app: node-app
  template:
    metadata:
      labels:
        app: node-app
    spec:
      containers:
      - name: node-app
        image: your-dockerhub-username/node-app:v1
        ports:
        - containerPort: 3000
        envFrom:
        - configMapRef:
            name: app-config
        - secretRef:
            name: app-secret
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "200m"
            memory: "256Mi"

部署命令

kubectl apply -f app-config.yaml
kubectl apply -f app-secret.yaml
kubectl apply -f node-app-with-config.yaml
kubectl get configmap,secret

7. 常见问题和解决方案

7.1 Pod 无法启动

问题:Pod 状态为 CrashLoopBackOff 或 ContainerCreating。

解决方案

  • 查看 Pod 日志:kubectl logs [pod-name]
  • 查看 Pod 详情:kubectl describe pod [pod-name]
  • 检查镜像是否存在
  • 检查资源是否足够
  • 检查网络配置

7.2 服务无法访问

问题:无法通过 Service 访问应用。

解决方案

  • 检查 Service 状态:kubectl get service [service-name]
  • 检查 Service 详情:kubectl describe service [service-name]
  • 检查 Pod 是否运行:kubectl get pods
  • 检查 Pod 标签是否与 Service 选择器匹配
  • 检查网络策略是否阻止访问

7.3 集群节点不可用

问题:节点状态为 NotReady。

解决方案

  • 查看节点状态:kubectl get nodes
  • 查看节点详情:kubectl describe node [node-name]
  • 检查节点上的 kubelet 服务是否运行
  • 检查节点网络连接
  • 检查节点资源是否足够

7.4 资源不足

问题:Pod 无法调度,提示资源不足。

解决方案

  • 检查节点资源:kubectl describe node
  • 调整 Pod 的资源请求和限制
  • 添加更多节点到集群
  • 清理不需要的 Pod 和服务

7.5 滚动更新失败

问题:滚动更新卡住或失败。

解决方案

  • 查看滚动更新状态:kubectl rollout status deployment [deployment-name]
  • 查看 Pod 日志:kubectl logs [pod-name]
  • 回滚更新:kubectl rollout undo deployment [deployment-name]
  • 检查应用的健康检查配置

8. 总结

Kubernetes 是一个功能强大的容器编排平台,它提供了完整的容器管理解决方案,包括部署、扩展、服务发现、负载均衡、存储编排等功能。通过 Kubernetes,开发者可以更加专注于应用的开发,而将部署和管理的复杂性交给平台处理。

8.1 优点

  • 自动化管理:自动处理容器的部署、扩展和故障恢复
  • 高可用性:确保应用持续运行,即使在节点故障时
  • 弹性伸缩:根据负载自动调整资源
  • 服务发现和负载均衡:为应用提供稳定的网络访问
  • 存储编排:支持多种存储系统,提供灵活的存储解决方案
  • 可扩展性:通过自定义资源和控制器扩展 Kubernetes 功能
  • 多云支持:在不同云提供商和本地环境中运行一致

8.2 局限性

  • 学习曲线陡峭:对于初学者来说,Kubernetes 有一定的学习曲线
  • 复杂性:配置和管理 Kubernetes 集群需要一定的专业知识
  • 资源开销:Kubernetes 本身需要一定的资源来运行
  • 网络复杂性:网络配置可能变得复杂,特别是在多集群环境中
  • 存储管理:存储配置和管理需要额外的考虑

8.3 适用场景

  • 微服务架构:管理大量微服务的部署和扩展
  • 高流量应用:需要自动扩缩容和高可用性的应用
  • 企业级应用:需要严格的资源管理和安全控制的应用
  • 多环境部署:在开发、测试和生产环境中一致部署应用
  • 混合云和多云:在不同云提供商和本地环境中运行应用

通过本教程,你应该已经掌握了 Kubernetes 的基本概念、安装配置、基本使用和常见场景的应用。在实际开发和部署中,Kubernetes 可以大大简化容器的管理和运维工作,提高应用的可靠性和可扩展性。

« 上一篇 Docker 教程:容器化平台详解 下一篇 » Terraform 教程:基础设施即代码工具详解