云服务器内容精选

  • networking.k8s.io/v1版本Ingress说明 CCE在v1.23版本集群开始Ingress切换到networking.k8s.io/v1版本。 v1版本参数相较v1beta1参数有如下区别。 ingress类型由annotations中kubernetes.io/ingress.class变为使用spec.ingressClassName字段。 backend的写法变化。 每个路径下必须指定路径类型pathType,支持如下类型。 ImplementationSpecific: 对于这种路径类型,匹配方法取决于具体Ingress Controller的实现。在CCE中会使用ingress.beta.kubernetes.io/url-match-mode指定的匹配方式,这与v1beta1方式相同。 Exact:精确匹配 URL 路径,且区分大小写。 Prefix:基于以 / 分隔的 URL 路径前缀匹配。匹配区分大小写,并且对路径中的元素逐个匹配。 路径元素指的是由 / 分隔符分隔的路径中的标签列表。
  • 前提条件 集群必须已安装NGINX Ingress 控制器,具体操作可参考安装插件。 Ingress为后端工作负载提供网络访问,因此集群中需提前部署可用的工作负载。若您无可用工作负载,可参考创建无状态负载(Deployment)、创建有状态负载(StatefulSet)或创建守护进程集(DaemonSet)部署工作负载。 为上述工作负载配置ClusterIP类型或NodePort类型的Service,可参考集群内访问(ClusterIP)或节点访问(NodePort)配置示例Service。
  • 场景示例 下图场景为例。某企业在华为云使用CCE集群,并通过自建Nginx Ingress Controller配置Ingress转发规则,配置域名和路径的转发策略,且对外通过DNS域名提供服务。客户端访问域名example.com时,Nginx Ingress接收到请求会根据对应的转发策略将流量转发至对应Service的Pod上。 由于业务发展需要,该企业需要将自建Nginx Ingress迁移到ELB Ingress上。为了保持业务稳定,希望不改变对外提供服务的DNS域名及后端服务器的IP地址。您可以通过在 CCE集群上配置 ELB Ingress 规则,使ELB提供的转发策略与之前一致,然后利用DNS域名解析的权重设置完成流量的迁移。 建议在业务低谷期进行流量的切换。 使用ELB会产生计费信息,具体计费详情请参见计费概述。
  • 切流至ELB Ingress 流量切换前,假设您已将业务域名通过A记录解析的方式指向了自建Nginx Ingress的公网地址。您可以使用DNS的流量权重分配,逐步将访问原Nginx Ingress的流量切换至新的ELB Ingress。 图1 使用DNS切流 您可以通过以下步骤完成流量的切换。 进入公网域名列表页面。 在“公网域名”页面的域名列表中,单击域名example.com的名称。 进入“解析记录”页面。此时已存在一个A记录,对应Nginx Ingress的公网IP。修改Nginx Ingress的A记录的权重为9。 单击“添加记录集”,添加A记录,地址为待迁移的ELB公网IP,并将权重设置为1。 图2 修改DNS记录集 在观察业务没有影响的情况下,逐步调整ELB实例解析记录的权重值至100%。
  • 通过控制台创建 登录CCE控制台,单击集群名称进入集群。 在左侧导航栏中选择“服务”,切换至“路由”页签,在右上角单击“创建路由”。 设置Ingress参数。本示例中仅列举必选参数,其余参数可根据需求参考通过控制台创建ELB Ingress进行设置。 名称:自定义服务名称,可与工作负载名称保持一致。 负载均衡器:选择弹性负载均衡的类型、创建方式。 类型:本例中仅支持选择“独享型”。 创建方式:本文中以选择已有ELB为例进行说明,关于自动创建的配置参数请参见负载均衡器。 监听器配置: 前端协议:支持HTTP和HTTPS。本文以HTTP协议为例。 对外端口:开放在负载均衡服务地址的端口,可任意指定。 高级配置: 配置 说明 使用限制 获取监听器端口号 开启后可以将ELB实例的监听端口从报文的HTTP头中带到后端云服务器。 独享型ELB实例支持配置。 获取客户端请求端口号 开启后可以将客户端的源端口从报文的HTTP头中带到后端云服务器。 独享型ELB实例支持配置。 重写X-Forwarded-Host 开启后将以客户端请求头的Host重写X-Forwarded-Host传递到后端云服务器。 独享型ELB实例支持配置。 图1 配置HTTP/HTTPS头字段 转发策略配置:填写域名匹配规则及需要访问的目标Service。请求的访问地址与转发规则匹配时(转发规则由域名、URL组成,例如:10.117.117.117:80/helloworld),此请求将被转发到对应的目标Service处理。 单击“确定”,创建Ingress。
  • Ingress支持的Service类型 ELB Ingress支持的Service类型如表1所示。 表1 ELB Ingress支持的Service类型 集群类型 ELB类型 集群内访问(ClusterIP) 节点访问(NodePort) CCE Standard集群 共享型负载均衡 不支持 支持 独享型负载均衡 不支持(集群内访问服务关联实例未绑定eni网卡,独享型负载均衡无法对接) 支持 CCE Turbo集群 共享型负载均衡 不支持 支持 独享型负载均衡 支持 不支持(节点访问服务关联实例已绑定eni网卡,独享型负载均衡无法对接) Nginx Ingress支持的Service类型如表2所示。 表2 Nginx Ingress支持的Service类型 集群类型 ELB类型 集群内访问(ClusterIP) 节点访问(NodePort) CCE Standard集群 共享型负载均衡 支持 支持 独享型负载均衡 支持 支持 CCE Turbo集群 共享型负载均衡 支持 支持 独享型负载均衡 支持 支持
  • 为什么需要Ingress Service基于TCP和UDP协议进行访问转发,为集群提供了四层负载均衡的能力。但是在实际场景中,Service无法满足应用层中存在着大量的HTTP/HTTPS访问需求。因此,Kubernetes集群提供了另一种基于HTTP协议的访问方式——Ingress。 Ingress是Kubernetes集群中一种独立的资源,制定了集群外部访问流量的转发规则。如图1所示,用户可根据域名和路径对转发规则进行自定义,完成对访问流量的细粒度划分。 图1 Ingress示意图 下面对Ingress的相关定义进行介绍: Ingress资源:一组基于域名或URL把请求转发到指定Service实例的访问规则,是Kubernetes的一种资源对象,通过接口服务实现增、删、改、查的操作。 Ingress Controller:请求转发的执行器,用以实时监控资源对象Ingress、Service、Endpoint、Secret(主要是TLS证书和Key)、Node、ConfigMap的变化,解析Ingress定义的规则并负责将请求转发到相应的后端Service。 Ingress Controller在不同厂商之间的实现方式不同,根据负载均衡器种类的不同,可以将其分成ELB型和Nginx型。CCE支持上述两种Ingress Controller类型,其中ELB Ingress Controller基于弹性负载均衡服务(ELB)实现流量转发;而Nginx Ingress Controller使用Kubernetes社区维护的模板与镜像,通过Nginx组件完成流量转发。
  • ELB Ingress Controller工作原理 CCE自研的ELB Ingress Controller基于弹性负载均衡服务ELB实现公网和内网(同一VPC内)的七层网络访问,通过不同的URL将访问流量分发到对应的服务。 ELB Ingress Controller部署于Master节点上,与集群所在VPC下的弹性负载均衡器绑定,支持在同一个ELB实例(同一IP)下进行不同域名、端口和转发策略的设置。ELB Ingress Controller的工作原理如图2,实现步骤如下: 用户创建Ingress资源,在Ingress中配置流量访问规则,包括负载均衡器、URL、SSL以及访问的后端Service端口等。 Ingress Controller监听到Ingress资源发生变化时,就会根据其中定义的流量访问规则,在ELB侧重新配置监听器以及后端服务器路由。 当用户进行访问时,流量根据ELB中配置的转发策略转发到对应的后端Service端口,然后再经过Service二次转发访问到关联的各个工作负载。 图2 ELB Ingress工作原理(CCE Standard集群以及CCE Turbo集群使用共享型ELB场景) 在使用CCE Turbo集群 + 独享型ELB实例时,Pod IP直接从VPC中分配,支持ELB直通Pod。创建集群外部访问的Ingress时,可使用ELB对接ClusterIP服务,直接将Pod作为ELB监听器的后端服务器,外部流量可以不经过节点端口转发直接访问集群中的Pod。 图3 ELB Ingress直通容器原理(CCE Turbo集群使用独享型ELB场景)
  • Nginx Ingress Controller工作原理 Nginx型的Ingress使用弹性负载均衡(ELB)作为流量入口,并在集群中部署nginx-ingress插件来对流量进行负载均衡及访问控制。 nginx-ingress插件使用开源社区的模板与镜像,使用过程中可能存在缺陷,CCE会定期同步社区版本来修复已知漏洞。请评估是否满足您的业务场景要求。 开源社区地址:https://github.com/kubernetes/ingress-nginx Nginx型的Ingress Controller通过pod部署在工作节点上,因此引入了相应的运维成本和Nginx组件运行成本,其工作原理如图4,实现步骤如下: 当用户更新Ingress资源后,Ingress Controller就会将其中定义的转发规则写入到Nginx的配置文件(nginx.conf)中。 内置的Nginx组件进行reload,加载更新后的配置文件,完成Nginx转发规则的修改和更新。 在流量访问集群时,首先被已创建的负载均衡实例转发到集群内部的Nginx组件,然后Nginx组件再根据转发规则将其转发至对应的各个工作负载。 图4 Nginx Ingress Controller工作原理
  • 步骤1:创建工作负载,并通过Ingress对外暴露服务 在cluster-1集群中部署应用,并测试访问。 复制以下文件保存到nginx-deploy.yaml文件。 apiVersion: apps/v1 kind: Deployment metadata: labels: version: v1 name: nginx namespace: default spec: selector: matchLabels: app: nginx version: v1 template: metadata: labels: app: nginx version: v1 spec: containers: - name: container-1 image: nginx:latest imagePullPolicy: IfNotPresent terminationGracePeriodSeconds: 30 dnsPolicy: ClusterFirst replicas: 1 --- apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx namespace: default spec: selector: app: nginx externalTrafficPolicy: Cluster ports: - name: cce-service-0 targetPort: 80 port: 80 protocol: TCP type: NodePort --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx namespace: default spec: rules: - host: example.com http: paths: - path: / backend: service: name: nginx port: number: 80 property: ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH pathType: ImplementationSpecific ingressClassName: nginx 对cluster-1集群执行以下命令,创建工作负载。 kubectl apply -f nginx-deploy.yaml 在cluster-2集群中部署相同的应用,重复执行以上命令,创建相同的工作负载。
  • 参数说明 表1 灰度发布参数说明 参数 是否必填 参数类型 描述 kubernetes.io/elb.canary 否 string 设置Ingress灰度发布的开关。设置为true后,配合不同的注解,可以实现不同的灰度发布功能。 取值范围:true 独享型负载均衡器生效。 设置为true后,不允许删除或修改。 kubernetes.io/elb.canary-weight 否 string 权重灰度发布权重值,设置后Ingress以权重灰度形式发布。 取值为0-100的正整数,为灰度流量分配的百分比。 发布成权重灰度Ingress时,该参数必填。 不能与其他灰度发布功能同时设置。 kubernetes.io/elb.session-affinity-mode 否 string 开启权重灰度发布后,配置会话保持能力。 灰度发布仅支持设置为 "HTTP_COOKIE"。 kubernetes.io/ elb.session-affinity-option 否 string 开启权重灰度发布会话保持能力后,会话保持的超时时间。 参数值为json字符串,格式如下: {"persistence_timeout": "1440"} 参数说明: 超时时间范围为1-1440。 默认值为1440。 kubernetes.io/elb.canary-by-header 否 string header灰度发布的Key值,表示请求头参数的名称。需要与kubernetes.io/elb.canary-by-header-value成对使用。 参数说明: 长度限制1-40字符,只允许包含字母、数字、中划线(-)和下划线(_)。 kubernetes.io/elb.canary-by-header-value 否 string header灰度发布的Values值,需要与kubernetes.io/elb.canary-by-header成对使用。 参数值为json格式的数组,例如: '{"values":["a","b"]}' 参数说明: 数组长度:最小值为1,最大值为10。 数组取值:长度限制1-128字符,不支持空格,双引号,支持以下通配符:*(匹配0个或更多字符)和?(正好匹配1个字符)。 kubernetes.io/elb.canary-by-cookie 否 string cookie灰度发布的key值,表示请求cookie参数的名称。需要与kubernetes.io/elb.canary-by-cookie-value成对使用。 参数说明: 长度限制1-100字符,支持包含字母、数字、以及 !%'"()*+,./:=?@^\\-_`~ 等字符。 kubernetes.io/elb.canary-by-cookie-value 否 string cookie灰度发布的values值,需要与kubernetes.io/elb.canary-by-cookie成对使用。 参数值为json格式的数组,例如: '{"values":["a","b"]}' 参数说明: 数组长度:最小值为1,最大值为10。 数组取值:长度限制1-100字符,不支持空格,支持包含字母、数字、以及 !%'"()*+,./:=?@^\\-_`~ 等字符。 kubernetes.io/elb.canary-related-ingress-uid 否 string 灰度发布Ingress关联的原始Ingress的uid信息,用于前端展示原始Ingress和灰度发布的Ingress的关联关系。 ● 参数格式:字符串 ● 取值:原始Ingress的metadata.uid字段
  • 灰度发布服务部署 部署原服务。 部署名为origin-server的工作负载。 部署名为origin-service的service,关联刚创建的origin-server工作负载。(CCE Standard集群创建nodeport类型Service,Turbo集群创建ClusterIP类型Service) 部署名为origin-ingress的Ingress,关联刚创建的origin-service服务。 Ingress的配置如下: apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: origin-ingress namespace: default annotations: kubernetes.io/elb.port: '81' kubernetes.io/elb.id: e491f4e7-2351-4984-ad0a-8569e5e964a3 kubernetes.io/elb.class: performance spec: rules: - host: nginx1.com http: paths: - path: / backend: service: name: origin-service port: number: 81 property: ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH pathType: ImplementationSpecific ingressClassName: cce 灰度发布新版本服务。 部署新版本工作负载、服务和Ingress,使得流量能够通过权重或者头域导流到新版本服务上。 部署名为canary-server的工作负载。 部署名为canary-service的服务,关联刚创建的canary-server工作负载。(CCE Standard集群创建nodeport类型Service,Turbo集群创建ClusterIP类型Service) 部署名为canary-weight-ingress的Ingress,关联刚创建的canary-service服务,实现权重灰度发布。 Ingress的配置如下: apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: canary-weight-ingress namespace: default annotations: kubernetes.io/elb.canary: 'true' // 设置为true,表示启用canary注解功能。 kubernetes.io/elb.canary-weight: '40' // 权重值设置,表示对应请求40%的流量将被导流到新版本服务上。 kubernetes.io/elb.class: performance // 仅独享型ELB支持灰度发布 kubernetes.io/elb.id: e491f4e7-2351-4984-ad0a-8569e5e964a3 kubernetes.io/elb.port: '81' spec: ingressClassName: cce rules: - host: nginx1.com http: paths: - path: / pathType: ImplementationSpecific backend: service: name: canary-service port: number: 81 property: ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH 部署名为canary-header-ingress的Ingress,关联刚创建的canary-service服务,实现Header灰度发布。 Ingress的配置如下: apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: canary-header-ingress namespace: default annotations: kubernetes.io/elb.canary: 'true' kubernetes.io/elb.canary-by-header: 'location' // header的key值设置为location kubernetes.io/elb.canary-by-header-value: '{"values":["hz","sz","sh"]}' // header的value值设置为hz、sz、sh kubernetes.io/elb.class: performance kubernetes.io/elb.id: e491f4e7-2351-4984-ad0a-8569e5e964a3 kubernetes.io/elb.port: '81' spec: ingressClassName: cce rules: - host: nginx1.com http: paths: - path: / pathType: ImplementationSpecific backend: service: name: canary-service port: number: 80 property: ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH 查看灰度发布新版本服务是否成功。 查看Ingress创建: $ kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE canary-header-ingress cce nginx1.com 88.88.88.165 80 46s canary-weight-ingress cce nginx1.com 88.88.88.165 80 117s origin-ingress cce nginx1.com 88.88.88.165 80 2m25s 查看ELB生成规则: 服务请求返回结果: 使用location:hz请求头的请求访问服务: $ curl -H "Host: nginx1.com" -H "location: hz" http://88.88.88.165:81/ 预期结果: $ new 多次访问,返回结果均为new 不使用请求头的请求访问服务: $ curl -H "Host: nginx1.com" http://88.88.88.165:81/ 预期结果:返回值40%为new,60%为old。 老版本服务下线。 新版本服务运行稳定后,需要下线老版本服务。下线流程将原服务Ingress中的Service修改为新版本服务的Service,使流量都路由到新版本服务上,然后删除灰度Ingress。 将原服务Ingress关联的Service更新为新版本Service。 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: origin-ingress namespace: default annotations: kubernetes.io/elb.port: '81' kubernetes.io/elb.id: e491f4e7-2351-4984-ad0a-8569e5e964a3 kubernetes.io/elb.class: performance spec: rules: - host: nginx1.com http: paths: - path: / backend: service: name: canary-service port: number: 81 property: ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH pathType: ImplementationSpecific ingressClassName: cce 验证老版本服务是否下线完成。 使用带header和不带header的请求,多次访问。 $ curl -H "Host: nginx1.com" -H "location: hz" http://88.88.88.165:81/ $ curl -H "Host: nginx1.com" http://88.88.88.165:81/ 预期结果:输出均为new,无old返回。 确认老版本服务下线完成后,删除灰度发布Ingress。 $ kubectl delete ingress canary-weight-ingress canary-header-ingress
  • 约束与限制 该特性存在集群版本限制,仅在以下版本中生效: v1.23集群:v1.23.14-r0 及以上版本 v1.25集群:v1.25.9-r0 及以上版本 v1.27集群:v1.27.6-r0 及以上版本 v1.28集群:v1.28.4-r0 及以上版本 其他更高版本的集群 创建灰度Ingress后,不应删除原Ingress。 单个ELB下的监听器,如果关联的多个Ingress配置了多个灰度策略,头域优先级最高,cookie次之,权重优先级最低。
  • 高级Rewrite配置 对于一些复杂高级的Rewrite需求,可以通过如下注解来实现,其本质也是修改Nginx的配置文件(nginx.conf),可以实现上面提到的“nginx.ingress.kubernetes.io/rewrite-target”注解的功能,但是自定义程度更高,适合更加复杂的Rewrite需求。 nginx.ingress.kubernetes.io/server-snippet:在nginx.conf的“server”字段中添加自定义配置。 nginx.ingress.kubernetes.io/configuration-snippet:在nginx.conf的“location”字段中添加自定义配置。 snippet配置在NGINX Ingress控制器版本为2.4.6版本及以上时(对应社区版本为v1.9.3)不再默认启用,详情请参见Changelog。如果您仍需要使用snippet配置,可以通过allow-snippet-annotations启用。 通过以上两个注解可以在nginx.conf中的“server”或“location”字段中插入Rewrite指令,完成URL的重写,示例如下: annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/configuration-snippet: | rewrite ^/stylesheets/(.*)$ /something/stylesheets/$1 redirect; # 添加 /something 前缀 rewrite ^/images/(.*)$ /something/images/$1 redirect; # 添加 /something 前缀 如上两条规则在访问URL中添加了“/something”路径,即: 当用户访问rewrite.bar.com/stylesheets/new.css时,重写为rewrite.bar.com/something/stylesheets/new.css 当用户访问rewrite.bar.com/images/new.jpg时,重写为rewrite.bar.com/something/images/new.jpg
  • 简介 Nginx Ingress:基于社区的Nginx Ingress Controller进行了优化,为精选开源插件,提供丰富的Ingress配置,如果您对网关定制有强烈的需求,可以选择Nginx Ingress。 ELB Ingress:基于华为弹性负载均衡ELB(Elastic Load Balance),全托管,免运维,支持千万级并发链接,百万级新建连接。支持对接共享型负载均衡、独享性负载均衡实例。