|
| 1 | +InfraKit Manager |
| 2 | +================ |
| 3 | + |
| 4 | +The Manager is a binary that offers a Group interface while providing the following: |
| 5 | + |
| 6 | + + Leadership detection - for coordinating multiple sets (replicas) of InfraKit plugins |
| 7 | + + State storage - persists user configuration in some backend |
| 8 | + |
| 9 | +Both file-based and Docker Swarm (Swarm Mode) based leadership detection and state storage are |
| 10 | +available. |
| 11 | + |
| 12 | +## Group Interface |
| 13 | + |
| 14 | +Currently the manager exposes the same Group plugin interface as the `infrakit-group-default`. |
| 15 | +This means `infrakit group ...` command will work as usual. The manager expects a group plugin |
| 16 | +to be running prior to starting up and it functions as proxy for that group plugin: |
| 17 | + |
| 18 | + + When user does a `infrakit group watch` or `infrakit group update`, the manager will |
| 19 | + persist the input configuration in the data store it was configured at startup time. |
| 20 | + + If the data store is configured with a backend that is shared or replicated across multiple |
| 21 | + instances of InfraKit ensemble (all the collaborating plugins), high availability can be |
| 22 | + achieved via leader detection and global availabilit of state (the stored config). |
| 23 | + + Multiple replicas of the manager can do leader detection so that only one is active. As |
| 24 | + soon as leadership changes, the responsibility of maintaining infrastructure state is transfered |
| 25 | + to the new manager that became active. |
| 26 | + |
| 27 | +## Leadership |
| 28 | + |
| 29 | +The manager can use either `os` or `swarm` for leadership detection: |
| 30 | + |
| 31 | +### OS mode (via the `os` subcommand) |
| 32 | + |
| 33 | + 1. Assumes multiple instances of managers can access a shared file (e.g. over NFS or FUSE on S3). |
| 34 | + 2. Each manager starts up with a name (the `--name` flag). |
| 35 | + 3. The manager instance with the name that matches the content of the shared file is the leader. |
| 36 | + |
| 37 | +### Swarm mode (via the `swarm` subcommand) |
| 38 | + |
| 39 | + 1. Assumes there's a manager instance per Docker Swarm manager instance |
| 40 | + 2. Leadership depends on the status of the Swarm manager node. If the Swarm manager node is the |
| 41 | + leader, then the InfraKit manager instance running on that node is the leader. |
| 42 | + 3. When leadership changes in the Swarm, InfraKit leadership follows. |
| 43 | + |
| 44 | +When an instance assumes leadership: |
| 45 | + |
| 46 | + + State is retrieved from shared storage (see below) and for each group in the config, a group |
| 47 | + `watch` is invoked so that the new leader can begin watching the groups |
| 48 | + + Since this is the frontend for the stateless group, it records any input the user provides when the |
| 49 | + user performs and update. The new config is then written in the shared store and `update` is forwarded |
| 50 | + to the actual group plugin to do the real work. |
| 51 | + |
| 52 | +When an instance loses leadership: |
| 53 | + |
| 54 | + + The manager uses previous configuration and 'deactivates' the local group plugin by calling `unwatch` |
| 55 | + on the downstream group plugin |
| 56 | + + It rejects user's attempt to `update` since it's not the leader. |
| 57 | + |
| 58 | + |
| 59 | +## State Storage |
| 60 | + |
| 61 | +The manager can use either `os` or `swarm` for state storage: |
| 62 | + |
| 63 | +### OS mode (via the `os` subcommand) |
| 64 | + |
| 65 | + 1. State is stored in a local file that is well-known and defined at startup of the manager. |
| 66 | + 2. This file is a global config that can include multiple groups. |
| 67 | + |
| 68 | +### Swarm mode (via the `swarm` subcommand) |
| 69 | + |
| 70 | + 1. State is stored in the Swarm via annotations |
| 71 | + 2. A single global state is stored in a single annotation. The data is compressed and encoded. |
| 72 | + |
| 73 | + |
| 74 | +## Fronted (Proxy) for Group |
| 75 | + |
| 76 | +The manager requires a group plugin to be running so that it can forward calls to it to actually |
| 77 | +perform the work of watching and updating: |
| 78 | + |
| 79 | + + When you intend to use the manager, you should start your default group plugin with a name like |
| 80 | + `group-stateless` |
| 81 | + + Then when starting the manager, set the `--proxy-for-group` flag to the name of the group plugin |
| 82 | + (e.g. `group-stateless`). By default, the manager starts up with the name of `group`. This matches |
| 83 | + the default name that the CLI (`infrakit group ...`) uses. |
| 84 | + |
| 85 | + |
| 86 | +## Running |
| 87 | + |
| 88 | +```shell |
| 89 | +$ make binaries |
| 90 | +$ build/infrakit-manager -h |
| 91 | +Manager |
| 92 | + |
| 93 | +Usage: |
| 94 | + infrakit-manager [command] |
| 95 | + |
| 96 | +Available Commands: |
| 97 | + os os |
| 98 | + swarm swarm mode for leader detection and storage |
| 99 | + version print build version information |
| 100 | + |
| 101 | +Flags: |
| 102 | + --log int Logging level. 0 is least verbose. Max is 5 (default 4) |
| 103 | + --name string Name of the manager (default "group") |
| 104 | + --proxy-for-group string Name of the group plugin to proxy for. (default "group-stateless") |
| 105 | + |
| 106 | +Use "infrakit-manager [command] --help" for more information about a command. |
| 107 | +``` |
| 108 | + |
| 109 | +### Running in OS Mode |
| 110 | + |
| 111 | +Useful for local testing: |
| 112 | + |
| 113 | +```shell |
| 114 | +$ infrakit-manager os --log 5 |
| 115 | +``` |
| 116 | + |
| 117 | +### Running in Swarm Mode |
| 118 | + |
| 119 | +First enable Swarm mode: |
| 120 | + |
| 121 | +```shell |
| 122 | +docker swarm init |
| 123 | +``` |
| 124 | + |
| 125 | +On each Swarm manager node: |
| 126 | + |
| 127 | +```shell |
| 128 | +$ infrakit-manager swarm --log 5 |
| 129 | +``` |
| 130 | +will connect to Docker using defaulted Docker socket. |
| 131 | + |
| 132 | + |
| 133 | +## Example -- Running Locally |
| 134 | + |
| 135 | +You can use the `os` subcommand of the manager to run the manager in the local, os mode where a |
| 136 | +shared file is used to determine leadership. |
| 137 | + |
| 138 | +1. Start the plugins depending on which plugins you reference in your config. Note that the |
| 139 | +usual Group plugin is renamed `group-stateless`. |
| 140 | + |
| 141 | +```shell |
| 142 | +$ make binaries |
| 143 | +$ build/infrakit-group-default --name group-stateless & |
| 144 | +$ build/infrakit-instance-file |
| 145 | +$ build/infrakit-flavor-vanilla |
| 146 | +``` |
| 147 | + |
| 148 | +2. Use a local file for leadership. For example - `/tmp/leader` |
| 149 | + |
| 150 | +```shell |
| 151 | +echo group > /tmp/leader |
| 152 | +``` |
| 153 | +2. Start the manager with the name `group` |
| 154 | + |
| 155 | +```shell |
| 156 | +$ build/infrakit-manager os --log 5 --proxy-for-group group-stateless --leader-file /tmp/leader --name group |
| 157 | +DEBU[0000] Opening: /Users/myuser/.infrakit/plugins |
| 158 | +DEBU[0000] Discovered plugin at /Users/myuser/.infrakit/plugins/group-stateless |
| 159 | +DEBU[0000] Discovered plugin at /Users/myuser/.infrakit/plugins/infrakit-flavor-vanilla |
| 160 | +DEBU[0000] Discovered plugin at /Users/myuser/.infrakit/plugins/infrakit-instance-file |
| 161 | +INFO[0000] Starting up manager: &{group 0xc4202ce7e0 0xc4202e8810 0xc4202ce940 group-stateless} |
| 162 | +DEBU[0000] Opening: /Users/myuser/.infrakit/plugins |
| 163 | +DEBU[0000] Discovered plugin at /Users/myuser/.infrakit/plugins/group-stateless |
| 164 | +DEBU[0000] Discovered plugin at /Users/myuser/.infrakit/plugins/infrakit-flavor-vanilla |
| 165 | +DEBU[0000] Discovered plugin at /Users/myuser/.infrakit/plugins/infrakit-instance-file |
| 166 | +INFO[0000] Manager starting |
| 167 | +INFO[0000] Listening at: /Users/myuser/.infrakit/plugins/group |
| 168 | +DEBU[0005] ID (group) - checked /tmp/leader for leadership: group, err=<nil>, leader=true |
| 169 | +DEBU[0005] leader: true |
| 170 | +INFO[0005] Assuming leadership |
| 171 | +INFO[0005] Loaded snapshot. err= <nil> |
| 172 | +INFO[0005] Start watching groups |
| 173 | +DEBU[0005] Opening: /Users/myuser/.infrakit/plugins |
| 174 | +DEBU[0005] Discovered plugin at /Users/myuser/.infrakit/plugins/group |
| 175 | +DEBU[0005] Discovered plugin at /Users/myuser/.infrakit/plugins/group-stateless |
| 176 | +DEBU[0005] Discovered plugin at /Users/myuser/.infrakit/plugins/infrakit-flavor-vanilla |
| 177 | +DEBU[0005] Discovered plugin at /Users/myuser/.infrakit/plugins/infrakit-instance-file |
| 178 | +INFO[0005] Processing group managers with plugin group-stateless |
| 179 | +DEBU[0005] exec on group managers plugin= group-stateless |
| 180 | +INFO[0005] WATCH group managers with spec: {managers 0xc420122600} |
| 181 | +INFO[0005] Processing group workers with plugin group-stateless |
| 182 | +DEBU[0005] exec on group workers plugin= group-stateless |
| 183 | +INFO[0005] WATCH group workers with spec: {workers 0xc420122a60} |
| 184 | +DEBU[0010] ID (group) - checked /tmp/leader for leadership: group, err=<nil>, leader=true |
| 185 | +DEBU[0015] ID (group) - checked /tmp/leader for leadership: group, err=<nil>, leader=true |
| 186 | +DEBU[0020] ID (group) - checked /tmp/leader for leadership: group, err=<nil>, leader=true |
| 187 | +DEBU[0025] ID (group) - checked /tmp/leader for leadership: group, err=<nil>, leader=true |
| 188 | +DEBU[0030] ID (group) - checked /tmp/leader for leadership: group, err=<nil>, leader=true |
| 189 | + |
| 190 | +``` |
| 191 | + |
| 192 | +You should see that the current instance is detecting that it's the leader, since `$(cat /tmp/leader) == 'group'`. |
| 193 | +You can change the leadership by changing the content of the file `/tmp/leader`: |
| 194 | + |
| 195 | +```shell |
| 196 | +$ echo group2 > /tmp/leader |
| 197 | +``` |
| 198 | + |
| 199 | +You should see the instance detecting its non-leader status and will unwatch groups if any. |
| 200 | + |
| 201 | +```shell |
| 202 | +DEBU[0150] leader: false |
| 203 | +INFO[0150] Lost leadership |
| 204 | +INFO[0150] Unwatching groups |
| 205 | +DEBU[0150] Opening: /Users/myuser/.infrakit/plugins |
| 206 | +DEBU[0150] Discovered plugin at /Users/myuser/.infrakit/plugins/group |
| 207 | +DEBU[0150] Discovered plugin at /Users/myuser/.infrakit/plugins/group-stateless |
| 208 | +DEBU[0150] Discovered plugin at /Users/myuser/.infrakit/plugins/infrakit-flavor-vanilla |
| 209 | +DEBU[0150] Discovered plugin at /Users/myuser/.infrakit/plugins/infrakit-instance-file |
| 210 | +INFO[0150] Processing group managers with plugin group-stateless |
| 211 | +DEBU[0150] exec on group managers plugin= group-stateless |
| 212 | +INFO[0150] UNWATCH group managers with spec: {managers 0xc420123580} |
| 213 | +INFO[0150] Processing group workers with plugin group-stateless |
| 214 | +DEBU[0150] exec on group workers plugin= group-stateless |
| 215 | +INFO[0150] UNWATCH group workers with spec: {workers 0xc4200cb880} |
| 216 | +DEBU[0155] ID (group) - checked /tmp/leader for leadership: group2, err=<nil>, leader=false |
| 217 | +DEBU[0160] ID (group) - checked /tmp/leader for leadership: group2, err=<nil>, leader=false |
| 218 | +``` |
0 commit comments