07-03 (2)

코코볼·2023년 7월 5일
0

네트워크 보안

목록 보기
35/35

https://kubernetes.io 사이트에 들어가면 하단에 Kubernetes Features가 보이는데 => 365 No Downtime 지양!!!
a. Automated rollouts and rollbacks (자동 변경 취소/되돌림)
b. Storage orchestration(저장소 관리)
c. Automatic bin packing(자동 실행파일 패키징)
d. Service discovery and load balancing(서비스 발견과 로드밸런싱)
e. Secret and configuration management(비번과 구성 관리)
f. Batch exection(배치 실행)
g. IPv4/IPv6 dual-stack(IPv4와 IPv6와 동시 사용)
h. Self-healing(오류 자동 수정)
i. Horizontal scaling(수평적 확장)
j. Designed for extensibility(확장성 고려) 등의 기법이라고 보인다.

도커와 컨테이너가 등장하면서 애플리케이션의 배포/관리(CI/CD) 방식에서 많은 부분의 변화가 불가피해졌는데 모든 세팅을 서버에서 직접할 필요가 없어졌고 애플리케이션을 서버에서 컴파일 할 필요도 없어졌다. 그리고 생성된 도커 이미지를 서버에서 실행시키기만 하면 되기 때문에 애플리케이션 관리도 컨테이너 중심으로 관리하는 생태계로 변화되었는데 이 컨테이너들을 관리해주는 도구가 쿠버네티스이다.

쿠버네티스는 간단하게 말하면 애플리케이션의 배포/관리를 수행해주는 도구로써 도커 이미지를 가져와서 실행하기도 하고, 실행중인 애플리케이션에 문제가 생겨을 떄 자동으로 복구해서 장애를 방지하기도 한다. 또 쿠버네티스를 사용하면 개발자가 직접 서버에 애플리케이션을 설피하고 배포할 필요가 없어지는데 쿠버네티스는 사용자가 배포서버에 있는 애플리케이션 이미지를 다운 받아서 별도의 조절 없이 이미지에 설정되어 있는대로 애플리케이션을 실행하기만 하면 되게 하고, 사용자가 급격하게 몰리면 스케일 조절을 통해서 애플리케이션을 수평적으로 확장해서 사용자가 접근하기 용이하게 해주고, 트래픽이 몰리면 여러 애플리케이션으로 부하를 분산해주는 로드 밸런싱을 수행해주기도 한다.

K8s는 노드 시스템이 모듈을 사용할 떄 Monolith 방식에서 Micro Service 방식으로 전환하므로써 컨테이너 사용을 증가시켜서 컨테이너의 고가용성, 컨테이너의 정지시간(downtime)감소, 확장성과 성능 증가, 백업과 복원을 통한 재난극복 등이 가능하게 한다. 또 CLI, APPs, 그리고 Server 등의 기능을 하는 Docker Engine을 Kubelet를 통해서 관리할 수 있다.
=> 간단히 말하면 컨테이너는 Volumes와 Network, 그리고 Build Images를 가지고 있는 Runtime Box로 볼 수 있다. K8s는 K8s CLI, K8s Volumes, 그리고 K8s Network를 가지고 있다. 컨테이너의 APPs를 배포하고 관리하는데 사용량 요청(Demand)에 따라서 APPs의 규모를 늘리거나 줄여서 Downtime이 없게 하고(Scaling), 문제가 있을 때 되돌릴 수 있다.(Rollback)

K8s에서의 용어 정리

K8s의 Cluster, Volumes, Pods, Service Ingress, SatatefulSet, Deployment, ConfigMap, 그리고 Secrets와 같은 요소들을 알아보자.

1. Cluster

  • 쿠베네티스에서 관리하는 가장 큰 단위로써 여러 노드들을 논리적으로 묶은 하나의 단위이다. 이 클러스터 내부에는 Hadoop에서처럼 실제로 Service를 담당하는 Worker Node와 이 Worker Node를 관리하는 Master Node가 존재한다. Cluster는 Ubuntu와 같은 노드들의 집합으로써 노드는 가상 머신이거나 물리적 머신이 될 수 있다. AWS, Azure, Google Cloud(GCP) 등이 바로 이 클라우드의 클러스터이다. 이 클러스터는 마스터인 Master 노드와 클라이언트인 Worker 노드들로 구성되는데 각 Worker 노드에는 node agent로 불리는 kublet명령어가 들어 있다. Master 노드는 클라이언트 Worker 노드들을 관리하기 위해서 Scheduler, Cluster sotre인 etcd, Controller Manager 등을 가지고 있다. Worker 노드는 APPs가 실행되고 있는 여러 Docker 이미지를 가지고 있는데 이들끼리는 IP_주소로 서로 통신한다.

    k8s는 key-value 구조로 Worker 노드들의 정보를 저장하고 있다. 그리고 메인 Master에 문제가 있을 경우를 대비해서 Backup-Master를 구성해 두기도 하는데 Worker 노드들은 문제가 있으면 교체/대체할 수 있지만 Master 노드에 문제가 생기면 클라우드 전체가 실행되지 않을 수 있기 때문이다. <= Backup-Master는 Hadoop의 SecondaryNameNode와 비슷한 역할으로 볼 수 있다.

2. Node

  • Ubuntu와 같은 물리적/가상 호스트(노드)를 의미하는데 1개의 노드는 곧 1대의 머신(가상 또는 물리)이고, 이 노드에는 여러 컨테이너가 실행될 수 있고, 각 컨테이너에는 APPs이 실행된다. K8s에서는 이들이 외부의 Pods로 표시한다. Docker로 해당 APPs의 이미지를 생성하고, Docker Hub에 업로드하면 쿠버네티스 네트워크상에서 해당 애플리케이션을 다른 컨테이너(Pod)에게 배포할 수 있다.
    <= GitHub와 같은 역할도 한다고 볼 수 있다.

3. Pod

  • K8s의 최소 단위이며 컨테이너의 추상화된 객체이다. 하나의 APPs 당 하나의 컨테이너가 존재하고 이는 하나의 Pod가 된다. Kube에서는 각 Pod별(컨테이너별)는 IP_주소로 서로 통신할 수 있다. 기존의 컨테이너가 크래시 되면 K8s가 새로운 IP를 가진 새로운 파드(컨테이너)로 자동 대체해준다.
    <=Kubernetes는 컨테이너를 Pod로 여긴다.

Apps 이미지를 올릴 수 있는 docker hub를 만들었다면, docker hub에서 필요한 이미지를 다운받아서 실행하면 컨테이너(Pod)를 생성할 수 있다. 하나의 컨테이너를 하나의 파드로 볼 수 도 있지만 여러 컨테이너가 실행되고 있고, 이 컨테이너에 외부에서 접근할 수 있는 인터페이스가 있을 떄를 파드로 볼 수도 있다.
=> 외부에서 접속할 수 있도록 IP_주소를 가질 수 있는 인터페이스를 가지고 있는 컨테이너가 파드인 셈이다.

Pod의 여러가지 특징
a. 쿠버네티스에서는 도커 컨테이너처럼 Pod를 언제든지 버리고 새로 만들 수 있다.
b. Pod는 인터페이스가 있어서 자신만의 가상_IP를 부여받지만 Pod가 새로 생성될 때마다 이 IP는 바뀐다. 즉 IP가 유동적으로 바뀌기 때문에 Pod를 독자적으로 배포한다면 IP를 설정하기가 까다로운데, Pod는 가상 IP를 가지고 있고 변경될 수 있기 때문에 외부에서 이 Pod의 IP주소로 직접 접근하지 않고 실제로 이들을 대표해서 접근할 수 있는 Service를 통한 경로 설정이 별도로 필요하다.
<= Java 프로그램에서의 Interface 기능과 유사하다. Super Daemon과도 역할이 비슷하다고 볼 수 있다.
c. Pod는 언제든지 장애가 발생하면 죽을 수 있다. 즉 애플리케이션이 중단될 가능성을 가지고 있다.
d. 사용하는 Image를 새로운 버전으로 업데이트하고 싶다면 모든 Pod를 새로운 애플리케이션으로 업데이트해야한다. Pod는 이미 만들어진 컨테이너로만 작동하기 때문에 업데이트된 버전으로 실행하고자 한다면 현재 존재하는 Pod를 하나씩 제거하고 새로운 버전의 이미지를 가진 새 Pod를 생성해서 하나씩 교체하는 방식으로 진행된다. 하지만 Auto Scaling 기능으로 인해서 총 실행되는 파드 수는 일정해야 하므로, 예를 들어서 10대 파드에서 업그레이드 한다면 실제 파드는 업그레이드 동안 11대가 실행되어서 실제 10대가 운영되고 하나씩 정지해서 업그레이드해 나아간다.

4. Service

  • 서비스는 Pod의 유동적 IP_주소의 문제를 해결해준다. Pod(컨테이너)는 Service를 가지고 있고, Service는 영구적 IP주소를 가지고 있다. 따라서 Service는 언제든 바뀔 수 있는 Pod의 IP를 사용하지 않고 Pod를 참조하는 가상 IP를 미리 정해서, Pod의 IP가 변하면 자동으로 서비스의 고정 IP와 연동(mapping)되게 해준다. Service는 고정 가상_IP를 가지기 때문에 Service를 제거하지 않는 한 IP가 변하지 않아서 파드를 외부와 연동시키기에 적합하다.
    서비스가 특정 파드를 지정하게 해줄 수도 있는데 Pod를 생성할 때 특정 라벨을 붙여놓으면 도커 실행 시 Service가 해당 Pod를 인식해서 해당 라벨의 도커 컨테이너(파드)와 연결된다. 예를 들어 API를 생성할 때 "app:serv1_app"이라고 라벨을 붙여두고, Service를 생성할 때 selector로 이 라벨을 지정하면 Service는 이 라벨이 붙어있는 Pod를 찾아서 자신이 관리하는 객체로 등록시키고, 자신의 고정 IP를 통해서 해당 파드를 외부와 연결시켜준다.
    Service가 Pod를 지시하고 있지만 Service와 Pod의 '생명주기'는 다르다. Pod는 컨테이너가 크래시되면 새로 생성되어서 다른 IP주소를 가진 객체로 대체되지만, 외부로 보이는 Service는 IP주소가 지속되기 때문에 이 Service를 통해서 새로 생성된 Pod에도 접속할 수 있다.

  • 도커 컨테이너에서 실행되고 있는 my-app는 Service면서 Pod이다. 실제 DB 서비스는 컨테이너에서 실행되고 있고, 이 DB 서비스를 외부로 표시해주는 것이 Pod이고, 파드가 외부와 통신하게끔 IP_주소 등으로 연결시켜주는 것이 Service이다.

  • 컨테이너(Pod)의 Service는 웹브라우저로만 통신이 가능하다. 예를 들어 DB APPs인 my-app 파드(80:80:80 매핑)에 외부에서 브라우저를 통해서 접속한다면
    http://my-app.com:80(외부_브라우저)의 Ingress과정
    -> https://my-app.com:8080(파드)의 External Service과정으로 실행된다.
    내부 컨테이너 Pod DB의 Service에 외부에서 직접 접속하는 Internal Service는 불가하다.

0개의 댓글