yamlを書かずにPrivateのコンテナレジストリからnginxを起動してアクセスする

kubernetes初学者向けの記事となります。
kubernetes環境でPrivateのコンテナレジストリを立てた後、その動作確認をすることを目的にnginxを立てたいことがあるかと思いますが、その具体的な手順を記載しています。

## 前提
- dockerが利用できること
- Kubernetesが利用できること
- Privateのコンテナレジストリが構築済みであること
- kubectl, dockerコマンドはインストール済みであること

## LocalのHarborにnginxをpushする
ローカル環境にtagがlatest（＝省略可能）のnginxのコンテナイメージを取得します。
```
docker pull nginx
```
コンテナイメージにLocalのコンテナレジストリのURLを含めたtagをつけます。
`my-registry.info/library`部分は自環境のものに適宜置き換えてください。
```
docker tag nginx my-registry.info/library/nginx
```
イメージをpushします。
```
docker push my-registry.info/library/nginx
```

## Privateのコンテナレジストリの認証情報を登録する
PrivateのコンテナレジストリがPublicに公開されていない場合、認証していないとイメージ取得に失敗します。そのため、認証情報を予め登録します。
```
kubectl create secret docker-registry my-registry --docker-password 'mypassword' --docker-username 'myusername' --docker-server 'my-regisry.info'
```
`mypassword`、`myusername`、`my-regisry.info`はそれぞれ自環境のものに置き換えてください。

次にnginxのコンテナを起動するサービスアカウントに認証情報を紐付けます。
Kubernetes利用時、リソースを起動するのには必ずサービスアカウントと呼ばれるものが関与します。特に指定しない場合は最初から用意されているdefaultが利用されます。
今回はdefaultのNamespaceにあるdefaultのサービスアカウントに紐付けます。
```
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "my-registry "}]}' -n default
```

## nginxコンテナを立ち上げる
nginxコンテナを利用してPodを起動します。
```
kubectl run --image my-registry.info/library/nginx nginx
```
`--image`でコンテナイメージを指定し、その後にPod名（ここではnginx）を指定しています。

数秒〜数十秒待つとコンテナが起動します。`kubectl get pod`で状態を取得し、STATUSが`Running`になっていればOKです。
```
$ kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          25s
```

## nginxコンテナを公開する
次に作成したnginx Podを公開してnginxにアクセスできるようにします。
公開は3つあります。公開方法とざっくりとした意味は以下となります。
- `type: ClusterIP`：主にPod間でアクセスするために利用する
- `type: NodePort`：Podが起動しているHostのIP:Portを利用してkubernetesクラスタ外からアクセスする
- `type: LoadBalancer`：LoadBalancerが管理しているIPなどを割り当ててkubernetesクラスタ外からアクセスする

この中で、`type: LoadBalancer`はLoadBalancerがいないとIPが割り当てられず外部からアクセスができないため、利用できる環境でのみ指定してください。
今回は利用できるものとして進みます。
`kubectl expose`コマンドを利用すると外部に公開できるため、こちらを利用して公開します。

```
kubectl expose pod nginx --name nginx-svc --port 80 --type LoadBalancer
```
`expose`の後の`pod`は公開する対象リソース、続く`nginx`はそのリソースの名前となります。
先程作成したnginxという名前のPodを公開するため、`kubectl expose pod nginx`となります。
また、exposeを実行すると`Service`というリソースが作成されますが、このServiceリソース名を`--name`で指定しています。`--port`で公開Portを指定し、`--type`で先程述べた公開方法を指定しています。
作成されたServiceリソースを見てみます。取得するには`kubectl get service`で取得します。以下ではServiceの省略形`svc`を使って取得しています。
```
$ kubectl get svc nginx-svc
NAME        TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
nginx-svc   LoadBalancer   10.98.80.43   10.220.21.6   80:31073/TCP   6s
```
無事IPがLoadBalancerから払い出されると、上記のように`EXTERNAL-IP`に外部公開されたIPが表示されます。
なお、LoadBalancerが存在しないなど、IPの割り当てに失敗した場合は以下のように`EXTERNAL-IP`が`<pending>`となります。
```
$ kubectl get svc nginx-svc
NAME        TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
nginx-svc   LoadBalancer   10.98.80.43   <pending>     80:31073/TCP   6s
```

## nginxコンテナにアクセスする
普通にブラウザでアクセスすれば、nginxの画面を見ることが出来るはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/230e7d73-9857-3dda-b5cb-ad7a178f7fa9.png)

なお、dockerhubで配布されているnginxコンテナは標準出力にログを吐いています。
ログは以下のコマンドで確認できます。
```
$ kubectl logs nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
：（省略）
192.168.3.1 - - [22/Dec/2022:03:51:14 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://10.220.21.6/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36" "-"
192.168.3.1 - - [22/Dec/2022:03:52:59 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36" "-"
```
このようにアクセスログを標準出力に吐いている場合はリアルタイムでログも確認することが出来ます。