全部产品
Search
文档中心

容器服务 Kubernetes 版 ACK:创建无状态工作负载Deployment

更新时间:Feb 11, 2025

Deployment是Kubernetes中最常使用的工作负载类型之一,也被称为“无状态工作负载”,它的目标是保证集群中始终有固定数量的Pod以您指定的状态持续运行。本文介绍如何在ACK集群中通过控制台及kubectl创建无状态应用。

阅读前提示

在创建工作负载前,建议您阅读工作负载,了解工作负载的基础知识和注意事项。本文主要分为以下两部分内容:

  • 创建Deployment:提供控制台和kubectl两种创建方式的快速创建流程。

  • 配置项说明:提供控制台配置项的相关文档以及使用kubectl时的YAML示例。

创建Deployment

通过控制台创建

重要

以下是一个简化的工作负载创建流程。您可以参考该流程快速部署并验证工作负载。熟悉基本操作后,您可以参考配置项说明自定义您的工作负载。

  1. 配置应用基本信息

    1. 登录容器服务管理控制,在左侧导航栏选择集群列表集群列表页面,单击目标集群名称,然后在左侧导航栏,选择工作负载 > 无状态无状态页面,单击使用镜像创建

      image

    2. 应用基本信息配置向导页面,设置应用的基本信息。然后单击下一步,进入容器配置向导页面。

      image

  2. 配置容器

    容器配置区域,完成容器的镜像名称端口基本配置。其余设置均为可选设置,保持默认即可。然后单击下一步,进入高级配置向导页面。镜像地址如下所示。

    重要

    拉取此镜像前,您需要为集群开启公网访问能力。如果您在创建集群时,为专有网络配置SNAT选择保持默认勾选,则集群已拥有公网访问能力。如果未选择,请参见为已有集群开启公网访问能力

    registry.cn-hangzhou.aliyuncs.com/acs-sample/nginx:latest

    image

  3. 完成高级配置

    高级配置向导页面中设置访问、伸缩、调度和标签注解。在访问设置区域,设置暴露后端Pod的方式,单击确定,然后单击最下方的创建

    重要

    此步骤会创建一个LoadBalancer类型的Service用于暴露工作负载,其使用的CLB实例会产生一定的费用,详细计费项请参见按量付费。如果您后续不计划使用此CLB,请及时释放。

    image

  4. 查看应用

    创建完成配置向导页面中查看应用任务。创建应用任务已提交面板,单击查看应用详情单击访问方式页签,找到新创建的服务(即nginx-test-svc),单击外部端点列的链接即可访问。image

    image

    您可通过控制台对已创建的工作负载进行查看编辑重新部署等操作。image

通过kubectl创建

重要

创建工作负载前,请确保已通过kubectl连接到集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群

  1. 执行以下命令创建工作负载。以下命令指定了容器镜像,而其他配置保持默认。

    • 1.18以上版本的集群,使用以下命令启动。

      kubectl create deployment nginx --image=registry.cn-hangzhou.aliyuncs.com/acs-sample/nginx:latest
    • 1.18及以下版本的集群,使用以下命令启动。

      kubectl run -it nginx --image=registry.cn-hangzhou.aliyuncs.com/acs-sample/nginx:latest
  2. 执行以下命令,创建一个LoadBalancer类型的Service,使用负载均衡实例对外暴露工作负载。

    kubectl expose deployment nginx --port=80 --target-port=80 --type=LoadBalancer
  3. 执行以下命令,查看Service的公网IP地址。

    kubectl get svc

    预期输出:

    NAME         TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)        AGE
    kubernetes   ClusterIP      172.16.**.***    <none>          443/TCP        4h47m
    nginx        LoadBalancer   172.16.**.***    106.14.**.***   80:31130/TCP   1h10m
  4. 在浏览器中输入nginx的公网IP(106.14.**.***),即可访问工作负载所属的Nginx容器。image

配置项说明

控制台配置项说明

应用基本信息

image

配置项

说明

应用名称

工作负载的名称,工作负载所属的Pod的名称会以此生成。

副本数量

工作负载包含的Pod数量,默认数量为2。

类型

工作负载的类型,本文中选择无状态(Deployment)。工作负载的选型请参见创建工作负载

标签

工作负载的标签。

注解

工作负载的注解(Annotation)。

时区同步

容器与所在节点是否使用相同的时区。

容器配置

基本配置

image

配置项

说明

镜像名称

  • 选择镜像

    您可以单击选择镜像,选择所需的镜像。支持选择以下三种类型的镜像。

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

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

    • 制品中心:由阿里云及龙蜥社区提供的一些常见镜像。使用制品中心时,需要集群开启公网访问能力。关于制品中心的更多信息,请参见制品中心

    使用其他来源的镜像时,您可直接填入镜像地址,格式为domainname/namespace/imagename:tag。不指定domainname时,例如输入nginx:1.7.9,将从DockerHub拉取镜像。

  • 选择镜像拉取策略

    ACK支持以下三种镜像拉取策略(imagePullPolicy):

    • 优先使用本地镜像(IfNotPresent)(默认):如果Worker节点上有本地镜像,则使用本地镜像,本地不存在时拉取镜像。

    • 总是拉取镜像(Always):表示每次部署或扩容都会从容器镜像服务重新拉取镜像,而不会从本地拉取镜像。

    • 仅使用本地镜像(Never):仅使用本地镜像,本地无镜像时拉取失败。

  • 设置镜像密钥

    使用ACR或第三方仓库时,您可能需要配置密钥以拉取镜像。

    说明

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

资源限制

容器资源的resources.limits。更多信息,请参见Requests and Limits

所需资源

容器资源的resources.requests。更多信息,请参见Requests and Limits

容器启动项

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

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

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

特权容器

  • 勾选特权容器,则privileged=true,开启特权模式。

  • 不勾选特权容器,则privileged=false,不使用特权模式。

特权模式允许容器拥有与所在的Worker节点操作系统近似的权限,例如访问硬件设备、挂载文件系统等。

初始化容器

选中该选项,表示创建一个初始化容器。

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

端口设置

image

配置项

说明

名称

容器端口的名称,仅用于区分端口,没有实际功能。

容器端口

设置容器对外暴露的端口,必须介于1~65535之间。容器只有对外暴露端口,才能实现对Pod外暴露以及Pod中容器互相通信。

一个Pod中的所有容器共享Pod的网络协议栈,因此在Pod中配置多个容器时,端口不能重复。

协议

容器端口使用的4层(传输层)协议,支持TCP和UDP。

环境变量

image

配置项

说明

类型

设置环境变量的类型,支持以下类型:

  • 自定义

    使用env直接在工作负载中硬编码环境变量。

  • 配置项

    使用envFrom获取存储在ConfigMap中的非敏感配置数据。

  • 保密字典

    使用envFrom获取存储在ConfigMap中的敏感信息,如密码、API 密钥等。

  • 变量/变量引用

    使用value/valueFrom获取其他环境变量或者预先定义的值。

  • 资源引用

    使用resourceFieldRef获取Pod所在节点的资源信息。

配置项、保密字典支持对全部文件的引用,以保密字典为例。选择保密字典类型,只选择目标保密字典,则默认引用全部文件。环境变量

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

选择资源引用,主要使用resourceFieldRef参数,从Pod规范中引用容器已经声明的资源值,然后将这些值作为环境变量传递给容器。对应的YAML如下:

image

变量名称

设置在Pod中环境变量名称。

变量/变量引用

指定环境变量的值或从其他来源获取的值。

健康检查

image

配置项

说明

存活检查(Liveness Probes):用来检查容器是否正常,不正常则重启容器。

请求类型:HTTP请求

向容器发送HTTP请求,定期检查容器是否正常。

  • 协议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将尝试在指定端口上打开容器的Socket。如果可以建立连接,容器被认为是健康的,如果不能,则认为容器已失败。

  • 端口:容器暴露的访问端口或端口名,端口号必须介于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。

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

启动探测(Startup Probes):用于检测容器内应用是否已启动。

说明

仅Kubernetes集群1.18及之后版本支持启动探测。

生命周期

image

配置项

说明

启动执行

为容器设置预启动命令和参数。启动命令与参数定义了容器启动时执行的操作,用于初始化应用服务。适用于需要特定环境变量、挂载点或端口映射的应用部署场景。

启动后处理

为容器设置启动后的命令。启动后处理命令用于容器启动后执行特定任务,如初始化配置、运行脚本等,适用于需要在主进程前完成准备工作的场景。

停止前处理

为容器设置预结束命令。停止前处理命令用于关闭容器内的应用进程,确保数据一致性与服务正常终止。适用于需安全停机避免数据丢失或服务异常的场景。

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

数据卷

配置项

说明

增加本地存储

使Pod挂载所在节点的本地存储卷,本地存储卷的数据保存在节点上,节点停机时数据即不再可用。在本地存储同样支持Secret、ConfigMap与其他临时卷类型。存储的功能较为复杂,使用存储卷前,建议您阅读存储了解ACK中存储的基础知识。

增加云存储声明(PersistentVolumeClaim)

使Pod挂载云存储卷,用于持久化保存容器内重要数据。云存储卷是位于集群外的远端存储服务,与Worker节点完全独立,不受节点变化的影响。在使用ACK时,云存储卷通常是阿里云提供的云盘、NAS、OSS等存储服务。存储的功能较为复杂,使用存储卷前,建议您阅读存储了解ACK中存储的基础知识。

日志配置

采集配置

  • 日志库:在集群关联的日志服务Project中生成一个对应的Logstore,用于存储采集到的日志。使用日志前,建议您阅读日志管理了解ACK中日志的基础知识。

  • 容器内日志路径:需要采集的容器内日志路径。设置为Stdout时,表示采集容器的标准输出日志。

自定义Tag

通过定时触发工作负载伸缩,适用于业务负载存在周期性变化的场景,例如社交媒体在午餐后和晚餐后周期性的流量高峰。更多信息,请参见使用容器定时水平伸缩(CronHPA)

高级配置

配置卡片

配置项

说明

访问设置

Service

服务(Service)为一组Pod提供一个固定、统一的四层(传输层)入口,它是对外暴露工作负载时必须配置的资源。Service支持多种类型,包括虚拟集群IP节点端口负载均衡等。配置Service前,请参见Service管理了解Service基础知识。

Ingress

路由(Ingress)为集群中的多个Service提供七层(应用层)入口,并通过域名匹配将请求转发到不同的Service。在使用Ingress前,您需要安装Ingress Controller,ACK为此提供了多种适用于不同的场景的选项,请参见Nginx Ingress、ALB Ingress和MSE Ingress对比进行选型。

伸缩配置

指标伸缩

通过监测容器的性能指标触发自动伸缩。指标伸缩可以帮助您在业务负载出现波动时自动调整工作负载使用的资源总量,在高负载时扩容缓解压力,低负载时缩容节省资源。更多信息,请参见使用容器水平伸缩(HPA)

定时伸缩

通过定时触发工作负载伸缩,适用于业务负载存在周期性变化的场景,例如社交媒体在午餐后和晚餐后周期性的流量高峰。更多信息,请参见使用容器定时水平伸缩(CronHPA)

调度设置

升级方式

Pod配置发生变更时,工作负载使用新Pod替换旧Pod的机制。

  • 滚动升级(rollingupdate):每次只替换一部分Pod,直到新Pod运行成功后再执行下一次替换。使用这种方式可以保证服务不中断,但用户可能同时访问到不同版本的Pod。

  • 替换升级(recreate):一次性替换所有的Pod,可能会造成服务中断,但是可以保证所有Pod版本的一致性。

  • 节点亲和性

  • 应用亲和性

  • 应用反亲和性

  • 调度容忍

亲和性、反亲和性、容忍等配置用于调度,即使Pod运行在特定节点上。调度的操作较为复杂,需要您提前按照需求进行规划。详细操作,请参见调度

标签和注解

Pod标签

为该工作负载所属的每个Pod添加标签(Label)。集群中包括工作负载、Service在内的各种资源会通过标签与Pod进行匹配。ACK为Pod默认添加格式为app:(应用名称)的标签。

Pod注解

为该工作负载所属的每个Pod添加注解(Annotation)。ACK中的部分功能会使用到注解,您可在使用这些功能时再编辑。

工作负载YAML示例

apiVersion: apps/v1
kind: Deployment    # 工作负载类型
metadata:
  name: nginx-test
  namespace: default  # 根据需要更改命名空间
  labels:
    app: nginx
spec:
  replicas: 2  # 指定Pod数量
  selector:
    matchLabels:
      app: nginx
  template: # Pod配置
    metadata:
      labels: # Pod标签
        app: nginx 
      annotations: # Pod注解
        description: "This is an application deployment"
    spec:
      containers:
      - name: nginx  # 镜像名称
        image: nginx:1.7.9  # 使用特定版本的 Nginx 镜像
        ports:
        - name: nginx  # name
          containerPort: 80  # 容器暴露的端口
          protocol: TCP  # 指定协议为 TCP/UDP,默认也是 TCP
        command: ["/bin/sh"]  # 容器启动项
        args: [ "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY) && exec nginx -g 'daemon off;'"] # 输出变量、添加启动 nginx 的命令
        stdin: true  # 开启标准输入
        tty: true    # 分配一个虚拟终端
        env:
          - name: SPECIAL_LEVEL_KEY
            valueFrom:
              configMapKeyRef:
                name: special-config  # 配置项的名称 
                key: SPECIAL_LEVEL    # 配置项的key名称
        securityContext:
          privileged: true  # true 开启特权模式,false关闭特权模式,默认值 false
        resources:
          limits:
            cpu: "500m"               # 最大 CPU 使用量,500 毫核
            memory: "256Mi"           # 最大内存使用量,256 MiB
            ephemeral-storage: "1Gi"  # 最大临时存储使用量,1 GiB
          requests:
            cpu: "200m"               # 请求的最小 CPU 使用量,200 毫核
            memory: "128Mi"           # 请求的最小内存使用量,128 MiB
            ephemeral-storage: "500Mi" # 请求的最小临时存储使用量,500 MiB
        livenessProbe:  # 存活性探针配置
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:  # 就绪探针配置
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 10
        volumeMounts:
        - name: tz-config
          mountPath: /etc/localtime
          readOnly: true
      volumes:
      - name: tz-config
        hostPath:
          path: /etc/localtime  #通过 volumeMounts 和 volumes 字段将宿主机的 /etc/localtime 文件挂载到容器内相同路径下。
---
# service
apiVersion: v1
kind: Service
metadata:
  name: nginx-test-svc
  namespace: default  # 根据需要更改命名空间
  labels:
    app: nginx
spec:
  selector:
    app: nginx  # 匹配标签,确保服务指向正确的 Pods
  ports:
    - port: 80           # Service 在集群内提供的端口
      targetPort: 80     # 指向容器内部应用程序监听的端口 (containerPort)
      protocol: TCP      # 协议,默认是 TCP
  type: ClusterIP        # 服务类型,默认是 ClusterIP,内部访问
---
# ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: default  # 根据需要更改命名空间
  annotations:
    kubernetes.io/ingress.class: "nginx"  # 指定 Ingress 控制器类型
    # 如果使用阿里云 SLB Ingress 控制器,可以指定如下:
    # service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: "lb-xxxxxxxxxx"
    # service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: "slb.spec.s1.small"
spec:
  rules:
    - host: foo.bar.com  # 替换为你的域名
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-service  # 后端服务名称
                port:
                  number: 80         # 后端服务端口
  tls:  # 可选,用于启用 HTTPS
    - hosts:
        - foo.bar.com  # 替换为你的域名
      secretName: tls-secret  # TLS 证书 Secret 名称

相关文档