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

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

makotow
makotow
Nov 6 · 5 min read

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

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を記述

手順

  1. Secretを作成する

コマンド

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’s blog

technical articles, learning articles and thoughts.

makotow

Written by

makotow

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

makotow’s blog

technical articles, learning articles and thoughts.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade