목표 : clusterip로 올린 service를 ingress를 사용해 외부에서 접근 가능하도록 할 예정
FLASK DOCKER BUILD 여기에서 만든 FLASK IMAGE를 사용해 ip/flask를 입력하면 flask web ui가 나오게 INGRESS 설정을 하려고 했는 데 자꾸 아래와 같은 에러가 발생함.
404 not found error
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
503 error
<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>nginx</center>
</body>
</html>
해결방안을 정리해봄
일단 ingress를 사용하기 위해서는 ingress-controller를 구성해야한다. 필수임
vm(bare metal)에 k8s를 클러스터를 구축한 경우에는 baremetal ingress yaml 파일을 다운받아 사용하면 된다.
1. nginx ingress controller 생성
[root@kw1 ~]# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.2/deploy/static/provider/baremetal/deploy.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
ingress-nginx namespace에 pod이 생성된다. 다음과 같이 출력되면 정상임
[root@kw1 ~]# kubectl get pods --namespace=ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-n9b9d 0/1 Completed 0 18m
ingress-nginx-admission-patch-5v4gd 0/1 Completed 1 18m
ingress-nginx-controller-5b6f946f99-6n9r5 1/1 Running 0 18m
아래와 같이 ingress-nginx-controller service가 nodePort로 올라와야함
[root@kw1 ~]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.111.2.246 <none> 80:32264/TCP,443:31477/TCP 2d1h
ingress-nginx-controller-admission ClusterIP 10.106.74.229 <none> 443/TCP 2d1h
2. flask docker image 빌드
FLASK DOCKER BUILD 이 코드를 조금 수정해서 이미지를 새로 빌드해서 사용할 예정
ksFlask.py의 내용을 아래와 같이 변경해줌
중요 "@app.route('/flask')이 route와 ingress의 path를 동일하게 설정해줘야한다."
from flask import Flask, render_template, url_for
app = Flask(__name__)
@app.route('/')
def image():
return render_template("index.html")
if __name__ == "__main__":
app.run(host="0.0.0.0")
이미지를 빌드한다. 태그를 별도 지정하지 않아 latest 태그가 붙었음 (맨 뒤에 . 하나 안 쓰면 에러남)
[root@kw1 flasktest]# docker build -t harbor.ks.io/privatetest/flasktest .
Successfully built 38b609e9c5bb
Successfully tagged harbor.ks.io/privatetest/flasktest:latest
3. pod, service, ingress 생성
하나하나 하기 귀찮으니까 한번에 다 생성하도록 한다.
kskube.yaml 파일을 하나 생성했다. pod, service, ingress 순으로 작성함
파일 하나에 pod을 여러 개 정의하거나, 아래와 같이 하나의 파일에 pod, service, ingress를 여러 개 정의할 때는
`---` 작대기 3개로 분리하면 된다. `---` 이걸 기준으로 파일 여러 개로 나눠서 각각 apply 해도 상관없음.
kind: Pod
apiVersion: v1
metadata:
name: ksimage-app
labels:
## 이 app이름이 service의 selector app과 동일해야함.
app: ksimage
spec:
containers:
- name: ksimage-app
image: harbor.ks.io/privatetest/flasktest:latest
imagePullPolicy: IfNotPresent
---
kind: Service
apiVersion: v1
metadata:
## 이 부분이 ingress의 service - name과 동일해야함
name: ksimage-service
spec:
selector:
## 이 부분이 pod의 labels의 app과 동일해야함
app: ksimage
ports:
## 이 포트가 ingress port - number와 동일해야함
- port: 5000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ksimage-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
## ip:port/flask로 접근하면 ksimage-service로 연결해준다는 의미
- path: /flask
pathType: Prefix
backend:
service:
name: ksimage-service
port:
## service의 port와 동일하게 설정
number: 5000
이제 apply해준다. 한번에 pod, service, ingress를 동작시킬 수 있다.
[root@kw1 ~]# kubectl apply -f kskube.yaml
pod/ksimage-app created
service/ksimage-service created
ingress.networking.k8s.io/ksimage-ingress created
kubectl get all 커맨드로 pod, service, deploy 정보를 한번에 볼 수 있다.
확인해보니 모두 정상적으로 구동중으로 확인된다.
[root@kw1 ~]# kubectl get all
NAME READY STATUS RESTARTS AGE
pod/ks-app 1/1 Running 0 4h26m
pod/ksflask-app 1/1 Running 0 124m
pod/ksimage-app 1/1 Running 0 21s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ks-service ClusterIP 10.102.236.171 172.30.1.144,172.30.1.145 5678/TCP 4h25m
service/ksflask-service ClusterIP 10.105.60.189 <none> 5000/TCP 164m
service/ksimage-service ClusterIP 10.99.222.55 <none> 5000/TCP 21s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h3m
ingress도 잘 올라왔는 지 확인해준다. ADDRESS가 빈 값일 수도 있는 데 조금만 기다리면 정상적으로 올라오니까
조금 기다리면 된다.
[root@kw1 ~]# kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress <none> * 172.30.1.145 80 5h58m
kf-ingress <none> * 172.30.1.145 80 6h1m
ks-ingress <none> * 172.30.1.145 80 16h
ksflask-ingress <none> * 172.30.1.145 80 165m
ksimage-ingress <none> * 172.30.1.145 80 80s
4. WEB 접속 테스트
잘 구동중이니 WEB에서 접속 테스트를 진행해본다.
접속하는 방법은 SERVERIP:INGRESSPORT/flask를 web 검색창에 입력하면 된다.
내가 테스트한 server의 hostname은 kw1.dd.io이고, INGRESSPORT는 아래에 보면 80:32264로 http로 접속할 경우 32264를 사용하면 된다.
최종적으로 접속 url은 kw1.dd.io:32264/flask
C:\Windows\System32\drivers\etc\hosts파일에 호스트 등록을 해놔서 hostname으로 접속 가능함
[root@kw1 ~]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.111.2.246 <none> 80:32264/TCP,443:31477/TCP 2d1h
ingress-nginx-controller-admission ClusterIP 10.106.74.229 <none> 443/TCP 2d1h
매우 이쁨
결론
적어놓긴 했지만 내가 못 찾을 예정이라 다시 정리하면
flask code의 @app.route('/flask') 이 부분과 ingress yaml의 path: /flask 이 부분을 동일하게 맞춰줘야 ingress 설정이 제대로 먹힌다.
@app.route('/')이고 path: /flask 이면 ingress 404나 503 error가 난다. 그러니 자알 맞춰주도록 하자.
'kubenetes' 카테고리의 다른 글
kubernetes 실행 중인 pod에 접속해 package 설치 (0) | 2022.03.30 |
---|---|
kubernetes pod에 파일 복사하고 다운로드 받기 (0) | 2022.03.30 |
docker image 제거 (0) | 2022.03.26 |
Dockerfile로 flask web docker image build 하는 방법 (0) | 2022.03.23 |
let's encrypt의 certbot을 사용해 harbor https 적용하기 (0) | 2022.03.22 |
댓글