美文网首页Docker容器
基于portmap CNI插件来实现端口映射

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

作者: 何约什 | 来源:发表于2019-03-13 09:24 被阅读12次

    前言

    公司早期的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插件来实现端口映射

        本文链接:https://www.haomeiwen.com/subject/bzompqtx.html