3. K8s 실전 활용을 위한 10단계

김하영·2021년 11월 21일
0

'15단계로 배우는 도커와 쿠버네티스' 기반으로 내용 정리하였습니다.

  • 클러스터 가상화
    K8s 클러스터를 논리적으로 분할하여 RBAC과 조합하여 운영 환경 구축

네임스페이스를 사용하여 K8s 클러스터를 논리적으로 분할하는 방법(=클러스터의 가상화)에 대해 알아보자.
설정 정보 및 보안 정보 관리, CPU 와 메모리 제한 설정 방법을 알아볼 것이다.

  • 클러스터 가상화가 필요한 이유는 무엇일까?

여러 개의 K8s 클러스터를 구성하고 운영할 수 있는 예산, 인력, 시간이 있다면 굳이 가상화를 할 필요는 없을 것이다.
그러나 현실적으로는 주어진 자원을 가장 효과적으로 운영하기 위해 하나의 K8s 클러스터를 여러 개 분할해서 사용한다.
(결론....돈을 아끼기 위해^^)

하나의 K8s 클러스터에 '운영 환경'과 '테스트 환경'에 해당하는 네임스페이스를 만들 것이다.
분리된 네임스페이스가 서로 영향을 미치지 않는지 확인하기 위해 다음과 같은 순서로 실습을 진행할 것이다.

  1. 네임스페이스(Namespace) 작성
  2. K8s 클러스터와 네임스페이스를 지정하는 kubectl 커맨드 설정
  3. 직원의 역할에 따라 액세스 권한 설정
  4. 보안이 필요한 정보(Secret)를 네임스페이스에 보존하고 이용
  5. 설정 파일(ConfigMap)을 네임스페이스에 보존하고 이용
  6. 리소스 제약(메모리,CPU) 설정
  7. 네임스페이스의 접근 제어 설정

네임스페이스(Namespace)

K8s 클러스터는 여러 개의 네임스페이스를 가질 수 있는데, 아래와 같은 네임스페이스를 가진다.
여기서는 명령어의 범위를 한정하기 위해 사용한다.

  • default : 기본 네임스페이스. 특별히 저정하지 않으면 기본으로 사용됨
  • kube-public : 모든 사용자가 읽을 수 있는 네임 스페이스. K8s 클러스터를 위해 예약된 공간
  • kube-system : 시스템이나 애드온(add-on)이 사용하는 네임스페이스

네임스페이스를 사용하여 논리적으로 구분할 수 있는 대상은

  • 명령어의 적용 범위
    kubectl get pod > 네임스페이스 default 영역의 pod 출력
    kubectl get pod -n kube-system > 쿠버네티스 시스템 관련 pod 출력
  • CPU 시간과 메모리 용량등의 리소스 할당
  • 파드 네트워크 통신의 접근제어

네임스페이스를 만들면 서비스 어카운트 default와 그에 대응하는 시크릿이 만들어진다.
시크릿에는 클라이언트 인증서, 네임스페이스의 이름, 서비스 어카운트의 토큰이 들어 있다.
시크릿은 이 네임스페이스에 있는 파드의 컨테이너에 마운트되어 사용된다.

하나의 K8s 클러스터에 운영환경과 테스트용 환경을 같이 돌리고 싶은 경우가 있다.
이때 하나의 네임스페이스 내에서 중복된 오브젝트의 이름이 허용되지 않기 때문에 매니페스트를 수정하여 오브젝트의 이름을 변경해야 하는 번거로움이 발생한다.

이런 경우에는 각 환경별로 네임스페이스를 만들어 관리하는 것이 좋다.

즉, 네임스페이스가 다르면 같은 이름의 오브젝트를 만들 수 있어 매니페스트를 관리하기 용이해진다.
같은 매니페스트를 각 네임스페이스에 배포할 수 있기 떄문이다.

네임스페이스에 배포된 서비스는 기본적으로 같은 네임스페이스의 파드에서 서비스의 이름만으로 접근할 수 있다. 그리고 네임스페이스에 배포된 컨피그맵과 시크릿도 같은 네임스페이스 파드에서 접근할 수 있다. 그래서 네임스페이스별로 바뀌는 정보들은 네임스페이스에 보관하는 것이 좋다. (시크릿/컨피그맵)

kubectl 커맨드의 네임스페이스 설정

kubectl을 사용할 때 네임스페이스를 지정하려면 옵션 '-n <네임스페이스명>'을 사용한다.
그러나 매번 네임스페이스를 지정하다 보면 실수가 발생할 수도 있다.

옵션을 지정하지 않았을 때 kubectl이 기본으로 사용하는 네임스페이스를 바꾸려면 kubectl config를 사용하면 된다. 그러면 여러 개의 K8s 클러스터 중에서 조작할 클러스터와 그 네임스페이스를 지정할 수 있다.

kubectl config는 마스터에 대한 접근 정보를 기반으로 한다.
kubectl이 마스터에 대한 정보를 얻는 방법은 다음과 같이 세 가지가 있다.

  1. 실행 시 옵션으로 지정 '-kubeconfig <config 파일_경로>'
  2. 홈 디렉터리 밑의 '.kube/config' 참조
  3. 환경 변수 KUBECONFIG에 지정된 경로 참조

클러스터, 인증 정보, 네임스페이스를 기반으로 콘텍스트를 등록하면 kubectl의 대상 클러스터와 네임스페이스를 쉽게 바꿀 수 있다.

[ 콘텍스트 추가와 기본 네임스페이스 변경 ]

## 콘텍스트 추가
## prod 라는 이름의 콘텍스트를 만들고 있다.

##
$ kubectl config set-context prod --namespace=prod --cluster=mycluster2 --user=takara 
Context "prod" creadted.

## prod 콘텍스트 사용
##
$ kubectl config user-context prod
Switched to context "prod".

## 현재 사용 중인 콘텍스트가 prod로 변경되었다.
## 이제 네임스페이스 prod가 기본으로 사용된다.

시크릿과 컨피그맵

애플리케이션의 설정 정보나 패스워드와 같은 인증 정보는 컨테이너에 담지 말고 분리하여 네임스페이스에 저장하고 컨테이너가 읽도록 해야 한다.
그러면 테스트 환경과 프로덕션 환경별로 컨테이너를 별도로 빌드할 필요가 없게 된다.

이미지의 빌드 횟수를 줄이는 것은 의도치 않은 버그를 미연에 방지하는 것과 연결된다.
테스트가 끝난 상태에서 다시 빌드하면 의도치 않은 변경 사항이 포함될 가능성이 생기기 때문이다.
이를테면, 라이브러리의 새로운 버전이 빌드에 포함될 수 있다.

따라서 컨테이너의 불변성(Immutable)을 유지하는 것이 중요하다.

  • 컨피그맵(ConfigMap) : 네임스페이스에 저장한 설정 정보
  • 시크릿(Secret) : 인증 정보와 같이 보안이 필요한 정보를 네임스페이스에 저장한 것

컨테이너에서는 이들 오브젝트를 파일 시스템으로 마운트하여 파일로 읽거나 환경 변수로 참조할 수 있다.

[ 시크릿 특징 ]

  • 시크릿은 패스워드, 토큰, 키처럼 보안이 필요한 데이터를 저장하는 데 사용한다.
    보안 데이터의 노출 리스크를 줄이기 위해 사용된다. 사이즈는 1MB 미만이어야 한다.
  • 서비스 어카운트를 만들면 서비스 어카운트의 토큰을 담은 시크릿이 네임스페이스에 자동으로 생성된다. 해당 토큰은 RBAC 기반의 접근 제어에 사용된다.

  • 사용자가 시크릿을 등록하면 파드의 환경 변수나 마운트된 볼륨의 파일을 통해 접근할 수 있다.
    모든 파드에는 secret 볼륨이 자동으로 연결되어 있기 때문이다.
  • 시크릿은 네임스페이스에 속하며 다른 네임스페이스에서는 읽을 수 있다.
  • 시크릿 자체는 암호화와는 직접적인 관계가 없으며 벤더가 제공하는 추가적인 암호화 기능을 사용할 수도 있다.
  • 파드가 시크릿을 사용하도록 설정했으면 기동하기 전에 시크릿이 존재해야 한다.

컨피그맵

컨피그맵은 시크릿과 비슷하게 사용된다. 환경에 따라 변하는 정보를 컨테이너에서 분리하여 컨테이너의 불변성과 재사용성을 높여 준다. 컨피그맵은 네임스페이스에 설정 정보를 저장하고 공유하는 것을 목적으로 한다.

[ 컨피그맵 특징 ]

  • 컨피그맵을 등록할 때는 시크릿처럼 값을 Base64로 인코드하지 않아도 된다.
  • 'kubectl describe secret'에서는 등록된 내용이 표시되지 않으나, 컨피그맵의 경우
    'kubectl describe configmap'으로 내용이 표시된다.
  • 시크릿과 컨피그맵은 정기적으로 갱신이 체크된다. 볼륨으로 마운트된 경우에도 kubectl 갱신 주기에 따른 지연이 있기는 하지만 자동으로 갱신된다.
  • 클러스터 롤 view의 대상 리소스에 시크릿은 포함되지 않지만, 컨피그맵은 포함된다.
    따라서 참조 권한만으로도 컨피그맵의 내용을 참조할 수 있다.

메모리와 CPU 할당과 상한 지정

쿠버네티스에서는 네임스페이스마다 CPU나 메모리의 최소 요구량과 최대 사용 제한을 설정할 수 있따.
예를 들어, 2개의 프로젝트가 하나의 K8s 클러스터를 공유하는 경우. 각 프로젝트에 대한 네임스페이스를 만들고 리소스를 할당할 수 있다. 그러면 하나의 애플리케이션이 무한 루프에 빠지더라도 운영환경에서 악영향을 끼치는 것을 방지할 수 있다.

네임스페이스에 리소스를 할당하는 방법은 Resource Quota와 Limit Range의 두 가지 방법이 있다.

  • Resource Quota : 네임스페이스별 리소스의 총 사용량을 제한한다. 여기서의 리소스란 컨테이너의 CPU 시간과 메모리량을 말하며 기동시에 확보하는 리소스의 합계량 및 상한 값을 설정한다.

  • Limit Range : CPU와 메모리 각각의 요구량과 최대량의 기본값을 설정한다.

네트워크의 접근 제어(Calico)

네트워크 정책을 네임스페이스에 적용하여 액세스 제한을 실시할 수 있다.
Calico를 사용하면 여러 네임스페이스 사이의 접근을 제한할 수 있다.

하나의 물리적 K8s 클러스터를 네임스페이스로 구분하여, 테스트 환경과 운영 환경이 존재한다.
운영환경의 문제를 분석하기 위해 테스트 환경에서 재현 테스트로 운영 환경의 데이터를 손상시키는 문제가 발생할 수도 있다. 이때 네트워크 정책을 적용하면 이러한 문제를 미연에 방지할 수 있다.

이러한 기능은 Calico가 활성화되어 있어야 한다.
이는 K8s 클러스터 내의 네임스페이스 간 상호 액세스 정책에 사용된다.

역할에 따른 접근 범위 제한

모든 직원에게 슈퍼 유저 권한을 주면 안되므로 직원의 역할에 맞게 권한을 부여해야 안정적으로 운영할 수 있다.

따라서, 각 네임스페이스에 서비스 어카운트를 작성하여 적절한 롤과 맵핑한 후 서비스 어카운트의 토큰을 담당 직원에게 전달한다.

  • 참고 :

https://nzzi.kr/kubernetes/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4.html

https://velog.io/@sanspareilsmyn/K8s-in-Action-7.-%EC%BB%A8%ED%94%BC%EA%B7%B8%EB%A7%B5%EA%B3%BC-%EC%8B%9C%ED%81%AC%EB%A6%BF-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EC%84%A4%EC%A0%95

profile
Back-end Developer

0개의 댓글