반응형
2장에서 다루는 내용
- 도커를 사용한 컨테이너 이미지 생성, 실행, 공유
- 로컬에 단일 노드 쿠버네티스 클러스터 실행
- 구글 쿠버네티스 엔진에서 쿠버네티스 클러스터 설치
- kubectl CLI 클라이언트 설정과 사용
- 쿠버네티스에서 애플리케이션의 배포와 수평 스케일링
2.1 도커를 사용한 컨테이너 이미지 생성, 실행, 공유하기
2.1.1 도커 설치와 Hello World 컨테이너 실행하기
- 책에서는 busybox 컨테이너를 실행했다.
- busybox는 echo, ls, gzip 등과 같은 UNIX 명령줄 도구들을 합쳐 놓은 단일 실행파일이다.
- busybox는 docker run을 사용해 어떤 이미지를 다운로드하고 실행할지, 필요하다면 실행할 다른 명령어를 추가적으로 기술하면 된다.
$ docker run busybox echo "Hello world"
Unable to find image 'busybox:latest' locally
latest: Pulling from docker.io/busybox
9a163e0b8d13: Pull complete
fef924a0204a: Pull complete
Digest: sha256:97473e34e311e6c1b3f61f2a721d038d1e5eef17d98d1353a513007cf46ca6bd
Status: Downloaded newer image for docker.io/busybox:latest
Hello world
- 예시에 사용된 busybox는 단일 실행파일이지만 다양한 종속성을 가진 복잡한 애플리케이션이 될 수도 있다.
- 중요한 것은 애플리케이션이 컨테이너 내부에서 실행되고, 컴퓨터에서 실행 중인 다른 모든 프소세스로부터 완전히 격리된다는 점
- docker run 명령을 수행했을 때 먼저 도커는 busybox:latest 이미지가 로컬 컴퓨터에 존재하는지 체크한다.
- 존재하지 않는다면 https://docker.io의 도커 허브 레지스트리에서 이미지를 다운로드한다.
- 이미지 다운로드가 완료되면 도커는 이미지로부터 컨테이너를 생성하고 컨테이너 내부에서 명령어를 실행한다.
- echo는 텍스트를 표준 출력으로 출력한 후 프로세스를 중단하고 컨테이너도 중지된다.
- busybox 외에도 다른 이미지를 실행 할 수 있고 이와 동일하다.
http://hub.docker.com에 공개된 이미지를 검색하거나 탐색한 후 다음과 같이 도커에 이미지를 실행하도록 전달할 수 있다.
# docker run <image>
- 모든 소프트웨어 패키지는 업데이트되기 때문에 일반적으로 하나 이상의 버전이 존재한다.
- 도커는 동일한 이미지와 이름에 여러 개의 버전을 가질 수 있다.
- 이미지를 가져올 때 명시적으로 태그를 지정해서 원하는 버전을 가져올 수도 있고, 태그 없이 명령어를 실행하면 도커는 latest 태그를 참조한 것으로 간주한다.
- tag 를 붙여서 불러오려면 아래와 같이 명령어를 입력하면 된다.
docker run <image>:<tag>
예를 들어
nginx 이미지를 가져온다고 가정했을 때
docker run nginx:1.25.3
docker run nginx:1.25.3-alpine-slim
이런식으로 버전을 지정해서 가져올수 있다는 뜻
2.1.3 이미지를 위한 Dockerfile 생성
- 애플리케이션을 이미지로 패키징하기 위해 먼저 Dockerfile이라고 부르는 파일을 생성해야 한다. Dockerfile에는 도커가 이미지를 생성하기 위해 수행해야 할 지시 사항이 담겨 있다.
FROM node:7 ADD app.js /app.js ENTRYPOINT ["node", "app.js"]
- 위와 같은 내용이라고 했을 때 FROM은 이미지 생성의 기반이 되는 기본 이미지로 사용할 컨테이너 이미지를 정의한다.
- node 의 버전 7을 사용한다.
- ADD는 로컬 디렉토리의 app.js 파일을 컨테이너의 루트 디렉토리의 app.js로 추가한다.
- ENTRYPOINT는 이미지를 실행했을 때 수행돼야 할 명령어를 정의한다.
2.1.4 컨테이너 이미지 생성
- Dockerfile과 app.js 파일을 생성했으므로 이미지를 빌드하기 위한 모든 것이 준비됐다.
- 이미지를 빌드하려면 아래 도커 명령어를 실행한다.
$ docker build -t kubia .
- 위와 같은 과정으로 컨테이너가 띄워진다고 생각하면 된다.
- 빌드 프로세스는 도커 클라이언트가 수행하지 않는다. 대신 디렉터리의 전체 콘텐츠가 도커 데몬에 업로드되고 그곳에서 이미지가 빌드된다. 도커 클라이언트와 데몬은 같은 머신에 있을 필요는 없다. 리눅스가 아닌 OS에서 도커를 사용하는 경우 도커 클라이언트는 호스트 OS에 위치하고, 데몬은 가상머신 내부에서 실행되기도 한다.
- 빌드 디렉터리의 모든 파일이 데몬에 업로드돼야 하기 때문에 데몬이 로컬로 실행 중이지 않은 상황에서 큰 파일이 다수 포함되면 업로드 시간이 오래 걸릴 수 있다. 왜? 데몬이 없는 OS에서 데몬이 있는 OS로 파일을 전송해야하기 때문에
- 이미지는 하나의 큰 바이너리 덩어리가 아니라 여러 개의 레이어로 구성된다.
- 서로 다른 이미지가 여러 개의 레이어를 공유할 수 있기 때문에 이미지의 저장과 전송에 효과적이다.
- 컴퓨터에 여러 개의 레이어가 이미 저장돼 있다면 도커는 저장되지 않은 레이어만 다운로드한다.
- 각 Dockerfile이 새로운 레이어를 하나만 생성한다고 생각할 수 있지만 그렇지 않다.
- 이미지를 빌드하는 동안 기본 이미지의 모든 레이어를 가져온 다음, 도커는 그 위에 새로운 레이어를 생성하고 app.js 파일을 그 위에 추가한다. 그런 다음 이미지가 실행할 때 수행돼야 할 명령을 지정하는 또 하나의 레이어를 추가한다. 이 마지막 레이어는 kubia:latest라고 태그를 지정한다.
- 만약 kubia:latest 이미지와 other:latest 이미지를 구성한다고 가정했을 때 other:latest 이미지가 어떻게 kubia에서 사용하는 것과 동일한 이미지를 즉, 레이어를 사용할 수 있는 지 보여준다.
- 이미지 빌드 프로세스가 완료되면 새로운 이미지가 로컬에 저장된다.
- 아래와 같은 명령어로 확인이 가능하다.
$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE kubia latest d30ecc7419e7 1 minute ago 637.1 MB ...
- Dockerfile은 도커로 컨테이너 이미지를 생성하는 일반적인 방법이지만, 기존 이미지에서 컨테이너를 실행하고 컨테이너 내부에서 명령어를 수행한 후 빠져나와 최종 상태를 새로운 이미지로 커밋하는 방법으로 이미지를 수동으로 생성할 수도 있다.
- 위와 같은 방법을 사용할 수도 있지만, Dockerfile을 이용하는 것이 훨씬 반복 가능하고 이미지 빌드를 자동화할 수 있는 방법이다.
2.1.5 컨테이너 이미지 실행
$ docker run --name kubia-container -p 8080:8080 -d kubia
- 위 명령어는 도커가 kubia 이미지에서 kubia-container라는 이름의 새로운 컨테이너를 실행하도록 한다.
- -d 옵션은 콘솔에서 분리돼 백그라운드에서 실행됨을 의미한다.
- -p 옵션은 로컬 머신의 8080 포트가 컨테이너 내부의 8080 포트와 매핑되는 것을 의미한다.
- --name 옵션은 해당 이름으로 컨테이너 이름을 지정한다.
- 로컬 머신에서 도커 데몬이 실행 중이 아니라면 localhost 대신에 데몬이 실행 중인 가상머신의 호스트 이름이나 IP를 사용해서 해당 컨테이너로 접근해야 한다. 이 정보는 로컬 머신에서 DOCKER_HOST 환경변수로 확인 가능하다.
$ export DOCKER_HOST 로 확인 가능 - 실행 중인 모든 컨테이너를 조회할 수도 있다.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED ...
44d76963e8e1 kubia:latest "/bin/sh -c 'node ap 6 minutes ago ...
... STATUS PORTS NAMES
... Up 6 minutes 0.0.0.0:8080->8080/tcp kubia-container
- 더 자세한 정보를 보려면 docker inspect를 사용한다.
2.1.6 컨테이너 이미지 실행
- 컨테이너 내부의 환경을 보고 싶다면 아래와 같이 확인하면 된다. 허나 이미지 내에 실행 가능한 셸 바이너리가 제공되어야 한다.
$ docker exec -it kubia-container bash
- 이 명령어는 현재 실행 중인 kubia-container 컨테이너 내부에 bash를 실행한다.
- bash 프로세스는 컨테이너의 메인 프로세스와 동일한 리눅스 네임스페이스를 갖는다. 따라서 컨테이너 내부를 탐색할 수 있다.
- -i 옵션은 표준 입력을 오픈 상태로 유지해 사용자가 셸에 명령어를 입력할 수 있도록 해준다.
- -t 옵션은 의사(pseudo) 터미널(TTY)을 할당한다.
- 일반적인 셸을 사용하는 것과 동일하게 셸을 사용하고 싶다면 두 옵션이 필요하다.
- 컨테이너 내부에 실행 중인 프로세스를 조회 할 수 있다.
root@44d76963e8e1:/# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 676380 16504 ? Sl 12:31 0:00 node app.js
root 10 0.0 0.0 20216 1924 ? Ss 12:31 0:00 bash
root 19 0.0 0.0 17492 1136 ? R+ 12:38 0:00 ps aux
- 호스트 운영체제에서 실행 중인 컨테이너 프로세스를 조회할 수 있다.
- 이것은 컨테이너에서 실행 중인 프로세스가 호스트 운영체제에서 실행 중이라는 것을 증명한다.
- 호스트 운영체제와 컨테이너 내부에서 조회한 프로세스의 ID는 다르며, 컨테이너는 자체 리눅스 PID 네임스페이스를 사용하며 고유의 시퀀스 번호를 가지고 완전히 분리된 프로세스 트리를 갖고 있다.
$ ps aux | grep app.js
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 382 0.0 0.1 676380 16504 ? Sl 12:31 0:00 node app.js
- 격리된 프로세스를 가진 것과 마찬가지로 각 컨테이너는 격리된 파일시스템을 갖고 있다. 컨테이너 내부에서 루트 디렉터리의 내용을 조회해보면 컨테이너 안의 파일만 보여준다.
root@44d76963e8e1:/# ls /
app.js boot etc lib media opt root sbin sys usr
bin dev home lib64 mnt proc run srv tmp var
- 컨테이너에 진입하는 것은 컨테이너에 실행 중인 애플리케이션을 디버깅 할 때 유용하다.
2.1.7 컨테이너 중지와 삭제
- 애플리케이션을 중지하기 위해 도커에게 컨테이너를 중지하도록 명령할 수 있다.
$ docekr stop kubia-container
- 위 명령은 실행 중인 메인 프로세스를 중지시키고 컨테이너 내부에 실행 중인 다른 프로세스가 없으므로 결과적으로 컨테이너가 중지 된다. 이는 일시정지와 같으며, docker ps -a 명령어를 사용하면 컨테이너 자체는 여전히 존재한다.
- 컨테이너를 완전 삭제하려면 아래와 같다.
$ docker rm kubia-container
2.1.8 이미지 레지스트리에 이미지 푸시
- 여태까지의 과정은 모두 로컬 컴퓨터에서만 사용이 가능하고, 공개 레지스트리를 사용하면 공유가 가능하다. docker hub , quay.io, 구글 컨테이너 레지스트리 등이 있다.
- 공개 레지스트리의 ID가 있다면 kubia 이미지를 luksa/kubia로 변경해 ID를 명시해주어라
$ docker tag kubia luksa/kubia # 현재 kubia 이미지를 luksa/kubia로 변경하라.
$ docker images | head
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
luksa/kubia latest d30ecc7419e7 About an hour ago 654.5 MB
kubia latest d30ecc7419e7 About an hour ago 654.5 MB
docker.io/node 7.0 04c0ca2a8dad 2 days ago 654.5 MB
...
- kubia와 luksa/kubia가 동일한 이미지 ID를 가지고 있으므로 사실 같은 이미지에 두 개의 태그를 갖는 것이다.
- 도커 허브에 이미지를 푸시하기 전에 docker login 명령어를 이용해 사용자 ID로 로그인 해야한다.
- 로그인 하면 /kubia로 이미지를 푸시할 수 있다.
$ docker push luksa/kubia
- 도커 허브에 이미지가 푸시되면 모든 사람이 이미지를 사용할 수 있다.
$ docker run -p 8080:8080 -d luksa/kubia
- 무엇보다 좋은 점은 애플리케이션이 언제 어디서나 동일한 환경을 유지한다는 것이고, 사용자의 머신에서 정상적으로 실행되면 어느 리눅스 머신에서도 잘 실행된다.
2.2 쿠버네티스 클러스터 설치
- 도커에서 직접 실행하는 대신 쿠버네티스 클러스터에 배포할 수 있다.
2.2.1 Minikube를 활용한 단일 노드 쿠버네티스 클러스터 실행하기
(실행과정이기 때문에 빠르게 생략 해본다.)
$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/
➥ v0.23.0/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube
➥ /usr/local/bin/
$ minikube start
Starting local Kubernetes cluster...
Starting VM...
SSH-ing files into VM...
...
Kubectl is now configured to use the cluster.
- 쿠버네티스 클라이언트 설치하기
➥ /$(curl -s https://storage.googleapis.com/kubernetes-release/release
➥ /stable.txt)/bin/darwin/amd64/kubectl
➥ && chmod +x kubectl
➥ && sudo mv kubectl /usr/local/bin/
- 클러스터 작동 여부 확인하기
$ kubectl cluster-info
Kubernetes master is running at https://192.168.99.100:8443
KubeDNS is running at https://192.168.99.100:8443/api/v1/proxy/...
kubernetes-dashboard is running at https://192.168.99.100:8443/api/v1/...
2.2.2 구글 쿠버네티스 엔진을 활용한 관리형 쿠버네티스 클러스터 사용하기
생략 하도록 한다...
2.3 쿠버네티스에 첫 번째 애플리케이션 실행하기
- 쿠버네티스는 보통 배포하고자 하는 모든 구성 요소를 기술한 JSON이나 YAML 매니페스트를 준비해야 하는데 아래는 간단히 설명했다.
2.3.1 Node.js 애플리케이션 구동하기
- 애플리케이션을 배포하기 위한 가장 간단한 방법은 kubectl run 명령어를 사용하는 것이다.
$ kubectl run kubia --image=luksa/kubia --port=8080 --generator=run/v1 replicationcontroller "kubia" created
- generator 옵션은 보통 사용하지 않는다. 레플리케이션컨트롤러를 생성하기 때문에 사용한다.
- 실행 중인 모든 컨테이너를 보여주는 방법이 궁금할 수 있다. 쿠버네티스는 개별 컨테이너들을 직접 다루지 않는다. 대신 함께 배치된 다수의 컨테이너라는 개념을 사용한다. 이 컨테이너의 그룹을 파드라고 한다.
- 파드는 하나 이상의 밀접하게 연관된 컨테이너의 그룹으로 같은 워커 노드에서 같은 리눅스 네임스페이스로 함께 실행된다.
- 각 파드는 자체 IP, 호스트 이름, 프로세스 등이 있는 논리적으로 분리된 머신이다.
- 파드에서 실행 중인 모든 컨테이너는 동일한 논리적인 머신에서 실행하는 것처럼 보이는 반면, 다른 파드에 실행 중인 컨테이너는 같은 워커 노드에서 실행 중이라 할지라도 다른 머신에서 실행 중인 것으로 나타난다.
- kubectl get pods를 이용하면 파드를 조회할 수 있다.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia-4jfyf 0/1 Pending 0 1m # Pending 상태는 현재 컨테이너가 준비가 되지 않은 상태
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia-4jfyf 1/1 Running 0 5m # 시간이 지나면 Running 상태로 변하는 것을 알 수 있음
- 백그라운드에서는 이런 동작을 했다.
- 쿠버네티스 내부에서 컨테이너 이미지를 빌드해 도커 허브에 푸시한다. 로컬에 빌드한 이미지는 로컬에서만 사용 가능하기 때문에 도커 데몬이 실행 중인 다른 워커 노드에서 컨테이너 이미지를 접근하게 하고자 이 절차가 필요하다.
- kubectl 명령어를 실행하면 쿠버네티스의 API 서버로 REST HTTP 요청을 전달하고 클러스터에 새로운 레플리케이션컨트롤러 오브젝트를 생성한다.
- 레플리케이션컨트롤러는 새 파드를 생성하고 스케줄러에 의해 워커 노드 중 하나에 스케줄링이 된다.
- 스케줄링이라는 용어는 파드가 특정 노드에 할당됨을 의미한다. 파드는 즉시 실행된다.
- 해당 워커 노드의 Kubelet은 파드가 스케줄링됐다는 것을 보고 이미지가 로컬에 없기 때문에 도커에게 레지스트리에서 특정 이미지를 pull 하도록 지시한다. 이미지를 다운로드한 후 도커는 컨테이너를 생성하고 실행한다.
2.3.2 웹 애플리케이션 접근하기
- 실행 중인 파드에 접근하기 위해서는 외부에서 접근 하도록 해야한다.
- 각 파드는 자체 IP를 가조기 있지만 클러스터 내부에 있으며 외부에서 사용이 불가능하다.
- 외부에서 접근하려면 서비스 오브젝트를 통해서 노출해야한다.
- LoadBalancer 유형의 특별한 서비스를 생성해야 한다. 이 유형의 서비스를 생성하면 외부 로드 밸런서가 구성되므로 로드 밸런서의 퍼블릭 IP를 통해 파드에 연결할 수 있다.
- expose 명령어를 통해서 앞서 생성한 레플리케이션컨트롤러를 노출하도록 명령한다.
$ kubectl expose rc kubia --type=LoadBalancer --name kubia-http
service "kubia-http" exposed
- expose의 결과를 보면 kubia-http 라는 서비스가 표시된다. 서비스는 파드와 노드 같은 오브젝트로 kubectl get services 명령으로 확인 가능하다.
$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.3.240.1 <none> 443/TCP 34m
kubia-http 10.3.246.185 <pending> 8080:31348/TCP 4s
- kubia-http 서비스를 살펴보면
$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.3.240.1 <none> 443/TCP 34m
kubia-http 10.3.246.185 <pending> 8080:31348/TCP 4s
$ kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.3.240.1 <none> 443/TCP 35m
kubia-http 10.3.246.185 104.155.74.57 8080:31348/TCP 1m
- pending 상태에서 EXTERNAL-IP가 생성됨을 알 수 있다. 이를 이용해서 http://104.155.74.57:8080 으로 접근이 가능하다.
2.3.3 시스템의 논리적인 부분
- 시스템은 물리적인 것 외에도 논리적으로 분리된 관점도 있다.
- 마스터 노드가 단일 마스터 노드인지 여러 대의 마스터 노드에 분산된 것인지 알 수 없다. 단지 단일 엔드포인트로 접근 가능한 API 서버를 통해 상호작용하고 있기 때문에 큰 상관이 없다.
- 레플리케이션컨트롤러, 파드, 서비스는 아래와 같이 작동한다.
- kubectl run 명령을 수행하면 레플리케이션컨트롤러를 생성하고 레플리케이션컨트롤러가 실제 파드를 생성한다. 클러스터 외부에서 파드에 접근케 하기 위해 쿠버네티스에게 레플리케이션 컨트롤러에 의해 관리되는 모든 파드를 단일 서비스로 노출하도록 명령한다.
- 시스템에서 가장 중요한 구성 요소는 파드다. 보통 파드는 원하는 만큼의 컨테이너를 포함시킬 수 있다.
- 레플리케이션 컨트롤러는 정확히 하나의 파드 인스턴스를 실행하도록 지정한다. 위 예제에서는 파드의 replicas를 지정하지 않았기 때문에 파드를 하나만 생성했지만 지정하면 여러개 생성 가능하다. 어떤 이유로 파드가 사라진다면 레플리케이션컨트롤러는 사라진 파드를 대체하기 위해 새로운 파드를 생성할 것이다.
- 파드는 일시적이다(ephemeral) 그렇기 때문에 서비스가 필요하다. 파드는 언제든 사라질 수 있기 때문에 사라진 파드를 레플리케이션컨트롤러가 새로 파드를 생성해 대체하고 새로운 파드는 기존과는 다른 IP를 할당 받는다. 이것이 서비스가 필요한 이유다. 항상 변경되는 파드의 IP 주소 문제와 여러 개의 파드를 단일 IP 와 포트의 쌍으로 노출시키는 문제를 해결한다. 서비스의 IP와 포트로 유입된 요청은 서비스에 속해 있는 파드 중 하나에게 전달된다.
2.3.4 애플리케이션 수평 확장
- 쿠버네티스를 사용하는 주요 이점 중 하나는 간단하게 배포를 확장할 수 있다는 점이다.
$ kubectl get replicationcontrollers
NAME DESIRED CURRENT AGE
kubia 1 1 17m
- 위와 같이 DESIRED는 레플리케이션컨트롤러에서 지정한 원하는 파드의 개수이다. CURRENT는 현재 실행되고 있는 실제 파드의 수이며, 항상 CURRENT 를 DESIRED 숫자로 맞춘다.
- DESIRED를 변경하기 위해서는 아래와 같이 변경하면 된다.
$ kubectl scale rc kubia --replicas=3
replicationcontroller "kubia" scaled
- 쿠버네티스에게 직접적으로 파드를 2개 늘려라 라고 액션을 지시해준 것이 아니라 우리는 DESIRED를 3개로 변경했을 뿐이다. 쿠버네티스가 어떤 액션을 수행해야 하는지 알려주는 대신 시스템의 의도하는 상태를 선언적으로 변경하고 쿠버네티스가 실제 현재 상태를 검사해 의도한 상태로 조정한다. 쿠버네티스의 전체 기능은 이와 동일한 방식으로 돌아간다.
- 스케일아웃 결과 보기
- 파드가 늘고 있음을 알수있음
$ kubectl get rc
NAME DESIRED CURRENT READY AGE
kubia 3 3 2 17m
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia-hczji 1/1 Running 0 7s
kubia-iq9y6 0/1 Pending 0 7s
kubia-4jfyf 1/1 Running 0 18m
- 서비스 호출 시 모든 파드가 요청을 받는지 확인
$ curl 104.155.74.57:8080
You’ve hit kubia-hczji
$ curl 104.155.74.57:8080
You’ve hit kubia-iq9y6
$ curl 104.155.74.57:8080
You’ve hit kubia-iq9y6
$ curl 104.155.74.57:8080
You’ve hit kubia-4jfyf
- 각자 다른 pod의 호스트 이름을 뱉고 있는 것을 확인 가능하다.
- 하나 이상의 파드가 서비스 뒤에 존재할 때 쿠버네티스 서비스는 요청을 무작위로 다른 파드로 보내준다.
- 서비스는 항상 동일한 주소를 갖기 때문에 클라이언트는 얼마나 많은 파드가 존재하고 위치가 변경되는지에 관계없이 쉽게 연결 가능하다.
2.3.5 애플리케이션이 실행 중인 노드 검사하기
- 쿠버네티스에서는 파드가 적절히 실행하는 데 필요한 CPU와 메모리를 제공하는 노드에 스케줄링됐다면, 어떤 노드에 파드가 실행 중인지는 중요하지 않다.
- -o wide 옵션을 사용하면 파드 IP와 실행중인 노드를 확인할 수 있다.
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
kubia-hczji 1/1 Running 0 7s 10.1.0.2 gke-kubia-85...
- describe로도 확인 가능하다.
$ kubectl describe pod kubia-hczji
Name: kubia-hczji
Namespace: default
Node: gke-kubia-85f6-node-vs9f/10.132.0.3
Start Time: Fri, 29 Apr 2016 14:12:33 +0200
Labels: run=kubia
Status: Running
IP: 10.1.0.2
Controllers: ReplicationController/kubia
Containers: ...
Conditions:
Type Status
Ready True
Volumes: ...
Events: ...
2.3.6 쿠버네티스 대시보드 소개
(생략)
느낀 점
도커 이미지 생성하는 거나 빌드 과정에서 구체적인 내부 프로세싱을 알 수 있어서 좋았다.
쿠버네티스도 마찬가지로 구체적인 프로세싱이 나왔음
정리
- 도커 이미지를 생성하는 명령어
$ docker build -t <이미지>:<태그>
명령어를 이용해서 생성하면 된다.
- 도커 이미지를 도커 허브로 공유하는 명령어
$ docker push <이미지>
- 도커 컨테이너 실행하는 명령어
$ docekr run <이미지>:<태그>
- 도커 컨테이너를 중지하는 명령어
$ docker stop <컨테이너이름>
- 도커 컨테이너를 삭제하는 명령어
$ docker rm <컨테이너이름>
- Dockerfile 간략한 설명
- Dockerfile은 애플리케이션을 이미지로 패키징하게 끔 하는 파일이고, 도커가 이미지를 생성하기 위해 수행해야 할 지시 사항이다.
- FROM은 베이스 이미지를 지정하는 라인
- ADD 는 현재 로컬 PC에 있는 파일을 컨테이너에 있는 위치로 복사할 수 있음
예시 -> ADD app.js /app.js - ENTRYPOINT는 이미지를 실행했을 때 수행해야 할 명령어를 의미한다.
- 컨테이너 이미지 생성되는 과정
- 빌드 프로세스는 도커 클라이언트가 수행하지 않고 도커 데몬이 수행한다.
- docker run 명령어를 사용자가 입력한다 -> 명령어를 전달받은 docker 클라이언트는 Dockerfile 및 app.js 등 디렉터리 컨텐츠를 데몬으로 보냄 -> 데몬은 이미지를 확인하고 로컬에 베이스 이미지가 없다면 도커 허브에 pull 요청함 -> 베이스 이미지가 확인이 되면 디렉터리 컨텐츠를 포함해 새로운 이미지를 생성함.
- 컨테이너 이미지 특성
- 이미지는 하나의 큰 바이너리 덩어리가 아니라 여러 개의 레이어로 구성되어 있어서 서로 다른 이미지가 여러 개의 레이어를 공유할 수 있기 때문에 이미지의 전송과 저장에 효과적이다.
- 컴퓨터에 여러 개의 레이어가 이미 저장되어 있다면 도커는 저장되지 않은 레이어만 다운로드한다.
- 만약 도커 클라이언트와 데몬이 같은 머신에 위치하지 않는다면 디렉터리 전체 콘텐츠를 도커 데몬으로 보내야하기 때문에 큰 파일이 다수 포함되면 업로드 시간이 오래 걸릴 수 있다.
- 쿠버네티스는 어떻게 논리적으로 분리되어 있는 가?
- 쿠버네티스는 서비스, 레플리케이션컨트롤러, 파드 등으로 분리 되어 있다.
- 서비스는 외부의 트래픽을 파드로 전달해주는 오브젝트이다.
- 레플리케이션컨트롤러는 파드의 필요 개수와 현재 개수를 감시해 현재 개수를 필요 개수로 맞추는 역할을 한다.
- kubectl run 동작하는 프로세싱 (레플리케이션컨트롤러)
- 레지스트리에 있는 이미지를 이용해 kubectl 명령어를 실행한다.(로컬에 존재하는 이미지는 로컬에서만 사용 가능함 다른 워커 노드에서 컨테이너 이미지를 접근하게 하고자 한다면 이미지를 전송해야만 한다.) -> 쿠버네티스의 API 서버로 REST HTTP 요청을 전달하고 클러스터에 새로운 레플리케이션컨트롤러 오브젝트를 생성한다. -> 생성된 레플리케이션컨트롤러는 새 파드를 생성하고 스케줄러에 의해 워커 노드 중 하나에 스케줄링된다.
- 레플리케이션컨트롤러는 파드의 복제만 관리하는 오브젝트
- 만약 이미지가 로컬에 없으면 해당 노드의 kubelet은 파드가 스케줄링됐다는 것을 보고 도커에게 레지스트리에서 특정 이미지를 pull 하도록 지시한다.
- 외부에서 애플리케이션에 접속하는 방법
- 외부에서 애플리케이션에 접속하기 위해서는 서비스의 EXTERNAL-IP를 알아야한다.
$ kubectl get services
명령어를 실행해 확인 가능하다.
- 쿠버네티스 애플리케이션 수평 확장
- 레플리케이션컨트롤러는 DESIRED와 CURRENT를 항상 비교하면서 DESIRED 개수로 파드의 개수를 맞춘다.
참고 자료
쿠버네티스 인 액션
반응형
'책, 강의' 카테고리의 다른 글
[쿠버네티스 인 액션] 5장 - 서비스: 클라이언트가 파드를 검색하고 통신을 가능하게 함 (1) | 2023.11.21 |
---|---|
[쿠버네티스 인 액션] 4장 - 레플리케이션과 그 밖의 컨트롤러: 관리되는 파드 배포 (1) | 2023.11.02 |
[쿠버네티스 인 액션] 3장 - 쿠버네티스에서 컨테이너 실행 (1) | 2023.10.30 |
[쿠버네티스 인 액션] 1장 - 쿠버네티스 소개 (1) | 2023.10.29 |