できるだけ簡単にKubernetesする（Windows10）Part3

[前回](https://qiita.com/kumato/items/a07e0033b6b09846d45c)は、コンテナ1個しか使わなかったので、
今回は、コンテナを複数使えるようにしていこうと思います。

とはいえ、コンテナの数が多すぎると、
やはり簡単さから遠ざかりますので、
2つでいってみようと思います。

2つでいければ、3つ以上もやり方はほぼ同じですし。


では、コンテナ2つ動かそうと思いますが、
Webサイトでいうところの、
Webサーバー部分と、アプリケーション部分を
分けてみたいと思います。

使うものはなんでも良いのですが、
Webサーバー→nginx
アプリケーション→php
でいってみます。

他のWebサーバーやアプリケーションを使う場合でも、
基本、方法は同じです。


##コンテナを複数起動

ファイル名を「nginx-php.yaml」とでもして、
作成してみます。

今回、他にもいくつかファイルを作成しますが、
すべて前回作った kubernetes ディレクトリ直下に
置いてしまって大丈夫です。

ちなみにですが、
\---
で区切れば、複数書くことが可能です。
ということで、今回は、nginx と php 2つのコンテナを
1つのファイルに書いてみました。

さらに、image のタグもつけてみました。

```
apiVersion: v1
kind: Pod
metadata:
  name: sample-nginx
spec:
  containers:
  - name: sample-nginx-container
    image: nginx:1.19
---
apiVersion: v1
kind: Pod
metadata:
  name: sample-php
spec:
  containers:
  - name: sample-php-container
    image: php:7.4-fpm
```

それではさっそく、試しにこのファイルを適用させてみましょう。

```
C:\Users\test\kubernetes> kubectl apply -f nginx-php.yaml
pod/sample-nginx created
pod/sample-php created
```

nginx と php 両方とも作れたようです。

前回と同じように「kubectl get pods」のコマンドで
状況を確認しようと思いますが、
pods 部分は po に省略できますので、
「kubectl get po」で確認してみます。


```
C:\Users\test\kubernetes> kubectl get po
NAME           READY   STATUS              RESTARTS   AGE
sample-nginx   0/1     ContainerCreating   0          2s
sample-php     0/1     ContainerCreating   0          2s
```

ここまでは、問題なさそうですね。

```
C:\Users\test\kubernetes> kubectl get po
NAME           READY   STATUS    RESTARTS   AGE
sample-nginx   1/1     Running   0          17s
sample-php     1/1     Running   0          17s
```
すこし時間がかかりましたが、両方ともRunningになりました。
問題なさそうです。

##Nginxをブラウザで閲覧する

ひとまず、コンテナは動いたのですが、Webサイト予定ですし、
最終的にはブラウザで見えるようにしたいです。

とはいっても、現状、localhost で、アクセスしようとしても、
ポートが割り当てられていないので、アクセスできません。

ということで、まずは nginx にアクセスできるようにしてみたいと思います。


そこで使うのが「サービス」というものなのですが、
言葉だけ聞くと、わかりづらいので、
ここでは、コンテナへの通信を行うためのもの、
と覚えておいてもらえれば問題ないと思います。


では、そのサービスを追加します。

さきほど作成した nginx-php.yaml の一番下に、
追加してみました。

```
apiVersion: v1
kind: Pod
metadata:
  name: sample-nginx
  labels:
    app: nginx
spec:
  containers:
  - name: sample-nginx-container
    image: nginx:1.19
---
apiVersion: v1
kind: Pod
metadata:
  name: sample-php
spec:
  containers:
  - name: sample-php-container
    image: php:7.4-fpm
---
apiVersion: v1
kind: Service
metadata:
  name: sample-nodeport
spec:
  type: NodePort
  ports:
  - nodePort: 30080
    port: 8080
    targetPort: 80
  selector:
    app: nginx
```

ここも、1つずつ見ていくと、簡単さから遠ざかりそうですので、
必要そうな部分だけ見てみますと、

このサービスは、「30080」のポートで受けられるよ、というのと、
通信先は、「app: nginx」だよ、という部分です。

で、通信先の「app: nginx」は nginx のコンテナにしたいので、
nginx 部分に、

```
  labels:
    app: nginx
```

も追加しておきました。

では、「kubectl apply -f nginx-php.yaml」でファイルを適用させてみましょう。


```
C:\Users\test\kubernetes> kubectl apply -f nginx-php.yaml
pod/sample-nginx configured
pod/sample-php unchanged
service/sample-nodeport created
```

nginx は、「app: nginx」を追加したので、configured になっています。
php は、何もしてないので、unchanged ですね。
で、あらたにサービスを加えたので、nodeport が created しました。


では、この状態で、localhost からポート30080 で通信すると、
サービスを通り、nginx に到達するはずですので、試してみましょう。

http://localhost:30080/

いかがでしょうか。

Welcome to nginx!

が出てきたら、成功です。

![nginx.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645440/64d48af5-aa12-bfb6-edcf-4c790aff4abc.jpeg)


ここまで来れば、静的サイトであれば、
この Nginx コンテナにファイルを置いて完了ですね。


##PHPへのサービス設定

今回は、php とも通信するのが目的ですから、
さらに、php のサービスも追加してみます。


```
apiVersion: v1
kind: Pod
metadata:
  name: sample-nginx
  labels:
    app: nginx
spec:
  containers:
  - name: sample-nginx-container
    image: nginx:1.19
---
apiVersion: v1
kind: Pod
metadata:
  name: sample-php
  labels:
    app: php
spec:
  containers:
  - name: sample-php-container
    image: php:7.4-fpm
---
apiVersion: v1
kind: Service
metadata:
  name: sample-nodeport
spec:
  type: NodePort
  ports:
  - nodePort: 30080
    port: 8080
    targetPort: 80
  selector:
    app: nginx
---
apiVersion: v1
kind: Service
metadata:
  name: sample-clusterip
spec:
  type: ClusterIP
  ports:
  - port: 9000
    protocol: TCP
  selector:
    app: php
```

一番下のブロックに、php のサービスを追加しました。

さっきの nginx では、NodePort というサービスなのに対し、
今回の php では、ClusterIP というサービスです。

これも細かいところまでいくと、だいぶややこしくなるので、
現時点では、ローカルの Windows から通信できるのは、NodePort で、
Kubernetes の中だけで、通信できるのが、ClusterIP という感じで
考えていてください。

php は、nginx から受けられれば問題ないので、
Windows から通信できなくてもOKです。
むしろ通信できない方が安全ですしね。

##NginxからPHPへ通信

残りは、nginx から php へ接続すれば完了ですね。
となると、もう Kubernetes ではなく、nginx の設定になるので、
言われなくてもわかってるよ、という人も多いかもしれませんが、
nginx を以下のような設定にすれば、php のコンテナに通信されます。

「default.conf」という名称で、以下ファイルを作成してみましょう。

```
server {
  listen       80;
  server_name  localhost;

  location / {
    root /var/www/html;

    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass sample-clusterip:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
  }
}
```

nginx を普段から使われている方であれば、
いつもと違う部分は、おそらく fastcgi_pass だけですね。
ここを、「サービス名:ポート」にするだけです。
nginx は Kubernetes 内部にいるので、
clusterip で接続が可能です。

さて、このファイルを nginx コンテナに設置すればいいだけですが、
せっかくですし、今まで避けていた Docker を登場させようと思います。


とはいっても、簡単にしておきたいと思いますので、
ひとまず、「Dockerfile」という名称のファイルを作成してもらって、
以下2行のみ書き、保存します。

```
FROM nginx:1.19
COPY default.conf /etc/nginx/conf.d/default.conf
```

これは、nginx:1.19 の image を元にして、
default.conf を、/etc/nginx/conf.d/default.conf にコピーしてください、
というものです。

保存した「Dockerfile」から、新しく imege を作成するのが、
以下の「docker build -t イメージ名:タグ名 .」コマンドです。

```
C:\Users\test\kubernetes> docker build -t nginx:test .
```

これをざっくりと説明すると、nginx:test というイメージを、
現在のディレクトリにある、Dockerfile から作成するものなのですが、
最後の .（ドット）がわかりづらいですね。

実際はここで、Dockerfile を指定することも可能なのですが、
今いるディレクトリに、Dockerfile が置いてあれば省略可能なので、
. としていました。


問題なく作成できれば、「docker image ls」コマンドで、
作った image が確認できるはずです。

```
C:\Users\test\kubernetes> docker image ls
REPOSITORY                           TAG                                              IMAGE ID            CREATED             SIZE
nginx                                test                                             b1fa55172024        1 minutes ago      132MB
```

他のもずらずら出てくるかと思いますが、
今回は、nginx:test を作ったので問題なさそうですね。


こうなると、nginx:test という image が使用可能ですので、
yaml ファイルの nginx 部分を書き換えましょう。


```
apiVersion: v1
kind: Pod
metadata:
  name: sample-nginx
  labels:
    app: nginx
spec:
  containers:
  - name: sample-nginx-container
    image: nginx:test
---
apiVersion: v1
kind: Pod
metadata:
  name: sample-php
  labels:
    app: php
spec:
  containers:
  - name: sample-php-container
    image: php:7.4-fpm
---
apiVersion: v1
kind: Service
metadata:
  name: sample-nodeport
spec:
  type: NodePort
  ports:
  - nodePort: 30080
    port: 8080
    targetPort: 80
  selector:
    app: nginx
---
apiVersion: v1
kind: Service
metadata:
  name: sample-clusterip
spec:
  type: ClusterIP
  ports:
  - port: 9000
    protocol: TCP
  selector:
    app: php
```

では、これで、再度適用させてみましょう。

```
C:\Users\test\kubernetes> kubectl apply -f nginx-php.yaml
```

http://localhost:30080/

へアクセスしてみます。

File not found. になってしまいました。
php にファイルを置くのを忘れてましたね。

もし、今も nginx の画面が見えているとしたら、
おそらく Windows ブラウザのキャッシュだと思われます。
キャッシュを削除すると、nginx の画面が見えなくなるはずです。

このままだと、ちゃんと php へアクセスできているか
わからないですし、確認したいですね。

さっきのように、「Dockerfile」から新しい php image を作っても良いですが、
php であれば、コンパイルなしに確認できますし、直接コンテナを操作してみましょう。

コンテナを確認して、

```
C:\Users\test\kubernetes> kubectl get po
NAME           READY   STATUS    RESTARTS   AGE
sample-nginx   1/1     Running   0          10m
sample-php     1/1     Running   0          10m
```

sample-php という名前が確認できましたので、コンテナを操作してみましょう。

```
C:\Users\test\kubernetes> kubectl exec -it sample-php /bin/bash
root@sample-php:/var/www/html#  
```

もうすでに、ここが nginx で設定した root ディレクトリのようですので、
index.php を作成してみましょう。

```
root@sample-php:/var/www/html# vi index.php
bash: vi: command not found
```

このコンテナ vi 入ってなかったです。

もちろん vi をインストールしても良いのですが、
php に通信できることがわかりさえすれば良いので、
phpinfo くらいでいいですし、echo コマンドでいってしまいたいと思います。

```
root@sample-php:/var/www/html# echo "<?php phpinfo();" > index.php
```

再度、確認してみると、

http://localhost:30080/

phpinfo が見えました。

問題なさそうですね。

ここまで作成したものを削除したい場合は、
「kubectl delete -f nginx-php.yaml」を実行してください。

```
C:\Users\test\kubernetes> kubectl delete -f nginx-php.yaml
pod "sample-nginx" deleted
pod "sample-php" deleted
service "sample-nodeport" deleted
service "sample-clusterip" deleted
```

これで、消えたはずです。

```
C:\Users\test\kubernetes>kubectl get po
No resources found in default namespace.
```

大丈夫そうですね。

今回、Nginx + PHP で試しましたが、
他のものでも基本やりかたは同じなはずです。

##さいごに

読んでいただきありがとうございました。

ただ、すみません、もっと簡単にできると考えていたのですが、
予想以上に長い＆ややこしくなってしまいました。
もう少し、わかりやすくできたら修正しようと思います。