Kubernetes (K8s)
一、Kubernetes 基础
1. Kubernetes 是什么?
Kubernetes (K8s) 是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用。
核心特性:
- ✅ 自动部署 - 自动化应用部署
- ✅ 自动扩展 - 根据负载自动扩展
- ✅ 自我修复 - 自动重启失败的容器
- ✅ 服务发现 - 自动服务发现和负载均衡
- ✅ 存储编排 - 自动挂载存储系统
- ✅ 配置管理 - 密钥和配置管理
2. Kubernetes 架构
Master 节点(控制平面):
- API Server - 集群的统一入口
- etcd - 分布式键值存储
- Controller Manager - 控制器管理器
- Scheduler - 调度器
Worker 节点:
- kubelet - 节点代理
- kube-proxy - 网络代理
- Container Runtime - 容器运行时(Docker、containerd)
3. 核心概念
Pod:
- 最小的部署单元
- 包含一个或多个容器
- 共享网络和存储
Deployment:
- 管理 Pod 的副本集
- 支持滚动更新和回滚
Service:
- 为 Pod 提供稳定的网络访问
- 负载均衡
Namespace:
- 资源隔离和分组
二、Kubernetes 安装
1. 使用 kubeadm 安装
准备环境:
bash
# 关闭 swap
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab
# 配置内核参数
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system安装容器运行时:
bash
# 安装 containerd
sudo apt-get update
sudo apt-get install -y containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd安装 kubeadm、kubelet、kubectl:
bash
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl初始化 Master 节点:
bash
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
# 配置 kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config安装网络插件(Flannel):
bash
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml加入 Worker 节点:
bash
# 在 Master 节点获取 join 命令
kubeadm token create --print-join-command
# 在 Worker 节点执行
sudo kubeadm join <master-ip>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>2. 使用 Minikube(本地开发)
安装 Minikube:
bash
# Linux
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# 启动
minikube start3. 使用 Docker Desktop(Windows/Mac)
- Docker Desktop 内置 Kubernetes
- 在设置中启用 Kubernetes
三、Kubernetes 基本命令
1. 集群管理
bash
# 查看集群信息
kubectl cluster-info
# 查看节点
kubectl get nodes
kubectl get nodes -o wide
# 查看节点详情
kubectl describe node <node-name>2. Pod 管理
bash
# 创建 Pod
kubectl run nginx --image=nginx
# 查看 Pod
kubectl get pods
kubectl get pods -o wide
kubectl get pods -n kube-system
# 查看 Pod 详情
kubectl describe pod <pod-name>
# 查看 Pod 日志
kubectl logs <pod-name>
kubectl logs -f <pod-name>
# 进入 Pod
kubectl exec -it <pod-name> -- /bin/bash
# 删除 Pod
kubectl delete pod <pod-name>3. Deployment 管理
bash
# 创建 Deployment
kubectl create deployment nginx --image=nginx
kubectl apply -f deployment.yaml
# 查看 Deployment
kubectl get deployments
kubectl get deploy
# 扩展 Deployment
kubectl scale deployment nginx --replicas=3
# 更新 Deployment
kubectl set image deployment/nginx nginx=nginx:1.21
# 查看更新状态
kubectl rollout status deployment/nginx
# 回滚 Deployment
kubectl rollout undo deployment/nginx
# 删除 Deployment
kubectl delete deployment nginx4. Service 管理
bash
# 创建 Service
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl apply -f service.yaml
# 查看 Service
kubectl get services
kubectl get svc
# 查看 Service 详情
kubectl describe service nginx
# 删除 Service
kubectl delete service nginx5. Namespace 管理
bash
# 创建 Namespace
kubectl create namespace mynamespace
# 查看 Namespace
kubectl get namespaces
kubectl get ns
# 在 Namespace 中操作
kubectl get pods -n mynamespace
# 删除 Namespace
kubectl delete namespace mynamespace四、YAML 配置文件
1. Pod 配置
yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
env:
- name: ENV_VAR
value: "value"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"2. 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:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"3. Service 配置
yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP # ClusterIP, NodePort, LoadBalancerService 类型:
- ClusterIP - 集群内部访问(默认)
- NodePort - 通过节点端口访问
- LoadBalancer - 云服务商的负载均衡器
- ExternalName - 外部服务别名
4. ConfigMap 配置
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
key1=value1
key2=value2使用 ConfigMap:
yaml
spec:
containers:
- name: app
image: myapp
envFrom:
- configMapRef:
name: app-config
volumeMounts:
- name: config
mountPath: /etc/config
volumes:
- name: config
configMap:
name: app-config5. Secret 配置
yaml
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
username: YWRtaW4= # base64 编码
password: cGFzc3dvcmQ=创建 Secret:
bash
kubectl create secret generic app-secret \
--from-literal=username=admin \
--from-literal=password=password使用 Secret:
yaml
spec:
containers:
- name: app
image: myapp
env:
- name: USERNAME
valueFrom:
secretKeyRef:
name: app-secret
key: username五、.NET Core 应用部署
1. 创建 Dockerfile
dockerfile
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["MyApp.csproj", "./"]
RUN dotnet restore "MyApp.csproj"
COPY . .
RUN dotnet build "MyApp.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "MyApp.csproj" -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS final
WORKDIR /app
COPY --from=publish /app/publish .
EXPOSE 80
ENTRYPOINT ["dotnet", "MyApp.dll"]2. 构建和推送镜像
bash
# 构建镜像
docker build -t myregistry/myapp:1.0 .
# 推送镜像
docker push myregistry/myapp:1.03. 创建 Deployment
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry/myapp:1.0
ports:
- containerPort: 80
env:
- name: ASPNETCORE_ENVIRONMENT
value: "Production"
- name: ConnectionStrings__DefaultConnection
valueFrom:
secretKeyRef:
name: db-secret
key: connection-string
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 10
periodSeconds: 54. 创建 Service
yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer5. 部署
bash
# 应用配置
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
# 查看状态
kubectl get deployments
kubectl get pods
kubectl get services
# 查看日志
kubectl logs -f deployment/myapp-deployment六、滚动更新和回滚
1. 滚动更新
bash
# 更新镜像
kubectl set image deployment/myapp-deployment myapp=myregistry/myapp:2.0
# 查看更新状态
kubectl rollout status deployment/myapp-deployment
# 查看更新历史
kubectl rollout history deployment/myapp-deployment2. 回滚
bash
# 回滚到上一个版本
kubectl rollout undo deployment/myapp-deployment
# 回滚到指定版本
kubectl rollout undo deployment/myapp-deployment --to-revision=23. 更新策略
yaml
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最多新增 Pod 数
maxUnavailable: 1 # 最多不可用 Pod 数七、存储管理
1. Volume
emptyDir:
yaml
spec:
containers:
- name: app
volumeMounts:
- name: cache
mountPath: /cache
volumes:
- name: cache
emptyDir: {}hostPath:
yaml
volumes:
- name: data
hostPath:
path: /data
type: Directory2. PersistentVolume (PV) 和 PersistentVolumeClaim (PVC)
创建 PV:
yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-volume
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
hostPath:
path: /data/pv创建 PVC:
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: manual使用 PVC:
yaml
spec:
containers:
- name: app
volumeMounts:
- name: storage
mountPath: /data
volumes:
- name: storage
persistentVolumeClaim:
claimName: pvc-claim八、常见面试题
Q1: Kubernetes 的核心组件?
Master 节点:
- API Server - 统一入口
- etcd - 存储
- Controller Manager - 控制器
- Scheduler - 调度器
Worker 节点:
- kubelet - 节点代理
- kube-proxy - 网络代理
- Container Runtime - 容器运行时
Q2: Pod 和容器的关系?
- Pod 是最小的部署单元
- Pod 包含一个或多个容器
- 同一个 Pod 中的容器共享网络和存储
- 通常一个 Pod 只包含一个容器
Q3: Deployment 和 ReplicaSet 的关系?
- Deployment 管理 ReplicaSet
- ReplicaSet 管理 Pod 副本
- Deployment 提供滚动更新和回滚功能
Q4: Service 的作用?
- 服务发现 - 为 Pod 提供稳定的访问地址
- 负载均衡 - 在多个 Pod 之间分发流量
- 抽象 - 隐藏 Pod 的 IP 变化
Q5: 如何实现 Kubernetes 高可用?
- 多 Master 节点 - 使用 etcd 集群
- 多 Worker 节点 - 分散 Pod
- 健康检查 - liveness 和 readiness 探针
- 自动扩展 - HPA(Horizontal Pod Autoscaler)
- 存储高可用 - 使用分布式存储
九、最佳实践
- ✅ 使用 Deployment - 而不是直接创建 Pod
- ✅ 设置资源限制 - requests 和 limits
- ✅ 健康检查 - liveness 和 readiness 探针
- ✅ 使用 ConfigMap 和 Secret - 配置管理
- ✅ 标签和选择器 - 合理使用标签
- ✅ 命名空间 - 资源隔离
- ✅ 滚动更新 - 零停机部署
- ✅ 监控和日志 - 使用监控工具
- ❌ 不要使用 latest 标签 - 明确版本
- ❌ 不要忽略资源限制 - 防止资源耗尽