Docker Lab #1

반영환·2023년 6월 12일
0

Docker

목록 보기
10/18
post-thumbnail

Docker Lab week 1

Linux 커널 환경 설정

Docker는 Linux 커널을 조작하기 때문에 Linux 기반 Host OS 위에서 기동된다.
실습에서는 Ubuntu OS 22.04.2 LTS version 을 사용했다.

user 계정

도커를 사용할 때에는 root 계정 말고 일반 계정을 사용하고 권한을 부여하자.

adduser [userID] # 아이디 생성
# 비밀번호 설정하고 생성 프로세스 진행

usermod -aG docker [userID] # docker 명령어 사용 권한 append
usermod -aG sudo [userID] # sudo 명령어 사용 권한 append

su - [userID] # userID로 switch user
su -          # root 계정으로 switch user

Docker 설치

인터넷 환경

Install Docker Engine on Ubuntu - apt package use

설치할 때에도 LATEST라고 단순 명시하지 말고 정확한 버전을 설계단계에서 팀 단위로 설정해서 진행하자.

private 환경

Install Docker Engine from binaries

실무에서 사용할 때에는 외부 네트워크와 연결되지 않은 서버가 많을 것이다.
따라서 바이너리 파일로 프로그램을 다운 받는 것을 연습해보자.

Docker 기동 개요

설치 직후 상태

Docker가 설치 될 서버를 호스트 서버 라고 하자.

  • 호스트 서버의 Host OS ( ubuntu )위에 Docker Daemon이 설치된다.

  • 호스트 서버의 /var/lib 하위에 docker 관련 폴더가 생성되고 Docker bridge 가 운영에 들어간다.

  • Docker bridge는 컨테이너가 생성될 때 할당되는 IP들을 관리하는 bridge이다. docker0 라고 하며 ip mapping은 iptables에서 관리된다.

    iptables -t nat -L -n 
  • Docker Daemon에 접근하는 방법은 원격 서버 VM동일 서버 VM이 있다.

  • 원격 서버 VMhttp/https 프로토콜을 통해 호스트 서버에 접근한다. 이 방식은 중간에 해킹당할 위험이 높고, 실제로 자주 해킹당한다고 하셨다.

  • 동일 서버 VM은 직접 서버에 접근하기에 ssh 프로토콜을 사용한다.

이미지 / 컨테이너 실행


초기 상태에서는 어떤 이미지 파일도 가지고 있지 않기 때문에 컨테이너를 구동시킬 수 없다.
따라서 public docker repository인 docker hub 에서 이미지 파일을 pull 해서 가져온다.

sudo docker search nginx # image file search at docker hub

sudo docker pull nginx # pull image from docker hub

sudo docker images # show all pulled images


이미지 파일을 기반으로 컨테이너를 생성후 구동시킨다.
이때 컨테이너의 ip는 sequential increase 하게 할당된다.

docker run -p 8080:80 -d nginx # p options => #외부(HOST)Port:#내부(Container)Port

iptables -t nat -L -n # docker0에 할당된 IP Mapping 확인

Data Mount

호스트 서버에서 운영중인 컨테이너들은 개개인의 DB를 구동할 수도 있겠지만 보통은 MySQL 컨테이너를 독립적으로 운영한다. 다만 이 때 DB 컨테이너가 비정상종료 될 때 내부의 데이터는 복구 불가능이기 때문에 데이터를 안전한 저장소에 마운트 해놔야한다.

  • 도커 컨테이너는 프로세스 격리 기술이지 비정상 종료를 막는 고가용성을 보장하는 기술이 아니다.
  • 도커 데몬을 실행하는 서버의 특정 경로에 컨테이너의 DB와 서버의 DB를 마운트 시킨다.
  • DB 컨테이어는 장애가 발생시 복구하지 않고 새로 띄운다.

Stateless

컨테이너 아키텍처의 가장 큰 특성은 scale out이 자유롭다는 점.
이를 위해 각 컨테이너들은 stateless하게 관리돼야 한다.

그래서 redis를 띄워서 캐시를 관리하는 컨테이너를 따로 분리시킨다.

Docker Info

docker Storage

Storage Driver : overlay2
Backing Filesystem : extfs
Supports d_type : true
Using metacopy : false
Native Overlay Diff : true
userxattr : false

Docker Storage Drivers

도커가 지원하는 파일 시스템 드라이버 종류들이다.
도커가 네이티브 수준으로 빠른 가상화를 지원할 수 있는 이유는 네트워크스토리지 이기 때문에 해당 스펙을 지켜주자

file system

인프라를 설계할 때 각 컨테이너의 파일 시스템을 분리해주자.
Chroot linux 명령어를 통해 분리할 수 있다.

root path 는 사용하면 안된다.

  • svc : 소스 코드

  • logs : 로그 파일 ( 로그 파일을 언제까지 유지할 것인가, 등등을 고려해야한다.)

  • data : db 데이터가 올라가는 경로

위 세 가지 정도는 디스크를 logical volume으로 분리 시키자. 그래야 후에 백업을 진행할 때 편리하다.

Docker Root Dir 변경 방법

Docker Daemon Configuration overview

vi /etc/docker/daemon.json

	{
	  "data-root": "/mnt/docker-data"
	}

sudo systemctl stop docker
sudo systemctl restart docker

plugins

Volume : local
Network : bridge host ipvlan macvlan null overlay
Log : awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog

Network - bridge : docker0 ( docker bridge ) 사용
Network - overlay : VxLAN 사용, 도커에서 자체적으로 제공하는 컨테이너 오케스트라 서비스인 swarm 이 active 상태일 때 ( default : inactive ) 사용된다.

Underlying Tech.

Chroot ( Change Root Directory )


각 프로세스마다 파일 시스템의 root를 분리시켜야한다.

Cgroup ( Control Groups )

자원에 대한 제어를 가능하게 해주는 리눅스 커널의 기능이다.

실무에서 쓰이는 것은 Memory, Bikio, CPU 정도라고 한다.

Namespace

Chroot와 비슷하지만 파일 시스템이 아닌 Mount, PID, Network, IPC, Hostname, UID를 분리시켜준다.

Images

Image

이미지는 Read Only이다. Writable한 영역은 오직 Container !

도커 이미지 파일을 삭제할 때에는 Copy On Write로 관리되기 때문에 이미지 파일은 최대한 read만 해야하고 컨테이너의 이미지들은 최소한의 가장 필요한 것들로만 구성해야 한다.

그렇지 않으면 성능이 저하된다. 따라서 Base Image의 변경은 지양하고, 변경 사항은 Volume을 통해 관리하자.

alpine?
컨테이너 전용 리눅스 파일로 경량화 파일이다. alpine-slim은 더 경량화 된 것!

Docker file

docker file은 이미지 배포용 파일이다.

FROM : Base Image 지정 명령
RUN : 명령어 실행용
COPY : 호스트 파일을 이미지 경로에 복사
EXPOSE : 포트 설정 문서화 -> 실제 포트 설정은 docker run -p 옵션으로 시행
CMD ["command1", "command2"] : 이미지 내부에 기록돼, 이미지가 가동되면 [] 내부의 명령어가 컨테이너 내부에서 실행된다.

Docker file의 각 명령 라인마다 독립적으로 Image가 생성된다.
명령어가 8줄이면 8개의 독립적인 이미지 레이어가 생성되는 것.

도커 파일의 변동이 생길 때, 바뀌지 않은 이미지 파일에 대해서는 캐싱 처리를 해서 빠른 빌드가 가능하다. ( 자원의 절약 )

이모저모

Container IP 변동

컨테이너 IP는 때때로 바뀐다.
이때 바뀐 IP에 대해 컨테이너와 매핑해주어야 하는데 alias를 지정해서 매핑을 도와준다.

다만 단순히 hosts 파일에서 ip/domain을 계속 업데이트 해주는 것인데 DNS만큼 안전하지는 않다.

K8S는 DNS를 자체적으로 제공해준다.

DB 패스워드 암호화

application.yml 파일에 때려 넣을 때 어떻게 암호화 시켜서 넘길지 고민해야 한다.

컨테이너 컨슘 메모리

컨테이너를 운용할 때 메모리 사용에 있어 상한을 걸어주어야 한다.
프로젝트를 진행하며 어플리케이션을 올릴 때 부하테스트를 반드시 진행해서 상한을 정해주어야 한다.

컨테이너에 OS를 올린다면?

VM과 Docker의 가장 큰 차이는 Guest OS의 차이일 것이다.

그렇다면 OS가 컨테이너에 올라간다면? 이는 VM과 Docker의 사용성이 같아지는 것인가?

결론은 컨테이너에 올린 OS는 독립된 커널을 사용하는 것이 아니라 HOST OS의 커널을 공유한다. 따라서 VM 환경에서 사용되는 GuestOS의 부하 문제와 동일시 될 순 없다.

최근 서버 점검을 경험하지 못하는 이유

앱을 배포하는데 모놀리딕으로 진행하는데 새로운 버전에서 버튼 위치만 변경됐어도 전체를 빌드해서 배포해야 한다. 실시간 배포가 어렵다!

하지만 도커를 쓰면 변경된 레이어만 실제로 배포가 되기 때문에 네트워크 트래픽 양도 줄고, 속도도 빠르기에 실시간 배포가 가능하다.

따라서 도커를 쓸 때 DockerFile을 만들면서 부모 레이어를 잘 나누어주어야 정말 도커를 잘 쓴다고 할 수 있는 것이다.

profile
최고의 오늘을 꿈꾸는 개발자

0개의 댓글