728x90
반응형
lion-app K8S
lion-app 을 쿠바네티스로 구동시켜보자.
테스트로 사용하기 위해 기존에 사용하던 도커파일을 sqlite db 와 연결하게 끔 새롭게 만든다.
App
# test 를 진행하기위해 allowed host 에 와일드 카드 추가
ALLOWED_HOSTS = [
"localhost",
"*",
"127.0.0.1",
# LOCAL_IP,
]
FROM python:3.11-alpine
LABEL likelion.web.backendauthor="Ivan kim <xormrdlsrks2@gmail.com>"
ARG APP_HOME=/app
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
WORKDIR ${APP_HOME}
COPY ./requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . ${APP_HOME}
COPY ./scripts/start /start
RUN sed -i 's/\\r$//g' /start
RUN chmod +x /start
CMD [ "/start" ]
이후 NCP 에 이미지 파일을 올리는데, MacOS 유저라 멀티 플랫폼 형식으로 올린다.
docker build -t likelion-cr-mh.kr.ncr.ntruss.com/lion-app:sqlite -f Dockerfile.test --platform linux/arm64 --platform linux/amd64 .
# docker build 옵션중 멀티 플랫폼을 위한 옵션
--platform linux/arm64 --platform linux/amd64
docker push likelion-cr-mh.kr.ncr.ntruss.com/lion-app:sqlite
도커 이미지를 만들고 sqlite 라는 태그를 달아 latest 와 구분지어 준다.
K8S
이후 k8s 부분으로 넘어와서 해당 이미지를 pull 받아 파드를 생성하는 파일을 만든다.
# lion-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: lion-app
labels:
app: lion-app
spec:
imagePullSecrets:
- name: regcred
containers:
- name: lion-app
image: likelion-cr-mh.kr.ncr.ntruss.com/lion-app:sqlite
ports:
- containerPort: 8000
k create -f lion-pod.yaml
파드의 로그를 살펴보면 환경변수가 지정되어 있지 않아 에러가 발생하는 것을 확인할 수 있다.
kimminhyeok@Ivans-Mac lion-app % k logs lion-app
160 static files copied to '/var/www/html/static'.
Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 289, in ensure_connection
self.connect()
File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 270, in connect
self.connection = self.get_new_connection(conn_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
...
File "/usr/local/lib/python3.11/site-packages/psycopg2/__init__.py", line 122, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
django.db.utils.OperationalError: could not translate host name "db" to address: Name does not resolve
이를 해결하기 위해 env 설정을 추가한다.
# lion-pod-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: lion-app
labels:
app: lion-app
spec:
imagePullSecrets:
- name: regcred
containers:
- name: lion-app
image: likelion-cr-mh.kr.ncr.ntruss.com/lion-app:sqlite
env:
- name: DJANGO_SETTINGS_MODULE
value: "lion_app.settings.test"
- name: DJANGO_SECRET_KEY
value: "DJANGO_SECRET_KEY"
ports:
- containerPort: 8000
# 파드 생성 후
k logs lion-app
kimminhyeok@Ivans-Mac lion-app % k logs lion-app
160 static files copied to '/var/www/html/static'.
Operations to perform:
Apply all migrations: admin, auth, contenttypes, forumapp, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying forumapp.0001_initial... OK
Applying forumapp.0002_alter_post_topic... OK
Applying forumapp.0003_topicgroupuser... OK
Applying forumapp.0004_post_image_url_alter_topicgroupuser_topic... OK
Applying forumapp.0005_alter_post_image_url... OK
Applying sessions.0001_initial... OK
[2023-09-06 01:22:03 +0000] [18] [INFO] Starting gunicorn 21.2.0
[2023-09-06 01:22:03 +0000] [18] [INFO] Listening at: <http://0.0.0.0:8000> (18)
[2023-09-06 01:22:03 +0000] [18] [INFO] Using worker: sync
[2023-09-06 01:22:03 +0000] [21] [INFO] Booting worker with pid: 21
[2023-09-06 01:22:03 +0000] [23] [INFO] Booting worker with pid: 23
[2023-09-06 01:22:03 +0000] [25] [INFO] Booting worker with pid: 25
[2023-09-06 01:22:03 +0000] [27] [INFO] Booting worker with pid: 27
[2023-09-06 01:22:03 +0000] [29] [INFO] Booting worker with pid: 29
[2023-09-06 01:22:03 +0000] [31] [INFO] Booting worker with pid: 31
[2023-09-06 01:22:03 +0000] [33] [INFO] Booting worker with pid: 33
[2023-09-06 01:22:03 +0000] [35] [INFO] Booting worker with pid: 35
[2023-09-06 01:22:03 +0000] [37] [INFO] Booting worker with pid: 37
마이그레이션까지 잘 동작하는 것을 확인 할 수 있다.
파드를 생성했으니 svc 와 ingress 를 연결하여 외부에서도 접근할 수 있게 한다.
# lion-svc-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: lion-svc-nodeport
spec:
type: NodePort
selector: # app 으로 레이블을 달아서 서비스가 해당 레이블 정보를 가진 파드를 관리할 수 있게 한다.
app: lion-app
ports:
# 기본적으로 그리고 편의상 `targetPort` 는 `port` 필드와 동일한 값으로 설정된다.
- port: 80
targetPort: 8000
k creaet -f lion-svc-nodeport.yaml
k get svc
# result
kimminhyeok@Ivans-Mac lion_app % k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
fortune-configmap NodePort 10.104.173.25 <none> 80:30383/TCP 18h
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d21h
lion-svc-nodeport NodePort 10.102.165.204 <none> 80:32353/TCP 5m51
파드의 레이블과 서비스의 셀렉터의 정보값을 일치시켜 서비스가 파드를 관리할 수 있도록 한다.
k label po lion-app app=lion-app
연결이 잘 되었는지 확인하기 위해
파드로 접속한뒤 curl 을 서비스 주소로 날려본다.
해당 이미지는 알파인 이기 때문에 쉘로 접속 후 curl 을 설치해준다.
k exec -it lion-app -- sh
apk add curl
# result
kimminhyeok@Ivans-Mac lion-app % k exec -it lion-app -- sh
/app # apk add curl
fetch <https://dl-cdn.alpinelinux.org/alpine/v3.18/main/x86_64/APKINDEX.tar.gz>
fetch <https://dl-cdn.alpinelinux.org/alpine/v3.18/community/x86_64/APKINDEX.tar.gz>
(1/6) Installing brotli-libs (1.0.9-r14)
(2/6) Installing libunistring (1.1-r1)
(3/6) Installing libidn2 (2.3.4-r1)
(4/6) Installing nghttp2-libs (1.55.1-r0)
(5/6) Installing libcurl (8.2.1-r0)
(6/6) Installing curl (8.2.1-r0)
Executing busybox-1.36.1-r2.trigger
OK: 19 MiB in 44 packages
# curl with out code info
curl -I <http://10.244.0.248/api/docs>
# api/docs/ 는 다른게 필요없이 바로 생성되고 넘어가니까 200 을 반환 할 것이다.
# result
HTTP/1.1 200 OK
Server: gunicorn
Date: Wed, 06 Sep 2023 02:15:23 GMT
Connection: close
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTION
...
...
...
Django 서버에서 /health/ 요청시 특정 값을 리턴하는 미들웨어 생성하고 replicaset 을 이용해서 파드 생성 및 조회 검증
# lion_app/common/middleware.py
from django.http import JsonResponse
class HealthcheckMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if request.path == "/health/":
return JsonResponse({"status": "ok"})
return self.get_response(request) # 그 다음 미들웨어로 보낸다...
docker build ...
docker push ...
# lion-rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: lion-app
labels:
app: lion-app
spec:
replicas: 1
selector:
matchLabels:
app: lion-app
template:
metadata:
labels:
app: lion-app
spec:
imagePullSecrets:
- name: regcred
containers:
- name: lion-app
image: likelion-cr-mh.kr.ncr.ntruss.com/lion-app:sqlite
imagePullPolicy: Always # 기존의 이미지를 쓰지않고 항상 가져오게 끔
env:
- name: DJANGO_SETTINGS_MODULE
value: lion_app.settings.test
- name: DJANGO_SECRET_KEY
value: "DJANGO_SECRET_KEY"
ports:
- containerPort: 8000
k create -f lion-rs.yaml
k exec -it ${pod_name} -- sh
apk add curl
curl <http://10.102.165.204/health/>
# result
/app # curl <http://10.102.165.204/health/>
{"status": "ok"}
k describe po ${pod_name}
# result
kimminhyeok@Ivans-Mac lion-app % k describe po lion-app-zblkm
Name: lion-app-zblkm
Namespace: default
Priority: 0
Service Account: default
Node: minikube/192.168.49.2
Start Time: Wed, 06 Sep 2023 14:31:15 +0900
Labels: app=lion-app
Annotations: <none>
Status: Running
IP: 10.244.1.18
IPs:
IP: 10.244.1.18
Controlled By: ReplicaSet/lion-app
Containers:
lion-app:
Container ID: docker://24cb9f53e060ec56556a946057bc787bb20cbe5c8f1e361697847afd1a3d12e6
Image: likelion-cr-mh.kr.ncr.ntruss.com/lion-app:sqlite
Image ID: docker-pullable://likelion-cr-mh.kr.ncr.ntruss.com/lion-app@sha256:5dd01b56334854fedcf611a9903c61f73422d4f95ece42836f9013cabb16f9c0
Port: 8000/TCP
Host Port: 0/TCP
State: Running
Started: Wed, 06 Sep 2023 14:31:16 +0900
Ready: True
Restart Count: 0
Liveness: http-get http://:8000/health/ delay=0s timeout=1s period=10s #success=1 #failure=3
Environment:
DJANGO_SETTINGS_MODULE: lion_app.settings.test
DJANGO_SECRET_KEY: eykjzm7ro(ewbug#3r%s64xeygef6q_k!cb+ns_vexsza^9n--
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hw88k (ro)
Conditions:
Type Status
Initialized True
728x90
반응형
'Dev. > Kubernetes & Helm' 카테고리의 다른 글
Kubernetes: nks 에서 서비스 띄우기 (4) | 2023.09.26 |
---|---|
Kubernetes: nks IAM 인증 (0) | 2023.09.25 |
Kubernetes: ConfigMap (0) | 2023.09.18 |
Kubernetes: svc - pod 구조 이해 (0) | 2023.09.17 |
Kubernetes: 서비스, 파드의 관리자 (0) | 2023.09.16 |
댓글