[lv4]ft_services(1/6) metallb+nginx

-> 次(2/6): phpmyadmin portアクセス

0. mysample
https://github.com/syamashi/ft_services

0. VMの設定
https://note.com/syamashi/n/n37a8c524db79

Q. 何ができたらゴール?
A. ft_serverでは、1つのコンテナにwordpress + phpmyadmin + mysqlを積みました。
今回は、それぞれ独立したコンテナを作ります。コンテナ間通信を通じて、マルチサービスが機能すればゴールです。

0. minikube起動
1. metallb+nginx

2. basecamp作る
3. phpmyadmin作る
4. nginxからphpmyadminにリバースプロキシ
5. mysqlのDB作成
6. pypmyadminとmysqlの連携
7. wordpress立ち上げ
8. nginxからwordpressにリダイレクト

[0]. minikubeを起動します
Q. minikube?
A. 作業環境を作るパッケージです。kubernetesが扱える空間ができます。

Q. kubernetes?
A. 少し遠回りします。kubernetesは、独立したコンテナをもとに、何か機能をもったアプリケーション(ポッド)をたくさん起動し、ポッド同士を関連させて運用できる環境です。
wordpress+nginxのポッドはブログサイトとして機能します。
mysqlのポッドはデータベースを用意します。
wordpressポッドとmysqlポッドを連携してデータを保持するとか。
wordpressポッドをたくさん作成し、アクセス窓口を増やして負荷分散させるとか。便利な運用を可能にします。

早速。
/setup.sh 作成

#!/bin/sh

sudo sysctl fs.protected_regular=0
sudo minikube start --vm-driver=none --extra-config=apiserver.service-node-port-range=1-65535
sudo chown -R $USER:$USER $HOME/.minikube
sudo chmod -R 755 $HOME/.minikube
sudo chown -R $USER:$USER $HOME/.kube
sudo chmod -R 755 $HOME/.kube
sudo chmod -R 777 /var/run/docker.sock

Q. #!/bin/sh?
A. コメントアウトじゃないです。Shebangです。/bin/shでの起動を明示します。
A. もしsetup.shに実行権限があれば(chmod 777 とかしておく)、
./setup.sh
だけで、shebangから起動してくれます。(sh ./setup.sh と打たなくてよい)

Q. fs.protected_regular=0?
A. 書き込み制限のオプション。0が制限なしで誰でも書き込みできます。。本当は1がいいかもしれませんが。

Q. --vm-driver=none?

※非推奨。noneはVMのrootをいじるため、レビュワー環境に依存する動作が多いようです。
レビュワー環境の権限設定やコンフィグによって、minikubeが立ち上がらない、実行権限がない、などの不具合が頻発します。
--vm-driver=dockerでの実装をおすすめします。お互い守るため。

A. --vm-driver=noneオプションを付けると、minikubeを実行しているホスト上にkubernetesを構築されます。
この設定は環境を汚すので、気になる場合は、=dockerがいいかもしれませんが、以降の実装に工夫を要します。
デフォルト(このオプションをつけない)ではVirtualBoxのVMを作成して、その上にkubernetes環境が構築されます。

A. =dockerにする場合
eval $(minikube docker-env)
を付け足してください。imageの展開先がローカルじゃなくなるため、docker imagesで表示されません。evalでローカルに展開されるようになります。

Q. chown?
A. sudoを入れなくて済むようにします。

sh setup.sh 実行(~10分くらい)
kubectl --cluster-info 実行し、起動確認。以下成功例

➜  kubectl cluster-info
Kubernetes master is running at https://10.0.2.15:8443
KubeDNS is running at https://10.0.2.15:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

/srcs/nginx/Dockerfile 作成
お気楽にnginxのDockerイメージを作ってみる

FROM alpine:3.13

RUN set -ex; \
	apk update; \
	apk add nginx openssl; \
	mkdir -p /run/nginx

# .key:秘密鍵
# cirtificate signing request = 証明書署名要求 「証明書を発行してもらうために必要なもの」
# "/C=CountryName/ST=StateName/L=CityName/O=OrganizaitonName/OU=OrganizationalUnit/CN=DomainName"

RUN mkdir /etc/nginx/ssl
WORKDIR /etc/nginx/ssl/
RUN openssl req -newkey rsa:4096 -x509 -sha256 -days 3650 -nodes -out ft_service.crt -keyout ft_service.key \
	-subj "/C=JP/ST=Tokyo/L=hoge/O=fuga/OU=foo/CN=localhost"

# doc root
RUN mkdir -p app

COPY app /app
COPY default.conf /etc/nginx/conf.d/default.conf
COPY start.sh /tmp/start.sh

RUN	chmod -R 755 /app /tmp /etc
#access logへの書き込み権限を与えないと、環境変数が出力されない
RUN chown -R nginx:nginx /etc/nginx

WORKDIR /
# port
EXPOSE 80 443 22

# cache clear
RUN rm -rf /var/cache/apk/*

CMD [ "/tmp/start.sh" ]

Q. FROM alpine?
A. 最低限のものしか存在しないイメージです。aptgetが使えないので、apk addを使用する、など対応します。

Q. alpine:3.13?
A. バージョン指定。なければlatestをとってくるかも。ですが、alpineのバージョンによって、apk addできるパッケージが存在したりしなかったりするので、バージョンを固定すべきです(1敗)

​Q. Dockerfileは個別に必要?
A. 独立したコンテナを作るので、機能ごとにDockerfileを作成します。

Q. chown -R nginx:nginx?
A. ※最後に補足します。

Q. chmod -R 755 /tmp?
A. start.shに権限をつけないと、レビュー相手の環境で必ずpermission deniedになり、コンテナが立ち上がりません。(1敗)

/srcs/nginx/app/index.html 作成

<html>
<body>
TEST
</body>
</html>

/srcs/nginx/default.conf 作成

server {
		listen 80 default_server;
		listen [::]:80 default_server;

		server_name _;
       return 301 https://$host$request_uri; # host=192.168.10.10 request_uri=path
}

# log_format: https://www.hatarakumama-pj.com/posts/ginzaitlab8071005/
# 表示させたいserver{}の直前にのみ指定可能。ここ以外だとerror
log_format debug_val_format '$remote_addr - $remote_user [$time_local] "$debug_val"';
server {
		listen 443 ssl ;
		listen [::]:443 ssl;

		ssl_certificate /etc/nginx/ssl/ft_service.crt;
		ssl_certificate_key /etc/nginx/ssl/ft_service.key;

		set $debug_val "uri:$uri request_uri:$request_uri host:$host document_root:$document_root fastcgi_script_name:$fastcgi_script_name";
		access_log /var/log/nginx/access.log debug_val_format;
		error_log  /var/log/nginx/error.log;

		location / {
			index index.html;
			alias /app/;
           try_files $uri $uri/ =404;
		}
}

Q. log_format?
A. デバッグ。環境変数の中身をaccess_logに表示します。

/srcs/nginx/start.sh

#!/bin/sh

nginx
echo "mynginx start"
tail -f /var/log/nginx/access.log

Q. tail -f /var/log/nginx/access.log?
A. アクセスログを標準出力に表示させます。

[1] metallbを起動して、nginxポッドとのアクセス窓口を作る
Q. ゴールは?
A. https://192.168.10.10 で、テストhtmlにアクセスできること。
minikubeでは、https://localhostでアクセスできません。
metalLBに、minikubeとの疎通ができる外部IP(192.168.10.10)を振り出してもらいます。

Q. なぜlocalhostでアクセスできない?
A. 以下の熟読が最も理解しやすかったです。
MetalLB入門 ― オンプレKubernetesクラスタでLoadBalancerタイプのServiceを使う

Q. Node?
A. 今実装のNodeは1つです。複数Nodeは考えません。NodePortも不要。
あわせて、名前空間(Namespace)も1つです。複数Namespaceは考えません。

実装
【手順あり】MetalLBの使い方から動きまで解説します

/srcs/metallb/metallb-config.yaml 作成

apiVersion: v1
kind: ConfigMap
metadata:
 namespace: metallb-system
 name: config
data:
 config: |
   address-pools:
   - name: default
     protocol: layer2
     addresses:
----------変更前---------------------
     - 192.168.10.10-192.168.10.30
----------変更後----------------------
     - 192.168.10.10-192.168.10.10

Q. yaml?
A. kubernetesへの指示書です。公式テンプレートをもとに作成します。

Q. addresses?
A. [subject] 外部IP1つでの運用指示なので、範囲をIP1つ分に絞ります。

srcs/nginx/nginx.yaml 作成

apiVersion: apps/v1
kind: Deployment
metadata:
 labels:
   app: nginx-metallb
 name: nginx-metallb
spec: # podの概要
 replicas: 1
 selector:
   matchLabels:
     app: nginx-metallb
 template: # podのtemplate
   metadata:
     labels:
       app: nginx-metallb
   spec:
     containers:
-----------変更前----------------
     - image: nginx
-----------変更後----------------
     - image: mynginx # 自分のnginxのimage名
       imagePullPolicy: Never
-----------------------------
       name: nginx-metallb
       ports:
       - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
 name: nginx-metallb
spec:
 type: LoadBalancer
 selector: # DeploymentのPodのlabelとセット
   app: nginx-metallb
 ports: # portsが複数ある場合、固有のnameが必要。
   - name: http
     port: 80
-------追記-------
   - name: https
     port: 443 # targetPortは指定がなければ、portと同じ値になる
-----------------

Q. imagePullPolicy: Never?
A. 指定しないと、絶対にローカルイメージをとってきてくれません。

Q. replicas?
A. レプリカセット。kind:Deploymentのメインタスク。
Depoymentは、ポッドの起動数を常に監視しています。
replicas: 1なので、ポッドが1つ立っている状態を常にキープしようとします。

# 1.pod名取得
kubectl get po

# 2.pod削除
kubectl delete pods <pod名>
^C (なんか終わらない)

# (1分待ってから)3.pod名とservice情報取得 (poカンマsvc)
kubectl get po,svc

pod名が変わって立ち上がっているのが確認できます。


/run.sh 作成

#!/bin/sh

# stop services
kubectl delete -f srcs/metallb/metallb-config.yaml
kubectl delete -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml
kubectl delete -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml
kubectl delete -f srcs/nginx/nginx.yaml

# images
docker build -t mynginx srcs/nginx/.

# metallb
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml
# On first install only
kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
kubectl apply -f srcs/metallb/metallb-config.yaml

# containers
kubectl apply -f srcs/nginx/nginx.yaml

Q. なぜsetup.shに追記しないの?
A. 更新はkubectl apply -f でなされます。minikube startは省略可なので、タスク分けします。

➜ sh run.sh
➜ kubectl get svc
nginx-metallb LoadBalancer EXTERNAL-IP=192.168.10.10 を確認
firefoxにて、https://192.168.10.10入力
test画面が表示すれば成功
➜ kubectl get po
nginx-metallb-5656cd6d78-849sx 1/1 Running 0 70s
➜ kubectl logs nginx-metallb-5656cd6d78-849sx
nginx-podの標準出力が確認

Q. Error?
A. kubectl logs deploy/nginx
にてログ確認。何があればログ出し。ログ読む。

metallb+nginxが開通しました。

-> 次(2/6): phpmyadmin portアクセス

追記。nginx.confについて。
※Q. chown -R nginx:nginx?
A. nginxでは、/etc/nginx/conf.d/default.conf にてポートが振り分けられましたが、このdefault.conf、実はサブconfでした。
メインconfは、/etc/nginx/nginx.confです。

/ # cat /etc/nginx/nginx.conf

user nginx;
...
http {
   ...
	# Includes virtual hosts configs.
	include /etc/nginx/http.d/*.conf;
}

Q. user nginx;?
A. 実行ユーザー:nginxが指定されているので、nginxというユーザによって操作されます。
なので、オーナーをnginxにしてpermission deniedを避けます。

Q. include?
A.  /etc/nginx/http.d/*.conf を参照しに行きます。
http.dは、conf.dのシンボリックリンクなので、サブconf (/etc/nginx/conf.d/default.conf) が参照されます。
おそらく、扱うURLが複数あったらurl1.conf, url2,confなど、分けて管理するのが正しい設定かもしれません。
今回単独URL(192.168.10.10だけ)なので、default.confではなく、nginx.confに直接
server {
  listen 80 ...
}
を設定するのがスマートです。

-> 次(2/6): phpmyadmin portアクセス

この記事が気に入ったらサポートをしてみませんか?