You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2021/09/02 01:00:16 UTC

[apisix] branch master updated: feat: support configurating the node listening address(#4856)

This is an automated email from the ASF dual-hosted git repository.

spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new c72700e  feat: support configurating the node listening address(#4856)
c72700e is described below

commit c72700e59eb00e09c4763b2dfb9fac754f85bca8
Author: Way2go <zh...@tiduyun.com>
AuthorDate: Thu Sep 2 09:00:06 2021 +0800

    feat: support configurating the node listening address(#4856)
---
 apisix/cli/ngx_tpl.lua   |  17 ++-----
 apisix/cli/ops.lua       | 124 +++++++++++++++++++++++++++++++++++++++--------
 conf/config-default.yaml |  16 +++++-
 t/admin/plugins-reload.t |   1 +
 t/cli/test_control.sh    |   2 +-
 t/cli/test_main.sh       |  58 ++++++++++++++++++++--
 t/cli/test_prometheus.sh |   2 +-
 7 files changed, 176 insertions(+), 44 deletions(-)

diff --git a/apisix/cli/ngx_tpl.lua b/apisix/cli/ngx_tpl.lua
index 7728ec2..cecc623 100644
--- a/apisix/cli/ngx_tpl.lua
+++ b/apisix/cli/ngx_tpl.lua
@@ -459,11 +459,11 @@ http {
 
     server {
         {% for _, item in ipairs(node_listen) do %}
-        listen {* item.port *} default_server {% if enable_reuseport then %} reuseport {% end %} {% if item.enable_http2 then %} http2 {% end %};
+        listen {* item.ip *}:{* item.port *} default_server {% if item.enable_http2 then %} http2 {% end %} {% if enable_reuseport then %} reuseport {% end %};
         {% end %}
         {% if ssl.enable then %}
-        {% for _, port in ipairs(ssl.listen_port) do %}
-        listen {* port *} ssl default_server {% if ssl.enable_http2 then %} http2 {% end %} {% if enable_reuseport then %} reuseport {% end %};
+        {% for _, item in ipairs(ssl.listen) do %}
+        listen {* item.ip *}:{* item.port *} ssl default_server {% if item.enable_http2 then %} http2 {% end %} {% if enable_reuseport then %} reuseport {% end %};
         {% end %}
         {% end %}
         {% if proxy_protocol and proxy_protocol.listen_http_port then %}
@@ -473,17 +473,6 @@ http {
         listen {* proxy_protocol.listen_https_port *} ssl default_server {% if ssl.enable_http2 then %} http2 {% end %} proxy_protocol;
         {% end %}
 
-        {% if enable_ipv6 then %}
-        {% for _, item in ipairs(node_listen) do %}
-        listen [::]:{* item.port *} default_server {% if enable_reuseport then %} reuseport {% end %} {% if item.enable_http2 then %} http2 {% end %};
-        {% end %}
-        {% if ssl.enable then %}
-        {% for _, port in ipairs(ssl.listen_port) do %}
-        listen [::]:{* port *} ssl default_server {% if ssl.enable_http2 then %} http2 {% end %} {% if enable_reuseport then %} reuseport {% end %};
-        {% end %}
-        {% end %}
-        {% end %} {% -- if enable_ipv6 %}
-
         server_name _;
 
         {% if ssl.enable then %}
diff --git a/apisix/cli/ops.lua b/apisix/cli/ops.lua
index 4c1c46a..e5fbe20 100644
--- a/apisix/cli/ops.lua
+++ b/apisix/cli/ops.lua
@@ -461,45 +461,127 @@ Please modify "admin_key" in conf/config.yaml .
         end
     end
 
-    -- support multiple ports listen, compatible with the original style
-    if type(yaml_conf.apisix.node_listen) == "number" then
+    local ip_port_to_check = {}
+
+    local function listen_table_insert(listen_table, scheme, ip, port, enable_http2, enable_ipv6)
+        if type(ip) ~= "string" then
+            util.die(scheme, " listen ip format error, must be string", "\n")
+        end
+
+        if type(port) ~= "number" then
+            util.die(scheme, " listen port format error, must be number", "\n")
+        end
+
+        if ports_to_check[port] ~= nil then
+            util.die(scheme, " listen port ", port, " conflicts with ",
+                ports_to_check[port], "\n")
+        end
+
+        local addr = ip .. ":" .. port
 
-        if ports_to_check[yaml_conf.apisix.node_listen] ~= nil then
-            util.die("node_listen port ", yaml_conf.apisix.node_listen,
-                    " conflicts with ", ports_to_check[yaml_conf.apisix.node_listen], "\n")
+        if ip_port_to_check[addr] == nil then
+            table_insert(listen_table,
+                    {ip = ip, port = port, enable_http2 = enable_http2})
+            ip_port_to_check[addr] = scheme
         end
 
-        local node_listen = {{port = yaml_conf.apisix.node_listen}}
-        yaml_conf.apisix.node_listen = node_listen
+        if enable_ipv6 then
+            ip = "[::]"
+            addr = ip .. ":" .. port
+
+            if ip_port_to_check[addr] == nil then
+                table_insert(listen_table,
+                        {ip = ip, port = port, enable_http2 = enable_http2})
+                ip_port_to_check[addr] = scheme
+            end
+        end
+    end
+
+    local node_listen = {}
+    -- listen in http, support multiple ports and specific IP, compatible with the original style
+    if type(yaml_conf.apisix.node_listen) == "number" then
+        listen_table_insert(node_listen, "http", "0.0.0.0", yaml_conf.apisix.node_listen,
+                false, yaml_conf.apisix.enable_ipv6)
     elseif type(yaml_conf.apisix.node_listen) == "table" then
-        local node_listen = {}
-        for index, value in ipairs(yaml_conf.apisix.node_listen) do
+        for _, value in ipairs(yaml_conf.apisix.node_listen) do
             if type(value) == "number" then
+                listen_table_insert(node_listen, "http", "0.0.0.0", value,
+                        false, yaml_conf.apisix.enable_ipv6)
+            elseif type(value) == "table" then
+                local ip = value.ip
+                local port = value.port
+                local enable_ipv6 = false
+                local enable_http2 = value.enable_http2
+
+                if ip == nil then
+                    ip = "0.0.0.0"
+                    if yaml_conf.apisix.enable_ipv6 then
+                        enable_ipv6 = true
+                    end
+                end
 
-                if ports_to_check[value] ~= nil then
-                    util.die("node_listen port ", value, " conflicts with ",
-                        ports_to_check[value], "\n")
+                if port == nil then
+                    port = 9080
                 end
 
-                table_insert(node_listen, index, {port = value})
-            elseif type(value) == "table" then
+                if enable_http2 == nil then
+                    enable_http2 = false
+                end
+
+                listen_table_insert(node_listen, "http", ip, port,
+                        enable_http2, enable_ipv6)
+            end
+        end
+    end
+    yaml_conf.apisix.node_listen = node_listen
 
-                if type(value.port) == "number" and ports_to_check[value.port] ~= nil then
-                    util.die("node_listen port ", value.port, " conflicts with ",
-                        ports_to_check[value.port], "\n")
+    local ssl_listen = {}
+    -- listen in https, support multiple ports, support specific IP
+    for _, value in ipairs(yaml_conf.apisix.ssl.listen) do
+        if type(value) == "number" then
+            listen_table_insert(ssl_listen, "https", "0.0.0.0", value,
+                    yaml_conf.apisix.ssl.enable_http2, yaml_conf.apisix.enable_ipv6)
+        elseif type(value) == "table" then
+            local ip = value.ip
+            local port = value.port
+            local enable_ipv6 = false
+            local enable_http2 = (value.enable_http2 or yaml_conf.apisix.ssl.enable_http2)
+
+            if ip == nil then
+                ip = "0.0.0.0"
+                if yaml_conf.apisix.enable_ipv6 then
+                    enable_ipv6 = true
                 end
+            end
+
+            if port == nil then
+                port = 9443
+            end
 
-                table_insert(node_listen, index, value)
+            if enable_http2 == nil then
+                enable_http2 = false
             end
+
+            listen_table_insert(ssl_listen, "https", ip, port,
+                    enable_http2, enable_ipv6)
         end
-        yaml_conf.apisix.node_listen = node_listen
     end
 
+    -- listen in https, compatible with the original style
     if type(yaml_conf.apisix.ssl.listen_port) == "number" then
-        local listen_port = {yaml_conf.apisix.ssl.listen_port}
-        yaml_conf.apisix.ssl.listen_port = listen_port
+        listen_table_insert(ssl_listen, "https", "0.0.0.0", yaml_conf.apisix.ssl.listen_port,
+                yaml_conf.apisix.ssl.enable_http2, yaml_conf.apisix.enable_ipv6)
+    elseif type(yaml_conf.apisix.ssl.listen_port) == "table" then
+        for _, value in ipairs(yaml_conf.apisix.ssl.listen_port) do
+            if type(value) == "number" then
+                listen_table_insert(ssl_listen, "https", "0.0.0.0", value,
+                        yaml_conf.apisix.ssl.enable_http2, yaml_conf.apisix.enable_ipv6)
+            end
+        end
     end
 
+    yaml_conf.apisix.ssl.listen = ssl_listen
+
     if yaml_conf.apisix.ssl.ssl_trusted_certificate ~= nil then
         local cert_path = yaml_conf.apisix.ssl.ssl_trusted_certificate
         -- During validation, the path is relative to PWD
diff --git a/conf/config-default.yaml b/conf/config-default.yaml
index 55f3f30..48ac994 100644
--- a/conf/config-default.yaml
+++ b/conf/config-default.yaml
@@ -23,6 +23,11 @@ apisix:
   # node_listen: 9080              # APISIX listening port
   node_listen:                     # This style support multiple ports
     - 9080
+  #   - port: 9081
+  #     enable_http2: true         # If not set, the default value is `false`.
+  #   - ip: 127.0.0.2              # Specific IP, If not set, the default value is `0.0.0.0`.
+  #     port: 9082
+  #     enable_http2: true
   enable_admin: true
   enable_admin_cors: true          # Admin API support CORS response headers.
   enable_debug: false
@@ -115,8 +120,15 @@ apisix:
   enable_resolv_search_opt: true  # enable search option in resolv.conf
   ssl:
     enable: true
-    enable_http2: true
-    listen_port: 9443
+    listen:                       # APISIX listening port in https.
+      - 9443
+    #   - port: 9444
+    #     enable_http2: true      # If not set, the default value is `false`.
+    #   - ip: 127.0.0.3           # Specific IP, If not set, the default value is `0.0.0.0`.
+    #     port: 9445
+    #     enable_http2: true
+    enable_http2: true            # Not recommend: This parameter should be set via the `listen`.
+    # listen_port: 9443           # Not recommend: This parameter should be set via the `listen`.
     #ssl_trusted_certificate: /path/to/ca-cert  # Specifies a file path with trusted CA certificates in the PEM format
                                                 # used to verify the certificate when APISIX needs to do SSL/TLS handshaking
                                                 # with external services (e.g. etcd)
diff --git a/t/admin/plugins-reload.t b/t/admin/plugins-reload.t
index 2aa1b8d..1e15611 100644
--- a/t/admin/plugins-reload.t
+++ b/t/admin/plugins-reload.t
@@ -332,6 +332,7 @@ Instance report fails
                 ngx.status = code
             end
             ngx.say(body)
+            ngx.sleep(0.1)
         }
     }
 --- request
diff --git a/t/cli/test_control.sh b/t/cli/test_control.sh
index fd924ac..4e642d6 100755
--- a/t/cli/test_control.sh
+++ b/t/cli/test_control.sh
@@ -124,7 +124,7 @@ apisix:
 ' > conf/config.yaml
 
 out=$(make init 2>&1 || true)
-if ! echo "$out" | grep "node_listen port 9090 conflicts with control"; then
+if ! echo "$out" | grep "http listen port 9090 conflicts with control"; then
     echo "failed: can't detect port conflicts"
     exit 1
 fi
diff --git a/t/cli/test_main.sh b/t/cli/test_main.sh
index 74dd79d..d267f6f 100755
--- a/t/cli/test_main.sh
+++ b/t/cli/test_main.sh
@@ -47,7 +47,7 @@ echo "passed: error_log directive uses warn level by default"
 
 # check whether the 'reuseport' is in nginx.conf .
 
-grep -E "listen 9080.*reuseport" conf/nginx.conf > /dev/null
+grep -E "listen 0.0.0.0:9080.*reuseport" conf/nginx.conf > /dev/null
 if [ ! $? -eq 0 ]; then
     echo "failed: nginx.conf file is missing reuseport configuration"
     exit 1
@@ -64,7 +64,7 @@ apisix:
 
 make init
 
-grep "listen 8443 ssl" conf/nginx.conf > /dev/null
+grep "listen 0.0.0.0:8443 ssl" conf/nginx.conf > /dev/null
 if [ ! $? -eq 0 ]; then
     echo "failed: failed to update ssl port"
     exit 1
@@ -95,7 +95,7 @@ apisix:
 
 make init
 
-count_http_ipv4=`grep -c "listen 908." conf/nginx.conf || true`
+count_http_ipv4=`grep -c "listen 0.0.0.0:908." conf/nginx.conf || true`
 if [ $count_http_ipv4 -ne 3 ]; then
     echo "failed: failed to support multiple ports listen in http with ipv4"
     exit 1
@@ -107,7 +107,7 @@ if [ $count_http_ipv6 -ne 3 ]; then
     exit 1
 fi
 
-count_https_ipv4=`grep -c "listen 944. ssl" conf/nginx.conf || true`
+count_https_ipv4=`grep -c "listen 0.0.0.0:944. ssl" conf/nginx.conf || true`
 if [ $count_https_ipv4 -ne 3 ]; then
     echo "failed: failed to support multiple ports listen in https with ipv4"
     exit 1
@@ -121,6 +121,54 @@ fi
 
 echo "passed: support multiple ports listen in http and https"
 
+# check support specific IP listen in http and https
+
+echo "
+apisix:
+  node_listen:
+    - ip: 127.0.0.1
+      port: 9081
+    - ip: 127.0.0.2
+      port: 9082
+      enable_http2: true
+  ssl:
+    enable_http2: false
+    listen:
+      - ip: 127.0.0.3
+        port: 9444
+      - ip: 127.0.0.4
+        port: 9445
+        enable_http2: true
+" > conf/config.yaml
+
+make init
+
+count_http_specific_ip=`grep -c "listen 127.0.0..:908." conf/nginx.conf || true`
+if [ $count_http_specific_ip -ne 2 ]; then
+    echo "failed: failed to support specific IP listen in http"
+    exit 1
+fi
+
+count_http_specific_ip_and_enable_http2=`grep -c "listen 127.0.0..:908. default_server http2" conf/nginx.conf || true`
+if [ $count_http_specific_ip_and_enable_http2 -ne 1 ]; then
+    echo "failed: failed to support specific IP and enable http2 listen in http"
+    exit 1
+fi
+
+count_https_specific_ip=`grep -c "listen 127.0.0..:944. ssl" conf/nginx.conf || true`
+if [ $count_https_specific_ip -ne 2 ]; then
+    echo "failed: failed to support specific IP listen in https"
+    exit 1
+fi
+
+count_https_specific_ip_and_enable_http2=`grep -c "listen 127.0.0..:944. ssl default_server http2" conf/nginx.conf || true`
+if [ $count_https_specific_ip_and_enable_http2 -ne 1 ]; then
+    echo "failed: failed to support specific IP and enable http2 listen in https"
+    exit 1
+fi
+
+echo "passed: support specific IP listen in http and https"
+
 # check default env
 echo "
 nginx_config:
@@ -345,7 +393,7 @@ if [ $count -ne 1 ]; then
     exit 1
 fi
 
-count=`grep -c "listen 9080.*reuseport" conf/nginx.conf || true`
+count=`grep -c "listen 0.0.0.0:9080.*reuseport" conf/nginx.conf || true`
 if [ $count -ne 0 ]; then
     echo "failed: reuseport should be disabled when enable enable_dev_mode"
     exit 1
diff --git a/t/cli/test_prometheus.sh b/t/cli/test_prometheus.sh
index 9a9af39..7130044 100755
--- a/t/cli/test_prometheus.sh
+++ b/t/cli/test_prometheus.sh
@@ -117,7 +117,7 @@ plugin_attr:
 ' > conf/config.yaml
 
 out=$(IP=127.0.0.1 PORT=9092 make init 2>&1 || true)
-if ! echo "$out" | grep "node_listen port 9092 conflicts with prometheus"; then
+if ! echo "$out" | grep "http listen port 9092 conflicts with prometheus"; then
     echo "failed: can't detect port conflicts"
     exit 1
 fi