Merge release1.14 into master (#16584)

* initial commit

* promote AWS-NLB Support from alpha to beta (#14451) (#16459) (#16484)

* 1. Sync release-1.15 into master
2. Sync with en version

* 1. Add the lost yaml file.

* Update he cluster administration folder of concepts
1. Sync with 1.14 branch
2. Sync with en version

* Add yaml files which are used

* 1. Sync the configuration folder from 1.14 version
2. Sync the configuration folder files with en version
3. Changed some files structure for easily review
4. Add glossary folder for fixup build error

* 1. Sync the storage folder from 1.14 version
2. Sync the storage folder files with 1.16 version en document
3. Changed some files structure for easily review

* 1. Sync the service-networking folder from 1.14 version
2. Sync the service-networking folder files with 1.16 version en document
3. Changed some files structure for easily review
4. Add the necessary documents
5. Add the runtime-class file
This commit is contained in:
成臣 Chengchen
2019-09-27 19:27:36 +09:00
committed by Kubernetes Prow Robot
parent 1e3596f7bc
commit 324f05b68f
30 changed files with 4018 additions and 597 deletions
@@ -0,0 +1,392 @@
---
title: 容器运行时类(Runtime Class)
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.14" state="beta" >}}
<!--
This page describes the RuntimeClass resource and runtime selection mechanism.
-->
这个文档主要说明了 RuntimeClass 资源和 kubernetes 指定容器运行时的功能。
{{< warning >}}
<!--
RuntimeClass includes *breaking* changes in the beta upgrade in v1.14. If you were using
RuntimeClass prior to v1.14, see [Upgrading RuntimeClass from Alpha to
Beta](#upgrading-runtimeclass-from-alpha-to-beta).
-->
Kubernetes1.14 的 β 版的升级包含了 RuntimeClass 的 *破坏性* 的变更。
如果用户在使用 Kubernetes1.14 以前的 RuntimeClass 版本,
请参考文档[从 RuntimeClass 的 α 版升级到β版](#upgrading-runtimeclass-from-alpha-to-beta)。
{{< /warning >}}
{{% /capture %}}
{{% capture body %}}
<!--
## Runtime Class
RuntimeClass is a feature for selecting the container runtime configuration. The container runtime
configuration is used to run a Pod's containers.
-->
## 关于RuntimeClass
RuntimeClass 是可以让用户选择容器运行时的功能。用户通过设定容器运行时可以选择 Pod 的容器运行在那种容器运行时之上。
<!--
## Motivation
You can set a different RuntimeClass between different Pods to provide a balance of
performance versus security. For example, if part of your workload deserves a high
level of information security assurance, you might choose to schedule those Pods so
that they run in a container runtime that uses hardware virtualization. You'd then
benefit from the extra isolation of the alternative runtime, at the expense of some
additional overhead.
You can also use RuntimeClass to run different Pods with the same container runtime
but with different settings.
-->
## 使用场景
用户可以为不同的 Pod 设定不同的 RuntimeClass ,以达到动态调整容器安全和容器性能间的平衡的目的。例如,
如果用户的一部分工作需要确保高安全性,那么可以选择调度Pod使用到硬件虚拟化的容器运行时。
受益于硬件虚拟化带来的附加的容器隔离特性的同时,也会带来性能上的额外开销。
用户也可以通过这种方式,为Pod提供不同设定的同一种容器运行时。
<!--
### Set Up
Ensure the RuntimeClass feature gate is enabled (it is by default). See [Feature
Gates](/docs/reference/command-line-tools-reference/feature-gates/) for an explanation of enabling
feature gates. The `RuntimeClass` feature gate must be enabled on apiservers _and_ kubelets.
1. Configure the CRI implementation on nodes (runtime dependent)
2. Create the corresponding RuntimeClass resources
-->
### 设定
首先要先确认 RuntimeClass 功能的 Feature Gate 被设定为开启(默认是有效状态)。设定 Feature Gate 为有效的文档请参考[Feature Gates](/docs/reference/command-line-tools-reference/feature-gates/)。
`RuntimeClass`的 Feature Gate 开启需要 ApiServer 和 kubelet 同时将相关配置开启。
1. 配置节点的 CRI。(依赖于容器运行时)
2. 创建相应的 RuntimeClass 资源。
<!--
#### 1. Configure the CRI implementation on nodes
The configurations available through RuntimeClass are Container Runtime Interface (CRI)
implementation dependent. See the corresponding documentation ([below](#cri-configuration)) for your
CRI implementation for how to configure.
-->
#### 1. 实现节点上的CRI设定。
通过 RuntimeClass 进行设定的有效化,依赖于 Container Runtime Interface (CRI) 组件。
在用户环境中,CRI 的设定方法请参考([见下面](#cri-configuration))文档。
{{< note >}}
<--
RuntimeClass assumes a homogeneous node configuration across the cluster by default (which means
that all nodes are configured the same way with respect to container runtimes). To support
heterogenous node configurations, see [Scheduling](#scheduling) below.
-->
默认情况下,RuntimeClass 被假设为所有节点上的配置均为一致。(这意味着所有的 Node 节点的容器运行时必须以相同的方式进行设定)。
要支持不同配置构节点配置,请参见下面的[Scheduling](#scheduling)。
{{< /note >}}
<!--
The configurations have a corresponding `handler` name, referenced by the RuntimeClass. The
handler must be a valid DNS 1123 label (alpha-numeric + `-` characters).
-->
配置需要具有相应的 `handler` 名称,被用于 RuntimeClass 的设定。
被定义的 Handler 名称必须是有效的 DNS-1123 标准。(只能使用英文字母,数字 和 `-`)。
<!--
#### 2. Create the corresponding RuntimeClass resources
The configurations setup in step 1 should each have an associated `handler` name, which identifies
the configuration. For each handler, create a corresponding RuntimeClass object.
The RuntimeClass resource currently only has 2 significant fields: the RuntimeClass name
(`metadata.name`) and the handler (`handler`). The object definition looks like this:
-->
#### 2. 创建对应的RuntimeClass资源
为了便于识别各个项目,安装配置的第一步需要每个项目有一个关联的 `handler` 名称。这样就可以为每个 `handler` 创建对应的 RuntimeClass 资源了。
所以当前 RuntimeClass 资源有两个重要的设定项。一个是 RuntimeClass 的名称( `metadata.name` )和 Handler (`handler`)。RuntimeClass 的资源定义可以参考下面的内容。
```yaml
apiVersion: node.k8s.io/v1beta1 # RuntimeClass is defined in the node.k8s.io API group
kind: RuntimeClass
metadata:
name: myclass # The name the RuntimeClass will be referenced by
# RuntimeClass is a non-namespaced resource
handler: myconfiguration # The name of the corresponding CRI configuration
```
{{< note >}}
<!--
It is recommended that RuntimeClass write operations (create/update/patch/delete) be
restricted to the cluster administrator. This is typically the default. See [Authorization
Overview](/docs/reference/access-authn-authz/authorization/) for more details.
-->
推荐只有集群管理员具有针对 RuntimeClass 的各项操作权限(create/update/patch/delete)。
这通常是默认值。具体内容可以[授权概况](/docs/reference/access-authn-authz/authorization/)文档了解详细信息。
{{< /note >}}
<!--
### Usage
Once RuntimeClasses are configured for the cluster, using them is very simple. Specify a
`runtimeClassName` in the Pod spec. For example:
-->
### 使用方法
一旦集群中的 RuntimeClass 的设定完成,接下来的使用就变得非常简单了。只需要设定 PodSpec 的 `runtimeClassName` 设定项。
例如:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
runtimeClassName: myclass
# ...
```
<!--
This will instruct the Kubelet to use the named RuntimeClass to run this pod. If the named
RuntimeClass does not exist, or the CRI cannot run the corresponding handler, the pod will enter the
`Failed` terminal [phase](/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase). Look for a
corresponding [event](/docs/tasks/debug-application-cluster/debug-application-introspection/) for an
error message.
If no `runtimeClassName` is specified, the default RuntimeHandler will be used, which is equivalent
to the behavior when the RuntimeClass feature is disabled.
-->
这个设定将让Kubelet使用指定的 RuntimeClass 来运行 Pod。如果 RuntimeClass 不存在, 或者 CRI 不能执行相应的 HandlerPod 将会变成`Failed`[状态](/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase)。
请参考对应的相关[事件](/docs/tasks/debug-application-cluster/debug-application-introspection/)文档,确定错误信息。
如果 `runtimeClassName` 没有被设定的情况下,将会使用默认的 RuntimeHandler,这里的运行效果和 RuntimeClass 功能被禁止的情况下是一样的。
<!--
### CRI Configuration
For more details on setting up CRI runtimes, see [CRI installation](/docs/setup/production-environment/container-runtimes/).
-->
### CRI的设定
CRI 运行时的相关设定详细内容请参考[CRI的安装](/docs/setup/cri/)。
<!--
#### dockershim
Kubernetes built-in dockershim CRI does not support runtime handlers.
-->
#### dockershim
Kubernetes 的内置 dockershim CRI 不支持容器运行时 handlers。
<!--
#### [containerd](https://containerd.io/)
Runtime handlers are configured through containerd's configuration at
`/etc/containerd/config.toml`. Valid handlers are configured under the runtimes section:
-->
#### [containerd](https://containerd.io/)
运行时 handler 可以通过 containerd 的配置文件 `/etc/containerd/config.toml` 进行设定。
有效的 handlers 被设定在 runtimes 部分的下一层级。
```
[plugins.cri.containerd.runtimes.${HANDLER_NAME}]
```
<!--
See containerd's config documentation for more details:
https://github.com/containerd/cri/blob/master/docs/config.md
-->
`containerd` 的具体设定请参考下面的文档信息。
https://github.com/containerd/cri/blob/master/docs/config.md
#### [cri-o](https://cri-o.io/)
<!--
Runtime handlers are configured through cri-o's configuration at `/etc/crio/crio.conf`. Valid
handlers are configured under the [crio.runtime
table](https://github.com/kubernetes-sigs/cri-o/blob/master/docs/crio.conf.5.md#crioruntime-table):
-->
运行时处理程序通过cri-o的配置在 `/etc/crio/crio.conf` 中进行配置。
有效的处理程序在[crio.runtime表](https://github.com/kubernetes-sigs/cri-o/blob/master/docs/crio.conf.5.md#crioruntime-table)下配置。
```
[crio.runtime.runtimes.${HANDLER_NAME}]
runtime_path = "${PATH_TO_BINARY}"
```
<!--
See cri-o's config documentation for more details:
https://github.com/kubernetes-sigs/cri-o/blob/master/cmd/crio/config.go
-->
有关更多详细信息,请参见cri-o的配置文档:
https://github.com/kubernetes-sigs/cri-o/blob/master/cmd/crio/config.go
<!--
### Scheduling
-->
### 调度
{{< feature-state for_k8s_version="v1.16" state="beta" >}}
<!--
As of Kubernetes v1.16, RuntimeClass includes support for heterogenous clusters through its
`scheduling` fields. Through the use of these fields, you can ensure that pods running with this
RuntimeClass are scheduled to nodes that support it. To use the scheduling support, you must have
the RuntimeClass [admission controller][] enabled (the default, as of 1.16).
To ensure pods land on nodes supporting a specific RuntimeClass, that set of nodes should have a
common label which is then selected by the `runtimeclass.scheduling.nodeSelector` field. The
RuntimeClass's nodeSelector is merged with the pod's nodeSelector in admission, effectively taking
the intersection of the set of nodes selected by each. If there is a conflict, the pod will be
rejected.
-->
从Kubernetes v1.16开始,RuntimeClass 通过 `scheduling` 字段添加了对异构集群的支持。
通过使用这些字段,可以确保将与此 RuntimeClass一 起运行的 Pod 调度到支持它的节点上。
要使用计划支持,您必须启用 RuntimeClass [admission controller] [](默认值,自1.16开始)。
为了确保 Pod 被调度到支持特定 RuntimeClass 的节点上,
那组节点应该具有一个公共标签,然后由 `runtimeclass.scheduling.nodeSelector` 字段选择该标签。
RuntimeClass 的 nodeSelector 在调度时与 Pod 的 nodeSelector 合并,有效地进行节点选择,并且调度到相应节点。
如果有冲突,则将拒绝该 Pod 被调度。
<!--
If the supported nodes are tainted to prevent other RuntimeClass pods from running on the node, you
can add `tolerations` to the RuntimeClass. As with the `nodeSelector`, the tolerations are merged
with the pod's tolerations in admission, effectively taking the union of the set of nodes tolerated
by each.
To learn more about configuring the node selector and tolerations, see [Assigning Pods to
Nodes](/docs/concepts/configuration/assign-pod-node/).
[admission controller]: /docs/reference/access-authn-authz/admission-controllers/
-->
如果受支持的节点被污染以防止其他 RuntimeClass 容器在该节点上运行,则可以向RuntimeClass添加 `tolerations` 设定。
`nodeSelector` 一样,容忍度在接纳时与容器的容忍度合并,从而有效地吸收了每个容忍度的节点集的并集。
要了解有关配置节点选择器和容差的更多信息,请参阅[分配 Pod 到节点](/docs/concepts/configuration/assign-pod-node/)。
[准入控制器]: /docs/reference/access-authn-authz/admission-controllers/
<!--
### Pod Overhead
-->
### Pod 开销
{{< feature-state for_k8s_version="v1.16" state="alpha" >}}
<!--
As of Kubernetes v1.16, RuntimeClass includes support for specifying overhead associated with
running a pod, as part of the [`PodOverhead`](/docs/concepts/configuration/pod-overhead.md) feature.
To use `PodOverhead`, you must have the PodOverhead [feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
enabled (it is off by default).
Pod overhead is defined in RuntimeClass through the `Overhead` fields. Through the use of these fields,
you can specify the overhead of running pods utilizing this RuntimeClass and ensure these overheads
are accounted for in Kubernetes.
-->
从 Kubernetes v1.16 开始,RuntimeClass 包含了对指定与运行 Pod 相关的开销的支持,
这是[`Pod 开销`](/docs/concepts/configuration/pod-overhead.md)功能的一部分。
要使用 `PodOverhead` ,您必须确保 PodOverhead [功能](/docs/reference/command-line-tools-reference/feature-gates/) 已启用(默认情况下处于关闭状态)。
Pod 的开销是在 RuntimeClass 中通过 `Overhead` 字段定义的。 通过使用这些字段,
您可以使用此 RuntimeClass 指定运行 Pod 的开销,并确保在Kubernetes中考虑了这些开销。
<!--
### Upgrading RuntimeClass from Alpha to Beta
The RuntimeClass Beta feature includes the following changes:
- The `node.k8s.io` API group and `runtimeclasses.node.k8s.io` resource have been migrated to a
built-in API from a CustomResourceDefinition.
- The `spec` has been inlined in the RuntimeClass definition (i.e. there is no more
RuntimeClassSpec).
- The `runtimeHandler` field has been renamed `handler`.
- The `handler` field is now required in all API versions. This means the `runtimeHandler` field in
the Alpha API is also required.
- The `handler` field must be a valid DNS label ([RFC 1123](https://tools.ietf.org/html/rfc1123)),
meaning it can no longer contain `.` characters (in all versions). Valid handlers match the
following regular expression: `^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`.
-->
### 将 RuntimeClass 从 Alpha 升级到 Beta
RuntimeClass Beta 功能包括以下更改:
- `node.k8s.io` API 组和 `runtimeclasses.node.k8s.io` 资源已从 `CustomResourceDefinition` 迁移到内置API。
- 已在 RuntimeClass 定义中内联了 `spec`(即不再有RuntimeClassSpec)。
- `runtimeHandler` 字段已重命名为 `handler`
- 所有 API 版本中现在都需要 `handler` 字段。 这意味着 Alpha API 中的 `runtimeHandler` 字段也是必须设定项。
- `handler`字段必须是有效的DNS标签([RFC 1123](https://tools.ietf.org/html/rfc1123)),这意味着它不再包含 `.` 字符(在所有版本中)。
有效的处理程序匹配以下正则表达式:`^ [a-z0-9][-a-z0-9] * [a-z0-9])?$`
<!--
**Action Required:** The following actions are required to upgrade from the alpha version of the
RuntimeClass feature to the beta version:
- RuntimeClass resources must be recreated *after* upgrading to v1.14, and the
`runtimeclasses.node.k8s.io` CRD should be manually deleted:
```
kubectl delete customresourcedefinitions.apiextensions.k8s.io runtimeclasses.node.k8s.io
```
- Alpha RuntimeClasses with an unspecified or empty `runtimeHandler` or those using a `.` character
in the handler are no longer valid, and must be migrated to a valid handler configuration (see
above).
-->
**需要采取的措施:** 要从 RuntimeClass 功能的 Alpha 版本升级到 Beta 版本,需要执行以下操作:
- 在升级到v1.14之后,必须重新创建 RuntimeClass 资源,并且应该手动删除 runtimeclasses.node.k8s.io 的 CRD
```
kubectl delete customresourcedefinitions.apiextensions.k8s.io runtimeclasses.node.k8s.io
```
- 在处理程序中具有未指定或为空的 `runtimeHandler` 字段或使用 `.` 字符的 Alpha RuntimeClass 不再有效,
必须将其迁移到有效的处理程序配置中(请参见上文)。
<!--
### Further Reading
- [RuntimeClass Design](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/runtime-class.md)
- [RuntimeClass Scheduling Design](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/runtime-class-scheduling.md)
- Read about the [Pod Overhead](/docs/concepts/configuration/pod-overhead/) concept
- [PodOverhead Feature Design](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/20190226-pod-overhead.md)
-->
### 进一步阅读
- [运行时类设计](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/runtime-class.md)
- [RuntimeClass 计划设计](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/runtime-class-scheduling.md)
- 了解有关 [Pod 开销](/docs/concepts/configuration/pod-overhead/) 概念
- [Pod 开销功能设计](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/20190226-pod-overhead.md)
{{% /capture %}}
@@ -0,0 +1,4 @@
---
title: "服务、负载均衡和联网"
weight: 80
---
@@ -1,49 +1,68 @@
--- ---
approvers:
- rickypai
- thockin
title: 使用 HostAliases 向 Pod /etc/hosts 文件添加条目 title: 使用 HostAliases 向 Pod /etc/hosts 文件添加条目
redirect_from: content_template: templates/concept
- "/docs/user-guide/add-entries-to-pod-etc-hosts-with-host-aliases/" weight: 60
- "/docs/user-guide/add-entries-to-pod-etc-hosts-with-host-aliases.md"
--- ---
{{< toc >}} {{< toc >}}
{{% capture overview %}}
<!--
Adding entries to a Pod's /etc/hosts file provides Pod-level override of hostname resolution when DNS and other options are not applicable. In 1.7, users can add these custom entries with the HostAliases field in PodSpec.
Modification not using HostAliases is not suggested because the file is managed by Kubelet and can be overwritten on during Pod creation/restart.
-->
当 DNS 配置以及其它选项不合理的时候,通过向 Pod 的 /etc/hosts 文件中添加条目,可以在 Pod 级别覆盖对主机名的解析。在 1.7 版本,用户可以通过 PodSpec 的 HostAliases 字段来添加这些自定义的条目。 当 DNS 配置以及其它选项不合理的时候,通过向 Pod 的 /etc/hosts 文件中添加条目,可以在 Pod 级别覆盖对主机名的解析。在 1.7 版本,用户可以通过 PodSpec 的 HostAliases 字段来添加这些自定义的条目。
建议通过使用 HostAliases 来进行修改,因为该文件由 Kubelet 管理,并且可以在 Pod 创建/重启过程中被重写。 建议通过使用 HostAliases 来进行修改,因为该文件由 Kubelet 管理,并且可以在 Pod 创建/重启过程中被重写。
{{% /capture %}}
{{% capture body %}}
<!--
## Default Hosts File Content
Let's start an Nginx Pod which is assigned a Pod IP:
-->
## 默认 hosts 文件内容 ## 默认 hosts 文件内容
让我们从一个 Nginx Pod 开始,给该 Pod 分配一个 IP: 让我们从一个 Nginx Pod 开始,给该 Pod 分配一个 IP:
```shell
kubectl run nginx --image nginx --generator=run-pod/v1
``` ```
$ kubectl get pods --output=wide
```shell
pod/nginx created
```
<!--
Examine a Pod IP:
-->
检查Pod IP
```shell
kubectl get pods --output=wide
```
```shell
NAME READY STATUS RESTARTS AGE IP NODE NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0 nginx 1/1 Running 0 13s 10.200.0.4 worker0
``` ```
<!--
The hosts file content would look like this:
-->
主机文件的内容如下所示:
默认,hosts 文件只包含 ipv4 和 ipv6 的样板内容,像 `localhost` 和主机名称。 ```shell
kubectl exec nginx -- cat /etc/hosts
## 通过 HostAliases 增加额外的条目
除了默认的样板内容,我们可以向 hosts 文件添加额外的条目,将 `foo.local``bar.local` 解析为`127.0.0.1`,将 `foo.remote``bar.remote` 解析为 `10.1.2.3`,我们可以在 `.spec.hostAliases` 下为 Pod 添加 HostAliases。
{{< code file="hostaliases-pod.yaml" >}}
hosts 文件的内容看起来类似如下这样:
``` ```
$ kubectl logs hostaliases-pod
```none
# Kubernetes-managed hosts file. # Kubernetes-managed hosts file.
127.0.0.1 localhost 127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback ::1 localhost ip6-localhost ip6-loopback
@@ -51,25 +70,111 @@ fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes fe00::1 ip6-allnodes
fe00::2 ip6-allrouters fe00::2 ip6-allrouters
10.200.0.4 hostaliases-pod 10.200.0.4 nginx
127.0.0.1 foo.local
127.0.0.1 bar.local
10.1.2.3 foo.remote
10.1.2.3 bar.remote
``` ```
<!--
By default, the `hosts` file only includes IPv4 and IPv6 boilerplates like
`localhost` and its own hostname.
-->
默认,hosts 文件只包含 ipv4 和 ipv6 的样板内容,像 `localhost` 和主机名称。
<!--
## Adding Additional Entries with HostAliases
In addition to the default boilerplate, we can add additional entries to the
`hosts` file to resolve `foo.local`, `bar.local` to `127.0.0.1` and `foo.remote`,
`bar.remote` to `10.1.2.3`, we can by adding HostAliases to the Pod under
`.spec.hostAliases`:
-->
## 通过 HostAliases 增加额外的条目
除了默认的样板内容,我们可以向 hosts 文件添加额外的条目,将 `foo.local``bar.local` 解析为`127.0.0.1`
`foo.remote``bar.remote` 解析为 `10.1.2.3`,我们可以在 `.spec.hostAliases` 下为 Pod 添加 HostAliases。
{{< codenew file="service/networking/hostaliases-pod.yaml" >}}
<!--
This Pod can be started with the following commands:
-->
可以使用以下命令启动此Pod
```shell
kubectl apply -f hostaliases-pod.yaml
```
```shell
pod/hostaliases-pod created
```
<!--
Examine a Pod IP and status:
-->
检查Pod IP 和状态:
```shell
kubectl get pod --output=wide
```
```shell
NAME READY STATUS RESTARTS AGE IP NODE
hostaliases-pod 0/1 Completed 0 6s 10.200.0.5 worker0
```
<!--
The `hosts` file content would look like this:
-->
hosts 文件的内容看起来类似如下这样:
```shell
kubectl logs hostaliases-pod
```
```none
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.200.0.5 hostaliases-pod
# Entries added by HostAliases.
127.0.0.1 foo.local bar.local
10.1.2.3 foo.remote bar.remote
```
<!--
With the additional entries specified at the bottom.
-->
在最下面额外添加了一些条目。 在最下面额外添加了一些条目。
## 限制 <!--
With the additional entries specified at the bottom.
在 1.7 版本,如果 Pod 启用 hostNetwork,那么将不能使用这个特性,因为 kubelet 只管理非 hostNetwork 类型 Pod 的 hosts 文件。目前正在讨论要改变这个情况。 ## Why Does Kubelet Manage the Hosts File?
Kubelet [manages](https://github.com/kubernetes/kubernetes/issues/14633) the
`hosts` file for each container of the Pod to prevent Docker from
[modifying](https://github.com/moby/moby/issues/17190) the file after the
containers have already been started.
Because of the managed-nature of the file, any user-written content will be
overwritten whenever the `hosts` file is remounted by Kubelet in the event of
a container restart or a Pod reschedule. Thus, it is not suggested to modify
the contents of the file.
-->
## 为什么 Kubelet 管理 hosts文件? ## 为什么 Kubelet 管理 hosts文件?
kubelet [管理](https://github.com/kubernetes/kubernetes/issues/14633) Pod 中每个容器的 hosts 文件,避免 Docker 在容器已经启动之后去 [修改](https://github.com/moby/moby/issues/17190) 该文件。 kubelet [管理](https://github.com/kubernetes/kubernetes/issues/14633) Pod 中每个容器的 hosts 文件,避免 Docker 在容器已经启动之后去 [修改](https://github.com/moby/moby/issues/17190) 该文件。
因为该文件是托管性质的文件,无论容器重启或 Pod 重新调度,用户修改该 hosts 文件的任何内容,都会在 Kubelet 重新安装后被覆盖。因此,不建议修改该文件的内容。 因为该文件是托管性质的文件,无论容器重启或 Pod 重新调度,用户修改该 hosts 文件的任何内容,都会在 Kubelet 重新安装后被覆盖。因此,不建议修改该文件的内容。
{{% /capture %}}
@@ -1,14 +1,23 @@
--- ---
approvers:
- caesarxuchao
- lavalamp
- thockin
title: 应用连接到 Service title: 应用连接到 Service
content_template: templates/concept
weight: 30
--- ---
{{< toc >}}
{{% capture overview %}}
<!--
## The Kubernetes model for connecting containers
Now that you have a continuously running, replicated application you can expose it on a network. Before discussing the Kubernetes approach to networking, it is worthwhile to contrast it with the "normal" way networking works with Docker.
By default, Docker uses host-private networking, so containers can talk to other containers only if they are on the same machine. In order for Docker containers to communicate across nodes, there must be allocated ports on the machines own IP address, which are then forwarded or proxied to the containers. This obviously means that containers must either coordinate which ports they use very carefully or ports must be allocated dynamically.
Coordinating ports across multiple developers is very difficult to do at scale and exposes users to cluster-level issues outside of their control. Kubernetes assumes that pods can communicate with other pods, regardless of which host they land on. We give every pod its own cluster-private-IP address so you do not need to explicitly create links between pods or map container ports to host ports. This means that containers within a Pod can all reach each other's ports on localhost, and all pods in a cluster can see each other without NAT. The rest of this document will elaborate on how you can run reliable services on such a networking model.
This guide uses a simple nginx server to demonstrate proof of concept. The same principles are embodied in a more complete [Jenkins CI application](https://kubernetes.io/blog/2015/07/strong-simple-ssl-for-kubernetes).
-->
## Kubernetes 连接容器模型 ## Kubernetes 连接容器模型
@@ -29,37 +38,57 @@ Kubernetes 假设 Pod 可与其它 Pod 通信,不管它们在哪个主机上
该指南使用一个简单的 Nginx server 来演示并证明谈到的概念。同样的原则也体现在一个更加完整的 [Jenkins CI 应用](http://kubernetes.io/blog/2015/07/strong-simple-ssl-for-kubernetes.html) 中。 该指南使用一个简单的 Nginx server 来演示并证明谈到的概念。同样的原则也体现在一个更加完整的 [Jenkins CI 应用](http://kubernetes.io/blog/2015/07/strong-simple-ssl-for-kubernetes.html) 中。
{{% /capture %}}
{{% capture body %}}
<!--
## Exposing pods to the cluster
We did this in a previous example, but let's do it once again and focus on the networking perspective.
Create an nginx Pod, and note that it has a container port specification:
-->
## 在集群中暴露 Pod ## 在集群中暴露 Pod
我们在之前的示例中已经做过,然而再让我重试一次,这次聚焦在网络连接的视角。 我们在之前的示例中已经做过,然而再让我重试一次,这次聚焦在网络连接的视角。
创建一个 Nginx Pod,指示它具有一个容器端口的说明: 创建一个 Nginx Pod,指示它具有一个容器端口的说明:
{{< code file="run-my-nginx.yaml" >}} {{< codenew file="service/networking/run-my-nginx.yaml" >}}
<!--
This makes it accessible from any node in your cluster. Check the nodes the Pod is running on:
-->
这使得可以从集群中任何一个节点来访问它。检查节点,该 Pod 正在运行: 这使得可以从集群中任何一个节点来访问它。检查节点,该 Pod 正在运行:
```shell ```shell
$ kubectl create -f ./run-my-nginx.yaml kubectl apply -f ./run-my-nginx.yaml
$ kubectl get pods -l run=my-nginx -o wide kubectl get pods -l run=my-nginx -o wide
```
```
NAME READY STATUS RESTARTS AGE IP NODE NAME READY STATUS RESTARTS AGE IP NODE
my-nginx-3800858182-jr4a2 1/1 Running 0 13s 10.244.3.4 kubernetes-minion-905m my-nginx-3800858182-jr4a2 1/1 Running 0 13s 10.244.3.4 kubernetes-minion-905m
my-nginx-3800858182-kna2y 1/1 Running 0 13s 10.244.2.5 kubernetes-minion-ljyd my-nginx-3800858182-kna2y 1/1 Running 0 13s 10.244.2.5 kubernetes-minion-ljyd
``` ```
<!--
Check your pods' IPs:
-->
检查 Pod 的 IP 地址: 检查 Pod 的 IP 地址:
```shell ```shell
$ kubectl get pods -l run=my-nginx -o yaml | grep podIP kubectl get pods -l run=my-nginx -o yaml | grep podIP
podIP: 10.244.3.4 podIP: 10.244.3.4
podIP: 10.244.2.5 podIP: 10.244.2.5
``` ```
<!--
You should be able to ssh into any node in your cluster and curl both IPs. Note that the containers are *not* using port 80 on the node, nor are there any special NAT rules to route traffic to the pod. This means you can run multiple nginx pods on the same node all using the same containerPort and access them from any other pod or node in your cluster using IP. Like Docker, ports can still be published to the host node's interfaces, but the need for this is radically diminished because of the networking model.
You can read more about [how we achieve this](/docs/concepts/cluster-administration/networking/#how-to-achieve-this) if you're curious.
-->
应该能够通过 ssh 登录到集群中的任何一个节点上,使用 curl 也能调通所有 IP 地址。 应该能够通过 ssh 登录到集群中的任何一个节点上,使用 curl 也能调通所有 IP 地址。
需要注意的是,容器不会使用该节点上的 80 端口,也不会使用任何特定的 NAT 规则去路由流量到 Pod 上。 需要注意的是,容器不会使用该节点上的 80 端口,也不会使用任何特定的 NAT 规则去路由流量到 Pod 上。
@@ -69,6 +98,15 @@ $ kubectl get pods -l run=my-nginx -o yaml | grep podIP
如果对此好奇,可以获取更多关于 [如何实现网络模型](/docs/concepts/cluster-administration/networking/#how-to-achieve-this) 的内容。 如果对此好奇,可以获取更多关于 [如何实现网络模型](/docs/concepts/cluster-administration/networking/#how-to-achieve-this) 的内容。
<!--
## Creating a Service
So we have pods running nginx in a flat, cluster wide, address space. In theory, you could talk to these pods directly, but what happens when a node dies? The pods die with it, and the Deployment will create new ones, with different IPs. This is the problem a Service solves.
A Kubernetes Service is an abstraction which defines a logical set of Pods running somewhere in your cluster, that all provide the same functionality. When created, each Service is assigned a unique IP address (also called clusterIP). This address is tied to the lifespan of the Service, and will not change while the Service is alive. Pods can be configured to talk to the Service, and know that communication to the Service will be automatically load-balanced out to some pod that is a member of the Service.
You can create a Service for your 2 nginx replicas with `kubectl expose`:
-->
## 创建 Service ## 创建 Service
@@ -83,28 +121,52 @@ Kubernetes Service 从逻辑上定义了运行在集群中的一组 Pod,这些
可以使用 `kubectl expose` 命令为 2个 Nginx 副本创建一个 Service 可以使用 `kubectl expose` 命令为 2个 Nginx 副本创建一个 Service
```shell ```shell
$ kubectl expose deployment/my-nginx kubectl expose deployment/my-nginx
service "my-nginx" exposed ```
```
service/my-nginx exposed
``` ```
<!--
This is equivalent to `kubectl apply -f` the following yaml:
-->
这等价于使用 `kubectl create -f` 命令创建,对应如下的 yaml 文件: 这等价于使用 `kubectl create -f` 命令创建,对应如下的 yaml 文件:
{{< code file="nginx-svc.yaml" >}} {{< codenew file="service/networking/nginx-svc.yaml" >}}
<!--
This specification will create a Service which targets TCP port 80 on any Pod
with the `run: my-nginx` label, and expose it on an abstracted Service port
(`targetPort`: is the port the container accepts traffic on, `port`: is the
abstracted Service port, which can be any port other pods use to access the
Service).
View [Service](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core)
API object to see the list of supported fields in service definition.
Check your Service:
-->
上述规约将创建一个 Service,对应具有标签 `run: my-nginx` 的 Pod,目标 TCP 端口 80,并且在一个抽象的 Service 端口(`targetPort`:容器接收流量的端口;`port`:抽象的 Service 端口,可以使任何其它 Pod 访问该 Service 的端口)上暴露。 上述规约将创建一个 Service,对应具有标签 `run: my-nginx` 的 Pod,目标 TCP 端口 80,并且在一个抽象的 Service 端口(`targetPort`:容器接收流量的端口;`port`:抽象的 Service 端口,可以使任何其它 Pod 访问该 Service 的端口)上暴露。
查看 [Service API 对象](/docs/api-reference/{{< param "version" >}}/#service-v1-core) 了解 Service 定义支持的字段列表。 查看 [Service API 对象](/docs/api-reference/{{< param "version" >}}/#service-v1-core) 了解 Service 定义支持的字段列表。
查看你的 Service 资源:
```shell ```shell
$ kubectl get svc my-nginx kubectl get svc my-nginx
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE ```
my-nginx 10.0.162.149 <none> 80/TCP 21s ```
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx ClusterIP 10.0.162.149 <none> 80/TCP 21s
``` ```
<!--
As mentioned previously, a Service is backed by a group of Pods. These Pods are
exposed through `endpoints`. The Service's selector will be evaluated continuously
and the results will be POSTed to an Endpoints object also named `my-nginx`.
When a Pod dies, it is automatically removed from the endpoints, and new Pods
matching the Service's selector will automatically get added to the endpoints.
Check the endpoints, and note that the IPs are the same as the Pods created in
the first step:
-->
正如前面所提到的,一个 Service 由一组 backend Pod 组成。这些 Pod 通过 `endpoints` 暴露出来。 正如前面所提到的,一个 Service 由一组 backend Pod 组成。这些 Pod 通过 `endpoints` 暴露出来。
Service Selector 将持续评估,结果被 POST 到一个名称为 `my-nginx` 的 Endpoint 对象上。 Service Selector 将持续评估,结果被 POST 到一个名称为 `my-nginx` 的 Endpoint 对象上。
@@ -112,48 +174,98 @@ Service Selector 将持续评估,结果被 POST 到一个名称为 `my-nginx`
检查该 Endpoint,注意到 IP 地址与在第一步创建的 Pod 是相同的。 检查该 Endpoint,注意到 IP 地址与在第一步创建的 Pod 是相同的。
```shell ```shell
$ kubectl describe svc my-nginx kubectl describe svc my-nginx
```
```
Name: my-nginx Name: my-nginx
Namespace: default Namespace: default
Labels: run=my-nginx Labels: run=my-nginx
Annotations: <none>
Selector: run=my-nginx Selector: run=my-nginx
Type: ClusterIP Type: ClusterIP
IP: 10.0.162.149 IP: 10.0.162.149
Port: <unset> 80/TCP Port: <unset> 80/TCP
Endpoints: 10.244.2.5:80,10.244.3.4:80 Endpoints: 10.244.2.5:80,10.244.3.4:80
Session Affinity: None Session Affinity: None
No events. Events: <none>
```
$ kubectl get ep my-nginx ```shell
kubectl get ep my-nginx
```
```
NAME ENDPOINTS AGE NAME ENDPOINTS AGE
my-nginx 10.244.2.5:80,10.244.3.4:80 1m my-nginx 10.244.2.5:80,10.244.3.4:80 1m
``` ```
<!--
You should now be able to curl the nginx Service on `<CLUSTER-IP>:<PORT>` from
any node in your cluster. Note that the Service IP is completely virtual, it
never hits the wire. If you're curious about how this works you can read more
about the [service proxy](/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies).
-->
现在,能够从集群中任意节点上使用 curl 命令请求 Nginx Service `<CLUSTER-IP>:<PORT>` 现在,能够从集群中任意节点上使用 curl 命令请求 Nginx Service `<CLUSTER-IP>:<PORT>`
注意 Service IP 完全是虚拟的,它从来没有走过网络,如果对它如何工作的原理感到好奇,可以阅读更多关于 [服务代理](/docs/user-guide/services/#virtual-ips-and-service-proxies) 的内容。 注意 Service IP 完全是虚拟的,它从来没有走过网络,如果对它如何工作的原理感到好奇,
可以阅读更多关于 [服务代理](/docs/user-guide/services/#virtual-ips-and-service-proxies) 的内容。
<!--
## Accessing the Service
Kubernetes supports 2 primary modes of finding a Service - environment variables
and DNS. The former works out of the box while the latter requires the
[CoreDNS cluster addon](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/coredns).
-->
## 访问 Service ## 访问 Service
Kubernetes 支持两种主要的服务发现模式 —— 环境变量和 DNS。前者在单个节点上可用使用,而后者必须使用 [kube-dns 集群插件](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/README.md)。 Kubernetes支持两种查找服务的主要模式: 环境变量和DNS。 前者开箱即用,而后者则需要[CoreDNS集群插件]
[CoreDNS 集群插件](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/coredns).
{{< note >}}
<!--
If the service environment variables are not desired (because possible clashing with expected program ones,
too many variables to process, only using DNS, etc) you can disable this mode by setting the `enableServiceLinks`
flag to `false` on the [pod spec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core).
-->
如果不需要服务环境变量(因为可能与预期的程序冲突,可能要处理的变量太多,或者仅使用DNS等),则可以通过在
[pod spec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core)上将 `enableServiceLinks` 标志设置为 `false` 来禁用此模式。
{{< /note >}}
<!--
### Environment Variables
When a Pod runs on a Node, the kubelet adds a set of environment variables for
each active Service. This introduces an ordering problem. To see why, inspect
the environment of your running nginx Pods (your Pod name will be different):
-->
### 环境变量 ### 环境变量
当 Pod 在 Node 上运行时,kubelet 会为每个活跃的 Service 添加一组环境变量。这会有一个顺序的问题。想了解为何,检查正在运行的 Nginx Pod 的环境变量(Pod 名称将不会相同): 当 Pod 在 Node 上运行时,kubelet 会为每个活跃的 Service 添加一组环境变量。
这会有一个顺序的问题。想了解为何,检查正在运行的 Nginx Pod 的环境变量(Pod 名称将不会相同):
```shell ```shell
$ kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE
```
```
KUBERNETES_SERVICE_HOST=10.0.0.1 KUBERNETES_SERVICE_HOST=10.0.0.1
KUBERNETES_SERVICE_PORT=443 KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_SERVICE_PORT_HTTPS=443
``` ```
<!--
Note there's no mention of your Service. This is because you created the replicas
before the Service. Another disadvantage of doing this is that the scheduler might
put both Pods on the same machine, which will take your entire Service down if
it dies. We can do this the right way by killing the 2 Pods and waiting for the
Deployment to recreate them. This time around the Service exists *before* the
replicas. This will give you scheduler-level Service spreading of your Pods
(provided all your nodes have equal capacity), as well as the right environment
variables:
-->
注意,还没有谈及到 Service。这是因为创建副本先于 Service。 注意,还没有谈及到 Service。这是因为创建副本先于 Service。
这样做的另一个缺点是,调度器可能在同一个机器上放置所有 Pod,如果该机器宕机则所有的 Service 都会挂掉。 这样做的另一个缺点是,调度器可能在同一个机器上放置所有 Pod,如果该机器宕机则所有的 Service 都会挂掉。
@@ -161,20 +273,26 @@ KUBERNETES_SERVICE_PORT_HTTPS=443
这次 Service 会 *先于* 副本存在。这将实现调度器级别的 Service,能够使 Pod 分散创建(假定所有的 Node 都具有同样的容量),以及正确的环境变量: 这次 Service 会 *先于* 副本存在。这将实现调度器级别的 Service,能够使 Pod 分散创建(假定所有的 Node 都具有同样的容量),以及正确的环境变量:
```shell ```shell
$ kubectl scale deployment my-nginx --replicas=0; kubectl scale deployment my-nginx --replicas=2; kubectl scale deployment my-nginx --replicas=0; kubectl scale deployment my-nginx --replicas=2;
$ kubectl get pods -l run=my-nginx -o wide kubectl get pods -l run=my-nginx -o wide
```
```
NAME READY STATUS RESTARTS AGE IP NODE NAME READY STATUS RESTARTS AGE IP NODE
my-nginx-3800858182-e9ihh 1/1 Running 0 5s 10.244.2.7 kubernetes-minion-ljyd my-nginx-3800858182-e9ihh 1/1 Running 0 5s 10.244.2.7 kubernetes-minion-ljyd
my-nginx-3800858182-j4rm4 1/1 Running 0 5s 10.244.3.8 kubernetes-minion-905m my-nginx-3800858182-j4rm4 1/1 Running 0 5s 10.244.3.8 kubernetes-minion-905m
``` ```
<!--
You may notice that the pods have different names, since they are killed and recreated.
-->
可能注意到,Pod 具有不同的名称,因为它们被杀掉后并被重新创建。 可能注意到,Pod 具有不同的名称,因为它们被杀掉后并被重新创建。
```shell ```shell
$ kubectl exec my-nginx-3800858182-e9ihh -- printenv | grep SERVICE kubectl exec my-nginx-3800858182-e9ihh -- printenv | grep SERVICE
```
```
KUBERNETES_SERVICE_PORT=443 KUBERNETES_SERVICE_PORT=443
MY_NGINX_SERVICE_HOST=10.0.162.149 MY_NGINX_SERVICE_HOST=10.0.162.149
KUBERNETES_SERVICE_HOST=10.0.0.1 KUBERNETES_SERVICE_HOST=10.0.0.1
@@ -184,29 +302,44 @@ KUBERNETES_SERVICE_PORT_HTTPS=443
### DNS ### DNS
<!--
Kubernetes offers a DNS cluster addon Service that automatically assigns dns names to other Services. You can check if it's running on your cluster:
-->
Kubernetes 提供了一个 DNS 插件 Service,它使用 skydns 自动为其它 Service 指派 DNS 名字。 Kubernetes 提供了一个 DNS 插件 Service,它使用 skydns 自动为其它 Service 指派 DNS 名字。
如果它在集群中处于运行状态,可以通过如下命令来检查: 如果它在集群中处于运行状态,可以通过如下命令来检查:
```shell ```shell
$ kubectl get services kube-dns --namespace=kube-system kubectl get services kube-dns --namespace=kube-system
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE ```
kube-dns 10.0.0.10 <none> 53/UDP,53/TCP 8m ```
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.0.0.10 <none> 53/UDP,53/TCP 8m
``` ```
<!--
If it isn't running, you can [enable it](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/kube-dns/README.md#how-do-i-configure-it).
The rest of this section will assume you have a Service with a long lived IP
(my-nginx), and a DNS server that has assigned a name to that IP (the CoreDNS
cluster addon), so you can talk to the Service from any pod in your cluster using
standard methods (e.g. gethostbyname). Let's run another curl application to test this:
-->
如果没有在运行,可以 [启用它](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/kube-dns/README.md#how-do-i-configure-it)。
如果没有在运行,可以 [启用它](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/README.md#how-do-i-configure-it)。
本段剩余的内容,将假设已经有一个 Service,它具有一个长久存在的 IP(my-nginx),一个为该 IP 指派名称的 DNS 服务器(kube-dns 集群插件),所以可以通过标准做法,使在集群中的任何 Pod 都能与该 Service 通信(例如:gethostbyname)。 本段剩余的内容,将假设已经有一个 Service,它具有一个长久存在的 IP(my-nginx),一个为该 IP 指派名称的 DNS 服务器(kube-dns 集群插件),所以可以通过标准做法,使在集群中的任何 Pod 都能与该 Service 通信(例如:gethostbyname)。
让我们运行另一个 curl 应用来进行测试: 让我们运行另一个 curl 应用来进行测试:
```shell ```shell
$ kubectl run curl --image=radial/busyboxplus:curl -i --tty kubectl run curl --image=radial/busyboxplus:curl -i --tty
```
```
Waiting for pod default/curl-131556218-9fnch to be running, status is Pending, pod ready: false Waiting for pod default/curl-131556218-9fnch to be running, status is Pending, pod ready: false
Hit enter for command prompt Hit enter for command prompt
``` ```
<!--
Then, hit enter and run `nslookup my-nginx`:
-->
然后,按回车并执行命令 `nslookup my-nginx` 然后,按回车并执行命令 `nslookup my-nginx`
@@ -219,14 +352,22 @@ Name: my-nginx
Address 1: 10.0.162.149 Address 1: 10.0.162.149
``` ```
<!--
## Securing the Service
Till now we have only accessed the nginx server from within the cluster. Before exposing the Service to the internet, you want to make sure the communication channel is secure. For this, you will need:
* Self signed certificates for https (unless you already have an identity certificate)
* An nginx server configured to use the certificates
* A [secret](/docs/concepts/configuration/secret/) that makes the certificates accessible to pods
You can acquire all these from the [nginx https example](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/https-nginx/). This requires having go and make tools installed. If you don't want to install those, then follow the manual steps later. In short:
-->
## Service 安全 ## Service 安全
到现在为止,我们只在集群内部访问了 Nginx server。在将 Service 暴露到 Internet 之前,我们希望确保通信信道是安全的。对于这可能需要: 到现在为止,我们只在集群内部访问了 Nginx server。在将 Service 暴露到 Internet 之前,我们希望确保通信信道是安全的。对于这可能需要:
* https 自签名证书(除非已经有了一个识别身份的证书) * https 自签名证书(除非已经有了一个识别身份的证书)
* 使用证书配置的 Nginx server * 使用证书配置的 Nginx server
* 使证书可以访问 Pod 的[秘钥](/docs/user-guide/secrets) * 使证书可以访问 Pod 的[秘钥](/docs/user-guide/secrets)
@@ -234,66 +375,144 @@ Address 1: 10.0.162.149
可以从 [Nginx https 示例](https://github.com/kubernetes/kubernetes/tree/{{< param "githubbranch" >}}/examples/https-nginx/) 获取所有上述内容,简明示例如下: 可以从 [Nginx https 示例](https://github.com/kubernetes/kubernetes/tree/{{< param "githubbranch" >}}/examples/https-nginx/) 获取所有上述内容,简明示例如下:
```shell ```shell
$ make keys secret KEY=/tmp/nginx.key CERT=/tmp/nginx.crt SECRET=/tmp/secret.json make keys secret KEY=/tmp/nginx.key CERT=/tmp/nginx.crt SECRET=/tmp/secret.json
$ kubectl create -f /tmp/secret.json kubectl apply -f /tmp/secret.json
secret "nginxsecret" created ```
$ kubectl get secrets ```
secret/nginxsecret created
```
```shell
kubectl get secrets
```
```
NAME TYPE DATA AGE NAME TYPE DATA AGE
default-token-il9rc kubernetes.io/service-account-token 1 1d default-token-il9rc kubernetes.io/service-account-token 1 1d
nginxsecret Opaque 2 1m nginxsecret Opaque 2 1m
``` ```
<!--
Following are the manual steps to follow in case you run into problems running make (on windows for example):
-->
以下是您在运行make时遇到问题时要遵循的手动步骤(例如,在Windows上):
```shell
#create a public private key pair
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /d/tmp/nginx.key -out /d/tmp/nginx.crt -subj "/CN=my-nginx/O=my-nginx"
#convert the keys to base64 encoding
cat /d/tmp/nginx.crt | base64
cat /d/tmp/nginx.key | base64
```
<!--
Use the output from the previous commands to create a yaml file as follows. The base64 encoded value should all be on a single line.
-->
使用前面命令的输出来创建yaml文件,如下所示。 base64编码的值应全部放在一行上。
```yaml
apiVersion: "v1"
kind: "Secret"
metadata:
name: "nginxsecret"
namespace: "default"
data:
nginx.crt: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURIekNDQWdlZ0F3SUJBZ0lKQUp5M3lQK0pzMlpJTUEwR0NTcUdTSWIzRFFFQkJRVUFNQ1l4RVRBUEJnTlYKQkFNVENHNW5hVzU0YzNaak1SRXdEd1lEVlFRS0V3aHVaMmx1ZUhOMll6QWVGdzB4TnpFd01qWXdOekEzTVRKYQpGdzB4T0RFd01qWXdOekEzTVRKYU1DWXhFVEFQQmdOVkJBTVRDRzVuYVc1NGMzWmpNUkV3RHdZRFZRUUtFd2h1CloybHVlSE4yWXpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSjFxSU1SOVdWM0IKMlZIQlRMRmtobDRONXljMEJxYUhIQktMSnJMcy8vdzZhU3hRS29GbHlJSU94NGUrMlN5ajBFcndCLzlYTnBwbQppeW1CL3JkRldkOXg5UWhBQUxCZkVaTmNiV3NsTVFVcnhBZW50VWt1dk1vLzgvMHRpbGhjc3paenJEYVJ4NEo5Ci82UVRtVVI3a0ZTWUpOWTVQZkR3cGc3dlVvaDZmZ1Voam92VG42eHNVR0M2QURVODBpNXFlZWhNeVI1N2lmU2YKNHZpaXdIY3hnL3lZR1JBRS9mRTRqakxCdmdONjc2SU90S01rZXV3R0ljNDFhd05tNnNTSzRqYUNGeGpYSnZaZQp2by9kTlEybHhHWCtKT2l3SEhXbXNhdGp4WTRaNVk3R1ZoK0QrWnYvcW1mMFgvbVY0Rmo1NzV3ajFMWVBocWtsCmdhSXZYRyt4U1FVQ0F3RUFBYU5RTUU0d0hRWURWUjBPQkJZRUZPNG9OWkI3YXc1OUlsYkROMzhIYkduYnhFVjcKTUI4R0ExVWRJd1FZTUJhQUZPNG9OWkI3YXc1OUlsYkROMzhIYkduYnhFVjdNQXdHQTFVZEV3UUZNQU1CQWY4dwpEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBRVhTMW9FU0lFaXdyMDhWcVA0K2NwTHI3TW5FMTducDBvMm14alFvCjRGb0RvRjdRZnZqeE04Tzd2TjB0clcxb2pGSW0vWDE4ZnZaL3k4ZzVaWG40Vm8zc3hKVmRBcStNZC9jTStzUGEKNmJjTkNUekZqeFpUV0UrKzE5NS9zb2dmOUZ3VDVDK3U2Q3B5N0M3MTZvUXRUakViV05VdEt4cXI0Nk1OZWNCMApwRFhWZmdWQTRadkR4NFo3S2RiZDY5eXM3OVFHYmg5ZW1PZ05NZFlsSUswSGt0ejF5WU4vbVpmK3FqTkJqbWZjCkNnMnlwbGQ0Wi8rUUNQZjl3SkoybFIrY2FnT0R4elBWcGxNSEcybzgvTHFDdnh6elZPUDUxeXdLZEtxaUMwSVEKQ0I5T2wwWW5scE9UNEh1b2hSUzBPOStlMm9KdFZsNUIyczRpbDlhZ3RTVXFxUlU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
nginx.key: "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2RhaURFZlZsZHdkbFIKd1V5eFpJWmVEZWNuTkFhbWh4d1NpeWF5N1AvOE9ta3NVQ3FCWmNpQ0RzZUh2dGtzbzlCSzhBZi9WemFhWm9zcApnZjYzUlZuZmNmVUlRQUN3WHhHVFhHMXJKVEVGSzhRSHA3VkpMcnpLUC9QOUxZcFlYTE0yYzZ3MmtjZUNmZitrCkU1bEVlNUJVbUNUV09UM3c4S1lPNzFLSWVuNEZJWTZMMDUrc2JGQmd1Z0ExUE5JdWFubm9UTWtlZTRuMG4rTDQKb3NCM01ZUDhtQmtRQlAzeE9JNHl3YjREZXUraURyU2pKSHJzQmlIT05Xc0RadXJFaXVJMmdoY1kxeWIyWHI2UAozVFVOcGNSbC9pVG9zQngxcHJHclk4V09HZVdPeGxZZmcvbWIvNnBuOUYvNWxlQlkrZStjSTlTMkQ0YXBKWUdpCkwxeHZzVWtGQWdNQkFBRUNnZ0VBZFhCK0xkbk8ySElOTGo5bWRsb25IUGlHWWVzZ294RGQwci9hQ1Zkank4dlEKTjIwL3FQWkUxek1yall6Ry9kVGhTMmMwc0QxaTBXSjdwR1lGb0xtdXlWTjltY0FXUTM5SjM0VHZaU2FFSWZWNgo5TE1jUHhNTmFsNjRLMFRVbUFQZytGam9QSFlhUUxLOERLOUtnNXNrSE5pOWNzMlY5ckd6VWlVZWtBL0RBUlBTClI3L2ZjUFBacDRuRWVBZmI3WTk1R1llb1p5V21SU3VKdlNyblBESGtUdW1vVlVWdkxMRHRzaG9reUxiTWVtN3oKMmJzVmpwSW1GTHJqbGtmQXlpNHg0WjJrV3YyMFRrdWtsZU1jaVlMbjk4QWxiRi9DSmRLM3QraTRoMTVlR2ZQegpoTnh3bk9QdlVTaDR2Q0o3c2Q5TmtEUGJvS2JneVVHOXBYamZhRGR2UVFLQmdRRFFLM01nUkhkQ1pKNVFqZWFKClFGdXF4cHdnNzhZTjQyL1NwenlUYmtGcVFoQWtyczJxWGx1MDZBRzhrZzIzQkswaHkzaE9zSGgxcXRVK3NHZVAKOWRERHBsUWV0ODZsY2FlR3hoc0V0L1R6cEdtNGFKSm5oNzVVaTVGZk9QTDhPTm1FZ3MxMVRhUldhNzZxelRyMgphRlpjQ2pWV1g0YnRSTHVwSkgrMjZnY0FhUUtCZ1FEQmxVSUUzTnNVOFBBZEYvL25sQVB5VWs1T3lDdWc3dmVyClUycXlrdXFzYnBkSi9hODViT1JhM05IVmpVM25uRGpHVHBWaE9JeXg5TEFrc2RwZEFjVmxvcG9HODhXYk9lMTAKMUdqbnkySmdDK3JVWUZiRGtpUGx1K09IYnRnOXFYcGJMSHBzUVpsMGhucDBYSFNYVm9CMUliQndnMGEyOFVadApCbFBtWmc2d1BRS0JnRHVIUVV2SDZHYTNDVUsxNFdmOFhIcFFnMU16M2VvWTBPQm5iSDRvZUZKZmcraEppSXlnCm9RN3hqWldVR3BIc3AyblRtcHErQWlSNzdyRVhsdlhtOElVU2FsbkNiRGlKY01Pc29RdFBZNS9NczJMRm5LQTQKaENmL0pWb2FtZm1nZEN0ZGtFMXNINE9MR2lJVHdEbTRpb0dWZGIwMllnbzFyb2htNUpLMUI3MkpBb0dBUW01UQpHNDhXOTVhL0w1eSt5dCsyZ3YvUHM2VnBvMjZlTzRNQ3lJazJVem9ZWE9IYnNkODJkaC8xT2sybGdHZlI2K3VuCnc1YytZUXRSTHlhQmd3MUtpbGhFZDBKTWU3cGpUSVpnQWJ0LzVPbnlDak9OVXN2aDJjS2lrQ1Z2dTZsZlBjNkQKckliT2ZIaHhxV0RZK2Q1TGN1YSt2NzJ0RkxhenJsSlBsRzlOZHhrQ2dZRUF5elIzT3UyMDNRVVV6bUlCRkwzZAp4Wm5XZ0JLSEo3TnNxcGFWb2RjL0d5aGVycjFDZzE2MmJaSjJDV2RsZkI0VEdtUjZZdmxTZEFOOFRwUWhFbUtKCnFBLzVzdHdxNWd0WGVLOVJmMWxXK29xNThRNTBxMmk1NVdUTThoSDZhTjlaMTltZ0FGdE5VdGNqQUx2dFYxdEYKWSs4WFJkSHJaRnBIWll2NWkwVW1VbGc9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K"
```
<!--
Now create the secrets using the file:
-->
现在使用文件创建 secrets
```shell
kubectl apply -f nginxsecrets.yaml
kubectl get secrets
```
```
NAME TYPE DATA AGE
default-token-il9rc kubernetes.io/service-account-token 1 1d
nginxsecret Opaque 2 1m
```
<!--
Now modify your nginx replicas to start an https server using the certificate in the secret, and the Service, to expose both ports (80 and 443):
-->
现在修改 Nginx 副本,启动一个使用在秘钥中的证书的 https 服务器和 Servcie,都暴露端口(80 和 443): 现在修改 Nginx 副本,启动一个使用在秘钥中的证书的 https 服务器和 Servcie,都暴露端口(80 和 443):
{{< code file="nginx-secure-app.yaml" >}} {{< codenew file="service/networking/nginx-secure-app.yaml" >}}
<!--
Noteworthy points about the nginx-secure-app manifest:
- It contains both Deployment and Service specification in the same file.
- The [nginx server](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/https-nginx/default.conf)
serves HTTP traffic on port 80 and HTTPS traffic on 443, and nginx Service
exposes both ports.
- Each container has access to the keys through a volume mounted at `/etc/nginx/ssl`.
This is setup *before* the nginx server is started.
-->
关于 nginx-secure-app manifest 值得注意的点如下: 关于 nginx-secure-app manifest 值得注意的点如下:
- 它在相同的文件中包含了 Deployment 和 Service 的规格 - 它在相同的文件中包含了 Deployment 和 Service 的规格
- [Nginx server](https://github.com/kubernetes/kubernetes/tree/{{< param "githubbranch" >}}/examples/https-nginx/default.conf) 处理 80 端口上的 http 流量,以及 443 端口上的 https 流量,Nginx Service 暴露了这两个端口。 - [Nginx server](https://github.com/kubernetes/kubernetes/tree/{{< param "githubbranch" >}}/examples/https-nginx/default.conf) 处理 80 端口上的 http 流量,以及 443 端口上的 https 流量,Nginx Service 暴露了这两个端口。
- 每个容器访问挂载在 /etc/nginx/ssl 卷上的秘钥。这需要在 Nginx server 启动之前安装好。 - 每个容器访问挂载在 /etc/nginx/ssl 卷上的秘钥。这需要在 Nginx server 启动之前安装好。
```shell ```shell
$ kubectl delete deployments,svc my-nginx; kubectl create -f ./nginx-secure-app.yaml kubectl delete deployments,svc my-nginx; kubectl create -f ./nginx-secure-app.yaml
``` ```
<!--
At this point you can reach the nginx server from any node.
-->
这时可以从任何节点访问到 Nginx server。 这时可以从任何节点访问到 Nginx server。
```shell ```shell
$ kubectl get pods -o yaml | grep -i podip kubectl get pods -o yaml | grep -i podip
podIP: 10.244.3.5 podIP: 10.244.3.5
node $ curl -k https://10.244.3.5 node $ curl -k https://10.244.3.5
... ...
<h1>Welcome to nginx!</h1> <h1>Welcome to nginx!</h1>
``` ```
<!--
Note how we supplied the `-k` parameter to curl in the last step, this is because we don't know anything about the pods running nginx at certificate generation time,
so we have to tell curl to ignore the CName mismatch. By creating a Service we linked the CName used in the certificate with the actual DNS name used by pods during Service lookup.
Let's test this from a pod (the same secret is being reused for simplicity, the pod only needs nginx.crt to access the Service):
-->
注意最后一步我们是如何提供 `-k` 参数执行 curl命令的,这是因为在证书生成时,我们不知道任何关于运行 Nginx 的 Pod 的信息,所以不得不在执行 curl 命令时忽略 CName 不匹配的情况。 注意最后一步我们是如何提供 `-k` 参数执行 curl命令的,这是因为在证书生成时,我们不知道任何关于运行 Nginx 的 Pod 的信息,所以不得不在执行 curl 命令时忽略 CName 不匹配的情况。
通过创建 Service,我们连接了在证书中的 CName 与在 Service 查询时被 Pod使用的实际 DNS 名字。 通过创建 Service,我们连接了在证书中的 CName 与在 Service 查询时被 Pod使用的实际 DNS 名字。
让我们从一个 Pod 来测试(为了简化使用同一个秘钥,Pod 仅需要使用 nginx.crt 去访问 Service): 让我们从一个 Pod 来测试(为了简化使用同一个秘钥,Pod 仅需要使用 nginx.crt 去访问 Service):
{{< code file="curlpod.yaml" >}} {{< codenew file="service/networking/curlpod.yaml" >}}
```shell ```shell
$ kubectl create -f ./curlpod.yaml kubectl apply -f ./curlpod.yaml
$ kubectl get pods -l app=curlpod kubectl get pods -l app=curlpod
```
```
NAME READY STATUS RESTARTS AGE NAME READY STATUS RESTARTS AGE
curl-deployment-1515033274-1410r 1/1 Running 0 1m curl-deployment-1515033274-1410r 1/1 Running 0 1m
$ kubectl exec curl-deployment-1515033274-1410r -- curl https://my-nginx --cacert /etc/nginx/ssl/nginx.crt ```
```shell
kubectl exec curl-deployment-1515033274-1410r -- curl https://my-nginx --cacert /etc/nginx/ssl/nginx.crt
... ...
<title>Welcome to nginx!</title> <title>Welcome to nginx!</title>
... ...
``` ```
<!--
## Exposing the Service
For some parts of your applications you may want to expose a Service onto an
external IP address. Kubernetes supports two ways of doing this: NodePorts and
LoadBalancers. The Service created in the last section already used `NodePort`,
so your nginx HTTPS replica is ready to serve traffic on the internet if your
node has a public IP.
-->
## 暴露 Service ## 暴露 Service
@@ -302,7 +521,7 @@ Kubernetes 支持两种实现方式:NodePort 和 LoadBalancer。
在上一段创建的 Service 使用了 `NodePort`,因此 Nginx https 副本已经就绪,如果使用一个公网 IP,能够处理 Internet 上的流量。 在上一段创建的 Service 使用了 `NodePort`,因此 Nginx https 副本已经就绪,如果使用一个公网 IP,能够处理 Internet 上的流量。
```shell ```shell
$ kubectl get svc my-nginx -o yaml | grep nodePort -C 5 kubectl get svc my-nginx -o yaml | grep nodePort -C 5
uid: 07191fb3-f61a-11e5-8ae5-42010af00002 uid: 07191fb3-f61a-11e5-8ae5-42010af00002
spec: spec:
clusterIP: 10.0.162.149 clusterIP: 10.0.162.149
@@ -319,8 +538,9 @@ spec:
targetPort: 443 targetPort: 443
selector: selector:
run: my-nginx run: my-nginx
```
$ kubectl get nodes -o yaml | grep ExternalIP -C 1 ```shell
kubectl get nodes -o yaml | grep ExternalIP -C 1
- address: 104.197.41.11 - address: 104.197.41.11
type: ExternalIP type: ExternalIP
allocatable: allocatable:
@@ -335,22 +555,35 @@ $ curl https://<EXTERNAL-IP>:<NODE-PORT> -k
<h1>Welcome to nginx!</h1> <h1>Welcome to nginx!</h1>
``` ```
<!--
Let's now recreate the Service to use a cloud load balancer, just change the `Type` of `my-nginx` Service from `NodePort` to `LoadBalancer`:
-->
让我们重新创建一个 Service,使用一个云负载均衡器,只需要将 `my-nginx` Service 的 `Type``NodePort` 改成 `LoadBalancer` 让我们重新创建一个 Service,使用一个云负载均衡器,只需要将 `my-nginx` Service 的 `Type``NodePort` 改成 `LoadBalancer`
```shell ```shell
$ kubectl edit svc my-nginx kubectl edit svc my-nginx
$ kubectl get svc my-nginx kubectl get svc my-nginx
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE ```
my-nginx 10.0.162.149 162.222.184.144 80/TCP,81/TCP,82/TCP 21s ```
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
$ curl https://<EXTERNAL-IP> -k my-nginx ClusterIP 10.0.162.149 162.222.184.144 80/TCP,81/TCP,82/TCP 21s
```
```
curl https://<EXTERNAL-IP> -k
... ...
<title>Welcome to nginx!</title> <title>Welcome to nginx!</title>
``` ```
<!--
The IP address in the `EXTERNAL-IP` column is the one that is available on the public internet. The `CLUSTER-IP` is only available inside your
cluster/private cloud network.
Note that on AWS, type `LoadBalancer` creates an ELB, which uses a (long)
hostname, not an IP. It's too long to fit in the standard `kubectl get svc`
output, in fact, so you'll need to do `kubectl describe service my-nginx` to
see it. You'll see something like this:
-->
`EXTERNAL-IP` 列指定的 IP 地址是在公网上可用的。`CLUSTER-IP` 只在集群/私有云网络中可用。 `EXTERNAL-IP` 列指定的 IP 地址是在公网上可用的。`CLUSTER-IP` 只在集群/私有云网络中可用。
@@ -359,13 +592,25 @@ $ curl https://<EXTERNAL-IP> -k
可以看到类似如下内容: 可以看到类似如下内容:
```shell ```shell
$ kubectl describe service my-nginx kubectl describe service my-nginx
... ...
LoadBalancer Ingress: a320587ffd19711e5a37606cf4a74574-1142138393.us-east-1.elb.amazonaws.com LoadBalancer Ingress: a320587ffd19711e5a37606cf4a74574-1142138393.us-east-1.elb.amazonaws.com
... ...
``` ```
## 进一步阅读 {{% /capture %}}
{{% capture whatsnext %}}
<!--
Kubernetes also supports Federated Services, which can span multiple
clusters and cloud providers, to provide increased availability,
better fault tolerance and greater scalability for your services. See
the [Federated Services User Guide](/docs/concepts/cluster-administration/federation-service-discovery/)
for further information.
-->
Kubernetes 也支持联合 Service,能够跨多个集群和云提供商,为 Service 提供逐步增强的可用性、更优的容错、更好的可伸缩性。 Kubernetes 也支持联合 Service,能够跨多个集群和云提供商,为 Service 提供逐步增强的可用性、更优的容错、更好的可伸缩性。
查看 [联合 Service 用户指南](/docs/concepts/cluster-administration/federation-service-discovery/) 获取更进一步信息。 查看 [联合 Service 用户指南](/docs/concepts/cluster-administration/federation-service-discovery/) 获取更进一步信息。
{{% /capture %}}
@@ -1,23 +1,48 @@
--- ---
approvers: title: Pod 与 Service 的 DNS
- davidopp content_template: templates/concept
- thockin weight: 20
title: DNS Pod 与 Service
redirect_from:
- "/docs/admin/dns/"
- "/docs/admin/dns.html"
--- ---
{{% capture overview %}}
<!--
This page provides an overview of DNS support by Kubernetes.
-->
该页面概述了Kubernetes对DNS的支持。
{{% /capture %}}
{{% capture body %}}
<!--
## Introduction
Kubernetes DNS schedules a DNS Pod and Service on the cluster, and configures
the kubelets to tell individual containers to use the DNS Service's IP to
resolve DNS names.
-->
## 介绍 ## 介绍
Kubernetes 从 1.3 版本起, DNS 是内置的服务,通过插件管理器 [集群插件](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/README.md) 自动被启动 Kubernetes DNS 在群集上调度 DNS Pod 和服务,并配置 kubelet 以告知各个容器使用 DNS 服务的 IP 来解析 DNS 名称
Kubernetes DNS 在集群中调度 DNS Pod 和 Service ,配置 kubelet 以通知个别容器使用 DNS Service 的 IP 解析 DNS 名字。 <!--
### What things get DNS names?
Every Service defined in the cluster (including the DNS server itself) is
assigned a DNS name. By default, a client Pod's DNS search list will
include the Pod's own namespace and the cluster's default domain. This is best
illustrated by example:
Assume a Service named `foo` in the Kubernetes namespace `bar`. A Pod running
in namespace `bar` can look up this service by simply doing a DNS query for
`foo`. A Pod running in namespace `quux` can look up this service by doing a
DNS query for `foo.bar`.
The following sections detail the supported record types and layout that is
supported. Any other layout or names or queries that happen to work are
considered implementation details and are subject to change without warning.
For more up-to-date specification, see
[Kubernetes DNS-Based Service Discovery](https://github.com/kubernetes/dns/blob/master/docs/specification.md).
-->
## 怎样获取 DNS 名字? ## 怎样获取 DNS 名字?
@@ -29,52 +54,87 @@ Kubernetes DNS 在集群中调度 DNS Pod 和 Service ,配置 kubelet 以通
运行在Namespace `bar` 中的一个 Pod,可以简单地通过 DNS 查询 `foo` 来找到该 Service。 运行在Namespace `bar` 中的一个 Pod,可以简单地通过 DNS 查询 `foo` 来找到该 Service。
运行在 Namespace `quux` 中的一个 Pod 可以通过 DNS 查询 `foo.bar` 找到该 Service。 运行在 Namespace `quux` 中的一个 Pod 可以通过 DNS 查询 `foo.bar` 找到该 Service。
以下各节详细介绍了受支持的记录类型和支持的布局。 其中代码部分的布局,名称或查询命令均被视为实现细节,如有更改,恕不另行通知。
有关最新规范请查看
[Kubernetes 基于 DNS 的服务发现](https://github.com/kubernetes/dns/blob/master/docs/specification.md).
## 支持的 DNS 模式 ## 支持的 DNS 模式
下面各段详细说明支持的记录类型和布局。 下面各段详细说明支持的记录类型和布局。
如果任何其它的布局、名称或查询,碰巧也能够使用,这就需要研究下它们的实现细节,以免后续修改它们又不能使用了。 如果任何其它的布局、名称或查询,碰巧也能够使用,这就需要研究下它们的实现细节,以免后续修改它们又不能使用了。
<!--
## Services
### A records
"Normal" (not headless) Services are assigned a DNS A record for a name of the
form `my-svc.my-namespace.svc.cluster-domain.example`. This resolves to the cluster IP
of the Service.
"Headless" (without a cluster IP) Services are also assigned a DNS A record for
a name of the form `my-svc.my-namespace.svc.cluster-domain.example`. Unlike normal
Services, this resolves to the set of IPs of the pods selected by the Service.
Clients are expected to consume the set or else use standard round-robin
selection from the set.
-->
### Service ### Service
#### A 记录 #### A 记录
“正常” Service(除了 Headless Service)会以 `my-svc.my-namespace.svc.cluster.local` 这种名字的形式被指派一个 DNS A 记录。这会解析成该 Service 的 Cluster IP。 “正常” Service(除了 Headless Service)会以 `my-svc.my-namespace.svc.cluster-domain.example` 这种名字的形式被指派一个 DNS A 记录。
这会解析成该 Service 的 Cluster IP。
“Headless” Service(没有Cluster IP)也会以 `my-svc.my-namespace.svc.cluster.local` 这种名字的形式被指派一个 DNS A 记录。 “Headless” Service(没有Cluster IP)也会以 `my-svc.my-namespace.svc.cluster-domain.example` 这种名字的形式被指派一个 DNS A 记录。
不像正常 Service,它会解析成该 Service 选择的一组 Pod 的 IP。 不像正常 Service,它会解析成该 Service 选择的一组 Pod 的 IP。
希望客户端能够使用这一组 IP,否则就使用标准的 round-robin 策略从这一组 IP 中进行选择。 希望客户端能够使用这一组 IP,否则就使用标准的 round-robin 策略从这一组 IP 中进行选择。
<!--
### SRV records
SRV Records are created for named ports that are part of normal or [Headless
Services](/docs/concepts/services-networking/service/#headless-services).
For each named port, the SRV record would have the form
`_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster-domain.example`.
For a regular service, this resolves to the port number and the domain name:
`my-svc.my-namespace.svc.cluster-domain.example`.
For a headless service, this resolves to multiple answers, one for each pod
that is backing the service, and contains the port number and the domain name of the pod
of the form `auto-generated-name.my-svc.my-namespace.svc.cluster-domain.example`.
-->
#### SRV 记录 #### SRV 记录
命名端口需要创建 SRV 记录,这些端口是正常 Service或 [Headless 命名端口需要创建 SRV 记录,这些端口是正常 Service或 [Headless
Services](/docs/concepts/services-networking/service/#headless-services) 的一部分。 Services](/docs/concepts/services-networking/service/#headless-services) 的一部分。
对每个命名端口,SRV 记录具有 `_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster.local` 这种形式。 对每个命名端口,SRV 记录具有 `_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster-domain.example` 这种形式。
对普通 Service,这会被解析成端口号和 CNAME:`my-svc.my-namespace.svc.cluster.local` 对普通 Service,这会被解析成端口号和 CNAME:`my-svc.my-namespace.svc.cluster-domain.example`
对 Headless Service,这会被解析成多个结果,Service 对应的每个 backend Pod 各一个,包含 `auto-generated-name.my-svc.my-namespace.svc.cluster.local` 这种形式 Pod 的端口号和 CNAME。 对 Headless Service,这会被解析成多个结果,Service 对应的每个 backend Pod 各一个,
包含 `auto-generated-name.my-svc.my-namespace.svc.cluster-domain.example` 这种形式 Pod 的端口号和 CNAME。
#### 后向兼容性
上一版本的 kube-dns 使用 `my-svc.my-namespace.cluster.local` 这种形式的名字(后续会增加 'svc' 这一级),以后这将不再被支持。
## Pods
### Pod <!--
### Pod's hostname and subdomain fields
#### A 记录 Currently when a pod is created, its hostname is the Pod's `metadata.name` value.
如果启用,Pod 会以 `pod-ip-address.my-namespace.pod.cluster.local` 这种形式被指派一个 DNS A 记录。 The Pod spec has an optional `hostname` field, which can be used to specify the
Pod's hostname. When specified, it takes precedence over the Pod's name to be
the hostname of the pod. For example, given a Pod with `hostname` set to
"`my-host`", the Pod will have its hostname set to "`my-host`".
例如,`default` Namespace 具有 DNS 名字 `cluster.local`,在该 Namespace 中一个 IP 为 `1.2.3.4` 的 Pod 将具有一个条目:`1-2-3-4.default.pod.cluster.local` The Pod spec also has an optional `subdomain` field which can be used to specify
its subdomain. For example, a Pod with `hostname` set to "`foo`", and `subdomain`
set to "`bar`", in namespace "`my-namespace`", will have the fully qualified
domain name (FQDN) "`foo.bar.my-namespace.svc.cluster-domain.example`".
Example:
-->
### Pod的 hostname 和 subdomain 字段
#### 基于 Pod hostname、subdomain 字段的 A 记录和主机名
当前,创建 Pod 后,它的主机名是该 Pod 的 `metadata.name` 值。 当前,创建 Pod 后,它的主机名是该 Pod 的 `metadata.name` 值。
@@ -82,18 +142,15 @@ Services](/docs/concepts/services-networking/service/#headless-services) 的一
如果为 Pod 配置了 annotation,会优先使用 Pod 的名称作为主机名。 如果为 Pod 配置了 annotation,会优先使用 Pod 的名称作为主机名。
例如,给定一个 Pod,它具有 annotation `pod.beta.kubernetes.io/hostname: my-pod-name`,该 Pod 的主机名被设置为 “my-pod-name”。 例如,给定一个 Pod,它具有 annotation `pod.beta.kubernetes.io/hostname: my-pod-name`,该 Pod 的主机名被设置为 “my-pod-name”。
在 v1.3 版本中,PodSpec 具有 `hostname` 字段,可以用来指定 Pod 的主机名。这个字段的值优先于 annotation `pod.beta.kubernetes.io/hostname` 在 v1.3 版本中,PodSpec 具有 `hostname` 字段,可以用来指定 Pod 的主机名。这个字段的值优先于 annotation `pod.beta.kubernetes.io/hostname`
在 v1.2 版本中引入了 beta 特性,用户可以为 Pod 指定 annotation,其中 `pod.beta.kubernetes.io/subdomain` 指定了 Pod 的子域名。 在 v1.2 版本中引入了 beta 特性,用户可以为 Pod 指定 annotation,其中 `pod.beta.kubernetes.io/subdomain` 指定了 Pod 的子域名。
最终的域名将是 “<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>”。 最终的域名将是 “<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>”。
举个例子,Pod 的主机名 annotation 设置为 “foo”,子域名 annotation 设置为 “bar”,在 Namespace “my-namespace” 中对应的 FQDN 为 “foo.bar.my-namespace.svc.cluster.local”。 举个例子,Pod 的主机名 annotation 设置为 “foo”,子域名 annotation 设置为 “bar”,在 Namespace “my-namespace” 中对应的 FQDN 为 “foo.bar.my-namespace.svc.cluster.local”。
在 v1.3 版本中,PodSpec 具有 `subdomain` 字段,可以用来指定 Pod 的子域名。 在 v1.3 版本中,PodSpec 具有 `subdomain` 字段,可以用来指定 Pod 的子域名。
这个字段的值优先于 annotation `pod.beta.kubernetes.io/subdomain` 的值。 这个字段的值优先于 annotation `pod.beta.kubernetes.io/subdomain` 的值。
实例:
```yaml ```yaml
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
@@ -104,9 +161,9 @@ spec:
name: busybox name: busybox
clusterIP: None clusterIP: None
ports: ports:
- name: foo # Actually, no port is needed. - name: foo # Actually, no port is needed.
port: 1234 port: 1234
targetPort: 1234 targetPort: 1234
--- ---
apiVersion: v1 apiVersion: v1
kind: Pod kind: Pod
@@ -118,7 +175,7 @@ spec:
hostname: busybox-1 hostname: busybox-1
subdomain: default-subdomain subdomain: default-subdomain
containers: containers:
- image: busybox - image: busybox:1.28
command: command:
- sleep - sleep
- "3600" - "3600"
@@ -134,44 +191,103 @@ spec:
hostname: busybox-2 hostname: busybox-2
subdomain: default-subdomain subdomain: default-subdomain
containers: containers:
- image: busybox - image: busybox:1.28
command: command:
- sleep - sleep
- "3600" - "3600"
name: busybox name: busybox
``` ```
<!--
If there exists a headless service in the same namespace as the pod and with
the same name as the subdomain, the cluster's KubeDNS Server also returns an A
record for the Pod's fully qualified hostname.
For example, given a Pod with the hostname set to "`busybox-1`" and the subdomain set to
"`default-subdomain`", and a headless Service named "`default-subdomain`" in
the same namespace, the pod will see its own FQDN as
"`busybox-1.default-subdomain.my-namespace.svc.cluster-domain.example`". DNS serves an
A record at that name, pointing to the Pod's IP. Both pods "`busybox1`" and
"`busybox2`" can have their distinct A records.
-->
如果 Headless Service 与 Pod 在同一个 Namespace 中,它们具有相同的子域名,集群的 KubeDNS 服务器也会为该 Pod 的完整合法主机名返回 A 记录。 如果 Headless Service 与 Pod 在同一个 Namespace 中,它们具有相同的子域名,集群的 KubeDNS 服务器也会为该 Pod 的完整合法主机名返回 A 记录。
在同一个 Namespace 中,给定一个主机名为 “busybox-1” 的 Pod,子域名设置为 “default-subdomain”,名称为 “default-subdomain” 的 Headless Service Pod 将看到自己的 FQDN 为 “busybox-1.default-subdomain.my-namespace.svc.cluster.local”。 例如,在同一个 Namespace 中,给定一个主机名为 “busybox-1” 的 Pod,子域名设置为 “default-subdomain”,名称为 “default-subdomain” 的 Headless Service Pod 将看到自己的 FQDN 为 “busybox-1.default-subdomain.my-namespace.svc.cluster.local”。
DNS 会为那个名字提供一个 A 记录,指向该 Pod 的 IP。 DNS 会为那个名字提供一个 A 记录,指向该 Pod 的 IP。
“busybox1” 和 “busybox2” 这两个 Pod 分别具有它们自己的 A 记录。 “busybox1” 和 “busybox2” 这两个 Pod 分别具有它们自己的 A 记录。
<!--
The Endpoints object can specify the `hostname` for any endpoint addresses,
along with its IP.
-->
在Kubernetes v1.2 版本中,`Endpoints` 对象也具有 annotation `endpoints.beta.kubernetes.io/hostnames-map` 端点对象可以为任何端点地址及其 IP 指定 `hostname`
它的值是 map[string(IP)][endpoints.HostRecord] 的 JSON 格式,例如: '{"10.245.1.6":{HostName: "my-webserver"}}'。
如果是 Headless Service 的 `Endpoints`,会以 <hostname>.<service name>.<pod namespace>.svc.<cluster domain> 的格式创建 A 记录。 {{< note >}}
对示例中的 JSON 字符串,如果 `Endpoints` 是为名称为 “bar” 的 Headless Service 而创建的,其中一个 `Endpoints` 的 IP 是 “10.245.1.6”,则会创建一个名称为 “my-webserver.bar.my-namespace.svc.cluster.local” 的 A 记录,该 A 记录查询将返回 “10.245.1.6”。
`Endpoints` annotation 通常没必要由最终用户指定,但可以被内部的 Service Controller 用来提供上述功能。 <!--
Because A records are not created for Pod names, `hostname` is required for the Pod's A
record to be created. A Pod with no `hostname` but with `subdomain` will only create the
A record for the headless service (`default-subdomain.my-namespace.svc.cluster-domain.example`),
pointing to the Pod's IP address. Also, Pod needs to become ready in order to have a
record unless `publishNotReadyAddresses=True` is set on the Service.
-->
因为没有为 Pod 名称创建A记录,所以要创建 Pod 的 A 记录需要 `hostname`
没有 `hostname` 但带有 `subdomain` 的 Pod 只会为指向Pod的IP地址的 headless 服务创建 A 记录(`default-subdomain.my-namespace.svc.cluster-domain.example`)。
另外,除非在服务上设置了 `publishNotReadyAddresses=True`,否则 Pod 需要准备好 A 记录。
{{< /note >}}
<!--
### Pod's DNS Policy
DNS policies can be set on a per-pod basis. Currently Kubernetes supports the
following pod-specific DNS policies. These policies are specified in the
`dnsPolicy` field of a Pod Spec.
- "`Default`": The Pod inherits the name resolution configuration from the node
that the pods run on.
See [related discussion](/docs/tasks/administer-cluster/dns-custom-nameservers/#inheriting-dns-from-the-node)
for more details.
- "`ClusterFirst`": Any DNS query that does not match the configured cluster
domain suffix, such as "`www.kubernetes.io`", is forwarded to the upstream
nameserver inherited from the node. Cluster administrators may have extra
stub-domain and upstream DNS servers configured.
See [related discussion](/docs/tasks/administer-cluster/dns-custom-nameservers/#impacts-on-pods)
for details on how DNS queries are handled in those cases.
- "`ClusterFirstWithHostNet`": For Pods running with hostNetwork, you should
explicitly set its DNS policy "`ClusterFirstWithHostNet`".
- "`None`": It allows a Pod to ignore DNS settings from the Kubernetes
environment. All DNS settings are supposed to be provided using the
`dnsConfig` field in the Pod Spec.
See [Pod's DNS config](#pod-s-dns-config) subsection below.
-->
- "`Default`": Pod从运行所在的节点继承名称解析配置。
参考 [相关讨论](/docs/tasks/administer-cluster/dns-custom-nameservers/#inheriting-dns-from-the-node) 获取更多信息。
- "`ClusterFirst`": 与配置的群集域后缀不匹配的任何DNS查询(例如 “www.kubernetes.io” )都将转发到从节点继承的上游名称服务器。 群集管理员可能配置了额外的存根域和上游DNS服务器。
See [相关讨论](/docs/tasks/administer-cluster/dns-custom-nameservers/#impacts-on-pods) 获取如何 DNS 的查询和处理信息的相关资料。
- "`ClusterFirstWithHostNet`": 对于与 hostNetwork 一起运行的 Pod,应显式设置其DNS策略 "`ClusterFirstWithHostNet`"。
- "`None`": 它允许 Pod 忽略 Kubernetes 环境中的 DN S设置。 应该使用 Pod Spec 中的 `dnsConfig` 字段提供所有 DNS 设置。
{{< note >}}
<!--
"Default" is not the default DNS policy. If `dnsPolicy` is not
explicitly specified, then “ClusterFirst” is used.
-->
"Default" 不是默认的 DNS 策略。 如果未明确指定 `dnsPolicy`,则使用 “ClusterFirst”。
{{< /note >}}
<!--
The example below shows a Pod with its DNS policy set to
"`ClusterFirstWithHostNet`" because it has `hostNetwork` set to `true`.
-->
在 v1.3 版本中,`Endpoints` 对象可以为任何 endpoint 指定 `hostname` 和 IP 下面的示例显示了一个Pod,其DNS策略设置为 "`ClusterFirstWithHostNet`",因为它已将 `hostNetwork` 设置为 `true`
`hostname` 字段优先于通过 `endpoints.beta.kubernetes.io/hostnames-map` annotation 指定的主机名。
在 v1.3 版本中,下面的 annotation 是过时的:`pod.beta.kubernetes.io/hostname``pod.beta.kubernetes.io/subdomain``endpoints.beta.kubernetes.io/hostnames-map`
## 如何测试它是否可以使用?
### 创建一个简单的 Pod 作为测试环境
创建 `busybox.yaml` 文件,内容如下:
```yaml ```yaml
apiVersion: v1 apiVersion: v1
@@ -181,239 +297,132 @@ metadata:
namespace: default namespace: default
spec: spec:
containers: containers:
- image: busybox - image: busybox:1.28
command: command:
- sleep - sleep
- "3600" - "3600"
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
name: busybox name: busybox
restartPolicy: Always restartPolicy: Always
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
```
<!--
### Pod's DNS Config
Pod's DNS Config allows users more control on the DNS settings for a Pod.
The `dnsConfig` field is optional and it can work with any `dnsPolicy` settings.
However, when a Pod's `dnsPolicy` is set to "`None`", the `dnsConfig` field has
to be specified.
Below are the properties a user can specify in the `dnsConfig` field:
-->
### Pod 的 DNS 设定
Pod 的 DNS 配置可让用户对 Pod 的 DNS 设置进行更多控制。
`dnsConfig` 字段是可选的,它可以与任何 `dnsPolicy` 设置一起使用。
但是,当 Pod 的 `dnsPolicy` 设置为 "`None`" 时,必须指定 `dnsConfig` 字段。
用户可以在 `dnsConfig` 字段中指定以下属性:
<!--
- `nameservers`: a list of IP addresses that will be used as DNS servers for the
Pod. There can be at most 3 IP addresses specified. When the Pod's `dnsPolicy`
is set to "`None`", the list must contain at least one IP address, otherwise
this property is optional.
The servers listed will be combined to the base nameservers generated from the
specified DNS policy with duplicate addresses removed.
- `searches`: a list of DNS search domains for hostname lookup in the Pod.
This property is optional. When specified, the provided list will be merged
into the base search domain names generated from the chosen DNS policy.
Duplicate domain names are removed.
Kubernetes allows for at most 6 search domains.
- `options`: an optional list of objects where each object may have a `name`
property (required) and a `value` property (optional). The contents in this
property will be merged to the options generated from the specified DNS policy.
Duplicate entries are removed.
-->
- `nameservers`: 将用作于 Pod 的 DNS 服务器的 IP 地址列表。最多可以指定3个 IP 地址。 当 Pod 的 `dnsPolicy` 设置为 "`None`" 时,列表必须至少包含一个IP地址,否则此属性是可选的。列出的服务器将合并到从指定的 DNS 策略生成的基本名称服务器,并删除重复的地址。
- `searches`: 用于在 Pod 中查找主机名的 DNS 搜索域的列表。此属性是可选的。指定后,提供的列表将合并到根据所选 DNS 策略生成的基本搜索域名中。
重复的域名将被删除。
   Kubernetes最多允许6个搜索域。
- `options`: 对象的可选列表,其中每个对象可能具有 `name` 属性(必需)和 `value` 属性(可选)。 此属性中的内容将合并到从指定的 DNS 策略生成的选项。
重复的条目将被删除。
<!--
The following is an example Pod with custom DNS settings:
-->
以下是具有自定义DNS设置的Pod示例:
{{< codenew file="service/networking/custom-dns.yaml" >}}
<!--
When the Pod above is created, the container `test` gets the following contents
in its `/etc/resolv.conf` file:
-->
创建上面的Pod后,容器 `test` 会在其 `/etc/resolv.conf` 文件中获取以下内容:
```
nameserver 1.2.3.4
search ns1.svc.cluster-domain.example my.dns.search.suffix
options ndots:2 edns0
``` ```
然后,用该文件创建一个 Pod <!--
For IPv6 setup, search path and name server should be setup like this:
-->
对于IPv6设置,搜索路径和名称服务器应按以下方式设置:
``` ```shell
kubectl create -f busybox.yaml kubectl exec -it dns-example -- cat /etc/resolv.conf
``` ```
<!--
The output is similar to this:
### 等待这个 Pod 变成运行状态 -->
有以下输出:
获取它的状态,执行如下命令: ```shell
nameserver fd00:79:30::a
``` search default.svc.cluster-domain.example svc.cluster-domain.example cluster-domain.example
kubectl get pods busybox
```
可以看到如下内容:
```
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 <some-time>
```
### 验证 DNS 已经生效
一旦 Pod 处于运行中状态,可以在测试环境中执行如下 nslookup 查询:
```
kubectl exec -ti busybox -- nslookup kubernetes.default
```
可以看到类似如下的内容:
```
Server: 10.0.0.10
Address 1: 10.0.0.10
Name: kubernetes.default
Address 1: 10.0.0.1
```
如果看到了,说明 DNS 已经可以正确工作了。
### 问题排查技巧
如果执行 nslookup 命令失败,检查如下内容:
#### 先检查本地 DNS 配置
查看配置文件 resolv.conf。(关于更多信息,参考下面的 “从 Node 继承 DNS” 和 “已知问题”。)
```
kubectl exec busybox cat /etc/resolv.conf
```
按照如下方法(注意搜索路径可能会因为云提供商不同而变化)验证搜索路径和 Name Server 的建立:
```
search default.svc.cluster.local svc.cluster.local cluster.local google.internal c.gce_project_id.internal
nameserver 10.0.0.10
options ndots:5 options ndots:5
``` ```
<!--
### Feature availability
The availability of Pod DNS Config and DNS Policy "`None`"" is shown as below.
-->
#### 快速诊断 ### 可用功能
出现类似如下指示的错误,说明 kube-dns 插件或相关 Service 存在问题: Pod DNS 配置和 DNS 策略 "`None`" 的版本对应如下所示。
``` | k8s version | Feature support |
$ kubectl exec -ti busybox -- nslookup kubernetes.default | :---------: |:-----------:|
Server: 10.0.0.10 | 1.14 | Stable |
Address 1: 10.0.0.10 | 1.10 | Beta (on by default)|
| 1.9 | Alpha |
nslookup: can't resolve 'kubernetes.default' {{% /capture %}}
```
{{% capture whatsnext %}}
<!--
For guidance on administering DNS configurations, check
[Configure DNS Service](/docs/tasks/administer-cluster/dns-custom-nameservers/)
-->
或者 有关管理 DNS 配置的指导,请查看
[配置 DNS 服务](/docs/tasks/administer-cluster/dns-custom-nameservers/)
``` {{% /capture %}}
$ kubectl exec -ti busybox -- nslookup kubernetes.default
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
nslookup: can't resolve 'kubernetes.default'
```
#### 检查是否 DNS Pod 正在运行
使用 `kubectl get pods` 命令验证 DNS Pod 正在运行:
```
kubectl get pods --namespace=kube-system -l k8s-app=kube-dns
```
应该能够看到类似如下信息:
```
NAME READY STATUS RESTARTS AGE
...
kube-dns-v19-ezo1y 3/3 Running 0 1h
...
```
如果看到没有 Pod 运行,或 Pod 失败/结束,DNS 插件不能默认部署到当前的环境,必须手动部署。
#### 检查 DNS Pod 中的错误信息
使用 `kubectl logs` 命令查看 DNS 后台进程的日志:
```
kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c kubedns
kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c dnsmasq
kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c healthz
```
查看是否有任何可疑的日志。在行开头的字母 W、E、F 分别表示 警告、错误、失败。请搜索具有这些日志级别的日志行,通过 [Kubernetes 问题](https://github.com/kubernetes/kubernetes/issues) 报告意外的错误。
#### DNS 服务是否运行?
通过使用 `kubectl get service` 命令,验证 DNS 服务是否运行:
```
kubectl get svc --namespace=kube-system
```
应该能够看到:
```
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
kube-dns 10.0.0.10 <none> 53/UDP,53/TCP 1h
...
```
如果服务已经创建,或在这个例子中默认被创建,但是并没有看到,可以查看 [调试 Service 页面](/docs/tasks/debug-application-cluster/debug-service/) 获取更多信息。
```
kubectl get ep kube-dns --namespace=kube-system
```
应该能够看到类似如下信息:
```
NAME ENDPOINTS AGE
kube-dns 10.180.3.17:53,10.180.3.17:53 1h
```
如果没有看到 Endpoint,查看 [调试 Service 文档](/docs/tasks/debug-application-cluster/debug-service/) 中的 Endpoint 段内容。
关于更多 Kubernetes DNS 的示例,参考 Kubernetes GitHub 仓库中 [集群 DNS 示例](https://git.k8s.io/kubernetes/examples/cluster-dns)。
## Kubernetes Federation(多 Zone 支持)
在1.3 发行版本中,为多站点 Kubernetes 安装引入了集群 Federation 支持。这需要对 Kubernetes 集群 DNS 服务器处理 DNS 查询的方式,做出一些微小(后向兼容)改变,从而便利了对联合 Service 的查询(跨多个 Kubernetes 集群)。参考 [集群 Federation 管理员指南](/docs/concepts/cluster-administration/federation/) 获取更多关于集群 Federation 和多站点支持的细节。
## 工作原理
运行的 Kubernetes DNS Pod 包含 3 个容器 —— kubedns、dnsmasq 和负责健康检查的 healthz。
kubedns 进程监视 Kubernetes master 对 Service 和 Endpoint 操作的变更,并维护一个内存查询结构去处理 DNS 请求。dnsmasq 容器增加了一个 DNS 缓存来改善性能。为执行对 dnsmasq 和 kubedns 的健康检查,healthz 容器提供了一个单独的健康检查 Endpoint。
DNS Pod 通过一个静态 IP 暴露为一个 Service。一旦 IP 被分配,kubelet 会通过 `--cluster-dns=10.0.0.10` 标志将配置的 DNS 传递给每一个容器。
DNS 名字也需要域名,本地域名是可配置的,在 kubelet 中使用 `--cluster-domain=<default local domain>` 标志。
Kubernetes 集群 DNS 服务器(根据 [SkyDNS](https://github.com/skynetservices/skydns) 库)支持正向查询(A 记录),Service 查询(SRV 记录)和反向 IP 地址查询(PTR 记录)。
## 从 Node 继承 DNS
当运行 Pod 时,kubelet 将集群 DNS 服务器和搜索路径追加到 Node 自己的 DNS 设置中。如果 Node 能够在大型环境中解析 DNS 名字,Pod 也应该没问题。参考下面 "已知问题” 中给出的更多说明。
如果不想这样,或者希望 Pod 有一个不同的 DNS 配置,可以使用 kubelet 的 `--resolv-conf` 标志。设置为 "" 表示 Pod 将不继承自 DNS。设置为一个合法的文件路径,表示 kubelet 将使用这个文件而不是 `/etc/resolv.conf`
## 已知问题
Kubernetes 安装但并不配置 Node 的 resolv.conf 文件,而是默认使用集群 DNS的,因为那个过程本质上就是和特定的发行版本相关的。最终应该会被实现。
Linux libc 在限制为3个 DNS `nameserver` 记录和3个 DNS `search` 记录是不可能卡住的([查看 2005 年的一个 Bug](https://bugzilla.redhat.com/show_bug.cgi?id=168253))。Kubernetes 需要使用1个 `nameserver` 记录和3个 `search` 记录。这意味着如果本地安装已经使用了3个 `nameserver` 或使用了3个以上 `search`,那些设置将会丢失。作为部分解决方法, Node 可以运行 `dnsmasq` ,它能提供更多 `nameserver` 条目,但不能运行更多 `search` 条目。可以使用 kubelet 的 `--resolv-conf` 标志。
如果使用 3.3 版本的 Alpine 或更早版本作为 base 镜像,由于 Alpine 的一个已知问题,DNS 可能不会正确工作。查看 [这里](https://github.com/kubernetes/kubernetes/issues/30215) 获取更多信息。
## 参考
- [DNS 集群插件文档](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/README.md)
## 下一步
- [集群中 DNS Service 自动伸缩](/docs/tasks/administer-cluster/dns-horizontal-autoscaling/)
@@ -0,0 +1,118 @@
---
title: Ingress 控制器
content_template: templates/concept
weight: 40
---
{{% capture overview %}}
<!--
In order for the Ingress resource to work, the cluster must have an ingress controller running.
Unlike other types of controllers which run as part of the `kube-controller-manager` binary, Ingress controllers
are not started automatically with a cluster. Use this page to choose the ingress controller implementation
that best fits your cluster.
Kubernetes as a project currently supports and maintains [GCE](https://git.k8s.io/ingress-gce/README.md) and
[nginx](https://git.k8s.io/ingress-nginx/README.md) controllers.
-->
为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress 控制器。
与其他类型的控制器不同,它们是作为 `kube-controller-manager` 二进制文件的一部分运行的,而 Ingress 控制器不是随集群自动启动的。
通过此页面可选择最适合您的集群的 ingress 控制器实现。
Kubernetes 作为一个项目,目前支持和维护 [GCE](https://git.k8s.io/ingress-gce/README.md) 和
[nginx](https://git.k8s.io/ingress-nginx/README.md) 控制器。
{{% /capture %}}
{{% capture body %}}
<!--
## Additional controllers
* [Ambassador](https://www.getambassador.io/) API Gateway is an [Envoy](https://www.envoyproxy.io) based ingress
controller with [community](https://www.getambassador.io/docs) or
[commercial](https://www.getambassador.io/pro/) support from [Datawire](https://www.datawire.io/).
* [AppsCode Inc.](https://appscode.com) offers support and maintenance for the most widely used [HAProxy](http://www.haproxy.org/) based ingress controller [Voyager](https://appscode.com/products/voyager).
* [Contour](https://github.com/heptio/contour) is an [Envoy](https://www.envoyproxy.io) based ingress controller
provided and supported by Heptio.
* Citrix provides an [Ingress Controller](https://github.com/citrix/citrix-k8s-ingress-controller) for its hardware (MPX), virtualized (VPX) and [free containerized (CPX) ADC](https://www.citrix.com/products/citrix-adc/cpx-express.html) for [baremetal](https://github.com/citrix/citrix-k8s-ingress-controller/tree/master/deployment/baremetal) and [cloud](https://github.com/citrix/citrix-k8s-ingress-controller/tree/master/deployment) deployments.
* F5 Networks provides [support and maintenance](https://support.f5.com/csp/article/K86859508)
for the [F5 BIG-IP Controller for Kubernetes](http://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest).
* [Gloo](https://gloo.solo.io) is an open-source ingress controller based on [Envoy](https://www.envoyproxy.io) which offers API Gateway functionality with enterprise support from [solo.io](https://www.solo.io).
* [HAProxy Technologies](https://www.haproxy.com/) offers support and maintenance for the [HAProxy Ingress Controller for Kubernetes](https://github.com/haproxytech/kubernetes-ingress). See the [official documentation](https://www.haproxy.com/documentation/hapee/1-9r1/traffic-management/kubernetes-ingress-controller/).
* [Istio](https://istio.io/) based ingress controller
[Control Ingress Traffic](https://istio.io/docs/tasks/traffic-management/ingress/).
* [Kong](https://konghq.com/) offers [community](https://discuss.konghq.com/c/kubernetes) or
[commercial](https://konghq.com/kong-enterprise/) support and maintenance for the
[Kong Ingress Controller for Kubernetes](https://github.com/Kong/kubernetes-ingress-controller).
* [NGINX, Inc.](https://www.nginx.com/) offers support and maintenance for the
[NGINX Ingress Controller for Kubernetes](https://www.nginx.com/products/nginx/kubernetes-ingress-controller).
* [Skipper](https://opensource.zalando.com/skipper/kubernetes/ingress-controller/) HTTP router and reverse proxy for service composition, including use cases like Kubernetes Ingress, designed as a library to build your custom proxy
* [Traefik](https://github.com/containous/traefik) is a fully featured ingress controller
([Let's Encrypt](https://letsencrypt.org), secrets, http2, websocket), and it also comes with commercial
support by [Containous](https://containo.us/services).
-->
## 其他控制器
* [Ambassador](https://www.getambassador.io/) API 网关, 一个基于 [Envoy](https://www.envoyproxy.io) 的 ingress
控制器,有着来自 [Datawire](https://www.datawire.io/) [社区](https://www.getambassador.io/docs)或[商业](https://www.getambassador.io/pro/)的支持。
* [AppsCode Inc.](https://appscode.com) 为最广泛使用的基于 [HAProxy](http://www.haproxy.org/) 的 ingress 控制器 [Voyager](https://appscode.com/products/voyager) 提供支持和维护.
* [Contour](https://github.com/heptio/contour) 是一个基于 [Envoy](https://www.envoyproxy.io) 的 ingress 控制器,它由 Heptio 提供和支持。
* Citrix 为其硬件(MPX),虚拟化(VPX)和 [免费容器化 (CPX) ADC](https://www.citrix.com/products/citrix-adc/cpx-express.html) 提供了一个 [Ingress 控制器](https://github.com/citrix/citrix-k8s-ingress-controller),用于[裸金属](https://github.com/citrix/citrix-k8s-ingress-controller/tree/master/deployment/baremetal)和[](https://github.com/citrix/citrix-k8s-ingress-controller/tree/master/deployment)部署。
* F5 Networks 为 [用于 Kubernetes 的 F5 BIG-IP 控制器](http://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest)提供[支持和维护](https://support.f5.com/csp/article/K86859508)。
* [Gloo](https://gloo.solo.io) 是一个开源的基于 [Envoy](https://www.envoyproxy.io) 的 ingress 控制器,它提供了 API 网关功能,有着来自 [solo.io](https://www.solo.io) 的企业级支持。
* [HAProxy Technologies](https://www.haproxy.com/) 为 [HAProxy Ingress Controller for Kubernetes](https://github.com/haproxytech/kubernetes-ingress). See the [official documentation](https://www.haproxy.com/documentation/hapee/1-9r1/traffic-management/kubernetes-ingress-controller/) 提供支持和运维服务。
* 基于 [Istio](https://istio.io/) 的 ingress 控制器[控制 Ingress 流量](https://istio.io/docs/tasks/traffic-management/ingress/)。
* [Kong](https://konghq.com/) 为[用于 Kubernetes 的 Kong Ingress 控制器](https://github.com/Kong/kubernetes-ingress-controller) 提供[社区](https://discuss.konghq.com/c/kubernetes)或[商业](https://konghq.com/kong-enterprise/)支持和维护。
* [NGINX, Inc.](https://www.nginx.com/) 为[用于 Kubernetes 的 NGINX Ingress 控制器](https://www.nginx.com/products/nginx/kubernetes-ingress-controller)提供支持和维护。
* [Skipper](https://opensource.zalando.com/skipper/kubernetes/ingress-controller/) HTTP路由器和反向代理,用于服务组合,包括诸如Kubernetes Ingress之类的用例,被设计为用于构建自定义代理的库。
* [Traefik](https://github.com/containous/traefik) 是一个全功能的 ingress 控制器
[Let's Encrypt](https://letsencrypt.org)secretshttp2websocket),并且它也有来自 [Containous](https://containo.us/services) 的商业支持。
<!--
## Using multiple Ingress controllers
You may deploy [any number of ingress controllers](https://git.k8s.io/ingress-nginx/docs/user-guide/multiple-ingress.md#multiple-ingress-controllers)
within a cluster. When you create an ingress, you should annotate each ingress with the appropriate
[`ingress.class`](https://git.k8s.io/ingress-gce/docs/faq/README.md#how-do-i-run-multiple-ingress-controllers-in-the-same-cluster)
to indicate which ingress controller should be used if more than one exists within your cluster.
If you do not define a class, your cloud provider may use a default ingress controller.
Ideally, all ingress controllers should fulfill this specification, but the various ingress
controllers operate slightly differently.
-->
## 使用多个 Ingress 控制器
你可以在集群中部署[任意数量的 ingress 控制器](https://git.k8s.io/ingress-nginx/docs/user-guide/multiple-ingress.md#multiple-ingress-controllers)。
创建 ingress 时,应该使用适当的
[`ingress.class`](https://git.k8s.io/ingress-gce/docs/faq/README.md#how-do-i-run-multiple-ingress-controllers-in-the-same-cluster) 注解每个 ingress
以表明在集群中如果有多个 ingress 控制器时,应该使用哪个 ingress 控制器。
如果不定义 `ingress.class`,云提供商可能使用默认的 ingress 控制器。
理想情况下,所有 ingress 控制器都应满足此规范,但各种 ingress 控制器的操作略有不同。
{{< note >}}
<!--
Make sure you review your ingress controller's documentation to understand the caveats of choosing it.
-->
确保您查看了 ingress 控制器的文档,以了解选择它的注意事项。
{{< /note >}}
{{% /capture %}}
{{% capture whatsnext %}}
<!--
* Learn more about [Ingress](/docs/concepts/services-networking/ingress/).
* [Set up Ingress on Minikube with the NGINX Controller](/docs/tasks/access-application-cluster/ingress-minikube).
-->
* 了解更多关于 [Ingress](/docs/concepts/services-networking/ingress/)。
* [在 Minikube 上使用 NGINX 控制器安装 Ingress](/docs/tasks/access-application-cluster/ingress-minikube)。
{{% /capture %}}
@@ -0,0 +1,729 @@
---
title: Ingress
content_template: templates/concept
weight: 40
---
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.1" state="beta" >}}
{{< glossary_definition term_id="ingress" length="all" >}}
{{% /capture %}}
{{% capture body %}}
<!--
## Terminology
For clarity, this guide defines the following terms:
Node
: A worker machine in Kubernetes, part of a cluster.
Cluster
: A set of Nodes that run containerized applications managed by Kubernetes. For this example, and in most common Kubernetes deployments, nodes in the cluster are not part of the public internet.
Edge router
: A router that enforces the firewall policy for your cluster. This could be a gateway managed by a cloud provider or a physical piece of hardware.
Cluster network
: A set of links, logical or physical, that facilitate communication within a cluster according to the Kubernetes [networking model](/docs/concepts/cluster-administration/networking/).
Service
: A Kubernetes {{< glossary_tooltip term_id="service" >}} that identifies a set of Pods using {{< glossary_tooltip text="label" term_id="label" >}} selectors. Unless mentioned otherwise, Services are assumed to have virtual IPs only routable within the cluster network.
-->
## 专用术语
为了避免歧义,本指南定义了以下术语:
节点
Kubernetes 集群中的单个工作机器。
集群
:运行由Kubernetes管理的容器化应用程序的一组节点。 对于此示例,在大多数常见的Kubernetes部署中,群集中的节点不属于公共网络。
边缘路由器
:为集群强制执行防火墙策略的路由器。这可以是由云提供商管理的网关或物理硬件。
集群网络
:一组逻辑或物理的链接,根据 Kubernetes [网络模型](/docs/concepts/cluster-administration/networking/) 在集群内实现通信。
服务:
Kubernetes {{< glossary_tooltip term_id="service" >}} 使用 {{< glossary_tooltip text="标签" term_id="label" >}} 选择器标识一组 Pod。除非另有说明,否则假定服务只具有在集群网络中可路由的虚拟 IP。
<!--
## What is Ingress?
Ingress exposes HTTP and HTTPS routes from outside the cluster to
{{< link text="services" url="/docs/concepts/services-networking/service/" >}} within the cluster.
Traffic routing is controlled by rules defined on the Ingress resource.
-->
## Ingress 是什么?
Ingress公开了从群集外部到群集内 {{< link text="services" url="/docs/concepts/services-networking/service/" >}} 的HTTP和HTTPS路由。
流量路由由Ingress资源上定义的规则控制。
```none
internet
|
[ Ingress ]
--|-----|--
[ Services ]
```
<!--
An Ingress can be configured to give Services externally-reachable URLs, load balance traffic, terminate SSL / TLS, and offer name based virtual hosting. An [Ingress controller](/docs/concepts/services-networking/ingress-controllers) is responsible for fulfilling the Ingress, usually with a load balancer, though it may also configure your edge router or additional frontends to help handle the traffic.
An Ingress can be configured to give Services externally-reachable URLs, load balance traffic, terminate SSL / TLS, and offer name based virtual hosting. An [Ingress controller](/docs/concepts/services-networking/ingress-controllers) is responsible for fulfilling the Ingress, usually with a load balancer, though it may also configure your edge router or additional frontends to help handle the traffic.
An Ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typically
uses a service of type [Service.Type=NodePort](/docs/concepts/services-networking/service/#nodeport) or
[Service.Type=LoadBalancer](/docs/concepts/services-networking/service/#loadbalancer).
-->
可以将Ingress配置为提供服务外部可访问的URL,负载平衡流量,终止 SSL / TLS 并提供基于名称的虚拟主机。 [Ingress 控制器](/docs/concepts/services-networking/ingress-controllers)通常负责通过负载平衡器来实现入口,尽管它也可以配置边缘路由器或其他前端以帮助处理流量。
Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开给 Internet 时,通常使用以下类型的服务 [Service.Type=NodePort](/docs/concepts/services-networking/service/#nodeport) 或者 [Service.Type=LoadBalancer](/docs/concepts/services-networking/service/#loadbalancer).
<!--
## Prerequisites
You must have an [ingress controller](/docs/concepts/services-networking/ingress-controllers) to satisfy an Ingress. Only creating an Ingress resource has no effect.
You may need to deploy an Ingress controller such as [ingress-nginx](https://kubernetes.github.io/ingress-nginx/deploy/). You can choose from a number of
[Ingress controllers](/docs/concepts/services-networking/ingress-controllers).
Ideally, all Ingress controllers should fit the reference specification. In reality, the various Ingress
controllers operate slightly differently.
-->
## 环境准备
您必须具有[ Ingress 控制器](/docs/concepts/services-networking/ingress-controllers)才能满足Ingress的要求。 仅创建Ingress资源无效。
您可以部署一个 Ingress 控制器
GCEGoogle Kubernetes Engine 是在主节点上部署 Ingress 控制器。
您可以在 Pod 中部署任意数量的自定义 Ingress 控制器。
您必须使用适当的类来注释每个 Ingress,如[这里](https://git.k8s.io/ingress-nginx/docs/user-guide/multiple-ingress.md#multiple-ingress-controllers) 和 [这里](https://git.k8s.io/ingress-gce/examples/PREREQUISITES.md#ingress-class) 所示。
一定要检查一下这个控制器的 [beta 限制](https://github.com/kubernetes/ingress-gce/blob/master/BETA_LIMITATIONS.md#glbc-beta-limitations)。
在 GCEGoogle Kubernetes Engine 之外的环境中,需要将[控制器部署](https://git.k8s.io/ingress-nginx/README.md) 为 Pod。
{{< note >}}
<!--
Make sure you review your Ingress controller's documentation to understand the caveats of choosing it.
-->
确保您查看了 Ingress 控制器的文档,以了解选择它的注意事项。
{{< /note >}}
<!--
## The Ingress Resource
A minimal Ingress resource example:
-->
## Ingress 资源
最小的 Ingress 资源实例:
```yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: test
servicePort: 80
```
<!--
As with all other Kubernetes resources, an Ingress needs `apiVersion`, `kind`, and `metadata` fields.
For general information about working with config files, see [deploying applications](/docs/tasks/run-application/run-stateless-application-deployment/), [configuring containers](/docs/tasks/configure-pod-container/configure-pod-configmap/), [managing resources](/docs/concepts/cluster-administration/manage-deployment/).
Ingress frequently uses annotations to configure some options depending on the Ingress controller, an example of which
is the [rewrite-target annotation](https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/rewrite/README.md).
Different [Ingress controller](/docs/concepts/services-networking/ingress-controllers) support different annotations. Review the documentation for
your choice of Ingress controller to learn which annotations are supported.
The Ingress [spec](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)
has all the information needed to configure a load balancer or proxy server. Most importantly, it
contains a list of rules matched against all incoming requests. Ingress resource only supports rules
for directing HTTP traffic.
-->
与所有其他 Kubernetes 资源一样,Ingress 需要使用 `apiVersion`, `kind`, 和 `metadata`字段。
有关使用配置文件的一般信息,请参阅[部署应用程序](/docs/tasks/run-application/run-stateless-application-deployment/)[配置容器](/docs/tasks/configure-pod-container/configure-pod-configmap/)[管理资源](/docs/concepts/cluster-administration/manage-deployment/)。
Ingress 经常根据 Ingress 控制器使用注释来配置一些选项,例如 [rewrite-target注解](https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/rewrite/README.md)
不同的[Ingress控制器](/docs/concepts/services-networking/ingress-controllers)支持不同的注释。
查看文档以供您选择 Ingress 控制器,以了解支持哪些注释。
Ingress [spec](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status) 具有配置负载平衡器或代理服务器所需的所有信息。
最重要的是,它包含与所有传入请求匹配的规则列表。 Ingress 资源仅支持用于定向HTTP流量的规则。
<!--
### Ingress rules
Each HTTP rule contains the following information:
* An optional host. In this example, no host is specified, so the rule applies to all inbound
HTTP traffic through the IP address specified. If a host is provided (for example,
foo.bar.com), the rules apply to that host.
* A list of paths (for example, `/testpath`), each of which has an associated backend defined with a `serviceName`
and `servicePort`. Both the host and path must match the content of an incoming request before the
load balancer directs traffic to the referenced Service.
* A backend is a combination of Service and port names as described in the
[Service doc](/docs/concepts/services-networking/service/). HTTP (and HTTPS) requests to the
Ingress that matches the host and path of the rule are sent to the listed backend.
A default backend is often configured in an Ingress controller to service any requests that do not
match a path in the spec.
-->
### Ingress 规则
每个HTTP规则都包含以下信息:
* host 选项。在此示例中,未指定主机,因此该规则适用于通过指定 IP 地址的所有入站 HTTP 通信。 如果提供了 host 地址(例如foo.bar.com),则规则适用于该主机。
* 路径列表(例如,`/testpath` ),每个路径都有一个由 `serviceName``servicePort` 定义的关联后端。在负载均衡器将流量定向到引用的服务之前,主机和路径都必须匹配传入请求的内容。
* 后端是 [服务文档](/docs/concepts/services-networking/service/) 中所述的服务和端口名称的组合。与规则的主机和路径匹配的对 Ingress 的 HTTP 和 HTTPS 请求将发送到列出的后端。
<!--
### Default Backend
An Ingress with no rules sends all traffic to a single default backend. The default
backend is typically a configuration option of the [Ingress controller](/docs/concepts/services-networking/ingress-controllers) and is not specified in your Ingress resources.
If none of the hosts or paths match the HTTP request in the Ingress objects, the traffic is
routed to your default backend.
-->
### 默认后端
没有设定规则的 Ingress 将所有流量发送到单个默认后端。
默认后端通常是 [Ingress控制器](/docs/concepts/services-networking/ingress-controllers) 的配置选项,并且未在Ingress资源中指定。
如果没有主机或路径与 Ingress 对象中的 HTTP 请求匹配,则流量将路由到您的默认后端。
<!--
## Types of Ingress
### Single Service Ingress
There are existing Kubernetes concepts that allow you to expose a single Service
(see [alternatives](#alternatives)). You can also do this with an Ingress by specifying a
*default backend* with no rules.
-->
## Ingress 的类型
### 单服务 Ingress
现有的 Kubernetes 概念允许您暴露单个 Service (查看 [替代方案](#alternatives))
同样您也可以使用 Ingress 来实现,具体方法是指定一个没有规则的 *默认后端(default backend*
{{< codenew file="service/networking/ingress.yaml" >}}
<!--
If you create it using `kubectl apply -f` you should be able to view the state
of the Ingress you just added:
-->
如果使用 `kubectl apply -f` 创建它,则应该能够查看刚刚添加的Ingress的状态:
```shell
kubectl get ingress test-ingress
```
```
NAME HOSTS ADDRESS PORTS AGE
test-ingress * 107.178.254.228 80 59s
```
<!--
Where `107.178.254.228` is the IP allocated by the Ingress controller to satisfy
this Ingress.
-->
其中 `107.178.254.228` 是 Ingress 控制器为该 Ingress 分配的 IP 该。
{{< note >}}
<!--
Ingress controllers and load balancers may take a minute or two to allocate an IP address.
Until that time, you often see the address listed as `<pending>`.
-->
入口控制器和负载平衡器可能需要一两分钟才能分配IP地址。 在此之前,您通常会看到地址字段的值被设定为 `<pending>`
{{< /note >}}
<!--
### Simple fanout
A fanout configuration routes traffic from a single IP address to more than one Service,
based on the HTTP URI being requested. An Ingress allows you to keep the number of load balancers
down to a minimum. For example, a setup like:
-->
### 简单分列
分列配置根据请求的 HTTP URI 将流量从单个IP地址路由到多个服务。
通过Ingress,您可以将负载均衡器的数量保持在最低水平。 例如,如下设置:
```none
foo.bar.com -> 178.91.123.132 -> / foo service1:4200
/ bar service2:8080
```
<!--
would require an Ingress such as:
-->
可能需要一个 Ingress 就像:
```yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: simple-fanout-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
backend:
serviceName: service1
servicePort: 4200
- path: /bar
backend:
serviceName: service2
servicePort: 8080
```
<!--
When you create the Ingress with `kubectl apply -f`:
-->
当您使用 `kubectl apply -f` 创建 Ingress 时:
```shell
kubectl describe ingress test
```
```shell
kubectl describe ingress simple-fanout-example
```
```
Name: simple-fanout-example
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:4200 (10.8.0.90:4200)
/bar service2:8080 (10.8.0.91:8080)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 22s loadbalancer-controller default/test
```
<!--
The Ingress controller provisions an implementation-specific load balancer
that satisfies the Ingress, as long as the Services (`service1`, `service2`) exist.
When it has done so, you can see the address of the load balancer at the
Address field.
-->
Ingress 控制器提供实现特定的负载均衡器来满足 Ingress,只要 Service (`service1`, `service2`) 存在。
当它这样做了,你会在地址栏看到负载平衡器的地址。
{{< note >}}
<!--
Depending on the [Ingress controller](/docs/concepts/services-networking/ingress-controllers)
you are using, you may need to create a default-http-backend
[Service](/docs/concepts/services-networking/service/).
-->
取决于你使用的 [Ingress 控制器](/docs/concepts/services-networking/ingress-controllers),
您可能需要创建一个默认的 http-backend [Service](/docs/concepts/services-networking/service/).。
{{< /note >}}
<!--
### Name based virtual hosting
Name-based virtual hosts support routing HTTP traffic to multiple host names at the same IP address.
-->
### 基于名称的虚拟托管
基于名称的虚拟主机支持将 HTTP 流量路由到同一 IP 地址上的多个主机名。
```none
foo.bar.com --| |-> foo.bar.com service1:80
| 178.91.123.132 |
bar.foo.com --| |-> bar.foo.com service2:80
```
<!--
The following Ingress tells the backing load balancer to route requests based on
the [Host header](https://tools.ietf.org/html/rfc7230#section-5.4).
-->
下面的 Ingress 让后台的负载均衡器基于 [Host header](https://tools.ietf.org/html/rfc7230#section-5.4) 路由请求。
```yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
- host: bar.foo.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
```
<!--
If you create an Ingress resource without any hosts defined in the rules, then any
web traffic to the IP address of your Ingress controller can be matched without a name based
virtual host being required.
For example, the following Ingress resource will route traffic
requested for `first.bar.com` to `service1`, `second.foo.com` to `service2`, and any traffic
to the IP address without a hostname defined in request (that is, without a request header being
presented) to `service3`.
-->
如果您在规则中未定义任何主机的情况下创建 Ingress 资源,则可以匹配到 Ingress 控制器 IP 地址的任何网络流量,而无需基于名称的虚拟主机。
例如,以下Ingress资源会将 `first.bar.com` 请求的流量路由到 `service1`,将 `second.foo.com` 请求的流量路由到 `service2`
而所有到IP地址但未在请求中定义主机名的流量 (也就是说,不向 `service3` 提供请求报文头)。
```yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: first.bar.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
- host: second.foo.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
- http:
paths:
- backend:
serviceName: service3
servicePort: 80
```
<!--
### TLS
You can secure an Ingress by specifying a {{< glossary_tooltip term_id="secret" >}}
that contains a TLS private key and certificate. Currently the Ingress only
supports a single TLS port, 443, and assumes TLS termination. If the TLS
configuration section in an Ingress specifies different hosts, they are
multiplexed on the same port according to the hostname specified through the
SNI TLS extension (provided the Ingress controller supports SNI). The TLS secret
must contain keys named `tls.crt` and `tls.key` that contain the certificate
and private key to use for TLS. For example:
-->
### TLS
您可以通过指定包含TLS私钥和证书的 {{< glossary_tooltip term_id="secret" >}} 来加密 Ingress。
目前,Ingress 只支持单个 TLS 端口,443,并假定 TLS 终止。
如果 Ingress 中的 TLS 配置部分指定了不同的主机,那么它们将根据通过 SNI TLS 扩展指定的主机名(如果 Ingress 控制器支持 SNI)在同一端口上进行复用。
TLS Secret 必须包含名为 `tls.crt``tls.key` 的密钥,这些密钥包含用于 TLS 的证书和私钥,例如:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: testsecret-tls
namespace: default
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
type: kubernetes.io/tls
```
<!--
Referencing this secret in an Ingress tells the Ingress controller to
secure the channel from the client to the load balancer using TLS. You need to make
sure the TLS secret you created came from a certificate that contains a CN
for `sslexample.foo.com`.
-->
在 Ingress 中引用此秘钥会告诉 Ingress 控制器使用 TLS 保护从客户端到负载均衡器的通道。
您需要确保创建包含 `sslexample.foo.com` 的 TLS 秘钥的 CN 的证书。
```yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
tls:
- hosts:
- sslexample.foo.com
secretName: testsecret-tls
rules:
- host: sslexample.foo.com
http:
paths:
- path: /
backend:
serviceName: service1
servicePort: 80
```
{{< note >}}
<!--
There is a gap between TLS features supported by various Ingress
controllers. Please refer to documentation on
[nginx](https://git.k8s.io/ingress-nginx/README.md#https),
[GCE](https://git.k8s.io/ingress-gce/README.md#frontend-https), or any other
platform specific Ingress controller to understand how TLS works in your environment.
-->
各种 Ingress 控制器所支持的 TLS 功能之间存在间隙。请参阅有关文件
[nginx](https://git.k8s.io/ingress-nginx/README.md#https)
[GCE](https://git.k8s.io/ingress-gce/README.md#frontend-https)
或任何其他平台特定的 Ingress 控制器,以了解 TLS 如何在您的环境中工作。
{{< /note >}}
<!--
### Loadbalancing
An Ingress controller is bootstrapped with some load balancing policy settings
that it applies to all Ingress, such as the load balancing algorithm, backend
weight scheme, and others. More advanced load balancing concepts
(e.g. persistent sessions, dynamic weights) are not yet exposed through the
Ingress. You can instead get these features through the load balancer used for
a Service.
-->
### 负载均衡
Ingress 控制器使用一些适用于所有 Ingress 的负载均衡策略设置进行自举,例如负载平衡算法、后端权重方案等。
更高级的负载平衡概念(例如,持久会话、动态权重)尚未通过 Ingress 公开。
您可以通过用于服务的负载平衡器来获取这些功能。
<!--
It's also worth noting that even though health checks are not exposed directly
through the Ingress, there exist parallel concepts in Kubernetes such as
[readiness probes](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/)
that allow you to achieve the same end result. Please review the controller
specific documentation to see how they handle health checks (
[nginx](https://git.k8s.io/ingress-nginx/README.md),
[GCE](https://git.k8s.io/ingress-gce/README.md#health-checks)).
-->
值得注意的是,即使健康检查不是通过 Ingress 直接暴露的,但是在 Kubernetes 中存在并行概念,比如 [就绪检查](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/),它允许您实现相同的最终结果。
请检查控制器说明文档,以了解他们是怎样实现健康检查的 (
[nginx](https://git.k8s.io/ingress-nginx/README.md)
[GCE](https://git.k8s.io/ingress-gce/README.md#health-checks))。
<!--
## Updating an Ingress
To update an existing Ingress to add a new Host, you can update it by editing the resource:
-->
## 更新 Ingress
假设您想向现有的 Ingress 中添加新主机,可以通过编辑资源来更新它:
```shell
kubectl describe ingress test
```
```
Name: test
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:80 (10.8.0.90:80)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 35s loadbalancer-controller default/test
```
```shell
kubectl edit ingress test
```
<!--
This pops up an editor with the existing configuration in YAML format.
Modify it to include the new Host:
-->
弹出一个编辑器用于编辑现有的 yaml,修改它来增加新的主机:
```yaml
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
path: /foo
- host: bar.baz.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
path: /foo
..
```
<!--
After you save your changes, kubectl updates the resource in the API server, which tells the
Ingress controller to reconfigure the load balancer.
Verify this:
-->
保存更改后,kubectl 将更新 API 服务器中的资源,该资源将告诉 Ingress 控制器重新配置负载平衡器。
验证一下:
```shell
kubectl describe ingress test
```
```
Name: test
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:80 (10.8.0.90:80)
bar.baz.com
/foo service2:80 (10.8.0.91:80)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 45s loadbalancer-controller default/test
```
<!--
You can achieve the same outcome by invoking `kubectl replace -f` on a modified Ingress YAML file.
-->
您可以通过 `kubectl replace -f` 命令调用修改后的 Ingress YAML 文件来获得同样的结果。
<!--
## Failing across availability zones
Techniques for spreading traffic across failure domains differs between cloud providers.
Please check the documentation of the relevant [Ingress controller](/docs/concepts/services-networking/ingress-controllers) for details. You can also refer to the [federation documentation](/docs/concepts/cluster-administration/federation/)
for details on deploying Ingress in a federated cluster.
-->
## 跨可用区失败
用于跨故障域传播流量的技术在云提供商之间是不同的。详情请查阅相关 Ingress 控制器的文档。
请查看相关[Ingress控制器](/docs/concepts/services-networking/ingress-controllers)的文档以了解详细信息。
您还可以参考[联合文档](/docs/concepts/cluster-administration/federation/),以获取有关在联合群集中部署Ingress的详细信息。
<!--
## Future Work
Track [SIG Network](https://github.com/kubernetes/community/tree/master/sig-network)
for more details on the evolution of Ingress and related resources. You may also track the
[Ingress repository](https://github.com/kubernetes/ingress/tree/master) for more details on the
evolution of various Ingress controllers.
-->
## 未来的工作
跟踪 [SIG网络](https://github.com/kubernetes/community/tree/master/sig-network) 详细了解Ingress和相关资源的发展。
您也可以跟踪 [Ingress信息库](https://github.com/kubernetes/ingress/tree/master) 了解 Ingress 控制器进化的更多信息。
<!--
## Alternatives
You can expose a Service in multiple ways that don't directly involve the Ingress resource:
* Use [Service.Type=LoadBalancer](/docs/concepts/services-networking/service/#loadbalancer)
* Use [Service.Type=NodePort](/docs/concepts/services-networking/service/#nodeport)
-->
## 替代方案
不直接使用 Ingress 资源,也有多种方法暴露 Service:
* 使用 [Service.Type=LoadBalancer](/docs/concepts/services-networking/service/#loadbalancer)
* 使用 [Service.Type=NodePort](/docs/concepts/services-networking/service/#nodeport)
{{% /capture %}}
{{% capture whatsnext %}}
<!--
* Learn about [ingress controllers](/docs/concepts/services-networking/ingress-controllers/)
* [Set up Ingress on Minikube with the NGINX Controller](/docs/tasks/access-application-cluster/ingress-minikube)
-->
* 了解 [ingress 控制器](/docs/concepts/services-networking/ingress-controllers/)
* [使用NGINX控制器在Minikube上设置Ingress](/docs/tasks/access-application-cluster/ingress-minikube)
{{% /capture %}}
@@ -1,30 +1,62 @@
--- ---
approvers:
- thockin
- caseydavenport
- danwinship
title: 网络策略 title: 网络策略
content_template: templates/concept
weight: 50
--- ---
{{< toc >}} {{< toc >}}
{{% capture overview %}}
<!--
A network policy is a specification of how groups of pods are allowed to communicate with each other and other network endpoints.
`NetworkPolicy` resources use labels to select pods and define rules which specify what traffic is allowed to the selected pods.
-->
网络策略(NetworkPolicy)是一种关于pod间及pod与其他网络端点间所允许的通信规则的规范。 网络策略(NetworkPolicy)是一种关于pod间及pod与其他网络端点间所允许的通信规则的规范。
`NetworkPolicy` 资源使用标签选择pod,并定义选定pod所允许的通信规则。 `NetworkPolicy` 资源使用标签选择pod,并定义选定pod所允许的通信规则。
{{% /capture %}}
{{% capture body %}}
<!--
## Prerequisites
Network policies are implemented by the network plugin, so you must be using a networking solution which supports `NetworkPolicy` - simply creating the resource without a controller to implement it will have no effect.
-->
## 前提 ## 前提
网络策略通过网络插件来实现,所以用户必须使用支持 `NetworkPolicy` 的网络解决方案 - 简单地创建资源对象,而没有控制器来使它生效的话,是没有任何作用的。 网络策略通过网络插件来实现,所以用户必须使用支持 `NetworkPolicy` 的网络解决方案 - 简单地创建资源对象,而没有控制器来使它生效的话,是没有任何作用的。
<!--
## Isolated and Non-isolated Pods
By default, pods are non-isolated; they accept traffic from any source.
Pods become isolated by having a NetworkPolicy that selects them. Once there is any NetworkPolicy in a namespace selecting a particular pod, that pod will reject any connections that are not allowed by any NetworkPolicy. (Other pods in the namespace that are not selected by any NetworkPolicy will continue to accept all traffic.)
-->
## 隔离和非隔离的Pod ## 隔离和非隔离的Pod
默认情况下,Pod是非隔离的,它们接受任何来源的流量。 默认情况下,Pod是非隔离的,它们接受任何来源的流量。
Pod可以通过相关的网络策略进行隔离。一旦命名空间中有网络策略选择了特定的Pod,该Pod会拒绝网络策略所不允许的连接。 (命名空间下其他未被网络策略所选择的Pod会继续接收所有的流量) Pod可以通过相关的网络策略进行隔离。一旦命名空间中有网络策略选择了特定的Pod,该Pod会拒绝网络策略所不允许的连接。 (命名空间下其他未被网络策略所选择的Pod会继续接收所有的流量)
<!--
## The `NetworkPolicy` Resource
See the [NetworkPolicy](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#networkpolicy-v1-networking-k8s-io) for a full definition of the resource.
An example `NetworkPolicy` might look like this:
-->
## `NetworkPolicy` 资源 ## `NetworkPolicy` 资源
通过[api参考](/docs/api-reference/{{< param "version" >}}/#networkpolicy-v1-networking)来了解资源定义。 查看 [网络策略](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#networkpolicy-v1-networking-k8s-io) 来了解资源定义。
下面是一个 `NetworkPolicy` 的示例: 下面是一个 `NetworkPolicy` 的示例:
@@ -38,8 +70,15 @@ spec:
podSelector: podSelector:
matchLabels: matchLabels:
role: db role: db
policyTypes:
- Ingress
- Egress
ingress: ingress:
- from: - from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector: - namespaceSelector:
matchLabels: matchLabels:
project: myproject project: myproject
@@ -49,8 +88,35 @@ spec:
ports: ports:
- protocol: TCP - protocol: TCP
port: 6379 port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
``` ```
<!--
*POSTing this to the API server will have no effect unless your chosen networking solution supports network policy.*
__Mandatory Fields__: As with all other Kubernetes config, a `NetworkPolicy`
needs `apiVersion`, `kind`, and `metadata` fields. For general information
about working with config files, see
[Configure Containers Using a ConfigMap](/docs/tasks/configure-pod-container/configure-pod-configmap/),
and [Object Management](/docs/concepts/overview/working-with-objects/object-management).
__spec__: `NetworkPolicy` [spec](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status) has all the information needed to define a particular network policy in the given namespace.
__podSelector__: Each `NetworkPolicy` includes a `podSelector` which selects the grouping of pods to which the policy applies. The example policy selects pods with the label "role=db". An empty `podSelector` selects all pods in the namespace.
__policyTypes__: Each `NetworkPolicy` includes a `policyTypes` list which may include either `Ingress`, `Egress`, or both. The `policyTypes` field indicates whether or not the given policy applies to ingress traffic to selected pod, egress traffic from selected pods, or both. If no `policyTypes` are specified on a NetworkPolicy then by default `Ingress` will always be set and `Egress` will be set if the NetworkPolicy has any egress rules.
__ingress__: Each `NetworkPolicy` may include a list of whitelist `ingress` rules. Each rule allows traffic which matches both the `from` and `ports` sections. The example policy contains a single rule, which matches traffic on a single port, from one of three sources, the first specified via an `ipBlock`, the second via a `namespaceSelector` and the third via a `podSelector`.
__egress__: Each `NetworkPolicy` may include a list of whitelist `egress` rules. Each rule allows traffic which matches both the `to` and `ports` sections. The example policy contains a single rule, which matches traffic on a single port to any destination in `10.0.0.0/24`.
-->
除非选择支持网络策略的网络解决方案,否则将上述示例发送到API服务器没有任何效果。 除非选择支持网络策略的网络解决方案,否则将上述示例发送到API服务器没有任何效果。
__必填字段__: 与所有其他的Kubernetes配置一样,`NetworkPolicy` 需要 `apiVersion``kind``metadata` 字段。 关于配置文件操作的一般信息,请参考 [这里](/docs/user-guide/simple-yaml)、 [这里](/docs/user-guide/configuring-containers)和 [这里](/docs/user-guide/working-with-resources)。 __必填字段__: 与所有其他的Kubernetes配置一样,`NetworkPolicy` 需要 `apiVersion``kind``metadata` 字段。 关于配置文件操作的一般信息,请参考 [这里](/docs/user-guide/simple-yaml)、 [这里](/docs/user-guide/configuring-containers)和 [这里](/docs/user-guide/working-with-resources)。
@@ -59,19 +125,140 @@ __spec__: `NetworkPolicy` [spec](https://git.k8s.io/community/contributors/devel
__podSelector__: 每个 `NetworkPolicy` 都包括一个 `podSelector` ,它对该策略所应用的一组Pod进行选择。因为 `NetworkPolicy` 目前只支持定义 `ingress` 规则,这里的 `podSelector` 本质上是为该策略定义 "目标pod" 。示例中的策略选择带有 "role=db" 标签的pod。空的 `podSelector` 选择命名空间下的所有pod。 __podSelector__: 每个 `NetworkPolicy` 都包括一个 `podSelector` ,它对该策略所应用的一组Pod进行选择。因为 `NetworkPolicy` 目前只支持定义 `ingress` 规则,这里的 `podSelector` 本质上是为该策略定义 "目标pod" 。示例中的策略选择带有 "role=db" 标签的pod。空的 `podSelector` 选择命名空间下的所有pod。
__ingress__: 每个 `NetworkPolicy` 包含一个 `ingress` 规则的白名单列表。 (其中的)规则允许同时匹配 `from``ports` 部分的流量。示例策略中包含一条简单的规则: 它匹配一个单一的端口,来自两个来源中的一个, 第一个通过 `namespaceSelector` 指定,第二个通过 `podSelector` 指定。 __policyTypes__: Each `NetworkPolicy` includes a `policyTypes` list which may include either `Ingress`, `Egress`, or both. The `policyTypes` field indicates whether or not the given policy applies to ingress traffic to selected pod, egress traffic from selected pods, or both. If no `policyTypes` are specified on a NetworkPolicy then by default `Ingress` will always be set and `Egress` will be set if the NetworkPolicy has any egress rules.
__ingress__: 每个 `NetworkPolicy` 包含一个 `ingress` 规则的白名单列表。(其中的)规则允许同时匹配 `from``ports` 部分的流量。示例策略中包含一条简单的规则: 它匹配一个单一的端口,来自两个来源中的一个, 第一个通过 `namespaceSelector` 指定,第二个通过 `podSelector` 指定。
__egress__: 每个 `NetworkPolicy` 包含一个 `egress` 规则的白名单列表。每个规则都允许匹配 `to``port` 部分的流量。该示例策略包含一条规则,该规则将单个端口上的流量匹配到 `10.0.0.0/24` 中的任何目的地。
<!--
So, the example NetworkPolicy:
1. isolates "role=db" pods in the "default" namespace for both ingress and egress traffic (if they weren't already isolated)
2. (Ingress rules) allows connections to all pods in the “default” namespace with the label “role=db” on TCP port 6379 from:
* any pod in the "default" namespace with the label "role=frontend"
* any pod in a namespace with the label "project=myproject"
* IP addresses in the ranges 172.17.0.0172.17.0.255 and 172.17.2.0172.17.255.255 (ie, all of 172.17.0.0/16 except 172.17.1.0/24)
3. (Egress rules) allows connections from any pod in the "default" namespace with the label "role=db" to CIDR 10.0.0.0/24 on TCP port 5978
See the [Declare Network Policy](/docs/tasks/administer-cluster/declare-network-policy/) walkthrough for further examples.
-->
所以,示例网络策略: 所以,示例网络策略:
1. 隔离 "default" 命名空间下 "role=db" 的pod (如果它们不是已经被隔离的话)。 1. 隔离 "default" 命名空间下 "role=db" 的pod (如果它们不是已经被隔离的话)。
2. 允许从 "default" 命名空间下带有 "role=frontend" 标签的pod到 "default" 命名空间下的pod的6379 TCP端口的连接。 2. 允许从 "default" 命名空间下带有 "role=frontend" 标签的pod到 "default" 命名空间下的pod的6379 TCP端口的连接。
3. 允许从带有 "project=myproject" 标签的命名空间下的任何pod到 "default" 命名空间下的pod的6379 TCP端口的连接。
* 标签为 "role=frontend" 的 "default" 名称空间中的任何Pod
* 名称空间中带有标签 "project=myproject" 的任何pod
* IP 地址范围为 172.17.0.0172.17.0.255 和 172.17.2.0172.17.255.255(即,除了 172.17.1.0/24 之外的所有 172.17.0.0/16
3. 允许从带有 "project=myproject" 标签的命名空间下的任何 pod 到 "default" 命名空间下的 pod 的6379 TCP端口的连接。
查看 [网络策略入门指南](/docs/getting-started-guides/network-policy/walkthrough) 了解更多示例。 查看 [网络策略入门指南](/docs/getting-started-guides/network-policy/walkthrough) 了解更多示例。
<!--
## Behavior of `to` and `from` selectors
There are four kinds of selectors that can be specified in an `ingress` `from` section or `egress` `to` section:
__podSelector__: This selects particular Pods in the same namespace as the `NetworkPolicy` which should be allowed as ingress sources or egress destinations.
__namespaceSelector__: This selects particular namespaces for which all Pods should be allowed as ingress sources or egress destinations.
__namespaceSelector__ *and* __podSelector__: A single `to`/`from` entry that specifies both `namespaceSelector` and `podSelector` selects particular Pods within particular namespaces. Be careful to use correct YAML syntax; this policy:
-->
## 选择器 `to``from` 的行为
可以在 `ingress` `from` 部分或 `egress` `to` 部分中指定四种选择器:
__podSelector__: 这将在与 `NetworkPolicy` 相同的名称空间中选择特定的 Pod,应将其允许作为入口源或出口目的地。
__namespaceSelector__: 这将选择特定的名称空间,应将所有 Pod 用作其输入源或输出目的地。
__namespaceSelector__ ** __podSelector__: 一个指定 `namespaceSelector``podSelector``to`/`from` 条目选择特定命名空间中的特定 Pod。注意使用正确的YAML语法;这项政策:
```yaml
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
podSelector:
matchLabels:
role: client
...
```
contains a single `from` element allowing connections from Pods with the label `role=client` in namespaces with the label `user=alice`. But *this* policy:
```yaml
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
- podSelector:
matchLabels:
role: client
...
```
<!--
contains two elements in the `from` array, and allows connections from Pods in the local Namespace with the label `role=client`, *or* from any Pod in any namespace with the label `user=alice`.
When in doubt, use `kubectl describe` to see how Kubernetes has interpreted the policy.
__ipBlock__: This selects particular IP CIDR ranges to allow as ingress sources or egress destinations. These should be cluster-external IPs, since Pod IPs are ephemeral and unpredictable.
Cluster ingress and egress mechanisms often require rewriting the source or destination IP
of packets. In cases where this happens, it is not defined whether this happens before or
after NetworkPolicy processing, and the behavior may be different for different
combinations of network plugin, cloud provider, `Service` implementation, etc.
In the case of ingress, this means that in some cases you may be able to filter incoming
packets based on the actual original source IP, while in other cases, the "source IP" that
the NetworkPolicy acts on may be the IP of a `LoadBalancer` or of the Pod's node, etc.
For egress, this means that connections from pods to `Service` IPs that get rewritten to
cluster-external IPs may or may not be subject to `ipBlock`-based policies.
-->
`from` 数组中包含两个元素,允许来自本地命名空间中标有 `role = client` 的 Pod 的连接,*或*来自任何名称空间中标有`user = alice`的任何Pod的连接。
如有疑问,请使用 `kubectl describe` 查看 Kubernetes 如何解释该策略。
__ipBlock__: 这将选择特定的 IP CIDR 范围以用作入口源或出口目的地。 这些应该是群集外部 IP,因为 Pod IP 存在时间短暂的且随机产生。
群集的入口和出口机制通常需要重写数据包的源 IP 或目标 IP。在发生这种情况的情况下,不确定在 NetworkPolicy 处理之前还是之后发生,并且对于网络插件,云提供商,`Service` 实现等的不同组合,其行为可能会有所不同。
在进入的情况下,这意味着在某些情况下,您可以根据实际的原始源 IP 过滤传入的数据包,而在其他情况下,NetworkPolicy 所作用的 `源IP` 则可能是 `LoadBalancer` 或 Pod的节点等。
对于出口,这意味着从 Pod 到被重写为集群外部 IP 的 `Service` IP 的连接可能会或可能不会受到基于 `ipBlock` 的策略的约束。
<!--
## Default policies
By default, if no policies exist in a namespace, then all ingress and egress traffic is allowed to and from pods in that namespace. The following examples let you change the default behavior
in that namespace.
-->
## 默认策略 ## 默认策略
用户可以通过创建一个选择所有Pod,但是不允许任何通信的网络策略,来为一个命名空间创建 "默认的" 隔离策略: 默认情况下,如果名称空间中不存在任何策略,则所有进出该名称空间中的Pod的流量都被允许。以下示例使您可以更改该名称空间中的默认行为。
<!--
### Default deny all ingress traffic
You can create a "default" isolation policy for a namespace by creating a NetworkPolicy that selects all pods but does not allow any ingress traffic to those pods.
-->
### 默认拒绝所有入口流量
您可以通过创建选择所有容器但不允许任何进入这些容器的入口流量的 NetworkPolicy 来为名称空间创建 "default" 隔离策略。
```yaml ```yaml
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1
@@ -79,12 +266,25 @@ kind: NetworkPolicy
metadata: metadata:
name: default-deny name: default-deny
spec: spec:
podSelector: podSelector: {}
policyTypes:
- Ingress
``` ```
这可以确保即使Pod在未被其他任何网络策略所选择的情况下仍能被隔离。 <!--
This ensures that even pods that aren't selected by any other NetworkPolicy will still be isolated. This policy does not change the default egress isolation behavior.
-->
这样可以确保即使容器没有选择其他任何 NetworkPolicy,也仍然可以被隔离。此策略不会更改默认的出口隔离行为。
或者,如果用户希望允许一个命名空间下的所有Pod的所有通信 (即使已经添加了策略,使得一些pod被 "隔离"),仍可以创建一个明确允许所有通信的策略: <!--
### Default allow all ingress traffic
If you want to allow all traffic to all pods in a namespace (even if policies are added that cause some pods to be treated as "isolated"), you can create a policy that explicitly allows all traffic in that namespace.
-->
### 默认允许所有入口流量
如果要允许所有流量进入某个命名空间中的所有 Pod(即使添加了导致某些 Pod 被视为“隔离”的策略),则可以创建一个策略来明确允许该命名空间中的所有流量。
```yaml ```yaml
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1
@@ -92,12 +292,119 @@ kind: NetworkPolicy
metadata: metadata:
name: allow-all name: allow-all
spec: spec:
podSelector: podSelector: {}
ingress: ingress:
- {} - {}
policyTypes:
- Ingress
``` ```
## 下一步呢? <!--
### Default deny all egress traffic
You can create a "default" egress isolation policy for a namespace by creating a NetworkPolicy that selects all pods but does not allow any egress traffic from those pods.
-->
### 默认拒绝所有出口流量
您可以通过创建选择所有容器但不允许来自这些容器的任何出口流量的 NetworkPolicy 来为名称空间创建 "default" egress 隔离策略。
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Egress
```
<!--
This ensures that even pods that aren't selected by any other NetworkPolicy will not be allowed egress traffic. This policy does not
change the default ingress isolation behavior.
-->
这样可以确保即使没有被其他任何 NetworkPolicy 选择的 Pod 也不会被允许流出流量。此策略不会更改默认的 ingress 隔离行为。
<!--
### Default allow all egress traffic
If you want to allow all traffic from all pods in a namespace (even if policies are added that cause some pods to be treated as "isolated"), you can create a policy that explicitly allows all egress traffic in that namespace.
-->
### 默认允许所有出口流量
如果要允许来自命名空间中所有 Pod 的所有流量(即使添加了导致某些 Pod 被视为“隔离”的策略),则可以创建一个策略,该策略明确允许该命名空间中的所有出口流量。
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress
```
<!--
### Default deny all ingress and all egress traffic
You can create a "default" policy for a namespace which prevents all ingress AND egress traffic by creating the following NetworkPolicy in that namespace.
-->
### 默认拒绝所有入口和所有出口流量
您可以为名称空间创建 "default" 策略,以通过在该名称空间中创建以下 NetworkPolicy 来阻止所有入站和出站流量。
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
```
<!--
This ensures that even pods that aren't selected by any other NetworkPolicy will not be allowed ingress or egress traffic.
-->
这样可以确保即使没有被其他任何 NetworkPolicy 选择的 Pod 也不会被允许进入或流出流量。
<!--
## SCTP support
-->
## SCTP 支持
{{< feature-state for_k8s_version="v1.12" state="alpha" >}}
<!--
Kubernetes supports SCTP as a `protocol` value in `NetworkPolicy` definitions as an alpha feature. To enable this feature, the cluster administrator needs to enable the `SCTPSupport` feature gate on the apiserver, for example, `“--feature-gates=SCTPSupport=true,...”`. When the feature gate is enabled, users can set the `protocol` field of a `NetworkPolicy` to `SCTP`. Kubernetes sets up the network accordingly for the SCTP associations, just like it does for TCP connections.
The CNI plugin has to support SCTP as `protocol` value in `NetworkPolicy`.
-->
Kubernetes 支持 SCTP 作为 NetworkPolicy 定义中的协议值作为 alpha 功能提供。要启用此功能,集群管理员需要在 apiserver 上启用 `SCTPSupport` 功能门,例如 `“--feature-gates=SCTPSupport=true,...”`。启用功能门后,用户可以将 `NetworkPolicy``protocol` 字段设置为 `SCTP`。 Kubernetes 相应地为 SCTP 关联设置网络,就像为 TCP 连接一样。
CNI插件必须在 `NetworkPolicy` 中将 SCTP 作为 `protocol` 值支持。
{{% /capture %}}
{{% capture whatsnext %}}
<!--
- See the [Declare Network Policy](/docs/tasks/administer-cluster/declare-network-policy/)
walkthrough for further examples.
- See more [Recipes](https://github.com/ahmetb/kubernetes-network-policy-recipes) for common scenarios enabled by the NetworkPolicy resource.
-->
- 查看 [声明网络策略](/docs/tasks/administer-cluster/declare-network-policy/) - 查看 [声明网络策略](/docs/tasks/administer-cluster/declare-network-policy/)
来进行更多的示例演练 来进行更多的示例演练
- 有关NetworkPolicy资源启用的常见方案的更多信息,请参见 [Recipes](https://github.com/ahmetb/kubernetes-network-policy-recipes)。
{{% /capture %}}
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
---
title: Ingress
id: ingress
date: 2018-04-12
full_link: /docs/concepts/services-networking/ingress/
short_description: >
An API object that manages external access to the services in a cluster, typically HTTP.
aka:
tags:
- networking
- architecture
- extension
---
<!--
An API object that manages external access to the services in a cluster, typically HTTP.
-->
一个 API 对象,用于管理对集群中服务的外部访问,通常是 HTTP。
<!--more-->
<!--
Ingress can provide load balancing, SSL termination and name-based virtual hosting.
-->
Ingress 可以提供负载平衡,SSL 终端和基于名称的虚拟主机。
+25
View File
@@ -0,0 +1,25 @@
---
title: Service
id: service
date: 2018-04-12
full_link: /docs/concepts/services-networking/service/
short_description: >
A way to expose an application running on a set of Pods as a network service.
aka:
tags:
- fundamental
- core-object
---
<!--
An abstract way to expose an application running on a set of {{< glossary_tooltip text="Pods" term_id="pod" >}} as a network service.
-->
将运行在一组 {{< glossary_tooltip text="Pods" term_id="pod" >}} 上的应用程序公开为网络服务的抽象方法。
<!--more-->
<!--
The set of Pods targeted by a Service is (usually) determined by a {{< glossary_tooltip text="selector" term_id="selector" >}}. If more Pods are added or removed, the set of Pods matching the selector will change. The Service makes sure that network traffic can be directed to the current set of Pods for the workload.
-->
服务所针对的Pod集(通常)由 {{< glossary_tooltip text="selector" term_id="selector" >}} 确定。 如果添加或删除了更多Pod,则与选择器匹配的Pod集将发生变化。 该服务确保可以将网络流量定向到该工作负载的当前Pod集。
@@ -0,0 +1,4 @@
FROM nginx:1.17.3
RUN rm /etc/nginx/conf.d/default.conf
COPY frontend.conf /etc/nginx/conf.d
@@ -0,0 +1,11 @@
upstream hello {
server hello;
}
server {
listen 80;
location / {
proxy_pass http://hello;
}
}
@@ -0,0 +1,39 @@
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
selector:
app: hello
tier: frontend
ports:
- protocol: "TCP"
port: 80
targetPort: 80
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
selector:
matchLabels:
app: hello
tier: frontend
track: stable
replicas: 1
template:
metadata:
labels:
app: hello
tier: frontend
track: stable
spec:
containers:
- name: nginx
image: "gcr.io/google-samples/hello-frontend:1.0"
lifecycle:
preStop:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
@@ -0,0 +1,20 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world
spec:
selector:
matchLabels:
run: load-balancer-example
replicas: 2
template:
metadata:
labels:
run: load-balancer-example
spec:
containers:
- name: hello-world
image: gcr.io/google-samples/node-hello:1.0
ports:
- containerPort: 8080
protocol: TCP
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: hello
spec:
selector:
app: hello
tier: backend
ports:
- protocol: TCP
port: 80
targetPort: http
@@ -0,0 +1,24 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello
spec:
selector:
matchLabels:
app: hello
tier: backend
track: stable
replicas: 7
template:
metadata:
labels:
app: hello
tier: backend
track: stable
spec:
containers:
- name: hello
image: "gcr.io/google-samples/hello-go-gke:1.0"
ports:
- name: http
containerPort: 80
@@ -0,0 +1,21 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: load-balancer-example
name: hello-world
spec:
replicas: 5
selector:
matchLabels:
app.kubernetes.io/name: load-balancer-example
template:
metadata:
labels:
app.kubernetes.io/name: load-balancer-example
spec:
containers:
- image: gcr.io/google-samples/node-hello:1.0
name: hello-world
ports:
- containerPort: 8080
@@ -1,8 +1,11 @@
apiVersion: apps/v1beta1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: curl-deployment name: curl-deployment
spec: spec:
selector:
matchLabels:
app: curlpod
replicas: 1 replicas: 1
template: template:
metadata: metadata:
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Pod
metadata:
namespace: default
name: dns-example
spec:
containers:
- name: test
image: nginx
dnsPolicy: "None"
dnsConfig:
nameservers:
- 1.2.3.4
searches:
- ns1.svc.cluster-domain.example
- my.dns.search.suffix
options:
- name: ndots
value: "2"
- name: edns0
@@ -0,0 +1,11 @@
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ipFamily: IPv4
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app: MyApp
spec:
ipFamily: IPv6
type: LoadBalancer
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ipFamily: IPv6
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
@@ -3,6 +3,7 @@ kind: Pod
metadata: metadata:
name: hostaliases-pod name: hostaliases-pod
spec: spec:
restartPolicy: Never
hostAliases: hostAliases:
- ip: "127.0.0.1" - ip: "127.0.0.1"
hostnames: hostnames:
@@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
ports:
- port: 8000 # the port that this service should serve on
# the container on each pod to connect to, can be a name
# (e.g. 'www') or a number (e.g. 80)
targetPort: 80
protocol: TCP
# just like the selector in the deployment,
# but this time it identifies the set of pods to load balance
# traffic to.
selector:
app: nginx