Kubernetes(通常称为K8s)是一种用于自动化部署、扩展和管理容器化应用程序的开源平台。它提供了一个强大的容器编排和管理系统,可以简化容器化应用程序的部署、伸缩和运维。
在Kubernetes中,容器是最基本的部署单元,而容器化应用程序由一个或多个容器组成。Kubernetes的主要目标是在一个集群中管理和编排这些容器,以便应用程序可以高效地运行,并且能够自动处理故障恢复、扩展和负载均衡等任务。在 Kubernetes 中,有多种资源类型可以用来定义和管理应用程序的不同方面,以下是其中几种资源的介绍以及它们之间的关系:
k8s的资源类型
1. Pod
- 定义: Pod 是 Kubernetes 中最小的部署单元,代表集群中运行的一个或多个容器。一个 Pod 中的容器共享网络和存储资源。
- 作用: Pod 是应用程序的单个实例,通常包含一个主容器和可能的辅助容器(如 sidecar 容器)。
- 关系: Pod 是其他资源(如 Deployment、Service)的基础。Deployment 通过管理 Pod 的副本来实现应用的扩展和更新,Service 通过选择器与 Pod 关联,提供稳定的网络端点。
2. Deployment
- 定义: Deployment 是用于定义 Pod 的部署策略的资源,支持声明式更新、回滚和扩展。
- 作用: Deployment 确保指定数量的 Pod 副本始终运行,并支持滚动更新和回滚。
- 关系: Deployment 管理 ReplicaSet,ReplicaSet 管理 Pod。Deployment 通过 ReplicaSet 来控制 Pod 的生命周期。
3. ReplicaSet
- 定义: ReplicaSet 确保指定数量的 Pod 副本始终运行。
- 作用: ReplicaSet 通过标签选择器来管理 Pod,确保 Pod 的数量符合预期。
- 关系: ReplicaSet 是 Deployment 的底层实现,Deployment 通过 ReplicaSet 来管理 Pod 的副本。
4. Service
- 定义: Service 是 Kubernetes 中用于定义一组 Pod 的访问策略的资源,提供稳定的网络端点。
- 作用: Service 通过标签选择器与 Pod 关联,提供负载均衡和服务发现功能。
- 关系: Service 与 Pod 通过标签选择器关联,Service 为 Pod 提供网络访问入口。
5. ConfigMap
- 定义: ConfigMap 是用于存储非敏感配置数据的资源。
- 作用: ConfigMap 将配置数据与应用程序代码分离,便于配置管理。
- 关系: ConfigMap 可以被 Pod 挂载为卷或环境变量,供容器使用。
6. Secret
- 定义: Secret 是用于存储敏感信息(如密码、令牌、密钥)的资源。
- 作用: Secret 提供了一种安全的方式来管理敏感数据。
- 关系: Secret 可以被 Pod 挂载为卷或环境变量,供容器使用。
7. Volume
- 定义: Volume 是用于持久化存储数据的资源。
- 作用: Volume 提供了一种机制,使得容器可以在其生命周期之外访问和存储数据。
- 关系: Volume 可以被 Pod 挂载,供容器使用。
8. Namespace
- 定义: Namespace 是用于将集群资源划分为多个虚拟集群的资源。
- 作用: Namespace 提供了一种逻辑隔离机制,便于资源管理和权限控制。
- 关系: Namespace 包含其他资源(如 Pod、Service、Deployment 等),不同 Namespace 中的资源相互隔离。
9. Ingress
- 定义: Ingress 是用于管理外部访问集群服务的资源。
- 作用: Ingress 提供 HTTP 和 HTTPS 路由规则,将外部流量路由到集群内的 Service。
- 关系: Ingress 与 Service 关联,Service 与 Pod 关联,Ingress 通过 Service 将外部流量路由到 Pod。
10. StatefulSet
- 定义: StatefulSet 是用于管理有状态应用的资源。
- 作用: StatefulSet 确保 Pod 的唯一性和有序性,适用于需要稳定网络标识和持久化存储的应用。
- 关系: StatefulSet 管理 Pod,Pod 使用 Volume 进行持久化存储。
11. DaemonSet
- 定义: DaemonSet 是用于在集群的每个节点上运行一个 Pod 副本的资源。
- 作用: DaemonSet 确保每个节点上都运行一个特定的 Pod,适用于日志收集、监控等场景。
- 关系: DaemonSet 管理 Pod,Pod 在集群的每个节点上运行。
12. Job
- 定义: Job 是用于运行一次性任务的资源。
- 作用: Job 创建一个或多个 Pod,并确保它们成功完成。
- 关系: Job 管理 Pod,Pod 执行任务。
13. CronJob
- 定义: CronJob 是用于定期运行任务的资源。
- 作用: CronJob 基于时间表创建 Job,适用于定时任务。
- 关系: CronJob 管理 Job,Job 管理 Pod。
14. Horizontal Pod Autoscaler (HPA)
- 定义: HPA 是用于自动扩展 Pod 副本数量的资源。
- 作用: HPA 根据 CPU 使用率或其他自定义指标自动调整 Pod 的副本数量。
- 关系: HPA 与 Deployment 或 ReplicaSet 关联,自动调整 Pod 的副本数量。
15. Role 和 RoleBinding
- 定义: Role 定义了一组权限,RoleBinding 将 Role 绑定到用户或组。
- 作用: Role 和 RoleBinding 用于控制对 Kubernetes 资源的访问权限。
- 关系: Role 定义权限,RoleBinding 将权限授予用户或组。
16. ClusterRole 和 ClusterRoleBinding
- 定义: ClusterRole 定义了一组集群范围的权限,ClusterRoleBinding 将 ClusterRole 绑定到用户或组。
- 作用: ClusterRole 和 ClusterRoleBinding 用于控制对集群范围资源的访问权限。
- 关系: ClusterRole 定义集群范围的权限,ClusterRoleBinding 将权限授予用户或组。
17. PersistentVolume (PV) 和 PersistentVolumeClaim (PVC)
- 定义: PV 是集群中的存储资源,PVC 是用户对存储资源的请求。
- 作用: PV 和 PVC 提供了一种抽象机制,使得用户可以动态请求存储资源。
- 关系: PVC 请求 PV,Pod 使用 PVC 挂载存储卷。
PV(Persistent Volume):是Kubernetes中的持久化存储抽象,它代表一个网络存储卷。它与底层存储技术解耦,使得Kubernetes集群管理员可以更灵活地配置不同的存储后端,为不同的应用提供适当的存储。
PVC(Persistent Volume Claim):是对PV的申请,PVC与PV之间建立起了一个映射关系。PVC定义了需要的存储类别和存储资源请求(如大小),Kubernetes通过PV调度来满足PVC的要求。
Pod和PV、PVC之间的关系可以用下图表示:
+--------------+
| PV(10GB) |
| Storage |
+--------------+
^
|
|
+----------+-----------+
| |
+-------------+--+ +---+-------------+
| Pod | | Pod |
| Container 1 | | Container 2 |
| (app1) | | (app2) |
+-------------+--+ +---+-------------+
^ ^
| |
| |
+----------+-----------+ +--------+--------+
| |
+-------------+----------------+ +--------------+-----------------+
| PVC(claim 2GB) | | PVC(claim 2GB) |
| (Storage Class 1) | | (Storage Class 1) |
+----------------------------------+ +----------------------------------+
18. StorageClass
- 定义: StorageClass 是用于定义存储类型的资源。
- 作用: StorageClass 允许动态创建 PV,支持不同类型的存储(如 SSD、HDD)。
- 关系: StorageClass 与 PVC 关联,PVC 请求特定类型的存储。
19. CustomResourceDefinition (CRD)
- 定义: CRD 是用于定义自定义资源的资源。
- 作用: CRD 允许用户扩展 Kubernetes API,定义自己的资源类型。
- 关系: CRD 定义自定义资源,用户可以通过 Kubernetes API 管理这些资源。
20. NetworkPolicy
- 定义: NetworkPolicy 是用于定义网络策略的资源。
- 作用: NetworkPolicy 控制 Pod 之间的网络通信,提供网络安全策略。
- 关系: NetworkPolicy 与 Pod 关联,控制 Pod 的网络流量。
资源之间的关系总结
- Pod 是 Kubernetes 中最小的部署单元,其他资源(如 Deployment、Service、StatefulSet 等)都是围绕 Pod 进行管理的。
- Deployment 通过 ReplicaSet 管理 Pod 的副本,确保应用的稳定运行。
- Service 提供稳定的网络端点,与 Pod 通过标签选择器关联。
- ConfigMap 和 Secret 提供配置和敏感信息,供 Pod 使用。
- Volume 和 PersistentVolume 提供持久化存储,供 Pod 挂载。
- Namespace 提供资源隔离,不同 Namespace 中的资源相互独立。
- Ingress 管理外部流量,通过 Service 路由到 Pod。
- StatefulSet 和 DaemonSet 分别用于管理有状态应用和每个节点上的 Pod。
- Job 和 CronJob 用于运行一次性任务和定时任务。
- HPA 自动扩展 Pod 的副本数量,确保应用的性能。
- Role 和 RoleBinding 控制对资源的访问权限。
- CRD 允许用户定义自定义资源,扩展 Kubernetes 的功能。
资源之间的关系图描述
-
Namespace 是顶层资源,用于逻辑隔离。
- 一个 Namespace 中可以包含多个 Deployment、Service、Ingress、Pod 等资源。
- 不同 Namespace 中的资源默认是隔离的。
-
Deployment 是管理 Pod 的核心资源。
- 一个 Deployment 可以管理多个 Pod 副本。
- Deployment 通过 ReplicaSet 来管理 Pod 的生命周期。
- Deployment 定义了 Pod 的模板(Pod Template),用于创建 Pod。
-
ReplicaSet 是 Deployment 的底层实现。
- ReplicaSet 确保指定数量的 Pod 副本始终运行。
- ReplicaSet 通过标签选择器(Label Selector)来管理 Pod。
-
Pod 是最小的部署单元。
- 一个 Pod 可以包含一个或多个容器。
- Pod 可以通过 Volume 挂载存储卷。
- Pod 通过标签(Labels)与 Service 和 ReplicaSet 关联。
-
Service 提供稳定的网络访问。
- Service 通过标签选择器(Label Selector)与 Pod 关联。
- Service 为 Pod 提供负载均衡和服务发现功能。
- Service 可以是 ClusterIP、NodePort 或 LoadBalancer 类型。
-
Ingress 管理外部流量。
- Ingress 通过规则将外部 HTTP/HTTPS 流量路由到 Service。
- Service 再将流量转发到后端的 Pod。
-
Volume 提供持久化存储。
- Volume 可以被 Pod 挂载,供容器使用。
- Volume 可以是本地存储、网络存储(如 NFS)或云存储(如 AWS EBS)。
关系图结构
Namespace
│
├── Deployment
│ ├── ReplicaSet
│ │ └── Pod (多个副本)
│ │ └── Volume (挂载存储)
│ └── Pod Template (定义 Pod 的模板)
│
├── Service
│ └── 通过 Label Selector 关联 Pod
│
├── Ingress
│ └── 路由外部流量到 Service
│
└── Volume
└── 被 Pod 挂载
详细关系说明
-
Namespace 是资源的容器,所有资源都在某个 Namespace 中运行。
- 例如:
default
Namespace 包含一个 Deployment、一个 Service 和一个 Ingress。
- 例如:
-
Deployment 定义了应用的部署策略。
- 例如:一个 Deployment 定义了 3 个副本的 Nginx Pod。
- Deployment 创建并管理一个 ReplicaSet。
-
ReplicaSet 确保 Pod 的副本数量。
- 例如:ReplicaSet 确保始终有 3 个 Nginx Pod 运行。
- 如果某个 Pod 崩溃,ReplicaSet 会创建新的 Pod。
-
Pod 是实际运行的容器实例。
- 例如:每个 Nginx Pod 运行一个 Nginx 容器。
- Pod 可以通过 Volume 挂载配置文件或持久化数据。
-
Service 提供稳定的网络访问。
- 例如:一个 Service 将流量负载均衡到 3 个 Nginx Pod。
- Service 通过标签选择器(如
app: nginx
)找到对应的 Pod。
-
Ingress 管理外部流量。
- 例如:Ingress 将
example.com
的流量路由到 Nginx Service。 - Service 再将流量转发到后端的 Nginx Pod。
- 例如:Ingress 将
-
Volume 提供持久化存储。
- 例如:Nginx Pod 挂载一个 Volume 来存储日志文件。
- Volume 可以是本地存储或云存储。
示例场景1
假设我们有一个名为 web-app
的应用,部署在 default
Namespace 中:
- Namespace:
default
- Deployment:
web-app-deployment
- 定义了 3 个副本的 Nginx Pod。
- 使用
app: web-app
标签。
- ReplicaSet:
web-app-rs
- 确保 3 个 Nginx Pod 始终运行。
- Pod:
web-app-pod-1
,web-app-pod-2
,web-app-pod-3
- 每个 Pod 运行一个 Nginx 容器。
- 挂载一个 Volume 存储日志。
- Service:
web-app-service
- 类型为 ClusterIP,提供内部访问。
- 通过
app: web-app
标签选择器关联 Pod。
- Ingress:
web-app-ingress
- 将
example.com
的流量路由到web-app-service
。
- 将
- Volume:
web-app-logs
- 被 Pod 挂载,用于存储日志。
以下是各个 Kubernetes 资源的 YAML 文件及详细说明:
1. Deployment (web-app-deployment.yaml
)
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-deployment
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: web-app-logs
mountPath: /var/log/nginx
volumes:
- name: web-app-logs
emptyDir: {}
作用:
- 定义了一个 Deployment
web-app-deployment
,确保始终运行 3 个副本的 Pod。 - 使用标签
app: web-app
标记 Pod,用于与其他资源(如 Service)关联。 - 每个 Pod 运行一个
nginx
容器,暴露端口80
。 - 挂载名为
web-app-logs
的 Volume 到容器内的/var/log/nginx
路径,用于存储日志。
2. Service (web-app-service.yaml
)
apiVersion: v1
kind: Service
metadata:
name: web-app-service
namespace: default
spec:
type: ClusterIP
selector:
app: web-app
ports:
- protocol: TCP
port: 80
targetPort: 80
作用:
- 创建一个 ClusterIP 类型的 Service
web-app-service
,提供内部访问。 - 通过
app: web-app
标签选择器关联到 Deployment 管理的 Pod。 - 将 Service 的端口
80
映射到 Pod 的端口80
。
3. Ingress (web-app-ingress.yaml
)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-service
port:
number: 80
作用:
- 定义 Ingress
web-app-ingress
,将外部流量路由到 Service。 - 当访问
example.com
时,流量会被转发到web-app-service
的80
端口。 - 使用 Nginx Ingress 控制器的注解
rewrite-target
确保路径重写。
4. Volume (web-app-logs
)
在 Deployment 中已定义:
volumes:
- name: web-app-logs
emptyDir: {}
作用:
- 使用
emptyDir
类型的 Volume,生命周期与 Pod 绑定。 - 为 Pod 提供临时存储空间,用于存储 Nginx 日志文件(重启 Pod 后数据会丢失,适合临时存储)。
流量处理流程
-
外部请求进入集群:
- 用户访问
http://example.com
。 - DNS 解析到集群的 Ingress 控制器公网 IP(需提前配置)。
- 用户访问
-
Ingress 路由:
- Ingress 控制器(如 Nginx Ingress)根据
example.com
的 Host 匹配规则,将请求转发到web-app-service
。
- Ingress 控制器(如 Nginx Ingress)根据
-
Service 负载均衡:
- Service 通过标签
app: web-app
找到关联的 3 个 Pod。 - 使用 Kubernetes 内置的负载均衡,将请求分发到其中一个 Pod 的
80
端口。
- Service 通过标签
-
Pod 处理请求:
- Nginx 容器接收请求并返回响应。
- 日志写入挂载的 Volume 路径
/var/log/nginx
。
关键注意事项
-
标签一致性:
- Deployment、Service、Ingress 均通过
app: web-app
标签关联,确保流量正确路由。
- Deployment、Service、Ingress 均通过
-
Volume 持久化:
- 如果需持久化存储日志,可将
emptyDir
替换为persistentVolumeClaim
(需要提前创建 PV 和 PVC)。
- 如果需持久化存储日志,可将
-
Ingress 控制器:
- 需要提前部署 Ingress 控制器(如 Nginx Ingress Controller)。
-
DNS 配置:
- 实际环境中需将
example.com
的 DNS 解析指向 Ingress 控制器的公网 IP,或在本地 Hosts 文件中添加映射。
- 实际环境中需将
部署命令
kubectl apply -f web-app-deployment.yaml
kubectl apply -f web-app-service.yaml
kubectl apply -f web-app-ingress.yaml
以上配置实现了从外部访问到内部 Pod 的全链路流量处理,并确保日志存储和副本高可用。
示例场景2
以django网站为例,包含多个web容器实现负载均衡,mysql容器若干集群部署并实现主从同步,redis容器若干实现集群部署,nginx容器若干,volume若干,网站域名是helloworld.com
整体架构图
用户请求
│
↓
Ingress (helloworld.com, HTTPS)
│
↓
Nginx Service (负载均衡)
│
↓
Django Deployment (多副本) → MySQL StatefulSet (主从集群)
│ ↘ Redis StatefulSet (集群模式)
│
↓
静态文件存储 (Volume)
1. 环境准备
1.1 前置条件
- Kubernetes 集群(支持 StorageClass,如 AWS EBS、GCE PD 或 NFS)。
- 域名
helloworld.com
已解析到集群入口 IP(如 LoadBalancer 或 Ingress Controller)。 kubectl
已配置访问集群。
1.2 创建 Namespace
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: helloworld
执行命令:
kubectl apply -f namespace.yaml
2. 持久化存储
2.1 MySQL 主从存储
# mysql-storage.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: mysql-storage
namespace: helloworld
provisioner: kubernetes.io/aws-ebs # 根据实际环境调整(如 NFS、GCE PD)
parameters:
type: gp2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
namespace: helloworld
spec:
accessModes:
- ReadWriteOnce
storageClassName: mysql-storage
resources:
requests:
storage: 20Gi
2.2 Redis 存储
# redis-storage.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: redis-storage
namespace: helloworld
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-pvc
namespace: helloworld
spec:
accessModes:
- ReadWriteOnce
storageClassName: redis-storage
resources:
requests:
storage: 10Gi
3. MySQL 主从集群
# mysql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: helloworld
spec:
serviceName: mysql
replicas: 2 # 主节点 + 从节点
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: root-password
- name: MYSQL_REPLICATION_USER
value: repl_user
- name: MYSQL_REPLICATION_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: repl-password
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: mysql-storage
resources:
requests:
storage: 20Gi
---
# mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: helloworld
spec:
clusterIP: None # Headless Service,直接暴露 Pod IP
selector:
app: mysql
ports:
- port: 3306
---
# mysql-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
namespace: helloworld
type: Opaque
data:
root-password: BASE64_ENCODED_ROOT_PASSWORD
repl-password: BASE64_ENCODED_REPL_PASSWORD
主从同步配置
- 主节点(
mysql-0
)执行:CREATE USER 'repl_user'@'%' IDENTIFIED BY 'repl_password'; GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%'; FLUSH PRIVILEGES;
- 从节点(
mysql-1
)执行:CHANGE MASTER TO MASTER_HOST='mysql-0.mysql.helloworld.svc.cluster.local', MASTER_USER='repl_user', MASTER_PASSWORD='repl_password'; START SLAVE;
4. Redis 集群
# redis-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
namespace: helloworld
spec:
serviceName: redis
replicas: 3 # 3 节点集群
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:6.2
command: ["redis-server", "/etc/redis/redis.conf"]
ports:
- containerPort: 6379
volumeMounts:
- name: redis-config
mountPath: /etc/redis
- name: redis-data
mountPath: /data
volumes:
- name: redis-config
configMap:
name: redis-config
volumeClaimTemplates:
- metadata:
name: redis-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: redis-storage
resources:
requests:
storage: 10Gi
---
# redis-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
namespace: helloworld
data:
redis.conf: |
cluster-enabled yes
cluster-config-file /data/nodes.conf
cluster-node-timeout 5000
appendonly yes
---
# redis-service.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: helloworld
spec:
clusterIP: None
selector:
app: redis
ports:
- port: 6379
初始化 Redis 集群
kubectl exec -it redis-0 -n helloworld -- redis-cli --cluster create \
$(kubectl get pods -n helloworld -l app=redis -o jsonpath='{range.items[*]}{.status.podIP}:6379 ') \
--cluster-replicas 1
5. Django 应用部署
# django-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: django
namespace: helloworld
spec:
replicas: 3 # 3 副本负载均衡
selector:
matchLabels:
app: django
template:
metadata:
labels:
app: django
spec:
containers:
- name: django
image: your-django-image:latest
env:
- name: DJANGO_SECRET_KEY
valueFrom:
secretKeyRef:
name: django-secret
key: secret-key
- name: DATABASE_URL
value: "mysql://root:$(MYSQL_ROOT_PASSWORD)@mysql.helloworld.svc.cluster.local:3306/dbname"
- name: REDIS_URL
value: "redis://redis.helloworld.svc.cluster.local:6379/0"
ports:
- containerPort: 8000
volumeMounts:
- name: static-data
mountPath: /app/static
volumes:
- name: static-data
persistentVolumeClaim:
claimName: static-pvc
---
# django-service.yaml
apiVersion: v1
kind: Service
metadata:
name: django
namespace: helloworld
spec:
selector:
app: django
ports:
- protocol: TCP
port: 80
targetPort: 8000
---
# django-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: django-secret
namespace: helloworld
type: Opaque
data:
secret-key: BASE64_ENCODED_DJANGO_SECRET_KEY
6. Nginx 入口配置
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: helloworld-ingress
namespace: helloworld
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: letsencrypt-prod # 自动申请 TLS 证书
spec:
tls:
- hosts:
- helloworld.com
secretName: helloworld-tls
rules:
- host: helloworld.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: django
port:
number: 80
7. 流量处理流程
- 用户访问
https://helloworld.com
:- DNS 解析到 Kubernetes Ingress Controller 的 IP。
- Ingress 根据域名
helloworld.com
匹配路由规则,将 HTTPS 流量解密后转发到django
Service。
- Service 负载均衡:
django
Service 将请求分发到后端的 3 个 Django Pod。
- Django 处理请求:
- 动态请求:Django 访问 MySQL 主节点写入数据,从节点读取数据(需在 Django 配置中实现读写分离)。
- 缓存请求:Django 访问 Redis 集群读写缓存。
- 静态文件处理:
- Django 的静态文件(CSS/JS/图片)存储在
static-pvc
持久化卷中,通过 Nginx 直接提供(需在 Django 配置中设置STATIC_ROOT
)。
- Django 的静态文件(CSS/JS/图片)存储在
8. 启动所有组件
按顺序执行以下命令:
# 创建 Namespace
kubectl apply -f namespace.yaml
# 创建存储
kubectl apply -f mysql-storage.yaml
kubectl apply -f redis-storage.yaml
# 部署 MySQL
kubectl apply -f mysql-secret.yaml
kubectl apply -f mysql-statefulset.yaml
kubectl apply -f mysql-service.yaml
# 部署 Redis
kubectl apply -f redis-config.yaml
kubectl apply -f redis-statefulset.yaml
kubectl apply -f redis-service.yaml
# 部署 Django
kubectl apply -f django-secret.yaml
kubectl apply -f django-deployment.yaml
kubectl apply -f django-service.yaml
# 部署 Ingress
kubectl apply -f ingress.yaml
9. 高可用与扩展
- 自动扩缩容(HPA):
# hpa.yaml apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: django-hpa namespace: helloworld spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: django minReplicas: 3 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 80
- MySQL 读写分离:
- 在 Django 中使用
DATABASE_ROUTERS
配置读写分离。
- 在 Django 中使用
- Redis 集群监控:
- 使用
redis-cli --cluster check
监控集群状态。
- 使用
总结
- 高可用:通过多副本 Deployment、StatefulSet 和集群化存储实现。
- 高性能:Nginx 负载均衡、Redis 缓存、MySQL 主从分离。
- 扩展性:HPA 自动扩缩容、StorageClass 动态存储分配。
- 安全性:TLS 加密、Secret 管理敏感信息。
1.Django应用需要处理Web请求,所以需要部署多个Pod,并通过Service暴露,可能使用Deployment来管理。为了负载均衡,可能使用Nginx作为反向代理,或者Kubernetes的Ingress。不过用户提到了Nginx容器,可能需要用Nginx作为入口,或者作为静态文件服务器?这里可能需要澄清,但根据常见实践,可能使用Ingress来处理外部流量,而Nginx可能作为Web服务器的前端。
2.然后是数据库部分,MySQL需要主从同步,这意味着需要StatefulSet来管理有状态的Pod,每个Pod有稳定的网络标识和持久化存储。同样,Redis集群也需要多个实例,可能使用StatefulSet或者Deployment,但Redis集群需要特定的配置来启用集群模式。
3.Volume方面,每个有状态的服务(MySQL、Redis)都需要PersistentVolume来持久化数据,所以需要配置PVC和StorageClass。静态文件比如Django的静态文件可能需要一个共享存储,比如NFS,或者使用云存储。
4.域名helloworld.com需要通过Ingress配置,将流量路由到对应的Service,进而分发到后端的Pod。需要配置TLS证书,可能使用Let’s Encrypt的cert-manager来自动化证书管理。
5.高可用和高性能需要考虑各个组件的副本数,HPA自动扩缩容,以及资源的请求和限制。例如,Django的Deployment需要设置多个副本,并配置HPA基于CPU或内存使用率自动扩展。MySQL主从同步需要确保数据一致性,可能使用异步复制。Redis集群需要正确配置分片和主从复制。
6.然后,我需要编写各个组件的YAML文件,包括Deployment、Service、StatefulSet、ConfigMap、Secret、Ingress等。同时,要确保各个组件之间的正确关联,比如Service通过Label Selector找到对应的Pod,Ingress路由规则正确指向Service,Volume挂载正确配置。
7.流量进入后,首先到达Ingress Controller(比如Nginx Ingress),根据域名helloworld.com路由到Django的Service,然后负载均衡到各个Django Pod。如果是静态文件,可能由Nginx Pod直接处理,或者由Django应用处理,这取决于架构设计。MySQL和Redis的流量则由各自的Service内部处理,确保应用能够连接到正确的数据库实例。
8.在安全性方面,需要配置Secrets来存储数据库密码、Django的SECRET_KEY等敏感信息。ConfigMap用于存储配置文件,比如Django的settings.py部分配置,或者Nginx的配置。
9.可能还需要初始化容器来执行数据库迁移,或者Redis、MySQL的集群初始化。例如,在MySQL StatefulSet中,第一个Pod可能需要初始化数据库,并配置主从同步。同样,Redis集群可能需要一个初始化脚本来创建集群。
10.最后,整个系统的启动顺序可能需要按照依赖关系来部署,比如先部署MySQL和Redis,再部署Django应用,最后部署Nginx和Ingress,确保服务依赖正确启动。
此方案可直接应用于生产环境,根据实际需求调整资源配置和副本数量。
Label Selector(标签选择器)
是 Kubernetes 中用于筛选和匹配资源的一种机制。它通过资源的 Labels(标签) 来选择符合条件的资源。Label Selector 是 Kubernetes 中许多资源(如 Service、Deployment、ReplicaSet 等)与其他资源(如 Pod)关联的核心方式。
Labels(标签)
- 定义: Labels 是键值对(key-value pairs),附加到 Kubernetes 资源(如 Pod、Service、Node 等)上。
- 作用: Labels 用于标识资源的属性或特征,例如:
- 应用名称(
app: nginx
) - 环境(
env: prod
) - 版本(
version: v1
)
- 应用名称(
- 特点:
- 一个资源可以有多个 Labels。
- Labels 是灵活的,可以根据需要动态添加或修改。
Label Selector(标签选择器)
- 定义: Label Selector 是一种查询条件,用于筛选具有特定 Labels 的资源。
- 作用: Label Selector 用于将资源关联起来。例如:
- Service 通过 Label Selector 找到对应的 Pod。
- ReplicaSet 通过 Label Selector 管理 Pod 的副本。
- 类型:
- 等式选择器(Equality-based Selector):
- 通过
key=value
或key!=value
来匹配资源。 - 例如:
app=nginx
选择所有app
标签值为nginx
的资源。
- 通过
- 集合选择器(Set-based Selector):
- 支持更复杂的查询条件,如
in
、notin
、exists
等。 - 例如:
app in (nginx, web)
:选择app
标签值为nginx
或web
的资源。!env
:选择没有env
标签的资源。
- 支持更复杂的查询条件,如
- 等式选择器(Equality-based Selector):
Label Selector 的使用场景
-
Service 关联 Pod
- Service 通过 Label Selector 找到后端 Pod。
- 例如:
apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: nginx # 选择所有 app=nginx 的 Pod ports: - protocol: TCP port: 80 targetPort: 80
- 这个 Service 会将流量转发到所有
app=nginx
标签的 Pod。
- 这个 Service 会将流量转发到所有
-
ReplicaSet 管理 Pod
- ReplicaSet 通过 Label Selector 管理 Pod 的副本。
- 例如:
apiVersion: apps/v1 kind: ReplicaSet metadata: name: nginx-rs spec: replicas: 3 selector: matchLabels: app: nginx # 选择所有 app=nginx 的 Pod template: metadata: labels: app: nginx # Pod 的标签 spec: containers: - name: nginx image: nginx
- 这个 ReplicaSet 会确保有 3 个
app=nginx
标签的 Pod 运行。
- 这个 ReplicaSet 会确保有 3 个
-
Deployment 管理 ReplicaSet
- Deployment 通过 Label Selector 管理 ReplicaSet。
- 例如:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx # 选择所有 app=nginx 的 Pod template: metadata: labels: app: nginx # Pod 的标签 spec: containers: - name: nginx image: nginx
- 这个 Deployment 会创建和管理
app=nginx
标签的 Pod。
- 这个 Deployment 会创建和管理
-
Pod 调度
- Node Selector 或 Affinity 规则可以通过 Label Selector 将 Pod 调度到特定节点。
- 例如:
apiVersion: v1 kind: Pod metadata: name: nginx-pod spec: containers: - name: nginx image: nginx nodeSelector: disktype: ssd # 选择 disktype=ssd 的节点
Label Selector 的语法
-
等式选择器:
key=value
:匹配标签值等于value
的资源。key!=value
:匹配标签值不等于value
的资源。
-
集合选择器:
key in (value1, value2)
:匹配标签值在集合中的资源。key notin (value1, value2)
:匹配标签值不在集合中的资源。key
:匹配具有该标签的资源(无论值是什么)。!key
:匹配没有该标签的资源。
示例
假设有以下 Pod:
Pod 名称 | Labels |
---|---|
pod-1 | app=nginx, env=prod |
pod-2 | app=nginx, env=dev |
pod-3 | app=web, env=prod |
-
选择所有
app=nginx
的 Pod:- Label Selector:
app=nginx
- 匹配 Pod:
pod-1
,pod-2
- Label Selector:
-
选择所有
env=prod
的 Pod:- Label Selector:
env=prod
- 匹配 Pod:
pod-1
,pod-3
- Label Selector:
-
选择所有
app=nginx
且env=prod
的 Pod:- Label Selector:
app=nginx, env=prod
- 匹配 Pod:
pod-1
- Label Selector:
-
选择所有
app
标签存在且env
标签不存在的 Pod:- Label Selector:
app, !env
- 匹配 Pod: 无(因为所有 Pod 都有
env
标签)
- Label Selector:
总结
- Label Selector 是 Kubernetes 中用于筛选和匹配资源的核心机制。
- 它通过资源的 Labels 来选择符合条件的资源。
- 常见的应用场景包括 Service 关联 Pod、ReplicaSet 管理 Pod、Pod 调度等。
- 支持等式选择器和集合选择器,满足不同的筛选需求。
通过合理使用 Labels 和 Label Selector,可以更灵活地管理和组织 Kubernetes 中的资源。