k8s

docker야 이사가자 k8s로! - 2

nginx, django-web

by HOON


1

Last updated on Feb. 12, 2025, 10:30 a.m.


random_image

안녕하세요, 저번 포스트에 이어서 docker to k8s 내용을 작성해보도록 하겠습니다.

오늘은 web과 nginx를 k8s 리소스로 변경하는 작업을 해볼게요.


1. Web

먼저, web을 변환해보겠습니다.
그 전에, 우선 제가 운영하고있던 Dockerfile, docker-compose 내 web 컨테이너를 한 번 볼게요.

#Dockerfile
# pull official base image
FROM python:3.8.0-slim-buster

# set work directory
WORKDIR /usr/src/app

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# dependencies 먼저 복사
COPY requirements.txt /usr/src/app/

# pip 업그레이드 및 의존성 설치
RUN pip install --upgrade pip && pip install -r requirements.txt

# 나머지 소스 코드 복사
COPY . /usr/src/app/

#docker-compose 내 web
  web:
    build: .
    image: django_web:v1.0
    command: gunicorn --workers 4 --timeout 600 --limit-request-line 8190 django_prj.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static_volume:<_static 경로>
      - media_volume:<_media 경로>
      - ./:/usr/tmp
    expose:
     - 8000
    env_file:
      - ./.env.temp.prod
    depends_on:
      - db

별다른 내용은 없고, command로 gunicorn의 워커를 4개로 설정하고 타임아웃을 600으로 지정했습니다.
또한 볼륨 마운트를 유지해서 media 파일과 static 파일을 저장해두었구요.
env_file을 가져와 참고하도록 지정해뒀습니다.

이 web은 쿠버네티스에서 이미지를 다운받을 수 있어야하므로 docker hub에 이미지를 업로드 할게요.
도커 로그인 → 이미지 태그지정 → 태그 확인 → push 순서로 진행하면 됩니다.

$ docker login 
$ docker tag django_web:local myhubid/django_web:v1.0

$ docker images
REPOSITORY                                      TAG                 IMAGE ID       CREATED         SIZE
myhubid/django_web                      v1.0                c2a92575c9f9   3 days ago      682MB

$ docker push myhubid/django_web:v1.0

이런식으로 진행해주면 이미지가 docker hub에 올라간 걸 확인 할 수 있습니다.
따라서 k8s는 docker hub에 존재하는 이미지를 가져와 컨테이너를 실행하게 되는거죠.

자 이제 k8s manifest 파일로 작성해볼까요??
우선 필요해보이는건 media,static 각각 pvc,pv로 연결이 필요해보입니다.
그리고 env_file도 있으므로 이 파일은 ConfigMap으로 작성 하겠습니다.
마지막으로 Deployments 파일이 필요하겠죠??

그럼 차례대로 작성해볼게요.

#static-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: static-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

#static-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: static-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /mnt/data/static

#media-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: media-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

#media-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: media-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /mnt/data/media

#django-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: django-config
data:
  DEBUG: "0"
  SECRET_KEY: "<Secret_Key>"
  DJANGO_ALLOWED_HOSTS: "localhost 127.0.0.1"
  SQL_ENGINE: "django.db.backends.postgresql"
  SQL_DATABASE: "<DB_Name>"
  SQL_USER: "<DB_User>"
  SQL_PASSWORD: "<DB_Password>"
  SQL_HOST: "postgres-service"
  SQL_PORT: "5432"


$ k get pvc,pv
NAME                                 STATUS   VOLUME        CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
persistentvolumeclaim/media-pvc      Bound    media-pv      1Gi        RWO                           <unset>                 34m
persistentvolumeclaim/postgres-pvc   Bound    postgres-pv   1Gi        RWO                           <unset>                 20h
persistentvolumeclaim/static-pvc     Bound    static-pv     1Gi        RWO                           <unset>                 34m

NAME                           CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                  STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
persistentvolume/media-pv      1Gi        RWO            Retain           Bound    default/media-pvc                     <unset>                          34m
persistentvolume/postgres-pv   1Gi        RWO            Retain           Bound    default/postgres-pvc                  <unset>                          20h
persistentvolume/static-pv     1Gi        RWO            Retain           Bound    default/static-pvc                    <unset>                          34m

$ k get cm
NAME               DATA   AGE
django-config      9      53m
kube-root-ca.crt   1      21h

pvc,pv가 정상적으로 Bound 된 걸 확인 할 수 있습니다. configmap도 정상이네요!
이제 마저 deployments를 작성해줄게요

apiVersion: apps/v1
kind: Deployment
metadata:
  name: django-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: django
  template:
    metadata:
      labels:
        app: django
    spec:
      containers:
        - name: django
          image: myhubid/django_web:v1.0   # Docker Hub에 올린 이미지
          command: ["gunicorn", "--workers", "4", "--timeout", "600", "--limit-request-line", "8190", "do_it_django_prj.wsgi:application", "--bind", "0.0.0.0:8000"]
          ports:
            - containerPort: 8000
          envFrom:
            - configMapRef:
                name: django-config   # 위에서 작성한 ConfigMap
          volumeMounts:
            - name: static-volume
              mountPath: /usr/src/app/_static
            - name: media-volume
              mountPath: /usr/src/app/_media
      volumes:
        - name: static-volume
          persistentVolumeClaim:
            claimName: static-pvc
        - name: media-volume
          persistentVolumeClaim:
            claimName: media-pvc

우선, docker hub에 업로드한 web 이미지를 지정해주고, command는 동일하게 사용합니다.
config도 생성한 configmap을 참조하도록 정하고, 이미 생성한 pvc,pv를 지정해주면 끝입니다.

$ k get pods
NAME                               READY   STATUS    RESTARTS       AGE
django-deploy-5c7767dc68-wps45     1/1     Running   0              29m
postgres-deploy-7bb6d74d79-vwsvt   1/1     Running   1 (166m ago)   15h

정상 실행중입니다. 그럼 실제로 서비스가 작동중인지 확인해볼게요.
일단 nginx는 아직 생성되기 전이니, port-forward를 통해 포트를 열어주고, curl로 접근 해보면??

$ kubectl port-forward pod/django-deploy-5c7767dc68-wps45 8000:8000
Forwarding from 127.0.0.1:8000 -> 8000
Forwarding from [::1]:8000 -> 8000
Handling connection for 8000

$ $ curl http://localhost:8000
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta name="robots" content="NONE,NOARCHIVE">
  <title>DisallowedHost
          at /</title>
  <style type="text/css">
    html * { padding:0; margin:0; }
    body * { padding:10px 20px; }
    body * * { padding:0; }
    body { font:small sans-serif; background-color:#fff; color:#000; }
  . . .

정상 응답 하는걸 볼 수 있습니다!

이제 Nginx로 넘어가볼게요.


2. Nginx

우선 동일하게 각각 service,config map, deployment 를 작성하겠습니다.

#nginx-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-conf
data:
  default.conf: |
    resolver 10.96.0.10 valid=30s;
    upstream django_upstream {
        zone django_upstream 64k;
        # Django Service로 프록시 (Service 이름: django-service)
        # server django-service:8000 resolve;
         server django-service.default.svc.cluster.local:8000 resolve;
    }

    server {
        listen 80;
        server_name localhost;

        # Django 앱으로 프록시
        location / {
            proxy_pass http://django_upstream;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_redirect off;
        }

        # 정적 파일
        location /static/ {
            alias /usr/src/app/_static/;
        }

        # 미디어 파일
        location /media/ {
            alias /usr/src/app/_media/;
        }
    }

 #nginx-service.yaml
 apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080  # 원하는 포트 번호


#nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      dnsPolicy: "ClusterFirst"
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80
          volumeMounts:
            # 1) Nginx 설정파일 마운트
            - name: nginx-conf-volume
              mountPath: /etc/nginx/conf.d
            # 2) static/media PVC 마운트 (ReadOnly)
            - name: static-volume
              mountPath: /usr/src/app/_static
              readOnly: true
            - name: media-volume
              mountPath: /usr/src/app/_media
              readOnly: true
      volumes:
        # 1) ConfigMap
        - name: nginx-conf-volume
          configMap:
            name: nginx-conf
            items:
              - key: default.conf
                path: default.conf
        # 2) PVC (static, media)
        - name: static-volume
          persistentVolumeClaim:
            claimName: static-pvc   
        - name: media-volume
          persistentVolumeClaim:
            claimName: media-pvc   

우선 configmap에서의 특징을 살펴보자면
resolver 10.96.0.10 으로 작성했는데 이는 Kubernetes 클러스터의 DNS 서비스(CoreDNS) 주소입니다.
따라서 Nginx가 특정 도메인명을 사용하는 경우, 해당 도메인을 30초마다 CoreDNS에 조회하여 IP를 최신 상태로 유지 할 수 있는거죠.
또한, 아래 코드블럭 처럼 나뉘어있는데 설명은 주석에 첨부하겠습니다.
저는 FQDN을 사용했습니다.

server django-service:8000 resolve; #django-service라는 이름을 Kubernetes 내에서 DNS 조회하여 IP를 동적으로 변경 가능하다.
server django-service.default.svc.cluster.local:8000; #FQDN(완전한 도메인 네임)을 사용한 설정이다.

💡Tip. 여기서 FQDN이란 네트워크 상에서 특정 호스트(서버)를 유일하게 식별할 수 있도록 전체 도메인 경로를 포함한 이름입니다.

자, 이제 manifest 파일도 생성했으니, 적용하고 접속해볼까요??

$ k get pods
NAME                               READY   STATUS    RESTARTS   AGE
django-deploy-7c6d8769bd-r82bq     1/1     Running   0          32m
nginx-deploy-8567c4975d-gxd88      1/1     Running   0          46m
postgres-deploy-7bb6d74d79-4jp4k   1/1     Running   0          27m

nginx도 이상없이 실행중입니다.
아, 그리고 저희는 지금 Master,Worker로 구성되어있는 가상머신이 각각 NAT + Host Only 로 구성되어있었죠??

그럼 제 노트북 로컬호스트에서 웹브라우저를 통해 접근하려면 어떻게 해야할까요?
http:127.0.0.1:30080 으로 접근하면 됩니다. 그 전에, 먼저 NAT 네트워크에 대해 포트포워딩 부터 해줄게요.
저번과 마찬가지로 30080:30080으로 설정합니다.

그럼 30080으로 요청을 받았을 경우, 내부 30080을 LISTEN 하고있는 주소로 넘기겠죠?
자 그렇게 접속을 해보면??


3. Nginx Error

이상합니다.. 분명 pod도 정상적으로 실행중이고, 아까 web을 따로 curl 테스트 했을 때는 정상적으로 리턴도 됐어요. 그럼 어디가 문제일까요??
일단, 사용자가 접속을 요청하게될경우, 쿠버네티스는 어떤 경로로 트래픽을 전달하는지 정리해볼게요.

1️⃣ 클라이언트 요청 → 127.0.0.1:30080으로 웹 요청
2️⃣ NodePort 서비스 → 요청이 NodePort(30080)를 통해 nginx-service로 전달
3️⃣ kube-proxy → nginx-service에 연결된 nginx-pod으로 트래픽 전달
4️⃣ CoreDNS 조회 → nginx-service.default.svc.cluster.local 의 IP(ClusterIP)확인
5️⃣ Weave 네트워크 → Pod 간 Overlay 네트워크를 통해 Nginx Pod (10.32.0.12)로 전달
6️⃣ Nginx 컨테이너 → Django 서비스(django-service.default.svc.cluster.local:8000)로 프록시 요청
7️⃣ Django 컨테이너 → 최종적으로 응답을 생성하여 Nginx로 전달
8️⃣ 응답 반환 → Nginx가 응답을 받아 클라이언트(웹 브라우저)로 전송

그럼 2번부터 확인 해보겠습니다.

$ k get svc
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
django-service     ClusterIP   10.109.135.57   <none>        8000/TCP       9h
kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP        31h
nginx-service      NodePort    10.97.83.183    <none>        80:30080/TCP   9h
postgres-service   ClusterIP   10.99.216.250   <none>        5432/TCP       30h

우선 서비스는 정상 매핑이 되어있고, 외부 포트 노출을 위한 NodePort도 30080으로 설정되어있습니다.
30080으로 들어온 포트는 80번으로 매핑해주겠죠?

3번 kube-proxy 확인 해보겠습니다.

$ kubectl logs -n kube-system -l k8s-app=kube-proxy
I0210 07:04:35.800121       1 server.go:867] "Golang settings" GOGC="" GOMAXPROCS="" GOTRACEBACK=""
I0210 07:04:35.811691       1 config.go:188] "Starting service config controller"
I0210 07:04:35.816233       1 shared_informer.go:311] Waiting for caches to sync for service config
I0210 07:04:35.816343       1 config.go:97] "Starting endpoint slice config controller"
I0210 07:04:35.816426       1 shared_informer.go:311] Waiting for caches to sync for endpoint slice config
I0210 07:04:35.822598       1 config.go:315] "Starting node config controller"
I0210 07:04:35.824362       1 shared_informer.go:311] Waiting for caches to sync for node config
I0210 07:04:35.917281       1 shared_informer.go:318] Caches are synced for endpoint slice config
I0210 07:04:35.917332       1 shared_informer.go:318] Caches are synced for service config
I0210 07:04:35.925976       1 shared_informer.go:318] Caches are synced for node config

여기도 딱히 문제는 발견하지 못했어요.

4번 CoreDNS 확인해볼게요.

$ k get pods -A
NAMESPACE     NAME                                 READY   STATUS    RESTARTS       AGE
default       django-deploy-5c7767dc68-wrxcx       1/1     Running   2 (59m ago)    4h46m
default       nginx-deploy-8547754fbd-bqmzj        1/1     Running   0              23m
default       postgres-deploy-7bb6d74d79-nbrpj     1/1     Running   2 (59m ago)    4h46m
kube-system   coredns-76f75df574-h6pf7             1/1     Running   7 (59m ago)    27h
kube-system   coredns-76f75df574-qlbxf             1/1     Running   7 (59m ago)    27h
kube-system   etcd-k8s-master                      1/1     Running   23 (59m ago)   27h
kube-system   kube-apiserver-k8s-master            1/1     Running   7 (59m ago)    27h
kube-system   kube-controller-manager-k8s-master   1/1     Running   7 (59m ago)    27h
kube-system   kube-proxy-8rwrt                     1/1     Running   6 (59m ago)    27h
kube-system   kube-proxy-fwc7w                     1/1     Running   7 (59m ago)    27h
kube-system   kube-scheduler-k8s-master            1/1     Running   7 (59m ago)    27h
kube-system   weave-net-4wh94                      2/2     Running   0              39s
kube-system   weave-net-cpmtp                      2/2     Running   0              84s

CoreDNS가 정상작동인걸 확인했습니다. 그럼 DNS 해석도 제대로 되나 볼까요??

$ kubectl run -it --rm --image=nicolaka/netshoot dns-debug --restart=Never -- nslookup kubernetes.default.svc.cluster.local
;; communications error to 10.96.0.10#53: connection refused
;; communications error to 10.96.0.10#53: connection refused
;; communications error to 10.96.0.10#53: connection refused
;; no servers could be reached

pod "dns-debug" deleted
pod default/dns-debug terminated (Error)

어 뭔가 이상합니다. connection refused로 dns 해석이 제대로 안되고 에러가 발생하고있어요.
요청들어온 내역을 CoreDNS에서 해석해주지 못하기때문에 에러가 발생하고 있는 것 같습니다.

CoreDNS를 조금 더 파볼게요. 53번 포트를 열고있어야해요.

$ k debug -it coredns-75bc6f8ddb-2dd7t -n kube-system --image=busybox --target=coredns -- sh
Targeting container "coredns". If you don't see processes from this container it may be because the container runtime doesn't support this feature.
Defaulting debug container name to debugger-9f87x.
If you don't see a command prompt, try pressing enter.
/ # netstat -tulpn | grep :53
tcp        0      0 :::53                   :::*                    LISTEN      -
tcp        0      0 :::53                   :::*                    LISTEN      -
udp        0      0 :::53                   :::*                                -
udp        0      0 :::53                   :::*                                -
/ #

53번 포트는 제대로 열고 있어요.

다음 스텝인 Weave Net까지 확인해볼게요.

$ k logs -n kube-system weave-net-76px6
Defaulted container "weave" out of: weave, weave-npc, weave-init (init)
INFO: 2025/02/10 08:08:36.592107 Command line options: map[conn-limit:200 datapath:datapath db-prefix:/weavedb/weave-net docker-api: expect-npc:true http-addr:127.0.0.1:6784 ipalloc-init:consensus=1 ipalloc-range:10.32.0.0/12 metrics-addr:0.0.0.0:6782 name:d6:e3:96:b4:09:45 nickname:k8s-node1 no-dns:true no-masq-local:true port:6783]
. . . 

INFO: 2025/02/10 08:03:54.589438 ->[192.168.219.100:43541|0a:4f:4d:44:48:46(k8s-master)]: connection added (new peer)
INFO: 2025/02/10 08:03:54.593073 ->[192.168.219.100:43541|0a:4f:4d:44:48:46(k8s-master)]: connection shutting down due to error: read tcp 192.168.219.110:6783->192.168.219.100:43541: read: connection reset by peer
INFO: 2025/02/10 08:03:54.593577 ->[192.168.219.100:43541|0a:4f:4d:44:48:46(k8s-master)]: connection deleted
INFO: 2025/02/10 08:03:54.593657 Removed unreachable peer 0a:4f:4d:44:48:46(k8s-master)

여기도 로그에 에러가 있습니다. 클라이언트의 요청이 어째서인지 클러스터 네트워크로 접근이 안되는 상황이에요.

우선 제가 k8s 환경을 여러번 변경하고 네트워크도 그때마다 변경이 됐기때문에 각 노드의 weave 데이터를 제거하고, 재시작 할게요.

sudo rm -rf /weavedb
sudo rm -rf /var/lib/weave

kubectl -n kube-system rollout restart daemonset weave-net

$ k logs -n kube-system weave-net-76px6
Defaulted container "weave" out of: weave, weave-npc, weave-init (init)
INFO: 2025/02/10 08:08:36.592107 Command line options: map[conn-limit:200 datapath:datapath db-prefix:/weavedb/weave-net docker-api: expect-npc:true http-addr:127.0.0.1:6784 ipalloc-init:consensus=1 ipalloc-range:10.32.0.0/12 metrics-addr:0.0.0.0:6782 name:d6:e3:96:b4:09:45 nickname:k8s-node1 no-dns:true no-masq-local:true port:6783]
INFO: 2025/02/10 08:08:36.592185 weave  git-34de0b10a69c
INFO: 2025/02/10 08:08:37.083366 Re-exposing 10.32.0.1/12 on bridge "weave"
INFO: 2025/02/10 08:08:37.110626 Bridge type is bridged_fastdp
INFO: 2025/02/10 08:08:37.110685 Communication between peers is unencrypted.
INFO: 2025/02/10 08:08:37.177928 Our name is d6:e3:96:b4:09:45(k8s-node1)
INFO: 2025/02/10 08:08:37.177966 Launch detected - using supplied peer list: [192.168.219.100]
    . . .
INFO: 2025/02/10 08:08:37.276532 added entry 10.36.0.0/14 to weaver-no-masq-local of 0
INFO: 2025/02/10 08:08:37.277333 adding entry 10.40.0.0/14 to weaver-no-masq-local of 0
INFO: 2025/02/10 08:08:37.277430 added entry 10.40.0.0/14 to weaver-no-masq-local of 0
INFO: 2025/02/10 08:08:37.342968 overlay_switch ->[0a:4f:4d:44:48:46(k8s-master)] using sleeve
INFO: 2025/02/10 08:08:37.343101 ->[192.168.219.100:6783|0a:4f:4d:44:48:46(k8s-master)]: connection fully established
INFO: 2025/02/10 08:08:37.343145 overlay_switch ->[0a:4f:4d:44:48:46(k8s-master)] using fastdp
INFO: 2025/02/10 08:08:37.347249 sleeve ->[192.168.219.100:6783|0a:4f:4d:44:48:46(k8s-master)]: Effective MTU verified at 1438
INFO: 2025/02/10 08:08:37.616443 [kube-peers] Added myself to peer list &{[{0a:4f:4d:44:48:46 k8s-master} {d6:e3:96:b4:09:45 k8s-node1}]}
DEBU: 2025/02/10 08:08:37.627367 [kube-peers] Nodes that have disappeared: map[]
10.32.0.1
DEBU: 2025/02/10 08:08:37.731802 registering for updates for node delete events
INFO: 2025/02/10 08:08:42.309482 Error checking version: Get "https://checkpoint-api.weave.works/v1/check/weave-net?arch=amd64&flag_docker-version=none&flag_kernel-version=5.4.0-144-generic&flag_network=fastdp&os=linux&signature=cdd0XpIAZi2xBbPoF6RPg3t3n8gtSLLQOwRl77ljOKY%3D&version=git-34de0b10a69c": dial tcp: lookup checkpoint-api.weave.works on 10.96.0.10:53: read udp 10.0.2.15:37942->10.96.0.10:53: read: connection refused
k8s-master@k8s-master:~/nginx-yaml$

아까같은 connection error는 없는거보니, weave의 설정도 꼬였던 것 같습니다.

그럼 다시 CoreDNS에서 테스트 해볼게요.

$ kubectl run -it --rm --image=nicolaka/netshoot dns-debug --restart=Never -- nslookup kubernetes.default.svc.cluster.local
;; communications error to 10.96.0.10#53: connection refused
;; communications error to 10.96.0.10#53: connection refused
;; communications error to 10.96.0.10#53: connection refused
;; no servers could be reached

pod "dns-debug" deleted
pod default/dns-debug terminated (Error)

CoreDNS에서는 여전히 에러가 발생합니다. 이부분만 해결되면 될 것 같아요.
제가 DNS를 사용하는 부분이 어디에 있을까 곰곰히 생각해보겠습니다.
근데 한가지, 걸리는게 있어요. 아까 nginx 설치 전, web만 리소스를 생성하고 테스트 했을 때
curl http:localhost:8000 의 리턴값이 DisallowedHost 즉, 호스트 에러였거든요

호스트가 정의되어있지 않았기 때문입니다.

제가 호스트를 정의한 부분은 django-config.yaml의 DJANGO_ALLOWED_HOSTS: 입니다.
혹시 모르니 이 부분에 저희 FQDN인 django-service.default.svc.cluster.local 를 등록할게요.

그리고 검색을 좀 해보니 nginx 설정에서 server django-service.default.svc.cluster.local:8000 resolve; 로 되어 있는게 문제가 되는것같아요.
resolve 옵션을 사용하려면 server 뒤에 DNS 이름이 아니라 IP 주소가 필요하다고 합니다.
따라서 resolve는 제거해줄게요.

그럼 nginx-configmap.yaml 파일이 변동 되겠네요.

#기존
    upstream django_upstream {
        zone django_upstream 64k;
        # Django Service로 프록시 (Service 이름: django-service)
        # server django-service:8000 resolve;
         server django-service.default.svc.cluster.local:8000 resolve;
    }

#변경
    upstream django_upstream {
        zone django_upstream 64k;
        # Django Service로 프록시 (Service 이름: django-service)
        # server django-service:8000 resolve;
         server django-service.default.svc.cluster.local:8000;
    }


$ kubectl rollout restart deployment nginx-deployment

다시 접속 해볼까요??

http://127.0.0.1:30080

오, 드디어 접속이 됩니다!! (우선은 구축이 목적이기때문에 https는 적용하지 않았습니다.)
근데 어디서 많이 봤죠?? CSS가 적용이 안되어있어요.

$ k exec -it django-deploy-7c6d8769bd-r82bq -- python manage.py collectstatic --noinput

202 static files copied to '/usr/src/app/_static'.

CSS 적용하고 보면?

성공적으로 접속이 가능합니다.
이렇게 nginx,postgresql,django-web 까지 구현이 끝났습니다.
생각보다 nginx에서 시간을 많이잡아먹었는데, 이 또한 경험이 됐기에 다행입니다.

그럼 다음 포스트는 prometheus,grafana,jenkins까지 적용을 목표로 하겠습니다.

감사합니다!

×
k8s linux


Leave a Comment: