Salt: Firewalld state cause horrid performance during saltrun.

Created on 14 Dec 2017  路  2Comments  路  Source: saltstack/salt

Some of my formula will have firewalld rules in it like the following:

dokuwiki_fw:
    firewalld.service:
        - name: dokuwiki
        - ports:
            - 8002/tcp

dokuwiki_fw_rule:
    firewalld.present:
        - name: public
        - prune_services: False
        - services:
            - dokuwiki

Some subset of my nodes will have serveral firewalld states to run during an highstate run. Upon inspecting debug I realize the firewalld module is consuming a lot of time. It is inefficient.

E.G

consider the following formula test

doku_default_pw:
    file.managed:
        - name: /tmp/test
        - source: salt://test/testfile

test_fw:
    firewalld.service:
        - name: test
        - ports:
            - 8002/tcp

dokuwiki_fw_rule:
    firewalld.present:
        - name: public
        - prune_services: False
        - services:
            - test

When I run salt-call state.apply test on the minion it takes an average of 10s for a no change occurrence.

local:

Summary for local
------------
Succeeded: 9
Failed:    0
------------
Total states run:     9
Total run time:  12.718 s

When I commented out the firewall lines. it takes significantly less time to run the state.

local:

Summary for local
------------
Succeeded: 7
Failed:    0
------------
Total states run:     7
Total run time:   1.577 s

Bug P2 severity-medium

Most helpful comment

Thanks for the report. Sounds like the firewalld module(s) could benefit from the addition of mod_aggregate support.

All 2 comments

Thanks for the report. Sounds like the firewalld module(s) could benefit from the addition of mod_aggregate support.

@garethgreenaway, thanks for the mod_aggregate suggestion. I didn't know about that, but it could be really helpful in cases in which we need to run multiple firewall changes all at once.

Unfortunately, I don't think mod_aggregate will fix the slowness in the firewalld state module. Here's an example sls file with one invocation of the firewalld.present state function:

add firewall rule to test firewalld performance:
  firewalld.present:
    - name: public
    - ports:
      - 8080/tcp

Here is the output of a state.apply that made a change as well as 2 that did not (altered to hide username, hostname, and domain). Note that it took > 3 seconds to make a simple firewall rule change and > 2.3 seconds to confirm that the machine was already in the desired state:

user@master /srv/salt/test $ sudo salt 'testminion.example.org' state.apply test.fw
testminion.example.org:
----------
          ID: add firewall rule to test firewalld performance
    Function: firewalld.present
        Name: public
      Result: True
     Comment: 'public' was configured.
     Started: 12:24:29.134325
    Duration: 3217.489 ms
     Changes:   
              ----------
              ports:
                  ----------
                  new:
                      - 8080/tcp
                  old:

Summary for testminion.example.org
------------
Succeeded: 1 (changed=1)
Failed:    0
------------
Total states run:     1
Total run time:   3.217 s
user@master /srv/salt/test $ sudo salt 'testminion.example.org' state.apply test.fw
[sudo] password for user: 
testminion.example.org:
  Name: public - Function: firewalld.present - Result: Clean Started: - 12:44:31.981771 Duration: 2354.323 ms

Summary for testminion.example.org
------------
Succeeded: 1
Failed:    0
------------
Total states run:     1
Total run time:   2.354 s
user@master /srv/salt/test $ sudo salt 'testminion.example.org' state.apply test.fw
testminion.example.org:
  Name: public - Function: firewalld.present - Result: Clean Started: - 12:44:37.940333 Duration: 2334.168 ms

Summary for testminion.example.org
------------
Succeeded: 1
Failed:    0
------------
Total states run:     1 
Total run time:   2.334 s
user@master /srv/salt/test $ 

It looks like the firewalld.present state function makes many unnecessary calls to the firewalld execution module, which in turn runs the firewall-cmd command. Here the snip from the minion log file for the firewalld.present in the simple example above:

2018-05-09 13:13:52,076 [salt.state       :1795][INFO    ][30189] Executing state firewalld.present for [public]
2018-05-09 13:13:52,080 [salt.loaded.int.module.cmdmod:385 ][INFO    ][30189] Executing command '/usr/bin/firewall-cmd --get-zones --permanent' in directory '/root'
2018-05-09 13:13:52,313 [salt.loaded.int.module.cmdmod:385 ][INFO    ][30189] Executing command '/usr/bin/firewall-cmd --get-icmptypes --permanent' in directory '/root'
2018-05-09 13:13:52,532 [salt.loaded.int.module.cmdmod:385 ][INFO    ][30189] Executing command '/usr/bin/firewall-cmd --zone=public --list-icmp-blocks --permanent' in directory '/root'
2018-05-09 13:13:52,765 [salt.loaded.int.module.cmdmod:385 ][INFO    ][30189] Executing command '/usr/bin/firewall-cmd --zone=public --list-all --permanent' in directory '/root'
2018-05-09 13:13:52,997 [salt.loaded.int.module.cmdmod:385 ][INFO    ][30189] Executing command '/usr/bin/firewall-cmd --zone=public --list-ports --permanent' in directory '/root'
2018-05-09 13:13:53,242 [salt.loaded.int.module.cmdmod:385 ][INFO    ][30189] Executing command '/usr/bin/firewall-cmd --zone=public --add-port=8080/tcp --permanent' in directory '/root'
2018-05-09 13:13:53,478 [salt.loaded.int.module.cmdmod:385 ][INFO    ][30189] Executing command '/usr/bin/firewall-cmd --zone=public --list-forward-ports --permanent' in directory '/root'
2018-05-09 13:13:53,709 [salt.loaded.int.module.cmdmod:385 ][INFO    ][30189] Executing command '/usr/bin/firewall-cmd --zone=public --list-services --permanent' in directory '/root'
2018-05-09 13:13:53,939 [salt.loaded.int.module.cmdmod:385 ][INFO    ][30189] Executing command '/usr/bin/firewall-cmd --zone=public --list-interfaces --permanent' in directory '/root'
2018-05-09 13:13:54,184 [salt.loaded.int.module.cmdmod:385 ][INFO    ][30189] Executing command '/usr/bin/firewall-cmd --zone=public --list-sources --permanent' in directory '/root'
2018-05-09 13:13:54,416 [salt.loaded.int.module.cmdmod:385 ][INFO    ][30189] Executing command '/usr/bin/firewall-cmd --zone=public --list-rich-rules --permanent' in directory '/root'
2018-05-09 13:13:54,658 [salt.loaded.int.module.cmdmod:385 ][INFO    ][30189] Executing command '/usr/bin/firewall-cmd --reload' in directory '/root'
Was this page helpful?
0 / 5 - 0 ratings