2024. 3. 15. 18:10ㆍStudy/Kubernetes
2.1 도커를 사용한 컨테이너 이미지 생성, 실행, 공유
백그라운드에 일어난 동작 이해하기
컨테이너 이미지 생성
도커에게 현재 디렉터리의 콘텐츠를 기반으로 kubia라고 부르는 이미지를 빌드하는 명령어이다. 도커는 디렉터리 내 Dockfile을 살펴보고 파일에 명시된 지시 사항에 근거해 이미지를 빌드한다.
docker build -t kubia .
어떻게 이미지가 빌드되는지 이해하기
빌드 프로세스는 도커 클라이언트가 수행하지 않는다. 그 대신 디렉터리의 전체 콘텐츠가 도커 데몬에 업로드되고 그곳에서 이미지가 빌드된다.
❗️빌드 디렉터리에 불필요한 파일을 포함시키지 마라. 특히 원격 머신에 도커 데몬이 위치한 경우 이러한 파일이 빌드 프로세스의 속도 저하를 가져온다.
이미지 레이어에 관해 이해하기
이미지라는 것이 하나의 큰 바이너리 덩어리가 아니라 여러개의 레이어로 구성된다. 서로 다른 이미지가 여러 개의 레이어를 공유할 수 있기 때문에 이미지의 저장과 전송에 효과적이다.
컨테이너 이미지 실행
docker run --name kubia-container -p 8080:8080 -d kubia
이 명령어는 도커가 kubia 이미지에서 kubia-container라는 이름의 새로운 컨테이너를 실행하도록 한다. 컨테이너는 콘솔에서 분리돼(-d 플래그) 백그라운드에서 실행됨을 의미한다. 로컬 머신의 8080포트가 컨테이너 내부의 8080포트와 매핑되므로(-p 8080:8080 옵션) http://localhost:8080으로 애플리케이션에 접근할 수 있다.
컨테이너 정보 얻기
docker ps // 실행 중인 모든 컨테이너 조회하기
docker inspect <container-name> // 컨테이너에 관한 추가 정보 얻기
실행 중인 컨테이너 내부 탐색하기
docker exec -it kubia-container bash
이 명령어는 현재 실행 중인 kubia-container 컨테이너 내부에 bash를 실행한다. bash 프로세스는 컨테이너의 메인 프로세스와 동일한 리눅스 네임스페이스를 갖는다. 따라서, 컨테이너 내부를 탐색할 수 있고 컨테이너 내부에서 실행될 때 Node.js와 애플리케이션이 시스템을 보는 방법을 알 수 있다.
- -i : 표준 입력(STDIN)을 오픈 상태로 유지한다. 셸에 명령어를 입력하기 위해 필요하다.
- -t : 의사 터미널(TTY)을 할당한다.
일반적인 셸을 사용하는 것과 동일하게 셸을 사용하고 싶다면 두 옵션이 필요하다. 첫 번째 옵션을 빼면 명령어를 입력할 수 없고, 두 번째 옵션을 빼면 명령어 프롬프트가 화면에 표시되지 않는다.
내부에서 컨테이너 탐색
아래 명령어는 컨테이너 내부에 실행 중인 프로세스를 조회하는 방법이다.
ps aux
아래 예제 2.6, 2.7를 보면 호스트 운영체제와 컨테이너 내부에서 조회한 프로세스의 ID가 다르다는 것을 발견했을 것이다. 컨테이너는 자체 리눅스 PID 네임스페이스를 사용하며 고유의 시퀀스 번호를 가지고 완전히 분리된 프로세스 트리를 갖고 있다.
<<예제 2.6>>
<<예제 2.7>>
격리된 컨테이너 파일시스템
격리된 프로세스를 가진 것과 마찬가지로 각 컨테이너는 격리된 파일시스템을 갖고 있다. 컨테이너 내부에서 루트 디렉터리의 내용을 조회해보면 컨테이너 안의 파일만 보여준다.
컨테이너 중지와 삭제
docker stop <container name>
컨테이너에 실행 중인 메인 프로세스를 중지시키며 컨테이너 내부에 실행 중인 다른 프로세스가 없으므로 결과적으로 컨테이너가 중지된다.
컨테이너를 완전히 삭제하려면 아래 명령어를 수행한다.
docker rm <container name>
추가 태그로 이미지 태그 지정
docker tag <image> <docker hub id>/<image>
이 명령은 태그를 변경하지 않는다. 같은 이미지에 추가적은 태그를 생성한다. 참고로, 왼쪽 <image>는 현재 저장된 이미지이다.
도커 허브에 이미지 푸시
docker push <docker hub id>/<image name>
2.2 쿠버네티스 클러스터 설치
도커에서 직접 실행하는 대신 쿠버네티스 클러스터에 배포할 수 있다.
해당 장에서는 minikube, GKE(구글 쿠버네티스 엔진)을 활용한 단순한 예제를 보여주고 있다. 따라서, 단순 예제는 제외하고 개념들에 집중하여 본문을 작성한다.
클러스터의 개념 이해하기
kubectl 클라이언트 명령어는 마스터 노드에서 실행 중인 쿠버네티스 API 서버로 REST 요청을 보내 클러스터와 상호작용한다.
클러스터 노드 조회
kubectl get nodes
오브젝트 세부 정보 가져오기
CPU와 메모리, 시스템 정보, 노드에 실행 중인 컨테이너 등을 포함한 노드 상태를 보여준다.
kubectl describe node <node name>
2.3 쿠버테니스에 첫 번째 애플리케이션 실행하기
책에 소개된 예제는 macos에서 실행되지 않는다. 이유는 host platform이 달라서 생기는 문제 같다. 따라서, 일단 기본적인 개념들을 본문에 소개하고자 한다.
파드 조회하기
kubectl get pods
백그라운드에 일어난 동작 이해하기
1~2 단계 : 이미지를 빌드해 도커 허브에 푸시한다. 로컬에 빌드한 이미지는 로컬에서만 사용할 수 있기 때문에 도커 데몬이 실행 중인 다른 워커 노드에서 컨테이너 이미지를 접근하게 하고자 함
3~6 단계 : kubectl 명령어를 실행하면 쿠버네티스의 API 서버로 rest http 요청을 전달하고 클러스터에 새로운 레플리케이션컨트롤러 오브젝트를 생성한다. 레플리케이션컨트롤러는 새 파드를 생성하고 스케줄러에 의해 워커 노드 중 하나에 스케줄링이 된다.
7~8 단계 : 해당 워커 노드의 kubelet은 파드가 스케줄링됐다는 것을 보고 이미지가 로컬에 없기 때문에 도커에게 레지스트리에서 특정 이미지를 pull하도록 지시한다. 이미지를 다운로드한 후 도커는 컨테이너를 생성하고 실행한다.
웹 애플리케이션에 접근하기
실행 중인 파드에 어떻게 접근할 수 있을까? 각 파드는 자체 IP 주소를 가지고 있지만 이 주소는 클러스터 내부에 있으며 외부에서 접근이 불가능하다. 외부에서 파드에 접근을 가능하게 하려면 서비스 오브젝트를 통해 노출해야 한다. 파드와 마찬가지로 일반적인 서비스를 생성하면 이것은 클러스터 내부에서만 접근 가능하기 때문에 Load Balancer 유형의 특별한 서비스를 생성해야 한다. LoadBalancer 유형의 서비스를 생성하면 외부 로드 밸런서가 생성되므로 로드 밸런서의 퍼블릭 IP를 통해 파드에 연결할 수 있다.
서비스 오브젝트 생성하기
서비스를 생성하기 위해 쿠버네티스에게 앞서 생성한 레플리케이션컨트롤러를 노출하도록 명령한다.
kubectl expose rc <image> --type=LoadBalancer --name <service-name>
서비스 조회하기
kubectl get services
조회된 서비스는 파드나 노드 같은 오브젝트이다.
❗️minikube는 로드밸런서 서비스를 지원하지 않으므로 서비스는 외부 IP를 얻지 못한다. 하지만, 외부 포트를 통해 서비스에 접근할 수 있다.
레플리케이션컨트롤러, 파드, 서비스가 서로 동작하는 방식 이해
지금까진 시스템의 물리적인 구성 요소를 설명했다. 이후부터는 시스템의 논리적인 부분을 다루고자 한다.
kubectl run 명령을 수행하면 레플리케이션컨트롤러를 생성하고 이것이 실제 파드를 생성한다. 클러스터 외부에서 파드에 접근케 하기 위해 쿠버네티스에게 레플리케이션컨트롤러에 의해 관리되는 모든 파드를 단일 서비스로 노출하도록 명령한다.
파드와 컨테이너의 이해
파드는 가장 기본이 되는 배포 단위이다. 파드는 원하는 만큼의 컨테이너를 포함시킬 수 있다. 또한, 자체의 고유한 사설 ip 주소와 호스트 이름을 갖는다.
레플리케이션컨트롤러의 역할 이해
파드를 복제하고 항상 실행 상태로 만든다. 어떤 이유로 파드가 사라진다면 레플리케이션컨트롤러는 사라진 파드를 대체하기 위해 새로운 파드를 생성할 것이다.
서비스가 필요한 이유
파드는 언제든 사라질 수 있기 때문에 새로운 파드 생성시에 달느 ip주소를 할당받는다. 이것이 서비스가 필요한 이유다. 항상 변경되는 파드의 ip주소문제와 여러 개의 파드를 단일 ip와 포트의 쌍으로 노출시키는 문제를 해결한다.
정리하면, 서비스는 동일한 서비스를 제공하는 하나 이상의 파드 그룹의 정적 위치를 나타낸다.
의도하는 레플리카 수 늘이기
kubectl scale rc kubia --replicas=3
쿠버네티스에게 어떤 액션이 필요한지 지시하지 않았다. 두 개의 파드를 추가하도록 지시하는 것이 아니라 원하는 인스턴스 수를 설정해 쿠버네티스가 요청된 상태를 달성하기 위해 어떤 액션을 취해야 하는지 판단하도록 했다.
이것이 가장 기본적인 쿠버네티스 원칙 중 하나다. 쿠버네티스가 어떤 액션을 수행해야 하는지 정확하게 알려주는 대신에 시스템의 의도하는 상태(desired state)를 선언적으로 변경하고 쿠버네티스가 실제 현재 상태(current state)를 검사해 의도한 상태로 조정한다. 쿠버네티스의 전체 기능은 이와 동일한 방식으로 돌아간다.
시스템의 새로운 상태 시각화
파드를 조회할 때 파드 IP와 실행 중인 노드 표시
kubectl get pods -o wide
-o wide 옵션을 사용하면 추가 열을 요청할 수 있다. 파드를 조회할 때 이 옵션은 파드 ip와 파드가 실행 중인 노드를 표시한다. 추가적으로, kubectl describe pod <pod name> 을 입력하면 노드를 확인할 수 있다.
'Study > Kubernetes' 카테고리의 다른 글
1. 쿠버네티스 소개 (0) | 2024.03.09 |
---|