티스토리 뷰

Server

Docker & Kubernetes 개념 총 정리 7

마시멜로co. 2025. 1. 16. 17:21

1. 도커를 활용한 Flask 실행

Flask는 django와 마찬가지로 파이썬을 이용해 쉽게 웹사이트를 만들 수 있도록 도와주는 웹 프레임워크입니다.

 

flask 설치하기

user@myserver01:~$ pyenv activate py3_13_1
(py3_13_1) user@myserver01:~$ pip install flask
Collecting flask
  Downloading flask-3.1.0-py3-none-any.whl.metadata (2.7 kB)
..생략

 

설치 확인

(py3_13_1) user@myserver01:~$ python
Python 3.13.1 (main, Jan 17 2025, 00:30:07) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import flask
>>> from importlib.metadata import version
>>> version('flask')
'3.1.0'
>>> quit()
(py3_13_1) user@myserver01:~$ pyenv deactivate

 

8001 포트, 81 포트를 포트포워딩에 추가 후 적용합니다.

Flask를 이용해 간단한 서비스를 코드를 만듭니다.

user@myserver01:/home/work$ sudo mkdir ch25
user@myserver01:/home/work$ cd ch25
user@myserver01:/home/work/ch25$ sudo mkdir myapp
user@myserver01:/home/work/ch25$ ls
myapp
user@myserver01:/home/work/ch25$ cd myapp/
user@myserver01:/home/work/ch25/myapp$ sudo vi main.py

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'hello world!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8001)

 

app = Flask(__name__) : 웹 애플리케이션 객체를 app이라고 지정합니다.

@app.route('/') : 루트 경로에 접근합니다.

파이썬 스크립트가 실행되면 app.run을 통해 웹 애플리케이션을 실행하도록 정합니다. 이때 host=0.0.0.0은 모든 IP주소로 부터 요청을 수락하도록 하는 옵션이고 port=8001은 포트 8001를  사용하겠다는 의미입니다.

 

파이썬을 활용해 작성한 main.py를 실행합니다.

user@myserver01:/home/work/ch25/myapp$  pyenv activate py3_13_1
(py3_13_1) user@myserver01:/home/work/ch25/myapp$ ls
main.py
(py3_13_1) user@myserver01:/home/work/ch25/myapp$ python main.py
 * Serving Flask app 'main'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:8001
 * Running on http://10.0.2.4:8001
Press CTRL+C to quit

파이썬 가상환경 종료 

(py3_13_1) user@myserver01:/home/work/ch25/myapp$ pyenv deactivate

 

Nginx와 Flask를 컨테이너 형태로 연동한 후 실행하겠습니다. Flask와 Nginx 이미지를 각각 빌드한 후 컨테이너 형태로 실행합니다.

 

컨테이너를 실행하기 위해 필요한 Flask 이미지를 빌드하겠습니다.

 

앞서 생성한 Flask 폴더를 새폴더에 복사합니다.

user@myserver01:/home/work$ sudo mkdir ch26
user@myserver01:/home/work$ sudo cp -r ch25 ch26
user@myserver01:/home/work$ cd ch26
user@myserver01:/home/work/ch26$ ls
ch25
user@myserver01:/home/work/ch26$ mv ch25 myFlask02
user@myserver01:/home/work/ch26$ sudo mv ch25 myFlask02
user@myserver01:/home/work/ch26$ ls
myFlask02

 

requirements.txt 를 생성하여 도커 이미지 생성시 필요한 라이브러리를 입력합니다.

user@myserver01:/home/work/ch26$ cd myFlask02/
user@myserver01:/home/work/ch26/myFlask02$ ls
myapp
user@myserver01:/home/work/ch26/myFlask02$ sudo vi requirements.txt
flask==3.1.0
gunicorn==23.0.0

 

이미지 빌드에 필요한 Dockerfile생성

user@myserver01:/home/work/ch26/myFlask02$ sudo vi Dockerfile
FROM python:3.13.1

WORKDIR /usr/src/app

COPY . .

RUN python -m pip install --upgrade pip
RUN pip install -r requirements.txt

WORKDIR ./myapp

CMD gunicorn --bind 0.0.0.0:8001 main:app

EXPOSE 8001

 

Flask 컨테이너는 8001포트를 사용합니다.

 

도커이미지를 빌드합니다.

user@myserver01:/home/work/ch26/myFlask02$ sudo docker image build . -t myflask02
[+] Building 17.1s (12/12) FINISHED                                                                                                                                                                                           docker:default
 => [internal] load build definition from Dockerfile   
 ..생략..
user@myserver01:/home/work/ch26/myFlask02$ sudo docker image ls
REPOSITORY                TAG       IMAGE ID       CREATED          SIZE
myflask02                 latest    8ec39e43dcc9   14 seconds ago   1.03GB

 

Nginx 이미지를 빌드하겠습니다.

user@myserver01:/home/work/ch26/myFlask02$ cd ../
user@myserver01:/home/work/ch26$ ls
myFlask02
user@myserver01:/home/work/ch26$ sudo mkdir myNginx02f
user@myserver01:/home/work/ch26$ ls
myFlask02  myNginx02f
user@myserver01:/home/work/ch26$ cd myNginx02f/
user@myserver01:/home/work/ch26/myNginx02f$ sudo vi default.conf

upstream myweb{
        server flasktest:8001;
}

server{
        listen 81;
        server_name localhost;

        location /{
                proxy_pass http://myweb;
        }
}

 

nginx 포트를 81로 요청을 받습니다.

 

Dockerfile을 생성합니다.

user@myserver01:/home/work/ch26/myNginx02f$ sudo vi Dockerfile
FROM nginx:1.25.3
RUN rm /etc/nginx/conf.d/default.conf
COPY default.conf /etc/nginx/conf.d/
CMD ["nginx", "-g", "daemon off;"]

 

Nginx 이미지를 빌드합니다.

user@myserver01:/home/work/ch26/myNginx02f$ ls
default.conf  Dockerfile
user@myserver01:/home/work/ch26/myNginx02f$ sudo docker image build . -t mynginx02f
[+] Building 2.1s (9/9) FINISHED                                                                                                                                                                                              docker:default
 => [internal] load build definition from Dockerfile              
 ..생략....
user@myserver01:/home/work/ch26/myNginx02f$ sudo docker image ls
REPOSITORY                TAG       IMAGE ID       CREATED          SIZE
mynginx02f                latest    2a82e63870fa   39 seconds ago   187MB
myflask02                 latest    8ec39e43dcc9   9 minutes ago    1.03GB

 

도커를 활용해 Nginx와 Flask를 컨테이너 형태로 연동 후 실행합니다.

 

도커네트워크를 생성합니다.

user@myserver01:/home/work/ch26/myNginx02f$ sudo docker network create mynetwork02f
cf8d873e26f0255b7e4c3bcd67fe833f944c06d2983a7b667bd8bc8a9cfbfb1b
user@myserver01:/home/work/ch26/myNginx02f$ sudo docker network ls
NETWORK ID     NAME           DRIVER    SCOPE
4229e13d57bf   bridge         bridge    local
e25e86151666   host           host      local
cf8d873e26f0   mynetwork02f   bridge    local

 

Flask 컨테이너를 실행합니다.

user@myserver01:/home/work/ch26/myNginx02f$ sudo docker container run -d --name flasktest --network mynetwork02f myflask02
bb3d3ba0d9c6ceb16ee29ed70c4572346d4dee3d7f3ae2f216fc806a5bf90f08
user@myserver01:/home/work/ch26/myNginx02f$ sudo docker container ls
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS      NAMES
bb3d3ba0d9c6   myflask02   "/bin/sh -c 'gunicor…"   13 seconds ago   Up 12 seconds   8001/tcp   flasktest

 

Nginx 컨테이너를 실행합니다.

user@myserver01:/home/work/ch26/myNginx02f$ sudo docker container run -d --name nginxtest --network mynetwork02f -p 81:81 mynginx02f
2ebe5f62bcedb91a304cff7de85d62f2ecb5470b98b7f87063aef305ef06176d

 

도커 호스트의 81번 포트를 컨테이너의 81번 포트와 연결시키도록 설정하였습니다.

Nginx와 Flask 컨테이너를 종료합니다.

user@myserver01:/home/work/ch26/myNginx02f$ sudo docker container ls
CONTAINER ID   IMAGE        COMMAND                  CREATED         STATUS         PORTS                                       NAMES
2ebe5f62bced   mynginx02f   "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   80/tcp, 0.0.0.0:81->81/tcp, :::81->81/tcp   nginxtest
bb3d3ba0d9c6   myflask02    "/bin/sh -c 'gunicor…"   6 minutes ago   Up 6 minutes   8001/tcp                                    flasktest
user@myserver01:/home/work/ch26/myNginx02f$ sudo docker container stop 2ebe5f62bced bb3d3ba0d9c6
2ebe5f62bced
bb3d3ba0d9c6

 

도커 컴포즈를 활용해 Nginx와 Flask를 컨테이너 형태로 배포하겠습니다.

user@myserver01:/home/work$ sudo cp -r ch26 ch27
user@myserver01:/home/work$ cd ch27
user@myserver01:/home/work/ch27$ ls
myFlask02  myNginx02f
user@myserver01:/home/work/ch27$ sudo mv myFlask02 myFlask03
user@myserver01:/home/work/ch27$ sudo mv myNginx02f myNginx03f
user@myserver01:/home/work/ch27$ ls
myFlask03  myNginx03f
user@myserver01:/home/work/ch27$ sudo vi docker-compose.yml

services:
  flasktest:
    build: ./myFlask03
    networks:
      - composenet03
    restart: always


  nginxtest:
    build: ./myNginx03f
    networks:
      - composenet03
    ports:
      - "81:81"
    depends_on:
      - flasktest
    restart: always


networks:
  composenet03:

 

이미지를 빌드하고 실행합니다.

user@myserver01:/home/work/ch27$ ls
docker-compose.yml  myFlask03  myNginx03f
user@myserver01:/home/work/ch27$ sudo docker compose up -d --build
[+] Building 3.5s (23/23) FINISHED                                                                                                                                                                                            docker:default
 => [flasktest internal] load build definition from Dockerfile                                                                                                                                                                          0.1s
 => => transferring dockerfile: 241B       
 ..생략..
user@myserver01:/home/work/ch27$ sudo docker container ls
CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS         PORTS                                       NAMES
10b81d321bf4   ch27-nginxtest   "/docker-entrypoint.…"   10 seconds ago   Up 8 seconds   80/tcp, 0.0.0.0:81->81/tcp, :::81->81/tcp   ch27-nginxtest-1
8922e69daa6c   ch27-flasktest   "/bin/sh -c 'gunicor…"   10 seconds ago   Up 9 seconds   8001/tcp                                    ch27-flasktest-1

 

접속 확인 후 도커 컴포즈 종료

user@myserver01:/home/work/ch27$ sudo docker container logs 10b81d321bf4
..생략..
10.0.2.2 - - [17/Jan/2025:01:45:38 +0000] "GET / HTTP/1.1" 200 12 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0" "-"
10.0.2.2 - - [17/Jan/2025:01:45:38 +0000] "GET /favicon.ico HTTP/1.1" 404 207 "http://127.0.0.1:81/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0" "-"
user@myserver01:/home/work/ch27$ sudo docker compose down
[+] Running 3/3
 ✔ Container ch27-nginxtest-1  Removed                                                                                                                                                                                                  0.4s
 ✔ Container ch27-flasktest-1  Removed                                                                                                                                                                                                 10.3s
 ✔ Network ch27_composenet03   Removed

 

 

2.  인그레이스를 활용한 django 실행 

인그레스를 활용하여 django를 실행합니다.

root@myserver01:/home/work# mkdir ch23
root@myserver01:/home/work# cd ch23
root@myserver01:/home/work/ch23# cd ../ch22
root@myserver01:/home/work/ch22# cp -r ./ ../ch23
root@myserver01:/home/work/ch22# cd ../ch23
root@myserver01:/home/work/ch23# ls
myDjango04  myNginx04
root@myserver01:/home/work/ch23# mv myNginx04 myNginx04d
root@myserver01:/home/work/ch23# cd myDjango04/myapp/myapp/
root@myserver01:/home/work/ch23/myDjango04/myapp/myapp# vi settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'PASSWORD': '설정한 DB 비밀번호',
        'HOST':'10.0.2.4',
        'PORT': 5432
    }
}

 

django 이미지를 빌드합니다.

root@myserver01:/home/work/ch23/myDjango04/myapp/myapp# cd ../..
root@myserver01:/home/work/ch23/myDjango04# docker image build . -t mydjango_ch23:0.2
[+] Building 25.8s (11/11) FINISHED                                                                                                                                                                                           docker:default
revent unintended behavior related to OS signals (line 12)
...생략
root@myserver01:/home/work/ch23/myDjango04# docker image ls
REPOSITORY      TAG       IMAGE ID       CREATED          SIZE
mydjango_ch23   0.2       1cc90cf1437f   8 seconds ago    1.07GB

 

태그를 0.2로 지정하였습니다. mydjango_ch23 은 하단 docker hub 홈페이지의 repository와 동일하게 작성해야합니다.

https://hub.docker.com/

 

Docker Hub Container Image Library | App Containerization

Increase your reach and adoption on Docker Hub With a Docker Verified Publisher subscription, you'll increase trust, boost discoverability, get exclusive data insights, and much more.

hub.docker.com

 

접속하여 로그인 후 Repository를 생성합니다.

Create a Repository 버튼 클릭 -> repogistory name 작성 후 Create 버튼 클릭합니다. 

 

 

https://login.docker.com/activate

 

https://login.docker.com/activate

 

login.docker.com

 

root@myserver01:/home/work/ch23/myDjango04# docker login

USING WEB-BASED LOGIN
To sign in with credentials on the command line, use 'docker login -u <username>'

Your one-time device confirmation code is: MQDM-XPKT
Press ENTER to open your browser or submit your device code here: https://login.docker.com/activate

Waiting for authentication in the browser…
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credential-stores

Login Succeeded

 

 

 

태그 생성

root@myserver01:/home/work/ch23/myDjango04# docker tag mydjango_ch23:0.2  userId/mydjango_ch23:0.2
root@myserver01:/home/work/ch23/myDjango04# docker push userId/mydjango_ch23:0.2
The push refers to repository [docker.io/userId/mydjango_ch23]
f8300c471b39: Pushed
f8300c471b39: Pushing [==========>                                        ]  9.623MB/44.43MB
694998686090: Pushed
0f799ea47bf2: Pushed
c473e7987385: Pushed
75771920c930: Mounted from library/python
c40d71ec7d1d: Mounted from library/python
ac94309486a0: Mounted from library/python
ebad64620a59: Mounted from library/python
f379f6005525: Mounted from library/python
0e5c23e041ee: Mounted from library/python
0.2: digest: sha256:e56148628cae35e2ea342f4b03e13aee9e9682ebeb47bceefb43e6719fc47df3 size: 2840

 

docker hub에서 tags가 표시되어있으면 성공적으로 태그가 생성된 것입니다.

 

nginx 이미지를 생성합니다. 

root@myserver01:/home/work/ch23# cd myNginx04d/
root@myserver01:/home/work/ch23/myNginx04d# ls
default.conf  Dockerfile
root@myserver01:/home/work/ch23/myNginx04d# vi default.conf

server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://127.0.0.1:8000;
    }
}

 

nginx  도커 이미지를 빌드합니다.

root@myserver01:/home/work/ch23/myNginx04d# docker image build . -t mynginxd_ch23:0.3
[+] Building 2.2s (9/9) FINISHED                                                                                                                                                                                              docker:default
 => [internal] load build definition from Dockerfile                                                                                                                                                                                    0.1s
 => => transferring dockerfile: 164B

 

허브 홈페이지에서 repository를 추가 생성합니다.

태그 생성 후 도커 허브에 업로드

root@myserver01:/home/work/ch23/myNginx04d# docker tag  mynginxd_ch23:0.3 userId/mynginxd_ch23:0.3
root@myserver01:/home/work/ch23/myNginx04d# docker push userId/mynginxd_ch23:0.3
The push refers to repository [docker.io/userId/mynginxd_ch23]
2eef1cf9954e: Pushed
3ea02ffa3c72: Pushed
c4106aac4c13: Mounted from library/nginx
c57ad67cd261: Mounted from library/nginx
cbafde024849: Mounted from library/nginx
b88f5270d74a: Mounted from library/nginx
ff3d21334998: Mounted from library/nginx
4c6624954f4b: Mounted from library/nginx
ceb365432eec: Mounted from library/nginx
0.3: digest: sha256:a44fcb1e15864b2f0df72256c982444d3b57c5d7fa48ca6c093660fa4b1d05dc size: 2192

 

django와 nginx를 실행할 deployment를 생성합니다.

root@myserver01:/home/work/ch23/myNginx04d# cd ../
root@myserver01:/home/work/ch23# vi django-deploy.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-django
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: web-deploy
  template:
    metadata:
      labels:
        app.kubernetes.io/name: web-deploy
    spec:
      containers:
      - name: nginx-d
        image: 도커허브아이디/mynginxd_ch23:0.3
        ports:
        - containerPort: 80

      - name: django-web
        image: 도커허브아이디/mydjango_ch23:0.2
        ports:
        - containerPort: 8000

 

디플로이먼트 실행

root@myserver01:/home/work/ch23# exit
logout
user@myserver01:~$ cd /home/work/ch23/
user@myserver01:/home/work/ch23$ kubectl apply -f django-deploy.yml
deployment.apps/deploy-django created
user@myserver01:/home/work/ch23$ kubectl get pods
NAME                             READY   STATUS        RESTARTS   AGE
deploy-django-6cc964b995-8zxdw   2/2     Running       0          14m
deploy-django-6cc964b995-c7jnv   2/2     Running       0          14m
deploy-django-6cc964b995-cgnmz   2/2     Running       0          6m10s

 

ClusterIP타입으로 서비스 실행

user@myserver01:/home/work/ch23$ sudo vi django-service.yml
apiVersion: v1
kind: Service
metadata:
  name: django-service
spec:
  selector:
    app.kubernetes.io/name: web-deploy
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

 

서비스 실행

user@myserver01:/home/work/ch23$ kubectl apply -f django-service.yml
service/django-service created
user@myserver01:/home/work/ch23$ kubectl get pod,svc
NAME                                 READY   STATUS        RESTARTS   AGE
pod/deploy-django-6cc964b995-8zxdw   2/2     Running       0          19m
pod/deploy-django-6cc964b995-c7jnv   2/2     Running       0          19m
pod/deploy-django-6cc964b995-cgnmz   2/2     Running       0          10m
pod/deploy-django-6cc964b995-dhzh5   0/2     Terminating   0          19m

NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/django-service   ClusterIP   10.102.213.139   <none>        80/TCP    7s
service/kubernetes       ClusterIP   10.96.0.1        <none>        443/TCP   27h

 

인그레스 실행

user@myserver01:/home/work/ch23$ sudo vi django-ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: django-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /test01(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: django-service
            port:
              number: 80

 

 nginx.ingress.kubernetes.io/rewrite-target: /$2  Nginx 인그레스 컨트롤러 옵션을 입력합니다. 

인그레스 클래스 명은 nginx 이며 http 하위 경로입력을 위해 특수기호를 추가합니다.  /test01(/|$)(.*)

인그레스와 연동할 서비스 이름은 django-service입니다.

 

인그레스를 실행합니다.

user@myserver01:/home/work/ch23$ kubectl apply -f django-ingress.yml
ingress.networking.k8s.io/django-ingress created
user@myserver01:/home/work/ch23$ kubectl get pod,svc,ingress
NAME                                 READY   STATUS        RESTARTS   AGE
pod/deploy-django-6cc964b995-8zxdw   2/2     Running       0          30m
pod/deploy-django-6cc964b995-c7jnv   2/2     Running       0          30m
pod/deploy-django-6cc964b995-cgnmz   2/2     Running       0          22m
pod/deploy-django-6cc964b995-dhzh5   0/2     Terminating   0          30m

NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/django-service   ClusterIP   10.102.213.139   <none>        80/TCP    11m
service/kubernetes       ClusterIP   10.96.0.1        <none>        443/TCP   28h

NAME                                       CLASS   HOSTS   ADDRESS    PORTS   AGE
ingress.networking.k8s.io/django-ingress   nginx   *       10.0.2.4   80      89s

 

웹브라우저에서 인그레스 경로로 접근 테스트 해봅니다.

 

 

파드 내부로 접속하여 작성한 소스를 확인합니다.

user@myserver01:/home/work/ch23$ kubectl exec -it pod/deploy-django-6cc964b995-8zxdw -- /bin/bash
Defaulted container "nginx-d" out of: nginx-d, django-web
root@deploy-django-6cc964b995-8zxdw:/# cd /etc/nginx/conf.d/
root@deploy-django-6cc964b995-8zxdw:/etc/nginx/conf.d# ls
default.conf
root@deploy-django-6cc964b995-8zxdw:/etc/nginx/conf.d# cat default.conf
server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://127.0.0.1:8000;
    }
}

root@deploy-django-6cc964b995-8zxdw:/etc/nginx/conf.d# exit
exit

 

-c 옵션으로 django  컨테이너에  접속합니다.

user@myserver01:/home/work/ch23$ kubectl exec -it pod/deploy-django-6cc964b995-8zxdw -c django-web -- /bin/bash
root@deploy-django-6cc964b995-8zxdw:/usr/src/app/myapp# ls
db.sqlite3  manage.py  myapp
root@deploy-django-6cc964b995-8zxdw:/usr/src/app/myapp# python manage.py inspectdb
# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
#   * Rearrange models' order
#   * Make sure each model has one field with primary_key=True
#   * Make sure each ForeignKey and OneToOneField has `on_delete` set to the desired behavior
#   * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table
# Feel free to rename the models, but don't rename db_table values or field names.
from django.db import models
root@deploy-django-6cc964b995-8zxdw:/usr/src/app/myapp# exit
exit

 

inspectdb 명령어로 db 설정이 올바르게 되어있는지 확인합니다.

 

쿠버네티스 오브젝트를 모두 종료합니다.

user@myserver01:/home/work/ch23$ kubectl delete -f django-ingress.yml
ingress.networking.k8s.io "django-ingress" deleted
user@myserver01:/home/work/ch23$ kubectl delete -f django-service.yml
service "django-service" deleted
user@myserver01:/home/work/ch23$ kubectl delete -f django-deploy.yml
deployment.apps "deploy-django" deleted

 

 

 

3. 인그레스를 활용한 Flask 실행

인그레스를 활용하여 Flask서비스를 배포하겠습니다.

user@myserver01:/home/work$ sudo rm -rf ch24
user@myserver01:/home/work$ sudo cp -r ch23 myFlask01
user@myserver01:/home/work$ cd myFlask01/
user@myserver01:/home/work/myFlask01$ ls
django-deploy.yml  django-ingress.yml  django-service.yml  myDjango04  myNginx04d
user@myserver01:/home/work/myFlask01$ sudo cp -r myNginx04d myNginx04f
user@myserver01:/home/work/myFlask01$ ls
django-deploy.yml  django-ingress.yml  django-service.yml  myDjango04  myNginx04d  myNginx04f

 

파일을 생성합니다.

user@myserver01:/home/work$ sudo mkdir docker
user@myserver01:/home/work/docker$ cp -r ../ch23 .
user@myserver01:/home/work/docker$ ls -al
total 28
drwxr-xr-x  4 root root 4096 Jan 17 04:37 .
drwxr-xr-x 32 root root 4096 Jan 17 04:39 ..
-rw-r--r--  1 root root  492 Jan 17 04:37 django-deploy.yml
-rw-r--r--  1 root root  380 Jan 17 04:37 django-ingress.yml
-rw-r--r--  1 root root  197 Jan 17 04:37 django-service.yml
drwxr-xr-x  3 root root 4096 Jan 17 04:37 myDjango04
drwxr-xr-x  2 root root 4096 Jan 17 04:37 myNginx04d
user@myserver01:/home/work/ch26$ sudo cp -r . ../docker/
user@myserver01:/home/work/ch26$ cd ../docker/
user@myserver01:/home/work/docker$ ls -al
total 36
drwxr-xr-x  6 root root 4096 Jan 17 04:45 .
drwxr-xr-x 32 root root 4096 Jan 17 04:39 ..
-rw-r--r--  1 root root  492 Jan 17 04:37 django-deploy.yml
-rw-r--r--  1 root root  380 Jan 17 04:37 django-ingress.yml
-rw-r--r--  1 root root  197 Jan 17 04:37 django-service.yml
drwxr-xr-x  3 root root 4096 Jan 17 04:37 myDjango04
drwxr-xr-x  3 root root 4096 Jan 17 04:45 myFlask02
drwxr-xr-x  2 root root 4096 Jan 17 04:45 myNginx02f
drwxr-xr-x  2 root root 4096 Jan 17 04:37 myNginx04d
user@myserver01:/home/work/docker$ cd myFlask02/
user@myserver01:/home/work/docker/myFlask02$ ls
Dockerfile  myapp  requirements.txt

user@myserver01:/home/work/docker/myFlask02$ cd myapp/
user@myserver01:/home/work/docker/myFlask02/myapp$ cat main.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'hello world!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8001)
    

user@myserver01:/home/work/docker/myFlask02$ cat Dockerfile
FROM python:3.13.1

WORKDIR /usr/src/app

COPY . .

RUN python -m pip install --upgrade pip
RUN pip install -r requirements.txt

WORKDIR ./myapp

CMD gunicorn --bind 0.0.0.0:8001 main:app

EXPOSE 8001

user@myserver01:/home/work/docker/myFlask02$ cat requirements.txt
flask==3.1.0
gunicorn==23.0.0

 

이미지를 빌드합니다.

user@myserver01:/home/work/docker/myFlask02$ sudo docker image build . -t myflask_ch27:0.2

 

https://hub.docker.com/

 

Docker Hub Container Image Library | App Containerization

Increase your reach and adoption on Docker Hub With a Docker Verified Publisher subscription, you'll increase trust, boost discoverability, get exclusive data insights, and much more.

hub.docker.com

 

도커 허브에 접속하여 해당 리포지토리를 생성합니다.

 

도커 이미지를 업로드하기 위해 tag명령어를 활용해 업로드용 이미지를 생성하고 해당 이미지를 도커에 업로드하겠습니다.

user@myserver01:/home/work/docker/myFlask02$  sudo docker tag myflask_ch27:0.2 사용자아이디/myflask_ch27:0.2
user@myserver01:/home/work/docker/myFlask02$  sudo docker push  사용자아이디/myflask_ch27:0.2
The push refers to repository [docker.io/사용자아이디/myflask_ch27]
5f70bf18a086: Mounted from 사용자아이디/mydjango_ch23
5ae1d2eadde5: Pushed
ca72b5558e5f: Pushed
e67919dbb077: Pushed
...생략
0.2: digest: sha256:8dbbb64e9d1a230b6b70d27a0473c8628221c1ff47796eb5ff337c7e67ca8198 size: 2838

 

정상적으로 태그가 도커허브에 업로드 된 것을 확인 할 수 있습니다.

 

 

 

nginx 이미지를 빌드합니다.

user@myserver01:/home/work/docker$ cd myNginx02f
user@myserver01:/home/work/docker/myNginx02f$ ls
default.conf  Dockerfile
user@myserver01:/home/work/docker/myNginx02f$ cat Dockerfile
FROM nginx:1.25.3
RUN rm /etc/nginx/conf.d/default.conf
COPY default.conf /etc/nginx/conf.d/
CMD ["nginx", "-g", "daemon off;"]

user@myserver01:/home/work/docker/myNginx02f$ sudo vi default.conf
server{
        listen 80;
        server_name localhost;

        location /{
                proxy_pass http://127.0.0.1:8001;
        }
}

 

도커 이미지를 빌드합니다.

user@myserver01:/home/work/docker/myNginx02f$ sudo docker image build . -t mynginxf_ch27:0.3
[+] Building 2.2s (9/9) FINISHED                                                                                                                                                                                              docker:default
 => [internal] load build definition from Dockerfile                                                                                                                                                                                    0.0s
 => => transferring dockerfile: 168B

 

도커 허브에 리포지토리 생성

 

도커 이미지를 업로드하기 위해 tag명령어를 활용해 업로드용 이미지를 생성하고 해당 이미지를 도커에 업로드하겠습니다.

user@myserver01:/home/work/docker/myNginx02f$ sudo docker tag mynginxf_ch27:0.3 사용자아이디/mynginxf_ch27:0.3
user@myserver01:/home/work/docker/myNginx02f$ sudo docker push 사용자아이디/mynginxf_ch27:0.3
The push refers to repository [docker.io/사용자아이디/mynginxf_ch27]
9a85572dfa09: Pushed
..생략..
0.3: digest: sha256:2a21d4cfc8c2e13c813a057e6869e14c5ba15b31feeb86e55aa84fac072dc4e3 size: 2192

 

디플로이먼트 생성 후 실행

user@myserver01:/home/work/docker$ sudo vi flask-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-flask
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: flask-web-deploy
  template:
    metadata:
      labels:
        app.kubernetes.io/name: flask-web-deploy
    spec:
      containers:
      - name: nginx-f
        image: 도커허브사용자ID/mynginxf_ch27:0.3
        ports:
        - containerPort: 80

      - name: flask-web
        image: 도커허브사용자ID/myflask_ch27:0.2
        ports:
        - containerPort: 8001
        
user@myserver01:/home/work/docker$ kubectl apply -f flask-deploy.yml
deployment.apps/deploy-flask created

 

 

파일 정리 후 서비스 생성 및 실행

user@myserver01:/home/work/docker$ sudo rm -r djan*
user@myserver01:/home/work/docker$ ls
flask-deploy.yml  myDjango04  myFlask02  myNginx02f  myNginx04d
user@myserver01:/home/work/docker$ sudo rm -rf myDjango04
user@myserver01:/home/work/docker$ sudo rm -rf myNginx04d
user@myserver01:/home/work/docker$ ls
flask-deploy.yml  myFlask02  myNginx02f
user@myserver01:/home/work/docker$ sudo vi flask-service.yml
apiVersion: v1
kind: Service
metadata:
  name: flask-service
spec:
  selector:
    app.kubernetes.io/name: flask-web-deploy
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    
user@myserver01:/home/work/docker$ kubectl apply -f flask-service.yml
service/flask-service created

 

인그레스 파일 생성 후 실행

user@myserver01:/home/work/docker$ sudo vi flask-ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: flask-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /test02(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: flask-service
            port:
              number: 80

user@myserver01:/home/work/docker$ kubectl apply -f flask-ingress.yml
ingress.networking.k8s.io/flask-ingress created
user@myserver01:/home/work/docker$ kubectl get ingress
NAME            CLASS   HOSTS   ADDRESS    PORTS   AGE
flask-ingress   nginx   *       10.0.2.4   80      22s

 

모두 중지하기

user@myserver01:/home/work/docker$ kubectl delete -f flask-ingress.yml
ingress.networking.k8s.io "flask-ingress" deleted
user@myserver01:/home/work/docker$ kubectl delete -f flask-service.yml
service "flask-service" deleted
user@myserver01:/home/work/docker$ kubectl delete -f flask-deploy.yml
deployment.apps "deploy-flask" deleted
user@myserver01:/home/work/docker$ kubectl get pod,svc,ingress
NAME                                READY   STATUS        RESTARTS   AGE
pod/deploy-flask-6dc47b7f5d-fk28b   2/2     Terminating   0          16m
pod/deploy-flask-6dc47b7f5d-hvpmn   2/2     Terminating   0          16m
pod/deploy-flask-6dc47b7f5d-jd5zc   2/2     Terminating   0          16m

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   2d1h

 

 

4. 인그레스를 활용한 django와 flask 실행

인그레스를 활용하여 django와 flask를 동시에 실행해보겠습니다.

 

기존 폴더 복사 및 정리

user@myserver01:/home/work$ sudo cp -r ch23 ch27
user@myserver01:/home/work/docker$ sudo cp -r . ../ch27
user@myserver01:/home/work/docker$ cd ../ch27
user@myserver01:/home/work/ch27$ ls
django-deploy.yml  django-ingress.yml  django-service.yml  flask-deploy.yml  flask-ingress.yml  flask-service.yml  myDjango04  myFlask02  myNginx02f  myNginx04d
user@myserver01:/home/work/ch27$ sudo rm -rf my*
user@myserver01:/home/work/ch27$ ls
django-deploy.yml  django-ingress.yml  django-service.yml  flask-deploy.yml  flask-ingress.yml  flask-service.yml
user@myserver01:/home/work/ch27$ sudo rm -rf django-ingress.yml
user@myserver01:/home/work/ch27$ sudo rm -rf flask-ingress.yml
user@myserver01:/home/work/ch27$ ls
django-deploy.yml  django-service.yml  flask-deploy.yml  flask-service.yml
user@myserver01:/home/work/ch27$ sudo vi django-flask-ingress.yml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: django-flask-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /test01(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: django-service
            port:
              number: 80

      - path: /test02(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: flask-service
            port:
              number: 80

 

디플로이먼트 및 서비스 실행

user@myserver01:/home/work/ch27$ kubectl apply -f django-deploy.yml
deployment.apps/deploy-django created
user@myserver01:/home/work/ch27$ kubectl apply -f flask-deploy.yml
deployment.apps/deploy-flask created

user@myserver01:/home/work/ch27$ kubectl apply -f django-service.yml
service/django-service created
user@myserver01:/home/work/ch27$ kubectl apply -f flask-service.yml
service/flask-service created

 

마지막으로 인그레스 실행

user@myserver01:/home/work/ch27$ kubectl apply -f django-flask-ingress.yml
ingress.networking.k8s.io/django-flask-ingress created
user@myserver01:/home/work/ch27$ kubectl get all
NAME                                 READY   STATUS    RESTARTS   AGE
pod/deploy-django-6cc964b995-4dvlc   2/2     Running   0          83s
pod/deploy-django-6cc964b995-tp2jj   2/2     Running   0          83s
pod/deploy-django-6cc964b995-xl7bc   2/2     Running   0          83s
pod/deploy-flask-6dc47b7f5d-ctfv9    2/2     Running   0          77s
pod/deploy-flask-6dc47b7f5d-h7hlx    2/2     Running   0          77s
pod/deploy-flask-6dc47b7f5d-rlst2    2/2     Running   0          77s

NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/django-service   ClusterIP   10.109.205.15    <none>        80/TCP    69s
service/flask-service    ClusterIP   10.110.144.191   <none>        80/TCP    65s
service/kubernetes       ClusterIP   10.96.0.1        <none>        443/TCP   2m41s

NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deploy-django   3/3     3            3           83s
deployment.apps/deploy-flask    3/3     3            3           77s

NAME                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/deploy-django-6cc964b995   3         3         3       83s
replicaset.apps/deploy-flask-6dc47b7f5d    3         3         3       77s

 

django와 flask 웹서비스 경로로 접근하면 작동하는 것을 볼 수 있습니다.

 

모두 중지 

user@myserver01:/home/work/ch27$ kubectl delete -f django-flask-ingress.yml
ingress.networking.k8s.io "django-flask-ingress" deleted
user@myserver01:/home/work/ch27$ kubectl delete -f django-service.yml
service "django-service" deleted
user@myserver01:/home/work/ch27$ kubectl delete -f flask-service.yml
service "flask-service" deleted
user@myserver01:/home/work/ch27$ kubectl delete -f django-deploy.yml
deployment.apps "deploy-django" deleted
user@myserver01:/home/work/ch27$ kubectl delete -f flask-deploy.yml
deployment.apps "deploy-flask" deleted

 

다음글에서는 CI/CD에 대해 작성하겠습니다.

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크