728x90
쿠버네티스 모범 사례을 요약한 내용입니다.
- 서비스 운영중 런타임에 설정 데이터를 컨테이너에 전달 할 수 있음
- 설정을 효과적으로 변경 가능
- 민감한 데이터는 시크릿과 같은 방법으로 전달 해야함
- RBAC로 특정 사용자나 그룹의 API 이용에 대한 정교한 권한 구조를 구현할 수 있음
4.1 컨피그맵과 시크릿을 통한 설정
컨피그맵과 시크릿의 중요한 차이는 파드가 수신 정보를 저장하는 방식과 데이터가 etcd에 저장되는 방식 차이
4.1.1 컨피그맵
- 컨테이너를 사용해 애플리케이션과 설정 정보를 분리할 수 있음
- 컨피그맵 API를 이용해 전달받은 설정 정보를 주입할수 있음
- 컨피그맵은 유연성이 뛰어나기 때문에 다양한 처리를 할수 있음
- 키/쌍, JSON, XML 등 으로 전달 가능
- 설정 정보 뿐만 아니라 컨트롤러, CRD, 오퍼레이터 등 복잡한 시스템 서비스로 정보 제공 가능
- 민감한 데이터는 시크릿 API가 더 적합
- 파드에 볼륨 마운트 하거나 환경변수로 전달 가능
4.1.2 시크릿
- 컨피그맵 API와 대부분 기능이 비슷함
- 시크릿 데이터는 BASE64로 인코딩된 정보로 표현됨
- 암호화는 되지 않지만 다른 처리를 하면 가능
- 파드에 주입되자마자 일반 텍스트 형태로 보여짐
- 시크릿 데이터는 BASE64로 인코딩된 1MB로 제한되는 소량의 데이터를 의미
- 인코딩 오버헤드를 고려하면 대략 750KB 정도
- 시크릿에는 세가지 타입이 있음
- generic
- 일반적인 키/값 쌍
- 파일, 디렉터리, 문자열 리터럴로 생성
- kubectl create secret generic mysecret --from-literal=key1=$3cr3t1 --from-literal=key2=@3cr3t2
- docker-registry
- 개인 도커 레지스트리 인증에 필요한 신원
- image Pullsecret에서 지정하면 kubelet이 파드 템플릿으로 전달
- tls
- 공개/개인 키 쌍으로 전송 계층 보안(TLS) 시크릿을 생성
- cert가 올바른 PEM 포멧이라면 키 쌍은 시크릿으로 인코딩되어 SSL/TLS를 이용할 파드로 전달
- generic
- 시크릿은 자신을 사용하는 파드가 있는 노드의 tmpfs에만 마운트됨
- 파드가 종료될 때 시크릿은 삭제됨
- 보안상 안전해보이지만 기본적으로 시크릿은 etcd 데이터 스토리지에 평범한 텍스트로 저장 됨
- etcd에 데이터를 저장할 때 암호화를 하는등의 etcd 환경의 보안에 신경 써야함
- 쿠버네티스 최신 버전에서는 ectd3를 사용하며 네이티브 암호화를 지원함
- 쿠버네티스 v1.10부터 KMS(Key Management Server) 공급자를 제공
4.2 컨피그맵과 시크릿 API 모범 사례
- 컨피그맵이나 시크릿을 사용할 때 대부분의 문제는 업데이트될 때 변경사항이 어떻게 처리되는지 알지 못하기 때문에 발생
새로운 버전의 파드를 다시 배포하지 않고 애플리케이션의 동적 변경 방법
- 컨피그맵과 시크릿을 볼륨으로 마운트
- 변경된 파일 데이터를 감지하고 필요에 따라 재설정 하려면 애플리케이션을 파일 감시자로 설정
- apiVersion: v1 kind: ConfigMap metadata: name: nginx-http-config namespace: myapp-prod data: config: | http { server { location / { root /data/html; } location / { root /data; } } } apiVersion: v1 kind: Secert metadata: name: myapp-api-key type: Opaque data: myapikey: YWRtd5thSaW4= apiVersion: apps/v1 kind: Deployment metadata: name: mywebapp namespace: myapp-prod spec: containers: - name: nginx image: nginx ports: - containerPort: 8080 volumMounts: - moutPath: /etc/nginx name: nginx-config - mountPath: /usr/var/nginx/html/keys name: api-key volumes: - name: nginx-config configMap: name: nginx-http-config items: - key: config path: nginx.conf - name: api-key secert: name: myapp-api-key secertname: myapikey
시크릿 관련 모범 사례
- 해시코프 볼트, 아쿠아 컨테이너 보안 플랫폼, 트위스트락, AWS 시크릿관리자, 구글 클라우드 KMS, 애저 키 볼트와 같은 솔루션을 통해 쿠버네티스보다 더 높은 수준의 암호화 및 감사 기능을 제공하는 외부 스토리지 시스템을 이용할 수 있음
- pod.spec에 선언하지 않고 파드가 자동으로 시크릿을 마운트하기 위해 impagePullSecrets을 serviceaccount에 할당, 네임스페이스에 기본 서비스 계정을 패치하고 imagePullSercets을 추가하면 네임스페이스의 모든 파드에 자동으로 전달
- 배포 파이프라인 과정에서 CI/CD를 사용하여 하드웨어 보안 모듈로 보안 볼트나 암호화된 스토리지에서 시크릿을 가져옴
- 보안 관리 팀은 시크릿을 생성하고 암호화를 담당하고 개발팀은 시크릿의 이름만 참고 하는 방법으로 직무에 대한 책임을 분리하는 방법
4.3 RBAC
- 대규모 분산 환경에서 작업할 경우, 특정 보안 메커니즘을 통해 중요 시스템에 대한 무단 접근을 방지
- 시스템 리소스에 대한 접근을 제한하는 방법에는 수많은 전략이 있지만 대다수가 같은 절차를 거침
쿠버네티스 시스템에서 일어나는 프로세스를 해외여행에 빗대어 설명
- 여권(사용자 계정)
- 여권은 누구인지 증명
- 쿠버네티스는 사용자를 인증하기 위해 외부 권한에 의존함
- 서비스 계정은 쿠버네티스가 직접 관리
- 비자 또는 여행 정책(권한):
- 비자의 유형에 따라 방문객이 방문한 국가에서 할 수 있는 것과 체류할 수 있는 기간이 정해짐
- 쿠버네티스에는 여러 권한 방식이 있지만 RBAC를 가장 많이 사용
- API 기능에 대한 세밀한 접근을 제어할 수 있음
- 세관 또는 국경 경비대(어드미션 컨트롤러)
- 방문객이 법을 위반하지 않는지 확인하기 위해 소지한 물품을 검사함
- 쿠버네티스의 어드미션 컨트롤러와 일치
- 어드미션 컨트롤러는 정의된 규칙과 정책에 기반해 API에 대한 요청을 승인, 거절, 변경 함
- PodSecuirty, 리소스쿼터, ServiceAccount 컨트롤러와 같은 내장 어드미션 컨트롤러가 있음
- 검증과 변형 어드미션 컨트롤러를 이용해 동적 컨트롤러를 만들 수 있음
- 방문객이 법을 위반하지 않는지 확인하기 위해 소지한 물품을 검사함
4.3.1 RBAC 기초
쿠버네티스 RBAC 단계에서 정의해야 할 세가지 주요 컴포넌트는 대상, 규칙, 롤바인딩 임
4.3.1.1 대상
- 대상은 일반적으로 사용자, 서비스 계정, 그룹 임
- 사용자와 그룹은 권한 모듈을 이용해 쿠버네티스 외부에서 관리함
- 기본 인증, x.509 클라이언트 증명, 오픈 아이디 연결 시스템 사용하는 전달 토큰(bearer token) 등
<aside> 💡 쿠버네티스에서의 서비스 계정은 사용자 계정과 다름, 네임스페이스에 종속되며 쿠버네티스 내부에 저장됨, 사람이 아닌 프로세스를 나타내기 위해 만들어졌으며 네이티브 쿠버네티스 컨트롤러가 관리함
</aside>
4.3.1.2 규칙
- API로 특정 객체(리소스) 또는 객체 그룹에 실행할 수 있는 기능 목록
- CRUD 동작 및 watch, list, exec 기능 들이 있음
- 객체는 여러 API 컴포넌트와 연결되며 카테고리로 분류되어 있음
- 파드 객체는 핵심 API의 일부이며 apiGroup: “”으로 참조할 수 있지만 디플로이먼트는 앱 API 그룹 아래에 존재함
4.3.1.3 롤
- 정의된 규칙을 적용할 범위
- 쿠버네티스에는 role과 clusterRole 두가지 롤이 존재함
- role은 하나의 네임스페이스에 적용
- clusterRole은 클러스터 전체에 적용
- 네임스페이스 범위의 롤을 정의하는 예제
- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: default name: pod-viewer roles: - apiGroups: [""] # ""은 핵심 API 그룹을 나타냄 resources: ["pods"] verbs: ["get", "watch", "list"]
4.3.1.4 롤바인딩
- 사용자, 그룹과 같은 대상을 특정 롤에 매핑
- 롤바인딩에는 두가지 모드가 있음
- roleBinding: 네임스페이에 특정
- clusterRoleBinding: 클러스터 전체
- 네임스페이스 범위으 롤바인딩 예제
- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: non-helpdesk-view namespace: default subjects: - kind: User name: helpdeskuser@example.com apiGroup: rbac.authorization.k8s.io roleRef: kind: Role # Role 또는 ClusterRole name: pod-viwer # 바인딩된 Role 또는 ClusterRold의 이름과 일치 해야함 apiGroup: rbac.authorization.k8s.io
4.3.2 RBAC 모범 사례
- 쿠버네티스에서 실행되도록 개발된 애플리케이션은 대부분 RBAC나 롤바인딩을 필요로 하지 않음
- 애플리케이션 코드가 실제로 쿠버네티스 API와 직접 상호작용할 때만 RBAC 설정이 필요
- RBAC 적용 모범 사례
- 서비스의 엔드포인트에 따라 설정을 변경하기 위해 쿠버네이스 API에 직접 접근
- 특정 네임스페이스의 모든 파드를 나열하고자 할 때
- 오픈 아이디 연결 서비스를 사용해 신원 관리를 함
- 필요하다면 이중 인증을 해야함
- JIT(just in time) 접근 시스템을 사용해 SRE와 운영자, 작업 수행을 위한 단기간 권한 상향이 필요한 사용자들의 구체적인 작업을 할 수 있도록 해야함
- 쿠버네티스 클러스터에 배포될 CI/CD 도굴르 위해 특정 서비스 계정을 사용 해야함
- 배포 및 삭제한 사람이 누군지 감사할 수 있음
- 헬름을 사용해 애플리케이션을 배포하는 경우, 기본 서비스 계정은 kube-system에 배포된 틸러(Tiller) 임
- 헬름 버전 v3.4.0 이후에 틸러가 클러스터에서 사라짐
4.4 마치며
- 클라우트 네이티브 전달을 위한 애플리케이션 개발 원칙은 또 다른 주제이지만 설정과 코드를 엄격하게 분리하는 것이 성공의 핵심 원칙임
- 중요한 데이터가 쿠버네티스 API 자체에 표현되고 저장되는 일이 점점 많아지고 있음
- RBAC나 통합 인증 시스템 등의 보안 절차를 통하여 API 접근하는 것이 중요
728x90
'Kubernetes > 쿠버네티스 모범 사례 스터디' 카테고리의 다른 글
버전, 릴리스, 롤아웃 (1) | 2023.11.14 |
---|---|
지속적 통합, 테스트, 배포 (1) | 2023.11.14 |
모니터링과 로깅 (0) | 2023.11.14 |
개발자 워크플로 (0) | 2023.11.14 |
기본 서비스 설치 (1) | 2023.11.14 |