|
| 1 | +# DFaaS Plugin |
| 2 | + |
| 3 | +This plugin implements the legacy DFaaS sampling workflow using k6 on a |
| 4 | +dedicated host and OpenFaaS/Prometheus on the target. |
| 5 | + |
| 6 | +## Architecture |
| 7 | +- Target host: runner + k3s + OpenFaaS + Prometheus + exporters. |
| 8 | +- k6 host: executes load, controlled via SSH from the target host. |
| 9 | +- Network paths: |
| 10 | + - target -> k6-host over SSH (port 22 by default) |
| 11 | + - k6-host -> OpenFaaS gateway (port 31112 by default) |
| 12 | + - target -> Prometheus (NodePort 30411 by default) |
| 13 | + |
| 14 | +## Prerequisites |
| 15 | +- SSH access from target host to k6 host using the configured key. |
| 16 | +- Target host packages: `kubectl`, `helm`, `faas-cli`, `ansible-playbook`. |
| 17 | +- Open ports: 22 (SSH), 31112 (OpenFaaS gateway), 30411 (Prometheus). |
| 18 | + |
| 19 | +## Setup steps |
| 20 | +1. Install k6 on the k6 host: |
| 21 | + - Run `lb_plugins/plugins/dfaas/ansible/setup_k6.yml` against the k6 host. |
| 22 | +2. Install k3s/OpenFaaS/Prometheus on the target host: |
| 23 | + - Run `lb_plugins/plugins/dfaas/ansible/setup_target.yml` against the target. |
| 24 | +3. Verify: |
| 25 | + - `kubectl get nodes` shows Ready. |
| 26 | + - `faas-cli list --gateway http://<target>:31112` lists functions. |
| 27 | + - `curl http://<target>:30411/-/ready` returns 200. |
| 28 | + |
| 29 | +## Run flow |
| 30 | +- Generate all function combinations and rate vectors. |
| 31 | +- For each config: |
| 32 | + - Enforce cooldown (idle CPU/RAM/POWER and replicas < 2). |
| 33 | + - Generate a k6 script and run it on the k6 host. |
| 34 | + - Parse the k6 summary and query Prometheus. |
| 35 | + - Compute overload and skip dominant configs when needed. |
| 36 | + |
| 37 | +## Outputs |
| 38 | +In the workload output directory: |
| 39 | +- `results.csv`, `skipped.csv`, `index.csv` (legacy-compatible headers). |
| 40 | +- `summaries/summary-<config>-iter<iter>-rep<rep>.json` |
| 41 | +- `metrics/metrics-<config>-iter<iter>-rep<rep>.csv` |
| 42 | +- `k6_scripts/config-<config>.js` |
| 43 | + |
| 44 | +## Config loading |
| 45 | +- `config_path` can be passed via workload options to load a YAML/JSON file that |
| 46 | + contains `common` and `plugins.dfaas` sections. |
| 47 | +- `plugins.dfaas` overrides `common`, and any options passed alongside |
| 48 | + `config_path` override both. |
| 49 | + |
| 50 | +## Config schema |
| 51 | +Top-level fields (in `plugins.dfaas`): |
| 52 | +- `k6_host` (str): k6 host address. |
| 53 | +- `k6_user` (str): SSH user for the k6 host. |
| 54 | +- `k6_ssh_key` (str): SSH private key path. |
| 55 | +- `k6_port` (int): SSH port. |
| 56 | +- `k6_workspace_root` (str): workspace root on the k6 host. |
| 57 | +- `output_dir` (str): optional output directory override for DFaaS artifacts. |
| 58 | +- `run_id` (str): optional run identifier used for k6 workspace. |
| 59 | +- `gateway_url` (str): OpenFaaS gateway URL. |
| 60 | +- `prometheus_url` (str): Prometheus base URL (default NodePort 30411). |
| 61 | +- `functions` (list): list of function objects (name/method/body/headers/max_rate). |
| 62 | +- `rates` (object): `min_rate`, `max_rate`, `step`. |
| 63 | +- `combinations` (object): `min_functions`, `max_functions` (max is exclusive). |
| 64 | +- `duration` (str): k6 duration string (e.g. `30s`). |
| 65 | +- `iterations` (int): iterations per configuration. |
| 66 | +- `cooldown` (object): `max_wait_seconds`, `sleep_step_seconds`, |
| 67 | + `idle_threshold_pct`. |
| 68 | +- `overload` (object): `cpu_overload_pct_of_capacity`, `ram_overload_pct`, |
| 69 | + `success_rate_node_min`, `success_rate_function_min`, |
| 70 | + `replicas_overload_threshold`. |
| 71 | +- `queries_path` (str): path to the Prometheus queries file. |
| 72 | +- `deploy_functions` (bool): deploy OpenFaaS store functions. |
| 73 | +- `scaphandre_enabled` (bool): enable power metrics via Scaphandre. |
| 74 | +- `function_pid_regexes` (map): optional PID regex per function when Scaphandre is enabled. |
| 75 | + |
| 76 | +Common base fields: |
| 77 | +- `max_retries` (int): retries for the workload (default 0). |
| 78 | +- `timeout_buffer` (int): safety buffer added to expected runtime (default 10). |
| 79 | +- `tags` (list[str]): workload tags. |
| 80 | + |
| 81 | +Function object fields: |
| 82 | +- `name` (str): OpenFaaS function name. |
| 83 | +- `method` (str): HTTP method (GET/POST/etc). |
| 84 | +- `body` (str): request payload (match legacy payloads in |
| 85 | + `legacy_materials/samples_generator/utils.py`). |
| 86 | +- `headers` (map): HTTP headers. |
| 87 | +- `max_rate` (int, optional): per-function maximum rate (requests/sec). |
| 88 | + |
| 89 | +## Example config (YAML) |
| 90 | +``` |
| 91 | +common: |
| 92 | + timeout_buffer: 10 |
| 93 | +
|
| 94 | +plugins: |
| 95 | + dfaas: |
| 96 | + k6_host: "10.0.0.50" |
| 97 | + k6_user: "ubuntu" |
| 98 | + k6_ssh_key: "~/.ssh/id_rsa" |
| 99 | + k6_port: 22 |
| 100 | +
|
| 101 | + gateway_url: "http://<target-ip>:31112" |
| 102 | + prometheus_url: "http://<target-ip>:30411" |
| 103 | +
|
| 104 | + functions: |
| 105 | + - name: "figlet" |
| 106 | + method: "POST" |
| 107 | + body: "Hello DFaaS!" |
| 108 | + headers: |
| 109 | + Content-Type: "text/plain" |
| 110 | + max_rate: 100 |
| 111 | + - name: "eat-memory" |
| 112 | + method: "GET" |
| 113 | + body: "" |
| 114 | +
|
| 115 | + rates: |
| 116 | + min_rate: 0 |
| 117 | + max_rate: 200 |
| 118 | + step: 10 |
| 119 | +
|
| 120 | + combinations: |
| 121 | + min_functions: 1 |
| 122 | + max_functions: 2 |
| 123 | +
|
| 124 | + duration: "30s" |
| 125 | + iterations: 3 |
| 126 | +
|
| 127 | + cooldown: |
| 128 | + max_wait_seconds: 180 |
| 129 | + sleep_step_seconds: 5 |
| 130 | + idle_threshold_pct: 15 |
| 131 | +
|
| 132 | + overload: |
| 133 | + cpu_overload_pct_of_capacity: 80 |
| 134 | + ram_overload_pct: 90 |
| 135 | + success_rate_node_min: 0.95 |
| 136 | + success_rate_function_min: 0.90 |
| 137 | + replicas_overload_threshold: 15 |
| 138 | +
|
| 139 | + queries_path: "lb_plugins/plugins/dfaas/queries.yml" |
| 140 | + deploy_functions: true |
| 141 | + scaphandre_enabled: false |
| 142 | +``` |
| 143 | + |
| 144 | +## Formal rules (legacy) |
| 145 | +- Rate list: `rates = [min_rate..max_rate step]` inclusive, ascending. |
| 146 | +- Combinations: function sets from `min_functions..max_functions` (max exclusive). |
| 147 | +- Dominance: Config B dominates A if for every function `rate_B >= rate_A` and |
| 148 | + for at least one function `rate_B > rate_A`. If A is overloaded, skip all |
| 149 | + dominant configs. |
| 150 | +- Cooldown: wait until CPU/RAM/POWER <= idle + idle * 15% and replicas < 2, with |
| 151 | + a max wait of 180s. |
| 152 | +- Overload: |
| 153 | + - Node overloaded if avg success rate < 0.95 OR CPU > 80% capacity OR |
| 154 | + RAM > 90% OR any function overload. |
| 155 | + - Function overloaded if success rate < 0.90 OR replicas >= 15. |
| 156 | + |
| 157 | +## Troubleshooting |
| 158 | +- OpenFaaS gateway unreachable: confirm NodePort 31112 and `faas-cli login`. |
| 159 | +- Prometheus query timeouts: verify `prometheus_url` and NodePort 30411. |
| 160 | +- k6 SSH failures: confirm `k6_host`, `k6_user`, and `k6_ssh_key` are correct. |
| 161 | +- Cooldown never completes: check for stuck replicas or sustained CPU/RAM load. |
0 commit comments