Kubernetes 完全指南:从零基础到生产实践
本文定位 :一篇适合新手入门、中手查漏补缺、老手温故知新的 K8s 百科全书。全文约 15000 字 ,建议收藏后分章节阅读。
📚 目录
为什么需要 Kubernetes? 核心概念与架构 安装与配置 kubectl 完全命令手册 第一个应用部署(实操) 核心资源对象详解 进阶调度与弹性伸缩 存储管理 PV/PVC 网络模型与 Ingress 配置管理 ConfigMap/Secret Helm 包管理 CI/CD 与 GitOps 监控与日志 常见故障排查 生产环境最佳实践
1. 为什么需要 Kubernetes?
1.1 从单体到微服务的演进
痛点 :
微服务数量爆炸(几十上百个服务) 部署频繁(一天多次发布) 环境不一致(开发/测试/生产差异大) 资源利用率低(服务器闲置浪费)
1.2 Kubernetes 能做什么?
能力 说明 类比 自动装箱 根据资源需求自动调度容器到合适节点 智能物流分拣 自我修复 容器挂了自动重启,节点宕机自动迁移 自愈能力 水平扩展 根据 CPU/内存自动增减 Pod 数量 弹性伸缩 服务发现 自动为 Pod 分配 DNS 和 IP,负载均衡 内置服务注册中心 滚动更新 零停机发布,异常自动回滚 金丝雀发布 存储编排 自动挂载云存储、NFS、本地盘 自动挂载硬盘
1.3 K8s 不是什么?
❌ 不是 PaaS(平台即服务)—— 它不限制你用什么语言/框架 ❌ 不是 传统的 CI/CD 工具 —— 它只管部署,不负责构建 ❌ 不是 容器运行时 —— 它依赖 Docker/containerd 来运行容器 ❌ 不是 配置管理工具 —— 它用声明式 YAML,不用 Ansible/Puppet 那种命令式脚本
2. 核心概念与架构
2.1 整体架构图
2.2 组件详解
组件 位置 作用 关键点 kube-apiserver 控制平面 集群唯一入口,REST API 服务 所有操作都经过它,是集群的"前台" etcd 控制平面 分布式键值存储,保存所有集群数据 必须备份 ,损坏则集群无法恢复kube-scheduler 控制平面 为新 Pod 选择最优节点 考虑资源、亲和性、污点等 kube-controller-manager 控制平面 运行所有控制器(Deployment、Node 等) 确保实际状态与期望状态一致 cloud-controller-manager 控制平面 与云厂商交互(负载均衡、存储卷) 云上集群才有 kubelet 工作节点 管理 Pod 生命周期 与 API Server 通信,汇报节点状态 kube-proxy 工作节点 维护网络规则,实现 Service 负载均衡 支持 iptables/IPVS 模式 容器运行时 工作节点 实际运行容器 containerd、CRI-O、Docker
2.3 核心资源对象层级
2.4 核心资源对象速查表
资源类型 缩写 作用 有状态? Pod po最小部署单元,一个或多个容器 ❌ Deployment deploy无状态应用,滚动更新/回滚 ❌ StatefulSet sts有状态应用(数据库),稳定标识 ✅ DaemonSet ds每个节点跑一个 Pod(监控、日志) ❌ Job job一次性任务 ❌ CronJob cj定时任务 ❌ Service svc稳定访问入口,负载均衡 ❌ Ingress ing七层路由(域名/路径转发) ❌ ConfigMap cm非敏感配置项 ❌ Secret secret敏感信息(密码/证书) ❌ PersistentVolume pv集群级存储资源 ✅ PersistentVolumeClaim pvc存储资源申请 ❌ Namespace ns资源隔离 ❌ ServiceAccount saPod 身份认证 ❌
3. 安装与配置
3.1 本地开发环境
方式 适用场景 资源消耗 难度 Minikube 单节点本地学习 低 ⭐⭐ Kind 多节点本地测试 中 ⭐⭐⭐ K3s 轻量级生产/边缘 极低 ⭐⭐ Docker Desktop Mac/Windows 内置 低 ⭐ Play with K8s 在线免费体验 零 ⭐
3.1.1 Minikube 安装(推荐新手)
choco install minikube
brew install 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
3.1.2 Kind 安装(需先安装 Docker)
choco install kind
brew install kind
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
kind create cluster --name my-cluster --config - << EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
EOF
kubectl cluster-info --context kind-my-cluster
3.2 生产环境安装
方式 适用场景 复杂度 kubeadm 自建集群(裸金属/虚拟机) ⭐⭐⭐⭐ 云厂商托管 阿里云 ACK、腾讯云 TKE、AWS EKS ⭐ Rancher 多集群管理 ⭐⭐⭐
3.2.1 kubeadm 快速搭建(生产级)
apt-get update && apt-get install -y kubeadm kubelet kubectl
kubeadm init --pod-network-cidr= 10.244 .0.0/16
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/projectcalico/calico/v3.27/manifests/calico.yaml
kubeadm join < 控制平面IP> :6443 --token < token> --discovery-token-ca-cert-hash sha256:< hash>
kubectl get nodes
3.3 kubectl 配置
kubectl config view
kubectl config use-context docker-desktop
kubectl config get-contexts
kubectl config set-context --current --namespace = my-ns
source < ( kubectl completion bash )
echo "source <(kubectl completion bash)" >> ~/.bashrc
source < ( kubectl completion zsh )
echo "source <(kubectl completion zsh)" >> ~/.zshrc
4. kubectl 完全命令手册
4.1 命令结构
kubectl [ command] [ TYPE] [ NAME] [ flags]
部分 说明 示例 command操作类型 get, create, apply, delete, describe, logsTYPE资源类型 pod, deployment, serviceNAME资源名称 my-podflags额外参数 -n namespace, -o yaml
4.2 基础命令(每日必用)
kubectl get nodes
kubectl get pods
kubectl get pods -n kube-system
kubectl get pods -o wide
kubectl get pods -o yaml
kubectl get pods -o json
kubectl get pods -w
kubectl get all
kubectl describe pod my-pod
kubectl describe node node-1
kubectl apply -f deployment.yaml
kubectl create deployment nginx --image = nginx --replicas = 3
kubectl run nginx --image = nginx
kubectl expose deployment nginx --port = 80 --type = NodePort
kubectl delete pod my-pod
kubectl delete deployment nginx
kubectl delete -f deployment.yaml
kubectl delete pod --all
kubectl logs my-pod
kubectl logs my-pod -c container-1
kubectl logs -f my-pod
kubectl logs --tail = 100 my-pod
kubectl logs --since = 1h my-pod
kubectl exec -it my-pod -- /bin/bash
kubectl exec my-pod -- ls /app
kubectl port-forward pod/my-pod 8080 :80
kubectl port-forward service/my-svc 8080 :80
kubectl explain pod
kubectl api-resources
kubectl version
4.3 高级命令
kubectl set image deployment/nginx nginx = nginx:1.20
kubectl rollout status deployment/nginx
kubectl rollout history deployment/nginx
kubectl rollout undo deployment/nginx
kubectl rollout undo deployment/nginx --to-revision= 2
kubectl rollout pause deployment/nginx
kubectl rollout resume deployment/nginx
kubectl scale deployment/nginx --replicas = 5
kubectl autoscale deployment/nginx --min = 2 --max = 10 --cpu-percent= 80
kubectl label pods my-pod app = web
kubectl label pods my-pod app-
kubectl get pods -l app = web
kubectl create namespace my-ns
kubectl get ns
kubectl config set-context --current --namespace = my-ns
kubectl top nodes
kubectl top pods
kubectl get events --sort-by= '.lastTimestamp'
kubectl get events -n kube-system
kubectl describe pod my-pod | grep -A 10 "Events"
kubectl logs -n kube-system kube-apiserver-< node>
kubectl exec my-pod -- top
kubectl exec my-pod -- cat /proc/meminfo
4.4 常用别名配置(提高效率)
alias k = 'kubectl'
alias kgp = 'kubectl get pods'
alias kgd = 'kubectl get deployment'
alias kgs = 'kubectl get service'
alias kgn = 'kubectl get nodes'
alias kdp = 'kubectl describe pod'
alias kdd = 'kubectl describe deployment'
alias kl = 'kubectl logs'
alias kex = 'kubectl exec -it'
alias kaf = 'kubectl apply -f'
alias kdf = 'kubectl delete -f'
alias kgpw = 'kubectl get pods -o wide'
alias kgpa = 'kubectl get pods --all-namespaces'
5. 第一个应用部署(实操)
5.1 完整流程
5.2 步骤详解
步骤 1:准备一个简单的应用
创建一个 app.py(Flask 示例):
from flask import Flask
import os
import socket
app = Flask( __name__)
@app. route ( '/' )
def hello ( ) :
return {
'message' : 'Hello Kubernetes!' ,
'hostname' : socket. gethostname( ) ,
'version' : 'v1'
}
@app. route ( '/health' )
def health ( ) :
return { 'status' : 'ok' }
if __name__ == '__main__' :
app. run( host= '0.0.0.0' , port= 5000 )
步骤 2:编写 Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
COPY app.py .
EXPOSE 5000
CMD ["python", "app.py"]
步骤 3:构建并推送镜像
docker build -t myapp:v1 .
docker tag myapp:v1 yourusername/myapp:v1
docker push yourusername/myapp:v1
步骤 4:编写 Kubernetes 部署文件
deployment.yaml:
apiVersion : apps/v1
kind : Deployment
metadata :
name : myapp
namespace : default
labels :
app : myapp
spec :
replicas : 3
selector :
matchLabels :
app : myapp
template :
metadata :
labels :
app : myapp
spec :
containers :
- name : myapp
image : yourusername/myapp: v1
ports :
- containerPort : 5000
resources :
requests :
memory : "64Mi"
cpu : "100m"
limits :
memory : "128Mi"
cpu : "200m"
env :
- name : ENVIRONMENT
value : "production"
livenessProbe :
httpGet :
path : /health
port : 5000
initialDelaySeconds : 5
periodSeconds : 10
readinessProbe :
httpGet :
path : /health
port : 5000
initialDelaySeconds : 3
periodSeconds : 5
---
apiVersion : v1
kind : Service
metadata :
name : myapp- service
spec :
selector :
app : myapp
ports :
- port : 80
targetPort : 5000
type : NodePort
步骤 5:部署到 Kubernetes
kubectl apply -f deployment.yaml
kubectl get pods -w
kubectl get deployment myapp
kubectl get svc myapp-service
kubectl get svc myapp-service
curl http://localhost:31234
curl http://< NodeIP> :31234
kubectl logs -f deployment/myapp
步骤 6:滚动更新
docker build -t myapp:v2 .
docker push yourusername/myapp:v2
kubectl set image deployment/myapp myapp = yourusername/myapp:v2
kubectl rollout status deployment/myapp
kubectl rollout undo deployment/myapp
5.3 完整的 Ingress 配置(使用域名访问)
apiVersion : networking.k8s.io/v1
kind : Ingress
metadata :
name : myapp- ingress
annotations :
nginx.ingress.kubernetes.io/rewrite-target : /
spec :
ingressClassName : nginx
rules :
- host : api.myapp.com
http :
paths :
- path : /
pathType : Prefix
backend :
service :
name : myapp- service
port :
number : 80
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml
kubectl apply -f ingress.yaml
kubectl get ingress
echo "127.0.0.1 api.myapp.com" >> /etc/hosts
curl http://api.myapp.com
6. 核心资源对象详解
6.1 Pod 详解
apiVersion : v1
kind : Pod
metadata :
name : nginx- pod
namespace : default
labels :
app : nginx
env : prod
annotations :
description : "这是一个 Nginx 示例 Pod"
spec :
containers :
- name : nginx
image : nginx: 1.25
imagePullPolicy : IfNotPresent
ports :
- containerPort : 80
protocol : TCP
env :
- name : ENV
value : "production"
- name : SECRET_USERNAME
valueFrom :
secretKeyRef :
name : db- secret
key : username
resources :
requests :
memory : "64Mi"
cpu : "250m"
limits :
memory : "128Mi"
cpu : "500m"
volumeMounts :
- name : nginx- storage
mountPath : /usr/share/nginx/html
livenessProbe :
httpGet :
path : /health
port : 80
initialDelaySeconds : 3
periodSeconds : 5
failureThreshold : 3
readinessProbe :
httpGet :
path : /ready
port : 80
initialDelaySeconds : 2
periodSeconds : 3
startupProbe :
httpGet :
path : /startup
port : 80
initialDelaySeconds : 0
periodSeconds : 10
failureThreshold : 30
- name : sidecar
image : alpine: latest
command : [ "/bin/sh" , "-c" ]
args : [ "tail -f /dev/null" ]
volumes :
- name : nginx- storage
persistentVolumeClaim :
claimName : nginx- pvc
nodeSelector :
disktype : ssd
tolerations :
- key : "key"
operator : "Equal"
value : "value"
effect : "NoSchedule"
restartPolicy : Always
serviceAccountName : default
6.2 Deployment 详解
apiVersion : apps/v1
kind : Deployment
metadata :
name : myapp- deployment
namespace : default
labels :
app : myapp
spec :
replicas : 3
revisionHistoryLimit : 10
strategy :
type : RollingUpdate
rollingUpdate :
maxSurge : 1
maxUnavailable : 0
selector :
matchLabels :
app : myapp
template :
metadata :
labels :
app : myapp
spec :
containers :
- name : myapp
image : myapp: v1
ports :
- containerPort : 8080
6.3 Service 详解
apiVersion : v1
kind : Service
metadata :
name : myapp- service
spec :
type : ClusterIP
selector :
app : myapp
ports :
- name : http
port : 80
targetPort : 8080
nodePort : 30080
protocol : TCP
sessionAffinity : None
Service 类型对比 :
类型 访问范围 使用场景 ClusterIP 仅集群内部 Pod 间通信 NodePort 通过节点 IP:端口 外部访问测试 LoadBalancer 通过云厂商负载均衡器 生产环境外部访问 ExternalName 指向外部 DNS 访问集群外服务
6.4 StatefulSet(有状态应用)
apiVersion : apps/v1
kind : StatefulSet
metadata :
name : mysql
spec :
serviceName : mysql
replicas : 3
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 : mysql- secret
key : password
volumeMounts :
- name : data
mountPath : /var/lib/mysql
volumeClaimTemplates :
- metadata :
name : data
spec :
accessModes : [ "ReadWriteOnce" ]
resources :
requests :
storage : 10Gi
---
apiVersion : v1
kind : Service
metadata :
name : mysql
spec :
clusterIP : None
selector :
app : mysql
ports :
- port : 3306
StatefulSet 特点 :
Pod 有稳定的网络标识:mysql-0, mysql-1, mysql-2 每个 Pod 有自己的持久化存储 按顺序创建/删除(从 0 到 N-1)
6.5 DaemonSet(每个节点一个 Pod)
apiVersion : apps/v1
kind : DaemonSet
metadata :
name : filebeat
spec :
selector :
matchLabels :
app : filebeat
template :
metadata :
labels :
app : filebeat
spec :
containers :
- name : filebeat
image : elastic/filebeat: 8.11
volumeMounts :
- name : varlog
mountPath : /var/log
- name : varlibdockercontainers
mountPath : /var/lib/docker/containers
readOnly : true
tolerations :
- key : node- role.kubernetes.io/control- plane
operator : Exists
effect : NoSchedule
volumes :
- name : varlog
hostPath :
path : /var/log
- name : varlibdockercontainers
hostPath :
path : /var/lib/docker/containers
7. 进阶调度与弹性伸缩
7.1 调度策略
spec :
affinity :
nodeAffinity :
requiredDuringSchedulingIgnoredDuringExecution :
nodeSelectorTerms :
- matchExpressions :
- key : kubernetes.io/arch
operator : In
values :
- amd64
preferredDuringSchedulingIgnoredDuringExecution :
- weight : 100
preference :
matchExpressions :
- key : node- type
operator : In
values :
- high- cpu
podAffinity :
requiredDuringSchedulingIgnoredDuringExecution :
- labelSelector :
matchLabels :
app : cache
topologyKey : kubernetes.io/hostname
podAntiAffinity :
preferredDuringSchedulingIgnoredDuringExecution :
- weight : 100
podAffinityTerm :
labelSelector :
matchLabels :
app : web
topologyKey : kubernetes.io/hostname
7.2 污点与容忍度
kubectl taint nodes node1 key = value:NoSchedule
kubectl taint nodes node1 key = value:NoExecute
kubectl taint nodes node1 key = value:PreferNoSchedule
kubectl describe node node1 | grep Taints
kubectl taint nodes node1 key:NoSchedule-
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
- key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
7.3 水平 Pod 自动伸缩(HPA)
apiVersion : autoscaling/v2
kind : HorizontalPodAutoscaler
metadata :
name : myapp- hpa
spec :
scaleTargetRef :
apiVersion : apps/v1
kind : Deployment
name : myapp
minReplicas : 2
maxReplicas : 10
metrics :
- type : Resource
resource :
name : cpu
target :
type : Utilization
averageUtilization : 50
- type : Resource
resource :
name : memory
target :
type : AverageValue
averageValue : 200Mi
- type : Pods
pods :
metric :
name : requests_per_second
target :
type : AverageValue
averageValue : 1000
kubectl get hpa
kubectl describe hpa myapp-hpa
kubectl run -it --rm load-generator --image = busybox -- /bin/sh -c "while true; do wget -q -O- http://myapp-service; done"
7.4 垂直 Pod 自动伸缩(VPA)
apiVersion : autoscaling.k8s.io/v1
kind : VerticalPodAutoscaler
metadata :
name : myapp- vpa
spec :
targetRef :
apiVersion : apps/v1
kind : Deployment
name : myapp
updatePolicy :
updateMode : Auto
resourcePolicy :
containerPolicies :
- containerName : myapp
minAllowed :
cpu : 100m
memory : 50Mi
maxAllowed :
cpu : 2
memory : 2Gi
8. 存储管理 PV/PVC
8.1 存储架构
8.2 静态存储(预先创建 PV)
apiVersion : v1
kind : PersistentVolume
metadata :
name : nfs- pv
spec :
capacity :
storage : 10Gi
accessModes :
- ReadWriteMany
nfs :
server : 192.168.1.100
path : /data/nfs
persistentVolumeReclaimPolicy : Retain
---
apiVersion : v1
kind : PersistentVolumeClaim
metadata :
name : nfs- pvc
spec :
accessModes :
- ReadWriteMany
resources :
requests :
storage : 5Gi
---
apiVersion : v1
kind : Pod
metadata :
name : app- with- storage
spec :
containers :
- name : app
image : nginx
volumeMounts :
- name : storage
mountPath : /usr/share/nginx/html
volumes :
- name : storage
persistentVolumeClaim :
claimName : nfs- pvc
8.3 动态存储(StorageClass)
apiVersion : storage.k8s.io/v1
kind : StorageClass
metadata :
name : fast- storage
provisioner : kubernetes.io/aws- ebs
parameters :
type : gp3
fsType : ext4
reclaimPolicy : Delete
allowVolumeExpansion : true
---
apiVersion : v1
kind : PersistentVolumeClaim
metadata :
name : dynamic- pvc
spec :
storageClassName : fast- storage
accessModes :
- ReadWriteOnce
resources :
requests :
storage : 20Gi
8.4 存储访问模式
访问模式 缩写 说明 ReadWriteOnceRWO 仅单个节点可读写 ReadOnlyManyROX 多个节点只读 ReadWriteManyRWX 多个节点读写(如 NFS) ReadWriteOncePodRWOP 仅单个 Pod 可读写(K8s 1.27+)
9. 网络模型与 Ingress
9.1 Kubernetes 网络模型
Kubernetes 网络要求满足四个基本条件:
所有 Pod 可以在不使用 NAT 的情况下相互通信 所有节点可以在不使用 NAT 的情况下与所有 Pod 通信 Pod 看到的自己的 IP 与其他 Pod 看到的 IP 相同 每个 Pod 有独立的 IP 地址
9.2 常用 CNI 插件对比
CNI 插件 性能 特性 适用场景 Calico 高 网络策略丰富,支持 eBPF 生产环境首选 Flannel 中 简单易用,功能基础 学习/小规模 Cilium 极高 eBPF 驱动,安全能力强 高性能/安全敏感 Weave 中 加密通信,易部署 跨云/混合云 Antrea 高 VMware 支持,集成 NSX 虚拟化环境
9.3 NetworkPolicy(网络策略)
apiVersion : networking.k8s.io/v1
kind : NetworkPolicy
metadata :
name : allow- frontend
spec :
podSelector :
matchLabels :
app : backend
policyTypes :
- Ingress
- Egress
ingress :
- from :
- podSelector :
matchLabels :
app : frontend
- namespaceSelector :
matchLabels :
name : monitoring
ports :
- protocol : TCP
port : 8080
egress :
- to :
- ipBlock :
cidr : 10.0.0.0/8
ports :
- protocol : TCP
port : 3306
9.4 Ingress 完整配置
apiVersion : networking.k8s.io/v1
kind : Ingress
metadata :
name : myapp- ingress
annotations :
nginx.ingress.kubernetes.io/rewrite-target : /$2
nginx.ingress.kubernetes.io/ssl-redirect : "true"
nginx.ingress.kubernetes.io/proxy-body-size : "100m"
cert-manager.io/cluster-issuer : "letsencrypt-prod"
spec :
ingressClassName : nginx
tls :
- hosts :
- api.myapp.com
- www.myapp.com
secretName : myapp- tls
rules :
- host : api.myapp.com
http :
paths :
- path : /v1(/| $)(.*)
pathType : Prefix
backend :
service :
name : myapp- v1- service
port :
number : 80
- path : /v2(/| $)(.*)
pathType : Prefix
backend :
service :
name : myapp- v2- service
port :
number : 80
- host : www.myapp.com
http :
paths :
- path : /
pathType : Prefix
backend :
service :
name : myapp- service
port :
number : 80
10. 配置管理 ConfigMap/Secret
10.1 ConfigMap
kubectl create configmap app- config - - from- literal=ENV=production - - from- literal=LOG_LEVEL=info
kubectl create configmap app- config - - from- file=config.ini
apiVersion : v1
kind : ConfigMap
metadata :
name : app- config
data :
ENV : production
LOG_LEVEL : info
app.properties : |
database.url=jdbc:mysql://mysql:3306/app
cache.ttl=300
---
apiVersion : v1
kind : Pod
spec :
containers :
- name : app
image : myapp
env :
- name : ENV
valueFrom :
configMapKeyRef :
name : app- config
key : ENV
volumeMounts :
- name : config
mountPath : /etc/config
volumes :
- name : config
configMap :
name : app- config
10.2 Secret
kubectl create secret generic db- secret \
- - from- literal=username=admin \
- - from- literal=password=P@ssw0rd
kubectl create secret tls my- tls - - cert=cert.pem - - key=key.pem
apiVersion : v1
kind : Secret
metadata :
name : db- secret
type : Opaque
data :
username : YWRtaW4=
password : UEBzc3cwcmQ=
---
apiVersion : v1
kind : Pod
spec :
containers :
- name : app
env :
- name : DB_USER
valueFrom :
secretKeyRef :
name : db- secret
key : username
- name : DB_PASS
valueFrom :
secretKeyRef :
name : db- secret
key : password
imagePullSecrets :
- name : dockerhub- secret
10.3 敏感信息加密(Sealed Secrets / Vault)
kubeseal --format yaml < secret.yaml > sealed-secret.yaml
kubectl apply -f sealed-secret.yaml
11. Helm 包管理
11.1 Helm 核心概念
11.2 Helm 常用命令
helm repo add stable https://charts.helm.sh/stable
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm search repo nginx
helm search hub nginx
helm install my-nginx bitnami/nginx
helm install my-redis bitnami/redis --set auth.password = myPassword
helm list
helm list -n my-ns
helm upgrade my-nginx bitnami/nginx --set service.type = LoadBalancer
helm history my-nginx
helm rollback my-nginx 1
helm uninstall my-nginx
helm create myapp-chart
helm lint myapp-chart
helm template myapp-chart --set image.tag = v2
helm show values bitnami/nginx
11.3 Chart 目录结构
myapp-chart/
├── Chart.yaml # Chart 元数据
├── values.yaml # 默认配置
├── charts/ # 依赖的子 Chart
├── templates/ # K8s YAML 模板
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── configmap.yaml
│ ├── _helpers.tpl # 模板辅助函数
│ └── NOTES.txt # 安装后提示信息
└── .helmignore # 忽略文件
11.4 模板语法示例
apiVersion : apps/v1
kind : Deployment
metadata :
name : { { include "myapp.fullname" . } }
labels :
{ { - include "myapp.labels" . | nindent 4 } }
spec :
replicas : { { .Values.replicaCount } }
selector :
matchLabels :
{ { - include "myapp.selectorLabels" . | nindent 6 } }
template :
metadata :
labels :
{ { - include "myapp.selectorLabels" . | nindent 8 } }
spec :
containers :
- name : { { .Chart.Name } }
image : "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy : { { .Values.image.pullPolicy } }
ports :
- containerPort : { { .Values.service.port } }
env :
- name : ENVIRONMENT
value : { { .Values.environment | default "production" } }
resources :
{ { - toYaml .Values.resources | nindent 10 } }
replicaCount : 3
image :
repository : myapp
tag : v1.0.0
pullPolicy : IfNotPresent
service :
type : ClusterIP
port : 8080
environment : production
resources :
requests :
memory : "64Mi"
cpu : "100m"
limits :
memory : "128Mi"
cpu : "200m"
12. CI/CD 与 GitOps
12.1 GitOps 工作流
12.2 GitHub Actions 示例
name : Deploy to Kubernetes
on :
push :
branches : [ main]
paths :
- 'src/**'
- 'k8s/**'
env :
REGISTRY : your- registry.aliyuncs.com
IMAGE_NAME : myapp
jobs :
build-and-deploy :
runs-on : ubuntu- latest
steps :
- uses : actions/checkout@v3
- name : Set up Docker Buildx
uses : docker/setup- buildx- action@v2
- name : Log in to Container Registry
uses : docker/login- action@v2
with :
registry : ${ { env.REGISTRY } }
username : ${ { secrets.REGISTRY_USERNAME } }
password : ${ { secrets.REGISTRY_PASSWORD } }
- name : Build and push Docker image
uses : docker/build- push- action@v4
with :
context : .
push : true
tags : ${ { env.REGISTRY } } /${ { env.IMAGE_NAME } } : ${ { github.sha } }
- name : Update deployment image tag
run : |
sed -i "s|image:.*|image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}|" k8s/deployment.yaml
- name : Deploy to Kubernetes
uses : azure/setup- kubectl@v3
with :
version : 'latest'
- name : Deploy to Kubernetes
run : |
kubectl apply -f k8s/ -n production
kubectl rollout status deployment/myapp -n production
12.3 ArgoCD 配置
apiVersion : argoproj.io/v1alpha1
kind : Application
metadata :
name : myapp
namespace : argocd
spec :
project : default
source :
repoURL : https: //github.com/yourname/myapp- k8s- config
targetRevision : main
path : overlays/production
destination :
server : https: //kubernetes.default.svc
namespace : production
syncPolicy :
automated :
prune : true
selfHeal : true
syncOptions :
- CreateNamespace=true
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath = "{.data.password}" | base64 -d
kubectl port-forward svc/argocd-server -n argocd 8443 :443
kubectl apply -f application.yaml
13. 监控与日志
13.1 监控架构(Prometheus + Grafana)
13.2 安装 Prometheus Stack
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set grafana.adminPassword = admin \
--set prometheus.prometheusSpec.retention = 15d
13.3 日志采集(EFK Stack)
apiVersion : apps/v1
kind : DaemonSet
metadata :
name : fluentd
namespace : logging
spec :
selector :
matchLabels :
app : fluentd
template :
metadata :
labels :
app : fluentd
spec :
containers :
- name : fluentd
image : fluent/fluentd- kubernetes- daemonset: v1- debian- elasticsearch
env :
- name : FLUENT_ELASTICSEARCH_HOST
value : "elasticsearch.logging.svc.cluster.local"
- name : FLUENT_ELASTICSEARCH_PORT
value : "9200"
volumeMounts :
- name : varlog
mountPath : /var/log
- name : dockercontainers
mountPath : /var/lib/docker/containers
readOnly : true
volumes :
- name : varlog
hostPath :
path : /var/log
- name : dockercontainers
hostPath :
path : /var/lib/docker/containers
13.4 常用监控命令
kubectl top nodes
kubectl top nodes --sort-by= cpu
kubectl top nodes --sort-by= memory
kubectl top pods
kubectl top pods -n kube-system
kubectl top pods --sort-by= cpu
kubectl get events --sort-by= '.lastTimestamp' | tail -20
kubectl get events -n kube-system --field-selector type = Warning
100 - ( avg by ( instance) ( rate( node_cpu_seconds_total{ mode= "idle" } [ 5m] )) * 100 )
( 1 - ( node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
14. 常见故障排查
14.1 Pod 状态速查表
状态 含义 常见原因 排查方法 Pending 调度中 资源不足、节点选择器不匹配 kubectl describe pod 查看事件ContainerCreating 创建中 镜像拉取中、存储挂载中 检查网络和存储配置 Running 正常运行 - - CrashLoopBackOff 反复重启 应用启动失败、健康检查失败 kubectl logs 查看日志ImagePullBackOff 镜像拉取失败 镜像不存在、认证失败、网络问题 kubectl describe pod 查看错误ErrImagePull 镜像拉取错误 同上 同上 Failed 失败 应用退出 kubectl logs 查看退出原因Unknown 未知 节点失联 kubectl get nodes 检查节点状态
14.2 常见问题排查流程图
14.3 调试命令大全
kubectl describe pod my-pod
kubectl logs my-pod
kubectl logs my-pod -c container-name
kubectl logs my-pod --previous
kubectl exec -it my-pod -- /bin/sh
kubectl exec -it my-pod -- /bin/bash
kubectl exec my-pod -- curl -s http://localhost:8080/health
kubectl port-forward pod/my-pod 8080 :80
kubectl describe svc my-service
kubectl get endpoints my-service
kubectl run test --image = busybox -it --rm -- wget -O- http://my-service
kubectl run dns-test --image = busybox -it --rm -- nslookup kubernetes.default.svc.cluster.local
kubectl get networkpolicies
kubectl describe networkpolicy my-policy
kubectl get pvc
kubectl describe pvc my-pvc
kubectl get pv
kubectl describe pv my-pv
kubectl get nodes
kubectl describe node node-1
kubectl get pods --field-selector spec.nodeName = node-1
kubectl cordon node-1
kubectl uncordon node-1
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
kubectl cluster-info
kubectl cluster-info dump
kubectl logs -n kube-system kube-apiserver-$( hostname )
kubectl get events --all-namespaces --sort-by= '.lastTimestamp'
kubectl top nodes
kubectl top pods
14.4 常见错误与解决方案
错误 原因 解决方案 ImagePullBackOff镜像拉取失败 检查镜像名、标签、认证、网络 CrashLoopBackOff容器反复崩溃 查看日志,检查启动命令、健康检查 Pending (no nodes available)资源不足 增加节点或减少资源请求 FailedMount存储挂载失败 检查 PV/PVC 状态,查看存储服务 Readiness probe failed就绪检查失败 检查应用端口、路径,调整探针参数 Liveness probe failed存活检查失败 同上,或应用性能问题 context deadline exceededAPI Server 超时 检查网络连接,增加 kubelet 超时时间 port already allocated端口冲突 修改 NodePort 或检查端口占用 No such file or directory挂载路径错误 检查 volumeMounts 配置
15. 生产环境最佳实践
15.1 资源配额(ResourceQuota)
apiVersion : v1
kind : ResourceQuota
metadata :
name : namespace- quota
spec :
hard :
limits.cpu : "20"
limits.memory : 20Gi
requests.cpu : "10"
requests.memory : 10Gi
persistentvolumeclaims : "10"
pods : "50"
services : "20"
services.nodeports : "5"
count/deployments.apps : "10"
15.2 限制范围(LimitRange)
apiVersion : v1
kind : LimitRange
metadata :
name : default- limits
spec :
limits :
- default :
cpu : 200m
memory : 256Mi
defaultRequest :
cpu : 100m
memory : 128Mi
max :
cpu : 2
memory : 2Gi
min :
cpu : 50m
memory : 64Mi
type : Container
15.3 Pod 安全策略(PodSecurityContext)
apiVersion : v1
kind : Pod
spec :
securityContext :
runAsUser : 1000
runAsGroup : 3000
fsGroup : 2000
runAsNonRoot : true
seccompProfile :
type : RuntimeDefault
containers :
- name : app
securityContext :
allowPrivilegeEscalation : false
capabilities :
drop :
- ALL
readOnlyRootFilesystem : true
15.4 PodDisruptionBudget(保证服务可用性)
apiVersion : policy/v1
kind : PodDisruptionBudget
metadata :
name : myapp- pdb
spec :
minAvailable : 2
selector :
matchLabels :
app : myapp
15.5 节点维护流程
kubectl cordon node-1
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
kubectl uncordon node-1
15.6 生产环境检查清单
检查项 说明 ✅ 所有容器设置 resources.requests/limits 避免资源竞争 ✅ 配置 livenessProbe/readinessProbe 确保服务健康 ✅ 使用 PodDisruptionBudget 保证维护期间服务可用 ✅ 设置 revisionHistoryLimit 控制历史版本数量 ✅ 使用 私有镜像仓库 + imagePullSecret 安全拉取镜像 ✅ 敏感信息使用 Secret (非 ConfigMap) 保护敏感数据 ✅ 启用 RBAC 权限控制 最小权限原则 ✅ 配置 NetworkPolicy 网络隔离 ✅ 启用 PodSecurityPolicy/PodSecurityContext 安全加固 ✅ 定期备份 etcd 灾难恢复 ✅ 配置 日志收集 和 监控告警 可观测性 ✅ 使用 Ingress 暴露服务(非 NodePort) 统一入口管理 ✅ 开启 自动伸缩(HPA) 弹性应对流量 ✅ 使用 Helm 管理应用 版本控制和环境管理 ✅ 实施 GitOps 流程 声明式交付 ✅ 节点 定期更新/打补丁 安全合规 ✅ 使用 readOnlyRootFilesystem 提高安全性
📚 推荐学习资源
资源 链接 说明 官方文档 https://kubernetes.io/docs/ 最权威的参考 Play with K8s https://labs.play-with-k8s.com/ 在线免费实验环境 Killercoda https://killercoda.com/ 交互式 K8s 教程 K8s 练习 https://k8s-exercises.com/ 实战练习题 Kubernetes Patterns https://kubernetespatterns.com/ 设计模式 Awesome K8s https://github.com/ramitsurana/awesome-kubernetes 资源合集
最后的话 :Kubernetes 是一个庞大的生态系统,没有人能记住所有细节。重要的是理解核心概念和架构 ,掌握 kubectl 常用命令 ,学会查看文档和排查问题 。实践是最好的学习方式——从本地 Minikube 开始,逐步过渡到生产集群,每一次踩坑都是成长。希望这份指南能成为你 K8s 学习路上的一个可靠参考。🚀