카테고리 없음

[SERVER] - DOCKER Container

Kim David 2024. 9. 10. 21:42

클라우드 네이티브 기술

 

CNCF: Cloud Native Computing Foundation

 
조직이 퍼블릭, 프라이빗, 하이브리드 클라우드와 같은 현대적이고 동적인 환경에서 확장 가능한 애플리케이션을 개발하고 실행할 . 수있게 해주며, 컨테이너 서비스 메쉬, 마이크로 서비스, 불변 인프라, 선언형 API가 이러한 접근 방식의 예시들입니다.
이 클라우드 네이티브 기술은 회복성, 관리 편의성, 가시성을 갖춘 느슨하게 결합된 시스템을 가능하게 해줍니다.
이 견고한 자동화 기능을 통해 엔지니어는 많은 노력이 들어야하는 변경 과정을 최소한의 노력으로 수행할 수 있으며, 이러한 과정을 자주 수행이 가능하게 됩니다.
 
한마디로 표현하자면, 컨테이너 기반으로 애플리케이션을 만들어서 클라우드 환경에서 운영을 해주게 되는데 이러한 방식으로 진행하면 회복성, 관리 편의성, 느슨한 결합으로 인하여 어디든 편하게 올려서 사용할 수 있게되고, 견고한 자동화 기능과 자주 배포할 수 있는 환경까지 제공해주는 것이 클라우드 네이티브 기술입니다.
 
시대적으로 변화하면서 폭포수 모형 -> 애자일 모형 -> Devops(cloud native 기술)로 개발 환경과 인프라 구조가 변화되어 왔습니다.
 

 
 
그림에서 보시는 바와 같이 클라우드 환경에서 > 컨테이너로 만드어진 애플리케이션을 > 마이크로 서비스 아키텍쳐 환경으로 작게 쪼개서 운영하게 되니 > 강력한 자동화 민첩성 생산성을 지원해주는 환경으로 애플리케이션의 운영이 가능하게 되었습니다.
가상 서버를 os 가상화라고 한다면 컨테이너는 애플리케이션 가상화라고 말할 수 있습니다.
 
 

Container(독립된 공간)

- 애플리케이션과 운영 환경이 모두 들어있는 독립된 공간입니다.
- 컨테이너에는 경량의 독립 실행 형 소프트웨어 패키지, 코드, 런타임, 시스템 도구, 시스템 라이브러리 및 설정과 같이 응용 프로그램을 실행하는데 필요한 모든것이 포함되어있습니다.
 
이러한 컨테이너들은 각각 독립적으로 운영됩니다.
 

Container의 동작 원리

 
이 그림에는 크게 client, docker_host(서비스 데몬이 동작되어지는 곳), registry(컨테이너가 저장되어지는 곳)로 나누어져 있습니다.
 
docker host에는 docker demon이 동작되어지고 있습니다. 이 demon에게 명령을 잘 전달해주어야합니다.
client측에서 docker client commander로 docker pull로 image 다운로드 받아달라고 요청하게 되면 docker demon은 독립적인 container가 있는 공간인 registry에서 필요한 container image를 다운로드 받게되고 client측에서 client commander로 docker run 명령어를 전달하게되면 다운로드 받았던 container image를 실행시켜 줍니다. 
docker build를 하게되면 컨테이너 이미지를 빌드 할 수 있고, docker push 하게되면 registry로 업로드 해주는 것 또한 가능합니다.
( 이 동작들에 대해서는 이따 좀 더 세부적으로 직접 실제 public registry인 docker hub에 있는 nginx container와 busybox container을 통하여 실행해보도록 하겠습니다. )
 

docker 의 이슈와 한계점

하지만 이러한 docker는 말씀드렸던대로 demon 형태로 운영되어지는 특징을 가지고 있는데 이로 인하여 몇가지 이슈가 발생합니다.
container의 image, 동작되어지는 container, container들이 동작되어지게 하드웨어에서 사용하고있는 정보(커널에 대한 접근) 이 모든것이 demon에 의하여 운영됩니다.
( 즉, demon이 중지된다면 container와 관련된 애플리케이션 서비스는 하나도 실행을 못시킨다는 말이됩니다 = demon 의존성이 매우 강합니다. )
추가적으로 서비스 자체가 루트가 아니면 동작 시킬 수 없다는 한계를 가지고 있습니다. ( 동작시 루트 권한을 가지고 있어야 합니다. )
 
이러한 한계를 극복하기 위해 맘들어진 엔진들이 있습니다.
엔진중 podman엔진은 container 관리를 위해 docker와 매우 유사하게 만들어진 oci 호환 container 관리 툴입니다. ( 명령어도 docker command와 굉장히 유사합니다. )
이러한 podman은 demon 형태로 운영되지 않기에 독립적으로 container, image, 커널에 access가 가능합니다. ( 루트 권한이 필요하지 않습니다 = rootless 운영이 가능합니다. )
 

container 사용

우선 인스턴스를 생성해주기위해 aws에서 ec2에 들어가 생성해줍니다.

인스턴스 생성시 스토리지에 gp2보다 gp3이 더 비용절감을 수 있기에 8GiB gp3으로 설정 해주었습니다.
 
다음으로는 할당된 public IPv4주소를 이용하여 터미널에서 ssh 접속을 해주겠습니다.
( 윈도우는 XShell을 사용하는 것 같고, 저는 mac을 사용중이니 터미널에서 접속 설정을 해주도록 하겠습니다. )
 
이미 만들어뒀거나 만들어준 키페어를 사용하여 vim config 파일을 수정해줍니다.

( 명령 모드 -> i 눌러 입력 모드로 전환 -> esc 눌러 명령 모드로 전환 -> :wq 입력하여 저장 후 나오기 )
 
다음으로는 키페어를 사용하여 권한을 부여해주고 ssh 접속을 실행해주게되면 성공적으로 접속이 되는 것을 볼 수 있습니다.

 
다음으로는 ec2 인스턴스에 docker container을 설치해줍니다. ( 아까 docker는 항상 루트 권한을 요구한다고 말씀드렸는데, 서비스 demon을 실행하고 버전을 확인할때 루트 권한을 요구하게 됩니다. )
 
우선 sudo command로 루트 권한을 얻어줍니다.

 

 
그 후 docker container을 설치해주고, 설치가 완료 되었다면 시스템 demon을 실행 시켜줍니다.
 

systemctl enable --now docker 을 통하여 서비스 demon을 실행시켜주고, 다음 부팅시에도 서비스 demon이 실행되게끔 해주겠습니다. ( status 확인시 다음번 부팅될 때 실행(enable), 현재 active 되는걸 확인 할 수 있습니다. )
 
다음으로는 docker 가 제대로 동작중인지 확인하기 위해 docker info command를 사용하여 확인해줍니다. ( clinet와 server에 대한 정보도 출력해줍니다. )

 
그 후이제 ec2 사용자가 docker의 관리자가 될 수 있도록 구성해주어야합니다.
( ec2 user를 docker group의 멤버로 만들어주겠습니다. )

 
ec2-user가 docker group의 멤버인 것을 확인 할 수 있습니다. ( 이제 ec2-user 계정을 통하여 docker 관련 명령어들을 실행 시킬 수 있게됩니다. )
 
 

docker container의 기능

 

 
기능은 크게 build, ship, run으로 나눌 수 있습니다.
 
build : 원하는 애플리케이션을 build를 통해 컨테이너화 시켜서 배포가 가능하게 할 수 있습니다.
 
-> container가 다 배포되었으면 배포하기 위해 어딘가에 저장해 주어야합니다.
 
ship : registry라는 곳에 내가 만든 container를 저장해 둘 수 있습니다. 
 
-> 보존해 두기만 하는게 아닌 실제로 서비스를 동작 시켜야합니다.
 
run : 서비스를 실제로 동작 시킵니다. container 저장소(registry)안에 있는 container을 deploy시키고, container를 실행시켜서 원하는 결과를 얻어내고, container 갯수를 확장하거나 축소하여 서비스를 잘 응대할 수 있도록 운영해줍니다.
 

container architecture

 
 

 
 
아까 봤던 사진입니다.
이 사진에서 docker host에 리눅스 운영체제에 docker demon 서버가 동작되고 있는데 우리는 이걸 아까 aws ec2로 인스턴스를 만들어 주었습니다.
container가 저장되어있는 registry라는 공간이있는데( public or private로 다양하게 운영이 가능합니다. ) docker hub 사이트에 들어가게되면( hub.docker.com ) docker에서 제공해주는 public container들이 10만개가 있습니다.
이 저장되어있는 container를 부를때 container image라고 부릅니다. ( 읽기 전용 템플릿으로 지원되기에 image라고 부릅니다. )
container에 필요한 이미지들을 컨테이너화 시켜서 저 곳에 저장합니다.
이런 container들을 우리는 다운로드 받아서 image container로 실행시켜주게되면 container가 host에서 프로세스 형태로 동작하게 됩니다.
( container image를 docker run이라는 명령어를 통해 실행시켜주게되면, 하나의 image가 실제 메모리 상에 올라가 동작하게 됩니다. docker에서 container가 동작되게 하려면 우리가 직접 build 하던지 build된 container를 다운로드 받아야합니다. )
 
Container image
- container 실행을 위한 기반을 제공하는 읽기전용 템플릿(readOnly)입니다. ( 컨테이너화된 애플리케이션이라고 생각하시면 됩니다. )
- 애플리케이션이 동작되기 위한 모든 소스코드와 환경들이 들어있습니다.
 
Container ( container image를 실행하면 container가 됩니다, 이때 layer 하나가 추가로 생성됩니다(container layer : Read, Write) )
- container image를 시반으로 생성됩니다.
- 파일 시스템과 애플리케이션이 구체화 되어서 실행되는 하나의 프로세스입니다.
 

 
위 사진은 container image입니다. image가 선으로 나뉘어져 있는데 저 하나를 layer라고 합니다.
image는 한개 이상의 불변의 읽기전용 layer의 집합입니다. ( 유니언 파일 시스템 )
 

 
docker image layer에 수많은 layer들이 있습니다. ( 한개일수도있고 많을 수도 있습니다. )
이 상태에서 실행시키면 container에 layer가 생성되는데 read와 write를 할 수 있습니다.
아까 docker image layer을 말씀 드리면서 유니언 파일 시스템이 나왔는데 왜 유니언 파일 시스템인지에 대해 풀어보려고 합니다.
 

 
가장 아래 baseImage 부터 블록 쌓듯이 layer가 배치되면서 overlay로 구현이 되어지게 됩니다.
container가 실행될땐 read/write layer가 상단에 배치되고, 전체 layer을 merge하게 됩니다.
 
이처럼 여러개의 layer를 가지고 있음에도 불구하고 하나인 것처럼 보여주기에 overlay라고 합니다.
 
사진에 lowdir는 읽기전용의 image layer들이라고 보시면 됩니다. lowdir layer에 file1이 있고 file2, file3이 있습니다.
이것을 실행시키게되면 아까 말씀드렸던 것처럼 read write layer인 container layer가 생성되는데, 그것이 upper dir입니다.
( 이곳에서는 read/write 로써 기존 파일들을 수정하거나 새로운 파일을 만들어 낼 수 있습니다. 이때 새롭게 만들어지거나 수정된 파일은 upperdir에서 생성됩니다. )
즉, 이렇게 많은 레이어가 있지만 우리가 실제로 볼땐 하나의 layer인 것처럼 보여지게됩니다. ( 이것이 유니언 파일 시스템 )
 


다시 사진을 가져왔습니다.
registry에 있는 container image를 다운로드 받습니다. 그리고 container image를 docker run을 통해 실행하게 된다면 새로운 read write layer가 만들어지면서 하나의 프로세스로 동작이 되고, 변경 사항들은 모두 container 내부에 저장되게 됩니다. ( read write layer에 저장되어서 한개인 것처럼 유니언 파일 시스템으로 보여지게 됩니다. )
( 잘 만들어진 container는 layer의 수가 적고 경량의 container가 된다고 합니다. )
 

Registry

container의 registry는 container image를 보관하고 있는 저장소를 말합니다.
docker hub라는 아까 소개해드렸던 곳에는 10만 여개가 넘는 container들이 있는데 대표적인 public registry입니다.
이 container를 하나의 레포지토리라고 합니다.
즉, 레포지토리들이 모여서 하나의 registry가 됩니다.
 
registry > 레포지토리 > container image
 
레포지토리( 하나의 container image에 대해 다양한 출시 버전을 보관하는 곳 ) 안에는 버전별로 각각의 컨테이너가 존재합니다.
 
이 container 저장소인 registry는 다양하게 운용되는데, 만약 모든 사람들이 가져다 쓸 수 있도록 운용하고 싶다면 public하게 운용하면 되고, 자회사나 개인의 중요한 정보가있는 노출시 크리티컬한 것이라면 private하게 운용하면 됩니다.
클라우드 registry를 이용하여 우리가 쓸 것들만 public registry에서 가져와서 우리만의 registry를 구축하여 운용할 수도 있습니다.
( Amazon ECR, Azure container registry... )
 
 
다음번엔 docker 명령어로 직접 registry에서 container를 다뤄보도록 하겠습니다.