쿠버네티스 첫 발걸음

원래벌레·2023년 2월 4일

쿠버네티스를 하게 된 계기

대학교 졸업 작품으로 애플리케이션을 개발하기로 결정. 거기서 Spring Boot를 이용한 백엔드를 담당하게 됐다...
예전에 Django를 이용한 프로젝트를 했을 때, 프론트엔드 개발자와의 환경 문제로 골머리를 앓던 때가 생각이 났다..
그래서 기왕 하는거 처음부터 AWS에 배포를 해서 개발환경에 구애받지 않고 프로젝트를 진행하고 싶었다.
그래서 또 기왕 하는거! 요즘 핫한 k8s를 AWS에서 직접 구축하고 사용해보면 좋겠다고 생각을 했다...

그래서 이번 쿠버네티스 학습을 통해서 하고자 하는 바는 두가지이다.
첫번째, 쿠버네티스의 이해
두번째, AWS에 쿠버네티스 구축

k8s의 공부는 인프런의 있는 조훈 강사님의 쉽게 시작하는 쿠버네티스 강의를 통해서 해볼 생각이다.

쿠버네티스 환경 구성

k8s의 환경구성에는 Virtual Box, Vagrant, 강사님의 코드 총 세가지의 구성요소가 필요했다.

각각의 구성요소에 대해서 설명을 하자면,
먼저 Virtual Box는 하이퍼바이저로 가상머신을 실행 할 수 있게 해준다. 현재 구현하려는 쿠버네티스 환경을 현재 사용중인 OS가 아닌 가상머신의 OS에서 실행 할 수 있게 해준다.

다음은 Vagrant이다. Vagrant는 강사님의 코드를 실행 할 수 있게 해준다. 강사님의 코드에 가서 vagrant up을 하게 되면 가상환경에 OS 및 쿠버네티스 환경이 설치된다.

vagrant up을 완료한 이후에 Master노드에 접속을 하였다.
위의 화면은 Master노드에 접속 이후
kubectl get nodes 명령어를 입력한 결과 화면이다.
결과 화면으로 1개의 마스터노드와 3개의 워커노드가 문제없이 READY 상태인 것을 확인 할 수 있었다.

터미널 연결 구성

위 사진은 강의에서 나오는 터미널 연결 구성에 구조도이다.
여기서 처음보는 Putty와 Supper Putty라는 것이 나오는데,
먼저 Putty는 SSH, Telent과 같은 원격 프로토콜을 이용하여 원격 서버에 접속을 도와준다.
현재 가상머신은 HostOnly 방식으로 네트워크 인터페이스가 구성이 돼 있기 때문에 SSH서버를 이용하여 Host PC의 터미널과 가상머신의 터미널을 연결하려는 것이다.

이러한 Putty는 Session 내용을 저장하는 것은 가능 하지만, 여러개의 가상머신 OS와 터미널을 연결하는 것은 지원을 하지 않아 추가적으로 Super Putty를 이용하여 Putty의 사용성을 좋게 한 것이다.

여기서 Supper Putty에 대한 환경설정이 필요하지만, 이는 교수님이 만들어 두신 xml 파일을 통해서 쉽게 설정을 할 수 있었다.

그 결과 위와 같이 Host PC에서도 Supper Putty를 이용하여 쉽게 가상머신 터미널을 사용 할 수 있게 됐다.

배포!

이번 강의에서는 애플리케이션을 배포를 해보았다. 배포한 애플리케이션은 nginx이다.

이 nginx를 컨테이너화 하였다. 이러한 컨테이너는 여러개로 구성이 되어 하나의 단위로 pod(파드)라는 용어로 불리운다.

다시말해서 pod라는 단위는 하나의 기능을 하기위한 컨테이너들의 집합이다.

먼저 마스터 노드에는 kubectl이 다운로드 돼있다. 이 kubectl이 k8s의 바이너리파일 즉 빌드 된 파일이라고 생각하면 되겠다.

그래서 이 마스터노드에 들어가서 nginx를 배포하기 위하여 컨테이너를 nginx이미지로 실행을 해주어야 한다.

kubectl run <컨테이너 이름> --image=<이미지 이름>
위의 명령어를 통하여 nginx컨테이너를 nginx이미지로 실행한다.

그리고 kubectl get pod 명령어를 통해 컨테이너가 실행 되는 것을 확인 할 수 있다.

그 다음 kubectl get pod -o wide 명령어를 통하여 노드에서 실행된 컨테이너의 ip를 확인 할 수 있다. 현재 2번째 워커노드에서 실행된 컨테이너의 ip는 172.16.103.129이다. curl 172.16.103.129 명령어를 입력하면 그 결과로 nginx 초기화면이 나오는 것을 확인 할 수 있다.

배포된 파드가 외부에서는 실행이 안돼요!

이렇게 만들어진 파드를 외부에서 실행 하려고 하면 실행이 안된다. Host PC에서 Ping을 보내거나 curl 명령어를 보낼 때 아무 응답이 없다는 것이다. 이 이유는 왜일까?

그 이유는 k8s의 구조에 이유가 있다.
k8s는 마스터노드와 워커노드를 모두 묶어서 클러스터 라는 것으로 묶는데, 이렇게 클러스터로 묶여지게 된 마스터노드와 워커노드는 외부와 통신을 할 수 없게된다.

그러면 어쩌라고?

이를 위해서 있는 것이 쿠버네티스의 서비스이다. 이 서비스는 클러스터의 외부에서 브로커의 역할을 한다. 외부에서 클러스터의 접속을 위하여 서비스에게 요청을 하면 서비스는 노드포트를 통해 들어오고, 각 노드포트가 통신을 하면서 파드를 찾아간다.

노출

위 사진과 같이 먼저
kubectl expose pod nginx --type=NodePort --port=80 명령어를 입력하게 되면,
NodePort를 통해서 nginx파드가 외부에 노출이 된다.

kubectl get service 명령어를 통하여 현재 실행중인 서비스를 확인 할 수 있다.
nginx라는 이름의 서비스를 보게되면 현재 32282포트로 설정이 된 것을 확인 할 수 있다.

kubectl get nodes -o wide 명령어를 통해 INTERNAL-IP라고 나오지만, 외부와 접속 가능한 IP(아마 지금은 NAT 방식으로 IP가 설정 된 것으로 보인다.)를 확인 할 수 있다.


그 결과 위와 같이 192.168.1.101:32282에 접속을 하게 되면 nginx가 잘 실행되는 것을 확인 할 수 있다.

디플로이먼트

파드가 죽어버린다면, 서비스의 이용이 가능할까?
당연히 불가능 할 것이다. 이러한 파드의 위험성 관리를 위해서는 파드를 여러개 사용하면 될 것이다. 이것이 바로 디플로이먼트이다.

즉, 다시 말해서 디플로이먼트는 파드가 여러개 있는 것이다!

이러한 디플로이먼트는 앞서 사용했던 kubectl run 명령어를 통해서 배포가 불가능하다.
디플로이먼트를 배포하기 위해서는 kubectl create kubectl apply 명령어를 통해서만 배포가 가능하다.

사실 kubectl run은 단일 파드를 배포하기 위해서만 사용되기 때문에 파드가 잘 작동 되는지를 확인하기 위한 test 목적으로 사용되지 실제로 사용이 되지는 않는다. 그 이유는 파드 하나만으로 어떠한 기능을 한다는 것은 거의 없기 때문이다.

위의 사진은 디플로이먼트를 통해서 pod를 배포를 한 결과 화면이다.
kubectl create deployment deploy-nginx --image=nginx 명령어를 통해서 pod를 배포를 하였다.
배포한 결과 화면은 kubectl get pods 통해서 deploy-nginx-?*-?* 의 이름으로 확인 할 수 있다.

그리고 이 디플로이먼트의 ip를 확인하기 위하여 kubectl get pods -o wide 명령어를 입력하고 ip를 확인 할 수 있다.

이렇게 확인된 ip를 curl 명령어를 통해서 실행을 하면 nginx 초기화면의 내용이 도스창에 나오는 것을 확인 할 수 있다.

이로써 디플로이먼트의 배포 끝!! 이면 좋겠지만,

가만히 생각을 해보면 이상한 점이 있다. 바로 디플로이먼트의 경우에는 여러개의 파드로 구성되어 있다고 했는데, 지금의 경우에는 하나의 파드만을 가지고 있다. 어떻게 된 일인지는 밑의 사진을 통해서 알 수 있다.

터미널에 명령어를 통해서 Deployment를 생성하면 한 개의 파드 밖에 배포를 하지 못한다.
하지만 파일을 통해서 Deployment를 생성하면 여러 개의 파드를 배포 할 수 있다.
이것은 Deployment 내부의 ReplicaSet를 이용한 것이다.

현재 이 ReplicaSet은 디플로이먼트의 default 설정으로 자리매김 하고 있다. 이에 대한 속성 값으로 replicas가 있는데, 이 값이 파드의 개수를 뜻한다.

이 replicas 값의 변경을 통하여 pod를 1개에서 n개까지 설정 할 수 있다.

kubectl scale deployment deploy-nginx --replicas=3 명령어를 입력하게 되면, 3개의 파드가 한꺼번에 생성이 되고 생성된 파드의 NAME을 보게되면 하이푼으로 나뉘어진 두개의 해쉬값을 확인 할 수 있는데, 앞쪽 해쉬값은 디플로이먼트의 해쉬값이고 뒤쪽이 파드의 해쉬값이다. 그렇기 때문에 이 파드가 같은 디플로이먼트에 있는 파드들을 각각 식별 할 수 있습니다.

외부로 노출하는 더 좋은 방법인 로드밸런서

현재의 쿠버네티스 환경의 구조도이다.

기존의 구조에서 디플로이먼트가 추가되어 세개의 파드가 묶여 있는 것을 확인 할 수 있다.
이제 이 디플로이먼트를 어떻게 외부에서 접근 할 수 있는지를 알아보자!

kubectl expose deployment deploy-nginx --type=NodePort --port=80 명령어를 통해서 외부로 노출을 할 수 있었다. 이제 노드포트 주소를 통하여 외부에서 접속을 하게 되면 접속이 가능해진다.

이렇게 디플로이먼트 또한 노드포트를 통해서 외부의 접속을 허용하였는데, 이 방법보다 더 좋은 방법이 있다. 그 방법이 로드밸런서이다.

기존에 사용하던 노드포트 방식은 어찌됐든 노드의 ip주소를 사용자에게 노출을 해야하는 문제가 발생한다. 이를 대체 할 방법이 로드밸런서 방법이다.

이러한 로드밸런서 방식은 쿠버네티스 환경에서 default로 지원을 하지는 않는다. 그래서 이 로드밸런서를 이용하기 위해서 MetalLB의 도움을 받아야한다.

이제 MetalLB를 통해서 로드밸런서를 만들어보자!

kubectl apply -f <경로> 명령어는 파일에 적힌 코드 내용을 쿠버네티스 환경에 적용하는 명령어이다. 이 명령어를 통해서 강사님께서 만들어 둔 코드 실행을 통하여 MetalLB를 설치한다.

다음은 kubelctl create deployment chk-hn --image=sysnet4admin/chk-hn 지금 만드는 디플로이먼트의 경우에는 강사님께서 호스트이름을 불러오는 앱을 배포하는 것이기 때문에 image또한 강사님께서 만드신 레지스트리를 사용을 했다.

kubectl scale deployment chk-hn --replicas=3
이렇게 해서 만들어진 디플로이먼트의 사이즈를 3으로 조절한다.

kubectl get pods 결과를 통해서 디플로이먼트가 배포 된 것을 확인 할 수 있다.

이제 생성된 디플로이먼트를 외부에서 접속을 할 수 있도록 노출 해보자!

kubectl expose deployment chk-hn --type=LoadBalancer --port=80
전에 했던 노드포트 방식과 type 옵션의 값만 달라진 것을 확인 할 수 있다.
이렇게 노출을 하면 kubectl get services를 통하여 결과를 확인 할 수 있다.

위 결과 화면을 보면 LoadBalancer 타입의 chk-hn의 외부 IP를 확인 할 수 있다.
저 외부 IP를 통하여 Host PC에서 접속을 하면 아래와 같은 결과를 얻을 수 있다.

결과 값은 파드의 호스트 네임이다.

결과 값이 있는 것을 확인 할 수 있다.

배포된 것을 다 삭제해보자!

kubectl delete service <서비스명>
kubectl delete deployment <디플로이먼트명>
kubectl delete pod <파드명>
kubectl delete -f <파일경로>

위의 방법을 통해서 각각에 해당하는 것들을 삭제 할 수 있다.

쿠버네티스 첫 날을 마치며..

쿠버네티스의 대략적인 그림을 알 수 있었던 시간이었던 것 같다.
강사님께서 제공 해주시는 코드들이 진짜 쿠버네티스의 어려운 부분일 것으로 보이는데,
안에 내용들이 궁금하긴 하다..

다음 시간 부터는 쿠버네티스의 구조를 알아보는 시간으로 다시 이론으로 넘어가는 것으로 보이는데
이것 또한 많이 궁금하다.

생각보다... 내 흥미를 끄는 것이.. DevOps 재밌을 지도..?

이만 첫번째 쿠버네티스 포스트는 마치겠습니다.. 짝짝짝..

profile
학습한 내용을 담은 블로그 입니다.

0개의 댓글