2021年3月3日水曜日

外部に移行した registry で Gitlab 認証を使う方法

概要

過去に Gitlab の registry 機能を外部に移行する方法を紹介しました
そのままでは registry に認証が何もないので誰でも login/push できてしまいます
今回は registry と Gitlab を連携して registry に Gitlab の認証を付けたいと思います
デプロイは前回紹介した docker-compose をベースに修正して行います

環境

  • Gitlab-ee 13.8.4
  • registry

registry 用の証明書と鍵の準備

認証情報のやり取りをする際に暗号化するための証明書と鍵を使います
基本的には registry で https を使うための証明書と鍵があれば OK です
LetsEncrypt などで取得したもので OK です

registry 用の config.yml の作成

registry に必要な最低限の設定も含めて config.yml を作成します

  • vim config.yml
version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
  delete:
    enabled: true
http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3
auth:
  token:
    realm: https://gitlab.example.com/jwt/auth
    service: container_registry
    issuer: gitlab-issuer
    rootcertbundle: /home/tls.crt

ポイントは 2 箇所で storage.delete.enabled = trueauth の部分です
前者は registry のタグ情報を Gitlab 側から削除するのに必須です
後者が認証に必須の設定になります
まず realm は Gitlab の URL + /jwt/auth を記載します
このエンドポイントに対して認証情報を取りに行きます
service と issuer は固定になります
container_registrygitlab-issuer を入力しましょう
rootcerbundle は先程説明した証明書になります
registry 側では証明書を配置することになるのでコンテナに証明書を配置してそのパスを指定します
証明書の配置はこのあと docker-compose.yml 側で行います

gitlab.rb の編集

次に gitlab 側の設定をします
基本にはすでに外部の連携が済んでいる場合は鍵の情報を埋め込むだけになります

gitlab_rails['registry_enabled'] = true
gitlab_rails['registry_host'] = "registry.gitlab.example.com"
gitlab_rails['registry_api_url'] = "http://registry:5000"
gitlab_rails['registry_issuer'] = "gitlab-issuer"
registry['internal_key'] = "-----BEGIN PRIVATE KEY-----\nMIIEvgIBA\n-----END PRIVATE KEY-----"
gitlab_rails['registry_key_path'] = "/home/tls.key"

追加で必要そうなのは registry_issuerinternal_keyregistry_key_path になります
internal_key には冒頭で説明した鍵の方を直接記載します
改行は必ず \n に置換して入力してください
なお上記はサンプルで途中を省いているので実際は鍵の情報すべてを入力してください
そして registry_key_path はその鍵の情報を保存するパスをしていします
registry 側から公開鍵で暗号化されたデータをこの鍵を使って復号化して認証情報を取得し照合します

docker-compose 全体

長いですが全体を紹介します
証明書や config ファイルをマウントする部分が追加になっている感じです

  • vim docker-compose.yml
version: "3.8"

services:
  gitlab:
    image: gitlab/gitlab-ee:13.8.4-ee.0
    ports:
      - "22:22"
      - "80:80"
    volumes:
      - logs:/var/log/gitlab
      - etc_gitlab:/etc/gitlab
      - dot_ssh:/var/opt/gitlab/.ssh
      - uploads:/var/opt/gitlab/gitlab-rails/uploads
      - shared:/var/opt/gitlab/gitlab-rails/shared
      - builds:/var/opt/gitlab/gitlab-ci/builds
      - git-data:/var/opt/gitlab/git-data
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        roles ['application_role']

        external_url 'https://gitlab.example.com'
        nginx['enable'] = true
        nginx['listen_port'] = 80
        nginx['listen_https'] = false

        gitlab_rails['registry_enabled'] = true
        gitlab_rails['registry_host'] = "registry.gitlab.example.com"
        gitlab_rails['registry_api_url'] = "http://registry:5000"
        gitlab_rails['registry_issuer'] = "gitlab-issuer"
        registry['internal_key'] = "-----BEGIN PRIVATE KEY-----\nMIIEvgIBA\n-----END PRIVATE KEY-----"
        gitlab_rails['registry_key_path'] = "/home/tls.key"

        postgresql['enable'] = false
        gitlab_rails['db_adapter'] = 'postgresql'
        gitlab_rails['db_encoding'] = 'unicode'
        gitlab_rails['db_host'] = 'postgres'
        gitlab_rails['db_password'] = 'xxxxxxxx'

        redis['enable'] = false
        gitlab_rails['redis_host'] = "redis"

        prometheus['enable'] = false

        gitlab_workhorse['prometheus_listen_addr'] = "0.0.0.0:9229"
        gitaly['prometheus_listen_addr'] = "0.0.0.0:9236"
        node_exporter['listen_address'] = '0.0.0.0:9100'
        gitlab_exporter['listen_address'] = '0.0.0.0'
        gitlab_exporter['listen_port'] = '9168'
        sidekiq['listen_address'] = '0.0.0.0'
        puma['listen'] = '0.0.0.0'
        puma['port'] = 8080
        gitlab_rails['monitoring_whitelist'] = ['127.0.0.0/8', '172.30.1.0/24']
        gitlab_rails['prometheus_address'] = 'prometheus:9090'
        nginx['status']['options'] = {
          "server_tokens" => "off",
          "access_log" => "off",
          "allow" => "172.30.1.0/24",
          "deny" => "all",
        }
    depends_on:
      - redis
    deploy:
      mode: replicated
      replicas: 2
      placement:
        max_replicas_per_node: 1
  gitlab-runner:
    image: gitlab/gitlab-runner:v13.6.0
  registry:
    image: registry:2
    volumes:
      - registry:/var/lib/registry
      - /root/docker_gitlab/registry/config.yml:/etc/docker/registry/config.yml
      - /root/docker_gitlab/registry/tls.crt:/home/tls.crt
    deploy:
      placement:
        constraints:
          - node.hostname == node1
  registry_web:
    image: nginx:1.19.7
    ports:
      - "81:80"
    volumes:
      - /root/docker_gitlab/registry_nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - registry
    deploy:
      placement:
        constraints:
          - node.hostname == node1
  postgres:
    image: postgres:11.10
    volumes:
      - postgres:/var/lib/postgresql/data/pgdata
      - /root/docker_gitlab/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
    environment:
      POSTGRES_PASSWORD: xxxxxxxx
      PGDATA: /var/lib/postgresql/data/pgdata
    deploy:
      placement:
        constraints:
          - node.hostname == node1
  redis:
    image: redis:6
    volumes:
      - redis:/data
    depends_on:
      - postgres
    command: ["redis-server", "--appendonly", "yes"]
    deploy:
      placement:
        constraints:
          - node.hostname == node1
  prometheus:
    image: prom/prometheus:v2.25.0
    ports:
      - "9090:9090"
    volumes:
      - /root/docker_gitlab/prometheus:/prometheus-data
    command: ["--config.file=/prometheus-data/prometheus.yml"]
    deploy:
      placement:
        constraints:
          - node.hostname == node1
  alertmanager:
    image: prom/alertmanager:v0.21.0
    volumes:
      - /root/docker_gitlab/alertmanager:/alertmanager
    ports:
      - "9093:9093"
    command: ["--config.file=/alertmanager/alertmanager.yml"]
    user: "0:0"
    deploy:
      placement:
        constraints:
          - node.hostname == node1
  grafana:
    image: grafana/grafana:7.4.2
    ports:
      - "3000:3000"
    volumes:
      - grafana:/var/lib/grafana
      - /root/docker_gitlab/grafana/grafana.ini:/etc/grafana/grafana.ini
    deploy:
      placement:
        constraints:
          - node.hostname == node1

volumes:
  logs:
    driver: local
  etc_gitlab:
    driver_opts:
      type: nfs
      o: "addr=192.168.200.10,rw,nfsvers=4"
      device: ":/etc_gitlab"
  dot_ssh:
    driver_opts:
      type: nfs
      o: "addr=192.168.200.10,rw,nfsvers=4"
      device: ":/dot_ssh"
  uploads:
    driver_opts:
      type: nfs
      o: "addr=192.168.200.10,rw,nfsvers=4"
      device: ":/uploads"
  shared:
    driver_opts:
      type: nfs
      o: "addr=192.168.200.10,rw,nfsvers=4"
      device: ":/shared"
  builds:
    driver_opts:
      type: nfs
      o: "addr=192.168.200.10,rw,nfsvers=4"
      device: ":/builds"
  git-data:
    driver_opts:
      type: nfs
      o: "addr=192.168.200.10,rw,nfsvers=4"
      device: ":/git-data"
  registry:
    driver: local
  postgres:
    driver: local
  redis:
    driver: local
  grafana:
    driver: local

networks:
  default:
    attachable: true
    ipam:
     driver: default
     config:
       - subnet: 172.30.1.0/24

動作確認

  • docker stack deploy -c docker-compose.yml

でデプロイして動作確認します
registry に login して Gitlab に存在するユーザでなければログインできないことを確認しましょう

参考サイト

0 件のコメント:

コメントを投稿