Kubernetes完整实践指南
目录
概述
Kubernetes(简称K8s)是一个开源的容器编排平台,用于自动化容器化应用的部署、扩展和管理。本指南详细介绍Kubernetes的核心概念、架构组件、基本操作、高级特性和最佳实践,帮助开发人员和运维人员掌握Kubernetes的使用技巧,构建和管理可靠的容器化应用。
Kubernetes核心概念
基础概念
- 集群(Cluster):Kubernetes的基本运行单元,由一组节点组成
- 节点(Node):运行Pod的工作机器(物理机或虚拟机)
- Pod:Kubernetes的基本调度单元,包含一个或多个紧密相关的容器
- 控制器(Controller):管理Pod的生命周期,如Deployment、StatefulSet、DaemonSet等
- 服务(Service):提供稳定的网络访问方式,将流量路由到Pod
- 命名空间(Namespace):将集群资源划分为不同的虚拟集群
- 配置(ConfigMap):存储非敏感的配置数据
- 密钥(Secret):存储敏感数据,如密码、令牌等
- 持久卷(PersistentVolume):集群级别的存储资源
- 持久卷声明(PersistentVolumeClaim):用户对存储资源的请求
- Ingress:管理外部访问集群服务的规则集合
- 资源配额(ResourceQuota):限制命名空间的资源使用
- 极限范围(LimitRange):限制Pod和容器的资源使用
设计理念
- 声明式API:通过声明期望状态,Kubernetes负责将系统状态调整到期望状态
- 自愈能力:自动检测和修复容器、节点故障
- 水平扩展:基于负载自动扩缩容
- 服务发现与负载均衡:自动为容器分配网络地址并提供负载均衡
- 滚动更新与回滚:支持应用的滚动更新和版本回滚
- 配置与存储管理:集中管理应用配置和存储资源
Kubernetes架构
控制平面组件(Control Plane Components)
- kube-apiserver:API服务器,是Kubernetes控制平面的前端,提供REST API接口
- etcd:分布式键值存储,保存集群的所有配置数据
- kube-scheduler:调度器,负责为新创建的Pod选择运行节点
- kube-controller-manager:控制器管理器,运行各种控制器进程
- cloud-controller-manager:云控制器管理器,与云提供商API交互
节点组件(Node Components)
- kubelet:节点代理,负责与API服务器通信,管理Pod生命周期
- kube-proxy:网络代理,实现Kubernetes服务概念
- 容器运行时:负责运行容器的软件,如Docker、containerd、CRI-O
架构图
┌─────────────────────────────────────────────────────────┐
│ Kubernetes集群架构 │
├─────────────────────────────────────────────────────────┤
│ 控制平面 (Control Plane) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ kube-apiserver │ │ etcd │ │ kube-scheduler │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ kube-controller-manager │ │ cloud-controller-manager │ │
│ └─────────────┘ └─────────────┘ │
├─────────────────────────────────────────────────────────┤
│ 工作节点 (Worker Nodes) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ kubelet │ │ kube-proxy │ │ 容器运行时 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Pod │ │ Pod │ │ Pod │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────┘
集群部署
使用kubeadm部署集群
1. 准备环境
# 在所有节点上执行
# 关闭swap
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 安装Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
# 安装kubeadm、kubelet和kubectl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | 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
2. 初始化主节点
# 初始化集群
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)
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
3. 加入工作节点
# 在工作节点上执行(使用主节点初始化时输出的命令)
sudo kubeadm join <master-ip>:6443 --token <token> --discovery-token-ca-cert-hash <hash>
使用k3s部署集群
1. 安装k3s
# 主节点
curl -sfL https://get.k3s.io | sh -
# 工作节点
curl -sfL https://get.k3s.io | K3S_URL=https://myserver:6443 K3S_TOKEN=mynodetoken sh -
2. 配置kubectl
# 复制kubeconfig
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER ~/.kube/config
基础资源管理
Pod管理
1. 创建Pod
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: my-app
spec:
containers:
- name: my-container
image: nginx:latest
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
# 创建Pod
kubectl apply -f pod.yaml
# 查看Pod
kubectl get pods
kubectl describe pod my-pod
# 查看Pod日志
kubectl logs my-pod
# 进入Pod
kubectl exec -it my-pod -- /bin/bash
# 删除Pod
kubectl delete pod my-pod
2. Pod生命周期
创建 → 调度 → 运行 → 终止
↓ ↓ ↓ ↓
Pending Running Succeeded/Failed
Deployment管理
1. 创建Deployment
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: nginx:latest
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
2. Deployment操作
# 创建Deployment
kubectl apply -f deployment.yaml
# 查看Deployment
kubectl get deployments
kubectl describe deployment my-deployment
# 扩缩容
kubectl scale deployment my-deployment --replicas=5
# 滚动更新
kubectl set image deployment/my-deployment my-container=nginx:1.20
# 查看更新状态
kubectl rollout status deployment/my-deployment
# 回滚
kubectl rollout undo deployment/my-deployment
# 查看历史
kubectl rollout history deployment/my-deployment
Service管理
1. 创建Service
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
2. Service类型
# ClusterIP(默认)
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
---
# NodePort
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30080
---
# LoadBalancer
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
高级功能
ConfigMap和Secret
1. ConfigMap
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
database_url: "postgresql://localhost:5432/mydb"
log_level: "info"
app.properties: |
server.port=8080
spring.profiles.active=production
# 使用ConfigMap
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: myapp:latest
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: my-config
key: database_url
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: my-config
key: log_level
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: my-config
2. Secret
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
username: YWRtaW4= # base64编码
password: cGFzc3dvcmQ= # base64编码
# 使用Secret
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: myapp:latest
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: my-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: my-secret
key: password
StatefulSet
# statefulset.yaml
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
value: password
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-storage
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
DaemonSet
# daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
spec:
selector:
matchLabels:
name: fluentd
template:
metadata:
labels:
name: fluentd
spec:
containers:
- name: fluentd
image: fluentd:latest
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
服务发现与负载均衡
Ingress配置
1. 安装Ingress Controller
# 安装Nginx Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml
2. 创建Ingress
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
服务网格(Istio)
1. 安装Istio
# 下载Istio
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.19.0
# 安装Istio
bin/istioctl install --set values.defaultRevision=default
# 启用sidecar注入
kubectl label namespace default istio-injection=enabled
2. 配置VirtualService
# virtualservice.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: my-virtual-service
spec:
hosts:
- myapp.example.com
http:
- match:
- uri:
prefix: /
route:
- destination:
host: my-service
port:
number: 80
timeout: 30s
retries:
attempts: 3
perTryTimeout: 10s
存储管理
持久卷(PV)和持久卷声明(PVC)
1. 创建PV
# pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
hostPath:
path: /data
2. 创建PVC
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: local-storage
3. 使用PVC
# pod-with-pvc.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx:latest
volumeMounts:
- name: my-storage
mountPath: /data
volumes:
- name: my-storage
persistentVolumeClaim:
claimName: my-pvc
StorageClass
# storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
网络配置
网络策略
# networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
# allow-specific.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-specific
spec:
podSelector:
matchLabels:
app: my-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 80
egress:
- to:
- namespaceSelector:
matchLabels:
name: database
ports:
- protocol: TCP
port: 5432
安全实践
RBAC配置
1. 创建Role
# role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
2. 创建RoleBinding
# rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Pod安全策略
# psp.yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restricted
spec:
privileged: false
allowPrivilegeEscalation: false
requiredDropCapabilities:
- ALL
volumes:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
- 'persistentVolumeClaim'
runAsUser:
rule: 'MustRunAsNonRoot'
seLinux:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
监控与运维
资源监控
1. 查看资源使用
# 查看节点资源使用
kubectl top nodes
# 查看Pod资源使用
kubectl top pods
# 查看特定命名空间的资源使用
kubectl top pods -n kube-system
2. 资源限制
# resource-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: default
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
persistentvolumeclaims: "4"
日志管理
1. 查看日志
# 查看Pod日志
kubectl logs my-pod
# 查看多容器Pod的日志
kubectl logs my-pod -c my-container
# 实时查看日志
kubectl logs -f my-pod
# 查看前一个容器的日志
kubectl logs my-pod --previous
2. 日志收集
# fluentd-daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
spec:
selector:
matchLabels:
name: fluentd
template:
metadata:
labels:
name: fluentd
spec:
containers:
- name: fluentd
image: fluentd:latest
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
故障排查
常用命令
# 查看集群状态
kubectl cluster-info
# 查看节点状态
kubectl get nodes
kubectl describe node <node-name>
# 查看Pod状态
kubectl get pods
kubectl describe pod <pod-name>
# 查看事件
kubectl get events --sort-by=.metadata.creationTimestamp
# 查看服务状态
kubectl get services
kubectl describe service <service-name>
# 查看Ingress状态
kubectl get ingress
kubectl describe ingress <ingress-name>
调试技巧
# 进入Pod调试
kubectl exec -it <pod-name> -- /bin/bash
# 查看Pod的YAML配置
kubectl get pod <pod-name> -o yaml
# 查看Service端点
kubectl get endpoints
# 查看ConfigMap和Secret
kubectl get configmap
kubectl get secret
# 查看Pod日志
kubectl logs <pod-name> --previous
生产环境最佳实践
1. 资源管理
# 设置资源请求和限制
apiVersion: v1
kind: Pod
spec:
containers:
- name: my-container
image: myapp:latest
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
2. 健康检查
# 配置健康检查
apiVersion: v1
kind: Pod
spec:
containers:
- name: my-container
image: myapp:latest
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
3. 滚动更新
# 配置滚动更新策略
apiVersion: apps/v1
kind: Deployment
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
4. 安全配置
# 安全上下文
apiVersion: v1
kind: Pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: my-container
image: myapp:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
通过遵循这些最佳实践,可以构建安全、高效、可扩展的Kubernetes集群,实现容器化应用的可靠部署和管理。