
이스티오 프록시 컨테이너 인젝션 대상 네임스페이스 지정
kubectl label ns myistio istio-injection-
kubectl label ns myistio istio-injection=enabled
REST API 서버를 배포한다. FastAPI는 Python 기반의 웹 프레임워크로, API 개발을 빠르고 효율적으로 할 수 있도록 설계되었다. 성능이 뛰어나고, 타입 힌트를 적극적으로 활용하여 코드의 안정성과 가독성을 높일 수 있다. 버전을 v1, v2 로 나누어 정책에 따라 트래픽이 라우팅되게 구성하였다.
Kubernetes Gateway API는 Kubernetes 클러스터 내에서 L4 및 L7 트래픽 라우팅을 관리하기 위한 공식 프로젝트로, 기존 Ingress API의 한계를 보완하고자 설계되었다.
ingress 보다 아래 기능이 향상된다.
이곳 아키텍처에서는 로드 밸런서를 대신하고 API Gateway가 관리하기 어려운 동서 트래픽(서비스 대 서비스 트래픽)을 관리하기 위해 사용하였다.
Backend for Frontend(BFF) 는 특정 프론트엔드(웹, 모바일 앱 등)의 요구사항에 맞게 백엔드를 커스텀하여 제공하는 아키텍처 패턴이다.
일반적인 API Gateway는 모든 클라이언트(웹, 모바일, 데스크톱 등)에 대해 동일한 API를 제공하지만, BFF는 각 클라이언트별 맞춤형 API를 제공하는 것이 특징이다.
NGINX는 가볍고 빠른 웹 서버이자 리버스 프록시, 로드 밸런서, API 게이트웨이 역할을 수행하는 오픈소스 소프트웨어이다. 높은 동시 연결 처리 성능과 비동기 이벤트 기반 아키텍처를 통해 트래픽이 많은 환경에서도 안정적인 서비스를 제공한다.
리버스 프록시를 설정하여 BFF 서비스를 호출한다.
쿠버네티스 네트워크 연결 확인을 위한 BASH 콘솔 실행을 위한 이미지로 사용하였다. 웹서버의 URL을 지속적으로 호출하여 트래픽을 발생시킨다.
주요 파일 내용을 참조가능하도록 노출하였으며, 세부 단계는 생략하였다.
main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def base():
return {"message": "Hello, FastAPI!"}
@app.get("/health")
async def base():
return {"message": "Hello, FastAPI!"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "query": q}
vagrant@slave1:~/myistio$ cat requirements.txt
fastapi>=0.68.0,<0.69.0
pydantic>=1.8.0,<2.0.0
uvicorn>=0.15.0,<0.16.0
Docerfile.backend-dev
FROM python:3.11-alpine
LABEL maintainer="chojeonghak@gmail.com"
LABEL version="1.0"
LABEL description="backend"
WORKDIR /app
USER root
RUN apk update && \
apk add --no-cache curl vim bash
COPY ./requirements.txt /app
RUN pip install -r requirements.txt
COPY ./main.py /app
EXPOSE 5000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "5000"]
backend.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-v1
namespace: myistio
spec:
selector:
matchLabels:
app: backend
version: v1
replicas: 1
template:
metadata:
labels:
app: backend
version: v1
spec:
containers:
- name: backend
image: 저장소/backend:0.2
ports:
- containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
name: backend-v1
namespace: myistio
labels:
app: backend
version: v1
spec:
ports:
- port: 5000
protocol: TCP
selector:
app: backend
version: v1
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-v2
namespace: myistio
spec:
selector:
matchLabels:
app: backend
version: v2
replicas: 1
template:
metadata:
labels:
app: dbackend
version: v2
spec:
containers:
- name: backend
image: 저장소/backend:0.2
ports:
- containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
name: backend-v2
namespace: myistio
labels:
app: backend
version: v2
spec:
ports:
- port: 5000
protocol: TCP
selector:
app: backend
version: v2
type: ClusterIP
mygateway.yml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: mygateway
namespace: myistio
labels:
app: mygateway
spec:
gatewayClassName: istio
listeners:
- protocol: HTTP
port: 80
name: http
myroute.yml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: myroute
namespace: myistio
spec:
parentRefs:
- name: mygateway
rules:
- matches:
- path:
type: PathPrefix
value: "/"
backendRefs:
- name: backend-v1
port: 5000
weight: 50
- name: backend-v2
port: 5000
weight: 50
import requests
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/', methods=['GET'])
def web_home():
return jsonify({
"title": "Welcome to Web",
"content": "This is web-specific content."
})
@app.get("/health")
async def base():
return {"message": "Hello, FastAPI!"}
@app.route('/bff')
def call_bff():
print("CALLED backend for frontend!")
response = requests.get("http://mygateway-istio")
return f"BFF RESPONSE: {response.text}"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
FROM python:3.11-slim
LABEL maintainer="chojeonghak@gmail.com"
LABEL version="1.0"
LABEL description="BFF"
USER root
WORKDIR /app
RUN apt-get update && \
apt-get install -y curl vim && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN pip install flask
RUN pip install requests
COPY ./bff.py /app
EXPOSE 3000
CMD ["python3", "bff.py"]
bff.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: bff
spec:
selector:
matchLabels:
app: bff
replicas: 1
template:
metadata:
labels:
app: bff
spec:
containers:
- name: bff
image: 저장소/bff:0.2
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: bff
namespace: myistio
labels:
app: bff
spec:
ports:
- port: 3000
protocol: TCP
selector:
app: bff
bff.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: bff
namespace: myistio
spec:
selector:
matchLabels:
app: bff
replicas: 1
template:
metadata:
labels:
app: bff
spec:
containers:
- name: bff
image: 저장소/bff:0.1
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: bff
namespace: myistio
labels:
app: bff
spec:
ports:
- port: 3000
protocol: TCP
selector:
app: bff
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
selector:
matchLabels:
app: frontend
replicas: 1
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
- mountPath: /etc/nginx/nginx.conf
readOnly: true
name: config
subPath: nginx.conf
volumes:
- name: shared-data
persistentVolumeClaim:
claimName: mypvc
- name: config
configMap:
name: nginx
items:
- key: nginx.conf
path: nginx.conf
- name: logs
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: frontend
labels:
app: frontend
spec:
ports:
- port: 80
protocol: TCP
selector:
app: frontend
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx
data:
nginx.conf: |
user nginx;
worker_processes 3;
error_log /var/log/nginx/error.log;
events {
worker_connections 10240;
}
http {
access_log /var/log/nginx/access.log main;
server {
listen 80;
server_name _;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /bff {
proxy_pass http://bff.myistio.svc.cluster.local:3000/bff;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";
proxy_set_header Upgrade $http_upgrade;
proxy_cache_bypass $http_upgrade;
proxy_connect_timeout 10s;
proxy_send_timeout 15s;
proxy_read_timeout 15s;
}
}
}
while true; do curl "http://frontend.myistio.svc.cluster.local/bff";sleep 1; done