How to use a private registry with docker swarm an

2019-06-09 18:30发布

I am running a single node swarm, I am using traefik to manage all my external connections, and I want to run a registry such that I can connect to it at registry.myhost.com

Now all the examples I can see suggest creating a registry as a normal container rather than a service, however when I do this, I do not have the ability to add it to my traefik network and thus enable it to be found externally.

Do I need to create another internal network and connect both traefik and it to it, and if so, what type. Or do I need to run the registry as a service (I'm only on a single node so volume shouldnt be much of an issue).

And for bonus points, can anyone give me some pointers on how to set it up with s3 as a storage backend?

1条回答
祖国的老花朵
2楼-- · 2019-06-09 19:15

Overview

You have two machines:

  • Server: Your (single) Docker Swarm manager node that runs traefik and other Docker containers like the registry.
  • Client: Another machine that should be able to connect to the registry and push Docker images to it.

I assume you have two certificate files:

  • registry.myhost.com.crt
  • registry.myhost.com.key

Server

Your server setup might look like this:

~/certs/registry.myhost.com.crt
~/certs/registry.myhost.com.key
~/docker-compose.yml
~/traefik.toml

docker-compose.yml

version: '3'

services:
  frontproxy:
    image: traefik
    command: --api --docker --docker.swarmmode
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./certs:/etc/ssl:ro
      - ./traefik.toml:/etc/traefik/traefik.toml:ro
      - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events
  docker-registry:
    image: registry:2
    deploy:
      labels:
        - traefik.port=5000 # default port exposed by the registry
        - traefik.frontend.rule=Host:registry.myhost.com
        - traefik.frontend.auth.basic=user:$$apr1$$9Cv/OMGj$$ZomWQzuQbL.3TRCS81A1g/ # user:password, see https://docs.traefik.io/configuration/backends/docker/#on-containers

traefik.toml

defaultEntryPoints = ["http", "https"]

# Redirect HTTP to HTTPS and use certificate, see https://docs.traefik.io/configuration/entrypoints/
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]
      [[entryPoints.https.tls.certificates]]
      certFile = "/etc/ssl/registry.myhost.com.crt"
      keyFile = "/etc/ssl/registry.myhost.com.key"

# Docker Swarm Mode Provider, see https://docs.traefik.io/configuration/backends/docker/#docker-swarm-mode
[docker]
endpoint = "tcp://127.0.0.1:2375"
domain = "docker.localhost"
watch = true
swarmMode = true

To deploy your registry run:

docker stack deploy myregistry -c ~/docker-compose.yml

Add Another Stack

If your service is not defined in the same docker-compose.yml as traefik you can use the (external) network of the traefik service:

version: '3'
services:
  whoami:
    image: emilevauge/whoami # A container that exposes an API to show its IP address
    networks:
      - frontproxy_default # add network of traefik service "frontproxy"
      - default
    deploy:
      labels:
        traefik.docker.network: frontproxy_default
        traefik.frontend.rule: Host:whoami.myhost.com
        traefik.frontend.auth.basic: user:$$apr1$$9Cv/OMGj$$ZomWQzuQbL.3TRCS81A1g/ # user:password, see https://docs.traefik.io/configuration/backends/docker/#on-containers
networks:
  frontproxy_default:
    external: true # network of traefik service "frontproxy" is defined in another stack

Make sure you add the certificate files of whoami.myhost.com to traefik.toml:

      [[entryPoints.https.tls.certificates]]
      certFile = "/etc/ssl/registry.myhost.com.crt"
      keyFile = "/etc/ssl/registry.myhost.com.key"
      [[entryPoints.https.tls.certificates]]
      certFile = "/etc/ssl/whoami.myhost.com.crt"
      keyFile = "/etc/ssl/whoami.myhost.com.key"

or use a (single) wildcard certificate *.myhost.com

      [[entryPoints.https.tls.certificates]]
      certFile = "/etc/ssl/myhost.com.crt"
      keyFile = "/etc/ssl/myhost.com.key"

See https://docs.traefik.io/configuration/entrypoints/ for further information.

Client

Copy registry.myhost.com.crt on your client machine to /etc/docker/certs.d/registry.myhost.com/ca.crt on Linux or ~/.docker/certs.d/registry.myhost.com/ca.crt on Mac. Now you should be able to login from the client:

docker login -u user -p password registry.myhost.com

Copy an image from Docker Hub to your registry

On your client run:

docker pull hello-world:latest
docker tag hello-world:latest registry.myhost.com/hello-world:latest
docker push registry.myhost.com/hello-world:latest

Now you can pull this image on another machine (for example on the server):

docker pull registry.myhost.com/hello-world:latest

Don't forget to add registry.myhost.com.crt on that client machine, too.

查看更多
登录 后发表回答