[TIL] 22.04.25

도커

도커는 공부할게 참 많은 분야인 것 같다. 기본 개념은 간단하면서도 똑똑한 사람들이 그걸 기반으로 이것저것 만들어내서 꽤나 복잡해졌다. 오늘 배운 내용을 기반으로 도커를 완벽히 정리해보자.

docker 전반(시리즈)
docker-compose

도커 용어 정리(이미지, 컨테이너)

이미지

  • 서비스 운영에 필요한 OS, 서버 프로그램, 소스코드, 설정 파일 등 필요한 모든 파일들을 묶는 형태, ISO와 동일
  • Immutable한 상태
  • Dockerhub을 통해 공유되는 것들이 이미지
  • Dockerhub에서 pull하면 이미지를 받아올 수 있고, push하면 이미지를 버전 관리하여 올릴 수 있음
  • Dockerfile에 적어놓은 대로 이미지를 생성/빌드(Dockerfile : 이미지 제작 레시피)

컨테이너

  • 이미지를 실행시킨 상태, VM와 동일
  • 당연히 컨테이너 상에서 작업한 내용은 이미지랑 상관이 없음

Dockerfile, docker-compose.yml 내용 정리

Dockerfile

1
2
FROM ubuntu:20.04  => 새로운 이미지의 기반이 될 이미지(base 이미지)
ENTRYPOINT ["echo", "hello"] => 컨테이너를 시작할 때 실행할 명령어

Dockerfile로 이미지 빌드

1
2
$ docker build --tag myimage:1.0 . # 현재 디렉토리(Dockerfile 있는)에 myimage라는 이름으로 도커 이미지를 생성/빌드
$ docker images # 내 컴퓨터에 갖고 있는(어디서 받아왔거나 내가 만들었거나) 이미지 목록 출력

생성된 이미지로 컨테이너 생성, 실행

1
2
3
4
5
6
7
8
9
10
11
12
13
$ docker create & docker start # 이미지로부터 컨테이너 생성 & 컨테이너 시작 == run
$ docker run --rm myimage:1.0 # run 명령어는 이미지를 기반으로 컨테이너를 생성 후 실행하는 명령어, --rm : 컨테이너 종료될 때 컨테이너 자동 삭제
$ docker run -d --name web -p 8080:80 -e MYSQL_PASS=root nginx:latest # -d : 백그라운드 실행, --name : 컨테이너 이름 지정, -e : 환경변수 전달
$ docker container ls # 실행중인 컨테이너 목록
$ docker ps # 실행중인 컨테이너 목록
$ docker ps -a # 모든 컨테이너 목록(실행 중 아니어도)
$ docker stop web(or ID) # 컨테이너 실행 중지
$ docker rm web # 컨테이너 삭제
$ docker exec -it web /bin/bash # 실행 중인 컨테이너에 bash로 접속
$ docker run -d --name web --rm \
> --mount type=bind,src=/home/vagrant/html,dst=/usr/share/nginx/html \ # mount : 로컬 디렉토리와 컨테이너 디렉토리를 연결
> -p 8080:80 \
> nginx:latest

Dockerfile 예제 - 2

1
2
3
4
5
6
7
8
9
10
#!/bin/sh
# entrypoint.sh => 스프링 어플리케이션을 실행시키기 위한 스크립트

ACTIVE_PROFILE="${PROFILE:-dev}"

echo "ACTIVE_PROFILE=${ACTIVE_PROFILE}"

exec java -Djava.security.egd=file:/dev/./urandom \
-Dspring.profiles.active=${ACTIVE_PROFILE} \
-jar hello.jar
1
2
3
4
5
6
7
8
9
10
11
FROM openjdk:8-jdk-alpine => 이미지를 받아와서
RUN apk --no-cache add tzdata && cp /usr/share/zoneinfo/Asia/Seoul /etc/localtime => 실행할 명령어 1(패키지 설치)

WORKDIR /app => 작업 디렉토리 지정(없으면 새로 생성)
COPY hello.jar hello.jar => Dockerfile 있는 디렉토리에 있는 파일을 이미지로 복사
COPY entrypoint.sh run.sh => Dockerfile 있는 디렉토리에 있는 파일을 이미지로 복사 2(다른 이름으로 저장)
RUN chmod 774 run.sh => 실행할 명령어 2(sh 파일 실행권한)

ENV PROFILE=local => 이미지에서 사용할 환경변수 값 지정, 여기까지 이미지 빌드 내용

ENTRYPOINT ["./run.sh"] => 이 이미지로 컨테이너를 생성할 때 실행할 명령어
1
2
$ docker build --tag myspring:1.0 .
$ docker run -rm -p 80:9090 myspring:1.0 => host 포트 : 컨테이터 포트 매칭

도커 볼륨

  • mount의 bind와 달리 도커에서 직접 관리하는 파일 시스템
  • 여러 컨테이너에서 공유 가능
1
2
3
4
5
6
$ docker vulume create --driver local myvol # --drivder : 볼륨 생성시 사용할 스토리지 드라이버
$ docker run -d --name web --rm \
> --mount type=volume,src=myvol,dst=/usr/share/nginx/html \ # 도커 볼륨과 컨테이너 디렉토리를 연결
> -p 8080:80 \
> nginx:latest
$ docker volume prune # 사용 중이지 않은 볼륨 모두 삭제

도커 네트워크

1
$ docker network ls # 도커가 제공 중인 네트워크 목록

docker-compose.yml

  • 도커 명령어를 yml 파일로 관리해서 좀 더 간단하게 만들기 위해 사용(각종 옵션 너무 길어짐..)
  • 특히 여러 도커 컨테이너끼리 연동시켜야 하는 경우(여러 컨테이너 사용하는 경우) 더 효과적임
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
version: '3'

volumes:
postgres_data: {}

services:
db:
image: postgres
volumes:
- postgres_data:/var/lib/postgres/data
environment:
- POSTGRES_DB=djangosample
- POSTGRES_USER=sampleuser
- POSTGRES_PASSWORD=samplesecret

django:
build:
context: .
dockerfile: ./compose/django/Dockerfile-dev
volumes:
- ./:/app/
command: ["./manage.py", "runserver", "0:8000"]
environment:
- DJANGO_DB_HOST=db
depends_on:
- db
restart: always
ports:
- 8000:8000

docker-compose.yml로 하면 이렇게 간단한 것이

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# network 생성
$ docker network create --driver bridge web-service

# 해당 network를 활용하여 컨테이너 실행
$ docker run --rm -d --name postgres \
--network web-service \
-e POSTGRES_DB=djangosample \
-e POSTGRES_USER=sampleuser \
-e POSTGRES_PASSWORD=samplesecret \
postgres

$ docker run -d --rm --name django1 \
--network web-service \
-p 8000:8000 \
-e DJANGO_DB_HOST=db \
--link postgres:db \
django-sample

명령어로 일일이 구현하려면 이렇게 귀찮아진다.

1
2
3
4
5
6
$ docker compose up -d # (컨테이너들 실행)
$ docker compose up --build # (이미지 빌드 후 실행)
$ docker compose down # (컨테이너들 종료, 삭제)
$ docker compose start # (정지했던 컨테이너 다시 시작)
$ docker compose start postgres # (정지했던 컨테이너 다시 시작)
$ docker compose restart # (이미 실행 중인 컨테이너 다시 시작)

도커 응용 체계 정리

도커 스웜

클러스트 환경에서 서비스 관리

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
version: "3.6"
services: # 서비스 목록
web: # 서비스 이름
image: madvirus/simplenode:0.1
ports:
- "5000:5000"
deploy:
mode: replicated
replicas: 2 # 2개로 복사
update_config:
parallelism: 1
order: start-first
delay: 10s
failure_action: rollback
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
interval: 10s
timeout: 5s
retries: 3
start_period: 10s
1
$ docker stack deploy -c docker-compose.yml simple # simple_default 네트워크 생성, 서비스 생성(도커 스웜은 클러스트 기반으로 여러 컨테이너를 구동시키므로 네트워크 생성이 기본)

paramiko

python으로 ssh 접속

paramiko

bash, zsh, 터미널 꾸미기

쉘, bash, zsh

콘솔 vs 터미널 vs 쉘

  • 콘솔 : 서버의 로컬 장치에서 직접 명령어를 작성할 수 있는 입출력 장치(물리 장치 개념)
  • 터미널 : 로컬 + 원격으로 접속할 수 있는 콘솔을 구현한 SW(SW 개념)
  • 쉘 : 터미널과 사용자 사이에서 명령어를 입력받아 전달해주는 프로그램 => 우리가 직접적으로 만나는 친구!

쉘의 종류

  • sh : Stephan Bourne…
  • csh : C Shell
  • tcsh : /bin/tcsh
  • zsh : /bin/zsh
  • bash : /bin/bash
1
$ echo $SHELL

alias

  • 명령어 설정
1
$ alias ll='ls -alGh'

oh-my-zsh

  • zsh 꾸미기 위한 도구

SSH 키 관리

SSH 키 개념

  • 공개키 알고리즘 기반
  • 공개키(pub) : 서버에 저장
    • ~/.ssh/authorized_keys에 추가
      • $ echo [public_key_string(cat id_rsa.pub)] >> ~/.ssh/authorized_keys
  • 개인키(priv) : 클라이언트가 보관, 사용
    • SSH 키 쌍은 클라이언트가 자기 컴퓨터에서 생성
      • $ ssh-keygen
        • id_rsa(개인키), id_rsa.pub(공개키)

키는 비밀번호랑 상관 없음!!

SSH 키 생성, 저장, 활용 명령어

1
2
3
4
5
6
7
8
9
# 클라이언트(내 컴퓨터)에서 키 생성
$ ssh-keygen
...
$ ls ~/.ssh
id_rsa id_rsa.pub # 키 생성 완료!

# 서버에다 id_rsa.pub 파일 업로드하고 시작
$ echo "$(cat id_rsa.pub)" >> ~/.ssh/authorized_keys
$ done!

Github 키 관리

Personal Access Token

Github Personal Access Token으로 로그인

Author

TaeBbong Kwon

Posted on

2021-04-18

Updated on

2022-08-06

Licensed under

Comments