云服务器内容精选

  • 创建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的路由加入到自定义路由表中。
  • 使用Service解决Pod的访问问题 Kubernetes中的Service对象就是用来解决上述Pod访问问题的。Service有一个固定IP地址(在创建CCE集群时有一个服务网段的设置,这个网段专门用于给Service分配IP地址),Service将访问它的流量转发给Pod,具体转发给哪些Pod通过Label来选择,而且Service可以给这些Pod做负载均衡。 那么对于上面的例子,为后台添加一个Service,通过Service来访问Pod,这样前台Pod就无需感知后台Pod的变化,如图2所示。 图2 通过Service访问Pod
  • 直接访问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的说明。
  • 集群内无法访问Service的说明 当Service设置了服务亲和为节点级别,即externalTrafficPolicy取值为Local时,在使用中可能会碰到从集群内部(节点上或容器中)访问不通的情况,回显类似如下内容: upstream connect error or disconnect/reset before headers. reset reason: connection failure 或: curl: (7) Failed to connect to 192.168.10.36 port 900: Connection refused 在集群中访问ELB地址时出现无法访问的场景较为常见,这是由于Kubernetes在创建Service时,kube-proxy会把ELB的访问地址作为外部IP(即External-IP,如下方回显所示)添加到iptables或IPVS中。如果客户端从集群内部发起访问ELB地址的请求,该地址会被认为是服务的外部IP,被kube-proxy直接转发,而不再经过集群外部的ELB。 # kubectl get svc nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx LoadBalancer 10.247.76.156 123.**.**.**,192.168.0.133 80:32146/TCP 37s 当externalTrafficPolicy的取值为Local时,在不同容器网络模型和服务转发模式下访问不通的场景如下: 多实例的工作负载需要保证所有实例均可正常访问,否则可能出现概率性访问不通的情况。 CCE Turbo集群(云原生2.0网络模型)中,仅当Service的后端对接使用主机网络(HostNetwork)的Pod时,亲和级别支持配置为节点级别。 表格中仅列举了可能存在访问不通的场景,其他不在表格中的场景即表示可以正常访问。 服务端发布服务类型 访问类型 客户端请求发起位置 容器隧道集群(IPVS) VPC集群(IPVS) 容器隧道集群(IPTABLES) VPC集群(IPTABLES) 节点访问类型Service 公网/私网 与服务Pod同节点 访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 与服务Pod不同节点 访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 正常访问 正常访问 与服务Pod同节点的其他容器 访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 无法访问 访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 无法访问 与服务Pod不同节点的其他容器 访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 独享型负载均衡类型Service 私网 与服务Pod同节点 无法访问 无法访问 无法访问 无法访问 与服务Pod同节点的其他容器 无法访问 无法访问 无法访问 无法访问 DNAT网关类型Service 公网 与服务Pod同节点 无法访问 无法访问 无法访问 无法访问 与服务Pod不同节点 无法访问 无法访问 无法访问 无法访问 与服务Pod同节点的其他容器 无法访问 无法访问 无法访问 无法访问 与服务Pod不同节点的其他容器 无法访问 无法访问 无法访问 无法访问 nginx-ingress插件对接独享型ELB(Local) 私网 与cceaddon-nginx-ingress-controller Pod同节点 无法访问 无法访问 无法访问 无法访问 与cceaddon-nginx-ingress-controller Pod同节点的其他容器 无法访问 无法访问 无法访问 无法访问 解决这个问题通常有如下办法: (推荐)在集群内部访问使用Service的ClusterIP或服务域名访问。 将Service的externalTrafficPolicy设置为Cluster,即集群级别服务亲和。不过需要注意这会影响源地址保持。 apiVersion: v1 kind: Service metadata: annotations: kubernetes.io/elb.class: union kubernetes.io/elb.autocreate: '{"type":"public","bandwidth_name":"cce-bandwidth","bandwidth_chargemode":"bandwidth","bandwidth_size":5,"bandwidth_sharetype":"PER","eip_type":"5_bgp","name":"james"}' labels: app: nginx name: nginx spec: externalTrafficPolicy: Cluster ports: - name: service0 port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: LoadBalancer 使用Service的pass-through特性,使用ELB地址访问时绕过kube-proxy,先访问ELB,经过ELB再访问到负载。具体请参见LoadBalancer类型Service使用pass-through能力。 独享型负载均衡配置pass-through后,CCE Standard集群在工作负载同节点和同节点容器内无法通过Service访问。 1.15及以下老版本集群暂不支持该能力。 IPVS网络模式下,对接同一个ELB的Service需保持pass-through设置情况一致。 使用节点级别(Local)的服务亲和的场景下,会自动设置kubernetes.io/elb.pass-through为onlyLocal,开启pass-through能力。 apiVersion: v1 kind: Service metadata: annotations: kubernetes.io/elb.pass-through: "true" kubernetes.io/elb.class: union kubernetes.io/elb.autocreate: '{"type":"public","bandwidth_name":"cce-bandwidth","bandwidth_chargemode":"bandwidth","bandwidth_size":5,"bandwidth_sharetype":"PER","eip_type":"5_bgp","name":"james"}' labels: app: nginx name: nginx spec: externalTrafficPolicy: Local ports: - name: service0 port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: LoadBalancer
  • 相关操作 通过UCS控制台,您还可以执行表1中的操作。 表1 相关操作 操作 说明 YAML创建 单击右上角“YAML创建”,可使用已有的YAML创建服务。 查看详情 选择服务所在的命名空间。 (可选)根据服务名称进行搜索。 单击服务名称即可查看服务详情,包括基本信息以及各集群的部署信息。 在服务详情页的部署集群栏中单击“查看YAML”,可查看各个集群中部署的服务实例YAML,并支持下载。 编辑YAML 单击服务名称后的“编辑YAML”,可查看并编辑当前服务的YAML文件。 更新 单击服务名称后的“更新”。 根据服务参数更改信息。 单击“确认”提交已修改的信息。 删除 单击服务名称后的“删除”,并单击“是”进行确认。 批量删除 勾选需要删除的服务。 单击左上角的“批量删除”。 单击“是”进行确认。
  • 创建工作负载时设置 创建Deployment、StatefulSet、DaemonSet等不同类型的工作负载时添加Service的方法一致。 参考创建无状态负载、创建有状态负载或创建守护进程集,在服务配置步骤,单击,进行工作负载服务配置。 Service名称:新增服务名称,用户可自定义。 访问类型:选择“集群内访问 ClusterIP”。 端口配置: 协议:TCP或UDP,请根据业务的协议类型选择。 服务端口:容器端口映射到集群虚拟IP上的端口,用虚拟IP访问应用时使用,端口范围为1-65535,可任意指定。 容器端口:容器镜像中应用程序实际监听的端口,需用户确定。例如:nginx程序实际监听的端口为80。 图1 工作负载服务配置 设置完成后,单击“确认”。 单击“下一步:调度与差异化”,进行集群调度与差异化配置。设置完成后,单击“创建工作负载”完成创建。 获取访问地址。 单击左侧导航栏“服务与路由”,选择“服务”页签。 单击所添加的Service名称进入“服务详情”界面,获取部署集群的访问地址。
  • 创建工作负载后设置 登录UCS控制台,在左侧导航栏中选择“容器舰队”。 在“容器舰队”页签下找到已开通集群联邦的舰队,单击名称进入详情页。 在左侧导航栏中选择“服务与路由”,选择“服务”页签。 选择服务所在命名空间,并单击右上角“创建服务”。如需新建命名空间,请参见创建命名空间。 设置访问参数。 图2 创建服务 Service名称:自定义服务名称,可与工作负载名称保持一致。 服务类型:选择“集群内访问 ClusterIP”。 端口配置: 协议:TCP或UDP,请根据业务的协议类型选择。 服务端口:容器端口映射到集群虚拟IP上的端口,用虚拟IP访问应用时使用,端口范围为1-65535,可任意指定。 容器端口:容器镜像中应用程序实际监听的端口,需用户确定。例如:nginx程序实际监听的端口为80。 命名空间:服务所在命名空间。 选择器:服务通过选择器与负载(标签)关联。单击“引用负载标签”,可选择已有的工作负载。 负载类型:选择需要关联的负载类型。 工作负载:选择一个已有的工作负载。如工作负载列表未显示,请单击刷新。 标签:选择工作负载后自动获取对应的标签,不可修改。 图3 引用负载标签 单击“确认”。创建成功后可在“服务”页签的列表中查看。