项目介绍

Kubernetes(常缩写为 K8s)是 Google 基于内部 Borg 系统的经验开源的容器编排平台,于 2014 年发布,现由 CNCF(云原生计算基金会)维护。它能够自动化容器化应用的部署、扩缩容、负载均衡和自愈,是云原生生态的核心基础设施。

K8s 采用声明式 API 和控制器模式,用户只需描述期望状态,系统自动调谐到目标状态。在 GitHub 上拥有超过 11.5 万星,是全球最活跃的开源项目之一,被 AWS、Azure、GCP 等主流云厂商原生支持。

项目信息详情
发起方Google(现由 CNCF 维护)
GitHub Stars115,000+
官方网站kubernetes.io
开源协议Apache License 2.0
技术栈Go
容器运行时containerd / CRI-O
部署方式kubeadm / minikube / 托管 K8s(EKS/AKS/GKE)
一句话理解:Kubernetes 就像一个"数据中心操作系统" — 你告诉它想要运行什么,它自动决定在哪台机器上运行、挂了怎么恢复、流量大了怎么扩容。

方案对比

容器编排领域有多个方案可选,以下是 Kubernetes 与主流竞品的对比:

特性KubernetesDocker SwarmNomadOpenShift
学习曲线较陡峭简单易学中等较陡峭
生态系统极其丰富较少中等丰富(含企业功能)
自动扩缩容HPA/VPA/CA手动内置内置
服务发现CoreDNS + Service内置 DNSConsul 集成内置
多租户Namespace + RBAC不支持NamespaceProject 级隔离
滚动更新Deployment 内置支持内置内置
云厂商支持EKS/AKS/GKE有限自部署ROSA/ARO
适用场景大规模生产环境小型项目快速部署混合调度(容器+VM)企业级平台
建议:生产环境优先选择 Kubernetes(或托管 K8s);小团队快速验证可考虑 Docker Swarm;需要混合调度可看 Nomad;企业需开箱即用平台可选 OpenShift。

安装部署

方式一minikube 本地开发

适合本地学习和开发,在单节点上运行完整 K8s 集群:

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

# 启动集群
minikube start --driver=docker --cpus=2 --memory=4096

# 验证
kubectl get nodes

方式二kubeadm 生产部署

官方推荐的生产级部署工具,适合自建集群:

# 所有节点安装 kubeadm、kubelet、kubectl
sudo apt-get update && sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

# Master 节点初始化
sudo kubeadm init --pod-network-cidr=10.244.0.0/16

# 配置 kubectl
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config

# 安装网络插件(Flannel)
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

# Worker 节点加入
sudo kubeadm join <master-ip>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>

方式三kind(Kubernetes in Docker)

使用 Docker 容器作为节点,适合 CI/CD 和测试:

# 安装 kind
go install sigs.k8s.io/kind@latest

# 创建多节点集群
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
EOF

kubectl cluster-info --context kind-kind

方式四云托管 K8s

使用云厂商的托管服务,免维护控制面:

# AWS EKS
eksctl create cluster --name my-cluster --region ap-east-1 --nodes 3

# Google GKE
gcloud container clusters create my-cluster --zone asia-east1-a --num-nodes 3

# Azure AKS
az aks create -g myRG -n myCluster --node-count 3
推荐:生产环境优先使用托管 K8s,省去控制面运维成本。

核心概念

概念一Pod — 最小调度单元

Pod 是 K8s 中最小的可部署单元,包含一个或多个共享网络和存储的容器。每个 Pod 拥有独立 IP。

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    ports:
    - containerPort: 80

概念二Service — 服务发现与负载均衡

Service 为一组 Pod 提供稳定的访问入口(ClusterIP),支持 ClusterIP、NodePort、LoadBalancer 三种类型。

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

概念三Deployment — 声明式部署与滚动更新

Deployment 管理 ReplicaSet,支持声明式更新、回滚、扩缩容,是最常用的工作负载控制器。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 250m
            memory: 256Mi

概念四ConfigMap & Secret — 配置管理

ConfigMap 存储非敏感配置,Secret 存储敏感数据(如密码、证书),均可以环境变量或卷挂载方式注入 Pod。

# 创建 ConfigMap
kubectl create configmap app-config --from-literal=DB_HOST=mysql --from-literal=DB_PORT=3306

# 创建 Secret
kubectl create secret generic db-secret --from-literal=DB_PASS=mypassword

# 在 Pod 中使用
env:
- name: DB_HOST
  valueFrom:
    configMapKeyRef:
      name: app-config
      key: DB_HOST

概念五Namespace — 资源隔离

Namespace 提供逻辑隔离,适合多团队、多环境共用同一集群。可配合 ResourceQuota 和 NetworkPolicy 实现资源与网络隔离。

# 创建命名空间
kubectl create namespace production
kubectl create namespace staging

# 在指定命名空间部署
kubectl apply -f deploy.yaml -n production

# 设置资源配额
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: production
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi

概念六Ingress — 外部流量入口

Ingress 提供 HTTP/HTTPS 路由规则,将外部流量导入集群内 Service。需配合 Ingress Controller(如 nginx-ingress)使用。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-svc
            port:
              number: 80

实战部署

实战一部署 Nginx Web 服务

kubectl create deployment nginx --image=nginx:1.25 --replicas=3
kubectl expose deployment nginx --port=80 --type=LoadBalancer
kubectl get svc nginx

实战二部署 MySQL 有状态服务

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: DB_PASS
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: mysql-data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi

实战三使用 Helm 部署应用

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

# 添加仓库并安装
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-redis bitnami/redis --set auth.password=mypass
helm list

实战四配置 HPA 自动扩缩容

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-deploy
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

实战五CronJob 定时任务

apiVersion: batch/v1
kind: CronJob
metadata:
  name: db-backup
spec:
  schedule: "0 2 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: mysql:8.0
            command: ["mysqldump", "-h", "mysql", "-u", "root", "-p$(DB_PASS)", "--all-databases"]
          restartPolicy: OnFailure

实战六配置 NetworkPolicy 网络隔离

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - port: 8080

运维监控

运维一Prometheus + Grafana 监控

使用 kube-prometheus-stack 一键部署完整监控栈:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install monitoring prometheus-community/kube-prometheus-stack -n monitoring --create-namespace

# 访问 Grafana
kubectl port-forward svc/monitoring-grafana 3000:80 -n monitoring
# 默认用户 admin,密码 prom-operator
推荐:生产环境务必监控 Node、Pod、API Server、etcd 的核心指标。

运维二日志收集(EFK 栈)

使用 Elasticsearch + Fluentd + Kibana 收集和查询日志:

# 使用 Helm 部署 EFK
helm install elasticsearch elastic/elasticsearch -n logging --create-namespace
helm install kibana elastic/kibana -n logging
helm install fluentd bitnami/fluentd -n logging

# 查看实时日志
kubectl logs -f deployment/nginx-deploy --all-containers=true
kubectl logs --previous pod-name  # 查看崩溃前日志

运维三集群备份与恢复(Velero)

使用 Velero 备份集群资源和持久卷数据:

# 安装 Velero
velero install --provider aws --bucket my-backup \
  --secret-file ./credentials-velero --backup-location-config region=ap-east-1

# 创建备份
velero backup create daily-backup --include-namespaces production

# 恢复
velero restore create --from-backup daily-backup

# 定期备份
velero schedule create daily --schedule="0 3 * * *" --include-namespaces production
注意:务必定期测试恢复流程,备份不验证等于没有备份。

常见问题 (30 个)

Q01Pod 一直处于 Pending 状态

Warning FailedScheduling 0/3 nodes are available: 3 Insufficient cpu.

节点资源不足。检查资源请求:kubectl describe pod <name>,降低 requests 或扩容节点。

Q02Pod CrashLoopBackOff

Back-off restarting failed container

容器反复崩溃。查看日志:kubectl logs <pod> --previous,常见原因:启动命令错误、缺少配置、OOM。

Q03ImagePullBackOff 镜像拉取失败

Failed to pull image "myrepo/app:v1": rpc error: code = Unknown desc = Error response from daemon: pull access denied

检查镜像名是否正确、私有仓库需创建 imagePullSecret:

kubectl create secret docker-registry regcred --docker-server=<server> --docker-username=<user> --docker-password=<pass>

Q04Service 无法访问后端 Pod

curl: (7) Failed to connect to service-ip port 80: Connection refused

检查 selector 标签是否匹配:kubectl get endpoints <svc>。如果 ENDPOINTS 为空,说明标签不匹配。

Q05kubectl 连接集群超时

Unable to connect to the server: dial tcp 10.0.0.1:6443: i/o timeout

检查 kubeconfig 配置:kubectl config view,确认 API Server 地址正确、网络连通、防火墙放行 6443 端口。

Q06Node NotReady

node/worker-1 NotReady <none> 5d v1.28.2

检查 kubelet 状态:systemctl status kubelet,常见原因:磁盘压力、内存压力、容器运行时故障。查看 kubectl describe node worker-1 的 Conditions。

Q07PVC 一直处于 Pending

waiting for a volume to be created, either by external provisioner or manually created by system administrator

检查 StorageClass 是否存在:kubectl get sc,确认 CSI 驱动已安装。若使用默认 SC,确认已标注 storageclass.kubernetes.io/is-default-class: "true"

Q08OOMKilled 内存溢出

Last State: Terminated Reason: OOMKilled Exit Code: 137

容器使用内存超过 limits。增加 resources.limits.memory,或优化应用内存使用。Java 应用需设置 -XX:MaxRAMPercentage=75

Q09DNS 解析失败

nslookup: can't resolve 'kubernetes.default' server: 10.96.0.10

检查 CoreDNS 是否正常:kubectl get pods -n kube-system -l k8s-app=kube-dns。如果 Pod 异常,删除重建或检查 CoreDNS 配置。

Q10Ingress 返回 404

default backend - 404

检查 Ingress 规则中的 host、path、backend service 是否正确。确认 Ingress Controller 已部署:kubectl get pods -n ingress-nginx

Q11RBAC 权限被拒绝

Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:default" cannot list resource "pods"

需要创建 Role/ClusterRole 和 RoleBinding:

kubectl create clusterrolebinding sa-admin --clusterrole=admin --serviceaccount=default:default

Q12Pod 被 Evicted 驱逐

Status: Failed Reason: Evicted Message: The node was low on resource: ephemeral-storage.

节点磁盘空间不足导致驱逐。清理日志和镜像:docker system prune -a,或增加节点磁盘。设置合理的 ephemeral-storage limits。

Q13Deployment 更新卡住

Waiting for deployment "app" rollout to finish: 1 old replicas are pending termination...

新 Pod 无法就绪或旧 Pod 无法终止。检查 readinessProbe 配置,查看 kubectl rollout status deployment/app。可回滚:kubectl rollout undo deployment/app

Q14etcd 磁盘空间不足

etcdserver: mvcc: database space exceeded

执行 etcd 压缩和碎片整理:

etcdctl compact $(etcdctl endpoint status --write-out="json" | jq '.[0].Status.header.revision')
etcdctl defrag

Q15证书过期导致集群异常

x509: certificate has expired or is not yet valid

检查证书过期时间:kubeadm certs check-expiration。续期:kubeadm certs renew all,然后重启控制面组件。

Q16Pod 无法挂载 Volume

MountVolume.SetUp failed for volume "data": mount failed: exit status 32

检查 PV/PVC 状态是否 Bound,确认存储后端(NFS/EBS/Ceph)可用。多节点挂载需使用 ReadWriteMany 模式的存储。

Q17容器 Liveness 探针失败不断重启

Liveness probe failed: HTTP probe failed with statuscode: 503

调整探针参数:增加 initialDelaySeconds(应用启动慢时)、增大 timeoutSeconds、增大 failureThreshold

Q18HPA 不生效 / 无法获取指标

unable to get metrics for resource cpu: no metrics known for pod

确认 metrics-server 已部署:kubectl top nodes。安装:kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

Q19kubectl apply 报 invalid 错误

error: error validating "deploy.yaml": error validating data: ValidationError(Deployment.spec): missing required field "selector"

YAML 格式错误。使用 kubectl apply --dry-run=client -f deploy.yaml 预校验。确认 apiVersion 和必填字段正确。

Q20NodePort 外部无法访问

curl: (7) Failed to connect to node-ip port 30080: No route to host

检查防火墙是否放行 NodePort 范围(默认 30000-32767):iptables -L -n 或云安全组规则。确认 kube-proxy 正常运行。

Q21Pod 间网络不通

ping: connect: Network is unreachable

检查 CNI 插件(Flannel/Calico/Cilium)是否正常:kubectl get pods -n kube-system。排查 iptables 规则和 NetworkPolicy 是否阻断了流量。

Q22kubectl exec 进入容器失败

error: unable to upgrade connection: pod does not exist

确认 Pod 正在运行:kubectl get pod <name>。如果使用代理,确认 API Server 到 kubelet 的 10250 端口连通。

Q23Helm release 安装失败

Error: INSTALLATION FAILED: cannot re-use a name that is still in use

先卸载旧 release:helm uninstall <name>。如果卡在 pending 状态:helm list -a 查看后 helm delete <name> --no-hooks

Q24ResourceQuota 限制导致创建失败

Error from server (Forbidden): exceeded quota: compute-quota, requested: requests.cpu=500m, used: requests.cpu=3800m, limited: requests.cpu=4

命名空间资源配额不足。调整 ResourceQuota 或优化现有工作负载的资源请求。查看:kubectl describe quota -n <ns>

Q25Taint/Toleration 导致 Pod 无法调度

0/3 nodes are available: 3 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }

Worker 节点不足或有 Taint。添加 toleration 或移除 taint:kubectl taint nodes <node> node-role.kubernetes.io/control-plane:NoSchedule-

Q26ConfigMap 更新后 Pod 未生效

应用仍使用旧配置

环境变量引用的 ConfigMap 不会自动更新,需重启 Pod:kubectl rollout restart deployment/<name>。卷挂载的 ConfigMap 会自动更新(有延迟)。

Q27kubectl 版本与集群不兼容

error: the server doesn't have a resource type "horizontalpodautoscalers" in version "autoscaling/v2"

kubectl 版本应与集群版本偏差不超过一个小版本。升级 kubectl:curl -LO "https://dl.k8s.io/release/$(curl -sL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

Q28StatefulSet Pod 删除后卡住

pod "mysql-0" has DeletionTimestamp but is stuck in Terminating

可能是 finalizer 阻塞或 preStop hook 超时。强制删除:kubectl delete pod mysql-0 --grace-period=0 --force。生产环境慎用。

Q29API Server 响应慢

The connection to the server was refused or timed out. Response took 30s.

检查 etcd 性能、API Server 负载。kubectl get --raw /healthz 验证健康状态。可能需要增加 etcd 磁盘 IOPS 或扩展 API Server 副本。

Q30集群升级失败

couldn't upgrade control plane. kubeadm has tried to recover, but the cluster may be in an inconsistent state

升级前必须备份 etcd:etcdctl snapshot save backup.db。遵循逐版本升级原则(不跨大版本)。检查 kubeadm upgrade plan 和弃用 API。