×

基于测试集群最大值规划您的环境

本文档介绍如何基于测试集群最大值规划您的 Red Hat OpenShift Service on AWS 环境。

超额订阅节点上的物理资源会影响 Kubernetes 调度程序在 Pod 部署期间提供的资源保证。了解您可以采取哪些措施来避免内存交换。

一些测试的最大值仅在一个维度上被拉伸。当集群上运行许多对象时,它们会发生变化。

本文档中提到的数字基于 Red Hat 测试方法、设置、配置和调整。这些数字会根据您自己的个人设置和环境而有所不同。

在规划您的环境时,请使用以下公式确定每个节点上预计要容纳多少个 Pod。

required pods per cluster / pods per node = total number of nodes needed

当前每个节点的最大 Pod 数为 250。但是,节点上可以容纳的 Pod 数取决于应用程序本身。请考虑应用程序的内存、CPU 和存储需求,如基于应用程序需求规划您的环境中所述。

示例场景

如果您希望将集群的范围设置为每个集群 2200 个 Pod,则假设每个节点最多 250 个 Pod,您至少需要九个节点。

2200 / 250 = 8.8

如果您将节点数量增加到 20 个,则 Pod 分布将变为每个节点 110 个 Pod。

2200 / 20 = 110

其中

required pods per cluster / total number of nodes = expected pods per node

基于应用程序需求规划您的环境

本文档介绍如何根据您的应用程序需求规划您的 Red Hat OpenShift Service on AWS 环境。

考虑一个示例应用程序环境

Pod 类型 Pod 数量 最大内存 CPU 核心数 持久性存储

apache

100

500 MB

0.5

1 GB

node.js

200

1 GB

1

1 GB

postgresql

100

1 GB

2

10 GB

JBoss EAP

100

1 GB

1

1 GB

推算的需求:550 个 CPU 核心、450 GB RAM 和 1.4 TB 存储。

节点的实例大小可以根据您的偏好进行调整。节点通常是资源超额分配的。在这个部署方案中,您可以选择运行更多较小的节点或较少的较大节点以提供相同数量的资源。应考虑操作敏捷性和每个实例的成本等因素。

节点类型 数量 CPU RAM (GB)

节点(选项 1)

100

4

16

节点(选项 2)

50

8

32

节点(选项 3)

25

16

64

有些应用程序非常适合超额分配的环境,而有些则不适合。大多数 Java 应用程序和使用巨型页面的应用程序都是不允许超额分配的应用程序示例。该内存不能用于其他应用程序。在上面的示例中,环境大约超额分配了 30%,这是一个常见的比率。

应用程序 Pod 可以通过使用环境变量或 DNS 来访问服务。如果使用环境变量,则对于每个活动服务,kubelet 在节点上运行 Pod 时会注入变量。集群感知 DNS 服务器监视 Kubernetes API 以查找新服务,并为每个服务创建一组 DNS 记录。如果在整个集群中启用了 DNS,则所有 Pod 都应该能够通过其 DNS 名称自动解析服务。如果必须超过 5000 个服务,可以使用使用 DNS 的服务发现。当使用环境变量进行服务发现时,如果命名空间中 5000 个服务后的参数列表超过允许的长度,则 Pod 和部署将开始失败。

禁用部署的服务规范文件中的服务链接以克服此问题。

示例
Kind: Template
apiVersion: template.openshift.io/v1
metadata:
  name: deploymentConfigTemplate
  creationTimestamp:
  annotations:
    description: This template will create a deploymentConfig with 1 replica, 4 env vars and a service.
    tags: ''
objects:
  - kind: DeploymentConfig
    apiVersion: apps.openshift.io/v1
    metadata:
      name: deploymentconfig${IDENTIFIER}
    spec:
      template:
        metadata:
          labels:
            name: replicationcontroller${IDENTIFIER}
        spec:
          enableServiceLinks: false
          containers:
          - name: pause${IDENTIFIER}
            image: "${IMAGE}"
            ports:
            - containerPort: 8080
              protocol: TCP
            env:
            - name: ENVVAR1_${IDENTIFIER}
              value: "${ENV_VALUE}"
            - name: ENVVAR2_${IDENTIFIER}
              value: "${ENV_VALUE}"
            - name: ENVVAR3_${IDENTIFIER}
              value: "${ENV_VALUE}"
            - name: ENVVAR4_${IDENTIFIER}
              value: "${ENV_VALUE}"
            resources: {}
            imagePullPolicy: IfNotPresent
            capabilities: {}
            securityContext:
              capabilities: {}
              privileged: false
          restartPolicy: Always
          serviceAccount: ''
      replicas: 1
      selector:
        name: replicationcontroller${IDENTIFIER}
      triggers:
      - type: ConfigChange
      strategy:
        type: Rolling
  - kind: Service
    apiVersion: v1
    metadata:
      name: service${IDENTIFIER}
    spec:
      selector:
        name: replicationcontroller${IDENTIFIER}
      ports:
      - name: serviceport${IDENTIFIER}
        protocol: TCP
        port: 80
        targetPort: 8080
      portalIP: ''
      type: ClusterIP
      sessionAffinity: None
    status:
      loadBalancer: {}
  parameters:
  - name: IDENTIFIER
    description: Number to append to the name of resources
    value: '1'
    required: true
  - name: IMAGE
    description: Image to use for deploymentConfig
    value: gcr.io/google-containers/pause-amd64:3.0
    required: false
  - name: ENV_VALUE
    description: Value to use for environment variables
    generate: expression
    from: "[A-Za-z0-9]{255}"
    required: false
  labels:
template: deploymentConfigTemplate

当使用环境变量进行服务发现时,命名空间中可以运行的应用程序 Pod 数量取决于服务的数量和服务名称的长度。系统上的ARG_MAX定义了新进程的最大参数长度,默认设置为 2097152 字节(2 MiB)。kubelet 会将环境变量注入到计划在命名空间中运行的每个 Pod 中,包括:

  • <SERVICE_NAME>_SERVICE_HOST=<IP>

  • <SERVICE_NAME>_SERVICE_PORT=<PORT>

  • <SERVICE_NAME>_PORT=tcp://<IP>:<PORT>

  • <SERVICE_NAME>_PORT_<PORT>_TCP=tcp://<IP>:<PORT>

  • <SERVICE_NAME>_PORT_<PORT>_TCP_PROTO=tcp

  • <SERVICE_NAME>_PORT_<PORT>_TCP_PORT=<PORT>

  • <SERVICE_NAME>_PORT_<PORT>_TCP_ADDR=<ADDR>

如果参数长度超过允许值,并且服务名称的字符数对其有影响,则命名空间中的 Pod 将开始失败。