端口和服务端口之间的区别?

difference between ports and service ports?

在探索 marathon REST API 时,我发现了以下 API 调用给出的信息(JSON 输出)中定义的两个端口号(端口和服务端口)-
curl http://x.y.z.w:8080/v2/tasks | python -m json.tool | less
示例输出为:

{
  "tasks":[
    {
      "appId":"/test",
      "host":"172.20.75.145",
      "id":"test.1fc922a9-f4c8-11e5-8bff-005056a76a7f",
      "ipAddresses":[

      ],
      "ports":[
        31313
      ],
      "servicePorts":[
        10000
      ],
      "slaveId":"2130f59b-7289-40eb-b24d-72f0c6fe94c8-S1",
      "stagedAt":"2016-03-28T09:33:26.859Z",
      "startedAt":"2016-03-28T09:33:26.936Z",
      "version":"2016-03-28T09:33:26.800Z"
    }
  ]
}

这里有人知道端口和服务端口的区别吗?还请补充更多信息。

根据马拉松文档:

servicePort: When you create a new application in Marathon (either through the REST API or the front end), you may assign one or more service ports to it. You can specify all valid port numbers as service ports or you can use 0 to indicate that Marathon should allocate free service ports to the app automatically. If you do choose your own service port, you have to ensure yourself that it is unique across all of your applications.

让我根据 Marathon 的两个主要网络配置对此进行详细说明,同时提供一些有关它们的信息。

主机模式

使用:Docker 应用程序的默认选项,非Docker 应用程序的唯一选项

在此配置下,您的应用程序将直接绑定到主机的端口。

不使用服务端口

您可以要求 Marathon 为您提供来自主机的任意两个端口,您希望将其提供给您的应用程序。在您的应用程序配置文件中有两种方法可以做到这一点:

"ports": [
    0, 0
],

"portDefinitions": [
      {"port": 0}, {"port": 0}
],

通过这样做,Marathon 将从可用端口范围中保留两个端口并将它们分配给环境变量 PORT1,以及 PORT2
然后在 Dockerfile:

中直接调用它们非常容易
CMD ./launch.sh --listen-on $PORT1 --monitor-on $PORT2

或在您的 Marathon 配置中的 cmd 定义中:

"cmd": "./launch.sh --listen-on $PORT1 --monitor-on $PORT2"

使用服务端口

假设您在多个主机(运行 多个实例)中 运行 您的应用程序,并且您希望能够通过特定端口连接到任何主机上的应用程序。这就是服务端口出现的时候。
通过在你的配置文件中写入:

"ports": [
    3000, 3001
],

或:

"portDefinitions": [
    {"port": 3000}, {"port": 3001}
],

... Marathon 仍会在主机上分配随机端口,它仍会将它们分配给环境变量 PORT1PORT2,并且还会保留端口 3000 和 3001 用于你用。

您可以使用服务发现机制将流量从这些服务端口路由到 $PORT1$PORT2

您可以使服务端口等于主机端口(例如,如果您希望避免使用服务发现机制)并使您的应用程序在主机之间具有一致的端口。您可以通过在端口规范后添加 "requirePorts": true 来实现。
这里需要注意的是,Marathon 只能在具有这些端口可用的节点中安排您的应用程序。

桥接模式

使用:仅用于 Docker 应用程序

在此配置下,一些指定的容器端口绑定到主机端口。

不使用服务端口

在此模式下,您不使用 "ports" 或 "portDefinitions" 指令,而是使用 "portMappings"。通过这样做,您实际上是在告诉 Docker 将流量从特定容器端口映射到主机端口,反之亦然。

您可以通过指定将容器端口映射到主机端口:

"portMappings": [
    { "containerPort": 80, "hostPort": 0, "protocol": "tcp"},
    { "containerPort": 443, "hostPort": 0, "protocol": "tcp"}
]

在这种情况下:
- 将 hostPort 设置为 0 使其再次从 可用端口范围。这些端口再次分配给 PORT1PORT2 env 变量。
- 将 containerPort 设置为 0 将使其等于 hostPort.

使用服务端口

和以前一样,您可以通过在您的配置中指定它们来为您的应用程序跨主机启用一致的服务端口,如下所示:

"portMappings": [
    { "containerPort": 80, "hostPort": 0, "protocol": "tcp", "servicePort": 3000},
    { "containerPort": 443, "hostPort": 0, "protocol": "tcp", "servicePort": 3001}
]

再次由您使用服务发现机制将流量从这些服务端口路由到 $PORT1$PORT2

有关详细信息,请参阅:

马拉松港口: https://mesosphere.github.io/marathon/docs/ports.html
Docker 主机模式: http://www.dasblinkenlichten.com/docker-networking-101-host-mode/
Docker桥接模式: http://www.dasblinkenlichten.com/docker-networking-101/

基本上通过服务端口 marathon 告诉 haproxy(或服务发现)你在这个端口上侦听,我会给你我的实例主机 ip 和端口的列表,你必须在其中路由你的流量。 haproxy 使用自己的路由算法在实例列表中分配流量。