티스토리 뷰

728x90
반응형

이번 포스팅에서는 Kubernetes Pod를 생성하고 애플리케이션을 배포하는 과정에 대해 살펴보겠습니다.

Kubernetes에서 Pod는 Scaling, Replication의 단위로 Kubernetes에서 관리되는 가장 작은 단위입니다.

Strongly coupled 한 관계로 Life-cycle이 일치하는 경우는 복수개의 컨테이너로 구성되며 일반적으로 동일한 애플리케이션 단위라고 생각할 수 있습니다.

지난 Kubernetes 가이드는 아래를 참고하세요.

 

[Container Management] Kubernetes Master Node 설치

[Container Management] Kubernetes Dashboard Install & Setting

[Container Management] Kubernetes Woker Node Install & Setting

Kubernetes Base 이미지 생성

본 포스팅에서 테스트할 순서는 다음과 같습니다.
1. Docker Hub를 통해 apache 이미지를 pull합니다. My Docker Hub에 수정한 apache 이미지를 push합니다.
2. Deployment를 위한 yaml파일 작성합니다.
3. CLI 또는 Dashboard에서 Pod를 배포합니다.
4. 마지막으로 배포된 Pod에 접속하여 상태를 확인합니다.

1. Base Image 구성

a) Dockerfile 작성
이미지는 간단히 Apache 서버 index.html 파일을 ADD하여 Deploy하는 방식으로 작성하겠습니다.

[Dockerfile]
FROM httpd:2.4
MAINTAINER nrson <nara0617@gmail.com>
COPY ./public-html/ /usr/local/apache2/htdocs/

b) docker build

Dockerfile을 기반으로 이미지를 생성합니다.

[root@guruson docker]# docker build -t my-apache2 .
Sending build context to Docker daemon 134.7 kB
Step 1/3 : FROM httpd:2.4
Trying to pull repository docker.io/library/httpd ... 
2.4: Pulling from docker.io/library/httpd
f5d23c7fed46: Pull complete 
b083c5fd185b: Pull complete 
bf5100a89e78: Pull complete 
98f47fcaa52f: Pull complete 
622a9dd8cfed: Pull complete 
Digest: sha256:dc4c86bc90593c6e4c5b06872a7a363fc7d4eec99c5d6bfac881f7371adcb2c4
Status: Downloaded newer image for docker.io/httpd:2.4
 ---> ee39f68eb241
Step 2/3 : MAINTAINER nrson <nara0617@gmail.com>
 ---> Running in 7a58968f2cd2
 ---> d9fd730e1bda
Removing intermediate container 7a58968f2cd2
Step 3/3 : COPY ./public-html/ /usr/local/apache2/htdocs/
 ---> b38072c5ab70
Removing intermediate container 16386db468d9
Successfully built b38072c5ab70
[root@guruson docker]#

c) docker 기동 테스트

생성된 이미지를 기동하여 테스트합니다.

[root@guruson docker]# docker run -dit --name my-running-app -p 8080:80 my-apache2
c5839229142a3a7bc24b7cef29fef224317821b94adc485b32c978e11add4359
[root@guruson docker]# docker images | grep apache
my-apache2                                               latest              b38072c5ab70        37 seconds ago      154 MB
[root@guruson docker]# docker ps -a | grep apache
c5839229142a        my-apache2                                                                                                 "httpd-foreground"       40 seconds ago      Up 39 seconds       0.0.0.0:8080->80/tcp   my-running-app
[root@guruson docker]#

아래와 같이 접속 테스트를 수행해 봅니다.

d) docker 이미지 업로드

해당 이미지를 Dockerhub에 업로드합니다.

[root@guruson docker]# docker tag my-apache2:latest docker.io/nara0617/my-apache2:latest
[root@guruson docker]# docker push docker.io/nara0617/my-apache2:latest
The push refers to a repository [docker.io/nara0617/my-apache2]
5b84d0f3e4ad: Pushed 
635721fc6973: Mounted from library/httpd 
bea448567d6c: Mounted from library/httpd 
bfaa5f9c3b51: Mounted from library/httpd 
9d542ac296cc: Mounted from library/httpd 
d8a33133e477: Mounted from library/httpd 
latest: digest: sha256:f3b7575cb17091534b8916f49aa373c4e1f469338facc231e50c4b3a0aca0a9a size: 1574
[root@guruson docker]#

Dockerhub에 접속하여 Docker Image를 확인합니다.

위와 같이 nara0617/my-apache2 이미지가 업로드된 것을 확인할 수 있습니다.

2. Deployment 생성

다음으로 deployment를 생성하기 위한 yaml 파일을 작성해 보도록 하겠습니다.

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: apache-docker-deployment
  labels:
    app: apache-docker
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apache-docker
  template:
    metadata:
      labels:
        app: apache-docker
    spec:
      containers:
      - name: apache-docker
        image: nara0617/my-apache2:latest
        ports:
        - containerPort: 8080
        imagePullPolicy: Always
        resources:
          requests:
            memory: "256Mi"
            cpu: "200m"
          limits:
            memory: "1Gi"
            cpu: "500m"

위 yaml 파일에 정의된 주요 정보는

  항목 설명
replicas replicas: 1 apache-docker pod 복제 개수를 지정합니다.
images image: nara0617/my-apache2:latest apache-doceer pod를 생성할 이미지를 지정합니다.
containerPort containerPort: 8080 Container를 기동한 포트를 지정합니다.
requests requests: (memory, cpu) Container를 기동할 때 사용할 memory와 cpu를 지정합니다.
limits limits: (memory, cpu) Container에서 사용할 수 있는 MAX memory와 cpu를 지정합니다.

3. Pod 생성

위와 같이 생성한 Deployment yaml 파일을 반영하여 pod를 생성해 보겠습니다.

[root@guruson docker]# kubectl apply --record -f ./apache-deployment.yaml 
deployment.apps/apache-docker-deployment created
[root@guruson docker]# kubectl get pods
NAME                                        READY     STATUS              RESTARTS   AGE
apache-docker-deployment-54876bbd86-rdkmn   0/1       ContainerCreating   0          6s
[root@guruson docker]# kubectl get pods
NAME                                        READY     STATUS    RESTARTS   AGE
apache-docker-deployment-54876bbd86-rdkmn   1/1       Running   0          70s
[root@guruson docker]# 

생성된 pod는 위와 같이 기동되었으며, 서비스 할 준비가 완료되었습니다.

이를 앞서 설치한 Kubernetes Dashboard에서 확인해 보도록 하겠습니다.

위와 같이 Workload Status에 Pods 정보가 표출되며

위와 같이 왼쪽 메뉴 탭 Pods를 통해 Pods의 기동 상태 정보를 대시보드에서 확인할 수 있습니다.

작성한 Deployment.yaml을 CLI에서 적용하는 방법과 동일하게 대시보드에서도 생성할 수 있습니다.

오른쪽 상단의 + 버튼을 클릭하면 Create from input 탭이 생기는데 여기에 deployment.yaml 파일을 입력하고 업데이트를 누르시면됩니다.

아래와 같이 Pod가 생성되고 있으며,

생성이 완료되면, 

위와 같이 2개의 pod가 생성된 것을 확인할 수 있습니다.

4. Pod 확인

먼저 Pods의 이름을 선택하여 상세 설정 정보를 확인합니다.

위와 같이 pod info 및 다양한 상태 정보를 표출합니다.

먼저 해당 Pods의 로그 정보를 확인해 보도록 하겠습니다.

오른쪽 상단의 햄버거 표시(View logs)를 클릭하면

위와 같이 서버에 대한 Deployment 로그 정보가 출력됩니다.

그 옆 버튼의 Exec info pod 버튼을 클릭하면 pod 내부로 진입할 수 있으나, 본 샘플의 경우 OS 이미지를 포함하고 있지 않아 접근할 수는 없습니다.

이왕 생성하는 김에 OS가 포함된 이미지를 하나 더 만들어보도록 하겠습니다.

 

a) 먼저 Docker Hub를 통해 gs-spring-boot-docker를 pull를 수행합니다.

[root@guruson ~]# docker pull springio/gs-spring-boot-docker 
Using default tag: latest
Trying to pull repository docker.io/springio/gs-spring-boot-docker ... 
latest: Pulling from docker.io/springio/gs-spring-boot-docker
88286f41530e: Pull complete 
8e194fc7b3fc: Pull complete 
bfed7f5c4dc0: Pull complete 
3269658dba07: Pull complete 
Digest: sha256:879e37e16545d45391f30e5559dface8d90636ab330b546fa53d3ae79dfed545
Status: Downloaded newer image for docker.io/springio/gs-spring-boot-docker:latest
[root@guruson ~]#

- 생성된 Docker Image를 확인해보면

[root@guruson ~]# docker images | grep spring
docker.io/springio/gs-spring-boot-docker                 latest              3a7a85f42b64        2 years ago         181 MB
[root@guruson ~]#

 

b) 다음으로 My Docker Hub에 gs-spring-boot-docker를 push합니다.
- docker push를 위한 docker tag를 생성합니다.

[root@guruson ~]# docker tag springio/gs-spring-boot-docker nara0617/gs-spring-boot-docker:latest 
[root@guruson ~]#

- docker push를 수행하여 registry에 업로드합니다.

[root@guruson ~]# docker push nara0617/gs-spring-boot-docker 
The push refers to a repository [docker.io/nara0617/gs-spring-boot-docker]
d89696c8d8f7: Mounted from springio/gs-spring-boot-docker 
8ed4ebdc2a2b: Mounted from springio/gs-spring-boot-docker 
2fd640341bb9: Mounted from springio/gs-spring-boot-docker 
5bef08742407: Mounted from springio/gs-spring-boot-docker 
latest: digest: sha256:879e37e16545d45391f30e5559dface8d90636ab330b546fa53d3ae79dfed545 size: 1163
[root@guruson ~]#

- docker hub에 업로드가 되었는지 확인해 봅니다.

위와 같이 nara0617 Registry에 nara0617/gs-spring-boot-docker Repository가 업로드 된것을 볼 수 있습니다.

 

c) 다음으로 deployment를 위한 yaml파일을 작성합니다.

apiVersion: apps/v1beta2 
kind: Deployment 
metadata: 
  name: gs-spring-boot-docker-deployment 
  labels: 
    app: gs-spring-boot-docker 
spec: 
  replicas: 1 
  selector: 
    matchLabels: 
      app: gs-spring-boot-docker 
  template: 
    metadata: 
      labels: 
        app: gs-spring-boot-docker 
    spec: 
      containers: 
      - name: gs-spring-boot-docker 
        image: nara0617/gs-spring-boot-docker:1.0 
        ports: 
        - containerPort: 8080 
        imagePullPolicy: Always 
        resources: 
          requests: 
            memory: "256Mi" 
            cpu: "200m" 
          limits: 
            memory: "1Gi" 
            cpu: "500m"
===============================================================================
1. apiVersion 
API Server에서 관리되는 API 버전을 나타냅니다. 사용자가 입력한 apiVersion에 맞는 API를 사용하게 됩니다. Kubernetes API는 실험 단계의 API를 ‘beta’ 형태로 지원하고, 지속 업데이트 하고 있습니다. 따라서 Kubernetes API 공식가이드를 통해 현재 사용자의 Kubernetes 버전 별 호환 및 사용 가능한 API를 확인 후 사용해야 합니다. 
2. kind 
현재 yaml이 어떤 object를 생성하기 위함인지 kind에 설정합니다. kind: Deployment 설정을 통해 현재 yaml로 Deployment object를 생성하게 됩니다. 
3. metadata 
Deployment object 자신의 고유 정보를 입력합니다. 
4. metadata.name 
Deployment object에 대한 Unique-key를 입력합니다. 이 name 값을 통해 여러 object 중 해당 name을 갖는 object를 조회할 수 있습니다. 
5. metadata.labels 
Deployment object에 대한 label을 설정하는데, 복수개의 label 설정이 가능 합니다. object들의 그룹화가 가능하고, 같은 label을 가진 object들을 같은 그룹으로 식별 됩니다. 
7. spec 
Deployment object가 수행하는 내용에 대한 설정 입니다. 
8. spec.replicas 
Deployment object가 ReplicaSets object를 통해 복제해야 할 Pod의 개수를 설정합니다. 
9. spec.selector.matchLabels 
Deployment object가 관리해야할 Pod이 어떤 것인지 찾기 위해 selector 정보로 Pod의 label 정보를 비교하고 매칭되는 label을 갖는 Pod들만 관리 대상으로 생각합니다. 
10. spec.template 
Deployment object가 생성할 Pod 관련 설정 입니다. 
11. spec.template.metadata.labels 
Pod의 label을 설정하는데, 복수개의 label 설정이 가능 합니다. object들의 그룹화가 가능하고, 같은 label을 가진 object들을 같은 그룹으로 식별 됩니다. 다른 애플리케이션을 위한 Pod과 label이 겹치지 않도록 유의 합니다. 
12. spec.template.spec 
Deployment object가 생성할 Pod에 대한 설정 입니다. 
13. spec.template.spec.containers 
Deployment object가 생성할 Pod이 관리하는 container들의 설정입니다. 
14. spec.template.spec.containers.name 
container 이름 입니다. 
15. spec.template.spec.containers.image 
container image name 입니다. docker에서의 image name 및 tag를 입력하는 방식과 같은 방식으로 입력합니다. 
16. spec.template.spec.containers.ports 
containerPort를 배열로 복수개 설정 합니다. 
17. spec.template.spec.containers.ports.containerPort 
contianer가 사용하는 port에 대한 설정 입니다. 8080 포트를 사용한다고 명시되어 있습니다. 
18. spec.template.spec.containers.imagePullPolicy 
“Always”와 “IfNotPresent”의 설정이 가능 합니다. “Always”인 경우, Remote Registry로 부터 Image를 항상 Download하고, “IfNotPresent”는 우선적으로 캐싱된 Image가 있으면 해당 Image를 사용하고, 없는 경우에만  Remote Registry로 부터 Download를 시도 합니다. 
19. spec.template.spec.containers.resources.requests 
컨테이너가 요청할 최소한의 리소스에 대한 설정입니다. Spring Boot 애플리케이션의 경우는 메모리 값을 256M 이상으로 설정해야 합니다. 
20. spec.template.spec.containers.resources.limits 
컨테이너가 최대한으로 사용할 리소스에 대한 설정입니다. 애플리케이션에 따라 적절한 CPU와 메모리 값으로 설정해주어야 합니다. CPU를 너무 낮게 설정하면 애플리케이션이 기동되는데 많은 시간이 걸릴 수 있습니다. 
수정에 유의해야하는 yaml 항목은 볼드처리한 부분입니다. yaml 작성 시 주의하시기 바랍니다. 

d) 다음으로 Pod를 배포해 보도록 하겠습니다.

Pod를 배포하는 방법은 Kubernetes GUI를 사용하거나 CLI 명령어를 사용하여 생성할 수 있습니다.
yaml 파일 작성 후 kubectl apply 명령어로 pod를 생성합니다.
확인 방법은 cli에서 확인하는 방법과 Kubernetes GUI에서 확인하는 방법이 있습니다.
kubectl get pods로 생성한 pod를 볼 수 있습니다.


e) 다음으로 정상적으로 생성된 Pod에 접속하여 상태를 확인해 보도록 하겠습니다.

Pod의 상태 확인 방법은 크게 3가지 정도 체크해 볼 수 있습니다. (애플리케이션 접속 테스트 제외.)
- 먼저 워크로드 => Pod 항목에서 초록색 체크가 들어와 있는지 확인
앞서 확인했던 것처럼 초록색 체크가 되어 있는지 확인합니다.
- 다음으로 워크로드 => Pod => Pod 이름 클릭 => 오른쪽 상단의 로그 클릭

위와 같이 pod 이름을 클릭하면 생성된 Container의 정보가 출력되며 로그를 클릭하여 문제 발생 여부를 확인할 수 있습니다.
- 마지막으로 컨테이너 내부에 들어가서 확인하는 방법입니다.

Pod Information의 기동 된 Node 정보를 확인하고 해당 서버에서 직접 접속해 보도록 하겠습니다.

[root@kubeworker ~]# docker ps -a | grep spring
a40304c7fc04        nara0617/gs-spring-boot-docker   "sh -c 'java $JAVA_O   47 minutes ago      Up 47 minutes                           k8s_gs-spring-boot-docker_gs-spring-boot-docker-deployment-7455d748bc-2rlgb_default_c5033e1a-d5bd-4ac2-b206-d591b1ae27cc_0
a3e1a219133d        k8s.gcr.io/pause:3.1             "/pause"                 47 minutes ago      Up 47 minutes                           k8s_POD_gs-spring-boot-docker-deployment-7455d748bc-2rlgb_default_c5033e1a-d5bd-4ac2-b206-d591b1ae27cc_0
[root@kubeworker ~]# docker exec -it a40304c7fc04 /bin/sh
/ # ls -la
total 14092
drwxr-xr-x    1 root     root            29 Aug  4 04:46 .
drwxr-xr-x    1 root     root            29 Aug  4 04:46 ..
-rwxr-xr-x    1 root     root             0 Aug  4 04:46 .dockerenv
-rw-rw-r--    1 root     root      14421089 Jul 24  2017 app.jar
drwxr-xr-x    2 root     root          4096 Jun 25  2017 bin
drwxr-xr-x    5 root     root           360 Aug  4 04:46 dev
drwxr-xr-x    1 root     root            66 Aug  4 04:46 etc
drwxr-xr-x    2 root     root             6 Jun 25  2017 home
drwxr-xr-x    1 root     root            17 Jun 27  2017 lib
drwxr-xr-x    2 root     root            34 Jun 27  2017 lib64
drwxr-xr-x    5 root     root            44 Jun 25  2017 media
drwxr-xr-x    2 root     root             6 Jun 25  2017 mnt
dr-xr-xr-x  143 root     root             0 Aug  4 04:46 proc
drwx------    1 root     root            51 Aug  4 05:25 root
drwxr-xr-x    2 root     root             6 Jun 25  2017 run
drwxr-xr-x    2 root     root          4096 Jun 25  2017 sbin
drwxr-xr-x    2 root     root             6 Jun 25  2017 srv
dr-xr-xr-x   13 root     root             0 Aug  3 21:58 sys
drwxrwxrwt    5 root     root           115 Aug  4 04:46 tmp
drwxr-xr-x    1 root     root            66 Jun 27  2017 usr
drwxr-xr-x    1 root     root            17 Jun 25  2017 var
/ # 

f) 마지막으로 Replica Set에 대해 확인할 수 있습니다.

[root@guruson ~]# kubectl get po
NAME                                                READY     STATUS    RESTARTS   AGE
apache-docker-deployment-54876bbd86-rdkmn           1/1       Running   0          4h33m
apache2-docker-deployment-5bf4bfdb-qlcdx            1/1       Running   0          4h23m
gs-spring-boot-docker-deployment-7455d748bc-2rlgb   1/1       Running   0          51m
[root@guruson ~]# kubectl get rs
NAME                                          DESIRED   CURRENT   READY     AGE
apache-docker-deployment-54876bbd86           1         1         1         4h33m
apache2-docker-deployment-5bf4bfdb            1         1         1         4h23m
gs-spring-boot-docker-deployment-7455d748bc   1         1         1         51m
[root@guruson ~]#

다음 포스팅에서는 이렇게 확인된 Pod들에 대한 서비스를 생성하고 Endpoint를 통해 직접 서비스를 호출해 보도록 하겠습니다.

728x90
반응형