文档

创建有状态工作负载StatefulSet

更新时间:

阿里云容器计算服务ACS集群支持通过界面创建StatefulSet类型的应用,满足您快速创建有状态应用的需求。本例中将创建一个Nginx的有状态应用,并演示StatefulSet应用的特性。

前提条件

背景信息

StatefulSet包括以下特性:

场景

说明

Pod一致性

包含次序(启动、停止次序)、网络一致性。此一致性与Pod相关,与被调度到哪个Node节点无关。

稳定的持久化存储

通过VolumeClaimTemplate为每个Pod创建一个PV。删除或减少副本不会删除相关的存储卷。

稳定的网络标志

Pod的hostname模式为:(statefulset名称)−(序号)

稳定的次序

对于N个副本的StatefulSet,每个Pod都在 [0,N)的范围内分配一个数字序号,且是唯一的。

操作步骤

  1. 登录容器计算服务控制台,在左侧导航栏选择集群

  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择工作负载 > 有状态

  3. 有状态页面,单击使用镜像创建

  4. 应用基本信息页面,设置应用的基本信息。

    配置项

    描述

    应用名称

    设置应用的名称。

    副本数量

    应用包含的Pod数量。

    工作负载

    定义资源对象的类型,选择有状态(StatefulSet)

    标签

    为该应用添加一个标签,标识该应用。

    注解

    为该应用添加一个注解(Annotation)。

    实例类型

    请选择实例类型。关于实例的说明,请参见ACS Pod实例概述

    QoS类型

    选择QoS类型。通用型实例支持QoS类型包括“default”、“best-effort",“default”类型即为“Guaranteed”;性能型仅支持“Guaranteed”的“default”类型。详见算力质量定义

  5. 单击下一步进入容器配置页签。

  6. 设置容器相关的配置。

    说明

    容器配置页签上方,单击添加容器为应用的Pod设置多个容器。

    容器配置的配置项及描述如下。

    • 基本配置

      参数

      描述

      镜像名称

      • 单击选择镜像,选择所需的镜像。

        • 容器镜像服务企业版:可以选择托管在容器镜像服务ACR中的企业版镜像。需要选择镜像所属地域,以及镜像服务实例。关于ACR的更多信息,请参见什么是容器镜像服务ACR

        • 容器镜像服务个人版(需要提前开通):可以选择托管在容器镜像服务ACR中的个人版镜像。需要选择镜像所属地域,以及镜像服务实例。

        • 制品中心:包含应用容器化基础OS镜像、基础语言镜像、AI/大数据相关镜像,本示例以制品中心的Nginx镜像为例说明。关于制品中心的更多信息,请参见制品中心

      • ACS只支持总是拉取镜像(Always),即每次部署或扩容都会从容器镜像服务重新拉取镜像,不会从本地拉取镜像。

      • 单击设置镜像密钥,为私有镜像设置密钥以确保安全。

        • 对于ACR个人版实例,您可以通过设置镜像密钥的方式拉取容器镜像。有关设置密钥的更多信息,请参见管理保密字典

        • 对于ACR企业版实例,您可以通过免密组件拉取镜像。具体操作,请参见使用免密组件拉取容器镜像

      CPU

      可指定该容器CPU资源额度和资源限制,默认资源额度和资源限制相等,计费模式为按量计费。如果您通过YAML方式设置不同于资源额度的资源限制,资源额度将改写成与资源限制相等。详见资源规格

      Memory

      可指定该容器Memory资源额度和资源限制,默认资源额度和资源限制相等,计费模式为按量计费。如果您通过YAML方式设置不同于资源额度的资源限制,资源额度将改写成与资源限制相等。详见资源规格

      容器启动项

      • stdin:表示为该容器开启标准输入。

      • tty:表示为该容器分配一个虚拟终端,以便于向容器发送信号。

      通常这两个选项是一起使用的,表示将终端(tty)绑定到容器的标准输入(stdin)上。例如,一个交互式的程序从用户获取标准输入,并显示到终端中。

      初始化容器

      选中该项,表示创建一个Init Container。

      Init Container提供了一种机制来阻塞或延迟应用容器的启动,Init Container执行成功后,Pod内的应用容器会并行启动,例如检测依赖服务的可用性。Init Container可以包括一些应用镜像中不存在的实用工具和安装脚本,用来初始化应用容器的运行环境,例如设置内核参数、生成配置文件。更多信息,请参见Init Containers

    • 可选:端口设置区域,单击新增设置容器的端口。

      配置项

      说明

      名称

      设置容器端口名称。

      容器端口

      设置暴露的容器访问端口或端口名,端口号必须介于1~65535。

      协议

      支持TCP和UDP。

    • 可选:环境变量区域,单击新增设置环境变量。

      支持通过键值对的形式为Pod配置环境变量,用于给Pod添加环境标志或传递配置等。更多信息,请参见Pod variable

      配置项

      说明

      类型

      设置环境变量的类型:

      • 自定义

      • 配置项

      • 保密字典

      • 变量/变量引用

      • 资源引用

      配置项、保密字典支持全部文件的引用。

      本示例以保密字典为例。选择保密字典类型,只选择目标保密字典,则默认引用全部文件。环境变量

      对应的YAML,也引用了整个密钥(Secret)。yaml

      变量名称

      设置环境变量名称。

      变量/变量引用

      设置变量引用的值。

    • 可选:健康检查区域,根据需要开启存活检查就绪检查启动探测

      更多信息,请参见配置存活、就绪和启动探测器

      配置项

      请求类型

      配置说明

      • 存活检查(Liveness):用于检测何时重启容器。

      • 就绪检查(Readiness):确定容器是否已经就绪,且可以接受流量。

      • 启动探测(Startup Probes):用于检测何时启动容器。

      Http请求

      向容器发送一个HTTP GET请求,支持的参数包括:

      • 协议HTTP/HTTPS

      • 路径:访问HTTP Server的路径。

      • 端口:容器暴露的访问端口或端口名,端口号必须介于1~65535之间。

      • Http头:即HTTP Headers,HTTP请求中自定义的请求头,HTTP允许重复的Header。支持键值对的配置方式。

      • 延迟探测时间(秒):即initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为3秒。

      • 执行探测频率(秒):即periodSeconds,指执行探测的时间间隔,默认为10秒,最小为1秒。

      • 超时时间(秒):即timeoutSeconds,探测超时时间。默认1秒,最小1秒。

      • 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1,最小值是1。对于存活检查(liveness)必须是1。

      • 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3,最小值是1。

      TCP连接

      向容器发送一个TCP Socket,Kubelet将尝试在指定端口上打开容器的套接字。 如果可以建立连接,容器被认为是健康的,如果不能就认为是失败的。支持的参数包括:

      • 端口:容器暴露的访问端口或端口名,端口号必须介于1~65535之间。

      • 延迟探测时间(秒):即initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为15秒。

      • 执行探测频率(秒):即periodSeconds,指执行探测的时间间隔,默认为10秒,最小为1秒。

      • 超时时间(秒):即timeoutSeconds,探测超时时间。默认1秒,最小1秒。

      • 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1,最小值是1。对于存活检查(liveness)必须是1。

      • 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3,最小值是1。

      命令行

      通过在容器中执行探针检测命令,来检测容器的健康情况。支持的参数包括:

      • 命令行:用于检测容器健康情况的探测命令。

      • 延迟探测时间(秒):即initialDelaySeconds,容器启动后第一次执行探测时需要等待多少秒,默认为5秒。

      • 执行探测频率(秒):即periodSeconds,指执行探测的时间间隔,默认为10秒,最小为1秒。

      • 超时时间(秒):即timeoutSeconds,探测超时时间。默认1秒,最小1秒。

      • 健康阈值:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1,最小值是1。对于存活检查(liveness)必须是1。

      • 不健康阈值:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3,最小值是1。

    • 可选:生命周期区域,设置容器的生命周期。

      您可以为容器的生命周期配置启动执行、启动后处理和停止前处理。具体操作,请参见配置生命周期

      配置项

      说明

      启动执行

      为容器设置预启动命令和参数。

      启动后处理

      为容器设置启动后的命令。

      停止前处理

      为容器设置预终止命令。

    • 可选:数据卷区域,增加本地存储或云存储声明PVC(Persistent Volume Claim)。

      配置项

      说明

      增加本地存储

      本地存储包括配置项保密字典临时目录,将对应的挂载源挂载到容器路径中。更多信息,请参见volumes

      增加云存储声明(PersistentVolumeClaim)

      支持通过PVC挂载云存储卷。在选择目标挂载源前,您需要创建云存储声明。

      增加NAS

      支持挂载NAS类型持久化存储。在挂载前,您需要先通过NAS产品控制台创建容器挂载接入点,操作方法可参考容器挂载文件系统

      本例中配置了一个云存储类型的数据卷声明disk-ssd,将其挂载到容器的/tmp路径下。

  7. 日志配置区域,进行采集配置自定义Tag设置。

    配置项

    描述

    采集配置

    日志库:即在日志服务中生成一个对应的Logstore,用于存储采集日志。

    容器内日志路径:支持Stdout和文本日志。

    Stdout:表示采集容器的标准输出日志。

    文本日志:表示收集容器内指定路径的日志本例中表示/var/log/nginx下所有的文本日志,也支持通配符的方式。

    自定义Tag

    您还可以设置自定义Tag,设置Tag后,会将该Tag一起采集到容器的日志输出中。自定义Tag可以帮助您给容器日志打上Tag,方便进行日志统计和过滤等分析操作。

  8. 单击下一步,进入高级配置配置向导页面。

  9. 可选:高级配置向导页面中设置访问、伸缩、调度和标签注解。

    • 访问设置区域,设置暴露后端Pod的方式。

      您可以设置暴露后端Pod的方式。本例中选择虚拟集群IP和路由(Ingress),构建一个公网可访问的Nginx应用。

    • 配置服务(Service):在服务(Service)右侧,单击创建,设置创建服务配置项。

      展开查看服务配置说明

      配置项

      说明

      名称

      输入服务的名称,本例为nginx-svc。

      类型

      选择服务类型,即服务访问的方式。本例中选择虚拟集群IP

      • 虚拟集群IP:即ClusterIP,指通过集群的内部IP暴露服务,选择该值,服务只能够在集群内部访问,这也是默认的ServiceType。

        说明

        您的服务类型为虚拟集群IP时,方可设置实例间发现服务(Headless Service)

      • 负载均衡:即LoadBalancer,指阿里云提供的负载均衡服务(SLB),可选择公网访问或私网访问。阿里云负载均衡服务可以路由到ClusterIP服务。

        • 新建SLB:您可以通过单击修改,修改SLB规格。

        • 使用已有SLB:您可以在现有的列表中选择SLB规格。

        说明

        负载均衡类型支持新建SLB和使用已有SLB,并且多个Kubernetes Service可以复用同一个SLB,但存在以下限制:

        • 使用已有的负载均衡实例会强制覆盖已有的监听。

        • Kubernetes通过Service创建的SLB不能复用(会导致SLB被意外删除)。只能复用您手动在控制台(或调用OpenAPI)创建的SLB。

        • 复用同一个SLB的多个Service不能有相同的前端监听端口,否则会造成端口冲突。

        • 复用SLB时,监听的名字以及虚拟服务器组的名字被Kubernetes作为唯一标识符。请勿修改监听和虚拟服务器组的名字。

        • 不支持跨集群复用SLB。

      端口映射

      添加服务端口和容器端口。容器端口需要与后端的Pod中暴露的容器端口一致。

      外部流量策略

      • Local:流量只发给本机的Pod。

      • Cluster:流量可以转发到其他节点上的Pod。

      说明

      当您的服务类型为负载均衡时,才能设置外部流量策略

      注解

      为该服务添加一个注解(Annotation),配置负载均衡的参数。例如设置service.beta.kubernetes.io/alicloud-loadbalancer-bandwidth:20表示将该服务的带宽峰值设置为20Mbit/s,从而控制服务的流量。

      标签

      为该服务添加一个标签,标识该服务。

    • 配置路由(Ingress):在路由(Ingress)右侧,单击创建设置后端Pod的路由规则。

      展开查看路由配置说明

      说明

      通过镜像创建应用时,您仅能为一个服务创建路由(Ingress)。本例中使用一个虚拟主机名称作为测试域名,您需要在Hosts文件中添加一条域名映射(Ingress外部端点 + Ingress域名)。在实际工作场景中,请使用备案域名。

      101.37.XX.XX   foo.bar.com    #即Ingress的IP。

      配置项

      说明

      名称

      输入路由的名称,本例为nginx-ingress。

      规则

      路由规则是指授权入站到达集群服务的规则。更多信息,请参见创建Nginx Ingress

      • 域名:输入Ingress域名。

      • 路径:指定服务访问的URL路径,默认为根路径/,本例中不做配置。每个路径(path)都关联一个backend(服务),在阿里云SLB将流量转发到backend之前,所有的入站请求都要先匹配域名和路径。

      • 服务:选择服务的名称和对应端口。

      • 开启TLS:配置安全的路由服务。具体操作,请参见Ingress高级用法

      本例中使用测试域名foo.bar.com,设置服务为nginx-svc。

      灰度发布

      开启灰度发布开关。此处建议选择社区版,阿里云版灰度发布已不再维护更新。

      Ingress Class

      自定义Ingress的类。

      注解

      您可以自定义注解名称和值,也可以根据名称选择或搜索需要配置的注解。单击添加按钮,输入注解名称和值,即Ingress的Annotation键值对。关于Ingress的注解,请参见Annotations

      标签

      单击+添加,输入标签的名称和值,为Ingress添加对应的标签,标识该Ingress的特点。

    1. 可选:伸缩配置区域,配置是否开启指标伸缩,从而满足应用在不同负载下的需求。

      • 容器服务支持容器组的指标伸缩,即根据容器的CPU和内存资源的占用情况自动调整容器组的数量。

        说明

        若要启用自动伸缩,您必须为容器设置所需资源,否则容器自动伸缩无法生效。

        配置项

        说明

        指标

        支持CPU和内存,需要和设置的所需资源类型相同。

        触发条件

        资源使用率的百分比,超过该使用量,容器开始扩容。

        最大副本数

        该负载类型可扩容的容器数量上限。

        最小副本数

        该负载类型可缩容的容器数量下限。

      • 容器服务支持容器组的定时伸缩,即定时地对容器服务Kubernetes集群进行扩/缩容。开启定时伸缩前,需要先安装ack-kubernetes-cronhpa-controller组件。关于定时伸缩的详细说明,请参见容器定时伸缩(CronHPA)

    1. 可选:标签和注解区域,单击添加设置容器组的标签和注解。

    2. 配置完成后,单击创建

  10. 创建完成配置向导页面中查看应用任务。

    1. 单击查看应用详情,进入新建应用的详情页面。

    2. 在左侧导航栏,选择网络 > 路由,在规则列可以看到工作负载对应的路由规则。

    3. 在浏览器中访问路由测试域名,您可以访问到Nginx欢迎页。

后续步骤

连接到Master节点,执行以下命令,验证持久化存储特性。

  1. 执行以下命令在云盘中创建临时文件。

    kubectl exec nginx-1 -- ls /tmp            #列出该目录下的文件lost+found。
    kubectl exec nginx-1 -- touch /tmp/statefulset         #增加一个临时文件statefulset。
    kubectl exec nginx-1 -- ls /tmp

    预期输出:

    lost+found
    statefulset
  2. 执行以下命令删除Pod,验证数据持久性。

    kubectl delete pod nginx-1

    预期输出:

    pod"nginx-1" deleted
  3. 过一段时间,待Pod自动重启后,验证数据持久性,证明StatefulSet应用的高可用性。

    kubectl exec nginx-1 -- ls /tmp   #数据持久化存储lost+found。

    预期输出:

    statefulset