k8s的资源类型

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 通过标签选择器关联。
  • ConfigMapSecret 提供配置和敏感信息,供 Pod 使用。
  • VolumePersistentVolume 提供持久化存储,供 Pod 挂载。
  • Namespace 提供资源隔离,不同 Namespace 中的资源相互独立。
  • Ingress 管理外部流量,通过 Service 路由到 Pod。
  • StatefulSetDaemonSet 分别用于管理有状态应用和每个节点上的 Pod。
  • JobCronJob 用于运行一次性任务和定时任务。
  • HPA 自动扩展 Pod 的副本数量,确保应用的性能。
  • RoleRoleBinding 控制对资源的访问权限。
  • CRD 允许用户定义自定义资源,扩展 Kubernetes 的功能。

资源之间的关系图描述

  1. Namespace 是顶层资源,用于逻辑隔离。

    • 一个 Namespace 中可以包含多个 DeploymentServiceIngressPod 等资源。
    • 不同 Namespace 中的资源默认是隔离的。
  2. Deployment 是管理 Pod 的核心资源。

    • 一个 Deployment 可以管理多个 Pod 副本。
    • Deployment 通过 ReplicaSet 来管理 Pod 的生命周期。
    • Deployment 定义了 Pod 的模板(Pod Template),用于创建 Pod
  3. ReplicaSetDeployment 的底层实现。

    • ReplicaSet 确保指定数量的 Pod 副本始终运行。
    • ReplicaSet 通过标签选择器(Label Selector)来管理 Pod
  4. Pod 是最小的部署单元。

    • 一个 Pod 可以包含一个或多个容器。
    • Pod 可以通过 Volume 挂载存储卷。
    • Pod 通过标签(Labels)与 ServiceReplicaSet 关联。
  5. Service 提供稳定的网络访问。

    • Service 通过标签选择器(Label Selector)与 Pod 关联。
    • ServicePod 提供负载均衡和服务发现功能。
    • Service 可以是 ClusterIP、NodePort 或 LoadBalancer 类型。
  6. Ingress 管理外部流量。

    • Ingress 通过规则将外部 HTTP/HTTPS 流量路由到 Service
    • Service 再将流量转发到后端的 Pod
  7. Volume 提供持久化存储。

    • Volume 可以被 Pod 挂载,供容器使用。
    • Volume 可以是本地存储、网络存储(如 NFS)或云存储(如 AWS EBS)。

关系图结构

Namespace
│
├── Deployment
│   ├── ReplicaSet
│   │   └── Pod (多个副本)
│   │       └── Volume (挂载存储)
│   └── Pod Template (定义 Pod 的模板)
│
├── Service
│   └── 通过 Label Selector 关联 Pod
│
├── Ingress
│   └── 路由外部流量到 Service
│
└── Volume
    └── 被 Pod 挂载

详细关系说明

  1. Namespace 是资源的容器,所有资源都在某个 Namespace 中运行。

    • 例如:default Namespace 包含一个 Deployment、一个 Service 和一个 Ingress。
  2. Deployment 定义了应用的部署策略。

    • 例如:一个 Deployment 定义了 3 个副本的 Nginx Pod。
    • Deployment 创建并管理一个 ReplicaSet。
  3. ReplicaSet 确保 Pod 的副本数量。

    • 例如:ReplicaSet 确保始终有 3 个 Nginx Pod 运行。
    • 如果某个 Pod 崩溃,ReplicaSet 会创建新的 Pod。
  4. Pod 是实际运行的容器实例。

    • 例如:每个 Nginx Pod 运行一个 Nginx 容器。
    • Pod 可以通过 Volume 挂载配置文件或持久化数据。
  5. Service 提供稳定的网络访问。

    • 例如:一个 Service 将流量负载均衡到 3 个 Nginx Pod。
    • Service 通过标签选择器(如 app: nginx)找到对应的 Pod。
  6. Ingress 管理外部流量。

    • 例如:Ingress 将 example.com 的流量路由到 Nginx Service。
    • Service 再将流量转发到后端的 Nginx Pod。
  7. Volume 提供持久化存储。

    • 例如:Nginx Pod 挂载一个 Volume 来存储日志文件。
    • Volume 可以是本地存储或云存储。

示例场景1

假设我们有一个名为 web-app 的应用,部署在 default Namespace 中:

  1. Namespace: default
  2. Deployment: web-app-deployment
    • 定义了 3 个副本的 Nginx Pod。
    • 使用 app: web-app 标签。
  3. ReplicaSet: web-app-rs
    • 确保 3 个 Nginx Pod 始终运行。
  4. Pod: web-app-pod-1, web-app-pod-2, web-app-pod-3
    • 每个 Pod 运行一个 Nginx 容器。
    • 挂载一个 Volume 存储日志。
  5. Service: web-app-service
    • 类型为 ClusterIP,提供内部访问。
    • 通过 app: web-app 标签选择器关联 Pod。
  6. Ingress: web-app-ingress
    • example.com 的流量路由到 web-app-service
  7. 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-service80 端口。
  • 使用 Nginx Ingress 控制器的注解 rewrite-target 确保路径重写。

4. Volume (web-app-logs)

在 Deployment 中已定义:

volumes:
- name: web-app-logs
  emptyDir: {}

作用

  • 使用 emptyDir 类型的 Volume,生命周期与 Pod 绑定。
  • 为 Pod 提供临时存储空间,用于存储 Nginx 日志文件(重启 Pod 后数据会丢失,适合临时存储)。

流量处理流程

  1. 外部请求进入集群

    • 用户访问 http://example.com
    • DNS 解析到集群的 Ingress 控制器公网 IP(需提前配置)。
  2. Ingress 路由

    • Ingress 控制器(如 Nginx Ingress)根据 example.com 的 Host 匹配规则,将请求转发到 web-app-service
  3. Service 负载均衡

    • Service 通过标签 app: web-app 找到关联的 3 个 Pod。
    • 使用 Kubernetes 内置的负载均衡,将请求分发到其中一个 Pod 的 80 端口。
  4. Pod 处理请求

    • Nginx 容器接收请求并返回响应。
    • 日志写入挂载的 Volume 路径 /var/log/nginx

关键注意事项

  1. 标签一致性

    • Deployment、Service、Ingress 均通过 app: web-app 标签关联,确保流量正确路由。
  2. Volume 持久化

    • 如果需持久化存储日志,可将 emptyDir 替换为 persistentVolumeClaim(需要提前创建 PV 和 PVC)。
  3. Ingress 控制器

    • 需要提前部署 Ingress 控制器(如 Nginx Ingress Controller)。
  4. 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. 流量处理流程

  1. 用户访问 https://helloworld.com:
    • DNS 解析到 Kubernetes Ingress Controller 的 IP。
    • Ingress 根据域名 helloworld.com 匹配路由规则,将 HTTPS 流量解密后转发到 django Service。
  2. Service 负载均衡:
    • django Service 将请求分发到后端的 3 个 Django Pod。
  3. Django 处理请求:
    • 动态请求:Django 访问 MySQL 主节点写入数据,从节点读取数据(需在 Django 配置中实现读写分离)。
    • 缓存请求:Django 访问 Redis 集群读写缓存。
  4. 静态文件处理:
    • Django 的静态文件(CSS/JS/图片)存储在 static-pvc 持久化卷中,通过 Nginx 直接提供(需在 Django 配置中设置 STATIC_ROOT)。

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. 高可用与扩展

  1. 自动扩缩容(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
    
  2. MySQL 读写分离:
    • 在 Django 中使用 DATABASE_ROUTERS 配置读写分离。
  3. 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 的副本。
  • 类型:
    1. 等式选择器(Equality-based Selector):
      • 通过 key=valuekey!=value 来匹配资源。
      • 例如:app=nginx 选择所有 app 标签值为 nginx 的资源。
    2. 集合选择器(Set-based Selector):
      • 支持更复杂的查询条件,如 innotinexists 等。
      • 例如:
        • app in (nginx, web):选择 app 标签值为 nginxweb 的资源。
        • !env:选择没有 env 标签的资源。

Label Selector 的使用场景

  1. 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。
  2. 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 运行。
  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。
  4. 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 的语法

  1. 等式选择器:

    • key=value:匹配标签值等于 value 的资源。
    • key!=value:匹配标签值不等于 value 的资源。
  2. 集合选择器:

    • key in (value1, value2):匹配标签值在集合中的资源。
    • key notin (value1, value2):匹配标签值不在集合中的资源。
    • key:匹配具有该标签的资源(无论值是什么)。
    • !key:匹配没有该标签的资源。

示例

假设有以下 Pod:

Pod 名称Labels
pod-1app=nginx, env=prod
pod-2app=nginx, env=dev
pod-3app=web, env=prod
  1. 选择所有 app=nginx 的 Pod:

    • Label Selector: app=nginx
    • 匹配 Pod: pod-1, pod-2
  2. 选择所有 env=prod 的 Pod:

    • Label Selector: env=prod
    • 匹配 Pod: pod-1, pod-3
  3. 选择所有 app=nginxenv=prod 的 Pod:

    • Label Selector: app=nginx, env=prod
    • 匹配 Pod: pod-1
  4. 选择所有 app 标签存在且 env 标签不存在的 Pod:

    • Label Selector: app, !env
    • 匹配 Pod: 无(因为所有 Pod 都有 env 标签)

总结

  • Label Selector 是 Kubernetes 中用于筛选和匹配资源的核心机制。
  • 它通过资源的 Labels 来选择符合条件的资源。
  • 常见的应用场景包括 Service 关联 Pod、ReplicaSet 管理 Pod、Pod 调度等。
  • 支持等式选择器和集合选择器,满足不同的筛选需求。

通过合理使用 Labels 和 Label Selector,可以更灵活地管理和组织 Kubernetes 中的资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值