Kubernetes 入门实战:从零搭建容器编排平台

· 阅读约需8分钟

一、引言

在云原生时代,容器化技术已经成为应用部署的标准方式。然而,随着容器数量的增加,手动管理成百上千个容器变得几乎不可能。这就是Kubernetes(简称K8s)发挥作用的地方。

Kubernetes是Google开源的容器编排平台,它提供了自动化部署、扩展和管理容器化应用的能力。本文将带你从零开始,一步步了解Kubernetes的核心概念,搭建你的第一个Kubernetes集群,并通过实战案例掌握应用部署的完整流程。

无论你是DevOps工程师、后端开发者还是运维人员,掌握Kubernetes都将成为你职业发展中的重要技能。

二、Kubernetes 核心概念

2.1 什么是 Kubernetes

Kubernetes是一个开源的容器编排引擎,用于自动化部署、扩展和管理容器化应用。它的名字来源于希腊语,意为”舵手”或”飞行员”,这也暗示了它在容器海洋中导航的角色。

Kubernetes的核心能力包括:

  • 服务发现与负载均衡:自动为容器分配IP地址和DNS名称,并提供负载均衡
  • 存储编排:自动挂载你选择的存储系统
  • 自动部署与回滚:声明式地定义期望状态,Kubernetes会自动调整
  • 自动装箱:根据资源需求和约束自动放置容器
  • 自我修复:重启失败的容器,替换和终止不响应健康检查的容器
  • 密钥与配置管理:存储和管理敏感信息和应用配置

2.2 核心架构组件

Kubernetes采用主从架构,主要由控制平面(Control Plane)和工作节点(Worker Node)组成。

控制平面组件:

  • kube-apiserver:集群的入口,提供REST API,所有组件都通过它交互
  • etcd:分布式键值存储,保存集群的所有状态数据
  • kube-scheduler:负责调度Pod到合适的节点上
  • kube-controller-manager:运行各种控制器,如节点控制器、副本控制器等
  • cloud-controller-manager:与云服务商API交互,管理云资源

工作节点组件:

  • kubelet:在每个节点上运行的代理,确保容器在Pod中正常运行
  • kube-proxy:维护节点上的网络规则,实现服务抽象
  • 容器运行时:负责运行容器,如Docker、containerd等

2.3 核心资源对象

Kubernetes通过各种资源对象来描述集群状态,最常用的有:

  • Pod:最小的部署单元,包含一个或多个容器
  • Service:定义一组Pod的访问方式,提供稳定的网络端点
  • Deployment:管理Pod的副本数和更新策略
  • Namespace:用于隔离集群资源的虚拟集群
  • ConfigMap:存储非敏感配置数据
  • Secret:存储敏感信息,如密码、密钥等
  • Volume:Pod中的数据卷,提供数据持久化

三、Kubernetes 集群搭建

3.1 环境准备

在开始搭建Kubernetes集群之前,我们需要准备以下环境:

硬件要求:

  • Master节点:2核CPU,2GB内存以上
  • Worker节点:2核CPU,2GB内存以上
  • 所有节点之间网络互通
  • 每个节点有唯一的主机名

软件要求:

  • 操作系统:Ubuntu 20.04+ 或 CentOS 7+
  • Docker 或 containerd 作为容器运行时
  • kubeadm、kubelet、kubectl 工具

3.2 使用 kubeadm 搭建集群

kubeadm是官方提供的集群搭建工具,可以快速部署一个生产可用的Kubernetes集群。

步骤一:在所有节点上安装 Docker

# 更新软件包索引
sudo apt update

# 安装依赖
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common

# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

# 添加Docker软件源
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

# 安装Docker
sudo apt update
sudo apt install -y docker-ce

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

步骤二:在所有节点上安装 kubeadm、kubelet 和 kubectl

# 添加Kubernetes官方GPG密钥
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -

# 添加Kubernetes软件源
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF

# 安装kubeadm、kubelet和kubectl
sudo apt update
sudo apt install -y kubelet kubeadm kubectl

# 锁定版本,防止意外升级
sudo apt-mark hold kubelet kubeadm kubectl

步骤三:初始化 Master 节点

# 在Master节点上执行初始化
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=<master-ip>

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

初始化成功后,会输出一个join命令,类似:

kubeadm join <master-ip>:6443 --token <token> \
    --discovery-token-ca-cert-hash sha256:
<hash>

步骤四:安装 Pod 网络插件

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

步骤五:将 Worker 节点加入集群

在每个Worker节点上执行之前保存的join命令:

sudo kubeadm join <master-ip>:6443 --token <token> \
    --discovery-token-ca-cert-hash sha256:
<hash>

步骤六:验证集群状态

# 查看节点状态
kubectl get nodes

# 查看所有Pod状态
kubectl get pods --all-namespaces

3.3 使用 Minikube 快速体验

如果你只是想快速体验Kubernetes,可以使用Minikube在本地搭建单节点集群:

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

# 启动集群
minikube start

# 查看集群状态
minikube status
kubectl get nodes

四、实战部署:部署一个 Web 应用

4.1 创建 Deployment

Deployment是Kubernetes中最常用的资源对象,用于管理无状态应用的部署。

创建一个nginx-deployment.yaml文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "200m"
            memory: "256Mi"

部署这个应用:

# 创建Deployment
kubectl apply -f nginx-deployment.yaml

# 查看Deployment状态
kubectl get deployments

# 查看Pod状态
kubectl get pods -l app=nginx

4.2 创建 Service

Service为Pod提供稳定的网络访问入口。创建一个nginx-service.yaml文件:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080

创建Service:

# 创建Service
kubectl apply -f nginx-service.yaml

# 查看Service
kubectl get services

现在你可以通过任意节点的IP:30080访问Nginx服务。

4.3 使用 ConfigMap 管理配置

ConfigMap用于存储应用的配置信息。创建一个app-config.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  app.properties: |
    server.port=8080
    app.name=myapp
    log.level=info
  database.url: jdbc:mysql://localhost:3306/mydb

在Deployment中引用ConfigMap:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:latest
        ports:
        - containerPort: 8080
        envFrom:
        - configMapRef:
            name: app-config
        volumeMounts:
        - name: config-volume
          mountPath: /etc/config
      volumes:
      - name: config-volume
        configMap:
          name: app-config

4.4 使用 Secret 管理敏感信息

Secret用于存储密码、密钥等敏感数据。创建一个db-secret.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  username: YWRtaW4=      # base64编码的"admin"
  password: cGFzc3dvcmQxMjM=  # base64编码的"password123"

在Deployment中使用Secret:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:latest
        env:
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: username
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password

五、Kubernetes 最佳实践

5.1 资源管理最佳实践

1. 为容器设置资源请求和限制

resources:
  requests:
    cpu: "100m"
    memory: "128Mi"
  limits:
    cpu: "200m"
    memory: "256Mi"

资源请求用于调度,确保Pod被调度到有足够资源的节点上;资源限制防止单个容器占用过多资源影响其他应用。

2. 使用命名空间隔离环境

# 创建开发环境命名空间
kubectl create namespace dev

# 创建生产环境命名空间
kubectl create namespace prod

3. 使用标签和选择器组织资源

metadata:
  labels:
    app: myapp
    environment: production
    tier: backend

5.2 安全最佳实践

1. 使用非root用户运行容器

FROM node:14-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# ... 其他指令

2. 最小化镜像体积

使用多阶段构建,只包含运行时需要的文件:

# 构建阶段
FROM golang:1.16 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

# 运行阶段
FROM alpine:3.14
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]

3. 启用RBAC权限控制

为不同的用户和服务账号分配最小必要权限:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

5.3 监控与日志最佳实践

1. 部署Prometheus监控

使用Prometheus Operator可以快速部署完整的监控栈:

# 安装Prometheus Operator
kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/main/bundle.yaml

2. 收集应用日志

使用EFK(Elasticsearch + Fluentd + Kibana)或Loki栈收集和分析日志。

3. 配置告警规则

groups:
- name: example
  rules:
  - alert: HighCPUUsage
    expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High CPU usage detected"
      description: "CPU usage is above 80% for more than 5 minutes"

5.4 持续部署最佳实践

1. 使用GitOps工作流

使用ArgoCD或Flux实现GitOps,将Git仓库作为唯一的可信源:

# 安装ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

2. 使用Helm管理应用包

Helm是Kubernetes的包管理器,可以简化复杂应用的部署:

# 安装Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

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

# 安装应用
helm install my-release bitnami/nginx

六、常见问题与解决方案

6.1 Pod 处于 Pending 状态

原因分析:

  • 节点资源不足
  • 没有匹配的节点选择器
  • 持久化卷无法绑定

排查命令:

# 查看Pod详情
kubectl describe pod <pod-name>

# 查看节点资源使用情况
kubectl top nodes

6.2 Service 无法访问

原因分析:

  • 标签选择器不匹配
  • 端口配置错误
  • 网络插件问题

排查命令:

# 查看Service详情
kubectl describe service <service-name>

# 检查Endpoint
kubectl get endpoints <service-name>

# 测试Service连通性
kubectl run -it --rm debug --image=busybox -- sh
wget -O- http://<service-name>.<namespace>.svc.cluster.local

6.3 节点 NotReady

原因分析:

  • kubelet服务异常
  • 网络问题
  • 磁盘压力

排查命令:

# 查看节点详情
kubectl describe node <node-name>

# 在节点上检查kubelet状态
systemctl status kubelet

# 查看kubelet日志
journalctl -u kubelet

七、总结

Kubernetes作为云原生时代的核心技术,已经成为容器编排领域的事实标准。它不仅提供了强大的容器编排能力,还形成了一个庞大的生态系统。

通过本文的学习,你应该已经掌握了:

  1. Kubernetes的核心概念和架构
  2. 使用kubeadm搭建生产级集群的方法
  3. Deployment、Service、ConfigMap、Secret等核心资源的使用
  4. 资源管理、安全、监控等最佳实践
  5. 常见问题的排查思路

在实际应用中,建议遵循以下原则:

  • 从小处开始:先掌握基础用法,再逐步深入高级特性
  • 重视安全:生产环境务必启用RBAC、网络策略等安全机制
  • 自动化优先:结合CI/CD和GitOps实现自动化部署
  • 监控告警:建立完善的监控和告警体系
  • 持续学习:Kubernetes生态发展迅速,保持学习的心态

随着云原生技术的发展,Kubernetes还在不断演进。虽然它有一定的学习曲线,但掌握它将大大提升你的技术能力和职业竞争力。希望本文能帮助你开启Kubernetes的学习之旅,在云原生的道路上越走越远。