IBM Cloud 他リージョンやDocker Hubのプライベートのレジストリからk8sへデプロイする方法


IBM Cloud k8s は、北米、欧州、豪州、韓国、東京などで展開しているのですが、レジストリ・サービスも、各リージョンに配置されていて、デフォルトでは、その地域のレジストリ・サービスを利用する様になります。 しかし、他地域に展開したり、マルチクラウドを考慮すると、レジストリ・サービスは、一箇所にしたいということもあります。　そこで、他リージョンのレジストリを利用する方法、そして、Docker Hub のレジストリを利用する方法についてのメモです。


# 他リージョンのレジストリ・サービスを利用してデプロイする

US南部のレジストリ・サービスからコンテナ・イメージをプルして、東京DCのk8sのクラスタへデプロイするケースについて書いてみます。


## US南部レジストリ・サービスのトークンを取得

利用したいコンテナが保存されているレジストリから、トークンを取り出します。
`bx login`した後に、レジストリ・サービスを北米南部(us-south)に指定して、レジストリ・サービスへログインします。

~~~
bx cr region-set us-south
~~~
リージョンを設定して、us-southにログイン

~~~
bx cr login
~~~
us-southのレジストリ・サービスをアクセスするために、トークンの値を取得します。`bx cr token-list`でトークンIDのリストを取得します。そのリージョンにk8sクラスタが作られた事があれば、そのクラスタ名でトークンが生成されています。 `bx cr token-get トークンID`で、認証に利用するトークン値を取り出します。

~~~
bx cr token-list
<中略>
トークン ID                            読み取り専用   有効期限   説明   
182e86d5-91e0-5876-99f9-ff7b1ce6a8b6   true           0          mycluster2   
<中略>

bx cr token-get 182e86d5-91e0-5876-99f9-ff7b1ce6a8b6
固有 ID が「182e86d5-91e0-5876-99f9-ff7b1ce6a8b6」のレジストリー・トークンを取得中...
                 
トークン ID   182e86d5-91e0-5876-99f9-ff7b1ce6a8b6   
トークン      eyJhbGciOiJI<以下省略>
~~~



## 東京DCのk8sクラスタへUS南部レジストリのトークンを登録

次に、東京データセンターに接続したkubectlの環境をセットアップします。手順は以下のようになります。

* `bx login` IBMクラウドへログイン
* `bx cs init --host https://ap-north.containers.bluemix.net` 東京DCへ接続
* `bx cs clusters` クラスタのリストを表示
* `bx cs cluster-config < my cluster name >` kubectlで必要な認証情報を取得
* `export KUBECONFIG=...` 上記で表示された環境変数を設置
* `kubectl get node` 確認のため、クラスタのノード構成を表示 

準備ができたら、kubectl で 認証情報を確認したシークレットを登録します。 この例では、`us-south`がシークレットのラベルになります。このラベルをk8sのデプロイに用いるYAMLファイルに指定することで、ユーザーIDとパスワードを知られることなく、設定する事ができます。

~~~
$ kubectl --namespace default create secret docker-registry us-south \
--docker-server=registry.ng.bluemix.net \
--docker-username=token \
--docker-password=eyJhbGciOiJI<以下省略> \
--docker-email=takara@jp.ibm.com
~~~

上記の\記号は、行の続きを意味する記号です。 

その他の項目を以下に解説します。

* `create secret docker-registry`は、コンテナ・レジストリのシークレットを生成することを指示します
* `--docker-server=` レジストリ・サービスのアドレス
* `--docker-username=token` ユーザー名は `token` で固定です。
* `--docker-password=` パスワードには トークンをセットします。
* `--docker-email=` は必須項目なのですが、特に何もしていません。　会社のメアドをセットしておきます。

これを実行した後、確認するには、次のコマンドを実行します。

~~~
$ kubectl get secret
NAME                     TYPE                                  DATA      AGE
<中略>
us-south                 kubernetes.io/dockercfg               1         1h
~~~


## 東京DCでデプロイ実行

東京DCにデプロイするためのYAMLを以下に示します。 ポイントは、14行目 `image:`で、米国南部のレジストリに登録されたコンテナを指定します。次に、17行目 `imagePullSecrets:` の `name:` で先にラベルを付けた us-south を指定します。 これで、レジストリをアクセスするために必要なトークンをYAMLファイルに記載しないで、認証を実行する事ができる様になります。

~~~file:south_rs.yaml
     1	apiVersion: extensions/v1beta1
     2	kind: Deployment
     3	metadata:
     4	  name: nginx-deployment
     5	spec:
     6	  replicas: 3
     7	  template:
     8	    metadata:
     9	      labels:
    10	        app: nginx
    11	    spec:
    12	      containers:
    13	      - name: nginx
    14	        image: registry.ng.bluemix.net/takara/web:v3
    15	        ports:
    16	        - containerPort: 80
    17	      imagePullSecrets:
    18	      - name: us-south
    19	
    20	---
    21	apiVersion: v1
    22	kind: Service
    23	metadata:
    24	  name: nginx-svc
    25	spec:
    26	  type: NodePort
    27	  selector:
    28	    app: nginx
    29	  ports:
    30	  - protocol: TCP
    31	    port: 80
    32	    nodePort: 31580
~~~    

以下のコマンドで、クラスタへデプロイできます。

~~~
$ kubectl create -f south_rs.yaml
~~~




# Docker Hub のプライベート・リポジトリを利用してデプロイする
Docker Hub にアカウントを持っていれば、IBM Cloud k8s にデプロイする事ができます。 ここではプライベートのリポジトリとして登録して、k8s クラスタにデプロイするまでを書いていきます。

## Docker Hub にプライベートのリポジトリ作成

Docker Hub https://hub.docker.com/ にログインして、"Create Repository" をクリックして、次の画面を開きます。 この例では、Docker Hub のユーザー名が "maho" となっており、その下に web というコンテナを作成します。そして、"Private"に設定します。

![スクリーンショット 2017-12-12 0.08.11.png](https://qiita-image-store.s3.amazonaws.com/0/42829/29509c57-9f1a-f5d3-1ce2-e558c9ed881c.png "スクリーンショット 2017-12-12 0.08.11.png")


## Docker Hubにコンテナ・イメージを登録
dockerコマンドで、Docker Hubにログインします。

~~~
$ docker login -u <username> 
~~~
`docker tag`を利用して、ローカルに登録されたイメージとDocker Hubのイメージを対応づけます。　

~~~
$ docker tag registry.ng.bluemix.net/takara/web:v3 maho/web:v3
~~~
次のコマンドで、Docker Hub にコンテナ・イメージをアップロードします。

~~~
$ docker push maho/web:v3
The push refers to a repository [docker.io/maho/web]
f237703ee57b: Pushed 
110566462efa: Pushed 
305e2b6ef454: Pushed 
24e065a5f328: Pushed 
v3: digest: sha256:659e3b2cf19e66755e0b7928a64a362c23f8e8bfc34a8a03ec13d16a811e4760 size: 1157
~~~
完了したらウェブ画面でも確認しておくと良いでしょう。　


## 東京DCのk8sクラスタへDocker Hubの認証情報を登録

kubectlで東京DCへ接続するまでの手順は、前述と同じです。　環境がセットアップできたら、次のコマンドで、`dockerhub`のラベルで、シークレットを登録します。

~~~
$ kubectl --namespace default create secret docker-registry dockerhub \
--docker-server=index.docker.io \
--docker-username=<username> \
--docker-password=<password> \
--docker-email=<登録メールアドレス>
~~~


## Docker Hubからプルしてk8sクラスタへデプロイ

Docker Hub からプルして、IBM Cloud 東京DCにデプロイするためのYAMLを以下に示します。 ポイントは、14行目 `image:`で、Docker Hubのレジストリに登録されたコンテナを指定します。次に、17行目 `imagePullSecrets:` の `name:` で先にラベルを付けた dockerhub を指定します。 これで、レジストリをアクセスするために必要なトークンをYAMLファイルに記載しないで、認証を実行する事ができる様になります。

~~~file:dockerhub.yml
     1	apiVersion: extensions/v1beta1
     2	kind: Deployment
     3	metadata:
     4	  name: nginx-deployment
     5	spec:
     6	  replicas: 3
     7	  template:
     8	    metadata:
     9	      labels:
    10	        app: nginx
    11	    spec:
    12	      containers:
    13	      - name: nginx
    14	        image: maho/web:v3
    15	        ports:
    16	        - containerPort: 80
    17	      imagePullSecrets:
    18	      - name: dockerhub
    19	
    20	---
    21	apiVersion: v1
    22	kind: Service
    23	metadata:
    24	  name: nginx-svc
    25	spec:
    26	  type: NodePort
    27	  selector:
    28	    app: nginx
    29	  ports:
    30	  - protocol: TCP
    31	    port: 80
    32	    nodePort: 31580
~~~


前述と同様に、適用します。

~~~
kubectl create -f dockerhub.yml
~~~


## まとめ
東京DCのk8sに、米国南部のレジストリからプルする方法、Docker Hub のリポジトリのプライベートからプルする方法について、確認してみました。実際に動作させると、やはり、その地域のレジストリからプルするのが、速度的に早いというのも判りました。 



# 参考資料


[1] IBM Cloud Container Registry CLI https://console.bluemix.net/docs/cli/plugins/registry/index.html#bx_cr_token_add
[2] IBM Cloud Container Registry の概説 https://console.bluemix.net/docs/services/Registry/index.html#index
[3] Push images to Docker Cloud https://docs.docker.com/docker-cloud/builds/push-images/