Sample application으로 dockerized 하는 과정에 대해 기술

안녕하세요! 굉장히 오랜만에 블로그로 다시 찾아온 것 같습니다.

지난시간에 Docker의 기본적인 개념과 어떻게 동작했는지를 알아봤는데요,
이번에는 실질적으로 사용하고있는 Application을 어떻게 Containerized 할지에 관련된 주제 를 가지고 돌아왔습니다.


순서는 다음과 같습니다.

1. Source code clone
2. npm build
3. docker file 생성
4. docker file을 통한 docker image 생성
5. docker run을 이용한 컨테이너 실행

1. Source Code Clone.

해당 Source 들은 GitLab에 올려져 있으며.
해당 애플리케이션 같은경우 Hostname과 현재 시간을 출력해주는 simple application입니다.

자 그럼 Giblab에 올려진 코드들을 가지고 와봅니다.

[root@kbseo-test1 stl]# git clone http://192.168.197.132/root/stlapp.git
Cloning into 'stlapp'...
Username for 'http://192.168.197.132': kbseo
Password for 'http://kbseo@192.168.197.132': 
remote: Enumerating objects: 131, done.
remote: Counting objects: 100% (131/131), done.
remote: Compressing objects: 100% (69/69), done.
remote: Total 217 (delta 70), reused 112 (delta 56), pack-reused 86
Receiving objects: 100% (217/217), 564.33 KiB | 0 bytes/s, done.
Resolving deltas: 100% (84/84), done.

소스들을 서버로 잘 데리고 왔습니다.
참고로 말씀드리자면 해당 Application은 React와 Spring Boot로 만들어졌고 maven을 통해 build하도록 되어져있습니다.
추가로 Maven내에 npm build가 가능하도록 한 상태여서 maven 명령을 통해서 빌드가 가능합니다.

2. npm build

[root@kbseo-test1 stlapp]# ./mvnw package
[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------------< no.kantega:stlapp >--------------------------
[INFO] Building spring-and-react 0.1
[INFO] --------------------------------[ war ]---------------------------------
[INFO] 
[INFO] --- frontend-maven-plugin:1.6:install-node-and-npm (install node and npm) @ stlapp ---
[INFO] Installing node version v6.17.1
[INFO] Unpacking /root/.m2/repository/com/github/eirslett/node/6.17.1/node-6.17.1-linux-x64.tar.gz into /root/stl/stlapp/target/node/tmp
[INFO] Copying node binary from /root/stl/stlapp/target/node/tmp/node-v6.17.1-linux-x64/bin/node to /root/stl/stlapp/target/node/node
[INFO] Installed node locally.
[INFO] Installing npm version 3.10.10
[INFO] Unpacking /root/.m2/repository/com/github/eirslett/npm/3.10.10/npm-3.10.10.tar.gz into /root/stl/stlapp/target/node/node_modules
.....
[INFO] --- spring-boot-maven-plugin:2.0.1.RELEASE:repackage (default) @ stlapp ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:22 min
[INFO] Finished at: 2020-04-24T18:30:05+09:00
[INFO] ------------------------------------------------------------------------
[root@kbseo-test1 stlapp]# 

빌드를 완료해주었습니다!

3. docker file 생성

이렇게 가지고 온 source를 컨테이너화 하기위하여 docker file을 먼저 생성해 줘야겠죠?

[root@kbseo-test1 stlapp]# vim Dockerfile
FROM tomcat:8.5.50-jdk8-openjdk

MAINTAINER kbseo@osci.kr

ENV TZ=Asia/Seoul
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime

RUN rm -rf /usr/local/tomcat/webapps/ROOT
COPY target/stlapp-0.1.war /usr/local/tomcat/webapps/ROOT.war

Simple application은 hostname과 time zone을 출력해주는 간단한 동작을 하는 애플리케이션 이기에
docker file안에 timezone을 설정해주고 tomcat상에서 동작될 war파일을 복사해줍니다.

4. docker file을 통한 docker image 생성

이전 글에서 설정해드린것과 같이 docker는 image로 배포를 하기 때문에
만들어두었던 docker file을 image화 해 줍니다.

# 현재 가지고있는 이미지가 있나 확인을 해줍니다
[root@kbseo-test1 stlapp]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
[root@kbseo-test1 stlapp]# 

이미지가 한개도 없는것을 확인하실수 있습니다.

이미지 형태로 빌드를 해줍니다!

[root@kbseo-test1 stlapp]# docker build -t stlapp:1.0 .
Sending build context to Docker daemon 252.2 MB
Step 1/6 : FROM tomcat:8.5.50-jdk8-openjdk
Trying to pull repository docker.io/library/tomcat ... 
8.5.50-jdk8-openjdk: Pulling from docker.io/library/tomcat
dc65f448a2e2: Pull complete 
346ffb2b67d7: Pull complete 
dea4ecac934f: Pull complete 
8ac92ddf84b3: Pull complete 
d8ef64070a18: Pull complete 
6577248b0d6e: Pull complete 
576c0a3a6af9: Pull complete 
6e0159bd18db: Pull complete 
944191e51caa: Pull complete 
9ee6a5ca751e: Pull complete 
Digest: sha256:d53c2079ea67db92f6d7c39e9450f641610336016fdddef5392c5afd41518e5e
Status: Downloaded newer image for docker.io/tomcat:8.5.50-jdk8-openjdk
 ---> b56d8850aed5
Step 2/6 : MAINTAINER jacobbaek@osci.kr
 ---> Running in 148cd746d772
 ---> 3b0a94a52842
Removing intermediate container 148cd746d772
Step 3/6 : ENV TZ Asia/Seoul
 ---> Running in 7398ad9609a2
 ---> 706e8669d2d6
Removing intermediate container 7398ad9609a2
Step 4/6 : RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime
 ---> Running in 1bcb6e658984

 ---> 453ac37a79dd
Removing intermediate container 1bcb6e658984
Step 5/6 : RUN rm -rf /usr/local/tomcat/webapps/ROOT
 ---> Running in f3c3bf4eb17b

 ---> 32f3bddc0334
Removing intermediate container f3c3bf4eb17b
Step 6/6 : COPY target/stlapp-0.1.war /usr/local/tomcat/webapps/ROOT.war
 ---> 3f24f0f7deaa
Removing intermediate container 134e07409a14
Successfully built 3f24f0f7deaa

docker build 같은경우 지난시간의 글에서 좀 더 자세히 확인 가능하십니다 ㅎ.ㅎ

명령어에 대해서 간단히 설명을 다시 드리자면,
$ docker build <옵션> <dockerfile 경로>
저는 태그를 지정해주기 위하여 -t옵션을 사용해주었습니다.
태그는 <저장소이름>/<이미지이름>:<태그> 형식입니다.

다시 이미지를 확인해보면 좀전에 build한 이미지가 올라온 것을 확인 하실 수 있습니다!

[root@kbseo-test1 stlapp]# docker images
REPOSITORY          TAG                   IMAGE ID            CREATED             SIZE
stlapp              1.0                   3f24f0f7deaa        3 minutes ago       545 MB
docker.io/tomcat    8.5.50-jdk8-openjdk   b56d8850aed5        2 months ago        529 MB

어라? 왜 두개의 이미지가 올라가져있을까요....? 분명히 도커 빌드는 한번만 실행했는데.. 도커파일을 다시 살펴볼까요?

FROM tomcat:8.5.50-jdk8-openjdk

첫줄에서 답이 나왔습니다!
FROM 을 통해 tomcat이미지를 먼저 받아서 그 위에 차례대로 레이어를 쌓아가면서 도커파일을 실행하기에
이미지가 두개가 만들어지게 됩니다.

  1. docker run을 이용한 컨테이너 실행

이제 Image를 만들었으니 실행해봅시다!

[root@kbseo-test1 stlapp]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@kbseo-test1 stlapp]#

아직까지 실행되고있는 컨테이너가 없네요

[root@kbseo-test1 stlapp]# docker run -d -p 8081:8080 --name=stlapp stlapp:1.0
fc16ba3e9f3f03ba22a2ca0b7eb12909a8311b555ef34bcf9b0f591537a76d2a

명령어에 대해 간단히 설명드리자면
$ docker run <옵션> <이미지이름, ID > <명령> <매개변수>

이렇게 구성되어있습니다.

docker run -d -p 8081:8080 --name=stlapp stlapp:1.0 이 명령어를 보자면

  • -d 데몬모드로 컨테이너를 실행하고,

  • -p 옵션을 이용하여 외부포트를 연결해줍니다 <호스트포트>:<컨테이너포트> -> 8080컨테이너 포트를 8081포트를 이용해 외부로 연결시킵니다.

  • --name 컨테이너 이름을 지정해줍니다. 여기에서는 stlapp이라는 이름을 달아주었습니다.

  • 실행시킬 컨테이너와 태그정보를 입력해줍니다.

결과를 한번 봐볼까요?

[root@kbseo-test1 stlapp]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
fc16ba3e9f3f        stlapp:1.0          "catalina.sh run"   11 minutes ago      Up 11 minutes       0.0.0.0:8081->8080/tcp   stlapp
[root@kbseo-test1 stlapp]# 

실행되고있는 컨테이너를 확인하실 수 있습니다.

브라우저를 통해 확인해볼까요?

컨테이너 이미지의 ID와 현재 시간이 잘 출력되는것을 보실 수 있습니다.

하지만 빨간색이라 눈이 너무나 아픈것같은 느낌적인 느낌입니다
그래서 검은색으로 바꾸고 재 배포를 해볼까요??

순서는 간단합니다!

  1. 실행되고 있는 컨테이너 중지
  2. 해당 컨테이너 삭제
  3. 소스수정
  4. 소스빌드, 컨테이너 빌드
  5. 컨테이너 실행

1. 실행되고 있는 컨테이너 중지

단칼에 중지시켜 줍니다.

[root@kbseo-test1 src]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
fc16ba3e9f3f        stlapp:1.0          "catalina.sh run"   29 minutes ago      Up 29 minutes       0.0.0.0:8081->8080/tcp   stlapp

 
[root@kbseo-test1 src]# docker kill stlapp
stlapp


[root@kbseo-test1 src]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
fc16ba3e9f3f        stlapp:1.0          "catalina.sh run"   29 minutes ago      Exited (137) 3 seconds ago                       stlapp

docker kill 명령어를 통해 중지시켜준 후
docker ps 를 통해 확인해보면 상태가 바뀐것을 보실 수 있습니다.
브라우저를 통해 접속해봐도 접속이 안되는것을 보실 수 있죠

2. 해당 컨테이너 삭제

프로세스를 삭제시켜 줍니다.

[root@kbseo-test1 src]# docker rm stlapp
stlapp

[root@kbseo-test1 src]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

3. 소스수정

css코드를 수정하여 색상을 변경해줍니다. 저는 블랙블랙으로 바꿨습니다.(TMI)

4. 소스빌드

소스를 수정했으니 재빌드를 해줘야겠죠?

[root@kbseo-test1 stlapp]# ./mvnw package
INFO] Scanning for projects...
[INFO] 
[INFO] -------------------------< no.kantega:stlapp >--------------------------
[INFO] Building spring-and-react 0.1
[INFO] --------------------------------[ war ]---------------------------------
[INFO] 
[INFO] --- frontend-maven-plugin:1.6:install-node-and-npm (install node and npm) @ stlapp ---
[INFO] Node v6.17.1 is already installed.
[INFO] NPM 3.10.10 is already installed.
[INFO] 
[INFO] --- frontend-maven-plugin:1.6:npm (npm install) @ stlapp ---
[INFO] Running 'npm install' in /root/stl/stlapp/frontend
...
...
[INFO] --- spring-boot-maven-plugin:2.0.1.RELEASE:repackage (default) @ stlapp ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 43.467 s
[INFO] Finished at: 2020-04-27T20:10:43+09:00
[INFO] ------------------------------------------------------------------------

소스를 빌드했으니 도커를 빌드해봅시다!

[root@kbseo-test1 stlapp]# docker build -t stlapp .
Sending build context to Docker daemon 252.2 MB
Step 1/6 : FROM tomcat:8.5.50-jdk8-openjdk
 ---> b56d8850aed5
Step 2/6 : MAINTAINER jacobbaek@osci.kr
 ---> Using cache
 ---> 3b0a94a52842
Step 3/6 : ENV TZ Asia/Seoul
 ---> Using cache
 ---> 706e8669d2d6
Step 4/6 : RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime
 ---> Using cache
 ---> 453ac37a79dd
Step 5/6 : RUN rm -rf /usr/local/tomcat/webapps/ROOT
 ---> Using cache
 ---> 32f3bddc0334
Step 6/6 : COPY target/stlapp-0.1.war /usr/local/tomcat/webapps/ROOT.war
 ---> Using cache
 ---> 3f24f0f7deaa
Successfully built 3f24f0f7deaa

이미지가 만들어졌는지 확인해볼까요?

[root@kbseo-test1 stlapp]# docker images
REPOSITORY          TAG                   IMAGE ID            CREATED             SIZE
stlapp              1.0                   3f24f0f7deaa        3 hours ago         545 MB
stlapp              latest                3f24f0f7deaa        3 hours ago         545 MB
docker.io/tomcat    8.5.50-jdk8-openjdk   b56d8850aed5        2 months ago        529 MB

하나의 이미지가 추가로 생성된 것을 보실 수 있습니다!

5. 컨테이너 실행

돌려봅니다

[root@kbseo-test1 stlapp]# docker run -d -p 8081:8080 --name=stlapp stlapp
5140e8332057ed23c4bf491a36d2d63fa0d09f0ffc4378073e145c2626075c30

잘 올라가져있는지 확인해볼까요?

[root@kbseo-test1 stlapp]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
dd58841261fa        stlapp              "catalina.sh run"   55 seconds ago      Up 55 seconds       0.0.0.0:8081->8080/tcp   stlapp

이제 깔끔한 BLACK 색상으로 바뀌었습니다.

이렇게 제 local환경에서 테스트한 컨테이너들에게 TAG를 지정하여서 버전관리도 할 수 있습니다.

[root@kbseo-test1 stlapp]# docker tag stlapp:latest 192.168.197.130:5000/stlapp_kb:1.2.0

[root@kbseo-test1 stlapp]# docker images
REPOSITORY                       TAG                   IMAGE ID            CREATED             SIZE
192.168.197.130:5000/stlapp_kb   1.2.0                 3e72ae5de27a        5 minutes ago       545 MB
stlapp                           latest                3e72ae5de27a        5 minutes ago       545 MB
docker.io/tomcat                 8.5.50-jdk8-openjdk   b56d8850aed5        2 months ago        529 MB
[root@kbseo-test1 stlapp]# 

테스트를 끝냈으니 registry에 올려줄 차례죠

[root@kbseo-test1 stlapp]# docker push 192.168.197.130:5000/stlapp_kb:1.2.0
The push refers to a repository [192.168.197.130:5000/stlapp_kb]
The push refers to a repository [192.168.197.130:5000/stlapp_kb]
Get https://192.168.197.130:5000/v1/_ping: http: server gave HTTP response to HTTPS client

어랏? 안돼네요?
이유는 바로 도커는 https 통신을 하기 때문입니다.

고로 저는 http 통신을 하기위해
docker에게 직접 친절히 사용하고자 하는 ip를 등록해주도록 하겠습니다.

docker insecure

여러가지의 방법이 있지만
저는 daemon.json 파일 안에 등록을 해주도록 하겠습니다.
(가장 간단해서 이방법으로 하였습니다 히힛)

  1. /etc/docker/daemon.json 수정
[root@kbseo-test1 stlapp]# cat /etc/docker/daemon.json 
{
"insecure-registries":["192.168.197.130:5000"]
}

사용할 registry 주소와 포트를 입력해줍니다.

  1. dpcker 데몬 재기동
[root@kbseo-test1 stlapp]# service docker restart
Redirecting to /bin/systemctl restart docker.service
  1. 레지스트리에 login
[root@kbseo-test1 stlapp]# docker login http://192.168.197.130:5000
Username: admin
Password: 
Login Succeeded
  1. 레지스트리에 push
[root@kbseo-test1 stlapp]# docker push 192.168.197.130:5000/stlapp_kb:1.2.0
The push refers to a repository [192.168.197.130:5000/stlapp_kb]
c20036844421: Pushed 
64bc7cab37ab: Pushed 
caeac141f483: Layer already exists 
5245df7d360d: Layer already exists 
78f5460c83b5: Layer already exists 
c601709dd5d2: Layer already exists 
72ce39f2b7f6: Layer already exists 
33783834b288: Layer already exists 
5c813a85f7f0: Layer already exists 
bdca38f94ff0: Layer already exists 
faac394a1ad3: Layer already exists 
ce8168f12337: Layer already exists 
1.2.0: digest: sha256:93e8b021981faed5cb1e5b22f4c0694f841afc1aa4502fff78d7edf9ffdb97cf size: 2840
[root@kbseo-test1 stlapp]#



짜잔! 등록이 되었습니다

이번시간에는 간단한 Application을 컨테이너화 하여 실행하는거 까지 함께 했는데요

간단하다고 했지만 실질적으로 여러 작업이 들어갔었습니다

그래서 다음시간에는 이를 좀 더 간단히 수행하기위해

젠킨스를 이용하여 작업을 해보도록 하겠습니다!

뿅!

kbseo's profile image

kbseo

2020-04-30

Read more posts by this author