전자책 출간 알림 [마이크로서비스패턴 쉽게 개발하기]

티스토리 뷰

3. 한장으로 이해하는 쿠버네티스 리소스

쿠버네티스 리소스들을 개발 측면과 운영 측면으로 나누어 설명 하겠습니다.
개발자 분들은 개발 측면의 쿠버네티스 리소스만 이해해도 쿠버네티스를 사용하시는데 큰 불편은 없으실 겁니다.
이 장의 목적이 개발자를 위한 쿠버네티스 핵심을 전달하는 것이기 때문에 운영 측면의 쿠버네티스 리소스들에 대해서는 간략하게만 소개하겠습니다. 개발 측면의 쿠버네티스 리소스들은 이어지는 각 절에서 실습을 하면서 배워보도록 하겠습니다.

쿠버네티스 리소스Resource와 오브젝트Object 차이
많은 사람들이 쿠버네티스 리소스와 오브젝트라는 용어를 명확히 구분하지 않고 사용하고 있습니다.
리소스와 오브젝트간의 관계는 자바에서 클래스Class와 오브젝트(객체)의 관계와 정확히 동일 합니다.
클래스는 오브젝트의 공통된 특성과 행위를 추상화한 틀입니다. 오브젝트는 클래스라는 틀로 찍어낸 실제 객체입니다.
클래스와 오브젝트의 예는 아래와 같습니다.
Class Car: ‘색깔’과 ‘모델’이라는 속성과 ‘달린다’, ‘멈춘다'라는 행위가 정의된 틀
Object myCar: 빨간 ‘색깔'과 Model X라는 ‘모델'로 생성된 객체. 생성 예제) Car myCar = new Car()
쿠버네티스 리소스는 클래스와 동일하게 쿠버네티스 오브젝트를 생성할 때 사용하는 틀입니다.
예를 들어 ‘k get po’라고 했을 때 apple, banana와 같은 결과가 나왔다면 이때 apple과 banana는 쿠버네티스 오브젝트이고 파드가 쿠버네티스 리소스입니다.
쿠버네티스 리소스 리스트는 ‘kubectl api-resources’로 확인할 수 있습니다.

3.1 개발 측면의 쿠버네티스 리소스

인그레스Ingress, 서비스Service, 파드Pod, 컨피그맵ConfigMap, 시크릿Secret, PVC, PV, 워크로드 컨트롤러Workload Controller인 디플로이먼트Deployment, 스테이트풀셋StatefulSet, 데몬셋DemonSet, 잡Job, 크론잡CronJob이 개발 측면의 쿠버네티스트 리소스들입니다.

간단히 한 장으로 정리하면 아래 그림과 같습니다. 빨간색으로 표시된 것들이 쿠버네티스 리소스입니다.

파드Pod는 컨테이너들을 담고 있는 리소스입니다. 하나의 파드에는 여러개의 컨테이너가 존재할 수 있습니다. 쿠버네티스에서는 파드를 ‘작은서버’라고 생각해도 크게 틀리지 않습니다.
그래서 쿠버네티스에서 스케일링 한다는 것은 이 파드수를 늘이거나 줄인다는 의미입니다.

파드는 실제 서비스 시 장애 대응을 위해 최소한 2개 이상을 실행하여야 합니다. 그래야 한 파드가 장애가 나면 다른 파드로 서비스를 할 수 있으니까요.
이렇게 서버를 2개 이상 구성하는 것을 ‘이중화’라고 표현하고 한 서버의 장애 시 다른 서버로 대체하는 것을 ‘Failover’라고 말합니다.

서버가 2개 이상이므로 사용자의 요청을 어떤 서버로 연결할 지 분배해주는 무언가가 필요합니다.
이렇게 사용자의 요청을 분배해주는 것을 로드밸런싱(Load Balancing)이라고 합니다.
여기서 로드Load는 워크로드Workload의 약자이고 서비스를 제공하는 서버를 의미합니다. 쿠버네티스에서는 파드라고 할 수 있습니다.

서비스Service는 파드를 로드밸런싱 해주는 리소스입니다.
우리가 흔히 말하는 서비스와 헷갈릴 수 있는데 마이크로서비스Microservice의 Service라고 생각하시면 자연스러울 수 있습니다.
예를 들어 우리가 주문을 처리하는 마이크로서비스를 만들었다면 ‘주문 Service’라는 오브젝트를 생성하고, ‘주문 Pod’ 오브젝트를 여러 개 띄우면 되는 것입니다.

쿠버네티스 Service는 특수한 경우가 아니면 클라이언트(웹브라우저, 모바일앱 등)에서 접근할 수 없도록 생성합니다. 그렇다면 클라이언트에서 접근할 수 있는 주소를 제공하고 쿠버네티스 Service를 연결해 주는 무언가가 필요하겠죠 ?
그것이 바로 Service Load Balancer인 ‘인그레스ingress입니다.

그냥 Service를 외부에서 접근할 수 있도록 만들면 돼지 왜 복잡하게 인그레스ingress라는 리소스를 또 만들어야 할까요 ? 가장 큰 이유는 쿠버네티스 서비스를 외부에서 노출시킬 수 있는 수의 제한이 있기 때문입니다.
인그레스는 요청되는 주소의 경로에 따라 Service를 로드밸런싱할 수 있습니다.
예를 들어 ‘http://{ingress host}/order’로 요청되면 ‘주문 Service’를 연결하고, ‘http://{ingress host}/pay’로 요청되면 ‘Pay결제 Service’로 연결하도록 할 수 있습니다.

어플리케이션을 개발할 때 유연한 개발을 위해 환경변수를 많이 사용합니다.
예를 들어 데이터베이스를 연결할 때 데이터베이스 서버 주소, DB 사용자명, DB 사용자 암호를 지정해 줘야 하는데 이를 소스에서 하드코딩하면 안되겠죠 ? 왜냐하면 개발계, 검증계, 운영계에서 사용하는 데이터베이스 서버가 다 다른데 각 환경에 배포할 때 마다 소스를 바꾸는 것은 바보같은 짓이기 때문입니다. 데이터베이스 서버의 주소나 계정정보가 바뀔때도 문제가 되구요.
쿠버네티스에서 환경변수를 만들어 주는 리소스가 컨피그맵ConfigMap과 씨크릿Secret입니다.

어떤 리소스로 생성하던 어플리케이션에서는 환경변수처럼 읽어서 사용할 수 있습니다.
예를 들어 ConfigMap에 DB서버 주소와 DB사용자명을 DBHost, DBUsername으로 정의 했고, Secret에 DB사용자 암호를 DBUserPW라고 정의했다고 합시다.
Java어플리케이션이라면 System.getenv(“DBHost”), System.getenv(“DBUsername”), System.getenv(“DBUserPW”)와 같이 환경변수를 읽을 수가 있습니다.

그럼 ConfigMap과 Secret의 차이는 무엇일까요 ?
ConfigMap은 환경변수의 값을 평문으로 정의하고 Secret은 base64로 암호화해서 정의한다는 것입니다. 상대적으로 Secret이 보안을 약간 더 보장하기 때문에 암호나 API키와 같이 중요한 환경변수는 Secret으로 만들어야 합니다.
Secret은 보안을 보장하기 위한 다른 추가적인 방법도 제공 합니다.

어플리케이션은 처리를 위해 필요한 데이터를 읽거나 처리 결과를 저장하기 위해 데이터 저장소가 대부분 필요합니다.
어플리케이션이 데이터 저장소를 사용하기 위해 필요한 리소스가 PVC(Persistent Volume Claim)와 PV(Persistent Volume)입니다.
PVC는 데이터 저장소 사용 요청서이고 PV는 실제 데이터 저장소 정의 리소스입니다.
파드가 데이터 저장소를 연결하려면 PVC와 연결 되어야 하고, PVC와 PV가 연결(바인드-Bind)되어야 합니다.

지금까지 서버인 Pod, Pod 로드밸런서 Service, Service 로드밸런서 ingress, 환경변수 ConfigMap과 Secret, 데이터 저장소 사용을 위한 PVC와 PV를 설명했습니다.
마지막으로 파드를 배포하고 통제하는 리소스들인 워크로드 컨트롤러Workload Controller까지만 설명 하겠습니다.
파드에 담긴 어플리케이션의 성격에 따라 워크로드 컨트롤러는 아래 5종류가 있습니다.

  • 디플로이먼트Deployment: 보통 어플리케이션 배포 시 사용. 파드이름이 랜덤숫자로 만들어짐
  • 스테이트풀셋StatefulSet: 보통 DB 배포 시 사용. Pod 이름이 일련번호가 붙어서 만들어짐
  • 데몬셋DaemonSet: 항상 실행되어 무언가를 감시하거나 처리하는 데몬 성격의 어플리케이션 배포 시 사용. 한 노드(물리머신 또는 VM)에 항상 한개의 파드만 실행됨.
  • Job: 1회성으로 무언가 처리를 하고 종료되는 어플리케이션을 배포할 때 사용. 예를 들어 데이터 마이그레이션(이관) 작업을 하는 어플리케이션이나 어떤 작업의 사전 준비 상태를 체크하는 어플리케이션 같은 것을 배포할 때 사용
  • 크론잡CronJob: 1회성이 아닌 주기적으로 무언가 처리를 하는 어플리케이션을 배포할 때 사용

이 리소스들은 가장 기본적이고 중요하기 때문에 각 리소스의 역할과 관계에 대해 다시 한번 꼼꼼히 읽고 이제는 외우시기 바랍니다.

다음으로 파드와 다른 리소스들과의 차이 입니다.

모든 쿠버네티스 리소스 중 물리적으로 각 노드에 생성되는 것은 파드밖에 없다는 것입니다.
다른 리소스들은 특정 노드에 생성되는 것이 아니라 환경설정과 같은 논리적인 리소스입니다.
예를 들어 컨테이너하우스는 특정 창고의 어느 공간에 실재하지만 컨테이너 하우스 위치나 찾아가는 경로 정보는 실제 물리적으로 존재하는 게 아닌 것과 비슷합니다.
쿠버네티스를 좀 안다는 사람들도 파드와 다른 리소스들의 차이를 모르는 사람들이 매우 많습니다.

진짜 그런지 눈으로 확인해 보겠습니다.
배천노드에 작업 디렉토리인 ‘work’를 만들고 테스트할 야믈 파일을 내려 받습니다.

[root@osboxes work]# mkdir -p ~/work && cd ~/work
[root@osboxes work]# curl -L -o http-echo.yaml https://hiondal.github.io/k8s-yaml/3.3/http-echo.yaml


그리고 쿠버네티스에 배포합니다. 파드 ‘apple’과 ‘banana’, 서비스 ‘apple’과 ‘banana’, 인그레스 ‘http-echo’가 생성될 겁니다.

[root@osboxes work]# k apply -f http-echo.yaml
pod/apple created
service/apple created
pod/banana created
service/banana created
ingress.networking.k8s.io/http-echo created


파드 리스트를 확인해 보겠습니다. ‘-o wide’ 옵션을 이용하면 좀 더 많은 정보가 나옵니다.
아래와 같이 ‘NODE’열에 보면 파드가 어떤 노드에 생성되었는지 확인이 됩니다.

[root@osboxes work]# k get po -o wide
NAME     READY   STATUS    RESTARTS        AGE     IP                NODE      NOMINATED NODE   READINESS GATES
apple    1/1     Running   0               5m26s   192.168.235.150   worker1   <none>           <none>
banana   1/1     Running   0               5m26s   192.168.235.151   worker1   <none>           <none>
curl     1/1     Running   1 (4d17h ago)   4d17h   192.168.235.135   worker1   <none>           <none>


하지만 서비스와 인그레스는 노드 정보가 나오지 않습니다. 컨피그레이션과 같은 논리적 리소스일뿐이니까요.

[root@osboxes work]# k get svc -o wide
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE     SELECTOR
apple        ClusterIP   10.99.138.63     <none>        5678/TCP   5m51s   app=apple
banana       ClusterIP   10.106.213.177   <none>        5678/TCP   5m50s   app=banana
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP    4d18h   <none>
[root@osboxes work]# k get ing -o wide
NAME        CLASS    HOSTS   ADDRESS         PORTS   AGE
http-echo   <none>   *       169.56.70.201   80      5m55s



3.2 운영 측면의 쿠버네티스 리소스와 운영 방안

컨테이너화된 서비스 운영을 위해 어떤 것들이 필요할까요 ?
일반적인 IT시스템 운영과 크게 다르지 않습니다. 아래와 같은 업무들이 필요할 겁니다.

  • 서비스 헬스 체크: 주기적으로 서비스를 호출하여 정상적으로 응답하는지 체크
  • 모니터링: 네트워크, 물리/가상서버, 스토리지, 어플리케이션 등의 자원 사용 현황을 상시 모니터링
  • 로그수집: 웹서버와 어플리케이션의 로그를 수집하여 서비스 사용 통계나 장애 분석에 이용
  • 배포와 롤백: 새로운 버전의 서비스를 배포하고 문제 시 원상 복구 위해 롤백Rollback 처리
  • 보안: 계정 및 권한관리, 보안 정책(예: 로그인 통제 정책, 루트 계정 봉인 등) 관리


이러한 5가지 측면에서 쿠버네티스 운영과 관련한 리소스들과 방안들을 배워 봅시다.

3.2.1 서비스 헬스 체크

서비스 헬스 체크를 하는 방법에는 스타트업 프로브Startup Probe, 레디니스 프로브Readiness Probe , 라이브니스 프로브Liveness Probe가 있습니다.
스타트업 프로브는 파드 시작 시에만 수행하는 헬스 체크이고 라이브니스 프로브와 레디니스 프로브는 스타트업 프로브가 성공한 후 수행하는 헬스 체크입니다.
각 헬스 체크의 목적과 실패 시 처리는 아래와 같습니다.
레디니스 프로브를 서비스를 할 준비가 되어 있는지 사전 체크하는 수단으로 사용할 수도 있지만 그 목적으로는 스타트업 프로브를 사용하고 레디니스 프로브는 일시적 서비스 장애나 장애 시 잠시 그 파드로의 연결을 유보하는 수단으로 사용하는 것이 더 맞습니다.


예를 들어 컨테이너 실행 전에 대량의 데이터를 마이그레이션 해야 한다면 그 작업이 끝날때까지 파드 연결을 하지 않게 스타트업 프로브에서 체크 합니다. 레디니스 프로브를 이용하여 특정 주소를 호출 했을 때 3초 이상의 응답이 3번 있으면 일시적 장애로 판단하고 서비스를 격리 시킵니다. 응답 시간이 3초 내로 돌아 오면 다시 서비스가 시작 됩니다. 라이브니스 프로브를 이용하여 특정 주소를 호출 했을때 10초 이상의 응답이 2번 발생 한다면 회복할 수 없는 장애로 판단하고 그 파드를 재 시작 합니다.

세 방법 모두 체크하는 방법은 동일 합니다.
HTTP나 TCP 또는 리눅스 커맨드를 파드로 주기적으로 전송하여 응답이 오는지 체크하는 것입니다.

헬스체크는 파드를 컨트롤하는 워크로드 컨트롤러 오브젝트(디플로이먼트, 스테이트풀겟, 데몬셋, 잡, 크론잡) 정의 파일안에 정의 합니다.
사용하는 방법은 ‘12. 헬스체크를 위한 스타트업 프로브, 라이브니스 프로브, 레디니스 프로브’에서 실습하도록 하겠습니다.

3.2.2 모니터링

일반적인 시스템 모니터링 대상은 네트워크, 물리/가상서버, 스토리지, 어플리케이션입니다.
쿠버네티스 모니터링 환경이 갖춰진다고 기존의 모니터링을 모두 대체할 수 있는건 아닙니다. 기존 모니터링 환경은 그대로 사용하는 것이고 쿠버네티스 모니터링은 쿠버네티스 클러스터와 관련된 대상을 모니터링 합니다.
쿠버네티스의 물리적인 구성 단위를 생각해 보면 그 대상이 뭔지 추측할 수 있을 겁니다.
바로 클러스터, 노드, 파드입니다. 추가적으로 데이터 저장을 위한 퍼시스턴트 볼륨(PV)도 중요한 모니터링 대상입니다. 클러스터, 노드, 파드는 주로 CPU와 메모리를 모니터링 하고 퍼시스턴트 볼륨은 볼륨 사용량같은 것을 모니터링 합니다.
쿠버네티스 모니터링 환경 구성을 위해 제일 많이 사용하는 툴이 프로메테우스Prometheus와 그라파나Grafana입니다.
프로메테우스는 쿠버네티스 클러스터와 연결하여 메트릭Metric(사용량)을 수집하고 저장합니다.
그라파나는 프로메테우스에 저장된 메트릭 정보를 대시보드 화면으로 제공해 줍니다.
모니터링에 대한 실습은 ‘15. 더 알면 좋을 주제들'에서 조금 더 설명 합니다.

3.2.3 로그 수집

일반적인 시스템 운영에 있어 로그 수집은 웹서버와 어플리케이션의 로그를 수집하여 서비스 사용 통계나 장애 분석에 이용하는 것입니다. 이중 웹서버의 로그를 수집하는 것은 기존 운영툴을 그대로 사용하면 됩니다.
쿠버네티스 클러스터에 어플리케이션을 컨테이너로 실행하면 더 이상 기존의 방법으로는 어플리케이션 로그를 수집할 수가 없습니다.
컨테이너로 서비스 하지 않을 때는 어플리케이션 로그를 Log4J같은 걸 이용해서 로그 파일에 기록하지만 컨테이너로 서비스하는 어플리케이션은 로그를 콘솔에 남겨야 합니다. 자바라면 System.out, Node.js라면 console.log 로 남겨야 한다는 말입니다.
왜일까요 ? 컨테이너는 언제라도 없어지거나 재시작할 수 있기 때문입니다. 컨테이너 안의 로그파일에 로깅을 했는데 그 컨테이너가 삭제되거나 재시작하면 그 로그파일들은 모두 사라지게 됩니다.

콘솔에 남긴다고 자동으로 로그가 수집되는건 아닙니다.
쿠버네티스에서는 통합로깅을 위해 EFK스택 또는 ELK스택이라는 툴 모음을 사용합니다.
EFK스택은 엘라스틱서치Elasticsearch, 플루언트디Fluentd, 키바나Kibana의 앞자를 모은 용어이고 ELK스택은 엘라스틱서치Elasticsearch, 로그스태시Logstash, 키바나Kibana의 앞자를 모은 용어입니다.
Fluentd 또는 Logstash는 각 컨테이너 내의 어플리케이션이 콘솔에 남긴 로그를 수집하는 툴입니다.
Elasticsearch는 수집된 로그를 저장하는 데이터베이스입니다.
Kibana는 Elasticsearch에 저장된 데이터를 이용하여 로그를 조회하고 검색하는 화면을 제공하는 툴입니다.
쿠버네티스 통합 로깅에는 대부분 EFK스택을 더 많이 사용합니다.
‘13. 통합 로깅을 위한 EFK 스택’에서 EFK 스택에 대해 좀 더 설명하겠습니다.

3.2.4 배포와 롤백 그리고 자동 스케일링

일반적인 시스템 운영에 있어 새로운 버전의 배포와 롤백이 중요 업무이듯이 쿠버네티스 환경에서도 서비스를 파드로 배포하고 롤백하는 것은 매우 중요합니다. 쿠버네티스 환경에서는 또 하나 중요한 것이 자동 스케일링입니다.

서비스를 무중단으로 배포하는 전략에는 롤링Rolling, 블루/그린Blud/Green, 카나리Canari가 있습니다.
롤링은 과거 버전 서비스는 하나씩 줄이고 새 버전 서비스는 하나씩 늘려서 배포하는 방법입니다.
블루/그린은 새 버전을 배포한 후 과거 버전으로 서비스 하다가 한 순간에 네트워크 트래픽을 새 버전으로 바꾸는 방법입니다. 맨 앞단의 로드밸런서에서 경로만 바꿔주면 간단히 할 수 있습니다.
카나리는 새 버전을 배포하고 네트워크 트랙픽의 일부만 새 버전으로 연결시키는 방법입니다. 새 버전에 대한 사용자 반응을 측정할 때 많이 사용합니다.

쿠버네티스의 기본 배포 전략은 롤링입니다. 블루/그린과 카나리도 구현할 수는 있지만 제대로 구현하려면 이스티오나 스프링클라우드와 같은 또 다른 툴이 필요합니다.
‘15. 더 알면 좋은 주제들'에서 기본 쿠버네티스에서 구현할 수 있는 세가지 전략을 조금 더 설명하고 이스티오는 별도의 장에서 다루도록 하겠습니다. 스프링클라우드는 이 책에서 다루기에는 내용이 많아 이후에 다른 책으로 만들 생각입니다.

서비스 인스턴스인 파드 수를 자동으로 증감시키는 자동 스케일링은 컨테이너 운영에 있어 반드시 필요한 작업입니다.
스케일링은 크게 수평 스케일링Horizontal Scaling과 수직 스케일링Vertical Scaling으로 나눌 수 있습니다.
수평 스케일링은 파드 수를 늘이거나 줄이는 것을 의미하고 수직 스케일링은 파드가 사용하는 CPU와 메모리를 늘이거나 줄이는것을 말합니다. 바닐라 쿠버네티스는 수직 스케일링은 지원하지 않습니다.

자동으로 수평 스케일링을 위한 쿠버네티스 리소스가 HPA(Horizontal Pod Autoscaler)입니다.
HPA는 CPU나 메모리 사용량을 기준으로 파드 수를 자동으로 증감 시켜 줍니다. 그 외 다른 커스텀 메트릭 정보를 기준으로 자동 스케일링을 할 수도 있습니다.
HPA에 대해서는 ‘15. 더 알면 좋은 주제들'에서 조금 더 다루도록 하겠습니다.

3.2.5 보안

일반적인 시스템 운영에 있어 인증 및 권한관리, 보안 정책 관리가 중요 하듯이 쿠버네티스에서도 클러스터를 접근하는 계정의 인증 및 권한 관리, 파드 보안 정책, 파드간 통신 제어가 안정적인 운영을 위해 중요 합니다.

1) 인증 및 권한관리
쿠버네티스를 접근할 수 있는 계정의 종류에는 두가지가 있습니다. 일반 사용자 계정과 시스템 계정입니다.
시스템 계정을 서비스 어카운트ServiceAccount라고 합니다.
일반 사용자 계정은 쿠버네티스 자체적으로 관리하거나 외부 시스템과 연동하여 관리할 수 있습니다.
외부 시스템은 계정관리 툴인 엘답LDAP이나 키클록Keycloak, 구글이나 카카오같은 OAuth 서비스 제공자, SSO(Single Sign On)솔루션, 직접 운영하는 계정관리 데이터베이스일 수 있습니다.
자체적으로 관리할때는 사용자가 쿠버네티스 접근 시 사용한 사용자ID와 암호/인증토큰 또는 인증서 데이터를 내부에 저장된 데이터와 비교하는 방식을 사용합니다.

외부시스템과 연동할때는 외부 시스템에서 사용자 ID/암호를 관리하고 쿠버네티스 클러스터 접근 시 외부시스템과 연동하여 ID와 암호가 맞는지 검사하는 방식입니다.
서비스 어카운트는 쿠버네티스에서 자체적으로 관리하는 방식의 하나이며 서비스 어카운트로 쿠버네티스 접근 시 사용한 인증서 데이터와 쿠버네티스가 갖고 있는 인증서 데이터를 비교하여 인증합니다.
인증 방식에는 아래와 같이 여러 방법이 있습니다. 하나의 인증 방식을 선택하거나 여러 방식을 조합하여 사용할 수 있으며 어떤 인증 방식을 사용할지는 상황에 따라 결정하여야 합니다.

- 기본 인증: ID와 암호 또는 인증 토큰을 이용한 인증 방식으로 일반 유저와 서비스 어카운트에 따라 이용 방법 다름
- X.509 인증서 기반 인증: X.509 인증서의 프라이빗키/퍼블릭키 비교 방식을 이용한 인증 방식
- OAuth 서비스 프로바이더 연동 인증: OAuth2.0으로 외부 OAuth서비스 프로파이더와 연동한 인증 방식
- WebHook 연동 인증: WebHook으로 인증 시스템을 연동한 인증 방식
- 프락시 서버 연동 인증: 프락시 서버로 인증 시스템을 연동하고 X.509 인증서 기반 인증을 조합한 인증 방식

 

 





기본 인증(일반 유저)


기본인증(서비스 어카운트)

X.509 인증서 기반 인증


OAuth 서비스 프로바이더 연동 인증

OAuth의 전체 인증/인가 순서는 아래와 같으며 위 그림은 11단계 ~ 14단계 수행 시 쿠버네티스에서 어떻게 인증 되는지 표현한 것입니다. 아래 그림에서 ‘백엔드 서비스'가 쿠버네티스라고 생각하시면 됩니다.




WebHook 연동 인증


프락시 서버 연동 인증



위 방식 중에 ‘기본 인증(일반 유저)’방식은 특수한 상황이 아니라면 실무에서 사용하기 어렵습니다.
실무에서 활용할 수 있는 방식 중 ‘기본 인증(서비스 어카운트)’, ‘X.509 인증서 기반 인증', ‘WebHook 연동 인증'을
‘14. 인증과 알백 방식의 인가'에서 실습해 보도록 하겠습니다.

인증을 통과한 계정에 대해 권한을 통제하여야 합니다.
쿠버네티스에서 계정에 권한을 부여하는 방식은 알백(RBAC-Role Based Access Control)이라는 방법입니다.
아래 그림과 같이 RBAC은 계정, 역할, 역할 바인딩으로 구성되어 동작 합니다.
클러스터롤ClusterRole과 롤Role은 권한에 대한 명세가 담긴 리소스 입니다. 여기서 권한이란 쿠버네티스 오브젝트에 대한 CRUD(Create, Read, Update, Delete) 수행 권한을 의미 합니다.

알백 방식은 계정에 역할을 바로 부여하는 것이 아니라 클러스터롤바인딩 또는 롤바인딩과 같은 역할 바인딩 오브젝트를 만들어 권한을 부여합니다. 중간에 역할 바인딩 오브젝트를 만드는 것이 훨씬 유연한 권한관리를 할 수 있기 때문입니다.
‘Cluster’가 앞에 붙어 있는 ClusterRoleBinding과 ClusterRole은 특정 네임스페이스가 아닌 클러스터 전체에 걸친 권한 관련 오브젝트이고 RoleBinding과 Role은 특정 네임스페이스에만 부여하는 권한 관련 오브젝트입니다.
다시 말해 어떤 계정이 특정 네임 스페이스를 접근할 때의 권한을 부여하고 싶으면 롤바인딩 오브젝트를 만들면 되고 모든 네임스페이스에 대한 권한을 부여하고 싶으면 클러스터 롤바인딩 오브젝트를 만들면 됩니다.
클러스터 롤 바인딩 오브젝트는 클러스터 롤 오브젝트만 참조할 수 있고 롤 바인딩 오브젝트는 클러스터롤과 롤 모두 사용할 수 있습니다.


클러스터롤은 기본으로 ‘cluster-admin’, ‘admin’, ‘edit’, ‘view’가 제공 됩니다.
cluster-admin과 바인딩 되면 클러스터에 대한 모든 권한을 가지게 됩니다.
admin과 바인딩 되면 네임 스페이스 관련한 편집 권한 외의 모든 권한을 가지게 되며 edit와 바인딩 되면 클러스터롤, 롤, 클러스터롤 바인딩, 롤 바인딩 외의 모든 권한을 갖습니다.
view와 바인딩 되면 모든 오브젝트에 대해 조회 권한만 갖습니다.

<팁>
위 4가지 클로스터롤은 부여하는 권한이 너무 넓어서 실무에서는 직접 롤을 만들어사 사용하는 것이 좋습니다.
</>

실제 예를 들어 알백 방식을 이해해 보겠습니다.
유저 ‘admin’에게 전체 네임스페이스에 대한 관리자(admin) 권한을 주려면 어떻게 해야 할까요 ?
아래와 같이 클러스터 롤 바인딩 오브젝트를 만들면 됩니다.

k create clusterrolebinding crb-admin --user=admin --clusterrole=admin 


유저 ‘user1’에게 ‘order’ 네임스페이스에 대한 관리자 권한을 주려면 아래와 같이 하면 됩니다.

k create rolebinding rb-oder-user1 --user=user1 --clusterrole=admin -n order


물론 기본 롤이 아닌 자신만의 롤 오브젝트를 만들어서 롤 바인딩 하는 것도 당연히 가능 합니다.
알백에 대해선 ‘14. 권한관리를 위한 RBAC’에서 조금 더 다루도록 하겠습니다.

2) 파드 보안 정책과 보안 설정: PodSecurityPolicy, PodSecurityContext
파드 보안 정책을 관리하는 리소스는 파드 시큐리티 폴리시PodSecurit Policy입니다.
파드가 실행될 때 먼저 이 정책을 검사하고 정책을 위반하지 않아야 실행 됩니다.
대표적인 보안 정책은 파드를 루트로 실행 못 하게 하는것과 파드의 호스트 OS 커널 접근을 통제 하는 것입니다.

파드 시큐리티 컨텍스트PodSecurityContext 는 파드의 보안관련 설정입니다.
파드 시큐리티 컨텍스트는 워크로드 컨트롤러나 파드 정의 파일안에서 ‘securityContext’항목에 정의 합니다.
정의할 수 있는 설정은 컨테이너의 실행 OS유저/그룹, 호스트 OS 커널에 대해 수행할 수 있는 명령입니다.

파드 시큐리티 컨텍스트에 정의한 보안 정책과 파드 시큐리티 폴리시에 정의한 보안 설정이 충돌하면 파드 시큐리티 폴리시의 보안 정책이 우선 됩니다.
예를 들어 파드 시큐리티 컨텍스트에서 루트 계정으로 실행하도록 정의해도 파드 시큐리티 폴리시에서 루트로 파드를 실행 못하게 했다면 그 파드는 실행되지 않습니다.

파드 시큐리티 폴리시는 쿠버네티스 1.21버전부터 EOS(End Of Service)되었고 1.25버전부터 더 이상 지원되지 않습니다. 어드미션 컨트롤Admission Control 이라는 방식으로 대체 되었으므로 현재 사용하고 있거나 새로 쿠버네티스를 사용하고자 하는 분들은 공식 문서를 확인하여 준비를 하시기 바랍니다.
관련된 공식 문서는 아래 링크에 있습니다.
https://kubernetes.io/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future

파드 시큐리티 폴리시를 대체하는 어드미션 컨트롤과 파드 시큐리티 컨텍스트는 개발자가 깊이 알 필요는 없습니다.
어드미션 컨트롤에 대해서는 아래 블로그에 잘 나와 있으니 참고 하십시오.
https://coffeewhale.com/kubernetes/admission-control/2021/04/28/opa1/

시큐리티 컨텍스트는 이후의 과정을 진행하면서 꼭 알아야 할것만 설명 하도록 하겠습니다.

3) 파드간 통신 제어: NetworkPolicy
파드간 통신을 제어하는 리소스는 네트워크 폴리시NetworkPolicy입니다.
네트워크 폴리시를 통해 파드로 들어오고 나가는 네트워크 트래픽을 제어할 수 있습니다.

지금까지 설명한 운영 측면에서의 쿠버네티스 리소스와 운영방안을 요약하면 아래 그림과 같습니다.
빨간색으로 표시된 것들이 쿠버네티스 리소스들이고 나머지 것들은 리소스 내에 지정하는 방법이나 운영을 위한 방법 또는 툴입니다.

 

쿠버네티스 쉽게 이해하기 시리즈 목차

[쿠버네티스 쉽게 이해하기 1] 쿠버네티스 설치하기
[쿠버네티스 쉽게 이해하기 2] 쿠버네티스 아키텍처
[쿠버네티스 쉽게 이해하기 3] 한장으로 이해하는 쿠버네티스 리소스
[쿠버네티스 쉽게 이해하기 4] 쿠버네티스 개발에서 배포까지 실습
[쿠버네티스 쉽게 이해하기 5] 쿠버네티스 오브젝트 정의 파일 쉽게 만들기
[쿠버네티스 쉽게 이해하기 6] 꼭 알아야 할 쿠버네티스 주요 명령어
[쿠버네티스 쉽게 이해하기 7] 파드 실행 및 통제를 위한 워크로드 컨트롤러
[쿠버네티스 쉽게 이해하기 8] 파드 로드 밸런서 서비스
[쿠버네티스 쉽게 이해하기 9] 서비스 로드 밸런서 인그레스
[쿠버네티스 쉽게 이해하기 10] 환경변수 컨피그맵과 시크릿
[쿠버네티스 쉽게 이해하기 11] 데이터 저장소 사용을 위한 PV/PVC
[쿠버네티스 쉽게 이해하기 12] 헬스 체크를 위한 스타트업 프로브, 라이브니스 프로브, 레디니스 프로브
[쿠버네티스 쉽게 이해하기 13] 통합 로깅을 위한 EFK 스택
[쿠버네티스 쉽게 이해하기 14] 인증Authentication과 알백RBAC 방식의 인가Authorization
[쿠버네티스 쉽게 이해하기 15] 더 알면 좋을 주제들: 무중단 배포, 모니터링, HPA

댓글

전자책 출간 알림 [마이크로서비스패턴 쉽게 개발하기]