SUSE / Portus

Authorization service and frontend for Docker registry (v2)
http://port.us.org/
Apache License 2.0
3k stars 470 forks source link

[Question] Portus best pratices when registry is also a pull through cache? #1989

Open branzo opened 5 years ago

branzo commented 5 years ago

Description

I'm sure this is not a real issue, but i would like to discuss, about some best practices of the use case redacted into the issue's description.

Steps to reproduce

add proxy configuration to registry's config.yaml:

proxy:
  remoteurl: https://registry-1.docker.io
  username: [username]
  password: [password]

then, configure your Docker daemon accordingly by insert into you docker daemon (dockerd) config json:

"registry-mirrors": ["https://your-registry-fqdn"]

or append the following parameters to your Docker daemon cmdline (Gentoo anyone?):

--registry-mirror=https://your-registry-fqdn

and start pull images such as alpine:3.7 or alpine:edge

Should Portus be aware of the library namespace? Should Portus be aware of all new repositories that could be created under the library/ namespace? Do you recommend using another registry for this purpose? Are HRs bad at asking CV in .doc or .docx format?

What do you guys think of this?

Deployment information

Deployment method: i just used examples as a base with some customizations tho.

Configuration:

docker-compose.yaml

version: "2"

services:
  clair:
    container_name: clair
    image: quay.io/coreos/clair:v2.0.5
    restart: unless-stopped
    depends_on:
      - postgres
    ports:
      - "6060-6061:6060-6061"
    links:
      - postgres
    volumes:
      - clairTmp:/tmp
      - ./clair_config:/config
    networks:
      - mynetwork
    command: [-config, /config/config.yaml]
  postgres:
    container_name: postgres
    image: postgres:9-alpine
    restart: unless-stopped
    environment:
      - POSTGRES_PASSWORD=${CLAIR_DB_PWD}
    volumes:
      - clairDB:/var/lib/postgresql/data
    networks:
      - mynetwork
  portus:
    image: opensuse/portus:2.3
    restart: unless-stopped
    environment:
      - PORTUS_MACHINE_FQDN_VALUE=${MACHINE_FQDN}

      # DB. The password for the database should definitely not be here. You are
      # probably better off with Docker Swarm secrets.
      - PORTUS_DB_HOST=db
      - PORTUS_DB_DATABASE=portus_production
      - PORTUS_DB_PASSWORD=${PORTUS_DB_PASSWORD}

      # Secrets. It can possibly be handled better with Swarm's secrets.
      - PORTUS_SECRET_KEY_BASE=${PORTUS_SECRET_KEY_BASE}
      - PORTUS_KEY_PATH=/certificates/cert.key
      - PORTUS_PASSWORD=${PORTUS_PASSWORD}

      # SSL
      - PORTUS_PUMA_TLS_KEY=/certificates/cert.key
      - PORTUS_PUMA_TLS_CERT=/certificates/bundle.pem
      - PORTUS_PUMA_WORKERS=6
      - PUMA_WORKERS=6

      # NGinx is serving the assets instead of Puma. If you want to change this,
      # uncomment this line.
      #- RAILS_SERVE_STATIC_FILES=true
    #ports:
    #  - 3000:3000
    links:
      - db
      - clair
    volumes:
      - /portus/portus_config.yml:/srv/Portus/config/config.yml:ro
      - /mycertpath:/certificates:ro
      - static:/srv/Portus/public
    networks:
      - mynetworks
  background:
    image: opensuse/portus:2.3
    restart: unless-stopped
    environment:
      - CCONFIG_PREFIX=PORTUS
      - PORTUS_MACHINE_FQDN_VALUE=${MACHINE_FQDN}

      # DB. The password for the database should definitely not be here. You are
      # probably better off with Docker Swarm secrets.
      - PORTUS_DB_HOST=db
      - PORTUS_DB_DATABASE=portus_production
      - PORTUS_DB_PASSWORD=${PORTUS_DB_PASSWORD}

      # Secrets. It can possibly be handled better with Swarm's secrets.
      - PORTUS_SECRET_KEY_BASE=${PORTUS_SECRET_KEY_BASE}
      - PORTUS_KEY_PATH=/certificates/cert.key
      - PORTUS_PASSWORD=${PORTUS_PASSWORD}

      #
      - PORTUS_BACKGROUND=true
    links:
      - db
    volumes:
      - /portus/background_config.yml:/srv/Portus/config/config.yml:ro
      - /mycertpath:/certificates:ro
    networks:
      - mynetwork
  db:
    image: library/mariadb:10.0.23
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci --init-connect='SET NAMES UTF8;' --innodb-flush-log-at-trx-commit=0
    environment:
      - MYSQL_DATABASE=portus_production
      # Again, the password shouldn't be handled like this.
      - MYSQL_ROOT_PASSWORD=${PORTUS_DB_PASSWORD}
    volumes:
      - portusDB:/var/lib/mysql
    networks:
      - mynetwork
  registry:
    #image: library/registry:2.6
    image: registry:latest
    command: ["/bin/sh", "/etc/docker/registry/init"]
    environment:
      # Authentication
      REGISTRY_AUTH_TOKEN_REALM: https://${MACHINE_FQDN}/v2/token
      REGISTRY_AUTH_TOKEN_SERVICE: ${MACHINE_FQDN}
      REGISTRY_AUTH_TOKEN_ISSUER: ${MACHINE_FQDN}
      REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE: /secrets/bundle.pem

      # SSL
      REGISTRY_HTTP_TLS_CERTIFICATE: /secrets/bundle.pem
      REGISTRY_HTTP_TLS_KEY: /secrets/cert.key

      # Portus endpoint
      REGISTRY_NOTIFICATIONS_ENDPOINTS: >
        - name: portus
          url: https://${MACHINE_FQDN}/v2/webhooks/events
          timeout: 2000ms
          threshold: 5
          backoff: 1s
    volumes:
      - portusReg:/var/lib/registry
      - /mycertpath:/secrets:ro
      - /portus/config.yml:/etc/docker/registry/config.yml:ro
      - /portus/init:/etc/docker/registry/init:ro
    #ports:
    #  - 5000:5000
    #  - 5001:5001 # required to access debug service
    links:
      - portus:portus
    networks:
      - mynetwork
  nginx:
    image: nginx:alpine
    volumes:
      - /portus/nginx.conf:/etc/nginx/nginx.conf:ro
      - /mycertpath:/secrets:ro
      - static:/srv/Portus/public:ro
    ports:
      - 10.99.99.40:80:80
      - 10.99.99.40:443:443
    links:
      - registry:registry
      - portus:portus
    networks:
      - mynetwork
volumes:
  clairTmp:
    driver: local
  clairDB:
    driver: local
  static:
    driver: local
  portusDB:
    driver: local
  portusReg:
    driver: local
networks:
  mynetwork:
    driver: bridge
    driver_opts:
      com.docker.network.enable_ipv6: "true"
    ipam:
      driver: default

registry config.yaml:

version: 0.1
storage:
  filesystem:
    rootdirectory: /var/lib/registry
  delete:
    enabled: true
  maintenance:
    uploadpurging:
      enabled: true
      age: 120h
      interval: 12h
      dryrun: false
http:
  addr: 0.0.0.0:5000
  debug:
    addr: 0.0.0.0:5001

proxy:
  remoteurl: https://registry-1.docker.io

Portus version: 2.3.5@35b9c801bf5275537a8bd8152d2f5769d6c24b09

mssola commented 5 years ago

I have to admit that I haven't done much with pull through caches. Thus, it's an area in which I need to do some research (thus the discussing tag).

As for the library namespace, I believe that there are three issues which are related and that they are going to be worked on during the 2.5 release: #1241, #1961 and #1944. With this, we should be able to handle the library namespace flawlessly, while allowing transfers, change of teams, etc.

I'd also say that documentation should be written for this one :+1:

branzo commented 5 years ago

Hello again,

i made some experiments during the past night and i would like to integrate some informations into the thread:

as far as i have been able to seen yesterday, it seems that there a problem with token based authentication when the "caching mode" is enabled:

Whilist the login / logout process works smoothly, trying to push to registry (at least to some other namespace than library) will result in a HTTP 405 being thrown as a reply. I have to dig deeper, but someone already pulled up the case at docker/distribution that could be related to this:

Issue: docker/distribution/issues/2478

PR: docker/distribution/pull/2481

mssola commented 5 years ago

Thanks for investigating :clap: That PR looks rather dead (almost a year since it was submitted), so maybe things have changed :thinking:

branzo commented 5 years ago

Hello,

mmh, i'll try to investigate a bit further asap. ^,^

orest-gulman commented 5 years ago

I think that it will be great, if you will deploy 2-to registry(registry and cache) in one UI.