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

Document socket-proxy permissions, return early when update failed on scaling down #343

Merged
merged 5 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/backup/stop_restart.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,9 @@ func (s *script) stopContainersAndServices() (func() error, error) {
warnings, err := scaleService(s.cli, svc.serviceID, 0)
if err != nil {
scaleDownErrors.append(err)
} else {
scaledDownServices = append(scaledDownServices, svc)
return
}
scaledDownServices = append(scaledDownServices, svc)
for _, warning := range warnings {
s.logger.Warn(
fmt.Sprintf("The Docker API returned a warning when scaling down service %s: %s", svc.serviceID, warning),
Expand Down
33 changes: 32 additions & 1 deletion docs/how-tos/use-custom-docker-host.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,36 @@ If you are interfacing with Docker via TCP, set `DOCKER_HOST` to the correct URL
DOCKER_HOST=tcp://docker_socket_proxy:2375
```

In case you are using a socket proxy, it must support `GET` and `POST` requests to the `/containers` endpoint. If you are using Docker Swarm, it must also support the `/services` endpoint. If you are using pre/post backup commands, it must also support the `/exec` endpoint.
If you do this as you seek to restrict access to the Docker socket, this tool is potentially calling the following Docker APIs:

| API | When |
|-|-|
| `Info` | always |
| `ContainerExecCreate` | running commands from `exec-labels` |
| `ContainerExecAttach` | running commands from `exec-labels` |
| `ContainerExecInspect` | running commands from `exec-labels` |
| `ContainerList` | always |
`ServiceList` | Docker engine is running in Swarm mode |
| `ServiceInspect` | Docker engine is running in Swarm mode |
| `ServiceUpdate` | Docker engine is running in Swarm mode and `stop-during-backup` is used |
| `ConatinerStop` | `stop-during-backup` labels are applied to containers |
| `ContainerStart` | `stop-during-backup` labels are applied to container |

---

In case you are using [`docker-socket-proxy`][proxy], this means following permissions are required:

| Permission | When |
|-|-|
| INFO | always required |
| CONTAINERS | always required |
| POST | required when using `stop-during-backup` labels |
m90 marked this conversation as resolved.
Show resolved Hide resolved
| EXEC | required when using `exec`-labeled commands |
| SERVICES | required when running in Swarm mode |
| NODES | required when using `stop-during-backup` and running in Swarm mode |
| TASKS | required when using `stop-during-backup` and running in Swarm mode |
m90 marked this conversation as resolved.
Show resolved Hide resolved
| ALLOW_START | required when labeling containers `stop-during-backup` |
| ALLOW_STOP | required when labeling containers `stop-during-backup` |


[proxy]: https://github.com/Tecnativa/docker-socket-proxy
40 changes: 40 additions & 0 deletions test/proxy/docker-compose.swarm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2020-2021 - Offen Authors <[email protected]>
# SPDX-License-Identifier: Unlicense

version: '3.8'

services:
backup:
image: offen/docker-volume-backup:${TEST_VERSION:-canary}
environment:
BACKUP_FILENAME: test.tar.gz
BACKUP_CRON_EXPRESSION: 0 0 5 31 2 ?
DOCKER_HOST: tcp://docker_socket_proxy:2375
volumes:
- pg_data:/backup/pg_data:ro
- ${LOCAL_DIR:-local}:/archive

docker_socket_proxy:
image: tecnativa/docker-socket-proxy:0.1
environment:
INFO: ${ALLOW_INFO:-1}
CONTAINERS: ${ALLOW_CONTAINERS:-1}
SERVICES: ${ALLOW_SERVICES:-1}
POST: ${ALLOW_POST:-1}
TASKS: ${ALLOW_TASKS:-1}
NODES: ${ALLOW_NODES:-1}
volumes:
- /var/run/docker.sock:/var/run/docker.sock

pg:
image: postgres:14-alpine
environment:
POSTGRES_PASSWORD: example
volumes:
- pg_data:/var/lib/postgresql/data
deploy:
labels:
- docker-volume-backup.stop-during-backup=true

volumes:
pg_data:
38 changes: 38 additions & 0 deletions test/proxy/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright 2020-2021 - Offen Authors <[email protected]>
# SPDX-License-Identifier: Unlicense

version: '3.8'

services:
backup:
image: offen/docker-volume-backup:${TEST_VERSION:-canary}
environment:
BACKUP_FILENAME: test.tar.gz
BACKUP_CRON_EXPRESSION: 0 0 5 31 2 ?
DOCKER_HOST: tcp://docker_socket_proxy:2375
volumes:
- pg_data:/backup/pg_data:ro
- ${LOCAL_DIR:-local}:/archive

docker_socket_proxy:
image: tecnativa/docker-socket-proxy:0.1
environment:
INFO: ${ALLOW_INFO:-1}
CONTAINERS: ${ALLOW_CONTAINERS:-1}
POST: ${ALLOW_POST:-1}
ALLOW_START: ${ALLOW_START:-1}
ALLOW_STOP: ${ALLOW_STOP:-1}
volumes:
- /var/run/docker.sock:/var/run/docker.sock

pg:
image: postgres:14-alpine
environment:
POSTGRES_PASSWORD: example
volumes:
- pg_data:/var/lib/postgresql/data
labels:
- docker-volume-backup.stop-during-backup=true

volumes:
pg_data:
76 changes: 76 additions & 0 deletions test/proxy/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/bin/sh

set -e

cd $(dirname $0)
. ../util.sh
current_test=$(basename $(pwd))

export LOCAL_DIR=$(mktemp -d)

docker compose up -d --quiet-pull
sleep 5

# The default configuration in docker-compose.yml should
# successfully create a backup.
docker compose exec backup backup

sleep 5

expect_running_containers "3"

if [ ! -f "$LOCAL_DIR/test.tar.gz" ]; then
fail "Archive was not created"
fi
pass "Found relevant archive file."

# Disabling POST should make the backup run fail
ALLOW_POST="0" docker compose up -d
sleep 5

set +e
docker compose exec backup backup
if [ $? = "0" ]; then
fail "Expected invocation to exit non-zero."
fi
set -e
pass "Invocation exited non-zero."

docker compose down --volumes

# Next, the test is run against a Swarm setup

docker swarm init

export LOCAL_DIR=$(mktemp -d)

docker stack deploy --compose-file=docker-compose.swarm.yml test_stack

sleep 20

# The default configuration in docker-compose.swarm.yml should
# successfully create a backup in Swarm mode.
docker exec $(docker ps -q -f name=backup) backup

if [ ! -f "$LOCAL_DIR/test.tar.gz" ]; then
fail "Archive was not created"
fi

pass "Found relevant archive file."

sleep 5
expect_running_containers "3"

# Disabling POST should make the backup run fail
ALLOW_POST="0" docker stack deploy --compose-file=docker-compose.swarm.yml test_stack

sleep 20

set +e
docker exec $(docker ps -q -f name=backup) backup
if [ $? = "0" ]; then
fail "Expected invocation to exit non-zero."
fi
set -e

pass "Invocation exited non-zero."
Loading