230508 Docker

Docker


이번 포스팅에서는

이미지와 컨테이너 관리하기

1
2
3
docker ps


docker run은 이미지를 기반으로 새로운 컨테이너를 띄운다.
따라서 별도의 수정이 없는 경우에는 docker start 명령으로 기존에 중지된 컨테이너를 재 사용할 수 있다.

docker run으로 컨테이너를 시작하면 container가 background가 아닌 foreground에서 실행된다. 반면 docker start는 background에서 container가 실행된다.

Attached mode(docker run default) , Detached mode(docker start)

Detached mode로 실행된 컨테이너의 경우에는 애플리케이션에서 발생한 로그 기록들을 실시간으로 확인(console 확인)할 수 없으며, Attached mode로 실행된 컨테이너의 경우에는 애플리케이션의 실행과정에서 발생한 로그 기록들을 실시간으로 console을 통해 확인할 수 있다.

컨테이너의 출력결과를 수신한다.

Read more

230507 Docker

Docker


이번 포스팅에서는 Docker의 이미지 & 컨테이너(코어 빌딩 블록)에 대해 학습한 내용을 정리한다.

Images and Container

  • Pre-Built & Custom Images

  • Create & Manage containers

Images와 Container의 관계

  • Container : The running “unit of software”

  • Images : Templates / Blueprints for containers

Contains code + required tools/runtimes

이미지를 사용하여 여러 컨테이너(running instance)를 생성할 수 있다.

Finding / Creating Images

  • 이미지는 기존에 생성된 이미지를 사용하거나, Dockerhub에 업로드 되어있는 pre-built 이미지를 사용할 수 있다.
1
docker run --name node-image node

위의 명령을 통해 node pre-built 이미지를 Docker hub를 pull해서 로컬에 다운받을 수 있다.

1
docker ps -a

위의 명령을 통해서 도커가 생성한 모든 컨테이너 정보를 확인할 수 있다.

1
2
docker run -it node
# 쉘을 통해서 node container에 접근

나만의 CUSTOM DOCKER IMAGE를 생성하기 위해 Dockerfile을 작성할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 운영체제 레이어 SETTING
FROM node

WORKDIR /app

# 첫번째 .(dot) : 컨테이너 외부 경로로, Dockerfile이 위치한 경로를 의미한다.
# 두번째 .(dot) : 자체 내부 시스템
# 만약에 /app 폴더가 존재하지 않는경우에는 이미지와 컨테이너에 생성된다.
COPY . /app

# 기본적으로 도커 컨테이너 및 이미지의 WORKDIR에서 아래 명령이 실행된다.
RUN npm install

# DOCKER 컨테이너는 외부 로컬 시스템과 격리되어있다.
# 자체 내부 네트워크도 있기 때문에 외부 로컬 시스템에 노출시켜줘야 한다.
EXPOSE 80

# 서버 시작
# 아래 명령도 틀린건 아니지만, 이 이미지가 빌드될 때마다 실행되기 때문에
# 아래와 같이 실행하는 것은 올바르지 않다.
# 위에서 작성한 모든 것은 이미지 설정을 위한 명령으로, 도커 명령어이다.
# 이미지는 컨테이너의 템플릿이어야 한다. (이미지를 실행하는 것이 아닌, 이미지를 기반으로 컨테이너를 실행하는 것)
# RUN node server.js

# 컨테이너를 실행하는 경우에만 서버를 실행하기를 원하기 때문에
# 아래와 같이 명령을 실행하는 것이 맞다.
# RUN과 CMD의 차이는 CMD는 이미지가 생성될 때 실행되지 않고, 컨테이너가 실행될때 실행된다.
# 만약 명시된 CMD 명령이 없다면, BASE IMAGE의 CMD 명령이 실행되며, BASE IMAGE가 없고, CMD 이미지가 없다면 에러 메시지가 팝업된다.
CMD ["node", "server.js"]

그 다음 STEP은 위에서 작성한 Dockerfile의 스크립트 내용을 기준으로 Docker image를 만들어야 한다.

1
docker build --tag node-custom-app .

아래 명령으로 생성한 이미지(node-custom-app)를 사용하여 node-custom-app-container 도커 컨테이너를 80번 포트로 portforwarding하여 백그라운드로 실행한다.

1
2
# 실행할 Docker 이미지의 full name 말고, 만약 이름이 유일하다면, 부분이름으로 지정해서 사용할 수 있다.
docker run --name node-custom-app-container -p 80:80 -d node-custom-app

Dockerfile에서 EXPOSE 80은 문서화하는 목적으로 작성되었기 때문에 실제 컨테이너를 실행할때 위와같이 -p option을 통해 portforwarding 해줘야 한다. (EXPOSE 명령은 선택사항이지만 모범적인 사용법)

여지까지 기존 이미지인 노드 이미지를 기반으로 하는 커스텀 이미지를 docker build 명령을 통해서 생성하였고, docker run 명령을 통해서 해당 이미지를 기반으로 컨테이너를 띄웠다.

CUSTOM APP 코드 수정

커스텀 앱의 코드 일부를 수정했다면, 생성한 커스텀 이미지를 다시 빌드하여, 코드 복사과정을 다시 실행해야 한다.

한 번 빌드된 이미지는 잠겨있으며, 읽기 전용이 된다.

이미지는 레이어 기반 아키텍처(모든 명령이 레이어로 구성)로 되어있기 때문에 이미지를 빌드하는 과정에서 과거 실행되었던 부분에 대해서는 모든 명령 결과를 캐시하고, 이미지를 다시 빌드할때 명령을 다시 실행할 필요가 없으면, 캐시된 결과를 사용한다.

만약 특정 레이어가 변경되었다면, 변경된 레이어 후의 모든 레이어가 다시 빌드된다. 따라서 Dockerfile 내 레이어를 최적화 시키기 위해서는 우선적으로 package.json파일 개별적으로 복사하고, npm install 명령을 실행하고 반복적으로 코드 수정이 발생하는 부분에 대해서는 별도로 복사를 하는 과정을 작성하도록 하는 것이 좋다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 운영체제 레이어 SETTING
FROM node

WORKDIR /app

# 선 dependencies 파일 복사 및 설치
COPY package.json /app

RUN npm install


COPY . /app

EXPOSE 80

CMD ["node", "server.js"]

이 이미지를 기반으로 컨테이너를 실행하면, 컨테이너는 기본적으로 Dockerfile에 지정한 명령을 실행한 결과로 코드를 실행중인 애플리케이션인 이미지 위에 컨테이너 레이어를 새로 추가한다.

CUSTOM APP 코드 수정

230506 Docker

Docker


이번 포스팅에서는 Docker에 대해 학습한 내용을 기록하고자 한다.

Docker

Docker는 컨테이너 기술로, 컨테이너를 생성하고 관리하는데 사용된다.

VM

VM과 비교했을때, VM 또한 도커와 같이 환경을 분리하고, 각 환경별로 구체적인 환경설정을 분리하는 것 또한 가능하다. 그리고 구성한 환경 설정을 공유할 수 있고, VM 간의 의존성을 낮출 수 있다.
위의 장점이 있지만, 환경 구성을 위해 각 각의 VM의 기반으로 OS를 설치해야 되기 때문에 시스템의 리소스가 낭비될 수 있으며, 퍼포먼스가 느려지고, 부팅 시간이 길어지는 단점이 있다.

Docker 구성

Docker 엔진 위에 복수의 컨테이너들을 띄워서 구성할 수 있다. 물론 Docker container 내에도 OS를 설치하지만 VM의 OS보다 훨씬 가볍고 빠르다. Share, Re-building, Distribution에 용이하며, apps와 환경을 Encapsulation한다.

Docker image

Container는 이미지를 기반으로 하기 때문에 이미지 생성을 우선 해야한다.
각 각의 이미지에는 개별 파일 시스템이 있기 때문에 Dockerfile이 위치한 경로에 있는 파일들을 Docker의 파일 시스템에 복사해서 처리해줘야 한다.

Read more

220616 Kubernetes 스터디 4일차

Kubernetes


ClusterIP Service 실습

ClusterIP Service를 생성하고, 지정한 selector가 app:pod를 가지는 pod와 연결을 하였다. 그런 다음에 연결된 app:pod label을 가지는 Pod를 삭제하고, 다시 재생성을 한다. 이렇게 되면, 실제 pod에 할당되어있던 IP는 동적으로 할당이 되어 변경이 되지만, ClusterIP Service는 재생성이 되지 않아, 동일한 Service IP로 Pod에 접근이 가능하다.

NodePort Servce 실습

실제 Dashboard의 디스커버리 및 로드 밸런싱 하위의 서비스 항목을 가보면, 내부 엔드 포인트가 두 개 생성된 것을 확인할 수 있는데, 상위에 있는 9000번 포트가 클러스터 내에서 접근할때 사용되는 포트이고, 30000번 포트가 각 각의 노드들에 동일하게 할당된 포트 번호이다. 이 포트를 통해 외부에서 클러스터 내부의 Service를 통해 하위 Pod들에 트래픽을 보낼 수 있다.
실습에서는 외부 터미널에서 curl 명령을 통해 서비스에 접근하여 각 pod에 대한 hostname이 출력되는 것을 확인하였다.

Read more

220611 Kubernetes 스터디 3일차

Kubernetes


이번 포스팅에는 쿠버네티스 클러스터에서 서비스와 관련된 이론내용을 정리하고, 실습한 내용에 대해서 정리하려고 한다.
저번시간에는 실습을 위한 쿠버네티스 클러스터 환경을 구축하고, Container, Label, NodeSchedule에 대한 부분을 학습하고 실습을 해보았다.
컨테이너는 쿼버네티스 클러스터 내의 namespace 상에 존재하는 pod의 내부에 복수로 존재하며, 각 각의 컨테이너들은 복수 개의 IP 할당이 가능하지만, pod 내에서는 IP 충돌로 인해 동일한 IP의 할당이 불가하다는 것을 이론과 실습을 통해 이해했다.
Label은 각 각의 용도에 따라 Pod에 명기된 label로 Pod들을 묶어서 하나의 서비스를 생성하거나, 또 다른 pod 집합으로 생성하기 위해 사용된다는 것을 이론과 실습을 통해 이해하였다.
마지막으로 NodeSchedule 파트에서는 각 각의 Pod들은 Cluster에 연결된 노드들에 할당이 되어야 하는데, 할당하는 방법에 대해서는 직접 Pod를 Node에 할당하는 방법과 스케줄러에 의해 각 각의 노드가 가지고 있는 여유 메모리 공간에 대한 확인으로, 자동 할당되는 방법에 대해서도 이론과 실습을 통해 이해하였다.

아직 개괄적으로 쿠버네티스에 있는 각 각의 요소들의 개념과 원리에 대해서 이해하는 과정이기 때문에 전체적인 그림 안에서 각 각의 요소가 어떤 기능을 하는지에 대해서 이해하면서 학습을 하고 있다.
엇그제 Label을 통해서 용도에 따라 pod(들)을 묶어서 하나의 Service로 만들어서 다른 운영자에게 IP와 Port를 제공한다고 배웠다. (웹 개발자가 웹 화면만 확인하고자 할때 type이 web인 pod들만 service에 연결시켜서 웹 개발자들에게 제공 / 외부에서 원하는 service의 pod들에만 접그하고자 할 때 label이 production으로 지정된 pod들을 묶어서 하나의 service로 생성하고 제공)
이 Service에 대해서 이론적으로 학습을 하고 직접 실습을 해 볼 것이다.

Read more

220609 Kubernetes 스터디 2일차

Kubernetes
이번 포스팅에는 쿠버네티스 클러스터를 구축하고 실습한 내용에 대해서 정리하려고 한다.

쿠버네티스 클러스터 실습 구성도

Kubernetes cluster 구성

Vagrant 명령(손쉽게 VirtualBox의 VM관리)

host os의 cmd창에서 실행

1
2
3
4
$vagrant up: 가상머신 기동
$vagrant halt: 가상머신 shutdown (클러스터 실습이 끝나고 VM 내리기)
$vagrant ssh: 가상머신 접속 (vagrant ssh k8s-master)
$vagrant destroy: 설치한 가상머신 삭제
Read more

220606 Kubernetes 스터디 1일차

Kubernetes
이번 포스팅부터는 쿠버네티스에 대해서 학습한 내용을 정리해보려고 한다. 빠르게 기본적인 내용에 대해서 정리를 하고, 앞으로 계속 실습을 해가면서 익숙해지는 시 간에 많이 투자해야겠다.

Kubernetes ?

큰 기업은 대규모의 서비스를 운영하고 있기 때문에 최대한 자원을 효율적으로 써야 비용적으로 유리하다. 따라서 서버자원을 효율적으로 쓰기 위해서는 가상화 기술에 대해서 이해해야 한다.

과거에는 리눅스의 자원격리 기술(1991)이 있었다. 이후에 VMware, Xen, openstack VM(Virtual Machine)(2010.7)
가상화를 위해서 띄우고자 하는 가벼운 서비스를 사용하기 위해 더 무거운 OS를 올려야되는 상황이 생겼다.

어려운 자원격리기술을 dotCloud라는 회사에서 쉽게 사용할 수 있도록 container 서비스를 만들었고, 회사를 docker로 변경하면서 만든 서비스를 오픈소스로 공개하였다. (2014.06)
컨테이너 가상화 기술은 서비스간에 자원격리를 하는데 별도의 OS를 안띄워도 되기 때문에 OS 기동시간이 필요없게 되고, 자동화시 엄청 빠르고 자원의 효율도 매우 높아지게 되었다.

이러한 이유로 도커는 유명해졌다. 하지만 도커 자체는 하나의 서비스를 컨테이너로 가상화시켜서 배포를 하는 것이기 때문에 많은 서비스들을 운영할때 일일이 배포하고 운영하는 역할을 해주지 않기 때문에 불편함이 있었다.

Read more

220606 Docker 스터디 5일차

docker


실습1) ghost 블로그 docker 컨테이너 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Ghost는 무료 오픈소스 블로깅 플랫폼으로, 자바스크립트로 작성되었다고 한다.

# *.yml 파일은 docker-compose 명령을 사용해서 up, down을 할 수 있도록 도와준다.
# 기존의 콘솔에서 명령어 입력할 때 띄어쓰기등의 입력의 불편한 점을 개선하고자 *.yml파일은 유용하게 사용된다.

version: '3' # docker compose에 정의된 버전에 따라 지원하는 docker의 engine도 달라진다.

services: # 실행할 컨테이너를 정의한다. ($docker run -name [name] [service])
ghost:
image: ghost:latest
ports:
- '60000:2368'
volumes:
- ./ghost/content:/var/lib/ghost/content
environment:
url: http://localhost:60000
Read more

220604 Docker 스터디 4일차

docker


실습1) Nginx를 이용한 정적 페이지 서버 만들기

  • Docker 이미지 생성하기(Dockerfile)

    1
    2
    3
    FROM nginx
    COPY ./index.html /user/share/nginx/html/index.html
    EXPOSE 80
  • 생성한 이미지를 활용해서 배포하기

    1
    2
    3
    4
    $docker build -t hyungi/test1 .
    $docker run -d --rm \
    -p 50000:80 \
    hyungi/test1

    실습2) NodeJS 어플리케이션 이미지 빌드 및 배포

(1) 우선 디렉토리 내에 NodeJS 프로젝트를 구성한다. (server.js 및 package.json)

(2) 이미지 생성을 위해 Dockerfile 작성한다.

1
2
3
4
5
6
7
FROM    node:12-alpine
COPY ./package* /usr/src/app/
WORKDIR /usr/src/app
RUN npm install
COPY . /usr/src/app
EXPOSE 8080
CMD ["node", "/app/server.js"]
Read more

220603 Docker 스터디 3일차

docker


이번 포스팅에서는 docker 실습한 내용과 docker image를 만들고, 생성한 이미지를 docker hub에서 관리하고 배포하는 부분에 대해서 정리해보려고 한다.

실습1) nginx 컨테이너 만들기

1
2
3
4
5
# local에서 생성한 index.html파일을 생성할 container 내의 index.html 파일로 -v 옵션으로 생성한다.
$ docker run -d --rm \
-p 5000:80
-v $(pwd)/index.html:/usr/share/nginx/html/index.html \
nginx

-v 에서 $(pwd)를 통해 현재 위치 정보를 입력할 수 있다는 것을 배웠고, local에서 생성한 파일을 -v 옵션을 사용해서 container 내의 파일을 mapping 시킬 수 있다는 것도 다시 한 번 정리할 수 있었다.

실습2) php 컨테이너 실행하기

1
2
3
4
$ docker run --rm \
-v $(pwd)/hello.php:/app/hello.php \
php:7 \
php /app/hello.php

php 컨테이너에서 /app 하위에 hello.php 파일을 mapping 시키고, 실행시키고자 하는 service의 버전을 지정한 뒤에 바로 php 명령을 사용해서 mapping시킨 컨테이너 내의 php 파일을 실행시킬 수 있다.

Read more