Kubernetes核心概念与实战指南
引言:容器编排的新时代
随着容器技术的普及,如何高效地管理大规模容器集群成为新的挑战。Kubernetes(简称K8s)作为业界领先的容器编排平台,应运而生。它不仅提供了容器的编排和调度能力,还构建了一套完整的容器应用生命周期管理体系。
从Google内部的Borg系统演变而来,Kubernetes已经成为云原生时代的"操作系统",支持在各类云环境和物理环境中运行。本文将带你深入了解Kubernetes的核心概念、架构设计和实战技巧,帮助你构建和管理可靠、高效的容器平台。
第一章:Kubernetes概述
1.1 什么是Kubernetes?
Kubernetes是一个开源的容器编排平台,用于自动化容器的部署、扩展和管理。它由Google于2014年开源,并由云原生计算基金会(CNCF)维护。
Kubernetes的核心价值在于:
- 自动化部署:简化容器应用的部署流程
- 弹性伸缩:根据负载自动调整容器数量
- 自我修复:自动重启失败的容器,替换不健康的容器
- 服务发现与负载均衡:为容器提供网络访问和流量分发
- 存储编排:自动挂载不同类型的存储系统
- 配置管理:集中管理容器的配置和密钥
1.2 Kubernetes的发展历程
Kubernetes的前身是Google内部使用的Borg系统,该系统管理着Google数百亿容器的运行。2014年,Google基于Borg的经验,开发并开源了Kubernetes项目。
主要里程碑:
- 2014年6月:Kubernetes首个版本发布
- 2015年7月:加入云原生计算基金会(CNCF),成为首个托管项目
- 2018年3月:Kubernetes 1.10版本发布,标志着项目进入稳定期
- 2020年8月:Kubernetes成为CNCF首个毕业级项目
- 至今:Kubernetes已成为容器编排领域的事实标准
1.3 Kubernetes与其他编排工具比较
市场上的容器编排工具主要有Kubernetes、Docker Swarm、Apache Mesos等,它们各有特点:
| 特性 |
Kubernetes |
Docker Swarm |
Apache Mesos |
| 社区活跃度 |
极高 |
较低 |
中等 |
| 复杂度 |
高 |
低 |
很高 |
| 功能完整性 |
最全 |
基础功能 |
强大但复杂 |
| 云提供商支持 |
所有主流云厂商 |
Docker Enterprise |
部分云厂商 |
| 学习曲线 |
陡峭 |
平缓 |
非常陡峭 |
从目前的市场趋势来看,Kubernetes已经成为容器编排的主导技术,拥有最活跃的社区和最广泛的生态支持。
第二章:Kubernetes核心概念
2.1 Pod
Pod是Kubernetes中最小的部署单元,它是一个或多个紧密相关的容器的集合,这些容器共享网络命名空间、存储和运行时配置。
Pod的特点:
- 包含一个或多个容器,它们在同一主机上运行
- 所有容器共享相同的网络命名空间(IP地址和端口)
- 可以共享存储卷
- 容器生命周期相互关联(通常一起启动和停止)
- Pod是临时性的,不应被视为持久实体
Pod的典型使用场景:
- 主容器与辅助容器(如日志收集器、数据处理器)配合工作
- 需要紧密协作的多容器应用
2.2 Service
Service是一种抽象,它定义了一组Pod的逻辑集合和访问这些Pod的策略。Service提供了稳定的IP地址和DNS名称,即使Pod的IP地址发生变化,客户端也能通过Service访问应用。
Service的类型:
- ClusterIP:默认类型,为Service分配一个集群内部可访问的IP
- NodePort:在每个节点上开放一个端口,将流量转发到Service
- LoadBalancer:使用云提供商的负载均衡器,将外部流量路由到Service
- ExternalName:将Service映射到外部DNS名称
2.3 Deployment
Deployment提供了对Pod的声明式更新能力。通过Deployment,你可以声明应用的期望状态,Kubernetes会自动将实际状态调整为期望状态。
Deployment的主要功能:
- 定义Pod和ReplicaSet的创建方式
- 支持滚动更新和回滚
- 提供应用扩缩容能力
- 支持暂停和继续更新过程
Deployment适用于无状态应用的管理,它确保指定数量的Pod副本始终运行。
2.4 StatefulSet
StatefulSet用于管理有状态应用,为Pod提供唯一的标识和稳定的存储。与Deployment不同,StatefulSet中的Pod具有固定的网络标识符和持久化存储。
StatefulSet的特点:
- Pod具有稳定、唯一的网络标识符
- Pod具有稳定的持久化存储
- Pod启动和终止顺序是有序的
- Pod扩缩容是有序的
StatefulSet适用于数据库、消息队列等需要稳定网络标识和持久存储的有状态应用。
2.5 ConfigMap和Secret
ConfigMap和Secret用于存储非敏感和敏感配置数据,使配置与应用代码分离。
ConfigMap:
- 存储非敏感配置信息
- 可以作为环境变量、命令行参数或卷挂载到Pod中
- 支持从文件、目录或字面值创建
Secret:
- 存储敏感信息,如密码、密钥和证书
- 数据默认使用Base64编码存储
- 支持加密存储(Kubernetes 1.13+)
- 可以通过环境变量或卷挂载到Pod中
2.6 Volume和PersistentVolume
Volume是Pod中容器可访问的目录,它可以由多种后端存储提供支持。PersistentVolume(PV)是集群级别的存储资源,而PersistentVolumeClaim(PVC)是对PV的请求。
Volume类型:
- emptyDir:Pod生命周期内的临时存储
- hostPath:宿主机上的文件系统路径
- NFS:网络文件系统
- ConfigMap/Secret:特殊类型的卷,用于挂载配置数据
PV和PVC:
- PV是由集群管理员创建的存储资源
- PVC是由用户创建的对存储资源的请求
- 支持多种存储类(StorageClass),提供不同性能和特性的存储
- 支持动态配置,自动创建PV以满足PVC请求
第三章:Kubernetes架构设计
3.1 控制平面组件
控制平面是Kubernetes集群的大脑,负责管理集群的整体状态。它由以下组件组成:
- API Server:集群的前端接口,所有组件都通过API Server交互
- etcd:高可用的键值存储,保存集群的所有配置数据
- Scheduler:负责监视新创建的Pod,并为其选择合适的节点
- Controller Manager:包含多种控制器,负责维护集群的期望状态
- Node Controller:管理节点生命周期
- Replication Controller:确保Pod副本数量
- Endpoints Controller:管理Service和Pod的关联
- Service Account & Token Controllers:管理ServiceAccount资源
3.2 节点组件
节点组件运行在每个工作节点上,负责Pod的实际运行和管理:
- kubelet:监视分配给节点的Pod,确保它们正在运行
- kube-proxy:网络代理,维护节点上的网络规则,实现Service的网络功能
- 容器运行时:负责容器的创建和运行,如Docker、containerd、CRI-O等
3.3 Kubernetes网络模型
Kubernetes网络模型定义了四个核心要求:
- 每个Pod都有一个唯一的IP地址
- 不同Pod之间可以直接通信,无需NAT
- 不同节点上的Pod可以直接通信,无需NAT
- Pod和节点之间可以直接通信,无需NAT
为了实现这些要求,Kubernetes支持多种网络插件,通过容器网络接口(CNI)进行集成:
- Calico:基于BGP的纯三层网络方案
- Flannel:简单易用的覆盖网络
- Cilium:基于eBPF的高性能网络和安全方案
- Weave Net:自动发现和加密的覆盖网络
第四章:Kubernetes安装与配置
4.1 选择合适的安装方式
Kubernetes提供了多种安装方式,可以根据需求选择:
- minikube:单节点Kubernetes集群,适合开发和测试
- kind (Kubernetes IN Docker):在Docker容器中运行Kubernetes集群
- kubeadm:官方推荐的工具,用于创建生产级集群
- 云厂商托管服务:如GKE、EKS、AKS等,无需自行管理控制平面
- 二进制安装:完全手动安装,适合深入理解Kubernetes架构
4.2 使用kubeadm安装Kubernetes
kubeadm是官方推荐的安装工具,下面是使用kubeadm创建集群的基本步骤:
准备工作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# 在所有节点上安装Docker或containerd
# 以containerd为例
sudo apt update
sudo apt install -y containerd.io
# 配置containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
# 安装kubelet、kubeadm和kubectl
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] 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
# 关闭swap
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
|
初始化控制平面节点:
1
2
3
4
5
6
7
8
9
10
|
# 初始化控制平面节点
sudo kubeadm init --pod-network-cidr=192.168.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
# 安装网络插件(以Calico为例)
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
|
加入工作节点:
1
2
|
# 在工作节点上执行从kubeadm init输出的命令
sudo kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>
|
4.3 配置kubectl
kubectl是Kubernetes的命令行工具,用于与集群交互。以下是一些基本配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# 查看集群状态
kubectl cluster-info
# 查看节点
kubectl get nodes
# 配置别名(可选)
alias k=kubectl
echo 'alias k=kubectl' >> ~/.bashrc
source ~/.bashrc
# 启用命令补全
apt-get install -y bash-completion
echo 'source <(kubectl completion bash)' >> ~/.bashrc
echo 'source <(kubectl completion bash | sed s/kubectl/k/g)' >> ~/.bashrc
source ~/.bashrc
|
4.4 基本集群管理
创建集群后,需要进行一些基本的管理操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# 查看集群组件状态
kubectl get componentstatuses
# 查看命名空间
kubectl get namespaces
# 创建命名空间
kubectl create namespace my-app
# 查看所有命名空间的Pod
kubectl get pods --all-namespaces
# 查看系统事件
kubectl get events
|
第五章:Kubernetes核心操作实战
5.1 部署应用
使用kubectl部署一个简单的Web应用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
# 创建Deployment
touch nginx-deployment.yaml
cat << EOF > nginx-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.14.2
ports:
- containerPort: 80
EOF
# 应用部署 kubectl apply -f nginx-deployment.yaml
# 查看Deployment状态
kubectl get deployments
# 查看创建的Pod
kubectl get pods
|
5.2 创建Service
为了使应用可访问,需要创建Service:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# 创建Service
touch nginx-service.yaml
cat << EOF > nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: NodePort
EOF
# 应用Service配置
kubectl apply -f nginx-service.yaml
# 查看Service
kubectl get services
# 访问应用(获取NodePort端口后)
# curl <node-ip>:<node-port>
|
5.3 扩缩容应用
根据负载需求调整Pod数量:
1
2
3
4
5
6
7
8
9
|
# 使用kubectl scale扩缩容
kubectl scale deployment nginx-deployment --replicas=5
# 验证Pod数量
kubectl get pods
# 通过修改Deployment配置文件扩缩容
kubectl edit deployment nginx-deployment
# 修改replicas字段的值,然后保存退出
|
5.4 滚动更新与回滚
Kubernetes支持无缝的滚动更新和快速回滚:
1
2
3
4
5
6
7
8
9
10
11
12
|
# 更新应用镜像(滚动更新)
kubectl set image deployment nginx-deployment nginx=nginx:1.16.1
# 查看更新状态
kubectl rollout status deployment nginx-deployment
# 如果需要回滚
sleep 5
kubectl rollout undo deployment nginx-deployment
# 查看回滚状态
kubectl rollout status deployment nginx-deployment
|
5.5 配置管理
使用ConfigMap和Secret管理应用配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
# 创建ConfigMap
echo "database.host=db.example.com" > config.properties
echo "database.port=3306" >> config.properties
kubectl create configmap app-config --from-file=config.properties
# 创建Secret
echo -n 'admin' > username.txt
echo -n 'password123' > password.txt
kubectl create secret generic app-secrets --from-file=username.txt --from-file=password.txt
# 在Pod中使用ConfigMap和Secret
touch app-deployment.yaml
cat << EOF > app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: database.host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: database.port
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: app-secrets
key: username.txt
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: password.txt
EOF
kubectl apply -f app-deployment.yaml
|
第六章:Kubernetes高级特性
6.1 资源配额与限制
Kubernetes提供了资源配额和限制机制,用于控制和限制集群资源的使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
# 创建资源配额
touch resource-quota.yaml
cat << EOF > resource-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
namespace: my-app
spec:
hard:
pods: "20"
requests.cpu: "10"
requests.memory: 20Gi
limits.cpu: "20"
limits.memory: 40Gi
EOF
kubectl apply -f resource-quota.yaml
# 在Pod中设置资源限制
touch resource-limits.yaml
cat << EOF > resource-limits.yaml
apiVersion: v1
kind: Pod
metadata:
name: resource-limited-pod
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
EOF
kubectl apply -f resource-limits.yaml
|
6.2 健康检查与自愈
Kubernetes通过探针(Probe)实现容器健康检查和自动恢复:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
# 创建带有健康检查的Deployment
touch health-check-deployment.yaml
cat << EOF > health-check-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: health-check-deployment
spec:
replicas: 3
selector:
matchLabels:
app: health-check-app
template:
metadata:
labels:
app: health-check-app
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 15
periodSeconds: 20
startupProbe:
httpGet:
path: /
port: 80
failureThreshold: 30
periodSeconds: 10
EOF
kubectl apply -f health-check-deployment.yaml
|
6.3 持久化存储配置
配置持久化存储以保存应用数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
# 创建StorageClass(如果使用云环境,通常已有默认StorageClass)
touch storage-class.yaml
cat << EOF > storage-class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/no-provisioner
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
EOF
kubectl apply -f storage-class.yaml
# 创建PVC
touch pvc.yaml
cat << EOF > pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: "standard"
resources:
requests:
storage: 10Gi
EOF
kubectl apply -f pvc.yaml
# 在Deployment中使用PVC
touch mysql-deployment.yaml
cat << EOF > mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.7
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secrets
key: root-password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pvc
EOF
# 创建Secret
echo -n 'mysqlpassword' | base64 # 复制输出值
kubectl create secret generic mysql-secrets --from-literal=root-password=mysqlpassword
kubectl apply -f mysql-deployment.yaml
|
6.4 网络策略
使用网络策略控制Pod间的通信:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
# 创建网络策略
touch network-policy.yaml
cat << EOF > network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-network-policy
namespace: default
spec:
podSelector:
matchLabels:
app: mysql
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: web
ports:
- protocol: TCP
port: 3306
egress:
- to:
- podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
EOF
kubectl apply -f network-policy.yaml
|
结语:Kubernetes的未来
Kubernetes已经成为容器编排的标准,它的生态系统正在不断发展壮大。通过本文的学习,你应该已经掌握了Kubernetes的核心概念和基本操作,能够部署和管理容器化应用。
在云原生时代,Kubernetes作为基础设施层的重要组成部分,将继续发挥关键作用。未来,Kubernetes将在以下几个方面持续演进:
- 简化操作体验:降低学习曲线,简化安装和管理
- 增强安全能力:提供更强大的安全策略和审计功能
- 优化边缘计算:更好地支持边缘场景下的容器运行
- 与AI/ML深度融合:支持机器学习工作负载的编排和管理
作为容器编排领域的领导者,Kubernetes将继续推动云原生技术的发展,为企业数字化转型提供有力支撑。在接下来的系列文章中,我们将深入探讨Kubernetes的高级主题,如Helm、Operator模式、服务网格等,帮助你成为Kubernetes专家!