概念

Kubernetes v1.16 文档不再得到积极维护。您当前正在查看的版本是静态快照。有关最新文档,请参见 最新版本。

编辑这个页面

服务

公开在一组应用程序上运行的应用程序的抽象方法 豆荚 最小和最简单的Kubernetes对象。 Pod代表集群上一组正在运行的容器。 作为网络服务。

使用Kubernetes,您不需要’无需修改您的应用程序即可使用不熟悉的服务发现机制。 Kubernetes为Pods提供自己的IP地址和一组Pod的单个DNS名称, 并可以在它们之间进行负载平衡。

动机

Kubernetes 豆荚 最小和最简单的Kubernetes对象。 Pod代表集群上一组正在运行的容器。 是凡人。 他们出生了,死了也没有复活。 If you use a 部署方式管理复制的应用程序的API对象。 运行您的应用, 它可以动态创建和销毁Pod。

每个Pod都有自己的IP地址,但是在Deployment中,这组Pod 在一瞬间运行可能与 稍后运行该应用程序的Pod集。

这导致了一个问题:如果某些Pod集(称为“后端”)提供了 群集中其他Pod的功能(称为“前端”), 前端如何查找并跟踪要连接的IP地址 ,以便前端可以使用工作量的后端部分?

输入 服务s.

服务资源

在Kubernetes中,服务是一种抽象,定义了Pod的逻辑集合 and a policy by 哪一个 to access them (sometimes this pattern is called 微型服务)。服务确定的Pod集合通常是确定的 by a 选择器允许用户基于标签过滤资源列表。 (看到 下面 为何需要服务 没有 选择器)。

例如,考虑使用以下命令运行的无状态图像处理后端 3个副本。这些复制品是可替代的—前端不在乎哪个后端 他们使用。虽然组成后端集的实际Pod可能会更改,但 前端客户不需要知道这一点,也不需要保持 跟踪自己的后端集。

服务抽象使这种解耦成为可能。

云原生服务发现

如果你’能够使用Kubernetes API在应用程序中发现服务, you 能够 query the API服务器提供Kubernetes API的控制平面组件。 对于端点,只要服务中的Pod集合发生更改,该端点就会更新。

对于非本机应用程序,Kubernetes提供了放置网络端口或负载的方法 您的应用程序和后端Pod之间的平衡器。

定义服务

Kubernetes中的服务是一个REST对象,类似于Pod。像所有的 REST objects, you 能够 POST a 服务 definition to the API服务器 to create a new instance.

例如,假设您有一组Pod,每个Pod都侦听TCP端口9376 and carry a label app=MyApp:

apiVersion: v1
kind: 服务
metadata:
  name: my-service
spec:
  选择器:
    app: MyApp
  ports:
    - protocol:   TCP协议 协议 
      port: 80
      targetPort: 9376

该规范创建一个名为“ my-service”的新服务对象,该对象 targets TCP协议 port 9376 on 任何 Pod with the app=MyApp label.

Kubernetes会为此服务分配一个IP地址(有时称为“cluster IP”), which is used by 服务 proxies (see 虚拟IP和服务代理 下面)。

服务选择器的控制器连续扫描Pod 匹配其选择器,然后将任何更新发布到Endpoint对象 也称为“我的服务”。

注意: 服务可以映射 任何 incoming port to a targetPort. By default and for convenience, the targetPort is 组 to the same value as the port 领域。

Pod中的端口定义有名称,您可以在 targetPort 服务的属性。即使有混合也可以 同一网络中使用单个配置名称的服务中的Pod数量 协议可通过不同的端口号获得。 这为部署和发展服务提供了很大的灵活性。 例如,您可以更改Pod在下一个中公开的端口号。 版本的后端软件,而不会破坏客户端。

服务的默认协议是TCP;默认协议是TCP。您也可以使用其他任何东西 支持的协议.

由于许多服务需要公开多个端口,因此Kubernetes支持多个 服务对象上的端口定义。 Each port definition 能够 have the same protocol, 要么 a different one.

没有选择器的服务

服务最常见的是抽象访问Kubernetes Pod,但它们也可以 抽象其他种类的后端。 For example:

在任何这些情况下,您都可以定义服务 没有 Pod选择器。 For example:

apiVersion: v1
kind: 服务
metadata:
  name: my-service
spec:
  ports:
    - protocol:   TCP协议 协议 
      port: 80
      targetPort: 9376

因为此服务没有选择器,所以相应的Endpoint对象是 自动创建。您可以手动将服务映射到网络地址和端口 where it’通过手动添加Endpoint对象来运行:

apiVersion: v1
kind: Endpoints
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 192.0.2.42
    ports:
      - port: 9376
注意:

端点IP 一定不 是:回送(对于IPv4为127.0.0.0/8,对于IPv6为:: 1/128),或 本地链接(对于IPv4为169.254.0.0/16和224.0.0.0/24,对于IPv6为fe80 :: / 64)。

Endpoint IP地址 能够 not be the 集群IPs of other Kubernetes 服务s, because 库贝代理库贝代理是在群集中每个节点上运行的网络代理。 没有’支持虚拟IP as a destination.

在没有选择器的情况下访问服务与在服务中具有选择器的情况相同。 在上面的示例中,流量被路由到在中定义的单个端点 the YAML: 192.0.2.42:9376 (TCP).

外部名称服务是服务的特殊情况,没有 选择器并使用DNS名称代替。有关更多信息,请参见 外部名称 本文档后面的部分。

端点切片

功能状态: Kubernetes v1.16 α
该功能当前位于 α 状态,含义:

  • 版本名称包含Alpha(例如v1alpha1)。
  • 可能是越野车。启用该功能可能会暴露错误。默认禁用。
  • 随时可能删除对功能的支持,恕不另行通知。
  • 在以后的软件版本中,API可能会以不兼容的方式更改,恕不另行通知。
  • 由于存在更高的错误风险和缺乏长期支持,建议仅用于短期测试集群。

端点切片是一种API资源,可以提供更具扩展性的替代方案 到端点。尽管在概念上与端点非常相似,但端点切片 允许跨多种资源分布网络端点。默认, 端点切片被视为“full”一旦达到100个端点, 点将创建额外的Endpoint Slice,以存储其他任何内容 endpoints.

端点切片 provide additional attributes and functionality 哪一个 is 详细描述 端点切片.

虚拟IP和服务代理

Every node in a Kubernetes cluster runs a 库贝代理. 库贝代理 is responsible for implementing a form of 虚拟 IP for 服务s of type other than 外部名称.

为什么不使用轮询DNS?

时不时出现一个问题,就是为什么Kubernetes依赖 代理以将入站流量转发到后端。那其他呢 方法?例如,是否可以配置DNS记录, 具有多个A值(对于IPv6,则为AAAA),并依赖循环名称 resolution?

使用服务代理的原因有几个:

  • 域名解析 的实施历史悠久,不遵守记录TTL, 并在名称查找结果到期后缓存它们。
  • 某些应用程序仅执行一次DNS查找,并无限期地缓存结果。
  • 即使应用程序和库进行了适当的重新解析,TTL也会很低或为零 DNS记录上的内容可能会给DNS施加高负载,然后变成 difficult to manage.

用户空间代理模式

在这种模式下,kube-proxy监视Kubernetes主服务器的添加和 删除服务和端点对象。为每个服务打开一个 本地节点上的端口(随机选择)。与此相关的任何连接“proxy port” 被代理到其中一项服务’的后端Pod(如通过 Endpoints). 库贝代理 takes the SessionAffinity 组 ting of 服务 into account when deciding 哪一个 backend Pod to use.

最后,用户空间代理安装iptables规则,以捕获流量 the 服务’s clusterIP (which is 虚拟) and port. The rules redirect that traffic to the 代理端口 哪一个 proxies the backend Pod.

默认情况下,用户空间模式下的kube-proxy通过循环算法选择后端。

用户空间代理的服务概述图

iptables 代理模式

在这种模式下,kube-proxy监视Kubernetes控制平面的添加和 删除服务和端点对象。对于每个服务,它都会安装 iptables rules, 哪一个 capture traffic to 服务’s clusterIP and port, and redirect that traffic to one of 服务’s 后端集。对于每个Endpoint对象,它会安装iptables规则 选择一个后端Pod。

默认情况下,iptables模式下的kube-proxy会随机选择一个后端。

使用iptables处理流量具有较低的系统开销,因为流量 由Linux netfilter处理,而无需在用户空间和 内核空间。这种方法也可能更可靠。

如果kube-proxy在iptables模式下运行,并且第一个Pod’s selected 不响应,连接失败。这与用户空间不同 模式:在这种情况下,kube-proxy将检测到与第一个连接 Pod失败,将自动使用其他后端Pod重试。

您可以使用Pod 准备就绪探针 验证后端Pod是否正常工作,以便在iptables模式下使用kube-proxy 只看到测试出来的后端是健康的。这样做意味着您避免 通过kube-proxy发送到Pod的流量’已知失败。

iptables代理的服务概述图

IPVS 代理模式

功能状态: Kubernetes v1.11 稳定
此功能是 稳定 ,意思是:

  • 版本名称为vX,其中X为整数。
  • 稳定的功能版本将在许多后续版本的发行软件中显示。

In ipvs mode, 库贝代理 watches Kubernetes 服务s and Endpoints, calls netlink interface to create IPVS rules accordingly and synchronizes IPVS定期与Kubernetes服务和端点进行规则。 该控制回路可确保IPVS状态与所需的状态相匹配 state. 访问服务时,IPVS将流量定向到后端Pod之一。

IPVS 代理模式基于类似于以下的netfilter挂钩函数 iptables模式,但是使用哈希表作为基础数据结构并且可以工作 in the kernel space. 这意味着IPVS模式下的kube-proxy重定向流量的延迟比 iptables模式下的kube-proxy,在同步时具有更好的性能 代理规则。与其他代理模式相比,IPVS模式还支持 网络流量的吞吐量更高。

IPVS 提供了更多选项来平衡后端Pod的流量。 these are:

  • rr:轮循
  • lc:连接最少(打开的连接最少)
  • dh:目标哈希
  • sh:源哈希
  • sed:最短的预期延迟
  • nq:永不排队
注意:

要在IPVS模式下运行kube-proxy,必须使IPVS Linux在 启动kube-proxy之前的节点。

当kube-proxy以IPVS代理模式启动时,它会验证IPVS是否 内核模块可用。如果未检测到IPVS内核模块,则使用kube-proxy 退回到以iptables代理模式运行。

 IPVS 代理的服务概述图

在这些代理模型中,绑定到服务IP:Port的流量为 代理到适当的后端,而客户不知道任何事情 关于Kubernetes或服务或Pod。

如果你 want to make sure that connections from a particular 客户 每次都传递到同一个Pod,则可以选择基于会话相似性 on 客户’s IP地址 by 组 ting service.spec.sessionAffinity to “ClientIP” (the default is “None”). 您还可以通过设置 service.spec.sessionAffinityConfig.clientIP.timeoutSeconds 适当地。 (the default value is 10800, 哪一个 works out to be 3 hours).

多端口服务

对于某些服务,您需要公开多个端口。 Kubernetes允许您在Service对象上配置多个端口定义。 为服务使用多个端口时,必须提供所有端口名称 这样它们才是明确的。 For example:

apiVersion: v1
kind: 服务
metadata:
  name: my-service
spec:
  选择器:
    app: MyApp
  ports:
    - name: http
      protocol:   TCP协议 协议 
      port: 80
      targetPort: 9376
    - name: https
      protocol:   TCP协议 协议 
      port: 443
      targetPort: 9377
注意:

与Kubernetes一样 名字 客户端提供的字符串,它引用资源URL中的对象,例如/ api / v1 / pods / some-name。 通常,端口名称 must only contain lowercase α numeric characters and -. Port 名字 must 还以字母数字字符开头和结尾。

For example, the 名字 123-abc and web are valid, but 123_abc and -web are 不 .

选择您自己的IP地址

You 能够 specify your own 集群IP address as part of a 服务 creation request. To do this, 组 the .spec.clusterIP 领域。 For example, if you 已经具有要重用的现有DNS条目,或旧系统 为特定IP地址配置的文件,并且难以重新配置。

您选择的IP地址必须是以下地址中的有效IPv4或IPv6地址: service-cluster-ip-range 为API服务器配置的CIDR范围。 如果您尝试使用无效的clusterIP地址值创建服务,则该API 服务器将返回422 HTTP 状态代码以表明存在’s a problem.

发现服务

Kubernetes支持两种找到服务的主要模式-环境 variables and 域名解析 .

环境变量

当Pod在节点上运行时,kubelet将添加一组环境变量 每个活动的服务。它同时支持 Docker链接 compatible 变量(请参见 makeLinkVariables) and simpler {SVCNAME}_SERVICE_HOST and {SVCNAME}_SERVICE_PORT variables, 服务名称为大写字母,并且破折号转换为下划线。

For example, 服务 "redis-master" 哪一个 exposes TCP协议 port 6379 and has been allocated 集群IP address 10.0.0.11, produces the following environment variables:

REDIS_MASTER_SERVICE_HOST=10.0.0.11
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
REDIS_MASTER_PORT_6379_TCP_PORT=6379
REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11
注意:

当您拥有需要访问服务的Pod且正在使用时 将端口和群集IP发布到客户端的环境变量方法 Pods, you must create 服务 之前 the 客户 豆荚 come into existence. 否则,那些客户豆荚赢了’填充其环境变量。

如果你 only use 域名解析 to discover the 集群IP for a 服务, you don’t need to 担心此订购问题。

域名解析

您可以(几乎总是应该)为您的Kubernetes设置DNS服务 cluster using an 添加在 .

诸如CoreDNS之类的支持群集的DNS服务器会监视Kubernetes API中的新内容 服务并为每个服务创建一组DNS记录。如果已启用DNS 整个集群中,那么所有Pod都应该能够自动解析 服务的DNS名称。

For example, if you have a 服务 called "my-service" in a Kubernetes Namespace "my-ns", the control plane and the 域名解析 服务 acting together create a 域名解析 record for "my-service.my-ns". 豆荚 in the "my-ns" 命名空间 应该能够通过简单地进行名称查找来找到它 my-service ("my-service.my-ns" would also work).

豆荚 in other 命名空间 must qualify the name as my-service.my-ns. These 名字 will resolve to the 集群IP assigned for 服务.

Kubernetes还支持命名端口的DNS SRV(服务)记录。如果 "my-service.my-ns" 服务 has a port named "http" with protocol 组 to TCP协议 协议 , you 能够 do a 域名解析 SRV query for _http._tcp.my-service.my-ns to discover the port number for "http", as well as the IP 地址。

The Kubernetes 域名解析 server is the only way to access 外部名称 服务s. You 能够 find more information about 外部名称 resolution in 域名解析 窗格和服务.

无头服务

有时候你不’需要负载平衡和单个服务IP。在 在这种情况下,您可以通过显式创建所谓的“无头”服务 specifying "None" for the 集群IP (.spec.clusterIP).

您可以使用无头服务与其他服务发现机制进行交互, 不受限于Kubernetes’ implementation.

For headless 服务s, a 集群IP is 不 allocated, 库贝代理 does 不 handle 这些服务,并且平台没有完成负载平衡或代理 为他们。如何自动配置DNS取决于服务是否具有 selectors defined:

带选择器

对于定义选择器的无头服务,端点控制器将创建 Endpoints 记录在API中,并修改DNS配置以返回 records (addresses) that point directly to the 豆荚 backing the 服务.

没有选择器

对于没有定义选择器的无头服务,端点控制器会执行 not create Endpoints records. However, the 域名解析 system looks for and configures either:

  • 的CNAME记录 外部名称型服务。
  • A records for 任何 Endpoints that share a name with 服务, for all other types.

发布服务(服务类型)

对于应用程序的某些部分(例如,前端),您可能需要公开 服务到一个外部IP地址,’不在群集中。

Kubernetes 服务Types allow you to specify what kind of 服务 you want. The default is ClusterIP.

Type 值及其行为是:

  • ClusterIP:在群集内部IP上公开服务。选择此值 使服务只能从群集内访问。这是 default 服务Type.
  • 没有 dePort:在每个节点上公开服务’静态端口的IP (the 没有 dePort). A ClusterIP 服务, to 哪一个 the 没有 dePort 服务 路线,是自动创建的。您’ll be able to contact the 没有 dePort 服务, 从集群外部 by requesting <NodeIP>:<NodePort>.
  • LoadBalancer: Exposes 服务 externally using a cloud 提供者’s load balancer. 没有 dePort and ClusterIP 服务s, to 哪一个 the external 负载均衡器路由,是自动创建的。
  • 外部名称: Maps 服务 to the contents of the externalName field (e.g. foo.bar.example.com ), by returning a CNAME record

    其价值。没有设置任何代理。

    注意: You need CoreDNS version 1.7 要么 higher to use the 外部名称 type.

您也可以使用 入口 公开您的服务。入口不是服务类型,但它充当集群的入口点。它可以将路由规则整合为一个资源,因为它可以在同一IP地址下公开多个服务。

类型NodePort

如果你 组 the type field to 没有 dePort, the Kubernetes control plane allocates a port from a range specified by --service-node-port-range flag (default: 30000-32767). 每个节点将那个端口(每个节点上的相同端口号)代理到您的服务中。 Your 服务 reports the allocated port in its .spec.ports[*].nodePort 领域。

如果你 want to specify particular IP(s) to proxy the port, you 能够 组 the --nodeport-addresses flag in 库贝代理 to particular IP block(s); this is supported since Kubernetes v1.10. 该标志采用逗号分隔的IP块列表(例如10.0.0.0/8、192.0.2.0/25)来指定kube-proxy应该认为是此节点本地的IP地址范围。

For example, if you start 库贝代理 with the --nodeport-addresses=127.0.0.0/8 flag, 库贝代理 only selects the loopback interface for 没有 dePort 服务s. The default for --nodeport-addresses is an empty list. This means that 库贝代理 should consider all available network interfaces for 没有 dePort. (That’还与Kubernetes的早期版本兼容)。

如果你 want a specific port number, you 能够 specify a value in the nodePort 领域。控制平面将为您分配该端口或报告 API交易失败。 这意味着您需要自己注意可能发生的端口冲突。 您还必须使用有效的端口号,’在配置的范围内 for 没有 dePort use.

使用NodePort,您可以自由设置自己的负载平衡解决方案, to configure environments that are 不 充分y supported by Kubernetes, 要么 even 只暴露一个或多个节点’ IPs directly.

请注意,此服务显示为 <NodeIP>:spec.ports[*].nodePort and .spec.clusterIP:spec.ports[*].port. (If the --nodeport-addresses flag in 库贝代理 is 组 , 将被过滤的NodeIP。

类型LoadBalancer

上 cloud 提供者s 哪一个 support external load balancers, 组 ting the type field to LoadBalancer provisions a load balancer for your 服务. 负载均衡器的实际创建是异步发生的,并且 服务中发布了有关预配置平衡器的信息’s .status.loadBalancer 领域。 For example:

apiVersion: v1
kind: 服务
metadata:
  name: my-service
spec:
  选择器:
    app: MyApp
  ports:
    - protocol:   TCP协议 协议 
      port: 80
      targetPort: 9376
  clusterIP: 10.0.171.239
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 192.0.2.127

来自外部负载平衡器的流量定向到后端Pod。云提供商决定如何进行负载均衡。

Some cloud 提供者s allow you to specify the loadBalancerIP. In those cases, the load-balancer is created with the user-specified loadBalancerIP. If the loadBalancerIP field is 不 specified, the loadBalancer is 组 up with an ephemeral IP 地址。 如果你 specify a loadBalancerIP but your cloud 提供者 does 不 support the feature, the loadbalancerIP field that you set is ignored.

注意: 如果你’重新使用SCTP,请参阅 警告 下面关于 LoadBalancer 服务类型。
注意:

蔚蓝 , if you want to use a user-specified public type loadBalancerIP, you first need 创建静态类型的公共IP地址资源。此公共IP地址资源应 与群集中其他自动创建的资源位于同一资源组中。 For example, MC_myResourceGroup_myAKSCluster_eastus.

Specify the assigned IP address as loadBalancerIP. Ensure that you have updated the securityGroupName in the cloud 提供者 configuration file. For information about troubleshooting CreatingLoadBalancerFailed permission issues see, 将静态IP地址与Azure Kubernetes服务(AKS)负载平衡器一起使用 要么 使用高级网络在AKS群集上创建LoadBalancer失败.

内部负载均衡器

在混合环境中,有时有必要从同一服务中的服务路由流量 (虚拟)网络地址块。

在水平分割DNS环境中,您需要两个服务才能将内部和外部流量都路由到您的端点。

您可以通过向服务添加以下注释之一来实现此目的。 要添加的注释取决于您的云服务提供商’re using.

选择一个选项卡。

[...]
metadata:
    name: my-service
    annotations:
        cloud.google.com/load-balancer-type: "Internal"
[...]

[...]
metadata:
    name: my-service
    annotations:
        service.beta.kubernetes.io/aws-load-balancer-internal: "true"
[...]

[...]
metadata:
    name: my-service
    annotations:
        service.beta.kubernetes.io/azure-load-balancer-internal: "true"
[...]

[...]
metadata:
    name: my-service
    annotations:
        service.beta.kubernetes.io/openstack-internal-load-balancer: "true"
[...]

[...]
metadata:
    name: my-service
    annotations:
        service.beta.kubernetes.io/cce-load-balancer-internal-vpc: "true"
[...]

[...]
metadata:
  annotations:  
    service.kubernetes.io/qcloud-loadbalancer-internal-subnetid: subnet-xxxxx
[...]

AWS 上的TLS支持

为了在AWS上运行的集群上获得部分TLS / SSL支持,您可以添加三个 annotations to a LoadBalancer service:

metadata:
  name: my-service
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012

第一个指定要使用的证书的ARN。可以是 来自第三方发行人的证书,该证书已上传到IAM或已创建 在AWS Certificate Manager中。

metadata:
  name: my-service
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: (https|http|ssl|tcp)

第二个注释指定Pod使用哪种协议。对于HTTPS和 SSL,ELB希望Pod能够通过加密对自己进行身份验证 连接,使用证书。

HTTP 和HTTPS选择第7层代理:ELB终止 与用户的连接,解析标头并注入 X-Forwarded-For用户头’s IP地址(窗格只能看到 转发请求时,连接另一端的ELB)。

TCP协议 协议 和SSL选择第4层代理:ELB转发流量而无需 修改标题。

在混合使用的环境中,某些端口受到保护,而另一些端口未加密, 您可以使用以下注释:

    metadata:
      name: my-service
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
        service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443,8443"

In the above example, if 服务 contained three ports, 80, 443, and 8443, then 443 and 8443 would use the SSL certificate, but 80 would just be proxied HTTP .

从Kubernetes v1.9起可以使用 预定义的AWS SSL策略 为您的服务使用HTTPS或SSL侦听器。 To see 哪一个 policies are available for use, you 能够 use the aws command line tool:

aws elb describe-load-balancer-policies --query 'PolicyDescriptions[].PolicyName'

然后,您可以使用 “service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy“ 注解;例如:

    metadata:
      name: my-service
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy: "ELBSecurityPolicy-TLS-1-2-2017-01"

AWS 上的PROXY协议支持

启用 代理协议 支持在AWS上运行的集群,您可以使用以下服务 annotation:

    metadata:
      name: my-service
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"

从版本1.3.0开始,此注释的使用适用于ELB代理的所有端口 并且无法进行其他配置。

AWS 上的ELB访问日志

有几个注释可用于管理AWS上ELB 服务s的访问日志。

注释 service.beta.kubernetes.io/aws-load-balancer-access-log-enabled 控制是否启用访问日志。

注释 service.beta.kubernetes.io/aws-load-balancer-access-log-emit-interval 控制发布访问日志的时间间隔(以分钟为单位)。您可以指定 5分钟或60分钟的间隔。

注释 service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name 控制负载均衡器访问日志所在的Amazon S3存储桶的名称 stored.

注释 service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix 指定您为Amazon S3存储桶创建的逻辑层次结构。

    metadata:
      name: my-service
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-access-log-enabled: "true"
        # Specifies whether access logs are enabled for the load balancer
        service.beta.kubernetes.io/aws-load-balancer-access-log-emit-interval: "60"
        # The interval for publishing the access logs. You  能够  specify an interval of either 5  要么  60 (minutes).
        service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name: "my-bucket"
        # The name of the Amazon S3 bucket where the access logs are stored
        service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix: "my-bucket-prefix/prod"
        # The logical hierarchy you created for your Amazon S3 bucket, for example `my-bucket-prefix/prod`

AWS 上的连接排空

可以通过注释管理经典ELB的连接消耗 service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled 组 to the value of "true". 注释 service.beta.kubernetes.io/aws-load-balancer-connection-draining-timeout 能够 也可用于设置最大时间(以秒为单位),以在取消注册实例之前保持现有连接的打开状态。

    metadata:
      name: my-service
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled: "true"
        service.beta.kubernetes.io/aws-load-balancer-connection-draining-timeout: "60"

其他ELB注释

还有其他一些注释,用于管理经典弹性负载均衡器,如下所述。

    metadata:
      name: my-service
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "60"
        # The time, in seconds, that the connection is allowed to be idle (no data has been sent over the connection)  之前  it is closed by the load balancer

        service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
        # Specifies whether cross-zone load balancing is enabled for the load balancer

        service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: "environment=prod,owner=devops"
        # A comma-separated list of key-value pairs 哪一个 will be recorded as
        # additional tags in the ELB.

        service.beta.kubernetes.io/aws-load-balancer-healthcheck-healthy-threshold: ""
        # The number of successive successful health checks required for a backend to
        # be considered healthy for traffic. 默认s to 2, must be between 2 and 10

        service.beta.kubernetes.io/aws-load-balancer-healthcheck-unhealthy-threshold: "3"
        # The number of unsuccessful health checks required for a backend to be
        # considered unhealthy for traffic. 默认s to 6, must be between 2 and 10

        service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval: "20"
        # The approximate interval, in seconds, between health checks of an
        # individual instance. 默认s to 10, must be between 5 and 300
        service.beta.kubernetes.io/aws-load-balancer-healthcheck-timeout: "5"
        # The amount of time, in seconds, during 哪一个 no response means a failed
        # health check. This value must be less  比  the service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval
        # value. 默认s to 5, must be between 2 and 60

        service.beta.kubernetes.io/aws-load-balancer-extra-security-groups: "sg-53fae93f,sg-42efd82e"
        # A list of additional security groups to be added to the ELB

AWS 上的Network Load Balancer支持

功能状态: Kubernetes v1.15 贝塔
该功能当前位于 贝塔 状态,含义:

  • 版本名称包含beta(例如v2beta3)。
  • 代码已经过测试。启用该功能被认为是安全的。默认启用。
  • 尽管细节可能会更改,但不会放弃对整体功能的支持。
  • 对象的架构和/或语义可能会在随后的Beta或稳定版本中以不兼容的方式更改。发生这种情况时,我们将提供有关迁移到下一个版本的说明。这可能需要删除,编辑和重新创建API对象。编辑过程可能需要一些思考。对于依赖该功能的应用程序,可能需要停机。
  • 建议仅用于非关键业务用途,因为在后续版本中可能会发生不兼容的更改。如果您有多个可以独立升级的群集,则可以放宽此限制。
  • 请尝试使用我们的Beta功能,并提供有关它们的反馈!他们退出测试版后,对我们进行更多更改可能不切实际。

To use a Network Load Balancer on AWS , use the annotation service.beta.kubernetes.io/aws-load-balancer-type with the value 组 to nlb.

    metadata:
      name: my-service
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
注意: NLB仅适用于某些实例类。看到 AWS 文档 在Elastic Load Balancing上获得支持的实例类型的列表。

与传统的弹性负载平衡器不同,网络负载平衡器(NLB)转发了 client’到节点的IP地址。如果一项服务’s .spec.externalTrafficPolicy is 组 to Cluster, the 客户’IP地址未传播到末尾 Pods.

By 组 ting .spec.externalTrafficPolicy to Local, the 客户 IP地址 is 传播到末端Pod,但这可能导致 交通。没有针对特定LoadBalancer服务的任何Pod的节点将失败 the NLB Target Group’自动分配的运行状况检查 .spec.healthCheckNodePort 并且没有收到任何流量。

为了达到平均流量,请使用DaemonSet或指定一个 吊舱反亲和力 不在同一节点上。

您还可以将NLB服务与 内部负载均衡器注解。

为了使客户端流量到达NLB后面的实例,节点安全性 使用以下IP规则修改组:

规则 协议 港口 IpRange IpRange说明
健康检查 TCP协议 协议 节点端口 (.spec.healthCheckNodePort for .spec.externalTrafficPolicy = Local) VPC CIDR kubernetes.io/rule/nlb/health=<loadBalancerName>
客户流量 TCP协议 协议 节点端口 .spec.loadBalancerSourceRanges (defaults to 0.0.0.0/0) kubernetes.io/rule/nlb/client=<loadBalancerName>
MTU发现 ICMP 3,4 .spec.loadBalancerSourceRanges (defaults to 0.0.0.0/0) kubernetes.io/rule/nlb/mtu=<loadBalancerName>

为了限制哪个客户端IP’可以访问网络负载平衡器, specify loadBalancerSourceRanges.

spec:
  loadBalancerSourceRanges:
    - "143.231.0.0/16"
注意: If .spec.loadBalancerSourceRanges is 不 组 , Kubernetes allows traffic from 0.0.0.0/0 to the 没有 de 安全 Group(s). If nodes have 公共IP地址,请注意非NLB流量也可以到达所有实例 在那些经过修改的安全组中。

腾讯Kubernetes引擎(TKE)上的其他CLB注释

如下所示,还有用于在TKE上管理Cloud Load Balancer的其他注释。

    metadata:
      name: my-service
      annotations:
        # Bind Loadbalancers with speicfied nodes
        service.kubernetes.io/qcloud-loadbalancer-backends-label: key in (value1, value2)

        # ID of an existing load balancer
        service.kubernetes.io/tke-existed-lbid:lb-6swtxxxx
        
        # Custom parameters for the load balancer (LB), does  不  support modification of LB type yet
        service.kubernetes.io/service.extensiveParameters: ""
        
        # Custom parameters for the LB listener 
        service.kubernetes.io/service.listenerParameters: ""
        
        # Specifies the type of Load balancer;
        # valid values: classic (Classic Cloud Load Balancer)  要么  application (Application Cloud Load Balancer)
        service.kubernetes.io/loadbalance-type: xxxxx

        # Specifies the public network bandwidth billing method; 
        # valid values: TRAFFIC_POSTPAID_BY_HOUR(bill-by-traffic) and BANDWIDTH_POSTPAID_BY_HOUR (bill-by-bandwidth).
        service.kubernetes.io/qcloud-loadbalancer-internet-charge-type: xxxxxx

        # Specifies the bandwidth value (value range: [1,2000] Mbps).
        service.kubernetes.io/qcloud-loadbalancer-internet-max-bandwidth-out: "10"

        # When this annotation is  组 ,the loadbalancers will only register nodes 
        # with pod running on it, otherwise all nodes will be registered.
        service.kubernetes.io/local-svc-only-bind-node-with-pod: true

类型ExternalName

类型为ExternalName的服务将服务映射到DNS名称,而不是典型的选择器,例如 my-service 要么 cassandra. You specify these 服务s with the spec.externalName parameter.

此服务定义,例如,地图 the my-service 服务 in the prod 名字 pace to my.database.example.com:

apiVersion: v1
kind: 服务
metadata:
  name: my-service
   名字 pace: prod
spec:
  type: 外部名称
  externalName: my.database.example.com
注意: 外部名称接受IPv4地址字符串,但作为包含数字的DNS名称,而不是IP地址。类似于IPv4地址的外部名称不能由CoreDNS或ingress-nginx解析,因为外部名称 用于指定规范的DNS名称。要对IP地址进行硬编码,请考虑使用 无头服务.

When looking up the host my-service.prod.svc.cluster.local, the cluster 域名解析 服务 returns a CNAME record with the value my.database.example.com. Accessing my-service 与其他服务的工作方式相同,但至关重要 重定向发生在DNS级别而不是通过代理或重定向的区别 转发。如果您以后决定将数据库移到群集中, 可以启动其Pod,添加适当的选择器或端点并更改 Service’s type.

警告:

您可能无法将ExternalName用于某些常见协议,包括HTTP和HTTPS。如果使用外部名称,则群集内的客户端使用的主机名与外部名称引用的名称不同。

For protocols that use hostnames this difference may lead to errors 要么 unexpected responses. HTTP requests will have a Host: header that the 要么 igin server does 不 recognize; TLS servers will 不 be able to provide a certificate matching the hostname that the 客户 connected to.

注意: 本节欠债 Kubernetes技巧-部分 1 来自的博客文章 艾伦·科姆连(Alen Komljen).

外部IP

如果有外部IP路由到一个或多个群集节点,则可以在这些IP上公开Kubernetes 服务s externalIPs。在服务端口上使用外部IP(作为目标IP)进入群集的流量, will be routed to one of 服务 端点。 externalIPs are 不 managed by Kubernetes and are the responsibility 集群管理员。

In 服务 spec, externalIPs 能够 be specified along with 任何 of the 服务Types. 在下面的示例中,“my-service”可以由客户端访问“80.11.12.10:80” (externalIP:port)

apiVersion: v1
kind: 服务
metadata:
  name: my-service
spec:
  选择器:
    app: MyApp
  ports:
    - name: http
      protocol:   TCP协议 协议 
      port: 80
      targetPort: 9376
  externalIPs:
    - 80.11.12.10

缺点

使用用于VIP的用户空间代理,可在中小型范围内工作,但可以 无法扩展到具有数千个服务的超大型集群。的 原版的 门户网站的设计方案 有更多详细信息 this.

使用用户空间代理会掩盖数据包访问的源IP地址 a 服务. 这使得某些类型的网络过滤(防火墙)成为不可能。 iptables proxy mode does 不 使群集中的源IP晦涩难懂,但这仍然会影响通过 负载均衡器或节点端口。

The Type field is designed as nested functionality - each level adds to the 以前。并非所有云提供商都严格要求这样做(例如Google Compute Engine not need to allocate a 没有 dePort to make LoadBalancer work, but AWS does) 但是当前的API要求使用它。

虚拟IP实施

对于许多只想 使用服务。但是,在幕后有很多事情要做 worth understanding.

避免碰撞

Kubernetes的主要哲学之一是您不应该 暴露于可能导致您的操作无故失败的情况 你自己。对于服务资源的设计,这意味着不要 您可以选择自己的端口号,如果该选择可能与 someone else’的选择。那是一个隔离失败。

为了让您选择服务的端口号,我们必须 确保没有两个服务可以冲突。 Kubernetes通过分配每个 服务自己的IP地址。

为了确保每个服务都收到唯一的IP,请使用原子分配一个内部分配器 更新全局分配图 一致且高度可用的键值存储用作Kubernetes’所有群集数据的后备存储。 在创建每个服务之前。映射对象必须存在于注册表中 获得IP地址分配的服务,否则创建将 失败,并显示一条消息,指示无法分配IP地址。

在控制平面中,后台控制器负责创建 map(需要支持从使用旧版本的Kubernetes迁移 内存锁定)。 Kubernetes还使用控制器检查无效 分配(例如由于管理员的干预)和清理分配 任何服务不再使用的IP地址。

服务IP地址

Unlike Pod IP地址, 哪一个 actually route to a fixed destination, 单个主机实际上并未应答服务IP。相反,kube-proxy 使用iptables(Linux中的数据包处理逻辑)来定义 虚拟 IP地址 根据需要透明重定向。当客户端连接到 VIP,其流量会自动传输到适当的端点。 实际上,环境变量和DNS for 服务s已填充在 terms of 服务’的虚拟IP地址(和端口)。

库贝代理支持三种代理模式—用户空间,iptables和IPVS—which 每个操作略有不同。

用户空间

作为示例,考虑上述图像处理应用程序。 创建后端服务后,Kubernetes主服务器会分配一个虚拟 IP地址,例如10.0.0.1。假设服务端口为1234, 群集中的所有kube-proxy实例均可观察到服务。 当代理看到新服务时,它将打开一个新的随机端口,并建立一个 iptables从虚拟IP地址重定向到此新端口,并开始接受 connections on it.

客户端连接到服务时’的虚拟IP地址iptables 规则生效,并将数据包重定向到代理’s own port. “服务代理”选择一个后端,然后开始代理从客户端到后端的流量。

这意味着服务所有者可以选择他们想要的任何端口,而不必担心 碰撞。客户端可以简单地连接到IP和端口,而无需知道 of 哪一个 豆荚 they are actually accessing.

iptables

再次考虑上述图像处理应用程序。 创建后端服务后,Kubernetes控制平面会分配一个虚拟 IP地址,例如10.0.0.1。假设服务端口为1234, 群集中的所有kube-proxy实例均可观察到服务。 当代理看到新服务时,它将安装一系列iptables规则,这些规则 从虚拟IP地址重定向到按服务规则。每项服务 规则链接到重定向流量的每个端点规则(使用目标NAT) to the backends.

客户端连接到服务时’iptables规则插入的虚拟IP地址。 选择一个后端(基于会话亲缘关系或随机选择),然后选择数据包 重定向到后端。与用户空间代理不同,数据包永远不会 复制到用户空间后,虚拟机不必运行kube-proxy IP地址正常工作,节点看到来自未更改客户端IP的流量 address.

当流量通过节点端口或端口进入时,执行相同的基本流程 通过负载平衡器,尽管在这种情况下,客户端IP确实会更改。

IPVS

在大规模集群(例如10,000个服务)中,iptables操作会显着降低速度。 IPVS专为负载平衡而设计,并基于内核内哈希表。因此,您可以通过基于IPVS的kube-proxy在大量服务中实现性能一致性。同时,基于IPVS的kube-proxy具有更复杂的负载平衡算法(最小连接,局部性,加权,持久性)。

API对象

服务是Kubernetes REST API中的顶级资源。您可以找到更多详细信息 关于API对象的信息: 服务API对象.

支持的协议

TCP协议 协议

功能状态: Kubernetes v1.0 稳定
此功能是 稳定 ,意思是:

  • 版本名称为vX,其中X为整数。
  • 稳定的功能版本将在许多后续版本的发行软件中显示。

您可以将TCP用于任何类型的服务,’s默认网络协议。

UDP协议 协议

功能状态: Kubernetes v1.0 稳定
此功能是 稳定 ,意思是:

  • 版本名称为vX,其中X为整数。
  • 稳定的功能版本将在许多后续版本的发行软件中显示。

您可以将UDP用于大多数服务。对于type = LoadBalancer服务,UDP支持 depends on the cloud 提供者 offering this facility.

HTTP

功能状态: Kubernetes v1.1 稳定
此功能是 稳定 ,意思是:

  • 版本名称为vX,其中X为整数。
  • 稳定的功能版本将在许多后续版本的发行软件中显示。

如果你r cloud 提供者 supports it, you 能够 use a 服务 in LoadBalancer mode 设置外部HTTP / HTTP S反向代理,转发给端点 of 服务.

注意: 您也可以使用 入口一个API对象,用于管理对集群中服务的外部访问,通常是HTTP。 代替服务 公开HTTP / HTTP S服务。

代理协议

功能状态: Kubernetes v1.1 稳定
此功能是 稳定 ,意思是:

  • 版本名称为vX,其中X为整数。
  • 稳定的功能版本将在许多后续版本的发行软件中显示。

如果你r cloud 提供者 supports it (eg, AWS ), 您可以在LoadBalancer模式下使用服务在外部配置负载均衡器 Kubernetes本身,它将转发以开头的连接 代理协议.

负载平衡器将发送一系列初始八位字节,描述 传入连接,类似于此示例

PROXY  TCP协议 4 192.0.2.202 10.0.42.7 12345 7\r\n

followed by the data from the 客户.

计划

功能状态: Kubernetes v1.12 α
该功能当前位于 α 状态,含义:

  • 版本名称包含Alpha(例如v1alpha1)。
  • 可能是越野车。启用该功能可能会暴露错误。默认禁用。
  • 随时可能删除对功能的支持,恕不另行通知。
  • 在以后的软件版本中,API可能会以不兼容的方式更改,恕不另行通知。
  • 由于存在更高的错误风险和缺乏长期支持,建议仅用于短期测试集群。

Kubernetes supports 计划 as a protocol value in 服务, Endpoint, NetworkPolicy and Pod definitions as an α feature. 启用 this feature, the cluster administrator needs to enable the 计划 Support feature gate on the apiserver, for example, --feature-gates=SCTPSupport=true,….

When the feature gate is enabled, you 能够 组 the protocol field of a 服务, Endpoint, NetworkPolicy 要么 Pod to 计划 . Kubernetes 组 s up the network accordingly for the 计划 associations, just like it does for TCP协议 connections.

警告事项

支持多宿主SCTP关联
警告:

对多宿主SCTP关联的支持要求CNI插件可以支持将多个接口和IP地址分配给Pod。

用于多宿主SCTP关联的NAT在相应的内核模块中需要特殊的逻辑。

类型= LoadBalancer的服务
警告: You 能够 only create a 服务 with type LoadBalancer plus protocol 计划 if the cloud 提供者’的负载均衡器实现支持SCTP作为协议。否则,服务创建请求将被拒绝。当前的一组云负载平衡器提供程序(Azure,AWS,CloudStack,GCE,OpenStack)都缺乏对SCTP的支持。
视窗
警告: 基于Windows的节点不支持SCTP。
用户空间kube-proxy
警告: 当kube-proxy处于用户空间模式时,它不支持SCTP关联的管理。

未来的工作

将来,服务的代理策略可能会变得比 简单的轮循平衡,例如主选举或分片。我们也 设想某些服务将具有“real”负载均衡器,在这种情况下 虚拟IP地址只会将数据包在那里传输。

Kubernetes项目旨在改善对L7(HTTP)服务的支持。

Kubernetes项目旨在为服务提供更灵活的入口模式 其中包括当前的ClusterIP,NodePort和LoadBalancer模式等等。

什么's next

反馈