Kubernetes(常缩写为 K8s)是 Google 基于内部 Borg 系统的经验开源的容器编排平台,于 2014 年发布,现由 CNCF(云原生计算基金会)维护。它能够自动化容器化应用的部署、扩缩容、负载均衡和自愈,是云原生生态的核心基础设施。
K8s 采用声明式 API 和控制器模式,用户只需描述期望状态,系统自动调谐到目标状态。在 GitHub 上拥有超过 11.5 万星,是全球最活跃的开源项目之一,被 AWS、Azure、GCP 等主流云厂商原生支持。
| 项目信息 | 详情 |
|---|---|
| 发起方 | Google(现由 CNCF 维护) |
| GitHub Stars | 115,000+ |
| 官方网站 | kubernetes.io |
| 开源协议 | Apache License 2.0 |
| 技术栈 | Go |
| 容器运行时 | containerd / CRI-O |
| 部署方式 | kubeadm / minikube / 托管 K8s(EKS/AKS/GKE) |
容器编排领域有多个方案可选,以下是 Kubernetes 与主流竞品的对比:
| 特性 | Kubernetes | Docker Swarm | Nomad | OpenShift |
|---|---|---|---|---|
| 学习曲线 | 较陡峭 | 简单易学 | 中等 | 较陡峭 |
| 生态系统 | 极其丰富 | 较少 | 中等 | 丰富(含企业功能) |
| 自动扩缩容 | HPA/VPA/CA | 手动 | 内置 | 内置 |
| 服务发现 | CoreDNS + Service | 内置 DNS | Consul 集成 | 内置 |
| 多租户 | Namespace + RBAC | 不支持 | Namespace | Project 级隔离 |
| 滚动更新 | Deployment 内置 | 支持 | 内置 | 内置 |
| 云厂商支持 | EKS/AKS/GKE | 有限 | 自部署 | ROSA/ARO |
| 适用场景 | 大规模生产环境 | 小型项目快速部署 | 混合调度(容器+VM) | 企业级平台 |
适合本地学习和开发,在单节点上运行完整 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、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>
使用 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
使用云厂商的托管服务,免维护控制面:
# 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
Pod 是 K8s 中最小的可部署单元,包含一个或多个共享网络和存储的容器。每个 Pod 拥有独立 IP。
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
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 管理 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 存储敏感数据(如密码、证书),均可以环境变量或卷挂载方式注入 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 提供逻辑隔离,适合多团队、多环境共用同一集群。可配合 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 提供 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
kubectl create deployment nginx --image=nginx:1.25 --replicas=3 kubectl expose deployment nginx --port=80 --type=LoadBalancer kubectl get svc nginx
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 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
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
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
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
使用 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
使用 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 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
节点资源不足。检查资源请求:kubectl describe pod <name>,降低 requests 或扩容节点。
容器反复崩溃。查看日志:kubectl logs <pod> --previous,常见原因:启动命令错误、缺少配置、OOM。
检查镜像名是否正确、私有仓库需创建 imagePullSecret:
kubectl create secret docker-registry regcred --docker-server=<server> --docker-username=<user> --docker-password=<pass>
检查 selector 标签是否匹配:kubectl get endpoints <svc>。如果 ENDPOINTS 为空,说明标签不匹配。
检查 kubeconfig 配置:kubectl config view,确认 API Server 地址正确、网络连通、防火墙放行 6443 端口。
检查 kubelet 状态:systemctl status kubelet,常见原因:磁盘压力、内存压力、容器运行时故障。查看 kubectl describe node worker-1 的 Conditions。
检查 StorageClass 是否存在:kubectl get sc,确认 CSI 驱动已安装。若使用默认 SC,确认已标注 storageclass.kubernetes.io/is-default-class: "true"。
容器使用内存超过 limits。增加 resources.limits.memory,或优化应用内存使用。Java 应用需设置 -XX:MaxRAMPercentage=75。
检查 CoreDNS 是否正常:kubectl get pods -n kube-system -l k8s-app=kube-dns。如果 Pod 异常,删除重建或检查 CoreDNS 配置。
检查 Ingress 规则中的 host、path、backend service 是否正确。确认 Ingress Controller 已部署:kubectl get pods -n ingress-nginx。
需要创建 Role/ClusterRole 和 RoleBinding:
kubectl create clusterrolebinding sa-admin --clusterrole=admin --serviceaccount=default:default
节点磁盘空间不足导致驱逐。清理日志和镜像:docker system prune -a,或增加节点磁盘。设置合理的 ephemeral-storage limits。
新 Pod 无法就绪或旧 Pod 无法终止。检查 readinessProbe 配置,查看 kubectl rollout status deployment/app。可回滚:kubectl rollout undo deployment/app。
执行 etcd 压缩和碎片整理:
etcdctl compact $(etcdctl endpoint status --write-out="json" | jq '.[0].Status.header.revision') etcdctl defrag
检查证书过期时间:kubeadm certs check-expiration。续期:kubeadm certs renew all,然后重启控制面组件。
检查 PV/PVC 状态是否 Bound,确认存储后端(NFS/EBS/Ceph)可用。多节点挂载需使用 ReadWriteMany 模式的存储。
调整探针参数:增加 initialDelaySeconds(应用启动慢时)、增大 timeoutSeconds、增大 failureThreshold。
确认 metrics-server 已部署:kubectl top nodes。安装:kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
YAML 格式错误。使用 kubectl apply --dry-run=client -f deploy.yaml 预校验。确认 apiVersion 和必填字段正确。
检查防火墙是否放行 NodePort 范围(默认 30000-32767):iptables -L -n 或云安全组规则。确认 kube-proxy 正常运行。
检查 CNI 插件(Flannel/Calico/Cilium)是否正常:kubectl get pods -n kube-system。排查 iptables 规则和 NetworkPolicy 是否阻断了流量。
确认 Pod 正在运行:kubectl get pod <name>。如果使用代理,确认 API Server 到 kubelet 的 10250 端口连通。
先卸载旧 release:helm uninstall <name>。如果卡在 pending 状态:helm list -a 查看后 helm delete <name> --no-hooks。
命名空间资源配额不足。调整 ResourceQuota 或优化现有工作负载的资源请求。查看:kubectl describe quota -n <ns>。
Worker 节点不足或有 Taint。添加 toleration 或移除 taint:kubectl taint nodes <node> node-role.kubernetes.io/control-plane:NoSchedule-
环境变量引用的 ConfigMap 不会自动更新,需重启 Pod:kubectl rollout restart deployment/<name>。卷挂载的 ConfigMap 会自动更新(有延迟)。
kubectl 版本应与集群版本偏差不超过一个小版本。升级 kubectl:curl -LO "https://dl.k8s.io/release/$(curl -sL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
可能是 finalizer 阻塞或 preStop hook 超时。强制删除:kubectl delete pod mysql-0 --grace-period=0 --force。生产环境慎用。
检查 etcd 性能、API Server 负载。kubectl get --raw /healthz 验证健康状态。可能需要增加 etcd 磁盘 IOPS 或扩展 API Server 副本。
升级前必须备份 etcd:etcdctl snapshot save backup.db。遵循逐版本升级原则(不跨大版本)。检查 kubeadm upgrade plan 和弃用 API。