はじめに
組織でコンテナワークロードを開発・運用する際、プライベートなコンテナレジストリを使用し、コンテナイメージを外部と共有することなく利用する環境が求められます。
プライベートなコンテナレジストリからのPodのデプロイは、アプリケーションのマニフェスト・ファイルで、プルするイメージ、プル元のレジストリ、およびイメージのプル時に使用する資格証明を指定することで実現できます。
本記事では、KubernetesのリソースであるSecretを使い、資格情報を.dockerconfigjsonに含めることで、OCIR(Oracle Cloud Infrastrucure Reistory)からOKE(Oracle Cloud Infrastructure Container Engine for Kubernetes)にPodをセキュアにデプロイする手順を解説します。
OCIR(Oracle Cloud Infrastructure Registry)とは
コンテナ・イメージ(Dockerイメージなど)を格納、共有および管理するコンテナレジストリサービスです。ユーザー設定で認証トークンを作成し、Docker CLIを使用してログインすると利用できます。
今回は、Secretを使用し、機密データである認証トークンをアプリケーションコードに含めることなく、プライベートレポジトリからNginxのコンテナイメージをデプロイします。
前提
【作業用インスタンス】
・作業用インスタンスとして ComputeVM(Oracle Linux8) が構築されていること
・作業用インスタンスにDocker CLIがインストールされていること
・作業用インスタンスにkubectlがインストールされていること
【OKEクラスタ】
・OKEクラスターが作成されていること
・OKEクラスターのカスタム作成については下記記事を参考にしてください。
手順
- プライベートコンテナレジストリ(OCIR)の作成とイメージのPush
- Dockerレジストリ・シークレットの作成
- Dockerシークレットを指定し、コンテナ・レジストリからコンテナイメージのデプロイ
1. プライベートコンテナレジストリ(OCIR)の作成とイメージのPush
1-1. プライベートコンテナレジストリ(OCIR)の作成
OCIコンソール画面を開き、「ナビゲーションメニュー」->「開発者サービス」から「コンテナ・レジストリ」を選択します。
「Create repository」を押下します。
画面右にCreate repository画面が表示されるので、作成するレポジトリのコンパートメントを指定し、AccessをPrivateに設定します。
また、Repojitory nameを記載します。今回はnginxをdockerコマンドでpushするため、レポジトリ名の末尾を"/nginx"としています。
画面下にあるCreateボタンを押下し、コンテナ・レジストリの画面に戻ります。
Repositories and imagesのラベルで作成したレポジトリを指定すると、リポジトリ情報が表示されます。
1-2. Nginxイメージのプッシュ
作業用のCompute VMから、作成したコンテナレジストリにイメージをプッシュします。
はじめにコンテナレジストリへログインする必要があります。
コンテナレジストリへのログインには、ユーザの認証トークンが必要です。
認証トークンを作成していない場合は、下記リファレンスを参考に認証トークンを作成します。
認証トークンは再度表示されないため、安全な場所で保管してください。
認証トークンを取得したら、作業用のCompute VMから下記コマンドでコンテナレジストリにログインします。
$ docker login repository_name
レポジトリ名は下記の命名規則となっています。
<リージョンコード>.ocir.io
リージョン別のOCIRレポジトリ名はこちらを参照してください。
今回はロンドンリージョンでOCIRを作成したため、レポジトリ名は lhr.ocir.io となります。
下記コマンドでログインします。
$ docker login lhr.ocir.io
プロンプトが表示されたら、下記命名規則に則ったユーザー名を入力します。
<tenancy-namespace>/oracleidentitycloudservice/<username>
tenancy-namespaceは画面右上のユーザアイコンからテナンシを参照してください。
usernameはナビゲーションメニューから「アイデンティティとセキュリティ」→「ユーザ」で確認できます。
例えば、tenancy-namespaceがoracle、usernameがRallyの場合、ユーザ名が下記となります。
oracle/oracleidentitycloudservice/Rally
パスワードの入力を求められたら、取得した認証トークンの文字列を入力します。
Login Succeededと表示されればログイン完了です。
予めDockerHubからpullし、タグ付けしたnginxのコンテナイメージをpushします。
$ docker push lhr.ocir.io/oracle/test-repo/nginx:1.0.0
OCIRのコンソール画面から、コンテナレポジトリにイメージが追加されたことを確認できます。
2. Dockerレジストリ・シークレットの作成
このプライベートレポジトリからコンテナイメージをpullし、Podをデプロイしたいと思います。
今回、Dockerシークレットを作成し、アプリケーションのマニフェスト・ファイル内でプライベートレポジトリへの認証情報を指定することで、コンテナイメージをpullします。
プライベートレポジトリからコンテナイメージをpullする際に、Secretに含まれているdockerconfigの認証情報が使用されます。
Dockerレジストリ・シークレットの作成には、下記コマンドを実行します。
kubectl create secret docker-registry <secret-name> \
--docker-server=<region-key>.ocir.io \
--docker-username=<tenancy-namespace>/<oci-username> \
--docker-password='<oci-auth-token>' \
--docker-email=<email-address>
"secret-name" には、任意のシークレットの名前を入力します。
"oci-auth-token" には、取得した認証トークンの文字列を入力します。
"email-address" は、任意のメールアドレスで結構です。
作成したシークレットは下記コマンドで確認できます。
今回は、repo-secretという名前でシークレットを作成しました。
$ kubectl get secret
NAME TYPE DATA AGE
repo-secret kubernetes.io/dockerconfigjson 1 2d
3. Dockerシークレットを指定し、コンテナ・レジストリからコンテナイメージのデプロイ
Podをデプロイするためのyamlファイルを作成します。
nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: ngnix-image
spec:
containers:
- name: ngnix
image: lhr.ocir.io/oracle/test-repo/nginx:1.0.0
imagePullPolicy: Always
ports:
- name: nginx
containerPort: 8080
protocol: TCP
imagePullSecrets:
- name: repo-secret
下記コマンドでデプロイします。
$ kubectl apply -f nginx.yaml
podがデプロイされたか確認します。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
ngnix-image 1/1 Running 0 89m
STATUSがRunningになり、Podが正常に稼働していることが確認できました。
参考:Secretを指定せずにデプロイしたパターン
参考に、SecretをimagePullSecretsに指定しないパターンでデプロイしてみます。
下記のyamlファイルでデプロイを行います。
nosecret.yaml
apiVersion: v1
kind: Pod
metadata:
name: no-secret
spec:
containers:
- name: ngnix
image: lhr.ocir.io/oracle/test-repo/nginx:1.0.0
imagePullPolicy: Always
ports:
- name: nginx
containerPort: 8080
protocol: TCP
$ kubectl apply -f nosecret.yaml
pod/no-secret created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
ngnix-image 1/1 Running 0 91m
no-secret 0/1 ErrImagePull 0 11s
Podを確認すると、STATUSにErrImagePullと表示され、Podがデプロイできていないことがわかります。
まとめ
KubernetesのリソースであるSecretを作成し、Secretにコンテナレジストリの資格情報を含めることで、プライベートレジストリからPodをデプロイする手順を解説しました。
Secretを利用することで、Kubernetesクラスタにアクセスできる複数ユーザが共通のプライベートレジストリからコンテナイメージをpullすることができます。
参考