[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 ...
}
を設定するのがスマートです。
この記事が気に入ったらサポートをしてみませんか?