Kubernetes组件

控制平面组件

控制平面组件会为集群做出全体决策,比如资源的调度。以及检测和响应集群事件,例如当不满足部署的replicas字段时,要启动新的pod。

看着屏幕组件可以再集群中任何节点上运行。然而为了简单起见,设置脚本通常ui在同一个计算机上启动所有控制平面组件,而且不会再次计算机上运行用户容器。请参阅使用 kubeadm 构建高可用性集群 中关于跨多机器控制平面设置的示例。

kube-apiserver

API服务器是Kubernetes控制平面组件,该组件负责公开了Kubernetes API,负责处理请求接受工作。API服务器是Kubernetes控制平面的前端。

Kubernetes API服务器的主要实现是 kube-apiserver。 kube-apiserver设计上考虑了水平扩缩,也就是说,它可以通过部署多个实例来进行扩缩。你可以运行kube-apiServer的多个实例,并在这些实例之间平衡流量。

Etcd

一致切高可用的键值存储,用作kubernetes所有集群数据的后台数据库。

如果你的kubernetes集群使用Etcd作为其后台数据库,请确保你针对这些数据有一份 备份计划。

kube-scheduler

kube-scheduler是控制平面的组件,负责监视新创建的、未指定运行节点的Pod,并选择节点让Pod在上面运行。

调度决策考虑的因素包括单个Pod及Pods集合的资源需求、软硬件策略约束、亲和性及反亲和性规范、数据位置、工作负载间的干扰及最后时限

kube-controller-manager

kube-controller-manager是控制平面的组件,负责运行控制器进程。

从逻辑上讲,每个控制器都是一个单独的进程,但是为了降低复杂性,它们都被编译到同一个可执行文件,并在同一个进程中运行。

有许多不同类型的控制器,下面是一些例子:

  • 节点控制器(Node Controller):负责节点出现故障时进行通知和响应
  • 任务控制器(Job Controller):检测代表一次性任务的Job对象,然后创建Pods来运行这些任务直至完成
  • 端点分片控制器(EndpointSlice controller):填充端点分片EndpointSlice对象(以提供Service和Pod之间的)
  • 服务账号控制器(ServiceAccount controller):为新的命名空间创建默认的服务账号(ServiceAccount)。
  • 。。。

cloud-controller-manager

一个Kubernetes控制平面组件,嵌入了特定云平台的控制逻辑。云控制器管理器(Cloud Controller Manager)允许你讲你的集群连接到云提供商的API之上,并讲该云平台交互的组件同于你的集群交互的组件分离开来。

与cloud-controller-manager类似,cloud-controller-manager讲若干逻辑上独立的控制回路组合到同一个可执行文件中,供你一同一进程的方式运行。你可以对其执行水平扩容(运行不止一个副本)以提升性能或者增强容错能力。

下面的控制器都包含对云平台驱动依赖:

节点控制器

节点控制器负责在云基础设施中创建了新服务器时为止更新节点(Node)对象。节点控制器从云提供商获取当前租户中主机的信息。节点控制器执行以下功能。

  1. 使用从云平台 API 获取的对应服务器的唯一标识符更新 Node 对象;
  2. 利用特定云平台的信息为 Node 对象添加注解和标签,例如节点所在的区域 (Region)和所具有的资源(CPU、内存等等);
  3. 获取节点的网络地址和主机名;
  4. 检查节点的健康状况。如果节点无响应,控制器通过云平台 API 查看该节点是否已从云中禁用、删除或终止。如果节点已从云中删除, 则控制器从 Kubernetes 集群中删除 Node 对象。

某些云驱动实现中,这些任务被划分到一个节点控制器和一个节点生命周期控制器中。

路由控制器

Route控制器负责适配当地配置云平台中的路由,以便Kubernetes急群中不同节点上的容器之间可以相互通信。

取决于云驱动本身,路由器控制器也可能会为Pod网络分配IP地址块。

服务控制器

服务Service与受控的负载均衡器、IP地址、网络包过滤、目标健康检查等云基础设施组件集成。服务控制器与云驱动的API交互,已配置负载均衡器和其他基础设施组件。你所创建的Service 资源会需要只写组件

Node组件

节点组件会在每个节点上云霄,负责维护运行的Pod并提供Kubernetes运行环境。

kubelet

kybelet会在急群众每个节点上云霄。保证容器都运行在Pod中。

Kubelet接受一组通过各类机制提供给它的PodSpec,确保这些PodSpec中描述的容器处于运行状态并且健康。

Kubelet不会接受管理不是有kubernetes创建的容器。

kube-proxy

kube-proxy是每个急群中每个节点上所运行的网络代理,实现kubernetes服务概念的一部分。

kube-proxy维护节点上的一些网络规则,这些网络规则会允许从集群内部或外部的网络会话与Pod进行网络通信。

如果操作系统提供了可用的数据包过滤层,则kube-proxy会通过它来实现网络规则。否则,kube-proxy仅做流量转发。

容器运行时

这个基础组件使Kubernetes能够有效运行容器。它负责管理Kubernetes环境中容器的执行和生命周期。

kubernetes支持许多容器运行环境,例如Containerd、CRI-O以及kubernetes CRI容器运行环境接口的其他任何实现。

插件(Addons)

插件使用Kubernetes资源(DaemonSet、Deplyment等)实现急群的功能。因为这些插件提供急群级别的功能,插件中命名空间域的资源属于kube-system命名空间。

DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。

DaemonSet 的一些典型用法:

  • 在每个节点上运行集群守护进程
  • 在每个节点上运行日志收集守护进程
  • 在每个节点上运行监控守护进程

一种简单的用法是为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。 一个稍微复杂的用法是为同一种守护进程部署多个 DaemonSet;每个具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。

DNS

接管其他插件都并非严格意义上的必须组件,但几乎所有Kubernetes急群都应该有急群DNS,因为很多示例都需要DNS服务。

集群DNS是一个DNS服务器,和环境中的其他DNS服务器一起工作,它为Kubernetes服务提供 DNS记录。

Kubernetes启动的容器自动将此DNS服务器包含在其DNS搜索列表中。

Kubernetes为Service和Pod创建DNS记录。你可以使用一致的DNS名称而非IP地址访问Service。

Kubernetes发布有关Pod和Service的信息,这些信息被用来对DNS进行编程。Kubelet配置Pod的DNS以便运行中的容器可以通过名称而不是IP来查找服务。集群中定义的Service被赋予DNS名称。默认情况下,客户端的Pod的DNS搜索列表会包含Pod自身的名字空间和集群的默认域。

Service的名字空间

DNS查询可能因为执行查询的Pod所在的名字空间而返回不同的结果。不指定名字空间的DNS查询会被限制在Pod所在的名字空间内。要访问其他名字空间中的Service,需要在DNS查询指定名字空间。

例如假定名字空间test中存在一个Pod,prod名字空间中存在一个服务data。

Pod查询data时没有返回结果,因为使用的是Pod名字空间test。

Pod查询data.prod时会返回预期结果,因为查询中指定了名字空间。

DNS 查询可以使用 Pod 中的 /etc/resolv.conf 展开。 Kubelet 为每个 Pod 配置此文件。 例如,对 data 的查询可能被展开为 data.test.svc.cluster.localsearch 选项的取值会被用来展开查询。要进一步了解 DNS 查询,可参阅 resolv.conf 手册页面

nameserver 10.32.0.10
search <namespace>.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

概括起来,名字空间 test 中的 Pod 可以成功地解析 data.prod 或者 data.prod.svc.cluster.local

DNS记录

哪些对象会获得DNS记录呢?

  1. Service
  2. Pods

以下各节详细介绍已支持的 DNS 记录类型和布局。 其它布局、名称或者查询即使碰巧可以工作,也应视为实现细节, 将来很可能被更改而且不会因此发出警告。 有关最新规范请查看 Kubernetes 基于 DNS 的服务发现

Web界面(仪表盘)

Dashboard是 Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身, 并进行故障排除。

容器资源监控

要扩展应用程序并提供可靠的服务,你需要了解应用程序在部署时的行为。你可以通过检测容器Pod、Service和整个集群的特征来检查Kubernetes集群中应用程序的功能。Kubernetes在每个级别上有提供有关应用程序资源使用情况的详细信息。此信息使你可以评估应用程序的性能,以及在何处可以消除瓶颈以提高整体性能。

在Kubernetes中,应用程序监控不依赖单个监控解决方案。在新集群上,你可以使用资源度量或完整度量管道来收集监控统计信息。

资源度量管道

资源指标管道提供了一组与集群组件,例如 Horizontal Pod Autoscaler 控制器以及 kubectl top 实用程序相关的有限度量。 这些指标是由轻量级的、短期、内存存储的 metrics-server 收集, 并通过 metrics.k8s.io 公开。

metrics-server发现急群中的所有节点,并且查询每个节点的kubelet以获取CPU和内存使用情况。kubelet充当kubernetes主节点与节点之间的桥梁,管理机器上运行的Pod和容器。kubelet将每个Pod转换为其组成的容器,通过容器运行时接口从容器运行时获取各个容器使用情况统计信息。如果某个容器运行时使用Linux cgroups和名字空间来实现容器。并且这一容器运行时不发布资源用量统计信息,那么kubelet可以直接查找这些统计信息(使用来自 cAdvisor 的代码)。 无论这些统计信息如何到达,kubelet 都会通过 metrics-server Resource Metrics API 公开聚合的 Pod 资源用量统计信息。 该 API 在 kubelet 的经过身份验证和只读的端口上的 /metrics/resource/v1beta1 中提供。

cAdvisor可以对Node机器上的资源及容器进行实时监控和性能数据采集,包括CPU、内存使用情况、网络吞吐量及文件系统使用情况,1.7.3版本以前,cadvisor的metrics数据集成在kubelet的metrics中,在1.7.3以后版本中cadvisor的metrics被从kubelet的metrics独立出来了,每个Node机器上都会有一个aAdvisor对这台机器进行监控。

完整度量管道

一个完整度量管道可以让你访问更丰富的度量。Kubernetes还可以根据集群的当前状态使用Pod水平自动扩缩容等机制,通过自动调用扩展或调整集群来响应这些度量。监控管道从kubelet获取度量值,然后通过适配器将它们公开给Kubernetes,方法是实现 custom.metrics.k8s.ioexternal.metrics.k8s.io API。

Kubernetes在设计上保证能够与OpenMetrics一同使用OpenMetrics是CNCF客观测性和分析-监控项目之一,它构建与Prometheus暴露格式之上,并对其进行了扩展,这些扩展几乎100%向后兼容。

如果你浏览 CNCF Landscape, 你可以看到许多监控项目,它们可以用在 Kubernetes 上,抓取指标数据并利用这些数据来观测你的集群, 选择哪种工具或哪些工具可以满足你的需求,这完全取决于你自己。 CNCF 的可观测性和分析景观包括了各种开源软件、付费的软件即服务(SaaS)以及其他混合商业产品。

当你设计和实现一个完整的指标监控数据管道时,你可以将监控数据反馈给 Kubernetes。 例如,HorizontalPodAutoscaler 可以使用处理过的指标数据来计算出你的工作负载组件运行了多少个 Pod。

将完整的指标管道集成到 Kubernetes 实现中超出了 Kubernetes 文档的范围,因为可能的解决方案具有非常广泛的范围。

监控平台的选择在很大程度上取决于你的需求、预算和技术资源。 Kubernetes 不推荐任何特定的指标管道; 可使用许多选项。 你的监控系统应能够处理 OpenMetrics 指标传输标准, 并且需要选择最适合基础设施平台的整体设计和部署。

集群层面日志

集群层面日志机制负责将容器的日志数据保存到一个集群中的日志存储中,这种急群中日志存储提供搜索和浏览接口。

日志架构

应用日志可以让你了解应用内部的运行状况。日志对调试问题和监控集群活动非常有用。 大部分现代化应用都有某种日志记录机制。同样地,容器引擎也被设计成支持日志记录。 针对容器化应用,最简单且最广泛采用的日志记录方式就是写入标准输出和标准错误流。

但是,由容器引擎或运行时提供的原生功能通常不足以构成完整的日志记录方案。

例如,如果发生容器崩溃、Pod 被逐出或节点宕机等情况,你可能想访问应用日志。

在急群中,日志应该具有独立的存储,并且与其生命周期与节点、Pod或容器的生命周期相互独立。这个概念叫集群级的日志。

集群级日志架构需要一个独立的后端用来存储、分析和查询日志。Kubernetes并不为日志数据提供原生的存储解决方案。相反,有很多线程的日志方案可以集成到Kubernetes中。下面各节点描述如何在节点上处理和存储日志。

集群级日志架构需要一个独立的后端用来存储、分析和查询日志。Kubernetes并不为日志数据提供原生存储解决方案。相反,有很多现成的日志方案可以集成到Kubernetes中。

Pod和容器日志

Kubernetes 从正在运行的 Pod 中捕捉每个容器的日志。

此示例使用带有一个容器的 Pod 的清单,该容器每秒将文本写入标准输出一次。

debug/counter-pod.yaml Copy debug/counter-pod.yaml to clipboard

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox:1.28
    args: [/bin/sh, -c,
            'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']

要运行此 Pod,请执行以下命令:

kubectl apply -f https://k8s.io/examples/debug/counter-pod.yaml

输出为:

pod/counter created

要获取这些日志,请执行以下 kubectl logs 命令:

kubectl logs counter

输出类似于:

0: Fri Apr  1 11:42:23 UTC 2022
1: Fri Apr  1 11:42:24 UTC 2022
2: Fri Apr  1 11:42:25 UTC 2022

你可以使用 kubectl logs --previous 从容器的先前实例中检索日志。 如果你的 Pod 有多个容器,请如下通过将容器名称追加到该命令并使用 -c 标志来指定要访问哪个容器的日志:

kubectl logs counter -c count

详见 kubectl logs 文档

节点的容器日志处理方式

容器运行时对写入到容器化应用程序的stdout和stderr流的所有输出进行处理和转发。不通过的容器运行时以不同的方式实现这一点;不过它们与kubelet的集成都会被标准为CRI日志格式。

默认情况下,如果容器重新启动,kubelet会保留一个终止的容器及日志。如果一个Pod被逐出节点,所对应的所有容器及其日志也会被逐出。

kubelet通过Kubernetes API的特殊功能将日志提供给客户端访问。访问这个日志的常用方法是运行kubectl logs。

日志轮转

你可以配置kubelet令其自动轮转日志。

如果配置轮转,kubelet负责轮转容器日志并管理日志目录结构。kubelet(使用CRI)将此信息发送到容器运行时,而运行时将容器日志写到给定位置。

你可以使用 kubelet 配置文件配置两个 kubelet 配置选项containerLogMaxSizecontainerLogMaxFiles。 这些设置分别允许你分别配置每个日志文件大小的最大值和每个容器允许的最大文件数。

当类似于基本日志示例一样运行 kubectl logs 时, 节点上的 kubelet 会处理请求并直接从日志文件读取。kubelet 将返回该日志文件的内容。

说明:

只有最新的日志文件的内容可以通过 kubectl logs 获得。

例如,如果 Pod 写入 40 MiB 的日志,并且 kubelet 在 10 MiB 之后轮转日志, 则运行 kubectl logs 将最多返回 10 MiB 的数据。

集群日志加架构

虽然Kubernetes没有为集群日志记录提供原生解决方案,但是你可以考虑几种常见用法

  • 使用在每个节点上运行的节点及日志记录代理
  • 在应用程序的Pod中,包含专门记录日志的sidecar容器
  • 将日志直接从应用程序中推送到日志记录后端。

使用节点级日志代理

你可以通过在每个节点上使用节点级的日志记录代理来实现急群级日志记录。日志记录代理是一种用于暴露日志或将日志推送到后端的专用工具。通常,日志记录代理程序是一个容器,它可以包含该节点上所有应用程序容器的日志文件的目录。

由于日志记录代理必须在每个节点上运行,推荐以DaemonSet的形式运行该代理。

节点及日志在每个节点上仅创建一个代理,不需要对节点说哪个的应用做修改。

容器想标准输出和标准错误输出写出数据,但在格式上并不统一。节点级代理收集这些日志并将其进行转发完成汇总。

使用边车运行日志代理

你可以通过以下方式之一使用边车(Sidecar)容器:

  • 边车容器将应用程序日志传送到自己的标准输出。
  • 边车容器运行一个日志代理,配置该日志代理以便从应用容器收集日志。

利用边车容器,写入到自己的 stdoutstderr 传输流, 你就可以利用每个节点上的 kubelet 和日志代理来处理日志。 边车容器从文件、套接字或 journald 读取日志。 每个边车容器向自己的 stdoutstderr 流中输出日志。

这种方法允许你将日志流从应用程序的不同部分分离开,其中一些可能缺乏对写入 stdoutstderr 的支持。重定向日志背后的逻辑是最小的,因此它的开销不大。 另外,因为 stdoutstderr 由 kubelet 处理,所以你可以使用内置的工具 kubectl logs

例如,某 Pod 中运行一个容器,且该容器使用两个不同的格式写入到两个不同的日志文件。 下面是这个 Pod 的清单:

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox:1.28
    args:
    - /bin/sh
    - -c
    - >
      i=0;
      while true;
      do
        echo "$i: $(date)" >> /var/log/1.log;
        echo "$(date) INFO $i" >> /var/log/2.log;
        i=$((i+1));
        sleep 1;
      done      
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  volumes:
  - name: varlog
    emptyDir: {}

不建议在同一个日志流中写入不同格式的日志条目,即使你成功地将其重定向到容器的 stdout 流。 相反,你可以创建两个边车容器。每个边车容器可以从共享卷跟踪特定的日志文件, 并将文件内容重定向到各自的 stdout 流。

下面是运行两个边车容器的 Pod 的清单:

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox:1.28
    args:
    - /bin/sh
    - -c
    - >
      i=0;
      while true;
      do
        echo "$i: $(date)" >> /var/log/1.log;
        echo "$(date) INFO $i" >> /var/log/2.log;
        i=$((i+1));
        sleep 1;
      done      
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  - name: count-log-1
    image: busybox:1.28
    args: [/bin/sh, -c, 'tail -n+1 -F /var/log/1.log']
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  - name: count-log-2
    image: busybox:1.28
    args: [/bin/sh, -c, 'tail -n+1 -F /var/log/2.log']
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  volumes:
  - name: varlog
    emptyDir: {}

现在当你运行这个 Pod 时,你可以运行如下命令分别访问每个日志流:

kubectl logs counter count-log-1

输出类似于:

0: Fri Apr  1 11:42:26 UTC 2022
1: Fri Apr  1 11:42:27 UTC 2022
2: Fri Apr  1 11:42:28 UTC 2022
...
kubectl logs counter count-log-2

输出类似于:

Fri Apr  1 11:42:29 UTC 2022 INFO 0
Fri Apr  1 11:42:30 UTC 2022 INFO 0
Fri Apr  1 11:42:31 UTC 2022 INFO 0
...

具有日志代理功能的边车容器

如果节点级日志代理程序对于你的场景来说不够灵活,你可以创建一个带有单独日志代理的边车容器,将代理程序专门配置为你的应用程序一起运行。

说明:

在边车容器中使用日志代理会带来严重的资源损耗。 此外,你不能使用 kubectl logs 访问日志,因为日志并没有被 kubelet 管理。

下面是两个配置文件,可以用来实现一个带日志代理的边车容器。 第一个文件包含用来配置 fluentd 的 ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: fluentd-config
data:
  fluentd.conf: |
    <source>
      type tail
      format none
      path /var/log/1.log
      pos_file /var/log/1.log.pos
      tag count.format1
    </source>

    <source>
      type tail
      format none
      path /var/log/2.log
      pos_file /var/log/2.log.pos
      tag count.format2
    </source>

    <match **>
      type google_cloud
    </match>    

说明:

你可以将此示例配置中的 fluentd 替换为其他日志代理,从应用容器内的其他来源读取数据。

第二个清单描述了一个运行 fluentd 边车容器的 Pod。 该 Pod 挂载一个卷,flutend 可以从这个卷上拣选其配置数据。

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox:1.28
    args:
    - /bin/sh
    - -c
    - >
      i=0;
      while true;
      do
        echo "$i: $(date)" >> /var/log/1.log;
        echo "$(date) INFO $i" >> /var/log/2.log;
        i=$((i+1));
        sleep 1;
      done      
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  - name: count-agent
    image: registry.k8s.io/fluentd-gcp:1.30
    env:
    - name: FLUENTD_ARGS
      value: -c /etc/fluentd-config/fluentd.conf
    volumeMounts:
    - name: varlog
      mountPath: /var/log
    - name: config-volume
      mountPath: /etc/fluentd-config
  volumes:
  - name: varlog
    emptyDir: {}
  - name: config-volume
    configMap:
      name: fluentd-config

从应用中直接暴露日志目录

从各个应用中直接暴露和推送日志数据的集群日志机制已超出 Kubernetes 的范围。

网络插件

网络插件是实现容器接口CNI规范的软件组件。它们负责为Pod分配IP地址,并使这些Pod内部相互通信。

kubernetes1.28支持用集群联网的容器接口CNI插件。你必须使用和你的集群想兼容并且满足你的需求的CNI插件。在更广泛的Kubernetes生态系统中你可以使用不同的插件。

你必须使用与 v0.4.0 或更高版本的 CNI 规范相符合的 CNI 插件。 Kubernetes 推荐使用一个兼容 v1.0.0 CNI 规范的插件(插件可以兼容多个规范版本)。

安装

在网络语境中,容器运行时(Container Runtime)是在节点上的守护进程,被配置用来为kubelet提供CRI服务。具体而言,容器运行时必须加载所需的CNI插件,从而实现Kubernetes网络模型。

在 Kubernetes 1.24 之前,CNI 插件也可以由 kubelet 使用命令行参数 cni-bin-dirnetwork-plugin 管理。Kubernetes 1.24 移除了这些命令行参数, CNI 的管理不再是 kubelet 的工作。

如果你在移除 dockershim 之后遇到问题, 请参阅排查 CNI 插件相关的错误

要了解容器运行时如何管理 CNI 插件的具体信息,可参见对应容器运行时的文档,例如:

要了解如何安装和管理 CNI 插件的具体信息,可参阅对应的插件或 网络驱动(Networking Provider) 的文档。

网络插件要求

对于插件开发人员以及时长会构建并部署Kubernetes的用户而言,插件可能也需要特定的配置来支持kube-proxy。iptables代理依赖于iptables,插件可能需要确保iptables能够监控容器的网络通信。例如,如果插件降容器连接到Linux网桥,插件必须将 net/bridge/bridge-nf-call-iptables sysctl 参数设置为 1,以确保iptables代理正常工作。如果插件不使用Linux网桥,而是使用类似于Open vSwitch或者其他一些机制,它应该确保为代理对容器通信执行正确的路由。

默认情况下,如果未指定 kubelet 网络插件,则使用 noop 插件, 该插件设置 net/bridge/bridge-nf-call-iptables=1,以确保简单的配置 (如带网桥的 Docker)与 iptables 代理正常工作。

本地回路CNI

除了安装到节点上用于实现Kubernetes网络模型的CNI插件外,Kubernetes害需要容器运行时提供一个本地回路接口 lo,用于各个沙箱(Pod沙箱、虚拟沙箱)。实现本地回路接口的工作可以通过复用 CNI 本地回路插件来实现, 也可以通过开发自己的代码来实现 (参阅 CRI-O 中的示例)。

支持 hostPort

CNI 网络插件支持 hostPort。你可以使用官方 portmap 插件,它由 CNI 插件团队提供,或者使用你自己的带有 portMapping 功能的插件。

如果你想要启动 hostPort 支持,则必须在 cni-conf-dir 指定 portMappings capability。 例如:

{
  "name": "k8s-pod-network",
  "cniVersion": "0.4.0",
  "plugins": [
    {
      "type": "calico",
      "log_level": "info",
      "datastore_type": "kubernetes",
      "nodename": "127.0.0.1",
      "ipam": {
        "type": "host-local",
        "subnet": "usePodCidr"
      },
      "policy": {
        "type": "k8s"
      },
      "kubernetes": {
        "kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
      }
    },
    {
      "type": "portmap",
      "capabilities": {"portMappings": true},
      "externalSetMarkChain": "KUBE-MARK-MASQ"
    }
  ]
}

支持流量整形

实验功能

CNI 网络插件还支持 Pod 入站和出站流量整形。 你可以使用 CNI 插件团队提供的 bandwidth 插件,也可以使用你自己的具有带宽控制功能的插件。

如果你想要启用流量整形支持,你必须将 bandwidth 插件添加到 CNI 配置文件 (默认是 /etc/cni/net.d)并保证该可执行文件包含在你的 CNI 的 bin 文件夹内 (默认为 /opt/cni/bin)。

{
  "name": "k8s-pod-network",
  "cniVersion": "0.4.0",
  "plugins": [
    {
      "type": "calico",
      "log_level": "info",
      "datastore_type": "kubernetes",
      "nodename": "127.0.0.1",
      "ipam": {
        "type": "host-local",
        "subnet": "usePodCidr"
      },
      "policy": {
        "type": "k8s"
      },
      "kubernetes": {
        "kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
      }
    },
    {
      "type": "bandwidth",
      "capabilities": {"bandwidth": true}
    }
  ]
}

现在,你可以将 kubernetes.io/ingress-bandwidthkubernetes.io/egress-bandwidth 注解添加到 Pod 中。例如:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubernetes.io/ingress-bandwidth: 1M
    kubernetes.io/egress-bandwidth: 1M
...
Last modification:December 11, 2023
如果觉得我的文章对你有用,请随意赞赏