클라우드 컴퓨팅/인프라 기초

[24.07.04] 인프라 기초 4 Docker와 컨테이너, 레지스트리

우잉~ 2024. 7. 4. 19:42

인프라 기초 3 복습

 

1,2일차

인프라를 관리하기 위해서 커널을 사용하는데

커널은 운영체제에 포함되어 있음 

우리는 리눅스라는 운영체제를 사용하고 rocky를 이용하여 실습하였다.

 

3일차

프로세스를 관리하기 위해 systemd를 사용한다.

명령어는 systemstl을 사용. 프로세스를 시작하려면 start, 종료하려면 stop 등의 명령어를 사용하여 다룬다.

스토리지 구성.

디스크를 새로 추가해서 디스크 파티셔닝을 진행했다.

파티션이 나뉜 디스크를 특정 디렉터리에 연결(mount)하여 사용해보았다.

표준입출력과 파이프라인도 살펴보았다.

표준 출력으로 파일 생성 및 변경, 추가가 가능하고 에러 또한 파일로 저장할 수 있다.

표준 입출력에서는 채널이라는 개념이 존재하는데, 표준 에러 출력은 2번 채널을 이용하고 있으며 표준 에러 출력을 이용할 때는 채널을 꼭 명시해야 한다. ex. ls -l 2>error.log


 

컨테이너

 

컨테이너란 개념을 알기 위해서는 애플리케이션에 대한 개념이 있어야 한다.

 

애플리케이션

개발자가 개발한 소스 코드드가 동작할 수 있는 실행 환경에 설치하여 동작하는 것.

이 실행 환경을 런타임이라고 한다.

런타임은 라이브러리 및 바이너리, 프레임워크 등을 포함한다.

 

가상화

인프라 자원을 효율적으로 사용할 수 있게 도와준다.

클라우드 환경을 지원한다.

 

가상화를 구분하는 방법 2가지

- Virtualizaton: 서버 가상화, 데스크탑 가상화. 컴퓨터를 가상으로 만들어준다. OS가 포함되어 있음.

- Containerization:  종속성과 같은 필수 요소를 패키징하여 컨테이너로 분리하는 것. 호스트가 집적적으로 이용하여 애플리케이션을 실행한다.

 

* 하이퍼바이저: 여러 가상 머신을 실행할 수 있도록 도와주는 가상 머신 관리 프로그램.

VMware ESX-i

Window Hyper-V

Opensource ZEN / KVM(커널 기반 가상 머신)

 

컨테이너란?

- 실행에 필요한 모든 종속성을 포함하여 패키징하고 격리하는 기술이다.

 

컨테이너 이미지

- 처음부터 모든 것(바이너리, 라이브러리 등)을 구성된 파일을 기반으로 실행하게 된다.

빠르게 프로비저닝이 가능하다! 이미지를 잘 만들어 놓으면 어디서든지 신속하게 배포할 수 있음.

 

* OCI(Open Container Initiative)

- 이미지 표준 규격, 컨테이너 표준 규격을 정의하는 명세서

 


docker 명령어

컨테이너 목록 출력

> docker ps -a

현재 생성되어 있는 컨테이너의 목록을 출력한다.

현재 생성되어 있는 컨테이너 없음

 

도커 정보 출력

> docker version

도커 정보를 확인할 수 있다.

도커는 client-server 통신을 하고 있다.

docker version

 

서버의 역할은 도커의 데몬

도커는 기본적으로 로컬 호스트를 사용한다.

 

레지스트리란?

이미지를 저장하는 저장소. docker pull 명령을 통해 이미지를 다운로드 할 수 있고, push로 이미지를 업로드할 수도 있다.

private, public 레지스트리를 제공하며, public 레지스트리는 공개되어 있어 누구든지 레지스트리에 접근하여 다운로드할 수 있다.

private registry는 나를 포함해서 권한을 부여받은 사용자만 접근할 수 있다.

=> dockerhub(hub.docker.com), quay(quay.io)

dockerhub에는 검증된 official image도 많이 업로드되어 있다.

ex. nginx, mysql 등

 

 

이미지 검색

> docker search [이미지 이름]

dockerhub에 업로드된 이미지 목록 출력

다른 레지스트리에서 검색하고 싶으면?

레지스트리 url을 입력해준다.

quay.io에 업로드된 nginx 이미지 목록 출력

 

레지스트리에 있는 이미지 다운로드

> docker pull url or 이미지 이름

디폴트로 가장 최신 버전인 latest가 다운로드 된다.

레지스트리 위치 명시하여 이미지 다운로드

디폴트 레지스트리는 docker.io이다.

 

레지스트리 위치 docker.io/library/nginx:latest

 

 

이미지를 이용한 컨테이너 실행

> docker run [이미지 이름]

-d 옵션을 붙여 deteched mode로 실행하여 컨테이너를 백그라운드로 실행하는 것이 편리하다.

-- name은 컨테이너의 이름을 지정해준다. 지정하지 않을 경우는 랜덤으로 부여됨.

--rm 옵션: 컨테이너가 종료될 때 컨테이너를 삭제하는 옵션. 옵션을 사용하지 않을 경우 컨테이너는 중단될 뿐이다.

컨테이너 실행
deteched mode와 컨테이너 이름 부여

 

도커 이미지의 목록

> docker images

이미지 목록 출력

 

 

컨테이너 목록 확인

> docker ps

옵션 없이 사용하면 실행 중인 컨테이너 목록이 출력되고,

실행 종료된 컨테이너를 확인하고 싶으면 -a 옵션을 사용한다.

모든 컨테이너 목록 확인

 

컨테이너 삭제

> docker rm [컨테이너 이름] or [컨테이너 ID]

컨테이너 삭제

* 컨테이너가 실행되고 있을 경우, 삭제가 불가능하다.

실행 중인 컨테이너 삭제 명령 결과

그래도 삭제하고 싶다면?

-f 옵션 이용하여 강제로 삭제한다.

* docker rm -f > docker kill + docker rm ==> 프로세스를 강제로 종료하고 컨테이너 삭제

실행 중인 컨테이너 강제 삭제 결과

 

실행 중인 컨테이너에 명령어 전달하여 추가 프로세스 실행

> docker exec

 

* 컨테이너 내부에 명령을 내리기 위해서 input, output을 사용할 수 있는 -i(interactive), -t(tty) 옵션을 사용하여 web 컨테이너에 bash 쉘을 사용할 수 있다.

> docker exec -it web bash

bash shell 사용

* run과 exec의 차이점?

- run은 메인 프로세스 실행. exec는 이미 실행된 컨테이너에서 다른 프로세스를 실행하는 것이다.

* run : pull + create + start ==> 이미지를 다운 받고 생성한 뒤, 이 이미지를 실행하는 컨테이너를 실행

 

이미지 삭제

> docker rmi [이미지 이름]:[버전]

최신 버전인 latest일 경우 명시안 해도 된다.

nginx 이미지 삭제 결과

 

이미지 이름이 너무 길어서 불편할 때 tag 명령을 이용해 새롭게 이름을 붙이기

> docker tag [이미지 이름] [변경할 이름]

tag 명령을 이용하여 이미지 이름 변경

* 여기서 기존에 있던 이미지의 이름이 바뀌지 않는다는 것을 알아야 한다. web이라는 새로운 이름의 이미지가 생성된다.

그럼 web과 quay.io/uvelyster/nginx와 다른 이미지일까?

다른 이미지가 아니다. 둘은 같은 이미지다. 동일한 이미지 ID를 가지고 있기 때문에 둘은 동일한 이미지를 참조한다.

즉, 두 이미지의 메모리는 같은 곳에 적재되어 있다.

 

로그 추적

> docker logs [컨테이너 이름]

컨테이너의 로그를 확인할 수 있다.

-f(follow) 옵션을 사용하면 실시간으로 로그를 추적할 수 있다.

 

 

 

컨테이너 정보 확인

> docker inspect [컨테이너 이름]

이곳에서 ip address도 확인할 수 있다.

inspect 명령어 사용 결과

 

 

docker 네트워크

- SDN(Software Define Network)라는 가상 네트워크를 사용하여 컨테이너 통신을 관리한다.

> docker network

ls 명령으로 네트워크 목록 출력

 

bridge라는 이름을 가진 네트워크가 기본 네트워크이다.

그래서 docker run 명령으로 실행된 컨테이너는 모두 bridge 네트워크에 연결된다.

* host 네트워크: 

 

네트워크 정보 확인

> docker network inspect bridge

 

현재 로컬 환경에 구성되어 있는 모습

윈도우 안에 버추얼박스 안에 도커

 

네트워크 설정할 때 각 프로그램에서 사용되고 있는 네트워크는 사전에 알아보고 사용하지 않는 것이 좋다.

 

네트워크 생성

> docker network create [네트워크 이름]

네트워크 생성 및 네트워크 정보 확인

 

 

네트워크 삭제

> docker network rm [네트워크 이름]

네트워크 삭제

 

* DNS(Domain Name Service)

: url에 입력하는 주소(도메인)을 ip로 변환

 

* Service Discovery(서비스 검색): 

 

 

컨테이너에 네트워크 지정

> docker run --network [네트워크 이름]

* 네트워크 지정이 필요 없을 땐 none 사용.

 

* 포트 포워딩(port-forwarding)

port forwarding
2222 포트를 80번 포트로 포워딩
접속 성공

 

* L4와 L7 차이

L4: 포트 기반

L7: 호스트 기반

 

* 도메인 기반 라우팅

auth.testdomain.com -> authentication service

shoppinglist.testdomain.com -> list service

admin.testdomain.com -> admin service

 

* 경로 기반 라우팅

testdomain.com/auth -> authentication service

testdomain.com/shoppinglist -> list service

testdomain.com/admin -> admin service

 

* NBL와 ABL 차이

NLB(Network Load Balancer): L4단의 로드 밸런서. TCP/IP 프로토콜을 참조하며 IP와 Port 확인하여 스위칭한다.

ALB(Application Load Balancer): L7단의 로드 밸런서. HTTP/HTTPS 프로토콜 참조하여 IP와 Port, 그리고 패킷 내용을 확인하여 스위칭한다.

 

 

 

docker volume

컨테이너는 stateless 특성을 가지고 있다.

이게 뭐냐면 컨테이너를 지우면 안에 있는 정보가 다 사라져버린다는 뜻이다...

안에 중요한 데이터를 남겨둔 채로 컨테이너를 삭제해버리면 모든 데이터가 다 삭제되어 복구할 수 없게 된다.

컨테이너를 삭제해도 데이터는 그대로 남겨두고 싶을 때 사용하는 것이 볼륨이다

 

볼륨 생성하기

> docker volume create [볼륨 이름]

 

따로 생성을 해도 되지만, run 명령을 통해 지정하면 자동으로 생성되기 때문에 run 명령어로 생성해보자.

 

> docker run -d -p 3333:80 -v web-vol:/usr/share/nginx/html web

web 이미지를 3333 호스트 포트를 컨테이너 80번으로 포트포워딩 하고, web-vol이라는 이름을 가진 볼륨을 /usr/share/nginx/html에 연결(마운트)하여 구성한다.

볼륨 생성 및 컨테이너 실행

 

inspect로 생성된 볼륨을 확인해보면,

컨테이너 내부가 아니라 로컬에 저장되는 것을 확인할 수 있다.

마운트 경로 확인

 

해당 경로로 들어가면 index.html이 있는 걸 확인할 수 있다.

vi 편집기로 수정하고 접속해보면 변경되어 있는 것을 확인할 수 있다.

파일 편집
변경사항 확인

 

 

 

 

레지스트리

 

가상머신 설정 > 시스템

시스템 탭에서는 메모리를 수정할 수 있다.

기본 메모리 2048 -> 8192 수정

메모리 8192로 변경

 

 

매모리 확인 방법

> free -h

 

메모리 확인

 

레지스트리 실습

demo/install/registry.sh

이 실행 파일을 실행하면 일반 레지스트리가 생성된다.

registry.sh 파일 내용

 

레지스트리에 연결된 도커, 쿠버네티스 등에게 이미지를 전달할 수 있다.

레지스트리를 사용하면 하이브리드 환경을 구축할 수 있다.

클라우드 환경에서는 ECR을 사용하면 될 거 같음

 

레지스트리 실행

> sh registry.sh

* sh 명령어는 쉘 스크립트를 실행하는 명령어임

레지스트리 쉘 스크립트가 실행되면서 docker run 명령어가 실행되고, 레지스트리 서버 컨테이너를 실행한다.

 

레지스트리 서버 컨테이너 실행

 

 

 

/etc/hosts 파일 수정

현재 컨테이너가 레지스트리 서버 컨테이너에 있는 자료를 다운 받기 위해서는 pull 명령과 레지스트리url을 적어야한다.

이 레지스트리 url 즉, 도메인 네임을 적는 것이다.

그런데 시스템에서는 도메인 네임이 아닌 ip 주소를 파악한다.

결국 /etc/hosts 파일은. 서버에 도메인 네임을 통해 ip를 알려주기 위해 작성하는 파일임!!! => 리졸빙

 

* 리졸빙(resolving)

도메인 네임을 입력했을 때 ip 주소를 반환하려고 하는 걸로 리졸브( resolve )라고 함. 

 

리졸브할 때 시스템에서 뒤적거리는 위치 순서

1. 캐시 정보가 있을 경우

2. /etc/hosts 파일

3. /etc/resolv.conf  파일(DNS Server)

4. 상위 DNS. 없으면? 또 상위 DNS. 또 없으면? 상위 DNS ... 최상위 DNS도 없으면 없다고 띄움

레드햇/우분투 계열에서는 /etc/hosts 파일을 우선적으로 참고하게 된다.

 

/etc/hosts 파일에 리졸빙할 도메인 네임과 ip 입력

 

리눅스 시스템이 /etc/hosts 파일에 등록된 내용을 참조하여 myregistry.com이라는 주소가 지정한 ip주소로  리졸빙(대입? ip 주소로 변환되었다라고 생각하면 될 것 같다.)되었다.

그래서 현재 컨테이너 환경에서 통신이 가능하게 되었다.

 

레지스트리에 있는 이미지 빌드(생성)

이미지를 생성할 때는 해당 디렉터리에 있는 Dockerfile에 있는 내용을 참조한다.

Dockerfile에는 이미지를 생성하면서 설정해줘야 하는 종속성, 디렉터리 위치 등이 포함되어 있다.

이 스크립트가 실행되면서 종속성을 가진 이미지가 생성된다.

해당 Dockerfile에는 마지막으로 app.py라는 파이썬 스크립트를 실행하게 된다.

Dockerfile 내용

app.py 파일에는 hello world를 출력하는 간단한 내용의 스크립트가 작성되어 있다.

app.py script

 

도커의 이미지 목록을 출력해보면 myregistry.com/test라는 이름의 이미지가 생성된 것을 확인할 수 있다.

 

이미지 생성

 

생성한 이미지 레지스트리 서버 컨테이너에 push하기

이미지 push 완료

 

레지스트리 서버 컨테이너에 이미지를 집어 넣었기(push) 때문에, 현재 저장된 이미지를 삭제하고 run 명령어를 사용하면, 레지스트리 서버에 존재하는 myregistry.com/test 이미지를 없으면 생성해서, 있으면 있는 이미지를 이용하여 컨테이너를 실행하게 된다.

이미지를 지운 뒤 이미지 실행

 

* 플라스크 포트는 5000이다.

내부 레지스트리를 이용하여 불러온 이미지 컨테이너 실행 결과

 

나중에 따로 해볼 것.

* harber.yml 실습

인증서 생성, http 80, https 443

 

 

 

'클라우드 컴퓨팅 > 인프라 기초' 카테고리의 다른 글

[24.07.03] 인프라 기초 3  (0) 2024.07.03
[24.07.02] 인프라 기초 2  (0) 2024.07.02
[24.07.01] 인프라 기초 1  (0) 2024.07.01