Docker & K8s 스터디 요약 자료
한정된 리소스를 논리적으로 나눠서 효율적으로 사용하고자 하는 니즈가 있었음.
1964년 IBM에서 system/360을 출시.
-> 멀티 태스킹이 가능해짐
-> 신뢰성을 이유로 제대로 활용을 못함.
가상화의 등장
-> 하나의 물리 서버에서 여러 가지 서비스를 독립적으로 운영 가능해짐
cpu 스케줄링
-> CPU 이용률, 처리 시간, 대기 시간.. 등등을 고려하여 스케줄링을 함
-> Load balancing vs Processor Affinity
프로세서에 균등하게 일을 분배 vs 균등하게 분배는 안되지만 캐싱 메모리 활용 가능
물리 머신 - host os - hypervisor - guestos - 어플피케이션
까지의 단계를 거치기 때문아래 리눅스 자체 기능을 이용해서 프로세스 단위의 격리 환경을 만듦.
chroot
: 프로세스의 루트 디렉터리를 변경하는 리눅스 시스템콜/명령어cgroups
: 프로세스들의 자원의 사용(CPU, 메모리, 디스크 입출력, 네트워크 등)을 제한하고 격리시키는 리눅스 커널 기능namespace
:동일한 시스템에서 별개의 독립된 공간을 격리된 환경에서 운영하는 가상화 기술Hierarchy 기반으로 자원을 묶어줌.
CPU, MEM 등의 자원을 그룹별로 몇%씩 사용할지 지정할 수 있음.
- Docker를 사용해야 하는 이유?
가볍다~ 배포가 편하다? 그것도 맞지만 이미지가 가장 큰 이점.
아래 02 도커엔진 - 이미지 에서 자세히 보자.
$ df -h
$ sudo fdisk -l
$ sudo fdisk /dev/sdb
$ sudo mkfs.ext4 /dev/sdb1
$ sudo mkdir -p /mnt/storage
$ sudo e2label /dev/sdb1 node_disk
$ sudo blkid
$ sudo vi /etc/fstab
$ cat /ect/fstab
LABEL=cloudimg-rootfs / ext4 discard,errors=remount-ro 0 1
LABEL=UEFI /boot/efi vfat umask=0077 0 1
LABEL=node_disk /mnt/storage ext3 default 0 0
$ sudo mount -a
$ df -h
$ sudo chmod 777 /mnt/storage
$ mkdir -p /mnt/storage/docker
$ mkdir -p /mnt/storage/containerd
$ sudo apt-get update
$ sudo apt-get install ca-certificates curl gnupg
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg
$ echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
$ sudo vi /etc/docker/daemon.json
{
"data-root": "/mnt/storage/docker",
"storage-driver": "overlay2"
}
$ sudo mkdir -p /etc/systemd/system/docker.service.d
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
$ systemctl status docker
아래 경로에 잘 쌓이고 있으면 정상
$ sudo ls /mnt/storage/docker/
buildkit containers engine-id image network overlay2 plugins runtimes swarm tmp volumes
pull
: 허브에서 이미지 다운받음create
: 컨테이너 생성start
: 컨테이너 실행attach
: 컨테이너 접속run
== pull
- create
- start
- attach
-i -t
: 상호 입출력을 가능하게 하는 옵션-d
: 입출력 xstop
: 컨테이너 정지rm
: 컨테이너 삭제container prune
: 컨테이너 전부 삭제 $ sudo docker run -i -t ubuntu:18.04
Status: Downloaded newer image for ubuntu:18.04
root@0c1c667dd261:/# --> container id 12자리
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0c1c667dd261 ubuntu:18.04 "/bin/bash" 5 minutes ago Exited (130) 4 seconds ago wonderful_clarke
$ sudo docker inspect wonderful_clarke
$ sudo docker pull centos:7
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 3941d3b032a8 5 weeks ago 63.1MB
centos 7 eeb6ee3f44bd 19 months ago 204MB
$ sudo docker inspect centos:7
$ sudo docker create -it --name mydocker centos:7
b8dafdf26aecadc3e1ec5ab8cff0b5991c781d2792ea0a76880242c03f89fbd6
$ sudo docker start mydocker
$ sudo docker attach mydocker # 컨테이너 접속
[root@b8dafdf26aec /]# --> ^Q 입력 --> 컨테이너 종료하지 않고 접속만 해제
alicek106/ubuntu:22:04
== 저장소/이미지이름:태그
container layer
라 부르기도 함.투명하다?
: 유저가 내부적인 상세 로직을 몰라도 사용하는 데 어려움이 없다는 뜻이미지, 컨테이너
도커 이미지로 컨테이너를 생성하면 이미지는 읽기 전용이 되고
컨테이너의 변경사항만 별도 저장하여 각 컨테이너 정보를 보전한다.
이미지에는 mysql 실행하는 데 필요한 애플리페이션 파일
컨테이너에는 워드프레스에서 쓰는 게시글 등 db운용하면서 쌓이는 데이터
컨테이너 레이어의 단점.
-> 컨테이너 데이터를 영속적으로 관리하기 위한 방법으로 볼륨을 활용해볼 수 있음.
볼륨 활용하기
호스트와 볼륨 공유
$ sudo docker run -d \
--name wordpressdb_hostvolume \
-e MYSQL_ROOT_PASSWORD=password \
-e MYSQL_DATABASE=wordpress \
-v ~/wordpress_db:/var/lib/mysql \ # [호스트 공유 디렉토리]:[컨테이너 공유 디렉토리]
mysql:5.7
~/wordpress_db:/var/lib/mysql 이 둘은 동기화 되는 개념이 아니라 그냥 같은 디렉토리임.
-v
옵션으로 볼륨을 사용하는 다른 컨테이너와 볼륨을 공유
docker volume
명령어
인터페이스 종류
eth0
: 공인 or 내부 ip가 할당되어 실제로 외부와 통신할 수 있는 호스트의 네트워크 인터페이스veth~
: 각 컨테이너의 eth0과 연결.docker0
: 각 veth 인터페이스와 바인딩돼 호스트의 eth0과 연결.LDCC@instance-node-1:~$ ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:20ff:feb1:9b78 prefixlen 64 scopeid 0x20<link>
...
ens4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1460
inet 10.178.0.5 netmask 255.255.255.255 broadcast 0.0.0.0
...
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
...
veth2d31241: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::34b2:8ff:fedb:d897 prefixlen 64 scopeid 0x20<link>
...
vethd7140a9: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::1879:46ff:fe19:5dd8 prefixlen 64 scopeid 0x20<link>
...
드라이버 종류
# 이미지 생성
$ docker run -it --name --name commit_container1 ubuntu:14.04
$ docker commit commit_container1 my-ubuntu:0.0
# docker hub에 업로드하기 위해 이미지 태그 추가
$ docker tag my-ubuntu:0.0 dchecheb/my-ubuntu:0.0
$ docker tag my-ubuntu:0.0 asia-northeast3-docker.pkg.dev/${PROJECT_ID}/mygcr/my-ubuntu:0.0
FROM ubuntu:14.04
LABEL maintainer "geoffyoon <geofff.yoon@gmail.com>"
LABEL "purpose"="practice"
RUN apt-get update
RUN apt-get install apache2 -y
ADD lotto.html /var/www/html
WORKDIR /var/www/html
RUN ["/bin/bash","-c","echo hello >> test.html"]
EXPOSE 80
CMD apachectl -DFOREGROUND
FROM
: 생성할 이미지의 베이스 이미지LABEL
: 이미지의 메타데이터를 추가, 키-벨류 형태로 저장RUN
: 이미지를 만들기 위해 컨테이너 내부에서 명령어를 실행ADD
: 파일을 이미지에 추가. WORKDIR
: 명령어를 실행할 디렉토리 == cd
EXPOSE
: 노출할 포트 지정. 바인딩은 XCMD
: 컨테이너가 시작할 때 실행할 명령어 설정이미지 용량을 줄여서 빌드 & 배포하기 위해 사용함.
하나의 Docker File 안에 여러 개의 FROM 이미지를 정의함으로써 빌드 완료 시 최종적으로 생성될 이미지 크기를 줄임.
FROM golang
ADD main.go /root
WORKDIR /root
RUN go build -o /root/mainApp /root/main.go
FROM alpine:latest
WORKDIR /root
COPY --from=0 /root/mainApp .
CMD ["./mainApp"]
아래 명령 2번을
$ docker run -d --name mysql \
alicek106/composetest:mysql \
mysqld
$ docker run -d -p 80:80 \
--link mysql:db --name web \
alicek106/composetest:web \
apachectl -DFOREGROUND
컴포즈로 하나로 묶을 수 있음.
version: '3.0' -- 파일 포멧 버전(1.2, 2.1, 3.0 ...)
services: -- 생성될 컨테이너들을 묶어 놓은 단위
web: -- 생성될 서비스 이름
image: alicek106/composetest:web -- 컨테이너 생성할 때 쓰일 이미지 이름 설정
ports:
- "80:80"
links: -- 다른 서비스의 컨테이너에 대한 네트워크 링크를 정의
- mysql:db
command: apachectl -DFOREGROUND
mysql: -- 생성될 서비스 이름
image: alicek106/composetest:mysql
command: mysqld
$ docker compose up -d
$ docker compose ps # 생성된 컨테이너 확인
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
first_compose-mysql-1 alicek106/composetest:mysql "mysqld" mysql About a minute ago Up 59 second
컨테이너 이름:
[프로젝트명]-[서비스명]-[서비스 내에서의 컨테이너 번호]
= first_compose-mysql-1
$ docker compose up --scale mysql=3 -d # 같은 서비스에 컨테이너를 3개까지 늘림
$ docker compose down # 프로젝트 삭제
$ docker compose -p myproject up -d # 같은 yaml로 프로젝트 여러 개 생성 가능
$ docker compose -p myproject down # 프로젝트 이름 지정해서 삭제
도커의 구조는 아래 2가지로 나뉜다.
dockerd
프로세스로 동작