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 サービスを使用します。
開始前に
始める前に、以下の作業を実行します。
- Git をインストールします。
- インストール IBM CloudDeveloper Tools、リポジトリの
README.md
ファイルの指示に従って、docker
、kubectl
、helm
、ibmcloud
CLI、および必要なプラグインをインストールするスクリプト。 - クラスターを作成します。
- 名前空間イメージをレジストリーに保管するリポジトリーのコレクション。 名前空間は、複数の名前空間を含めることができる IBM Cloud アカウントに関連付けられます。を追加および削除するための適切なアクセス権限があることを確認します。 IBM Cloud Container Registry を構成するためのアクセス ロール」 を参照してください。
コードからコンテナーの実行まで
コンテナ・イメージの保存に IBM Cloud Container Registry を使ってコンテナ・イメージを保存するのが、 IBM Cloud Kubernetes Service でアプリケーションを立ち上げて実行する最も簡単な方法だ。 以下のステップは、コンテナー・イメージをビルドして、IBM Cloud Container Registryに保管する方法、およびそのイメージを使用する Kubernetes デプロイメントを作成する方法を示しています。
名前空間を作成します。
IBM Cloud Container Registry にコンテナイメージを格納する名前空間を作成する。 リソースグループに含まれているリソース・インスタンスが従う環境および制約。 ユーザーをリソース・グループに関連付けることで、コラボレーションを有効にできます。名前空間が作成されます。 詳細については、名前空間の削除を参照してください。
-
IBM Cloud にログインして
us-south
リージョンをターゲットとして設定するために、以下のコマンドを実行します。ibmcloud login -r us-south [--sso]
フェデレーテッド ID がある場合は、
ibmcloud login -r us-south --sso
を使用してログインしてください。 ユーザー名を入力し、CLI 出力に示された URL を使用してワンタイム・パスコードを取得します。 フェデレーテッド ID がある場合は、--sso
を指定しないログインは失敗し、--sso
オプションを指定したログインは成功します。 -
IBM Cloud Container Registry コマンドのターゲット・リージョンとして
us-south
を設定します。ibmcloud cr region-set us-south
-
以下のコマンドを実行して名前空間を作成します。 名前空間の名前を選択し、
MY_NAMESPACE
をその名前に置き換えます。 このチュートリアルでは、MY_NAMESPACE
を選択したネームスペースに置き換えてください。名前空間は、同じリージョン内のすべての IBM Cloud アカウントにわたって固有である必要があります。 名前空間は 4 文字から 30 文字までで、小文字、数字、ハイフン (-)、下線 (_) のみを使用できます。 名前空間は、文字または数値で開始および終了する必要があります。
特定のリソース・グループに名前空間を作成したい場合は、名前空間のセットアップを参照してください。 名前空間を追加しようとして問題が発生した場合は 、「なぜ名前空間を追加できないのですか?」 を参照してください。
ibmcloud cr namespace-add MY_NAMESPACE
イメージのビルドとプッシュ
コンテナ・イメージをビルドして IBM Cloud Container Registry にプッシュ するには、アプリケーションと DockerfileがDocker イメージをビルドするための指示が含まれるテキスト・ファイル。必要です。 アプリケーションとDockerfile、その他必要な成果物を入手するには、このチュートリアルに関連する GitHub リポジトリをクローンしてください。 このチュートリアルの残りの部分では、複製したリポジトリーのディレクトリーからすべてのコマンドを実行してください。
-
以下のコマンドを実行して、イメージをビルドします。
docker build -t us.icr.io/MY_NAMESPACE/hello-world:1 .
Docker がコンピューター上で実行されている必要があります。実行されていない場合、
docker
コマンドは失敗します。 IBM Cloud Container Registry は、Docker だけでなく他のクライアントもサポートします。 他のクライアントを使用してログインするには、対話式に名前空間にアクセスするを参照してください。 -
ローカル Docker デーモンを IBM Cloud Container Registry に記録するには、
ibmcloud cr login
コマンドを実行します。ibmcloud cr login
ログインに問題がある場合は、Container Registry にログインできないのはなぜですか? を参考にしてください。
-
次のコマンドを実行して、イメージをプッシュします。
docker push us.icr.io/MY_NAMESPACE/hello-world:1
-
次のコマンドを実行して、イメージが正常にアップロードされたことを確認します。
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 クラスターの名前に置き換えます。
-
以下のコマンドを実行します。
ibmcloud ks cluster-config MY_CLUSTER --export
このコマンドによって、
export
環境変数を設定するKUBECONFIG
コマンドが生成されます。 -
前述のコマンドによって生成された
export
コマンドをコピーして貼り付けて実行します。 -
hello-world.yaml
をご使用の名前空間に置き換えて、MY_NAMESPACE
ファイル内の以下の行を更新します。image: us.icr.io/MY_NAMESPACE/hello-world:1
-
イメージをデプロイメントとして実行し、ワーカー・ノードの IP アドレスを使用してアクセスされるサービスを作成することでデプロイメントを公開します。
kubectl apply -f hello-world.yaml
-
次のコマンドを実行して新しいサービスの詳細を表示し、ワーカー・ノードで使用されているポートを確認します。
kubectl describe service hello-world
「
NodePort:
」行の番号をメモします。 このチュートリアルでは、その番号で変数NODE_PORT
を置き換えます。 -
次のコマンドの出力に示されているパブリック IP アドレスをメモします。 このチュートリアルでは、変数
PUBLIC_IP
を IP アドレスに置き換えます。ibmcloud ks workers MY_CLUSTER
-
次のコマンドを実行して、サービスにアクセスします。 Web ブラウザーを使用することもできます。
curl PUBLIC_IP:NODE_PORT
ハロー、ワールド!」と表示されればOKだ。
イメージとクラスターの保護
イメージを名前空間にプッシュすると、Vulnerability Advisor によってそのイメージが自動スキャンされ、潜在的な脆弱性が検出されます。 脆弱性が見つかると、報告された脆弱性に対処するための説明が表示されます。
これらの機能を実際に試すには、故意に脆弱性を持たせたイメージをプッシュする必要があります。
イメージは継続的に更新され、CVE は新たに発見されます。 そのため、イメージに存在する脆弱性が追加で見つかることがあります。 その場合は、Vulnerability Advisorから提供された情報を使用してそれらの脆弱性に対処してください。
イメージの脆弱性レポートの表示
イメージのいずれかに脆弱性が検出されると、脆弱性および脆弱性を解決するステップについての詳細情報が記載されたレポートが作成されます。
-
脆弱性のあるイメージをビルドしてプッシュします。
-
次のコマンドを実行して、脆弱性のあるイメージをビルドします。
docker build -t us.icr.io/MY_NAMESPACE/hello-world:2 -f Dockerfile-vulnerable .
-
次のコマンドを実行して、脆弱性のあるイメージをプッシュします。
docker push us.icr.io/MY_NAMESPACE/hello-world:2
Dockerfile を参照すれば、このイメージが脆弱になった理由がより詳しくわかります。 つまり、Debian ベースのイメージが使用されています。
apt
パッケージは、CVE-2019-3462
に対して脆弱なバージョンにロールバックされます。 -
-
次のコマンドを実行してイメージをリストし、
SECURITY STATUS
列に注目します。ibmcloud cr images --va
この列は、イメージに存在する問題の数を表しています。 数値がゼロではないので、このイメージには脆弱性があります。
-
ibmcloud cr vulnerability-assessment
(別名ibmcloud cr va
) コマンドを実行して、脆弱性に関する詳細を取得します。ibmcloud cr va us.icr.io/MY_NAMESPACE/hello-world:1
この出力には、脆弱性の ID (ある場合)、影響を受けるパッケージ、問題の解決手順などが含まれています。
クラスターにおけるセキュリティーの適用
イメージに脆弱性が存在していても、そのイメージを使用してクラスターにコンテナーをデプロイすることは可能です。しかし、これは推奨されません。 Portieris を使用すると、いくつかの方法でセキュリティーを適用できます。 例えば、脆弱性のあるイメージをクラスターへのデプロイメントに使用することを禁止できます。
-
Portieris のデフォルト・ポリシー は イメージ署名を含んでいるため、このチュートリアルでは制限が多すぎます。 そのため、カスタム・ポリシーを作成する必要があります。 GitHub リポジトリの
security.yaml
ファイルを見て、 ポリシーの カスタマイズについて読んで、このファイルの内容を理解してください。 簡単に言うと、このポリシーでは、名前空間に存在するすべてのイメージについて、Vulnerability Advisorから問題が報告されていないことが求められます。 -
security.yaml
ファイル内の以下のテキストを更新します。MY_NAMESPACE
はお客様の名前空間ですrepositories: - name: us.icr.io/MY_NAMESPACE/*
-
カスタム・ポリシーを適用します。
kubectl apply -f security.yaml
-
脆弱性のあるイメージを指すように
hello-world.yaml
を更新するために、次に示すようにタグを1
から2
に変更します。image: us.icr.io/MY_NAMESPACE/hello-world:2
-
次のコマンドを実行して、既存のデプロイメントへのパッチの適用を試みます。
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
をロールバックする行をコメント化します。
-
apt
がロールバックされないように、Dockerfile-vulnerable
の以下の行を、次のように番号記号 (#
) を行頭に付けてコメント化します。# RUN apt-get install --allow-downgrades -y apt=1.4.8
-
イメージを再度ビルドしてプッシュします。
-
次のコマンドを実行して、再度イメージをビルドします。
docker build -t us.icr.io/MY_NAMESPACE/hello-world:2 -f Dockerfile-vulnerable .
-
次のコマンドを実行して、再度イメージをプッシュします。
docker push us.icr.io/MY_NAMESPACE/hello-world:2
-
-
スキャンが完了するまで待ってから、以下のコマンドを実行してイメージに問題がないことを確認します。
ibmcloud cr images --va
-
デプロイメントにパッチを適用するために、以下のコマンドを実行します。
kubectl apply -f hello-world.yaml
-
デプロイメントの完了を待ちます。 デプロイメントが完了したかどうかを確認するには、次のコマンドを実行します。
kubectl rollout status deployment hello-world
このデプロイメントは成功するので、サービスにアクセスすると、「Hello, world!」と表示されます。
-
先に進む前に、デプロイメントとサービスを削除します。
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 名前空間の詳細については、 名前空間を参照してください。
-
クラスターで、
test
という Kubernetes の名前空間を作成します。kubectl create namespace test
-
デプロイメントとサービスをこの Kubernetes 名前空間にデプロイするために、
hello-world.yaml
ファイルのデプロイメントとサービスの両方のmetadata.namespace
フィールドをdefault
からtest
に変更します。 このスニペットは、コンテキストでのmetadata.namespace
フィールドを示しています。metadata: name: hello-world namespace: test
-
構成を適用します。
-
以下のコマンドを実行して、クラスター内でまだ有効な 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 のイメージをプルするための イメージ・プル・シークレットが事前に構成されています。 しかし、新しい名前空間にはそれらのシークレットは存在しません。 -
Portieris がクラスターから削除された後、構成を適用します。
-
Portieris を削除します。
-
次のコマンドを実行して、構成を適用します。
kubectl apply -f hello-world.yaml
kubectl apply
コマンドは正常に完了します。 ただし、kubectl describe pod POD_NAME -n test
コマンド(POD_NAME
はポッドの名前)を実行してデプロイの ポッドをKubernetes クラスター上で実行されているコンテナーのグループ。 ポッドは、スタンドアロン・アプリケーションまたはマイクロサービスのいずれかとして実行可能な作業単位です。検査すると、イベントログにクラスタがイメージをプルする権限がないことが示されます。ポッド名は、
kubectl get pod -n test
を実行して確認できます。
-
-
-
その名前空間にコンテナーをデプロイできるように、名前空間に イメージ・プル・シークレットをセットアップ する必要があります。 いくつかの方法がありますが、このチュートリアルでは、イメージ・プル・シークレットを
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 -
-
イメージ・プル・シークレットを使用するには、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
-
デプロイメントを削除し、構成を再適用します。
-
次のコマンドを実行して、デプロイメントを削除します。
kubectl delete -f hello-world.yaml
-
次のコマンドを実行して、構成を再適用します。
kubectl apply -f hello-world.yaml
今回はこのコマンドは成功するので、
curl
コマンドまたは Web ブラウザーを使用してコンテナーにアクセスできます。 -