基于portmap CNI插件来实现端口映射

前言

公司早期的K8S集群是基于flannel分配网段后,并没有在kubelet中启动cni插件功能,而是利用docker本身的网络管理功能,如下所示dockerd的启动命令为:

./dockerd --bip=10.236.51.1/25 ...

这利用了docker的自身的网络管理能力,我们知道docker本身是具备端口映射的功能,可以把容器中的服务通过端口映射的方式,如下所示,我们启动一个容器,把容器中的80端口映射到宿主机的8000端口上:

docker run -p 8000:80 -it ubuntu /bin/bash

有些老业务为了让容器与外部系统互通,把容器的端口映射到了宿主机的端口上,通过对宿主机的端口进行管理,来防止容器调度的冲突,这种方式一定层度上解决了业务上的问题。

近期,我们对K8S的网络模型进行了升级,通过自定义的网络CNI插件,实现三层网络模型,可以让容器网络与主机网络系统打通,为了统一K8S集群方便管理,我们需要把一些老的业务迁移到新的K8S集群中来。

我们又不希望管理多个K8S集群,但是新集群中的CNI插件本身,不具备这种端口映射的能力,所以碰到了旧的业务无法迁移的难题。

额外话题:
从这个问题本身来看,其实业务方并没有使用端口映射功能的必要性,既然业务自己管理分配的主机节点和端口号,那么我们完全可以基于Host网络部署Pod来达到相同的目的。
这里我们先不考虑方案替代性上来说,端口映射功能也是一个比较有意思的点,剖析一下如何在我们新的K8S集群中来支撑这种端口映射功能。

K8S中的端口映射

K8S在框架层面是支撑了端口映射的功能,我们可以看看下面这个Pod的定义:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
    - name: nginx
      image: nginx:1.7.9
      ports:
        - containerPort: 80
          hostPort: 8080

这个Pod要求把容器中80端口映射到宿主机的8080端口中,虽然我们能够这样申明,但是究竟能不能做到,就跟我们指定的网络模式有很大关系了。

如果按照我们老集群中,采用None的模式,让docker进程去管理网络,那么docker自身具备这种端口映射的能力,所以他就能够支持,而在我们新集群中应用的时候,发现不能达到目的,映射根本没有完成。

应用CNI portmap插件实现对端口映射的支持

我们首先来看看我们自定义的插件配置:

root@herrypc:/etc/cni/net.d# cat 11-flannel.conf 
{
  "cniVersion": "0.3.0",
  "name": "mynet",
  "type": "flannel",
  "ipMasq": false,
  "delegate": {
    "type": "bridge",
    "forceAddress": false,
    "ipMasq": false,
     "hairpinMode": true,
    "isDefaultGateway": true
  }
}

基础插件自身是不具备端口映射的能力的,所以基于上述配置无法实现端口映射,但是CNI本身支持级联插件的功能,可以在配置中指定portmap作为级联插件来支持端口映射能力。

为了支持级联插件,我们配置不能采用前面的配置格式,而是基于conflist的配置,文件名改为:11-flannel.conflist,内容如下:

root@herrypc:/etc/cni/net.d# cat 11-flannel.conflist
{
  "cniVersion": "0.3.0",
  "name": "mynet",
  "plugins": [
    {
      "type": "flannel",
      "ipMasq": false,
      "delegate": {
         "type": "bridge",
         "forceAddress": false,
         "ipMasq": false,
          "hairpinMode": true,
          "isDefaultGateway": true
         }
      },
      {
        "type": "portmap",
        "capabilities": {"portMappings": true},
        "snat": true
      },
   }
}

你可能感兴趣的:(基于portmap CNI插件来实现端口映射)