2장. 도커와 쿠버네티스 첫걸음

Hi yena·2021년 9월 20일
0

[출처 : 쿠버네티스 인 액션, 마르코룩샤]

🖌2021.09.20

✔️ 도커를 사용한 컨테이너 이미지 생성, 실행, 공유하기

**- 도커에서 이미지 실행하기**

$ docker run <image>

- 컨테이너 이미지에 버전 지정하기
→ 이미지를 참조할 때 명시적으로 태그를 지정하지 않으면, 도커는 lateste 태그를 참조한 것으로 간주한다. 다른 버전의 이미지를 실행하려면 다음과 같이 이미지 이름에 태그를 같이 지정해야 한다.

$ docker run <image>:<tag>

- 이미지를 위한 Dockerfile 생성
→ 애플리케이션을 이미지로 패키징하기 위해 먼저 Dockerfile이라고 부르는 파일을 생성해야한다. Dockerfile에는 도커가 이미지를 생성하기 위해 수행해야 할 지시 사항이 담겨있다. Dockerfile은 실행하고자 하는 소스파일?과 동일한 디렉터리에 있어야하며 아래와 같은 내용을 갖고있어야 한다.

FROM node:7
ADD app.js /app.js
ENTRYPOINT ["node", "app.js"] 

FROM 줄은 시작점(이미지 생성의 기반이 되는 기본 이미지)으로 사용할 컨테이너 이미지를 정의한다.
두번째 줄은 로컬디렉터리늬 app.js파일을 이미지 루트 디렉터리에 동일한 이름으로 추가한다.
마지막줄에서는 이미지를 실행했을 때 수행돼야 할 명령어를 정의한다.

- 컨테이너 이미지 생성
→ 이미지를 빌드하려면 다음 도커 명령어를 실행한다.

$ docker build -t kubia . 

도커에게 현재 디렉터리의 콘텐츠를 기반으로 Kubia 라고 부르는 이미지를 빌하라고 요청했다(빌드 명령아 마지막에 있는 .(마침표) 주의.

- 이미지 레이어에 관해 이해하기
→ 서로 다른 이미지가 여러개의 레이어를 공유 가능하기 때문에 이미지의 저장과 전송에 효과적이다.
→ 이미지를 가져올 때도 도커는 각 레이어를 개별적으로 다운로드한다.
→ Dockerfile이 새로운 레이어를 하나만 생성한다고 생각할수 있지만 그렇지 않다. 이미지를 빌드하는 동안 기본 이미지의 모든 레이어를 가져온 다음, 도커는 그 위에 새로운 레이어를 생성하고 app.js파일을 그 위에 추가한다. 그런 다음 이미지가 실행할 때 수행돼야 할 명령을 지정하는 또 하나의 레이어를 추가한다. 이 마지막 레이어는 kubia.latest 라고 태그를 지정한다.
→ 이미지 빌드 프로세스가 완료되면 새로운 이미지가 로컬에 저장된다. 아래와 같이 로컬에 저장된 이미지 리스트를 도커에게 요청할 수 있다.

$ docker images

- 컨테이너 이미지 실행
다음 명령어를 사용 해 이미지 실행을 할 수 있다

$ docker run --name kubia-container -p 8080:8080 -d kubia

위 명령어는 도커가 kubia 이미지에서 kubia-container 라는 이름의 새로운 컨테이너를 실행하도록 한다. 컨테이너는 콘솔에서 분리돼(-d 플래그) 백그라운드에서 실행됨을 의미한다. 로컬머신의 8080포트가 컨테이너 내부의 8080포트와 매핑 되므로 http://localhost:8080으로 애플리케이션에 접근할 수 있다.(로컬 머신에서 도커 데몬이 실행중이 아니라면 localhost 대신에 실행중인 가상머신 호스트 이름이나 IP를 사용해야한다. 이 정보는 DOCKER_HOST 환경번수로 확인이 가능하다.)

- 실행중인 모든 컨테이너 조회하기
→ 기본정보

$ docker ps

→ 자세한 정보

$ docker inspect kubia-container

도커는 컨테이너의 상세 정보를 JSON 형식으로 출력할 것이다.

- 실행중인 컨테이너 내부 탐색하기

$ docker exec -it kubia-container bash

이 명령어는 현재 실행중인 kubia-container 컨테이너 내부에 bash를 실행한다. bash 프로세스는 컨테이너의 메인 프로세스와 동일한 리눅스 네임스페이스를 갖는다.

    • i : 표준입력(STDIN)을 오픈 상태로 유지한다. 셸에 명령어를 입력하기 위해 필요하다.
    • t : 의사(pesudo) 터미널(TTY)을 할당한다.
      일반적인 셸을 사용하는 것과 동일하게 셸을 사용하고 싶다면 두 옵션이 필요하다. 첫번째 명령어 옵션을 빼면 셸 명령어를 입력할 수 없고, 두번째 옵션을 빼면 프롬프트가 화면에 표시되지 않는다. 또 어떤 명령어들은 TERM 변수가 선언되지 않아 에러가 난다.

- 컨테이너 내부에서 프로세스 조회하기

root@호스트이름:/# ps aux

단지 세 개의 프로세스만 볼 수 있고 호스트 운영체제의 다른 프로세스는 볼 수가 없다.

- 호스트 운영체제에서 샐행중인 컨테이너 프로세스

$ ps aux | grep app.js

이는 컨테이너에서 실행중인 프로세스가 호스트 운영체제에서 실행중이라는 것을 증명한다.

- 컨테이너 중지와 삭제

중지 : $ docker stop kubia-container
삭제 : $ docker rm kubia-container

$ docoker ps -a 로 보면 실행중인 컨테이너와 중지된 모든 컨테이너를 출력한다.

- 이미지 레지스트리에 이미지 푸시
다른 컴퓨터에서도 이미지를 실행하려면 이미지 저장소에 이미지를 푸시해야 한다.
→ 도커허브(http://hub.docker.com)
→ Quay.io
→ 구글 컨테이너 레지스트리
이미지를 푸시하기 전에 이미지저장소 규칙에 따라 이미지 태그를 다시 지정해야 한다. 도커허브는 이미지의 리포지터리 이름이 도커허브 ID로 시작해야만 이미지를 푸시할 수 있다. http://hub.docker.com에 등록해 도커허브 ID를 생성한다. (ID : hiyena)

- 도커허브에 이미지 푸시하기

$ docker push hiyena/kubia

다른 머신에서 이미지 실행 시
$ docker run -p 8080:8080 -d hiyena/kubia
와 같은 명령어로 이미지를 실행 할 수 있다.

✔️ 쿠버네티스 클러스터 설치

자세한 설명은 http://kubernetes.io 에 상세하게 기재되어 있음

- Minikube를 활용한 단일 노드 쿠버네티스 클러스터 실행하기.
→ 단일 이진 파일로 다운로드 후 실행 가능한 특정 경로(path)에 저장한다.

- 클러스터의 개념 이해하기
→ 각 노드는 도커, kubelet, kube-proxy를 생성한다. kubectl 클라이언트 명령어는 마스터 노드에서 실행중인 쿠버네티스 API 서버로 REST 요청을 보내 클러스터와 상호작용을 한다.

$ kubectl get nodes

클러스터의 모든 노드를 조회한다.

💡TIP
gcloud compute ssh 명령으로 노드에 로그인해 노드에 무엇이 실행 중인지 살펴볼 수 있다.

- 오브젝트 세부 정보 가져오기

$ kubectl describe node 노드이름

- 자동완성(alias) 활용하기
→ alias k=kubectl 등 자동완성 단어를 ~/.bashrc나 이에 준하는 파일에 추가한다.
→ bash 에서 탭 완성을 활성화 하려면 bash-completion 패키지를 설치한 후 아래 명령어 실행해야 한다.
$ source < (kubectl completion bash)
→ 위 방식은 k 별칭 이용시 사용할 수 없다 아래와 같이 변경해야 사용 가능
$ source < (kubectl completion bash | sed s/kubectl/k/g)

✔️ 쿠버네티스에 첫번째 애플리케이션 실행하기

- 파드 소개
→ 하나 이상의 밀접하게 연관된 컨테이너의 그룹으로, 같은 워커 노드에서 같은 리눅스 네임스페이스로 함께 실행된다.
→ 각 파드는 자체 IP, 호스트이름, 프로세스 등이 있는 논리적으로 분리된 머신이다.
→ 파드에서 실행중인 모든 컨테이너는 동일한 논리적인 머신에서 실행하는 것처럼 보이는 반면, 다른 파드에 실행중인 컨테이너는 같은 워커노드에서 실행 중이라 할지라도 다른 머신에서 실행 중인 것으로 나타난다. 파드는 다른 워크노드에 널리 퍼져있다.

- 파드 조회하기
→ 컨테이너는 독릭적인 쿠버네티스 오브젝트가 아니기 때문에 개별컨테이너를 조회할 수 없다. 대신 파드를 조회해야한다. 파드는 아래와 같이 조회한다.

$ kubectl get pods

→ kubectl describe pod 명령어로 파드의 세부 정도 조회 시 파드가 pending 상태로 멈춰 있다면 쿠버네티스가 레지스트리로부터 이미지를 가져오지 못했기 때문일 수도 있다. 자체 이미지를 사용한다면 도커 허브에서 퍼블릭으로 표시돼 있는지 확인해야한다. 이미지를 가져올수 있는지 확인하기 위해 다른머신에서 docker pull 명령으로 이미지 풀링을 시도해 볼 수 있다.

- 웹 애플리케이션에 접근하기
→ 각 파드는 자체 IP주소를 가지고 있지만 이 주소는 클러스터 내부에있으며 외부에서 접근이 불가능하다. 외부에서 접근을 가능하게 하려면 서비스 오브젝트를 통해 노출해야 한다. 외부에서 접근이 가능하도록 하려면 Load Balancer 유형의 특별한 서비스를 생성해야 한다. 로드밸런서 유형의 서비스를 생성하면 외부 로드 밸런서가 생성되므로 로드밸런서의 퍼블릭 IP를 통해 파드에 연결할 수 있다.

💡TIP
Minikube 를 사용한다면 minikube service kubia-http 를 실행해 서비스에 접근 가능한 IP와 포트를 얻을 수 있다.

- 레플리케이션컨트롤러, 파드, 서비스가 서로 동작하는 방식 이해
→ 앞서 설명했듯이 독자 여러분이 컨테이너를 직접 생성하거나 동작시키지는 않는다. 대신 쿠버네티스의 기본 빌딩 블록인 파드를 이용한다. 그러나 파드도 직접 생성하지 않는다. kubectl run 명령을 수행하면 레플리케이션컨트롤러를 생성하고 레플리케이션컨트롤러가 실제 파드를 생성한다. 클러스터 외부에서 파드에 접근케 하기 위해 쿠버네티스에게 레플맅케이션컨트롤러에 의해 관리되는 모든 파드를 단일 서비스로 노출하도록 명령한다.

- 파드와 컨테이너의 이해
→ 시스템의 가장 중요한 구성 요소는 파드다. 파드는 원하는 만큼의 컨테이너를 포함시킬 수 있다. 파드는 자체의 고유한 사설 IP 주소와 호스트 이름을 갖는다.

- 레플리케이션컨트롤러의 역할 이해
→ 다음 구성요소는 kubia 레플리케이션컨트롤러 이다. 항상 정확하게 하나의 파드 인스턴스를 실행하도록 지정한다. 보통 레플리케이션 ㅋ컨트롤러는 파드륵 복제하고 항상 실행 상태로 만든다. 어떤 이유로 pod가 사라진다면 레플리케이션 컨트롤러는 사라진 파드를 대체하기 위해 새로운 파드를 생성할 것이다.

- 서비스가 필요한 이유
→ 시스템의 세번째 구성 요솔는 kubia-http 서비스다. 서비스가필요한 이유를 이해하기 위해 파드의 주요 특성을 알아야 한다. 파드는 일시적이다. 파드는 언제든 사라질 수 있다. 파드가 실행중인 노드가 실패할 수도 있고, 누군가 파드를 삭제할수도 있고 비정상 노드에서 파드가 제거될 수도 있다. 이러한 상황에서 사라진 파드는 레플리케이션컨트롤러에 의해 생성된 파드로 대체된다.(새로운 파드는 다른 IP를 할당받는다.) 이것이 바로 서비스가 필요한 이유다. 서비스는 항상 변경되는 파드의 IP 주소 문제와 여러 개의 파드를 단일 IP와 포트의 쌍으로 노출시키는 문제를 해결한다. 서비스는 어떤 파드가 어디에서 존재하는지(어느 IP를 갖는지)에 관계없이 파드중 하나로 연결하여 요청을 처리하도록 한다.
→ 서비스는 동일한 서비스를 제공하는 하나 이상의 파드 그룹의 정적 위치를 나타낸다. 서비서의 IP와 포트로 유입된 요청은 그 순간 서비스에 속해 있는 파드 중 하나에게 전달된다.

- 애플리케이션 수평 확장
→ 쿠버네티스를 사용하는 주요 이점 중 하나는 간단하게 배포를 확장할 수 있다는 점이다.

$ kubectl get replicationcontrollers

실행중인 인스턴스를 세개로 증가시키기 위해 파드를 관리하는 레플리케이션컨트롤러를 위 명령어를 통해 살펴보자.

→ 의도하는 레플리카 수를 늘리려면 레플리카 컨트롤러에서 의도하는(Desired) 레플리카 수를 변경해야한다.

$ kubectl scale rc kubia --replicas=3

쿠버네티스에게 파드 인스턴스 세 개를 항상 유지해야 한다는 것을 알려줬다.

가장 기본적인 쿠버네티스 원칙 중 하나는 쿠버네티스가 어떤 액션을 수행해야하는지 정확하게 알려주는 대신에 시스템의 의도하는 상태(Desired state)를 선언적으로 변경하고 쿠버네티스가 실제 현재상태(current state)를 검사해 의도한 상태로 조정(reconcile)한다.

- 쿠버네티스 대시보드 소개
→ 대시보드에서 파드, 레플리케이션컨트롤러, 서비스 같은 클러스터의 많은 오브젝트 조회 할 수 있고 생성, 수정, 삭제 또한 가능하다.
→ GKE 를 사용하는 경우 kubectl cluster-info 명령으로 대시보드 URL을 찾을 수 있다.

$ kubectl cluster-info | grep dashboard
$ gcloud container clusters describe kubia | grep -E "(username|password):"

위 명령을 실행해 사용자 이름과 암호를 알 수 있다.

  • Minikube를 사용해 쿠버네티스 클러스터를실행중이라면 다음 명령어를 실행하여 대시보드를 열 수 있다
$ minikube dashboard

0개의 댓글