云服务器内容精选

  • 为什么需要M CS Service是Kubernetes中的一种资源对象,定义了一组Pod的访问方式。Service为Pod提供了一个稳定的IP地址和DNS名称,使得应用程序可以通过该IP地址或DNS名称来访问这些Pod,从而自动发现和连接到可用的Pod。在多集群场景下,为了满足数据主权、状态管理、可伸缩性等要求,需要将服务拆分至多个集群进行访问,这个过程相较单集群的服务访问而言更加困难。 MCS(Multi Cluster Service)是一种多集群Service资源对象,将Service的边界从单个集群扩展至集群联邦,帮助您简洁快速地实现跨集群服务发现和访问。 具体来说,MCS的应用场景非常广泛,典型的应用场景包括: 应用容灾:使用MCS,您可以在多个区域的不同集群中访问同一个Service,因此如果某个集群中应用不可用,访问请求可切换至其他集群进行处理。 服务共享:使用MCS,可以更便捷地在不同集群中访问公共服务(监控、日志系统等),无需为所有集群部署本地公共服务副本。 应用迁移:MCS桥接了不同集群服务间的通信,您可以将同一Service部署到不同集群,通过流量迁移来更轻松地进行应用迁移。
  • MCS的使用流程 MCS的使用流程见图2,具体的使用流程如下: 检测集群间的节点网络互通与容器网络互通,若未互通则需按照要求打通。具体操作请参见设置集群网络。 在集群联邦中提前部署可用的工作负载和服务。具体操作请参见准备工作。 创建MCS对象,并在MCS中配置访问规则。具体操作请参见创建MCS对象。 跨集群访问服务,即在MCS中配置的目标集群中访问部署在下发集群中的服务。具体操作请参见跨集群访问服务。 图2 MCS使用流程
  • MCS的工作原理 MCS的功能主要通过控制面组件karmada-controller-manager实现。karmada-controller-manager实时监控Service和MCS的变化,解析MCS对象定义的规则并负责将请求转发到相应的后端Service。 图1 MCS工作原理 MCS的工作原理如图1,实现流程如下: 用户在集群联邦控制面创建工作负载,并为其配置Service对象。图中名为foo的Service部署在cluster B中。 用户在集群联邦控制面创建MCS对象,并在MCS中配置访问规则,包括下发集群与目标集群名称等。图中的下发集群为cluster B,目标集群为cluster A。 karmada-controller-manager监控到Service和MCS对象的变化,将Service下发到源集群,并将源集群中的Endpoint Slices采集并下发到目标集群。 用户在目标集群(cluster A)中访问部署在下发集群(cluster B)中的Service时,请求将会被路由到源集群的服务后端,从而实现跨集群服务发现及访问。
  • 相关操作 通过UCS控制台,您还可以执行表1中的操作。 表1 相关操作 操作 说明 YAML创建 单击右上角“YAML创建”,可使用已有的YAML创建服务。 查看详情 选择服务所在的命名空间。 (可选)根据服务名称进行搜索。 单击服务名称即可查看服务详情,包括基本信息以及各集群的部署信息。 在服务详情页的部署集群栏中单击“查看YAML”,可查看各个集群中部署的服务实例YAML,并支持下载。 编辑YAML 单击服务名称后的“编辑YAML”,可查看并编辑当前服务的YAML文件。 更新 单击服务名称后的“更新”。 根据服务参数更改信息。 单击“确认”提交已修改的信息。 删除 单击服务名称后的“删除”,并单击“是”进行确认。 批量删除 勾选需要删除的服务。 单击左上角的“批量删除”。 单击“是”进行确认。
  • 创建工作负载时设置 创建Deployment、StatefulSet、DaemonSet等不同类型的工作负载时添加Service的方法一致。 参考创建无状态负载、创建有状态负载或创建守护进程集,在服务配置步骤,单击,进行工作负载服务配置。 Service名称:服务名称,可自定义,取值范围为1-50字符。 访问类型:选择“集群内访问 ClusterIP”。 端口配置: 协议:TCP或UDP,请根据业务的协议类型选择。 服务端口:容器端口映射到集群虚拟IP上的端口,用虚拟IP访问应用时使用,端口范围为1-65535,可任意指定。 容器端口:容器镜像中应用程序实际监听的端口,需用户确定。例如:nginx程序实际监听的端口为80。 图1 工作负载服务配置 设置完成后,单击“确认”。 单击“下一步:调度与差异化”,进行集群调度与差异化配置。设置完成后,单击“创建工作负载”完成创建。 获取访问地址。 单击左侧导航栏“服务与路由”,选择“服务”页签。 单击所添加的Service名称进入“服务详情”界面,获取部署集群的访问地址。
  • 创建工作负载后设置 登录UCS控制台,在左侧导航栏中选择“容器舰队”。 在“容器舰队”页签下找到已开通集群联邦的舰队,单击名称进入详情页。 在左侧导航栏中选择“服务与路由”,选择“服务”页签。 选择服务所在命名空间,并单击右上角“创建服务”。如需新建命名空间,请参见创建命名空间。 设置访问参数。 图2 创建服务 Service名称:自定义服务名称,可与工作负载名称保持一致。 服务类型:选择“集群内访问 ClusterIP”。 端口配置: 协议:TCP或UDP,请根据业务的协议类型选择。 服务端口:容器端口映射到集群虚拟IP上的端口,用虚拟IP访问应用时使用,端口范围为1-65535,可任意指定。 容器端口:容器镜像中应用程序实际监听的端口,需用户确定。例如:nginx程序实际监听的端口为80。 命名空间:服务所在命名空间。 选择器:服务通过选择器与负载(标签)关联。单击“引用负载标签”,可选择已有的工作负载。 负载类型:选择需要关联的负载类型。 工作负载:选择一个已有的工作负载。如工作负载列表未显示,请单击刷新。 标签:选择工作负载后自动获取对应的标签,不可修改。 图3 引用负载标签 单击“确认”。创建成功后可在“服务”页签的列表中查看。
  • 创建ClusterIP类型Service 登录CCE控制台,单击集群名称进入集群。 在左侧导航栏中选择“服务”,在右上角单击“创建服务”。 设置集群内访问参数。 Service名称:自定义服务名称,可与工作负载名称保持一致。 访问类型:选择“集群内访问”。 命名空间:工作负载所在命名空间。 选择器:添加标签,Service根据标签选择Pod,填写后单击“确认添加”。也可以引用已有工作负载的标签,单击“引用负载标签”,在弹出的窗口中选择负载,然后单击“确定”。 端口配置: 协议:请根据业务的协议类型选择。 服务端口:Service使用的端口,端口范围为1-65535。 容器端口:工作负载程序实际监听的端口,需用户确定。例如nginx默认使用80端口。 单击“确定”,创建Service。
  • 请求示例 创建ClusterIP类型的Service,公开的端口为80,端口的IP协议为"TCP"。 { "apiVersion" : "v1", "kind" : "Service", "metadata" : { "labels" : { "app" : "redis" }, "name" : "redis" }, "spec" : { "ports" : [ { "name" : "service0", "port" : 8080, "protocol" : "TCP", "targetPort" : 80 } ], "selector" : { "app" : "redis" }, "type" : "ClusterIP" } } 创建LoadBalancer类型的Service,指定elb实例ID、项目ID和账号ID。 LoadBalancer类型Service需要在metadata.annotations自定义中添加elb实例ID(kubernetes.io/elb.id)、项目ID(tenant.kubernetes.io/project-id)和账号ID(tenant.kubernetes.io/domain-id) { "apiVersion" : "v1", "kind" : "Service", "metadata" : { "annotations" : { "kubernetes.io/elb.id" : "77e6246c-a091-xxxx-xxxx-789baa571280", "tenant.kubernetes.io/domain-id" : "65382xxxxxxxxxxxxxxxxxe684b", "tenant.kubernetes.io/project-id" : "a9cab8xxxxxxxxxxxxxxxx41c0aeb" }, "name" : "nginx" }, "spec" : { "ports" : [ { "name" : "service0", "port" : 8080, "protocol" : "TCP", "targetPort" : 80 } ], "selector" : { "app" : "nginx" }, "type" : "LoadBalancer" } }
  • 响应示例 状态码: 200 OK { "apiVersion" : "v1", "kind" : "Service", "metadata" : { "creationTimestamp" : "2018-09-04T00:45:36Z", "labels" : { "app" : "redis" }, "name" : "redis", "namespace" : "namespace-test", "resourceVersion" : "5146412", "selfLink" : "/api/v1/namespaces/namespace-test/services/redis", "uid" : "d6a1ce79-afdb-11e8-b6ef-f898ef6c78b4" }, "spec" : { "clusterIP" : "10.247.212.210", "ports" : [ { "name" : "service0", "port" : 8080, "protocol" : "TCP", "targetPort" : 80 } ], "selector" : { "app" : "redis" }, "sessionAffinity" : "None", "type" : "ClusterIP" }, "status" : { "loadBalancer" : { } } }
  • URI POST /api/v1/namespaces/{namespace}/services 表1 路径参数 参数 是否必选 参数类型 描述 namespace 是 String object name and auth scope, such as for teams and projects 表2 Query参数 参数 是否必选 参数类型 描述 dryRun 否 String When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed fieldManager 否 String fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. pretty 否 String If 'true', then the output is pretty printed.
  • 状态码 状态码 描述 200 OK 201 Created 202 Accepted 400 BadRequest 401 Unauthorized 403 Forbidden 404 NotFound 405 MethodNotAllowed 406 NotAcceptable 409 AlreadyExists 415 UnsupportedMediaType 422 Invalid 429 TooManyRequests 500 InternalError 503 ServiceUnavailable 504 ServerTimeout
  • 创建DNAT网关类型Service 登录CCE控制台,单击集群名称进入集群。 在左侧导航栏中选择“服务”,在右上角单击“创建服务”。 设置集群内访问参数。 Service名称:自定义服务名称,可与工作负载名称保持一致。 访问类型:选择“DNAT网关”。 命名空间:工作负载所在命名空间。 服务亲和:详情请参见服务亲和(externalTrafficPolicy)。 集群级别:集群下所有节点的IP+访问端口均可以访问到此服务关联的负载,服务访问会因路由跳转导致一定性能损失,且无法获取到客户端源IP。 节点级别:只有通过负载所在节点的IP+访问端口才可以访问此服务关联的负载,服务访问没有因路由跳转导致的性能损失,且可以获取到客户端源IP。 选择器:添加标签,Service根据标签选择Pod,填写后单击“添加”。也可以引用已有工作负载的标签,单击“引用负载标签”,在弹出的窗口中选择负载,然后单击“确定”。 IPv6:默认不开启,开启后服务的集群内IP地址(ClusterIP)变为IPv6地址,具体请参见如何通过CCE搭建IPv4/IPv6双栈集群?。该功能仅在1.15及以上版本的集群创建时开启了IPv6功能才会显示。 DNAT网关:选择创建NAT网关和弹性公网IP中创建的DNAT网关实例和弹性公网IP。 端口配置: 协议:请根据业务的协议类型选择。 容器端口:工作负载程序实际监听的端口,需用户确定。nginx程序实际监听的端口为80。 服务端口:容器端口映射到集群虚拟IP上的端口,用虚拟IP访问工作负载时使用,端口范围为1-65535,可任意指定。 单击“确定”,创建Service。
  • 约束与限制 关于NAT网关的使用,您需要注意以下几点: DNAT规则不支持企业项目授权。 集群内容器不支持访问externalTrafficPolicy为Local模式的DNAT Service。 同一个NAT网关下的多条规则可以复用同一个弹性公网IP,不同网关下的规则必须使用不同的弹性公网IP。 每个VPC支持的NAT网关数为1。 用户不能在VPC下手动添加默认路由。 VPC内的每个子网只能添加一条SNAT规则。 SNAT规则和DNAT规则一般面向不同的业务,如果使用相同的EIP,会面临业务相互抢占问题,请尽量避免。SNAT规则不能和全端口的DNAT规则共用EIP。 DNAT规则不支持将弹性公网IP绑定到虚拟IP。 当云主机同时配置弹性公网IP服务和NAT网关服务时,数据均通过弹性公网IP转发。 SNAT规则中添加的自定义网段,对于虚拟私有云的配置,必须是虚拟私有云子网网段的子集,不能相等。 SNAT规则中添加的自定义网段,对于云专线的配置,必须是云专线侧网段,且不能与虚拟私有云侧的网段冲突。 当执行云服务器底层资源操作(如变更规格)时,会导致已配置的NAT规则失效,需要删除后重新配置。 创建service后,如果服务亲和从集群级别切换为节点级别,连接跟踪表将不会被清理,建议用户创建service后不要修改服务亲和属性,如需修改请重新创建service。 当集群的节点子网关联了自定义路由表时,使用DNAT类型service同时需要将NAT的路由加入到自定义路由表中。
  • 直接访问Pod的问题 Pod创建完成后,如何访问Pod呢?直接访问Pod会有如下几个问题: Pod会随时被Deployment这样的控制器删除重建,那访问Pod的结果就会变得不可预知。 Pod的IP地址是在Pod启动后才被分配,在启动前并不知道Pod的IP地址。 应用往往都是由多个运行相同镜像的一组Pod组成,逐个访问Pod也变得不现实。 举个例子,假设有这样一个应用程序,使用Deployment创建了前台和后台,前台会调用后台做一些计算处理,如图1所示。后台运行了3个Pod,这些Pod是相互独立且可被替换的,当Pod出现状况被重建时,新建的Pod的IP地址是新IP,前台的Pod无法直接感知。 图1 Pod间访问
  • 服务亲和(externalTrafficPolicy) NodePort类型及LoadBalancer类型的Service接收请求时,会先访问到节点,然后转到Service,再由Service选择一个Pod转发到该Pod,但Service选择的Pod不一定在接收请求的节点上。默认情况下,从任意节点IP+服务端口都能访问到后端工作负载,当Pod不在接收请求的节点上时,请求会再跳转到Pod所在的节点,带来一定性能损失。 Service有一个配置参数(externalTrafficPolicy),用于设置Service是否希望将外部流量路由到节点本地或集群范围的端点,示例如下: apiVersion: v1 kind: Service metadata: name: nginx-nodeport spec: externalTrafficPolicy: Local ports: - name: service nodePort: 30000 port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: NodePort 当externalTrafficPolicy取值为Local时,通过节点IP:服务端口的请求只会转发给本节点上的Pod,如果节点没有Pod的话请求会挂起。 当externalTrafficPolicy取值为Cluster时,请求会在集群内转发,从任意节点IP+服务端口都能访问到后端工作负载。 如不设置externalTrafficPolicy,默认取值为Cluster。 在CCE 控制台创建NodePort类型Service时,也可以通过“服务亲和”选项配置该参数。 总结服务亲和(externalTrafficPolicy)的两个选项对比如下: 表1 服务亲和特性对比 对比维度 服务亲和(externalTrafficPolicy) 集群级别(Cluster) 节点级别(Local) 使用场景 适用于对性能要求不高,无需保留客户端源IP场景,此方式能为集群各节点带来更均衡的负载。 适用于客户端源IP需要保留且对性能要求较高的业务,但是流量仅会转发至容器所在的节点,不会做源地址转换。 访问方式 集群下所有节点的IP+访问端口均可以访问到此服务关联的负载。 只有通过负载所在节点的IP+访问端口才可以访问此服务关联的负载。 获取客户端源IP 无法获取到客户端源IP。 可以获取到客户端源IP。 访问性能 服务访问会因路由跳转导致一定性能损失,可能导致第二跳到另一个节点。 服务访问没有因路由跳转导致的性能损失。 负载均衡性 流量传播具有良好的整体负载均衡性。 存在潜在的不均衡流量传播风险。 其他特殊情况 - 在不同容器网络模型和服务转发模式下,可能出现集群内无法访问Service的情况,详情请参见集群内无法访问Service的说明。