前回は、コンテナ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 に到達するはずですので、試してみましょう。
いかがでしょうか。
Welcome to nginx!
が出てきたら、成功です。
ここまで来れば、静的サイトであれば、
この 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
へアクセスしてみます。
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
再度、確認してみると、
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 で試しましたが、
他のものでも基本やりかたは同じなはずです。
##さいごに
読んでいただきありがとうございました。
ただ、すみません、もっと簡単にできると考えていたのですが、
予想以上に長い&ややこしくなってしまいました。
もう少し、わかりやすくできたら修正しようと思います。