Skip to content

Commit

Permalink
Feat: master auto-accepts minions
Browse files Browse the repository at this point in the history
* No more auth keys versioned
* Generalize instruction to build minion
* Do not pass volumes when launching containers
  • Loading branch information
mbologna committed Apr 26, 2017
1 parent fc2b66c commit 6e5d266
Show file tree
Hide file tree
Showing 18 changed files with 496 additions and 1,448 deletions.
1 change: 1 addition & 0 deletions Dockerfile-master
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ RUN zypper --non-interactive addrepo http://download.opensuse.org/repositories/d
mkdir /var/run/supervisord/

COPY etc_master/supervisord.conf /etc/supervisor.d/supervisord.conf
COPY etc_master/salt/master /etc/salt/master
VOLUME ["/etc/salt"]
EXPOSE 8000
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor.d/supervisord.conf"]
145 changes: 65 additions & 80 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,112 +6,97 @@ This repository contains two **Dockerfile**s of [*SaltStack*](https://http://sal

In particular, this repository contains two Docker images:

* [**saltstack-master**](https://registry.hub.docker.com/u/mbologna/saltstack-master): a SaltStack master container image with netapi module (cherrypy) enabled.
* [**saltstack-master**](https://registry.hub.docker.com/u/mbologna/saltstack-master): a SaltStack master container image. This salt setup accepts all minions that connects to it and comes with netapi module (cherrypy) enabled.
This container works with `supervisord` to automatically launch `salt-master` and `salt-api` daemons.
* [**saltstack-minion**](https://registry.hub.docker.com/u/mbologna/saltstack-minion): a SaltStack minion container image.

Both of the images *expect* that you declare a volume in which you pass config files and keys (see `etc_*` directories and usage).
In this way, the two images are standard and can be customized by specifing a volume with config files.

## Base Docker image

* opensuse 42.2

## Installation

1. Install [Docker](https://www.docker.com/).

2. Download [SaltStack master automated build](https://registry.hub.docker.com/u/mbologna/saltstack-master) from public [Docker Hub Registry](https://registry.hub.docker.com/): `docker pull mbologna/saltstack-master`

(alternatively, you can build an image from Dockerfile: `docker build -t="mbologna/saltstack-master" github.com/mbologna/saltstack-master`)
## Dependencies

3. Download [SaltStack minion automated build](https://registry.hub.docker.com/u/mbologna/saltstack-minion) from public [Docker Hub Registry](https://registry.hub.docker.com/): `docker pull mbologna/saltstack-master`

(alternatively, you can build an image from Dockerfile: `docker build -t="mbologna/saltstack-minion" github.com/mbologna/saltstack-minion`)
* [Docker](https://www.docker.com/)

## Usage

### run saltstack-master

% docker run -d --name saltmaster -v `pwd`/etc_master/salt:/etc/salt -p 8000:8000 -ti mbologna/saltstack-master

### run saltstack-minion1
### Start `saltstack-master` container

% docker run -d --name saltminion1 --link saltmaster -v `pwd`/etc_minion1/salt:/etc/salt mbologna/saltstack-minion
```bash
docker run -d --name saltmaster -p 8000:8000 -ti mbologna/saltstack-master
```

### run saltstack-minion2
### Start `saltstack-minion` container (could be more than one!)

% docker run -d --name saltminion2 --link saltmaster -v `pwd`/etc_minion2/salt:/etc/salt mbologna/saltstack-minion
* You can start one minion...

### have fun!
```bash
docker run -d --name saltminion --link saltmaster:salt mbologna/saltstack-minion
```

Now you can access `saltstack-master` either via NetAPI:
* or you can deploy an army of minions:

```bash
% curl -sS http://localhost:8000/login \
-c ~/cookies.txt \
-H 'Accept: application/json' \
-d username=saltdev \
-d password=saltdev \
-d eauth=pam
```
```bash
for i in {1..10}; do docker run -d --name saltminion$i --link saltmaster:salt mbologna/saltstack-minion ; done
```

```
{"return": [{"perms": [".*"], "start": 1446379166.406894, "token": "4072d45939ad1a33ffbe0565ec7d15d0cf2e24c2", "expire": 1446422366.406895, "user": "saltdev", "eauth": "pam"}]}
```
### Run Salt via command line

```bash
% curl -sS http://localhost:8000 \
-b ~/cookies.txt \
-H 'Accept: application/json' \
-d client=local \
-d tgt='*' \
-d fun=test.ping
docker exec saltmaster /bin/sh -c "salt '*' cmd.run 'uname -a'"
```

```
{"return": [{"minion1": true, "minion2": true}]}
2c11ad007398:
Linux 2c11ad007398 4.4.57-18.3-default #1 SMP Thu Mar 30 06:39:47 UTC 2017 (39c8557) x86_64 x86_64 x86_64 GNU/Linux
270d8ae3f11c:
Linux 270d8ae3f11c 4.4.57-18.3-default #1 SMP Thu Mar 30 06:39:47 UTC 2017 (39c8557) x86_64 x86_64 x86_64 GNU/Linux
3cdff54e495b:
Linux 3cdff54e495b 4.4.57-18.3-default #1 SMP Thu Mar 30 06:39:47 UTC 2017 (39c8557) x86_64 x86_64 x86_64 GNU/Linux
```

or via command line:

```bash
% docker exec saltmaster /bin/sh -c "salt '*' test.ping"
```
```
minion1:
True
minion2:
True
```

### (optional) configure additional minions

I'm sure you grasp the main concept now:

1. Generate keys and certs and place them in `/etc/salt`
2. Launch a saltstack-minion mapping `/etc/salt/` the correct volume and link the container to `saltmaster` container
3. Remember to accept minion keys on saltstack-master
4. Conquer the world
### Run Salt via NetAPI

1. Get a token to use in all subsequent calls:
```bash
curl -sS http://localhost:8000/login -c ~/cookies.txt -H 'Accept: application/json' -d username=saltdev -d password=saltdev -d eauth=pam
```
```
{
"return": [
{
"perms": [
".*"
],
"start": 1446379166.406894,
"token": "4072d45939ad1a33ffbe0565ec7d15d0cf2e24c2",
"expire": 1446422366.406895,
"user": "saltdev",
"eauth": "pam"
}
]
}
```
2. Invoke Salt using saved token:
```bash
curl -sS http://localhost:8000 -b ~/cookies.txt -H 'Accept: application/json' -d client=local -d tgt='*' -d fun=cmd.run -d arg="uptime"
```
```
{
"return": [
{
"2dea7929f17f": " 23:55pm up 2 days 8:28, 0 users, load average: 1.31, 1.97, 1.70",
"ed30e90b1caa": " 23:55pm up 2 days 8:28, 0 users, load average: 1.31, 1.97, 1.70",
"3cdff54e495b": " 23:55pm up 2 days 8:28, 0 users, load average: 1.31, 1.97, 1.70"
}
]
}
```

## Caveats and security

1. `saltstack-master` exposes port 8000/tcp (**NO SSL**) in order to consume `salt-api` via its HTTP interface.
**WARNING**: your credentials travel in plain-text.

2. Please note that the provided keys and certs are intended to use **ONLY** in test environments. **DO NOT** use them in production.

3. I couldn't get `saltstack-master` to work with EAUTO auth module.
Workaround: I had to manually add a `saltdev` user (password: `saltdev`) to the container (see `Dockerfile-master`) and use PAM authentication. Again, use these containers only in test environments.

## Credits

Credits goes to [@UtahDave](https://github.com/UtahDave/salt-vagrant-demo/): I copied certs and keys from its `salt-vagrant-demo` repository.
* `saltstack-master` exposes port `8000/tcp` (**NO SSL**) in order to consume `salt-api` via its HTTP interface.

## Contributing
**WARNING**: your credentials travel in plain-text.

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request
* `saltstack-master` works with PAM authentication module.
A `saltdev` user (password: `saltdev`) has been added to the container.
Loading

0 comments on commit 6e5d266

Please sign in to comment.