Kubernetes

什么是 Kubernetes

Kubernetes(简称 K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。它由 Google 开发并捐赠给云原生计算基金会(CNCF)。

核心功能

  • 服务发现与负载均衡:自动将流量分发到多个容器实例
  • 存储编排:自动挂载存储系统(本地存储、云存储等)
  • 自动部署和回滚:管理应用的发布版本,支持快速回滚
  • 自动装箱:根据资源需求和约束自动调度容器
  • 自我修复:自动重启失败容器、替换和重新调度异常节点上的容器
  • 密钥和配置管理:管理敏感信息和应用配置

应用场景

  • 微服务架构部署与管理
  • 持续集成/持续部署(CI/CD)
  • 混合云和多云环境管理
  • 大数据处理
  • 机器学习训练与推理

安装 Kubernetes

这里使用的是kubeasz来安装 Kubernetes。

在学习阶段可以使用all in one来安装 Kubernetes。

架构组件

Kubernetes 采用主从架构,主要分为控制平面(Control Plane)和工作节点(Worker Node)两部分。

控制平面组件

控制平面负责管理集群状态,做出全局决策。

kube-apiserver

集群的统一入口,所有请求都通过 API Server 进行处理。提供认证、授权、访问控制、API 注册和发现等机制。

etcd

高可用的键值数据库,用于存储集群所有状态数据。是 Kubernetes 的唯一数据源。

kube-scheduler

负责 Pod 的调度,根据资源需求、策略约束、亲和性规则等将 Pod 分配到合适的节点。

kube-controller-manager

运行控制器进程,包括:

  • 节点控制器(Node Controller)
  • 副本控制器(Replication Controller)
  • 端点控制器(Endpoints Controller)
  • 服务账户和令牌控制器(Service Account & Token Controllers)

cloud-controller-manager

将集群连接到云服务商的 API,实现与云平台的集成。

工作节点组件

工作节点负责运行容器组。

kubelet

节点上的主要代理,负责:

  • 监听 API Server 的调度指令
  • 挂载 Pod 所需的存储卷
  • 下载 Pod 所需的 Secret
  • 通过容器运行时接口(CRI)运行容器
  • 定期执行容器健康检查

kube-proxy

网络代理,维护节点上的网络规则,实现 Service 的负载均衡和转发。

容器运行时(Container Runtime)

负责运行容器的软件,如 containerd、CRI-O、Docker Engine 等。

核心概念

Pod

Pod 是 Kubernetes 中最小的部署单元,包含一个或多个容器。同一个 Pod 内的容器共享网络命名空间和存储卷。

Namespace

用于在集群内实现资源隔离,不同命名空间的资源相互隔离。

Node

集群中的工作机器,可以是物理机或虚拟机。

基础资源对象

Pod

Pod 是 Kubernetes 中最小的部署单元。

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80
    resources:
      # 一般生产环境最好请求和限制的资源设置为一样, 保证最大性能
      requests:
        cpu: "250m"       # 请求 CPU 资源 0.25 核
        memory: "64Mi"    # 请求内存 64MB
      limits:
        cpu: "500m"       # 限制最大 CPU 资源 0.5 核
        memory: "128Mi"   # 限制最大内存 128MB

Deployment

Deployment 提供声明式更新能力,管理 Pod 的副本数量和版本。

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

Service 定义一组 Pod 的访问策略,提供稳定的访问入口。

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: ClusterIP

Service 类型说明:

  • ClusterIP:集群内部访问(默认)
  • NodePort:通过节点端口暴露服务
  • LoadBalancer:使用云厂商的负载均衡器
  • ExternalName:映射到外部 DNS 名称

ConfigMap

用于存储非敏感配置数据。

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  database_host: "mysql-service"
  database_port: "3306"
  cache_ttl: "3600"

Secret

用于存储敏感信息,如密码、令牌、密钥等。

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

PersistentVolume 和 PersistentVolumeClaim

用于持久化存储管理。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-storage
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: standard
  hostPath:
    path: /mnt/data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-storage
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard

常用命令

集群管理

kubectl cluster-info
kubectl get nodes
kubectl describe node <node-name>
kubectl top nodes

资源查看

kubectl get pods
kubectl get pods -o wide
kubectl get pods --all-namespaces
kubectl get deployments
kubectl get services
kubectl get all

kubectl describe pod <pod-name>
kubectl logs <pod-name>
kubectl logs -f <pod-name>
kubectl exec -it <pod-name> -- /bin/bash

资源创建与更新

kubectl apply -f deployment.yaml
kubectl create -f deployment.yaml
kubectl edit deployment <deployment-name>
kubectl scale deployment <deployment-name> --replicas=5
kubectl set image deployment/<deployment-name> <container-name>=<new-image>

资源删除

kubectl delete -f deployment.yaml
kubectl delete pod <pod-name>
kubectl delete deployment <deployment-name>
kubectl delete service <service-name>

配置管理

kubectl create configmap <config-name> --from-literal=key=value
kubectl create configmap <config-name> --from-file=path/to/file
kubectl create secret generic <secret-name> --from-literal=key=value

kubectl get configmaps
kubectl get secrets
kubectl describe configmap <config-name>

调试与排查

kubectl describe pod <pod-name>
kubectl logs <pod-name> --previous
kubectl exec -it <pod-name> -- /bin/sh
kubectl port-forward <pod-name> 8080:80
kubectl cp <pod-name>:/path/to/file ./local-file

Helm 包管理器

Helm 是 Kubernetes 的包管理器,类似于 Linux 的 yum 或 apt,用于简化应用的部署和管理。

官方文档

核心概念

  • Chart:应用包,包含一组 Kubernetes 资源定义文件
  • Release:Chart 的一次安装实例
  • Repository:Chart 的存储仓库

安装 Helm

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-4
chmod 700 get_helm.sh
./get_helm.sh

常用命令

helm repo add <repo-name> <repo-url>
helm repo update
helm search repo <chart-name>
helm install <release-name> <chart> -n <namespace>
helm upgrade <release-name> <chart> -n <namespace>
helm rollback <release-name> <revision> -n <namespace>
helm uninstall <release-name> -n <namespace>
helm list -n <namespace>
helm status <release-name> -n <namespace>

Traefik 网关

Traefik 是一个现代化的 HTTP 反向代理和负载均衡器,专为微服务架构设计。

官方文档

安装 Traefik

helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik -n traefik --create-namespace --values values.yaml

配置示例

values.yaml
deployment:
  hostNetwork: true
  dnsPolicy: ClusterFirstWithHostNet

ports:
  web:
    port: 80
    hostPort: 80

  websecure:
    port: 443
    hostPort: 443

  port-40050:
    port: 40050
    hostPort: 40050

  port-40033:
    port: 40033
    hostPort: 40033

api:
  dashboard: true
  insecure: false

ingressClass:
  enabled: false

providers:
  kubernetesIngress:
    enabled: false
  kubernetesGateway:
    enabled: true

gateway:
  listeners:
    web:
      port: 80
      protocol: HTTP
      namespacePolicy:
        from: All

    websecure:
      port: 443
      protocol: HTTPS
      namespacePolicy:
        from: All
      mode: Terminate
      certificateRefs:
        - kind: Secret
          name: local-selfsigned-tls
          group: ""

    port-40050:
      port: 40050
      protocol: HTTP
      namespacePolicy:
        from: All

    port-40033:
      port: 40033
      protocol: HTTPS
      namespacePolicy:
        from: All
      mode: Terminate
      certificateRefs:
        - kind: Secret
          name: local-selfsigned-tls
          group: ""

logs:
  general:
    level: INFO
  access:
    enabled: true

metrics:
  prometheus:
    enabled: true

测试部署

部署一个测试服务验证 Traefik 路由功能:

whoami-test.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami-test
  namespace: traefik
spec:
  replicas: 1
  selector:
    matchLabels:
      app: whoami-test
  template:
    metadata:
      labels:
        app: whoami-test
    spec:
      containers:
        - name: whoami
          image: traefik/whoami
          ports:
            - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: whoami-test-svc
  namespace: traefik
spec:
  selector:
    app: whoami-test
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
    - name: port-40050
      port: 40050
      targetPort: 80
    - name: port-40033
      port: 40033
      targetPort: 80
  type: ClusterIP

---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: whoami-test
  namespace: traefik
spec:
  parentRefs:
    - name: traefik-gateway
  hostnames:
    - "whoami.k8s.tteam.icu"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: whoami-test-svc
          port: 80
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: whoami-test-svc
          port: 40050
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: whoami-test-svc
          port: 40033

最佳实践

资源限制

为所有容器设置资源请求和限制,避免资源争抢:

resources:
  # 一般生产环境最好请求和限制的资源设置为一样, 保证最大性能
  requests:
    cpu: "250m"       # 请求 CPU 资源 0.25 核
    memory: "64Mi"    # 请求内存 64MB
  limits:
    cpu: "500m"       # 限制最大 CPU 资源 0.5 核
    memory: "128Mi"   # 限制最大内存 128MB

健康检查

配置存活探针和就绪探针:

livenessProbe:
  httpGet:
    path: /health
    port: 80
  initialDelaySeconds: 30
  periodSeconds: 10

readinessProbe:
  httpGet:
    path: /ready
    port: 80
  initialDelaySeconds: 5
  periodSeconds: 5

安全配置

  • 使用非 root 用户运行容器
  • 设置只读文件系统
  • 限制能力(Capabilities)
  • 使用 Pod Security Standards
securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  readOnlyRootFilesystem: true
  capabilities:
    drop:
      - ALL

配置管理

  • 使用 ConfigMap 管理应用配置
  • 使用 Secret 管理敏感信息
  • 使用环境变量注入配置

版本控制

  • 使用 GitOps 管理集群配置
  • 使用声明式配置而非命令式
  • 保持配置文件的版本化

故障排查

Pod 状态异常

kubectl describe pod <pod-name>
kubectl logs <pod-name>
kubectl get events --sort-by='.lastTimestamp'

服务无法访问

kubectl get endpoints <service-name>
kubectl describe service <service-name>
kubectl exec -it <pod-name> -- nslookup <service-name>

持久化存储问题

kubectl get pv
kubectl get pvc
kubectl describe pvc <pvc-name>

节点问题

kubectl describe node <node-name>
kubectl get events --field-selector involvedObject.kind=Node