[zh-cn]sync content/zh-cn/docs/concepts/services-networking/service.md

Signed-off-by: xin.li <xin.li@daocloud.io>
pull/38212/head
xin.li 2022-12-01 20:55:15 +08:00
parent 25fdb78ff2
commit 55a58d0aa1
1 changed files with 45 additions and 684 deletions

View File

@ -240,14 +240,16 @@ in the next version of your backend software, without breaking clients.
例如,你可以在新版本中更改 Pod 中后端软件公开的端口号,而不会破坏客户端。
<!--
The default protocol for Services is TCP; you can also use any other
[supported protocol](#protocol-support).
The default protocol for Services is
[TCP](/docs/reference/networking/service-protocols/#protocol-tcp); you can also
use any other [supported protocol](/docs/reference/networking/service-protocols/).
As many Services need to expose more than one port, Kubernetes supports multiple
port definitions on a Service object.
Each port definition can have the same `protocol`, or a different one.
-->
服务的默认协议是 TCP你还可以使用任何其他[受支持的协议](#protocol-support)。
服务的默认协议是 TCP(/zh-cn/docs/reference/networking/service-protocols/#protocol-tcp)
你还可以使用任何其他[受支持的协议](/zh-cn/docs/reference/networking/service-protocols/)。
由于许多服务需要公开多个端口,因此 Kubernetes 在服务对象上支持多个端口定义。
每个端口定义可以具有相同的 `protocol`,也可以具有不同的协议。
@ -518,263 +520,6 @@ domain prefixed names such as `mycompany.com/my-custom-protocol`.
其值可以是 [IANA 标准服务名称](https://www.iana.org/assignments/service-names)
或以域名为前缀的名称,如 `mycompany.com/my-custom-protocol`
<!--
## Virtual IPs and service proxies
Every node in a Kubernetes cluster runs a `kube-proxy`. `kube-proxy` is
responsible for implementing a form of virtual IP for `Services` of type other
than [`ExternalName`](#externalname).
-->
## 虚拟 IP 和 Service 代理 {#virtual-ips-and-service-proxies}
在 Kubernetes 集群中,每个 Node 运行一个 `kube-proxy` 进程。
`kube-proxy` 负责为 Service 实现了一种 VIP虚拟 IP的形式而不是
[`ExternalName`](#externalname) 的形式。
<!--
### Why not use round-robin DNS?
A question that pops up every now and then is why Kubernetes relies on
proxying to forward inbound traffic to backends. What about other
approaches? For example, would it be possible to configure DNS records that
have multiple A values (or AAAA for IPv6), and rely on round-robin name
resolution?
There are a few reasons for using proxying for Services:
* There is a long history of DNS implementations not respecting record TTLs,
and caching the results of name lookups after they should have expired.
* Some apps do DNS lookups only once and cache the results indefinitely.
* Even if apps and libraries did proper re-resolution, the low or zero TTLs
on the DNS records could impose a high load on DNS that then becomes
difficult to manage.
-->
### 为什么不使用 DNS 轮询? {#why-not-use-round-robin-dns}
时不时会有人问到为什么 Kubernetes 依赖代理将入站流量转发到后端。那其他方法呢?
例如,是否可以配置具有多个 A 值(或 IPv6 为 AAAA的 DNS 记录,并依靠轮询名称解析?
使用服务代理有以下几个原因:
* DNS 实现的历史由来已久,它不遵守记录 TTL并且在名称查找结果到期后对其进行缓存。
* 有些应用程序仅执行一次 DNS 查找,并无限期地缓存结果。
* 即使应用和库进行了适当的重新解析DNS 记录上的 TTL 值低或为零也可能会给
DNS 带来高负载,从而使管理变得困难。
<!--
Later in this page you can read about how various kube-proxy implementations work. Overall,
you should note that, when running `kube-proxy`, kernel level rules may be
modified (for example, iptables rules might get created), which won't get cleaned up,
in some cases until you reboot. Thus, running kube-proxy is something that should
only be done by an administrator which understands the consequences of having a
low level, privileged network proxying service on a computer. Although the `kube-proxy`
executable supports a `cleanup` function, this function is not an official feature and
thus is only available to use as-is.
-->
在本页下文中,你可以了解各种 kube-proxy 实现是如何工作的。
总的来说,你应该注意当运行 `kube-proxy` 时,内核级别的规则可能会被修改(例如,可能会创建 iptables 规则),
在某些情况下直到你重新引导才会清理这些内核级别的规则。
因此,运行 kube-proxy 只能由了解在计算机上使用低级别、特权网络代理服务后果的管理员来完成。
尽管 `kube-proxy` 可执行文件支持 `cleanup` 功能,但此功能不是官方特性,因此只能按原样使用。
<!--
### Configuration
Note that the kube-proxy starts up in different modes, which are determined by its configuration.
- The kube-proxy's configuration is done via a ConfigMap, and the ConfigMap for kube-proxy
effectively deprecates the behavior for almost all of the flags for the kube-proxy.
- The ConfigMap for the kube-proxy does not support live reloading of configuration.
- The ConfigMap parameters for the kube-proxy cannot all be validated and verified on startup.
For example, if your operating system doesn't allow you to run iptables commands,
the standard kernel kube-proxy implementation will not work.
Likewise, if you have an operating system which doesn't support `netsh`,
it will not run in Windows userspace mode.
-->
### 配置 {#configuration}
请注意kube-proxy 可以以不同的模式启动,具体取决于其配置。
- kube-proxy 的配置是通过 ConfigMap 完成的,并且 kube-proxy 的 ConfigMap 有效地弃用了 kube-proxy 几乎所有标志的行为。
- kube-proxy 的 ConfigMap 不支持实时重新加载配置。
- kube-proxy 的 ConfigMap 参数不能在启动时被全部校验和验证。
例如,如果你的操作系统不允许你运行 iptables 命令,则标准内核 kube-proxy 实现将无法工作。
同样,如果你的操作系统不支持 `netsh`,它将无法在 Windows 用户空间模式下运行。
<!--
### User space proxy mode {#proxy-mode-userspace}
In this (legacy) mode, kube-proxy watches the Kubernetes control plane for the addition and
removal of Service and Endpoint objects. For each Service it opens a
port (randomly chosen) on the local node. Any connections to this "proxy port"
are proxied to one of the Service's backend Pods (as reported via
Endpoints). kube-proxy takes the `SessionAffinity` setting of the Service into
account when deciding which backend Pod to use.
Lastly, the user-space proxy installs iptables rules which capture traffic to
the Service's `clusterIP` (which is virtual) and `port`. The rules
redirect that traffic to the proxy port which proxies the backend Pod.
By default, kube-proxy in userspace mode chooses a backend via a round-robin algorithm.
![Services overview diagram for userspace proxy](/images/docs/services-userspace-overview.svg)
-->
### userspace 代理模式 {#proxy-mode-userspace}
在这种遗留模式下kube-proxy 会监视 Kubernetes 控制平面对 Service 对象和 Endpoints 对象的添加和移除操作。
对每个 Service它会在本地 Node 上打开一个端口(随机选择)。
任何连接到“代理端口”的请求,都会被代理到 Service 的后端 `Pods` 中的某个上面(如 `Endpoints` 所报告的一样)。
使用哪个后端 Pod是 kube-proxy 基于 `SessionAffinity` 来确定的。
最后,它配置 iptables 规则,捕获到达该 Service 的 `clusterIP`(是虚拟 IP
`Port` 的请求并重定向到代理端口代理端口再代理请求到后端Pod。
默认情况下,用户空间模式下的 kube-proxy 通过轮转算法选择后端。
![userspace 代理模式下 Service 概览图](/images/docs/services-userspace-overview.svg)
<!--
### `iptables` proxy mode {#proxy-mode-iptables}
In this mode, kube-proxy watches the Kubernetes control plane for the addition and
removal of Service and Endpoint objects. For each Service, it installs
iptables rules, which capture traffic to the Service's `clusterIP` and `port`,
and redirect that traffic to one of the Service's
backend sets. For each Endpoint object, it installs iptables rules which
select a backend Pod.
By default, kube-proxy in iptables mode chooses a backend at random.
Using iptables to handle traffic has a lower system overhead, because traffic
is handled by Linux netfilter without the need to switch between userspace and the
kernel space. This approach is also likely to be more reliable.
If kube-proxy is running in iptables mode and the first Pod that's selected
does not respond, the connection fails. This is different from userspace
mode: in that scenario, kube-proxy would detect that the connection to the first
Pod had failed and would automatically retry with a different backend Pod.
You can use Pod [readiness probes](/docs/concepts/workloads/pods/pod-lifecycle/#container-probes)
to verify that backend Pods are working OK, so that kube-proxy in iptables mode
only sees backends that test out as healthy. Doing this means you avoid
having traffic sent via kube-proxy to a Pod that's known to have failed.
![Services overview diagram for iptables proxy](/images/docs/services-iptables-overview.svg)
-->
### iptables 代理模式 {#proxy-mode-iptables}
这种模式,`kube-proxy` 会监视 Kubernetes 控制节点对 Service 对象和 Endpoints 对象的添加和移除。
对每个 Service它会配置 iptables 规则,从而捕获到达该 Service 的 `clusterIP`
和端口的请求,进而将请求重定向到 Service 的一组后端中的某个 Pod 上面。
对于每个 Endpoints 对象,它也会配置 iptables 规则,这个规则会选择一个后端组合。
默认的策略是kube-proxy 在 iptables 模式下随机选择一个后端。
使用 iptables 处理流量具有较低的系统开销,因为流量由 Linux netfilter 处理,
而无需在用户空间和内核空间之间切换。 这种方法也可能更可靠。
如果 kube-proxy 在 iptables 模式下运行,并且所选的第一个 Pod 没有响应,则连接失败。
这与用户空间模式不同在这种情况下kube-proxy 将检测到与第一个 Pod 的连接已失败,
并会自动使用其他后端 Pod 重试。
你可以使用 Pod [就绪探测器](/zh-cn/docs/concepts/workloads/pods/pod-lifecycle/#container-probes)
验证后端 Pod 可以正常工作,以便 iptables 模式下的 kube-proxy 仅看到测试正常的后端。
这样做意味着你避免将流量通过 kube-proxy 发送到已知已失败的 Pod。
![iptables 代理模式下 Service 概览图](/images/docs/services-iptables-overview.svg)
<!--
### IPVS proxy mode {#proxy-mode-ipvs}
-->
### IPVS 代理模式 {#proxy-mode-ipvs}
{{< feature-state for_k8s_version="v1.11" state="stable" >}}
<!--
In `ipvs` mode, kube-proxy watches Kubernetes Services and Endpoints,
calls `netlink` interface to create IPVS rules accordingly and synchronizes
IPVS rules with Kubernetes Services and Endpoints periodically.
This control loop ensures that IPVS status matches the desired
state.
When accessing a Service, IPVS directs traffic to one of the backend Pods.
The IPVS proxy mode is based on netfilter hook function that is similar to
iptables mode, but uses a hash table as the underlying data structure and works
in the kernel space.
That means kube-proxy in IPVS mode redirects traffic with lower latency than
kube-proxy in iptables mode, with much better performance when synchronizing
proxy rules. Compared to the other proxy modes, IPVS mode also supports a
higher throughput of network traffic.
IPVS provides more options for balancing traffic to backend Pods;
these are:
-->
`ipvs` 模式下kube-proxy 监视 Kubernetes 服务和端点,调用 `netlink` 接口相应地创建 IPVS 规则,
并定期将 IPVS 规则与 Kubernetes 服务和端点同步。该控制循环可确保 IPVS
状态与所需状态匹配。访问服务时IPVS 将流量定向到后端 Pod 之一。
IPVS 代理模式基于类似于 iptables 模式的 netfilter 挂钩函数,
但是使用哈希表作为基础数据结构,并且在内核空间中工作。
这意味着,与 iptables 模式下的 kube-proxy 相比IPVS 模式下的 kube-proxy
重定向通信的延迟要短,并且在同步代理规则时具有更好的性能。
与其他代理模式相比IPVS 模式还支持更高的网络流量吞吐量。
IPVS 提供了更多选项来平衡后端 Pod 的流量。这些是:
* `rr`轮替Round-Robin
* `lc`最少链接Least Connection即打开链接数量最少者优先
* `dh`目标地址哈希Destination Hashing
* `sh`源地址哈希Source Hashing
* `sed`最短预期延迟Shortest Expected Delay
* `nq`从不排队Never Queue
{{< note >}}
<!--
To run kube-proxy in IPVS mode, you must make IPVS available on
the node before starting kube-proxy.
When kube-proxy starts in IPVS proxy mode, it verifies whether IPVS
kernel modules are available. If the IPVS kernel modules are not detected, then kube-proxy
falls back to running in iptables proxy mode.
-->
要在 IPVS 模式下运行 kube-proxy必须在启动 kube-proxy 之前使 IPVS 在节点上可用。
当 kube-proxy 以 IPVS 代理模式启动时,它将验证 IPVS 内核模块是否可用。
如果未检测到 IPVS 内核模块,则 kube-proxy 将退回到以 iptables 代理模式运行。
{{< /note >}}
<!--
![Services overview diagram for IPVS proxy](/images/docs/services-ipvs-overview.svg)
In these proxy models, the traffic bound for the Service's IP:Port is
proxied to an appropriate backend without the clients knowing anything
about Kubernetes or Services or Pods.
If you want to make sure that connections from a particular client
are passed to the same Pod each time, you can select the session affinity based
on the client's IP addresses by setting `service.spec.sessionAffinity` to "ClientIP"
(the default is "None").
You can also set the maximum session sticky time by setting
`service.spec.sessionAffinityConfig.clientIP.timeoutSeconds` appropriately.
(the default value is 10800, which works out to be 3 hours).
-->
![IPVS 代理的 Services 概述图](/images/docs/services-ipvs-overview.svg)
在这些代理模型中,绑定到服务 IP 的流量:
在客户端不了解 Kubernetes 或服务或 Pod 的任何信息的情况下,将 Port 代理到适当的后端。
如果要确保每次都将来自特定客户端的连接传递到同一 Pod
则可以通过将 `service.spec.sessionAffinity` 设置为 "ClientIP"
(默认值是 "None"),来基于客户端的 IP 地址选择会话亲和性。
你还可以通过适当设置 `service.spec.sessionAffinityConfig.clientIP.timeoutSeconds`
来设置最大会话停留时间。(默认值为 10800 秒,即 3 小时)。
{{< note >}}
<!--
On Windows, setting the maximum session sticky time for Services is not supported.
-->
在 Windows 上,不支持为服务设置最大会话停留时间。
{{< /note >}}
<!--
## Multi-Port Services
@ -847,79 +592,6 @@ server will return a 422 HTTP status code to indicate that there's a problem.
这对 API 服务器来说是通过一个标识来指定的。
如果 IP 地址不合法API 服务器会返回 HTTP 状态码 422表示值不合法。
<!--
## Traffic policies
-->
## 流量策略 {#traffic-policies}
<!--
### External traffic policy
-->
### 外部流量策略 {#external-traffic-policy}
<!--
You can set the `spec.externalTrafficPolicy` field to control how traffic from external sources is routed.
Valid values are `Cluster` and `Local`. Set the field to `Cluster` to route external traffic to all ready endpoints
and `Local` to only route to ready node-local endpoints. If the traffic policy is `Local` and there are no node-local
endpoints, the kube-proxy does not forward any traffic for the relevant Service.
-->
你可以通过设置 `spec.externalTrafficPolicy` 字段来控制来自于外部的流量是如何路由的。
可选值有 `Cluster``Local`。字段设为 `Cluster` 会将外部流量路由到所有就绪的端点,
设为 `Local` 会只路由到当前节点上就绪的端点。
如果流量策略设置为 `Local`而且当前节点上没有就绪的端点kube-proxy 不会转发请求相关服务的任何流量。
{{< note >}}
{{< feature-state for_k8s_version="v1.22" state="alpha" >}}
<!--
If you enable the `ProxyTerminatingEndpoints`
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
for the kube-proxy, the kube-proxy checks if the node
has local endpoints and whether or not all the local endpoints are marked as terminating.
-->
如果你启用了 kube-proxy 的 `ProxyTerminatingEndpoints`
[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)
kube-proxy 会检查节点是否有本地的端点,以及是否所有的本地端点都被标记为终止中。
<!--
If there are local endpoints and **all** of those are terminating, then the kube-proxy ignores
any external traffic policy of `Local`. Instead, whilst the node-local endpoints remain as all
terminating, the kube-proxy forwards traffic for that Service to healthy endpoints elsewhere,
as if the external traffic policy were set to `Cluster`.
-->
如果本地有端点,而且所有端点处于终止中的状态,那么 kube-proxy 会忽略任何设为 `Local` 的外部流量策略。
在所有本地端点处于终止中的状态的同时kube-proxy 将请求指定服务的流量转发到位于其它节点的状态健康的端点,
如同外部流量策略设为 `Cluster`
<!--
This forwarding behavior for terminating endpoints exists to allow external load balancers to
gracefully drain connections that are backed by `NodePort` Services, even when the health check
node port starts to fail. Otherwise, traffic can be lost between the time a node is still in the node pool of a load
balancer and traffic is being dropped during the termination period of a pod.
-->
针对处于正被终止状态的端点这一转发行为使得外部负载均衡器可以优雅地排出由
`NodePort` 服务支持的连接,就算是健康检查节点端口开始失败也是如此。
否则,当节点还在负载均衡器的节点池内,在 Pod 终止过程中的流量会被丢掉,这些流量可能会丢失。
{{< /note >}}
<!--
### Internal traffic policy
-->
### 内部流量策略 {#internal-traffic-policy}
{{< feature-state for_k8s_version="v1.22" state="beta" >}}
<!--
You can set the `spec.internalTrafficPolicy` field to control how traffic from internal sources is routed.
Valid values are `Cluster` and `Local`. Set the field to `Cluster` to route internal traffic to all ready endpoints
and `Local` to only route to ready node-local endpoints. If the traffic policy is `Local` and there are no node-local
endpoints, traffic is dropped by kube-proxy.
-->
你可以设置 `spec.internalTrafficPolicy` 字段来控制内部来源的流量是如何转发的。可设置的值有 `Cluster``Local`
将字段设置为 `Cluster` 会将内部流量路由到所有就绪端点,设置为 `Local` 只会路由到当前节点上就绪的端点。
如果流量策略是 `Local`,而且当前节点上没有就绪的端点,那么 kube-proxy 会丢弃流量。
<!--
## Discovering services
@ -1148,6 +820,18 @@ Kubernetes `ServiceTypes` 允许指定你所需要的 Service 类型。
你需要使用 kube-dns 1.7 及以上版本或者 CoreDNS 0.0.8 及以上版本才能使用 `ExternalName` 类型。
{{< /note >}}
<!--
The `type` field was designed as nested functionality - each level adds to the
previous. This is not strictly required on all cloud providers (for example: Google
Compute Engine does not need to allocate a node port to make `type: LoadBalancer` work,
but another cloud provider integration might do). Although strict nesting is not required,
but the Kubernetes API design for Service requires it anyway.
-->
`type` 字段被设计为嵌套功能 - 每个级别都添加到前一个级别。
这并不是所有云提供商都严格要求的例如Google Compute Engine
不需要分配节点端口来使 `type: LoadBalancer` 工作,但另一个云提供商集成可能会这样做)。
虽然不需要严格的嵌套,但是 Service 的 Kubernetes API 设计无论如何都需要它。
<!--
You can also use [Ingress](/docs/concepts/services-networking/ingress/) to expose your Service.
Ingress is not a Service type, but it acts as the entry point for your cluster.
@ -2173,239 +1857,17 @@ spec:
```
<!--
## Shortcomings
## Session stickiness
Using the userspace proxy for VIPs works at small to medium scale, but will
not scale to very large clusters with thousands of Services. The
[original design proposal for portals](https://github.com/kubernetes/kubernetes/issues/1107)
has more details on this.
Using the userspace proxy obscures the source IP address of a packet accessing
a Service.
This makes some kinds of network filtering (firewalling) impossible. The iptables
proxy mode does not
obscure in-cluster source IPs, but it does still impact clients coming through
a load balancer or node-port.
The `Type` field is designed as nested functionality - each level adds to the
previous. This is not strictly required on all cloud providers (e.g. Google Compute Engine does
not need to allocate a `NodePort` to make `LoadBalancer` work, but AWS does)
but the Kubernetes API design for Service requires it anyway.
If you want to make sure that connections from a particular client are passed to
the same Pod each time, you can configure session affinity based on the client's
IP address. Read [session affinity](/docs/reference/networking/virtual-ips/#session-affinity)
to learn more.
-->
## 不足之处 {#shortcomings}
## 粘性会话 {#session-stickiness}
为 VIP 使用用户空间代理,将只适合小型到中型规模的集群,不能够扩展到上千 Service 的大型集群。
查看[最初设计方案](https://github.com/kubernetes/kubernetes/issues/1107) 获取更多细节。
使用用户空间代理,隐藏了访问 Service 的数据包的源 IP 地址。
这使得一些类型的防火墙无法起作用。
iptables 代理不会隐藏 Kubernetes 集群内部的 IP 地址,
但却要求客户端请求必须通过一个负载均衡器或 Node 端口。
`Type` 字段支持嵌套功能 —— 每一层需要添加到上一层里面。
不会严格要求所有云提供商例如GCE 就没必要为了使一个 `LoadBalancer`
能工作而分配一个 `NodePort`,但是 AWS 需要 ),但针对服务的 Kubernetes API 设计是强制要求的。
<!--
## Virtual IP implementation {#the-gory-details-of-virtual-ips}
The previous information should be sufficient for many people who want to
use Services. However, there is a lot going on behind the scenes that may be
worth understanding.
-->
## 虚拟 IP 实施 {#the-gory-details-of-virtual-ips}
对很多想使用 Service 的人来说,前面的信息应该足够了。
然而,有很多内部原理性的内容,还是值去理解的。
<!--
### Avoiding collisions
One of the primary philosophies of Kubernetes is that you should not be
exposed to situations that could cause your actions to fail through no fault
of your own. For the design of the Service resource, this means not making
you choose your own port number if that choice might collide with
someone else's choice. That is an isolation failure.
In order to allow you to choose a port number for your Services, we must
ensure that no two Services can collide. Kubernetes does that by allocating each
Service its own IP address from within the `service-cluster-ip-range`
CIDR range that is configured for the API server.
To ensure each Service receives a unique IP, an internal allocator atomically
updates a global allocation map in {{< glossary_tooltip term_id="etcd" >}}
prior to creating each Service. The map object must exist in the registry for
Services to get IP address assignments, otherwise creations will
fail with a message indicating an IP address could not be allocated.
In the control plane, a background controller is responsible for creating that
map (needed to support migrating from older versions of Kubernetes that used
in-memory locking). Kubernetes also uses controllers to check for invalid
assignments (e.g. due to administrator intervention) and for cleaning up allocated
IP addresses that are no longer used by any Services.
-->
### 避免冲突 {#avoiding-collisions}
Kubernetes 最主要的哲学之一,是用户不应该暴露那些能够导致他们操作失败、但又不是他们的过错的场景。
对于 Service 资源的设计,这意味着如果用户的选择有可能与他人冲突,那就不要让用户自行选择端口号。
这是一个隔离性的失败。
为了使用户能够为他们的 Service 选择一个端口号,我们必须确保不能有 2 个 Service 发生冲突。
Kubernetes 通过在为 API 服务器配置的 `service-cluster-ip-range` CIDR
范围内为每个服务分配自己的 IP 地址来实现。
为了保证每个 Service 被分配到一个唯一的 IP需要一个内部的分配器能够原子地更新
{{< glossary_tooltip term_id="etcd" >}} 中的一个全局分配映射表,
这个更新操作要先于创建每一个 Service。
为了使 Service 能够获取到 IP这个映射表对象必须在注册中心存在
否则创建 Service 将会失败,指示一个 IP 不能被分配。
在控制平面中,一个后台 Controller 的职责是创建映射表
(需要支持从使用了内存锁的 Kubernetes 的旧版本迁移过来)。
同时 Kubernetes 会通过控制器检查不合理的分配(如管理员干预导致的)
以及清理已被分配但不再被任何 Service 使用的 IP 地址。
<!--
#### IP address ranges for `type: ClusterIP` Services {#service-ip-static-sub-range}
{{< feature-state for_k8s_version="v1.25" state="beta" >}}
However, there is a problem with this `ClusterIP` allocation strategy, because a user
can also [choose their own address for the service](#choosing-your-own-ip-address).
This could result in a conflict if the internal allocator selects the same IP address
for another Service.
-->
#### `type: ClusterIP` 服务的 IP 地址范围 {#service-ip-static-sub-range}
{{< feature-state for_k8s_version="v1.25" state="beta" >}}
但是,这种 `ClusterIP` 分配策略存在一个问题,因为用户还可以[为服务选择自己的地址](#choosing-your-own-ip-address)。
如果内部分配器为另一个服务选择相同的 IP 地址,这可能会导致冲突。
<!--
The `ServiceIPStaticSubrange`
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled by default in v1.25
and later, using an allocation strategy that divides the `ClusterIP` range into two bands, based on
the size of the configured `service-cluster-ip-range` by using the following formula
`min(max(16, cidrSize / 16), 256)`, described as _never less than 16 or more than 256,
with a graduated step function between them_. Dynamic IP allocations will be preferentially
chosen from the upper band, reducing risks of conflicts with the IPs
assigned from the lower band.
This allows users to use the lower band of the `service-cluster-ip-range` for their
Services with static IPs assigned with a very low risk of running into conflicts.
-->
`ServiceIPStaticSubrange` [特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)在
v1.25 及后续版本中默认启用,其分配策略根据配置的 `service-cluster-ip-range` 的大小,使用以下公式
`min(max(16, cidrSize / 16), 256)` 进行划分,该公式可描述为
“在不小于 16 且不大于 256 之间有一个步进量Graduated Step
`ClusterIP` 范围分成两段。动态 IP 分配将优先从上半段地址中选择,
从而降低与下半段地址分配的 IP 冲突的风险。
这允许用户将 `service-cluster-ip-range` 的下半段地址用于他们的服务,
与所分配的静态 IP 的冲突风险非常低。
<!--
### Service IP addresses {#ips-and-vips}
Unlike Pod IP addresses, which actually route to a fixed destination,
Service IPs are not actually answered by a single host. Instead, kube-proxy
uses iptables (packet processing logic in Linux) to define _virtual_ IP addresses
which are transparently redirected as needed. When clients connect to the
VIP, their traffic is automatically transported to an appropriate endpoint.
The environment variables and DNS for Services are actually populated in
terms of the Service's virtual IP address (and port).
kube-proxy supports three proxy modes&mdash;userspace, iptables and IPVS&mdash;which
each operate slightly differently.
-->
### Service IP 地址 {#ips-and-vips}
不像 Pod 的 IP 地址它实际路由到一个固定的目的地Service 的 IP 实际上不能通过单个主机来进行应答。
相反,我们使用 `iptables`Linux 中的数据包处理逻辑)来定义一个虚拟 IP 地址VIP
它可以根据需要透明地进行重定向。
当客户端连接到 VIP 时,它们的流量会自动地传输到一个合适的 Endpoint。
环境变量和 DNS实际上会根据 Service 的 VIP 和端口来进行填充。
kube-proxy 支持三种代理模式: 用户空间、iptables 和 IPVS它们各自的操作略有不同。
#### Userspace {#userspace}
<!--
As an example, consider the image processing application described above.
When the backend Service is created, the Kubernetes master assigns a virtual
IP address, for example 10.0.0.1. Assuming the Service port is 1234, the
Service is observed by all of the kube-proxy instances in the cluster.
When a proxy sees a new Service, it opens a new random port, establishes an
iptables redirect from the virtual IP address to this new port, and starts accepting
connections on it.
When a client connects to the Service's virtual IP address, the iptables
rule kicks in, and redirects the packets to the proxy's own port.
The "Service proxy" chooses a backend, and starts proxying traffic from the client to the backend.
This means that Service owners can choose any port they want without risk of
collision. Clients can connect to an IP and port, without being aware
of which Pods they are actually accessing.
-->
作为一个例子,考虑前面提到的图片处理应用程序。
当创建后端 Service 时Kubernetes master 会给它指派一个虚拟 IP 地址,比如 10.0.0.1。
假设 Service 的端口是 1234该 Service 会被集群中所有的 `kube-proxy` 实例观察到。
当代理看到一个新的 Service它会打开一个新的端口
建立一个从该 VIP 重定向到新端口的 iptables并开始接收请求连接。
当一个客户端连接到一个 VIPiptables 规则开始起作用,它会重定向该数据包到
"服务代理" 的端口。
"服务代理" 选择一个后端,并将客户端的流量代理到后端上。
这意味着 Service 的所有者能够选择任何他们想使用的端口,而不存在冲突的风险。
客户端可以连接到一个 IP 和端口,而不需要知道实际访问了哪些 Pod。
#### iptables
<!--
Again, consider the image processing application described above.
When the backend Service is created, the Kubernetes control plane assigns a virtual
IP address, for example 10.0.0.1. Assuming the Service port is 1234, the
Service is observed by all of the kube-proxy instances in the cluster.
When a proxy sees a new Service, it installs a series of iptables rules which
redirect from the virtual IP address to per-Service rules. The per-Service
rules link to per-Endpoint rules which redirect traffic (using destination NAT)
to the backends.
When a client connects to the Service's virtual IP address the iptables rule kicks in.
A backend is chosen (either based on session affinity or randomly) and packets are
redirected to the backend. Unlike the userspace proxy, packets are never
copied to userspace, the kube-proxy does not have to be running for the virtual
IP address to work, and Nodes see traffic arriving from the unaltered client IP
address.
This same basic flow executes when traffic comes in through a node-port or
through a load-balancer, though in those cases the client IP does get altered.
-->
再次考虑前面提到的图片处理应用程序。
当创建后端 Service 时Kubernetes 控制面板会给它指派一个虚拟 IP 地址,比如 10.0.0.1。
假设 Service 的端口是 1234该 Service 会被集群中所有的 `kube-proxy` 实例观察到。
当代理看到一个新的 Service 它会配置一系列的 iptables 规则,从 VIP 重定向到每个 Service 规则。
该特定于服务的规则连接到特定于 Endpoint 的规则,而后者会重定向(目标地址转译)到后端。
当客户端连接到一个 VIPiptables 规则开始起作用。一个后端会被选择(或者根据会话亲和性,或者随机),
数据包被重定向到这个后端。
不像用户空间代理数据包从来不拷贝到用户空间kube-proxy 不是必须为该 VIP 工作而运行,
并且客户端 IP 是不可更改的。
当流量打到 Node 的端口上,或通过负载均衡器,会执行相同的基本流程,
但是在那些案例中客户端 IP 是可以更改的。
#### IPVS
<!--
iptables operations slow down dramatically in large scale cluster e.g. 10,000 Services.
IPVS is designed for load balancing and based on in-kernel hash tables.
So you can achieve performance consistency in large number of Services from IPVS-based kube-proxy.
Meanwhile, IPVS-based kube-proxy has more sophisticated load balancing algorithms
(least conns, locality, weighted, persistence).
-->
在大规模集群(例如 10000 个服务iptables 操作会显着降低速度。
IPVS 专为负载均衡而设计,并基于内核内哈希表。
因此,你可以通过基于 IPVS 的 kube-proxy 在大量服务中实现性能一致性。
同时,基于 IPVS 的 kube-proxy 具有更复杂的负载均衡算法(最小连接、局部性、加权、持久性)。
如果你想确保来自特定客户端的连接每次都传递到同一个 Pod你可以配置根据客户端 IP 地址来执行的会话亲和性。
阅读[会话亲和性](/zh-cn/docs/reference/networking/virtual-ips/#session-affinity)了解更多。
<!--
## API Object
@ -2413,7 +1875,6 @@ IPVS 专为负载均衡而设计,并基于内核内哈希表。
Service is a top-level resource in the Kubernetes REST API. You can find more details
about the [Service API object](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core).
## Supported protocols {#protocol-support}
-->
## API 对象 {#api-object}
@ -2421,130 +1882,19 @@ Service 是 Kubernetes REST API 中的顶级资源。你可以找到有关
[Service 对象 API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core)
的更多详细信息。
## 受支持的协议 {#protocol-support}
### TCP
<!-- preserve existing hyperlinks -->
<a id="shortcomings" /><a id="#the-gory-details-of-virtual-ips" />
<!--
You can use TCP for any kind of Service, and it's the default network protocol.
## Virtual IP addressing mechanism
Read [Virtual IPs and Service Proxies](/docs/reference/networking/virtual-ips/) to learn about the
mechanism Kubernetes provides to expose a Service with a virtual IP address.
-->
你可以将 TCP 用于任何类型的服务,这是默认的网络协议。
## 虚拟 IP 寻址机制 {#virtual-ip-addressing-mechanism}
### UDP
<!--
You can use UDP for most Services. For type=LoadBalancer Services, UDP support
depends on the cloud provider offering this facility.
-->
你可以将 UDP 用于大多数服务。 对于 type=LoadBalancer 服务,对 UDP 的支持取决于提供此功能的云提供商。
<!--
### SCTP
When using a network plugin that supports SCTP traffic, you can use SCTP for
most Services. For type=LoadBalancer Services, SCTP support depends on the cloud
provider offering this facility. (Most do not).
-->
### SCTP
{{< feature-state for_k8s_version="v1.20" state="stable" >}}
一旦你使用了支持 SCTP 流量的网络插件,你就可以使用 SCTP 于更多的服务。
对于 type = LoadBalancer 的服务SCTP 的支持取决于提供此设施的云供应商(大多数不支持)。
<!--
#### Warnings {#caveat-sctp-overview}
##### Support for multihomed SCTP associations {#caveat-sctp-multihomed}
-->
#### 警告 {#caveat-sctp-overview}
##### 支持多宿主 SCTP 关联 {#caveat-sctp-multihomed}
{{< warning >}}
<!--
The support of multihomed SCTP associations requires that the CNI plugin can support the
assignment of multiple interfaces and IP addresses to a Pod.
NAT for multihomed SCTP associations requires special logic in the corresponding kernel modules.
-->
支持多宿主 SCTP 关联要求 CNI 插件能够支持为一个 Pod 分配多个接口和 IP 地址。
用于多宿主 SCTP 关联的 NAT 在相应的内核模块中需要特殊的逻辑。
{{< /warning >}}
<!--
##### Windows {#caveat-sctp-windows-os}
-->
##### Windows {#caveat-sctp-windows-os}
{{< note >}}
<!--
SCTP is not supported on Windows based nodes.
-->
基于 Windows 的节点不支持 SCTP。
{{< /note >}}
<!--
##### Userspace kube-proxy {#caveat-sctp-kube-proxy-userspace}
-->
##### 用户空间 kube-proxy {#caveat-sctp-kube-proxy-userspace}
{{< warning >}}
<!--
The kube-proxy does not support the management of SCTP associations when it is in userspace mode.
-->
当 kube-proxy 处于用户空间模式时,它不支持 SCTP 关联的管理。
{{< /warning >}}
### HTTP
<!--
If your cloud provider supports it, you can use a Service in LoadBalancer mode
to set up external HTTP / HTTPS reverse proxying, forwarded to the Endpoints
of the Service.
-->
如果你的云提供商支持它,则可以在 LoadBalancer 模式下使用服务来设置外部
HTTP/HTTPS 反向代理,并将其转发到该服务的 Endpoints。
{{< note >}}
<!--
You can also use {{< glossary_tooltip term_id="ingress" >}} in place of Service
to expose HTTP/HTTPS Services.
-->
你还可以使用 {{< glossary_tooltip text="Ingress" term_id="ingress" >}} 代替
Service 来公开 HTTP/HTTPS 服务。
{{< /note >}}
<!--
### PROXY protocol
If your cloud provider supports it,
you can use a Service in LoadBalancer mode to configure a load balancer outside
of Kubernetes itself, that will forward connections prefixed with
[PROXY protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt).
The load balancer will send an initial series of octets describing the
incoming connection, similar to this example
-->
### PROXY 协议 {#proxy-protocol}
如果你的云提供商支持它,
则可以在 LoadBalancer 模式下使用 Service 在 Kubernetes 本身之外配置负载均衡器,
该负载均衡器将转发前缀为
[PROXY 协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)
的连接。
负载均衡器将发送一系列初始字节,描述传入的连接,类似于此示例:
```
PROXY TCP4 192.0.2.202 10.0.42.7 12345 7\r\n
```
<!--
followed by the data from the client.
-->
上述是来自客户端的数据。
阅读[虚拟 IP 和 Service 代理](/zh-cn/docs/reference/networking/virtual-ips/)以了解
Kubernetes 提供的使用虚拟 IP 地址公开服务的机制。
## {{% heading "whatsnext" %}}
@ -2552,7 +1902,18 @@ followed by the data from the client.
* Follow the [Connecting Applications with Services](/docs/tutorials/services/connect-applications-service/) tutorial
* Read about [Ingress](/docs/concepts/services-networking/ingress/)
* Read about [EndpointSlices](/docs/concepts/services-networking/endpoint-slices/)
For more context:
* Read [Virtual IPs and Service Proxies](/docs/reference/networking/virtual-ips/)
* Read the [API reference](/docs/reference/kubernetes-api/service-resources/service-v1/) for the Service API
* Read the [API reference](/docs/reference/kubernetes-api/service-resources/endpoints-v1/) for the Endpoints API
* Read the [API reference](/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/) for the EndpointSlice API
-->
* 遵循[使用 Service 连接到应用](/zh-cn/docs/tutorials/services/connect-applications-service/)教程
* 阅读了解 [Ingress](/zh-cn/docs/concepts/services-networking/ingress/)
* 阅读了解[端点切片Endpoint Slices](/zh-cn/docs/concepts/services-networking/endpoint-slices/)
更多上下文:
* 阅读[虚拟 IP 和 Service 代理](/zh-cn/docs/reference/networking/virtual-ips/)
* 阅读 Service API 的 [API 参考](/zh-cn/docs/reference/kubernetes-api/service-resources/service-v1/)
* 阅读 EndpointSlice API 的 [API 参考](/zh-cn/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/)