쿠버네티스

허현진·2022년 4월 9일
0

Kubernetes

목록 보기
1/1

3.1 쿠버네티스 아키텍처

  • 도커가 컨테이너와 관련된 전반적이고 추상화된 기술을 제공한다고 하면, 쿠버네티스는 다량의 컨테이너를 하나의 물리적인 서버에 배치하여 이를 사용하듯이 관리해주는 역할을 함.
  • 노드를 하나로 묶는 클러스터를 관리하는 컨트롤 플레인 영역과 흩어져 있는 각 노드를 관리하는 노드 영역으로 나눌 수 있음.

컨트롤 플레인 컴포넌트

  • 클러스터에 관한 결정을 내리고 클러스터 이벤트를 감지하며 반응함.
  • 클러스터 내 어떠한 머신에서라도 동작할 수 있음
- Kube-apiserver : 쿠버네티스의 모든 컴포넌트의 통신을 담당
- Etcd : 모든 클러스터 데이터를 담는 쿠버네티스 뒷단의 저장소로 사용되는 키-밸류 저장소
- Kube-scheduler : 노드가 배정되지 않은 새로 생성된 파드를 감지하고, 실행할 노드를 선택하는 컴포넌트.
- Kube-controller-manager : 컨트롤러를 구동하는 컴포넌트. 
구동되는 컨트롤러로 노드 컨트롤러, 레플리케이션 컨트롤러, 앤드포인트 컨트롤러, 서비스 어카운트, 토큰 컨트롤러 등이 있음.
- Cloud-controller-manager : 바탕을 이루는 클라우드 제공 사업자와 상호작용하는 컨트롤러를 작동시킴. Cloud-controller-manager 바이너리는 쿠버네티스 릴리스에서 도입된 알파 기능.
- Node-component : 동작 중인 파드를 유지시키고 쿠버네티스 런타임 환경을 제공하며, 모든 노드 상에서 동작함.
- Kubelet: 클러스터의 각 노드에서 실행되는 에이전트. Kubelet은 파드에서 컨테이너가 확실하게 동작하도록 관리함.
- Kube-proxy: 클러스터의 각 노드에서 실행되는 네트워크 프록시로, 쿠버네티스 서비스 개념의 구현부임. 또한 노드의 네트워크 규칙을 유지, 관리함. 이 네트워크 규칙이 내부 네트워크 세션이나 클러스터 바깥에서 파드로 네트워크 통신을 할 수 있도록 해줌.
- Container-runtime : 컨테이너 실행을 담당하는 소프트웨어. 

3.2 쿠버네티스 설치

https://kubernetes.io/ko/

예제 소스 : https://github.com/uphiller/dockerbook

  • kubeadm join 10.178.0.8:6443 –token r6qx7w.axjw3dlb9uyz7x1 \ --discovery-token-ca-cer-hash sha 256:72639bfe4cb24e2602d6ade65596eee35694967~~~
    : worker노드 추가할 때 필요

worker노드 조인

  • Kubeadm join --token <2. Token 값> --discovery-token-ca-cert-hash sha256:<3. Hash 값>

토큰은 24시간의 제한 시간이 있고, 이 시간이 지나면 kubeadm create token 명령을 통해 재발급 가능.
Kubeadm token create --print-join-command

파드 네트워크 Add-On설치

  • 본격적으로 통신을 하기 위해서는 Pod Network Add-On을 설치해야 함. 파드들의 배포와 통신을 위해 네트워크를 설정해야 하기 때문.
  • 다양한 애드온이 있지만 Weave Net 애드온 설치. 각 클러스터마다 Network Add-On 하나씩만 설치 가능.

포트 추가

  • 쿠버네티스를 운영하기 위해서는 필요한 포트를 열어 주어야 함.
  • 우분투를 사용한다면 우분투 자체 방화벽을 열어주기. 클라우드를 이용한다면 인스턴스의 방화벽을 열면 됨.

도커를 사용할 때 처럼 컨테이너를 하나 실행하기

  • Kubectl run nginx-app --image nginx --port=80
  • Kybectl get pods
  • kubectl expose pod nginx-app –type=NodePort
  • Kubectl get service

쿠버네티스에서 컨테이너를 담고 있는 객체인 파드(pod)를 생성하였고, 생성된 파드를 외부에 노출시킬 수 있도록 서비스(service)를 생성하였음.

삭제하기

  • Kubectl delete pod nginx-app
  • Kubectl delete svc nginx-app

단일 인스턴스에 쿠버네티스를 설치했고, nginx 컨테이너까지 실행함

3.3 쿠버네티스 오브젝트

  • 쿠버네티스는 모든 요소를 yaml 파일로 생성하여 관리 가능함.
  • 복잡한 인프라 관리에 코드화가 보편화된 최근 설정 파일을 사용하면 기존의 쿠버네티스 관리가 훨씬 수월해짐.

네임스페이스

  • 하나의 물리적인 공간에 있는 쿠버네티스를 다수의 팀이 사용할 때 유용함.
  • 다수의 팀이 쿠버네티스를 운영한다면 각 팀이 사용하는 부분이 서로 영향을 미칠 수 있기 때문에 분리해서 작업할 수 있는 환경이 필요함.
  • 네임스페이스가 작업되는 부분에 대해서 논리적으로 분리해줌.
  • 네임 스페이스 조회 : kubectl get namespace

  • 기본으로 생성되어 있는 네임스페이스 존재.
    • 어떤 작업을 할 때 네임스페이스에 대한 부분이 없다면 모든 작업은 default 네임스페이스에 할당됨.

Namespace.yaml 파일 생성

apiVersion: v1
kind: Namespace
metadata:
		name: team1
  • kubectl apply -f namespace.yaml : 구성 파일 실행
  • kubectl run nginx –image=nginx –namespace=team1 : 네임스페이스를 이용하여 파드 생성
  • kubectl get pod -n team1 : 파드가 잘 만들어졌는지 확인
  • kubectl delete pod nginx -n team1 : 삭제
  • kubectl delete namespace team1 : 삭제

파드

  • 쿠버네티스의 구성 요소 중 가장 작은 단위의 객체.
  • 파드는 해당 클러스터에서 러닝 프로세스를 나타냄.
  • 쿠버네티스에서 컨테이너와 같다고 생각
  • 도커에서는 단일 컨테이너가 가장 작은 단위의 객체인 반면, 쿠버네티스에서는 파드 내에 여러 개의 컨테이너가 존재할 수 있음.
  • 파드의 공유 컨텍스트는 Linux namespace, cgroup 및 도커 컨테이너를 격리하는 것과 같이 잠재적으로 서로 다른 격리 요소들임.
  • 파드 안의 컨테이너들은 IP주소와 포트 공간을 공유하고, localhost를 통해 서로를 찾을 수 있음.
  • 도커의 구조 관점에서 보면 파드는 공유 네임스페이스와 공유 볼륨을 가진 도커 컨테이너 그룹으로 모델링 됨.

1) 생명주기
: 파드의 상태들
(파드가 생성, 변경되었을 때 파드의 상태 부분에서 확인 가능 )

- Pending : 파드가 쿠버네티스 시스템에 의해 승인되었지만, 파드를 위한 하나 또는 하나 이상의 컨테이너 이미지 생성이 아직 완료되지 않은 상태.
- Running : 파드가 한 노드에 결합되었고, 모든 컨테이너 생성이 완료. 적어도 하나의 컨테이너가 동작 중이거나, 시작 또는 재시작 중에 있는 상태
- Succeeded : 파드에 있는 모든 컨테이너가 성공적으로 생성된 상태 
- Failed : 파드에 있는 모든 컨테이너가 종료되었고, 적어도 하나 이상의 컨테이너가 실패로 종료된 상태
- Unknown : 어떤 이유에 의해 파드의 상태를 얻을 수 없는 상태. 일반적으로 파드 호스트와의 통신 오류에 의해 발생함.

2) 파드 생성 (파드에 두 개의 컨테이너 포함 가능)

apiVersion: v1
kind: Pod
metadata:
		name: nodejs-app
spec:
		containers:
- name: nodejs-app
Image: uphiller/nodejs-hello-world
Ports:
- containerPort:3000
- name: mysql-app
Image: mysql
Env:
          -name: MYSQL_ROOT_PASSWORD
		  value : “1234”
		  Ports:
          - containerPort: 3306
  • kubectl apply -f pod.yaml : 파드 생성
  • kubectl get pod : 파드 조회
  • kubectl describe pod nodejs-app : 두 개의 컨테이너가 실행되었는지 확인

하나의 파드에 여러 개의 컨테이너를 배치시키면, 하나의 서비스에 필요한 부분들을 그룹핑 해서 파드 내의 컨테이너들끼리는 자유롭게 통신하고 다른 파드들과는 노출된 포트로만 통신할 수 있어서 하나의 마이크로서비스를 만드는 것과 유사한 형태를 만들 수 있음.

일반적으로 복제 관리를 해야 하기 때문에 사용자가 파드를 직접 만들지는 않음

디플로이먼트

  • 디플로이먼트는 파드와 레플리카셋에 대한 선언과 업데이트를 제공하는 상위 개념의 컨트롤러
  • 서비스를 파드만으로 운영하면 복제 불가능
  • 디플로이먼트 생성
  • 트래픽이 몰리는 상황이나 배포 상황에서 안정적인 서비스를 유지하기 위해서 복제의 조절은 필수적
  • 가장 중요한 부분이 replicas의 숫자임 : 복제 부분
  • 레플리카셋은 파드의 복제를 관리하고, 디플로이먼트는 복제를 포함한 파드를 생성하며 관리함.
  • 사용자가 직접 서비스를 위해 사용할 때는 파드 오브젝트 자체를 컨트롤하지 않고 디플로이먼트와 같은 컨트롤러를 사용하면 됨.

서비스

  • 파드에 접근할 수 있도록 정책을 정의하는 것.
  • 파드끼리 통신할 수 있도록 엔드포인트를 만들어 주고, 파드가 외부에 노출될 수 있도록 함.
- ClusterIP : 서비스가 클러스터-내부 IP에 노출되도록 한다.
- NodePort: 고정 포트(NodePort)로 각 노드의 IP에 서비스가 노출되도록 한다. 
- LoadBalancer : 클라우드 공급자의 로드 밸런서를 사용하여 서비스가 외부에 노출되도록 함. 외부 로드 밸런서가 라우팅되는 NodePort와 ClusterIP 서비스가 자동 생성됨.
- ExternalName : 값과 함께 CNAME 레코드를 리턴하여, 서비스를 externalName 필드의 콘텐츠에 맵핑함.

위 네 가지 옵션은 서비스가 파드를 노출해 줄 수 있는 방식을 나타낸 것.

  • kubectl apply -f nodejs.yaml : 이전에 생성한 디플로이먼트를 사용
  • kubectl expose deploy nodejs-app : 서비스 생성

인그레스

  • 클러스터 외부에서 클러스터 내부 서비스로 접속하도록 해줌.
  • 구성요소 : 인그레서 리소스, 인그레스 컨트롤러
  • 단일 파드를 노출하는 것은 kubectl expose 명령어를 사용하여 노출하는 것과 효과가 비슷하지만, 이외의 복잡한 상황에서는 인그레스가 더 많은 기능을 제공함.

스토리지
노드

  • 노드는 파드를 실행할 수 있는 물리적인 공간. 대부분 하나의 VM으로 구성되어 있음.
  • 노드 상의 서비스는 컨테이너 런타임, kubelet, kube-proxy를 포함함.
  • 노드 설치 ( join 명령어 추가)

3.4 네트워크

쿠버네티스 네트워크 구성도

  • 쿠버네티스는 여러 대의 노드로 구성되고 각 노드는 여러 개의 파드로 구성된다.
  • 쿠버네티스에서는 파드 간, 노드 간에 통신하는 네트워크 인터페이스를 제공함.
  • 파드의 상태를 관장하는 kubelet은 CNI를 통해 파드와 통신함
  • 대부분의 경우 파드는 싱글 컨테이너를 생성하여 운영됨.

Container Network Intefaces(CNI)

  • 쿠버네티스에서는 파드 간, 노드 간에 통신하는 네트워크 인터페이스를 제공함.
  • 네트워크 환경도 서드 파티에서 개발자 마음대로 개발할 수 있도록 인터페이스를 제공함.
  • 이를 직접 구현하기 어려울 수 있기 때문에 많은 종류의 서드 파티 플러그인이 존재함.
  • 이와 같은 플러그인을 CNI 플러그인이라 하며 여러 서드 파티 회사들이 지원하고 있음
  • 플러그인을 설치하지 않고 파드를 생성해보면 생성된 파드가 올바르게 생성되지 않음.

3.5 스케줄링

  • 쿠버네티스는 멀티 노드로 운영되며, 이는 여러 대의 노드를 한 대의 인스턴스를 사용하는 것과 같은 효과를 줌.
  • 사용자는 한 대의 인스턴스를 사용하는 것과 같은 느낌을 받지만, 여러 대의 노드를 다루는 쿠버네티스 입장에선 내부적으로 파드를 어떤 노드에 배치해야 하는지 결정해야 함.
  • 쿠버네티스에서 노드의 상황에 따라 어떤 방식에 의해 파드를 배치하는 것을 스케줄링이라 함.

3.6 구성 파일

  • 인프라를 코드로 관리하는 이유는 인프라를 마치 개발하는 소스처럼 다룰 수 있기 때문에 변경 관리가 유용하기 때문.
  • 오브젝트를 삭제 또는 변경하거나 정보를 볼 때마다 각각 명령어를 입력할 필요 없이 설정 파일을 기본으로 명령을 실행하며 되기 때문에 편리함.
  • 쿠버네티스의 중요한 요소들을 알아볼 때 대부분 yaml이라는 확장자로 된 설정 파일을 가지고 실습을 진행함.

설정 파일 일반적인 구성 팁

  • 쿠버네티스 오브젝트는 YAML 또는 JSON으로 작성된 오브젝트 구성 파일과 함께 kubectl 커맨드 라인 툴을 이용하여 생성, 업데이트 및 삭제할 수 있음.
    요구되는 필드
- apiVersion : 이 오브젝트를 생성하기 위해 사용하고 있는 쿠버네티스 API의 버전
- kind: 생성하려는 오브젝트의 종류
- metadata: 이름 문자열, UID 그리고 선택적인 네임스페이스를 포함하여 오브젝트를 유일하게 구분할 데이터
- spec : 오브젝트에 대하여 의도하는 상태
- diff 명령어를 사용하면 어떤 부분이 변경되었는지 볼 수 있음.
  • 의미가 통한다면 가능한 한 연관된 오브젝트들을 하나의 파일에 모아 놓는다.
  • kubectl 커맨드는 디렉토리만 지정해서 호출 가능함. 예를 들어 구성 파일들의 디렉토리에 대해 kubectl apply 호출 가능

4.1 쿠버네티스 적용

  1. 개발자가 자신의 컴퓨터에서 코딩을 하고 해당 애플리케이션을 도커 이미지로 만든다.
  2. 개발자가 도커 허브에 만들어진 도커 이미지를 푸시 한다.
  3. 쿠버네티스가 설치된 클러스터에서 해당 도커 이미지를 사용하여 파드를 생성하고 외부에 노출한다.
  • 프론트 페이지를 도커 이미지로 만듬.(ADD, COPY …)
  • 이미지 생성(docker build -t front .)
  • 로컬 컴퓨터에서 해당 이미지를 바탕으로 컨테이너를 만들어서 웹 페이지가 제대로 노출되는지 테스트
  • 생성된 이미지를 쿠버네티스가 설치된 인스턴스에서 사용하기 위해서는 해당 인스턴스에서 접속할 수 있는 레지스트리가 필요함. 이미지를 도커허브로 업로드
  • 이후 쿠버네티스가 설치되어 있는 마스터 인스턴스에 접속하여 도커 허브에 로그인
  • 단일 파드에 프론트, 백엔드, 데이터베이스를 배치해서 애플리케이션이 원활하게 동작하는지 확인
  • 세개의 컨테이너로 구성된 파드의 구성 파일임. 원래 특별한 상황이 아니라면 세 개의 컨테이너를 파드 내에 배치해서 사용하지는 않을 것임. 하지만 파드의 개수를 최소화하여 실습해볼 것임.
  • 스프링 애플리케이션과 데이터베이스가 통신을 해야 하는데, localhost를 이용하면 파드 내 컨테이너 간의 통신이 마치 하나의 컴퓨터에서 통신하는 것과 같기 때문에 신경쓰지 않아도 됨.
  • 구성 yaml파일을 실행하여 파드 생성 : kubectl apply -f board-app.yaml
  • 생성된 파드를 외부에 노출. ( 백앤드와 프론트 페이지에 대한 서비스 각각 생성)
  • 파드가 생성될 때 selector 부분에 지정한 라벨을 기입하여 해당 파드를 지정할 수 있도록 하였음. 그리고 파드 내의 프론트, 백엔드 컨테이너의 포트를 외부로 노출할 수 있도록 지정해 주었음.
  • 이후 구성 파일 실행 : kubectl apply -f board-app-svc.yaml
  • kubectl get -f board-app-svc.yaml : 클라우드에서 제공하는 공인IP를 통해 외부에 프론트 페이지와 백엔드 페이지가 노출되는 것을 볼 수 있음.
    노드의 스케줄링 금지
  • 여러 대의 노드가 존재한다면 쿠버네티스가 파드를 알아서 잘 배치할 것임.
  • 서비스 운영 중에 특별한 이유로 어떤 노드는 자원이 남아 있음에도 파드 배치를 중지해야 할 상황이 생긴다면 cordon 명령어 사용

5.1 헬름 : 좀 더 편하게 쓰는 쿠버네티스

  • 헬름은 쿠버네티스의 패키지 매니저임.
  • 쿠버네티스를 관리하면 수많은 YAML 파일을 관리해야 하며 환경 변수나 약간의 내용 차이에도 비슷한 YAML이 생김.
  • 이런 YAML을 사용하여 배포하는 부분을 패키지화 해서 관리해 주는 도구가 헬름.
  • 헬름은 사용자가 직접 사용할 수 있는 명령 도구인 헬름 클라이언트, 쿠버네티스 내부에서 헬름 클라이언트의 요청을 처리하는 헬름 서버인 틸러 두가지 구성 요소로 구성됨.
  • 헬름 설치
  • 헬름 클라이언트를 사용하면 로컬에서 차트를 개발할 수 있고 자바의 MAVEN 리포지토리나 노드의 NPM 처럼 원격 리포지토리를 사용할 수도 있음.
  • 리포지토리 추가 : 추가된 리포지토리에서 사용할 수 있는 많은 차트 리스트 확인 가능
  • 헬름을 이용하여 컨테이너 설치. ( 헬름을 사용하여 컨테이너를 설치하기 전에 설치를 원하는 컨테이너에 대한 차트가 존재하는지 확인해 보아야 함 : helm search repo)
  • helm search명령어 : hub, repo 명령어 사용해야 함
  • hub : 기본적으로 제공되는 hub 리포지토리에 대한 검색 기능. Docker hub와 비슷한 역할
  • repo 명령어를 사용하면 로컬 머신에서 설정된 리포지토리에 대한 검색을 할 수 있음.
  • repo에서 검색한 stable/nginx-ingress 차트 설치
  • 조회 결과를 보면 파드와 서비스가 한번에 설치되었음.
    --> 헬름은 쿠버네티스에 설치될 수 있는 부분을 간편하게 차트화 시켜서 관리하는 도구
  • hub.helm.sh : 헬름 허브 메인

5.2 Weave Scope를 이용한 모니터링

  • 쿠버네티스를 운영함에 있어서 모니터링은 매우 중요한 요소.
  • Weave Scope 직접 설치 : Weave Scope 프로그램을 위한 파드가 생성되었고 파드를 외부에 노출하여 접속할 수 있도록 서비스가 생성되었음.
  • 외부 ip접속 : 로드밸런서
    https://kubernetes.io/ko/docs/tutorials/stateless-application/expose-external-ip-address/
    : 외부 ip주소를 노출하여 클러스터의 애플리케이션에 접속하기
profile
코딩일지..

0개의 댓글