Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support configurating the node listening address #4856

Merged
merged 13 commits into from
Sep 2, 2021

Conversation

wayne-cheng
Copy link
Contributor

@wayne-cheng wayne-cheng commented Aug 19, 2021

Signed-off-by: wayne-cheng zhengwei@tiduyun.com

What this PR does / why we need it:

support configurating the node listening address,
The config.yaml example as below:

apisix:
  node_listen:
  - 9080
  - port: 9380
    ip: 127.0.0.2            # If not given, the default is 0.0.0.0
    allow_ssl: True        # if False, the ip connot be ued to config ssl.

Fix #4853

Pre-submission checklist:

  • Did you explain what problem does this PR solve? Or what new features have been added?
  • Have you added corresponding test cases?
  • Have you modified the corresponding document?
  • Is this PR backward compatible? If it is not backward compatible, please discuss on the mailing list first

@wayne-cheng
Copy link
Contributor Author

@spacewander Hi, PTAL

Copy link
Member

@nic-chen nic-chen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wayne-cheng tanks.need test cases

@spacewander spacewander changed the title feat:support configurating the node listening address (#4853) feat: support configurating the node listening address (#4853) Aug 19, 2021
Copy link
Member

@spacewander spacewander left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A test under t/cli is in need.

{% end %}
{% if ssl.enable then %}
listen {* item.ip *}:{* item.port *} default_server {% if enable_reuseport then %} reuseport {% end %} {% if item.enable_http2 then %} http2 {% end %};
{% if item.allow_ssl and ssl.enable then %}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to use enable_ssl.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok,and should I explain these params in the doc FAQ.md ?

apisix:
  node_listen:
  - 9080
  - port: 9380
    ip: 127.0.0.1            # If not given, the default is `0.0.0.0`.
    enable_ssl: True         # If `False`, the ip connot be ued to enable ssl. If not given, the default is `True`.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, document it in the conf/config-default.yaml as a comment is enough.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the default value of "enable_ssl" should not be true, since 9080 doesn't have "enable_ssl", and it doesn't enable SSL by default.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, we are planning to reduce the length of the current FAQ, let each answer go to suitable places, instead of putting them together.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to modify the config apisix.ssl.listen_port ,like this:

apisix:
  ssl:
    listen_port:
    - ip: 127.0.0.1
       port: 9443

The ssl config in the param apisix.node_listen[] could be confusing,for example:

apisix:
  node_listen:
    - ip: 127.0.0.2
      port: 9082
      enable_ssl: true
    - ip: 127.0.0.2
      port: 9083
      enable_ssl: false

What do you think? @spacewander

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. Personally, I prefer to use a new key "listen" since it is not just with port. Maybe we need to move "enable_http2" under "listen" too. Like this one:

apisix:
  ssl:
    # enable_http2: false
    # listen_port: ...
    listen:
    - ip: 127.0.0.1
      port: 9443
      enable_http2: true # per listen configuration

@wayne-cheng
What's your opinion?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spacewander
I cannot agree any more. BTW, do I need to consider compatibility with the old configuration about ssl? There are something troublesome to deal with, the new config need to be merged with the old config.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. We need to keep backward compatibility.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spacewander I have updated the code, please take a look.

node_listen: 9080 # APISIX listening port
node_listen: # APISIX listening port
- 9080
- ip: 127.0.0.2 # Specific IP, If not set, the default value is `0.0.0.0`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please comment out the example

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

listen_port: 9443
listen:
- 9443
- ip: 127.0.0.3 # Specific IP, If not set, the default value is `0.0.0.0`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

conf/config-default.yaml Outdated Show resolved Hide resolved
- ip: 127.0.0.3 # Specific IP, If not set, the default value is `0.0.0.0`.
port: 9444
enable_http2: true # If not set, the default value is `false`.
#port: 9081
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the irrelative line

local addr = ip .. ":" .. port

if ip_port_to_check[addr] == nil then
table_insert(total_ssl_listen, {ip = ip, port = port, enable_http2 = yaml_conf.apisix.ssl.enable_http2})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can refactor the repeated code in a function, which accepts enable_http2, enable_ipv6 and other arguments

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx, the code is much clearer now

enable_http2: true # If not set, the default value is `false`.
#port: 9081
#enable_http2: true
#listen_port: 9443
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to add a comment to show that this way still supports, but is no longer recommended

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok,I will comment it like this:

apisix:
  node_listen: 9080                # APISIX listening port
  # node_listen:                   # This style support multiple ports
  # - 9080
  # - ip: 127.0.0.2                # Specific IP, If not set, the default value is `0.0.0.0`.
  #   port: 9082
  ssl:
    enable: true
    # listen:                       # APISIX listening port in https.
    # - 9443
    # - ip: 127.0.0.3               # Specific IP, If not set, the default value is `0.0.0.0`.
    #   port: 9444
    #   enable_http2: true          # If not set, the default value is `false`.
    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`.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to:

apisix:
  # node_listen: 9080                # APISIX listening port
  node_listen:                       # This style support multiple ports
   - 9080
   # - ip: 127.0.0.2                # Specific IP, If not set, the default value is `0.0.0.0`.
   #   port: 9082
  ssl:
    enable: true
    listen:                       # APISIX listening port in https.
      - 9443
    # - ip: 127.0.0.3               # Specific IP, If not set, the default value is `0.0.0.0`.
    #   port: 9444
    #   enable_http2: true          # If not set, the default value is `false`.
    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`.

Let's encourage users to use the new style.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -20,7 +20,10 @@
#

apisix:
node_listen: 9080 # APISIX listening port
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@wayne-cheng
Copy link
Contributor Author

@spacewander A new commit has been pushed, PTAL

@@ -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 enable_reuseport then %} reuseport {% end %};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http port also need to enable_http2

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, and it means that the config apisix.node_listen[] also has the property enable_http2 , right?

apisix:
  # node_listen: 9080                # APISIX listening port
  node_listen:                   # This style support multiple ports
  - 9080
  # - ip: 127.0.0.2                # Specific IP, If not set, the default value is `0.0.0.0`.
  #   port: 9082
  #   enable_http2: true  

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it means that the config apisix.node_listen[] also has the property enable_http2 , right?

Yes.

end

local node_listen = {{port = yaml_conf.apisix.node_listen}}
yaml_conf.apisix.node_listen = node_listen
local addr = ip .. ":" .. port
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add scheme to this key so that we can reduce a branch

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the config apisix.node_listen[] also has the property enable_http2, the branch can be reduced.
Port conflicts should be checked at the TCP layer, not the scheme http/https, so the scheme would not be add to this key.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@wayne-cheng
Copy link
Contributor Author

The conifg apisix.port_admin also need to be compatible, now all changes have been pushed.
PTAL @spacewander

@@ -399,7 +399,11 @@ http {
{% if enable_admin and port_admin then %}
server {
{%if https_admin then%}
listen {* port_admin *} ssl;
{% for _, item in ipairs(ssl.listen) do %}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the idea that the admin requires multiple ports.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple admin ports are useless. You only need to set one in the API client.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not change the config port_admin. It is still the same as before, only one port_admin can be set.
The idea is to match the specific ip in the config node_listen,not for multiple ports.

@spacewander
Copy link
Member

Please don't change the port_admin, thanks!

@wayne-cheng
Copy link
Contributor Author

@spacewander
Please see this after that code:

{% if item.only_admin then %}
listen {* item.ip *}:{* item.port *} ssl;
{% end %}

In my environment, the apisix bind the VIP. If the port_admin is bound to all IP addresses, those programs with the same port but different IP will not work.

@spacewander
Copy link
Member

Maybe we can add an "admin_listen" section like what we have done with ssl.listen_port? We can do it in the next PR. This PR is big enough and should pass the CI first.

@wayne-cheng
Copy link
Contributor Author

Agree,Of course this way is better. Next, Do I undo the changes about port_admin and push commit again?

@spacewander
Copy link
Member

Yes

@wayne-cheng
Copy link
Contributor Author

OK,PTAL @spacewander

@wayne-cheng
Copy link
Contributor Author

@spacewander
The config apisix.node_listen in previous config-default.yaml is the type number, but the new has been the type table.
If a user still uses the type number to set the config apisix.node_listen like this:

apisix:
  node_listen: 9081

The error will occur when exec make init,and it also appeared in the CI test:

./bin/apisix init
/usr/local/openresty/luajit/bin/luajit ./apisix/cli/apisix.lua init
failed to read local yaml config of apisix: failed to merge, path[apisix->ssl->listen] expect: table, but got: number
make: *** [Makefile:127: init] Error 1

This bug should have existed before, but it was missed, since the previous file config-default.yaml used the number type.
Should I fix the function merge_conf in the code file apisix/cli/file.lua(+151) ?

 -- ...           
            elseif type(base[key]) ~= type_val then
                if (ppath == "nginx_config" or str_sub(ppath, 1, 14) == "nginx_config->") and
                    (type_val == "number" or type_val == "string")
                then
                    base[key] = val
                else
                    local path = ppath == "" and key or ppath .. "->" .. key
                    return nil, "failed to merge, path[" .. path ..  "] expect: " ..
                                type(base[key]) .. ", but got: " .. type_val
                end
            else
                base[key] = val
            end
-- ...

@spacewander
Copy link
Member

Thanks for your report. Let's add it to the allow list.

I think you can submit it via a separate PR. I can merge it first, so that you are no longer a first-time contributor, then you can see the CI result without approval.

Signed-off-by: wayne-cheng <zhengwei@tiduyun.com>
Signed-off-by: wayne-cheng <zhengwei@tiduyun.com>
Signed-off-by: wayne-cheng <zhengwei@tiduyun.com>
Signed-off-by: wayne-cheng <zhengwei@tiduyun.com>
Signed-off-by: wayne-cheng <zhengwei@tiduyun.com>
Signed-off-by: wayne-cheng <zhengwei@tiduyun.com>
Signed-off-by: wayne-cheng <zhengwei@tiduyun.com>
@@ -115,8 +120,16 @@ apisix:
enable_resolv_search_opt: true # enable search option in resolv.conf
ssl:
enable: true
enable_http2: true
listen_port: 9443
# listen: 9443 # APISIX listening port in https.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should only support table format for the new configuration, this will make it easier to understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok,I have removed it in the config-default.yaml.

Signed-off-by: wayne-cheng <zhengwei@tiduyun.com>
@@ -126,6 +126,10 @@ local function path_is_multi_type(path, type_val)
return true
end

if path == "apisix->ssl->listen" and type_val == "number" then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we remove it now?


local ssl_listen = {}
-- listen in https, support multiple ports, support specific IP
if type(yaml_conf.apisix.ssl.listen) == "number" then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, the related code has also been removed.

…format

Signed-off-by: wayne-cheng <zhengwei@tiduyun.com>
@spacewander spacewander changed the title feat: support configurating the node listening address (#4853) feat: support configurating the node listening address Sep 2, 2021
@spacewander spacewander merged commit c72700e into apache:master Sep 2, 2021
@wayne-cheng
Copy link
Contributor Author

@spacewander Thanks for your patience to review, I'll submit next PR to add the config admin_listen.

@wayne-cheng wayne-cheng deleted the 4853-2.8-zhengwei branch September 2, 2021 03:50
@jagerzhang
Copy link
Contributor

Hi, When will this feature be released to the docker image?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

request help: support configurating the node listening address
5 participants