分散型コンテナイメージレジストリQuayの紹介

Red Hat ソリューションアーキテクトの小島です。

エンタープライズ用途でコンテナアプリを開発・運用していく際には、コンテナイメージのバックアップ、バージョン管理、構成やセキュリティ基準の標準化などのいくつかの理由により、専用のコンテナイメージレジストリが必要になってきます。本記事ではKubernetesやOpenShiftなどのコンテナ環境に利用できる、分散型コンテナイメージレジストリQuayをご紹介します。

Quayとは

QuayはKubernetesやOpenShiftなどのコンテナ環境用のコンテナイメージレジストリです。最初は2013年にQuay.ioというSaaS型のサービスとして提供していたものを、2014年にCoreOSが買収してからオンプレミス版のQuay Enterpriseも提供するようになりました。そして2018年1月にRed HatがCoreOSを買収してからは、Quay EnterpriseをRed Hat Quayという名前に変更して提供しています。元々OpenShift環境の場合だと自動的に内部レジストリが作成され、それを利用して複数の開発チームでのコンテナイメージの共同開発・メンテナンスができるのですが、Quayは下記のような特徴を備えており、エンタープライズでのレジストリ利用をより強力に促進しています。

  • リポジトリ使用状況の可視化 (いつ誰がイメージをPush/Pullしたか、などの情報を保持)
  • Clairと連携したコンテナイメージ脆弱性情報の可視化
  • リポジトリへのイメージPushやイメージ脆弱性検知時などのイベントの自動通知
  • OpenShift環境とは独立した認証情報の利用 (LDAPやOpenID Connectなど)
  • registry.redhat.ioなど外部レジストリからのリポジトリの自動ミラーリング
  • Geo-Replicationによる遠隔地への非同期コピー
  • GitHubなどのWebhookを利用した、Dockerfileからのイメージ自動ビルド
  • OAuth 2 RESTful APIによる外部アプリとの連携
  • 様々なパブリック/プライベートのクラウドストレージサービスをQuayのバックエンドストレージとして利用可能

2020年2月時点では、Amazon S3, Azure Blob Storage, Google Cloud Storage, Ceph Object Gateway, OpenStack Swift, OpenShift Container Storage 4 といったクラウドストレージサービスを、Quayのバックエンドストレージとして利用できます。OpenShift Container Storageについては下記をご参照ください。

rheb.hatenablog.com

上記の特徴を備えているため、セキュリティを考慮したDevSecOpsや、大規模なKubernetes/OpenShift環境用の分散レジストリとしての利用がQuayのメインユースケースとなります。分散レジストリとして利用する場合はリポジトリミラーリングやGeo-Replicationによって、グローバルな環境でコンテナイメージを共有・開発・運用していくイメージが一例として挙げられます。

f:id:h-kojima:20200215000935p:plain

なお、Kubernetes/OpenShiftのマルチクラスタに対して、1つのAPIからサービスをデプロイできるようになるKubernetes KubeFedというOSSのプロジェクトがあります。こうした機能とQuayやOpenShiftを組み合わせると、大規模なコンテナ環境に対してセキュリティ基準や運用手法を統一できるため、ガバナンスを効かせやすくなります。KubeFedのデモ動画を参照したり、Katacodaを利用してKubeFedを体感できますので、これらのWebページもご参照ください。

Using KubeFed to Deploy Applications to OCP3 and OCP4 Clusters

Quayの提供形態

2020年2月時点では下記の2種類です。

この他に、Red Hat Quay.ioとRed Hat Quayのソースコードをベースにオープンソース化したProject Quayがあります。元々Quayはプロプライエタリ・ソフトウェアでしたが、2019年11月にオープンソース化したProject Quayをリリースしています。今後はProject QuayがRed Hat Quay.ioとRed Hat Quayのアップストリームになります。

SaaS版のQuay.ioについては、アカウントを作成して利用プランを選択するだけで使ってみることができます。利用プランは複数ありますが、どのプランでも30日間の無料トライアルを利用でき、かつ、パブリックなリポジトリは無制限に利用できます。無料期間が終了した後も、現時点では 15USドル/1ヶ月~ で利用できますので最初の利用ハードルは比較的低くなっています。

quay.io

Operatorを利用したRed Hat Quayのインストールの前準備

オンプレミス版のRed Hat Quayをインストールするには、下記の手順のいずれかを実行します。いずれの手順でも、Red Hatが提供しているQuayのコンテナイメージをダウンロードしてデプロイします。

Deploy Red Hat Quay - Basic (Quayのテスト用デプロイ)

Deploy Red Hat Quay on OpenShift

Deploy Red Hat Quay on OpenShift with Quay Setup Operator

Deploy Red Hat Quay - High Availability (オンプレやパブリッククラウド上に高可用性なQuay環境をデプロイ)

ここではOpenShift 4のOperatorを利用したRed Hat Quayのインストール手順を紹介していきます。2020年2月時点の最新バージョンであるOpenShift 4.3の利用をここでは想定します。Red Hat Quayは、2019年12月にリリースされた3.2からOperatorを利用したインストール手順を正式にサポートするようになりました。

www.redhat.com

Operatorにより、Red Hat Quayをとても簡単にOpenShift 4の環境上にインストールできるようになっています。Operatorによるインストールには、前提条件が2つあります。

  • OpenShiftクラスタの管理権限(cluster-adminユーザなどの権限)を利用
  • Red Hat Quayのコンテナイメージを取得するための認証情報

認証情報を取得した後は、下記のようなコマンドを実行してQuayをインストールするプロジェクト(この例ではquay-enterprise)上にSecretを作成します。

$ cat << EOF  > redhat-quay-pull-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: redhat-pull-secret
data:
  .dockerconfigjson: XXXXXXXXXX
type: kubernetes.io/dockerconfigjson
EOF
$ oc login -u kubeadmin <OpenShift 4環境のAPI URL>
$ oc new-project quay-enterprise
$ oc create -f redhat-quay-pull-secret.yaml
secret/redhat-pull-secret created

これで前準備は完了です。

Operatorを利用したRed Hat Quayのインストール (GUI)

quay-enterpriseプロジェクト上で、OpenShift 4のOperator HubからQuayのOperatorを選択してインストールします。インストール時に選択するものは、全てデフォルト値のままで「Subscribe」をクリックします。

f:id:h-kojima:20200215121917p:plain

f:id:h-kojima:20200215124522p:plain

これにより、Quay OperatorがPodとしてセットアップされます。quay-operator-xxxxという名前のPodがRunning/Ready状態になればOperatorのセットアップは完了です。このOperatorからQuay環境を自動作成・削除できるようになります。「Installed Operators」->「Quay」->「QuayEcosystem」->「Create QuayEcosystem」と選択していき、下記のようなYAMLファイルを入力して「Create」をクリックすればQuay環境が自動的に作成されます。このYAMLファイルではQuayや後述するClairのコンテナイメージをPullするためのSecretとして、上記手順で作成した「redhat-pull-secret」Secretを指定しています。これにより、example-quayecosystem-xxxxという名前のQuay関連のPod郡がquay-enterpriseプロジェクト上に作成されていきます。

apiVersion: redhatcop.redhat.io/v1alpha1
kind: QuayEcosystem
metadata:
  name: example-quayecosystem
spec:
  quay:
    imagePullSecretName: redhat-pull-secret
    enableRepoMirroring: true
  clair:
    enabled: true
    imagePullSecretName: redhat-pull-secret

f:id:h-kojima:20200215152503p:plain

もし、いずれかのPodがNot ReadyやCrashLoopBackOffなどの状態になっていてQuayのインストールが進まない場合は、一度作成したQuayEcosystemを削除して、再作成してみてください。その場合は、作成したQuayEcosystemの名前をクリックして、「Actions」->「Delete QuayEcosystem」から削除ができます。このとき、quay-operator-xxxxというPodによりQuay関連のPod郡が自動的に削除されます。

下記のようにexample-quayecosystem-xxxxというPodが全てRunning/Ready状態になり、example-quayecosystem-quayというRouteが作成された状態になれば、Quayのインストールは完了です。Quay Operatorにより、PostgreSQL(QuayとClairのメタデータ格納用)、Redis(Quayのチュートリアルやライブビルドログ格納用)、Quay、ClairのPodが自動的に作成されていることを確認できます。

f:id:h-kojima:20200215152433p:plain f:id:h-kojima:20200215132209p:plain

Operatorを利用したRed Hat Quayのインストール (CLI)

CLIを使用してOperator及びRed Hat Quayをインストールする場合は、下記のコマンドを実行します。QuayのOperator GroupとSubscriptionを作成すると、Quay Operatorがデプロイされます。Quay Operatorを利用してquayecosystemというリソースを作成することでQuay関連のPod郡がデプロイされます。

$ cat << EOF  > quay-operatorgroup.yaml
apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
  generateName: "quay-enterprise-"
  namespace: quay-enterprise
spec:
  targetNamespaces:
  - quay-enterprise
EOF
$ oc create -f quay-operatorgroup.yaml

$ cat << EOF  > quay-subscription.yaml
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  generateName: "quay-operator-"
  namespace: quay-enterprise
spec:
  channel: stable
  installPlanApproval: Automatic
  name: quay
  source: community-operators
  sourceNamespace: openshift-marketplace
EOF
$ oc create -f quay-subscription.yaml

$ cat << EOF  > quay-clair-ecosystem.yaml
apiVersion: redhatcop.redhat.io/v1alpha1
kind: QuayEcosystem
metadata:
  name: example-quayecosystem
  namespace: quay-enterprise
spec:
  quay:
    imagePullSecretName: redhat-pull-secret
    enableRepoMirroring: true
  clair:
    enabled: true
    imagePullSecretName: redhat-pull-secret
EOF
$ oc create -f quay-clair-ecosystem.yaml

(参考) 4.1.2. CLI を使用した OperatorHub からのインストール

Operatorを利用したQuayの削除、及び、クラスターからQuay Operatorを削除する場合は、下記のようなコマンドを実行します。

$ oc delete quayecosystem/example-quayecosystem -n quay-enterprise  <- "oc get quayecosystem"で取得したQuay Ecosystemの名前を指定
$ oc delete subscription/quay-operator-xxxxx  -n quay-enterprise    <- "oc get subscription"で取得したQuay Subscriptionの名前を指定
$ oc delete clusterserviceversion/quay.v1.0.1  -n quay-enterprise   <- "oc get clusterserviceversion"で取得したQuayのCluster Service Versionの名前を指定

(参考) 5.2. CLI の使用によるクラスターからの Operator の削除

Red Hat Quayの使用

上記のRouteで表示されているURLにアクセスして、Red Hat Quayにログインします。デフォルトのログインアカウントはUsername: quay, Password: passwordです。

f:id:h-kojima:20200215134830p:plain

イメージリポジトリの作成とPush/Pullを試してみたい場合は、上部の「TUTORIAL」から指定される手順を実施してみるといいでしょう。ただし、TUTORIALで指定される手順はroot権限を必要とするDockerの利用を前提としていますので、非管理ユーザで試して見る場合は、下記のようなPodmanを使う手順を試してみることもできます。やっていることは単純で、busyboxという名前のコンテナイメージをPullしてきてカスタムリポジトリにPushしているだけです。

$ podman login --tls-verify=false -u=quay -p=password example-quayecosystem-quay-XXXXXX.net
$ podman pull busybox
$ podman images
$ podman tag <busyboxイメージのContainer ID> example-quayecosystem-quay-XXXXXX.net/quay/testbusybox  <- QuayのURLの後にユーザ名(quay)と作成するリポジトリ名(testbusybox)を指定
$ podman push --tls-verify=false example-quayecosystem-quay-XXXXXX.net/quay/testbusybox

この手順によりtestbusyboxという名前のリポジトリが作成されることを確認できます。このリポジトリからイメージをPullする場合は下記のようなコマンドを実行します。

$ podman pull --tls-verify=false example-quayecosystem-quay-XXXXXX.net/quay/testbusybox

こうしたリポジトリに対するPush/PullのログをQuayのWebコンソールから確認できます。また、不要になったリポジトリは、リポジトリの設定メニューから削除できます。

f:id:h-kojima:20200215142809p:plain f:id:h-kojima:20200215142828p:plain

カスタムリポジトリに対するコンテナイメージのPushやPullはSaaS版のQuay.ioでもできますが、オンプレミス版のQuayだと外部レジストリを指定したリポジトリのミラーリングを自動実行できるようになります。ミラーリングにはskopeoというレジストリに対するイメージの情報取得・コピー・削除機能を持つソフトウェアを利用しています。設定手順は次の製品ドキュメントに沿って行いますが、基本的には以下の流れです。

Chapter 7. Repository Mirroring in Red Hat Quay

  • ミラーリングに利用する空リポジトリを作成
  • リポジトリの設定画面から、上記リポジトリのRepository Stateを「Mirror」に変更
  • 上記リポジトリに書き込み権限を持つ、ミラーリング用のロボットアカウントを作成
  • リポジトリのミラーリング設定画面から、ミラーリング対象のリポジトリのURL/認証情報、同期間隔などを設定して同期開始

同期間隔の単位は、秒/分/時間/日/週のいずれかを指定できます。下記の例だとDocker Hubにあるlatestタグがついたbusyboxコンテナイメージを、mirror-busyboxというリポジトリに30秒間隔で同期を取る設定にしています。

f:id:h-kojima:20200215155938p:plain

リポジトリのミラーリングログも保存されます。これもコンテナイメージのPush/Pullの場合と同様にWebコンソールから確認できます。ミラーリング機能により複数拠点にあるコンテナイメージレジストリの同期が取りやすくなります。

f:id:h-kojima:20200215160102p:plain

また、リポジトリの設定画面から、リポジトリに対する変更があったときの自動通知も設定できます。リポジトリへのPush、ミラーリング、パッケージの脆弱性発見などのイベント発生時に、Quayユーザアカウントへの通知、Slack、HipChatなどを利用した通知を設定できます。

f:id:h-kojima:20200219141017p:plain

(参考) Chapter 5. Repository Notifications

Clairによるコンテナイメージ脆弱性の静的解析

Quay.ioとQuayではコンテナイメージ脆弱性の静的解析にClairというソフトウェアを利用しています。Clairは公開されている脆弱性情報を定期的に取得し、コンテナイメージ脆弱性の静的解析を行います。Clairが取得する脆弱性情報はRed HatやNISTなどが公開しているものであり、これらの脆弱性情報に対応する種類のコンテナイメージを解析できます。なお、公開している脆弱性情報に該当するかを評価・報告するための言語仕様としてOVALというものがあり、この仕様に準拠した形式で実装されているOVALファイルを脆弱性検査に利用します。例えばRed HatはRHELの脆弱性検査に利用するOVALファイルを公開していますが、こうしたファイルをRHEL7やRHEL8のコンテナイメージの脆弱性解析に利用しています。ClairはRHELなどのコンテナイメージをPushすると、自動的にスキャンを実行してどのような脆弱性があるかを報告します。

f:id:h-kojima:20200215171545p:plain f:id:h-kojima:20200215171604p:plain

Clairはデフォルトでは500分に1回の頻度で脆弱性検査に利用する内部データベースを更新しますが、この更新頻度を変更することもできます。その場合は、QuayEcosystemを作成するときに指定するYAMLファイルにupdateIntervalを追加します。下記の例だと60分に1回の更新頻度を指定しています。

apiVersion: redhatcop.redhat.io/v1alpha1
kind: QuayEcosystem
metadata:
  name: example-quayecosystem
spec:
  quay:
    imagePullSecretName: redhat-pull-secret
    enableRepoMirroring: true
  clair:
    enabled: true
    imagePullSecretName: redhat-pull-secret
    updateInterval: "60m"

さらに、Clairを利用してOpenShift環境全体のコンテナイメージの脆弱性の静的解析を行うことができます。この機能を利用する場合は、Container Security Operator(CSO)をOperator Hubからインストールします。CSOをインストールする場合もデフォルト値から変更しなくてOKです。

f:id:h-kojima:20200215172957p:plain

CLIを使用してCSOをインストールする場合は、下記のコマンドを実行します。

$ cat << EOF  > container-security-subscription.yaml
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  generateName: "container-security-operator-"
  namespace: openshift-operators
spec:
  channel: alpha
  installPlanApproval: Automatic
  name: container-security-operator
  source: community-operators
  sourceNamespace: openshift-marketplace
EOF
$ oc create -f container-security-subscription.yaml

CSOがインストールされると、container-security-operator-xxxxというPodがopenshift-operatorsというプロジェクトに作成されます。このPodがKubernetes APIを利用して、Kubernetes/OpenShift環境にあるコンテナイメージの脆弱性を検査します。検査結果の概要はダッシュボードから確認できます。検知した脆弱性がどのくらいあるかを可視化します。

f:id:h-kojima:20200215173456p:plain

今回の場合だと、表示されているパッケージ名に、OpenShift 4やQuayをインストールする時にPullしてきたQuay.ioにあるRed Hatリポジトリのイメージマニフェストのリンクが貼られていますが、ほとんどの方はQuay.ioのRed Hatのリポジトリにアクセスするためのアカウントを持っていないので、マニフェストが見つかりませんというメッセージしかおそらく表示されないと思います。そこで、脆弱性の情報はYAML形式で確認します。「1 namespaces」といったリンクをクリックすると、ImageManifestVulnという脆弱性情報を持ったリソースが確認できますので、そちらからYAML形式で脆弱性情報を確認します。

f:id:h-kojima:20200215175135p:plain f:id:h-kojima:20200215175150p:plain

ImageManifestVulnの情報はocコマンドでも表示できます。その場合はoc get ImageManifestVulnを実行します。これで脆弱性情報をCLIからでも確認できます。こうして確認した脆弱性情報をもとに、コンテナイメージを随時更新・再デプロイすることで、既知の脆弱性を放置する危険性を少なくできます。

$ oc get ImageManifestVuln --all-namespaces
NAMESPACE         NAME                                                                      AGE
quay-enterprise   sha256.5073e39508248811c10398ce1dbb59d753ff47f690eb97e7938b80e13c628ab7   17m
quay-enterprise   sha256.93b911c720930a49d327f8f97c38dcd510db0692251f139ed709cb83fe00f903   17m
quay-enterprise   sha256.af7de1465d9992b8c5756723f75190d80ca8b18a08a0be7971792668120ee92d   17m
$ oc get ImageManifestVuln/sha256.5073e39508248811c10398ce1dbb59d753ff47f690eb97e7938b80e13c628ab7 -o yaml -n quay-enterprise
apiVersion: secscan.quay.redhat.com/v1alpha1
kind: ImageManifestVuln
metadata:
  creationTimestamp: "2020-02-15T08:25:46Z"
  generation: 1
  labels:
    quay-enterprise/example-quayecosystem-clair-556ff76bd6-g8zs2: "true"
  name: sha256.5073e39508248811c10398ce1dbb59d753ff47f690eb97e7938b80e13c628ab7
  namespace: quay-enterprise
  resourceVersion: "124174"
  selfLink: /apis/secscan.quay.redhat.com/v1alpha1/namespaces/quay-enterprise/imagemanifestvulns/sha256.5073e39508248811c10398ce1dbb59d753ff47f690eb97e7938b80e13c628ab7
  uid: a84d2fb0-8991-4ac0-83e7-ee86cbd07334
spec:
  features:
  - name: perl-Git
    namespaceName: centos:7
    version: 1.8.3.1-20.el7
    versionformat: rpm
    vulnerabilities:
    - description: 'Git is a distributed revision control system with a decentralized
        architecture. As opposed to centralized version control systems with a client-server
        model, Git ensures that each working copy of a Git repository is an exact
        copy with complete revision history. This not only allows the user to work
        on and contribute to projects without the need to have permission to push
        the changes to their official repositories, but also makes it possible for
        the user to work with no network connection. Security Fix(es): * git: Remote
        code execution in recursive clones with nested submodules (CVE-2019-1387)
        For more details about the security issue(s), including the impact, a CVSS
        score, acknowledgments, and other related information, refer to the CVE page(s)
        listed in the References section.'
      fixedby: 0:1.8.3.1-21.el7_7
      link: https://access.redhat.com/errata/RHSA-2020:0124
      name: RHSA-2020:0124
      namespaceName: centos:7
      severity: High
  - name: sqlite
    namespaceName: centos:7
    version: 3.7.17-8.el7
    versionformat: rpm
    vulnerabilities:
    - description: 'SQLite is a C library that implements an SQL database engine.
        A large subset of SQL92 is supported. A complete database is stored in a single
        disk file. The API is designed for convenience and ease of use. Applications
        that link against SQLite can enjoy the power and flexibility of an SQL database
        without the administrative hassles of supporting a separate database server.
        Security Fix(es): * sqlite: fts3: improve shadow table corruption detection
        (CVE-2019-13734) For more details about the security issue(s), including the
        impact, a CVSS score, acknowledgments, and other related information, refer
        to the CVE page(s) listed in the References section.'
      fixedby: 0:3.7.17-8.el7_7.1
      link: https://access.redhat.com/errata/RHSA-2020:0227
      name: RHSA-2020:0227
      namespaceName: centos:7
      severity: High
  - name: git
    namespaceName: centos:7
    version: 1.8.3.1-20.el7
    versionformat: rpm
    vulnerabilities:
    - description: 'Git is a distributed revision control system with a decentralized
        architecture. As opposed to centralized version control systems with a client-server
        model, Git ensures that each working copy of a Git repository is an exact
        copy with complete revision history. This not only allows the user to work
        on and contribute to projects without the need to have permission to push
        the changes to their official repositories, but also makes it possible for
        the user to work with no network connection. Security Fix(es): * git: Remote
        code execution in recursive clones with nested submodules (CVE-2019-1387)
        For more details about the security issue(s), including the impact, a CVSS
        score, acknowledgments, and other related information, refer to the CVE page(s)
        listed in the References section.'
      fixedby: 0:1.8.3.1-21.el7_7
      link: https://access.redhat.com/errata/RHSA-2020:0124
      name: RHSA-2020:0124
      namespaceName: centos:7
      severity: High
  image: quay.io/redhat/clair-jwt
  manifest: sha256:5073e39508248811c10398ce1dbb59d753ff47f690eb97e7938b80e13c628ab7
  namespaceName: centos:7
status:
  affectedPods:
    quay-enterprise/example-quayecosystem-clair-556ff76bd6-g8zs2:
    - cri-o://56c8f9dc4a68d3b02875b214721a0536d5f683d8c29ebf4382e6157168450626
  fixableCount: 3
  highCount: 3
  highestSeverity: High
  lastUpdate: 2020-02-15 08:25:46.564070808 +0000 UTC
まとめ

QuayとClairの概要や、Operatorによる基本的なセットアップ手順と利用手順を一通り紹介してきました。より詳細な情報については下記の参考情報もご参照ください。

References

Red Hat QuayとProject Quayの参考情報の一覧です。

Product Documentation for Red Hat Quay 3 - Red Hat Customer Portal

Red Hat Quay Life Cycle Policy - Red Hat Customer Portal

Red Hat Quay Support Policy - Red Hat Customer Portal

Quay Enterprise 3.x Tested Integrations - Red Hat Customer Portal

https://www.projectquay.io

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。