IBM Cloud Docs
Container Registry およびVulnerability Advisorのワークフローに関するチュートリアル

Container Registry およびVulnerability Advisorのワークフローに関するチュートリアル

このチュートリアルでは、IBM Cloud® Container Registry とVulnerability Advisorの両方の基本機能について説明します。

両サービスは事前統合されており、IBM Cloud でシームレスに動作し、コンテナーのユーザーに堅固でシンプルなワークフローを提供します。 両サービスを使用して、コンテナー・イメージの保管、イメージと Kubernetes クラスターのセキュリティーの確保、クラスターへのデプロイに使用できるイメージの管理など、さまざまな作業を行えます。

このチュートリアルで提供される情報の多くは、ドキュメントの "方法"セクションでより詳細に入手できます。 このチュートリアルでは両サービスのすべてのタスクをワークフローに結び付けて、IBM Cloud Container Registry および Vulnerability Advisor の使用の一助となるようにします。 各作業の詳細については、関連リンクをクリックしてください。

目標

チュートリアルには以下の目的があります。

  • IBM Cloud Container Registry および Vulnerability Advisor コア機能を理解します。
  • サービスの機能を使用してワークフローを作成する。

使用されるサービス

このチュートリアルでは以下の IBM Cloud サービスを使用します。

開始前に

始める前に、以下の作業を実行します。

コードからコンテナーの実行まで

コンテナ・イメージの保存に IBM Cloud Container Registry を使ってコンテナ・イメージを保存するのが、 IBM Cloud Kubernetes Service でアプリケーションを立ち上げて実行する最も簡単な方法だ。 以下のステップは、コンテナー・イメージをビルドして、IBM Cloud Container Registryに保管する方法、およびそのイメージを使用する Kubernetes デプロイメントを作成する方法を示しています。

名前空間を作成します。

IBM Cloud Container Registry にコンテナイメージを格納する名前空間を作成する。 リソースグループに含まれているリソース・インスタンスが従う環境および制約。 ユーザーをリソース・グループに関連付けることで、コラボレーションを有効にできます。名前空間が作成されます。 詳細については、名前空間の削除を参照してください。

  1. IBM Cloud にログインして us-south リージョンをターゲットとして設定するために、以下のコマンドを実行します。

    ibmcloud login -r us-south [--sso]
    

    フェデレーテッド ID がある場合は、ibmcloud login -r us-south --sso を使用してログインしてください。 ユーザー名を入力し、CLI 出力に示された URL を使用してワンタイム・パスコードを取得します。 フェデレーテッド ID がある場合は、--sso を指定しないログインは失敗し、--sso オプションを指定したログインは成功します。

  2. IBM Cloud Container Registry コマンドのターゲット・リージョンとして us-south を設定します。

    ibmcloud cr region-set us-south
    
  3. 以下のコマンドを実行して名前空間を作成します。 名前空間の名前を選択し、MY_NAMESPACE をその名前に置き換えます。 このチュートリアルでは、 MY_NAMESPACE を選択したネームスペースに置き換えてください。

    名前空間は、同じリージョン内のすべての IBM Cloud アカウントにわたって固有である必要があります。 名前空間は 4 文字から 30 文字までで、小文字、数字、ハイフン (-)、下線 (_) のみを使用できます。 名前空間は、文字または数値で開始および終了する必要があります。

    特定のリソース・グループに名前空間を作成したい場合は、名前空間のセットアップを参照してください。 名前空間を追加しようとして問題が発生した場合は 、「なぜ名前空間を追加できないのですか?」 を参照してください。

    ibmcloud cr namespace-add MY_NAMESPACE
    

イメージのビルドとプッシュ

コンテナ・イメージをビルドして IBM Cloud Container Registry にプッシュ するには、アプリケーションと DockerfileがDocker イメージをビルドするための指示が含まれるテキスト・ファイル。必要です。 アプリケーションとDockerfile、その他必要な成果物を入手するには、このチュートリアルに関連する GitHub リポジトリをクローンしてください。 このチュートリアルの残りの部分では、複製したリポジトリーのディレクトリーからすべてのコマンドを実行してください。

  1. 以下のコマンドを実行して、イメージをビルドします。

    docker build -t us.icr.io/MY_NAMESPACE/hello-world:1 .
    

    Docker がコンピューター上で実行されている必要があります。実行されていない場合、docker コマンドは失敗します。 IBM Cloud Container Registry は、Docker だけでなく他のクライアントもサポートします。 他のクライアントを使用してログインするには、対話式に名前空間にアクセスするを参照してください。

  2. ローカル Docker デーモンを IBM Cloud Container Registry に記録するには、ibmcloud cr login コマンドを実行します。

    ibmcloud cr login
    

    ログインに問題がある場合は、Container Registry にログインできないのはなぜですか? を参考にしてください。

  3. 次のコマンドを実行して、イメージをプッシュします。

    docker push us.icr.io/MY_NAMESPACE/hello-world:1
    
  4. 次のコマンドを実行して、イメージが正常にアップロードされたことを確認します。

    ibmcloud cr images
    

    APIキーAPIリクエストの認証と承認に使用される固有のコード。 このコードは、呼び出し元のアプリケーションまたはユーザーを識別し、APIの使用状況を追跡・管理するためにAPIに渡されます。 を使用して IBM Cloud Container Registry へのアクセスを自動化し、IAMを使用して IBM Cloud Container Registry リソースへのアクセスを許可することができます

イメージを使用するコンテナーのデプロイ

IBM Cloud Container Registry に保管されているイメージがあるため、そのイメージを使用する IBM Cloud Kubernetes Service でコンテナーを実行できます。CLI を使用したアプリのデプロイを参照してください。

このチュートリアルを通して、MY_CLUSTER を無料の Kubernetes クラスターの名前に置き換えます。

  1. 以下のコマンドを実行します。

    ibmcloud ks cluster-config MY_CLUSTER --export
    

    このコマンドによって、export 環境変数を設定する KUBECONFIG コマンドが生成されます。

  2. 前述のコマンドによって生成された export コマンドをコピーして貼り付けて実行します。

  3. hello-world.yaml をご使用の名前空間に置き換えて、MY_NAMESPACE ファイル内の以下の行を更新します。

    image: us.icr.io/MY_NAMESPACE/hello-world:1
    
  4. イメージをデプロイメントとして実行し、ワーカー・ノードの IP アドレスを使用してアクセスされるサービスを作成することでデプロイメントを公開します。

    kubectl apply -f hello-world.yaml
    
  5. 次のコマンドを実行して新しいサービスの詳細を表示し、ワーカー・ノードで使用されているポートを確認します。

    kubectl describe service hello-world
    

    NodePort:」行の番号をメモします。 このチュートリアルでは、その番号で変数 NODE_PORT を置き換えます。

  6. 次のコマンドの出力に示されているパブリック IP アドレスをメモします。 このチュートリアルでは、変数 PUBLIC_IP を IP アドレスに置き換えます。

    ibmcloud ks workers MY_CLUSTER
    
  7. 次のコマンドを実行して、サービスにアクセスします。 Web ブラウザーを使用することもできます。

    curl PUBLIC_IP:NODE_PORT
    

    ハロー、ワールド!」と表示されればOKだ。

イメージとクラスターの保護

イメージを名前空間にプッシュすると、Vulnerability Advisor によってそのイメージが自動スキャンされ、潜在的な脆弱性が検出されます。 脆弱性が見つかると、報告された脆弱性に対処するための説明が表示されます。

これらの機能を実際に試すには、故意に脆弱性を持たせたイメージをプッシュする必要があります。

イメージは継続的に更新され、CVE は新たに発見されます。 そのため、イメージに存在する脆弱性が追加で見つかることがあります。 その場合は、Vulnerability Advisorから提供された情報を使用してそれらの脆弱性に対処してください。

イメージの脆弱性レポートの表示

イメージのいずれかに脆弱性が検出されると、脆弱性および脆弱性を解決するステップについての詳細情報が記載されたレポートが作成されます。

  1. 脆弱性のあるイメージをビルドしてプッシュします。

    1. 次のコマンドを実行して、脆弱性のあるイメージをビルドします。

      docker build -t us.icr.io/MY_NAMESPACE/hello-world:2 -f Dockerfile-vulnerable .
      
    2. 次のコマンドを実行して、脆弱性のあるイメージをプッシュします。

      docker push us.icr.io/MY_NAMESPACE/hello-world:2
      

    Dockerfile を参照すれば、このイメージが脆弱になった理由がより詳しくわかります。 つまり、Debian ベースのイメージが使用されています。apt パッケージは、CVE-2019-3462 に対して脆弱なバージョンにロールバックされます。

  2. 次のコマンドを実行してイメージをリストし、SECURITY STATUS 列に注目します。

    ibmcloud cr images --va
    

    この列は、イメージに存在する問題の数を表しています。 数値がゼロではないので、このイメージには脆弱性があります。

  3. ibmcloud cr vulnerability-assessment (別名 ibmcloud cr va) コマンドを実行して、脆弱性に関する詳細を取得します。

    ibmcloud cr va us.icr.io/MY_NAMESPACE/hello-world:1
    

    この出力には、脆弱性の ID (ある場合)、影響を受けるパッケージ、問題の解決手順などが含まれています。

クラスターにおけるセキュリティーの適用

イメージに脆弱性が存在していても、そのイメージを使用してクラスターにコンテナーをデプロイすることは可能です。しかし、これは推奨されません。 Portieris を使用すると、いくつかの方法でセキュリティーを適用できます。 例えば、脆弱性のあるイメージをクラスターへのデプロイメントに使用することを禁止できます。

  1. Portieris をインストールします。

  2. Portieris のデフォルト・ポリシーイメージ署名を含んでいるため、このチュートリアルでは制限が多すぎます。 そのため、カスタム・ポリシーを作成する必要があります。 GitHub リポジトリの security.yaml ファイルを見て、 ポリシーの カスタマイズについて読んで、このファイルの内容を理解してください。 簡単に言うと、このポリシーでは、名前空間に存在するすべてのイメージについて、Vulnerability Advisorから問題が報告されていないことが求められます。

  3. security.yaml ファイル内の以下のテキストを更新します。 MY_NAMESPACE はお客様の名前空間です

    repositories:
      - name: us.icr.io/MY_NAMESPACE/*
    
  4. カスタム・ポリシーを適用します。

    kubectl apply -f security.yaml
    
  5. 脆弱性のあるイメージを指すように hello-world.yaml を更新するために、次に示すようにタグを 1から 2 に変更します。

    image: us.icr.io/MY_NAMESPACE/hello-world:2
    
  6. 次のコマンドを実行して、既存のデプロイメントへのパッチの適用を試みます。

    kubectl apply -f hello-world.yaml
    

    次のエラー・メッセージが表示されます。

    Deny "us.icr.io/MY_NAMESPACE/hello-world:2", the Vulnerability Advisor image scan assessment
    found issues with the container image that are not exempted. Refer to your image vulnerability
    report for more details by using the `ibmcloud cr va` command.
    

    Vulnerability Advisor の判断は、ユーザーが作成したすべての免除ポリシーに従うものです。 Vulnerability Advisorから脆弱性があると見なされたイメージを使用するには、1 つ以上の脆弱性を免除して、脆弱性アドバイザーが判断するときに脆弱性と見なされないようにします。 Policy Status コマンドの出力の「ibmcloud cr va」列を参照して問題が免除されているかどうかを確認できます。また、ibmcloud cr exemption-list コマンドを実行して免除をリストすることもできます。

イメージの脆弱性の解決

Vulnerability Advisorによって、イメージに存在する各脆弱性を解決するための手順が示されます。 手順は、How To Resolve コマンドの出力の「ibmcloud cr va」列に表示されます。 その手順に従うと、イメージの問題を解決できます。

CVE は頻繁に発見され、パッチを適用されるものであるため、この Dockerfile は、脆弱性のある既知のバージョンにパッケージをロールバックすることで脆弱性が生じるように意図的に作成されています。 そのため、この脆弱性に対処するには、apt をロールバックする行をコメント化します。

  1. apt がロールバックされないように、Dockerfile-vulnerable の以下の行を、次のように番号記号 (#) を行頭に付けてコメント化します。

    # RUN apt-get install --allow-downgrades -y apt=1.4.8
    
  2. イメージを再度ビルドしてプッシュします。

    1. 次のコマンドを実行して、再度イメージをビルドします。

      docker build -t us.icr.io/MY_NAMESPACE/hello-world:2 -f Dockerfile-vulnerable .
      
    2. 次のコマンドを実行して、再度イメージをプッシュします。

      docker push us.icr.io/MY_NAMESPACE/hello-world:2
      
  3. スキャンが完了するまで待ってから、以下のコマンドを実行してイメージに問題がないことを確認します。

    ibmcloud cr images --va
    
  4. デプロイメントにパッチを適用するために、以下のコマンドを実行します。

    kubectl apply -f hello-world.yaml
    
  5. デプロイメントの完了を待ちます。 デプロイメントが完了したかどうかを確認するには、次のコマンドを実行します。

    kubectl rollout status deployment hello-world
    

    このデプロイメントは成功するので、サービスにアクセスすると、「Hello, world!」と表示されます。

  6. 先に進む前に、デプロイメントとサービスを削除します。

    kubectl delete -f hello-world.yaml
    

デフォルト以外の Kubernetes 名前空間へのデプロイ

IBM Cloud Kubernetes Service クラスターは、IBM Cloud Container Registry のイメージを default の Kubernetes の名前空間に自動的にプルできます。 ただし、 default 以外のネームスペースにデプロイする場合は、さらなる手順が必要です。

Kubernetes と IBM Cloud Container Registry 名前空間は、別のものです。 IBM Cloud Container Registry 名前空間についての詳細は、レジストリー名前空間を参照してください。 Kubernetes 名前空間の詳細については、 名前空間を参照してください。

  1. クラスターで、test という Kubernetes の名前空間を作成します。

    kubectl create namespace test
    
  2. デプロイメントとサービスをこの Kubernetes 名前空間にデプロイするために、hello-world.yaml ファイルのデプロイメントとサービスの両方の metadata.namespace フィールドを default から test に変更します。 このスニペットは、コンテキストでの metadata.namespace フィールドを示しています。

    metadata:
        name: hello-world
        namespace: test
    
  3. 構成を適用します。

    1. 以下のコマンドを実行して、クラスター内でまだ有効な Portieris に構成を適用します。

      kubectl apply -f hello-world.yaml
      

      クラスタではまだ Portieris が有効になっているため、デプロイはすぐに失敗し、次のようなメッセージが表示されます:

      Error from server: error when creating "hello-world.yaml": admission webhook
      "va.hooks.securityenforcement.admission.cloud.ibm.com" denied the request:
      Deny "us.icr.io/MY_NAMESPACE/hello-world:2", no valid ImagePullSecret defined for us.icr.io
      

      このエラーが表示される原因は、Portieris が、test 名前空間では IBM Cloud Container Registry の名前空間のイメージをプルできないのでこのデプロイメントは成功しないと判断したからです。 IBM Cloud Kubernetes Service クラスターの default の Kubernetes 名前空間には、IBM Cloud Container Registry のイメージをプルするための イメージ・プル・シークレットが事前に構成されています。 しかし、新しい名前空間にはそれらのシークレットは存在しません。

    2. Portieris がクラスターから削除された後、構成を適用します。

      1. Portieris を削除します。

      2. 次のコマンドを実行して、構成を適用します。

        kubectl apply -f hello-world.yaml
        

        kubectl apply コマンドは正常に完了します。 ただし、 kubectl describe pod POD_NAME -n test コマンド( POD_NAME はポッドの名前)を実行してデプロイの ポッドをKubernetes クラスター上で実行されているコンテナーのグループ。 ポッドは、スタンドアロン・アプリケーションまたはマイクロサービスのいずれかとして実行可能な作業単位です。検査すると、イベントログにクラスタがイメージをプルする権限がないことが示されます。

        ポッド名は、kubectl get pod -n test を実行して確認できます。

  4. その名前空間にコンテナーをデプロイできるように、名前空間に イメージ・プル・シークレットをセットアップ する必要があります。 いくつかの方法がありますが、このチュートリアルでは、イメージ・プル・シークレットtest 名前空間にコピーする手順に従います。 イメージはこのローカル・レジストリーにあるので、すべての icr.io シークレットをコピーするのではなく、us.icr.io シークレットをコピーできます。 以下のコマンドは、default-us-icr-io シークレットを test 名前空間にコピーし、test-us-icr-io という名前を付けています。

    kubectl get secret default-us-icr-io -o yaml | sed 's/default/test/g' | kubectl -n test create -f -
    
  5. イメージ・プル・シークレットを使用するには、2 つのオプションが使用できます。 このチュートリアルでは、デプロイメントの .yaml ファイルで spec.imagePullSecrets フィールドを設定してイメージ・プル・シークレットを参照する方法を使用します。 次のスニペットは、本文中の必要な行を示しています。最後の 2 行は追加する必要があります。

    spec:
        containers:
        - name: hello-world
        image: us.icr.io/MY_NAMESPACE/hello-world:1
        imagePullPolicy: Always
        imagePullSecrets:
        - name: test-us-icr-io
    
  6. デプロイメントを削除し、構成を再適用します。

    1. 次のコマンドを実行して、デプロイメントを削除します。

      kubectl delete -f hello-world.yaml
      
    2. 次のコマンドを実行して、構成を再適用します。

      kubectl apply -f hello-world.yaml
      

    今回はこのコマンドは成功するので、curl コマンドまたは Web ブラウザーを使用してコンテナーにアクセスできます。