docker-composeで作ったものをkubernetesで動かしてみたので備忘録として記事を書いた
環境
Windows 10
Docker Desktop for Windows 3.3.1(63152)
元のdocker-compose
NginxとFlaskのごく単純なリバースプロキシ
ソースコードはこちら
https://github.com/legacyworld/compose_to_k8s
と表示されるようになっている。
ファイル構成
compose_to_k8s
├─app
│ │ Dockerfile
│ │
│ └─src
│ server.py
│
└─web
│ Dockerfile
│ nginx.conf
│
└─html
index.html
nginx.confで以下のように記述して分けている
proxy_pass http://app:8080
でフォワードしている。
フォワード先のapp
はdocker-compose.ymlに記載している
http{
server{
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /api/v1/ {
proxy_request_buffering off;
proxy_pass http://app:8080;
}
}
}
docker-compose.ymlはこちら
version: '3.7'
services:
web:
image: legacyworld/compose_to_k8s_web
build:
context: ./web
dockerfile: Dockerfile
container_name: web
ports:
- 80:80
volumes:
- ./web/html:/usr/share/nginx/html
app:
image: legacyworld/compose_to_k8s_app
build:
context: ./app
dockerfile: Dockerfile
container_name: app
ports:
- 8080:8080
volumes:
- ./app/src:/src
docker-composeだけだとimage: legacyworld/compose_to_k8s_web
は必須ではないが、Kubernetesでイメージを引っ張ってくるのに必要となるので追加してある
この状態で
docker-compose up --build -d
docker-compose push
と実行すればlocalhostへのアクセスが出来て、Docker Hubにイメージが保存される。
Kubernetesのmanifestを作る
上記でnginxがやっていたフォワーディングをIngressにさせるようにする。
nginxは静的ファイル(htmlやjs,cssファイル)の置き場となる。
Ingress
このページを見ればほぼほぼ書いてある
https://kubernetes.github.io/ingress-nginx/deploy/
このファイルをkubectlでapplyするだけ
https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.45.0/deploy/static/provider/cloud/deploy.yaml
今回はこれをingress_deploy.yamlとしてローカルに保存している
一つ注意点として、このdeployは結構時間がかかる(1分強)
なので下記のようにコマンドを実行してdeployが終わったことを確かめてから次に進む
# kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=120s
次のメッセージが出るまで待つ
pod/ingress-nginx-controller-6f5454cbfb-mkqlk condition met
Ingressのmanifest
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
- path: /api/v1
pathType: Prefix
backend:
service:
name: flask-service
port:
number: 8080
- path
の部分からがnginx.confに書いていたフォワーディングの部分
KubernetesだとコンテナにServiceを作っていくので、フォワーディング先はservice名となっている
/
へのアクセスはnginx-service、/api/v1
へのアクセスはflask-serviceへフォワードされる
nginxのmanifest
serviceとdeployの2種類の記述が必要
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
run: web
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deploy
spec:
selector:
matchLabels:
run: web
replicas: 1
template:
metadata:
labels:
run: web
spec:
containers:
- name: front-end
image: legacyworld/compose_to_k8s_web:latest
env:
- name: PORT
value: "80"
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html/
name: html
volumes:
- name: html
hostPath:
path: /run/desktop/mnt/host/c/source/compose_to_k8s/web/html
serviceはNodePortを指定
run:web
で紐づけるコンテナを指定
deployは以下の通り
kubertenesでhostpathを使うのはよろしく無いですが、やり方をメモしておくために残してます
- spec->template->spec->containers->image
- ここから引っ張ってくる。docker-composeで指定したもの
- volumeMounts
- /usr/share/nginx/htmlを
name:html
のvolumesにマウントする
- /usr/share/nginx/htmlを
- hostPath
- Windowsなのでこんな感じで長くなってしまう
-
/run/desktop/mnt/host/c
= C:\
flaskのmanifest
apiVersion: v1
kind: Service
metadata:
name: flask-service
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
protocol: TCP
selector:
run: app
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deploy
spec:
selector:
matchLabels:
run: app
replicas: 1
template:
metadata:
labels:
run: app
spec:
containers:
- name: back-end
image: legacyworld/compose_to_k8s_app:latest
volumeMounts:
- mountPath: /src
name: src
volumes:
- name: src
hostPath:
path: /run/desktop/mnt/host/c/source/compose_to_k8s/app/src
実行
kubectl apply -f manifest.yaml
で全く同じ結果が得られます。