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

Question: Support for rootless docker-compose #11

Closed
MarkusSchoelzel opened this issue Jun 21, 2021 · 6 comments
Closed

Question: Support for rootless docker-compose #11

MarkusSchoelzel opened this issue Jun 21, 2021 · 6 comments

Comments

@MarkusSchoelzel
Copy link
Contributor

General question:
Is rootless docker-compose a feature, which should be included in these binaries/container images?

With containers/podman#9169 there is (not yet complete) support for running docker-compose with rootless podman, but podman-static is missing some CNI plugins to make it work.

The problably needed plugins were removed in dc8ec32.

@mgoltzsche
Copy link
Owner

mgoltzsche commented Jun 21, 2021

Interesting! I haven't played around with that yet.
Which plugins are required?
Maybe I'll find a moment next weekend to play around with it a bit.

UPDATE: Actually rootless podman doesn't use CNI plugins at all but slirp4netns directly last time I looked.
Also you might run into containers/podman#10734. The fix is already merged though and will probably be released with podman 3.2.2.

@MarkusSchoelzel
Copy link
Contributor Author

I have a pretty special setup: docker running a privileged centos:7 container running rootless podman.

In this case cni plugins firewall and tuning are needed, which were removed in dc8ec32, to make this basic traefik example work.
(the loadbalancer.server.port has to be set manually as port discovery does not work yet?)

version: "3"

services:
  traefik:
    image: docker.io/library/traefik:v2.4
    command: --api.insecure=true --providers.docker
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /tmp/podman.sock:/var/run/docker.sock

  whoami:
    image: docker.io/traefik/whoami:v1.6.1
    labels:
      - "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
      - "traefik.http.services.whoami.loadbalancer.server.port=80"
podman system service --time 0 unix:///tmp/podman.sock
docker-compose -H unix:///tmp/podman.sock up -d
curl -s http://127.0.0.1:8080/api/rawdata | jq '.'
{
  "routers": {
    "api@internal": {
      "entryPoints": [
        "traefik"
      ],
      "service": "api@internal",
      "rule": "PathPrefix(`/api`)",
      "priority": 2147483646,
      "status": "enabled",
      "using": [
        "traefik"
      ]
    },
    "dashboard@internal": {
      "entryPoints": [
        "traefik"
      ],
      "middlewares": [
        "dashboard_redirect@internal",
        "dashboard_stripprefix@internal"
      ],
      "service": "dashboard@internal",
      "rule": "PathPrefix(`/`)",
      "priority": 2147483645,
      "status": "enabled",
      "using": [
        "traefik"
      ]
    },
    "traefik-jenkins@docker": {
      "entryPoints": [
        "http"
      ],
      "service": "traefik-jenkins",
      "rule": "Host(`traefik-jenkins`)",
      "status": "enabled",
      "using": [
        "http"
      ]
    },
    "whoami@docker": {
      "entryPoints": [
        "http"
      ],
      "service": "whoami",
      "rule": "Host(`whoami.docker.localhost`)",
      "status": "enabled",
      "using": [
        "http"
      ]
    }
  },
  "middlewares": {
    "dashboard_redirect@internal": {
      "redirectRegex": {
        "regex": "^(http:\\/\\/(\\[[\\w:.]+\\]|[\\w\\._-]+)(:\\d+)?)\\/$",
        "replacement": "${1}/dashboard/",
        "permanent": true
      },
      "status": "enabled",
      "usedBy": [
        "dashboard@internal"
      ]
    },
    "dashboard_stripprefix@internal": {
      "stripPrefix": {
        "prefixes": [
          "/dashboard/",
          "/dashboard"
        ]
      },
      "status": "enabled",
      "usedBy": [
        "dashboard@internal"
      ]
    }
  },
  "services": {
    "api@internal": {
      "status": "enabled",
      "usedBy": [
        "api@internal"
      ]
    },
    "dashboard@internal": {
      "status": "enabled",
      "usedBy": [
        "dashboard@internal"
      ]
    },
    "noop@internal": {
      "status": "enabled"
    },
    "traefik-jenkins@docker": {
      "loadBalancer": {
        "servers": [
          {
            "url": "http://10.88.2.3:80"
          }
        ],
        "passHostHeader": true
      },
      "status": "enabled",
      "usedBy": [
        "traefik-jenkins@docker"
      ],
      "serverStatus": {
        "http://10.88.2.3:80": "UP"
      }
    },
    "whoami@docker": {
      "loadBalancer": {
        "servers": [
          {
            "url": "http://10.88.2.2:80"
          }
        ],
        "passHostHeader": true
      },
      "status": "enabled",
      "usedBy": [
        "whoami@docker"
      ],
      "serverStatus": {
        "http://10.88.2.2:80": "UP"
      }
    }
  }
}
curl -H Host:whoami.docker.localhost http://127.0.0.1:80
Hostname: c9e5b8a5919a
IP: 127.0.0.1
IP: ::1
IP: 10.88.2.3
IP: fe80::e88d:4eff:fe28:3f8d
RemoteAddr: 10.88.2.2:57236
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.29.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.88.2.2
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: b0c7231c3840
X-Real-Ip: 10.88.2.2

@mgoltzsche
Copy link
Owner

mgoltzsche commented Jun 27, 2021

@MarkusSchoelzel Unfortunately I didn't find the time to play around with it but read about it a bit. So apparently podman-compose is a docker-compose implementation optimized for rootless podman but since version 3 podman also works with the classic docker-compose implementation that was written for docker.

Since I would like to keep the contents of each podman image provided by this repository minimal I don't think docker-compose (any of the two) should be added to one of the existing images.
However I think there could be an additional image tag that ships docker-compose with podman (and additional CNI plugins that are needed). If it makes sense to you a PR in this repo would be welcome.

@mgoltzsche
Copy link
Owner

mgoltzsche commented Jun 27, 2021

On second thought I realize you actually want to install compose on a host and therefore it would be helpful to have the required plugins shipped with the tar, right?
In this case we shouldn't need to add docker-compose to this project directly unless there is a concrete use case to run it within a container.
Also since it requires python and does not purely rely on static binaries that can simply be copied into other images/hosts I don't like shipping docker-compose as a tar from this repository.

To just make the tar release docker-compose compatible it might indeed make sense to just add the missing plugins to the main image this repo ships and from which the tar is built.
However first please have a look if you can disable the firewall and tuning plugins since I don't think that they are really needed in practice to make docker-compose work. They probably just appear in some default CNI configuration.
Since docker-compose does not deal with CNI I guess there is a CNI configuration on your host that uses these additional plugins. Which CNI network configurations (at /etc/cni/net.d) do you have on your host?

@mgoltzsche
Copy link
Owner

mgoltzsche commented Jun 27, 2021

Having now tried your example as well I can see the logs of podman system service --time 0 unix:///tmp/podman.sock:

WARN[0036] Error validating CNI config file /home/max/.config/cni/net.d/podman-static_default.conflist: [failed to find plugin "firewall" in path [/usr/libexec/cni /usr/lib/cni /usr/local/lib/cni /opt/cni/bin] failed to find plugin "tuning" in path [/usr/libexec/cni /usr/lib/cni /usr/local/lib/cni /opt/cni/bin]] 
ERRO[0036] error loading cached network config: network "podman-static_default" not found in CNI cache

So apparently podman generates a CNI configuration itself that includes those plugins upon receiving a call from docker-compose to create the network. In that case I agree it makes sense to add those two plugins here. However when doing so a docker-compose test script should be added to ./test as well - so far it didn't work on my machine (even if I change the example to use an unprivileged port) because it either failed to create the CNI config or paniced.

@MarkusSchoelzel
Copy link
Contributor Author

Thanks for your effort and for thinking about adding the missing plugins!

You are right, my primary concern is just about adding the plugins (as in MarkusSchoelzel@5706153) and don't see a need to add docker-compose (and its python dependencies) to this project.

I've started adding some basic tests, but wasn't able to run them successfully, yet.
Getting timeouts (which I don't see with my special centos:7 setup)

Creating tmp_reverse-proxy_1 ...
Creating tmp_whoami_1 ...
ERROR: for tmp_whoami_1 UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)
ERROR: for tmp_reverse-proxy_1 UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)
ERROR: for whoami UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)

So MarkusSchoelzel@2f76d3d is still wip while I won't be able to work on it in the next couple of weeks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants