Kubernetesで private registry のイメージをPull する場合には ImagePullSecretsを使う

プライベートレジストリへのログイン方法

makotow
makotow’s blog clone
5 min readNov 6, 2019

--

なにに困って、どのように解決したか

CI/CD のパイプラインを作成時に、イメージ置き場をプライベートレジストリに変えたあとにログインが必要になり、イメージPullが失敗しビルドが通らなくなりました。

プライベートレジストリからイメージをPullするためにはログインが必要になります。

複数のログイン方法がありますが(詳細は「Pull an Image from a Private Registry」を参考)ここではCI/CDパイプラインでイメージをビルドするときや、コンテナをデプロイするときにプライベートレジストリからイメージをダウンロードする際にログインしておらず、エラーで停止してしまうことを防ぐための方法を記載します。

やるべきこと

プライベートレジストリから Pull するときにはコンテナレジストリの認証のためのSecretを作って、ServiceAccount に IamgepullSecrets を追加します。
こうすることでServiceAccount に追加されたImagepullSecretsがPod作成時に自動で付与されるようになります。

各マニフェストにimagePullSecretsに記載する方法もあります。

imagePullSecrets

spec.Pod.imagePullSecrets が準備されており、こちらにpull時に使用するSecretを設定するとクレデンシャルとして使用するようになります。

imagePullSecretsの設定方法としては2つあります。

  • マニフェスト作成者がimagePullSecretsを記述
  • namespace の default service account を作成したSecretをimagePullSecretとして使うよう変更

手順

  1. Secretを作成する
  2. default service account の ImagePullSecrets を変更する。 (マニフェストに直接書く場合は不要)

コマンド

Secretの作成を実施します。
ここではGCRからコンテナイメージを取得することを想定しています。
そのため--docker-server に指定しているレジストリはGCRのアドレスとなっています。

プライベートレジストリなら方法は同じです。 — docker-server を適宜変更してください

コマンドラインからSecret作成時にユーザ名、パスワードを設定します。

$ kubectl create secret docker-registry regcred --docker-server=asia.gcr.io --docker-username=_json_key --docker-password=$(cat key.json)" --docker-email=email-address@address -n namespace

default service account に imagePullSecrets を追加します。上記で作成したSecret名をnameに設定します。

$ kubectl patch serviceaccount default -p '{\"imagePullSecrets\": [{\"name\": \"regcred\"}]}' -n namespace

以下のURLで公開されているマニフェストを例に説明します。

サンプルでは imagePullSecretsが記載されており、name: regcred が指定されています。
この場合、Secretオブジェクトの regcred をイメージPull時に使用します。

apiVersion: v1
kind: Pod
metadata:
name: private-reg
spec:
containers:
- name: private-reg-container
image: <your-private-image>
imagePullSecrets:
- name: regcred

default service account の imagePullSecretを変更した場合は次のようにマニフェストを定義しても(imagePullSecrets がない)、実際は上記のマニフェストと同じようになります。

apiVersion: v1
kind: Pod
metadata:
name: private-reg
spec:
containers:
- name: private-reg-container
image: <your-private-image>

所感

個人的には今回の用途としては、ImagePullSecretをサービスアカウントに設定し問題を解決しました。

運用時にはどちらがいいかと言われると、ケースバイケースという回答になりそうです。
いくつか方法があるということと、デプロイ時に追加できるということを覚えておくことで類似の問題は解決できるのではと考えます。

他にもトークンを設定してログインする方法もあります。
セキュリティ上、本来はトークンを都度生成したほうがいいのかなとも今回考えました。
最適な姿についてはもう少し検討したいと思います。

参考

--

--

makotow
makotow’s blog clone

kubernetes/container/docker/Programming/Go/Scala/Ruby/Mac/Emacs/IntelliJ/Rust/OpenShift.