클러스터 보안 설정하기
클러스터 보안 설정하기 (Securing a Cluster)
이 문서는 우발적이거나 악의적인 접근으로부터 클러스터를 보호하는 것과 관련된 주제를 다루고 전반적인 보안에 대한 권장 사항을 제공해요.
출처: 문서
본문
시작하기 전에 (Before you begin)
쿠버네티스 클러스터가 필요하고, kubectl 명령줄 도구가 클러스터와 통신하도록 구성돼 있어야 해요. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 두 개 이상 있는 클러스터에서 실행하는 것을 권장해요. 아직 클러스터가 없다면 minikube로 만들거나 다음 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있어요.
- iximiuz Labs
- Killercoda
- KodeKloud
버전을 확인하려면 kubectl version을 입력하세요.
쿠버네티스 API 접근 제어하기 (Controlling access to the Kubernetes API)
쿠버네티스는 완전히 API 기반이므로, 누가 클러스터에 접근할 수 있고 어떤 작업을 수행할 수 있는지 제어하고 제한하는 것이 첫 번째 방어선이에요.
모든 API 트래픽에 전송 계층 보안(TLS) 사용하기 (Use Transport Layer Security (TLS) for all API traffic)
쿠버네티스는 클러스터의 모든 API 통신이 기본적으로 TLS로 암호화되기를 기대하며, 대부분의 설치 방법은 필요한 인증서를 만들어 클러스터 컴포넌트에 배포할 수 있게 해 줘요. 일부 컴포넌트와 설치 방법은 로컬 포트를 HTTP로 활성화할 수 있고, 관리자는 각 컴포넌트의 설정을 숙지해 잠재적으로 안전하지 않은 트래픽을 식별해야 한다는 점에 주의하세요.
API 인증 (API Authentication)
클러스터를 설치할 때 API 서버가 사용할, 일반적인 접근 패턴과 일치하는 인증 메커니즘을 선택하세요. 예를 들어 작고 단일 사용자 클러스터는 단순한 인증서나 정적 Bearer 토큰 방식을 사용하고 싶을 수 있어요. 더 큰 클러스터는 사용자를 그룹으로 세분화할 수 있는 기존 OIDC 또는 LDAP 서버를 통합하고 싶을 수 있어요.
모든 API 클라이언트는 인증되어야 해요. 노드, 프록시, 스케줄러, 볼륨 플러그인 같은 인프라의 일부인 클라이언트도 말이죠. 이 클라이언트들은 보통 서비스어카운트이거나 x509 클라이언트 인증서를 사용하며, 클러스터 시작 시 자동으로 생성되거나 클러스터 설치의 일부로 설정돼요.
자세한 내용은 인증 참조 문서를 참고하세요.
API 인가 (API Authorization)
인증되면 모든 API 호출은 인가 검사도 통과해야 해요. 쿠버네티스는 들어오는 사용자나 그룹을 역할에 묶인 권한 집합과 일치시키는 통합 Role-Based Access Control(RBAC) 컴포넌트를 탑재해요. 이 권한들은 동사(get, create, delete)를 리소스(pods, services, nodes)와 결합하며, 네임스페이스 범위 또는 클러스터 범위일 수 있어요. 클라이언트가 수행하려는 작업에 따라 합리적인 기본 책임 분리를 제공하는 즉시 사용 가능한 역할 집합이 제공돼요. Node와 RBAC 인가자를 함께, NodeRestriction 승인 플러그인과 결합해 사용할 것을 권장해요.
인증과 마찬가지로 단순하고 광범위한 역할이 작은 클러스터에는 적합할 수 있지만, 더 많은 사용자가 클러스터와 상호작용함에 따라 팀을 더 제한된 역할을 가진 별도의 네임스페이스로 분리할 필요가 생길 수 있어요.
인가에서 중요한 것은 한 객체의 업데이트가 다른 곳에서 동작을 일으킬 수 있다는 것을 이해하는 것이에요. 예를 들어 사용자가 파드를 직접 만들 수는 없지만, 자신을 대신해 파드를 만드는 deployment를 만들도록 허용하면 간접적으로 그 파드를 만들 수 있게 돼요. 마찬가지로 API에서 노드를 삭제하면 그 노드에 스케줄링된 파드가 종료되고 다른 노드에서 재생성되게 돼요. 즉시 사용 가능한 역할은 유연성과 일반적인 사용 사례 사이의 균형을 나타내지만, 더 제한적인 역할은 우발적인 권한 상승을 방지하기 위해 신중히 검토해야 해요. 즉시 사용 가능한 역할이 요구를 충족하지 못한다면 사용 사례에 맞게 역할을 만들 수 있어요.
자세한 내용은 인가 참조 섹션을 참고하세요.
클러스터가 Dynamic Resource Allocation(DRA)을 사용한다면 DRA 합성 하위 리소스 인가(resourceclaims/binding과 resourceclaims/driver)를 검토하고 각 컴포넌트에 최소로 필요한 동사만 부여하세요. 자세한 내용은 Dynamic Resource Allocation 하드닝 가이드와 클러스터에서 Dynamic Resource Allocation 하드닝을 참고하세요.
Kubelet 접근 제어하기 (Controlling access to the Kubelet)
Kubelet은 노드와 컨테이너에 강력한 제어를 부여하는 HTTPS 엔드포인트를 노출해요. 기본적으로 Kubelet은 이 API에 대한 인증되지 않은 접근을 허용해요. 프로덕션 클러스터는 Kubelet 인증과 인가를 활성화해야 해요. 자세한 내용은 Kubelet 인증/인가 참조를 참고하세요.
런타임에서 워크로드 또는 사용자의 능력 제어하기 (Controlling the capabilities of a workload or user at runtime)
쿠버네티스의 인가는 의도적으로 고수준이며, 리소스에 대한 광범위한 동작에 초점을 맞춰요. 객체가 클러스터, 자기 자신, 다른 리소스에 대해 어떻게 행동하는지 사용 사례별로 제한하는 더 강력한 제어가 정책으로 존재해요.
클러스터의 리소스 사용량 제한하기 (Limiting resource usage on a cluster)
리소스 쿼터는 네임스페이스에 부여된 리소스의 수나 용량을 제한해요. 이는 네임스페이스가 할당할 수 있는 CPU, 메모리, 영구 디스크의 양을 제한하는 데 가장 자주 사용되지만, 각 네임스페이스에 얼마나 많은 파드, 서비스, 볼륨이 존재하는지도 제어할 수 있어요.
Limit range는 위 리소스 중 일부의 최대 또는 최소 크기를 제한해, 사용자가 메모리 같은 일반적으로 예약되는 리소스에 비합리적으로 높거나 낮은 값을 요청하는 것을 방지하거나, 지정되지 않았을 때 기본 제한을 제공해요.
컨테이너가 실행되는 권한 제어하기 (Controlling what privileges containers run with)
파드 정의에는 노드에서 특정 Linux 사용자(root 같은)로 실행할 접근, privileged로 실행할 접근, 호스트 네트워크에 접근하는 것, 그리고 그렇지 않으면 호스팅 노드에서 자유롭게 실행되게 할 다른 제어를 요청할 수 있게 하는 보안 컨텍스트가 포함돼요.
Pod security admission을 구성해 네임스페이스에서 특정 Pod Security Standard 사용을 강제하거나 위반을 감지할 수 있어요.
일반적으로 대부분의 애플리케이션 워크로드는 호스트 정보에 대한 접근 없이 root 프로세스(uid 0)로 성공적으로 실행될 수 있도록 호스트 리소스에 대한 제한된 접근이 필요해요. 하지만 root 사용자와 연관된 권한을 고려할 때, 애플리케이션 컨테이너를 비root 사용자로 실행하도록 작성해야 해요. 마찬가지로 클라이언트 애플리케이션이 컨테이너에서 탈출하는 것을 방지하려는 관리자는 Baseline 또는 Restricted Pod Security Standard를 적용해야 해요.
컨테이너가 원치 않는 커널 모듈을 로드하지 못하게 하기 (Preventing containers from loading unwanted kernel modules)
Linux 커널은 하드웨어가 연결되거나 파일시스템이 마운트되는 것 같은 특정 상황에서 필요하면 디스크에서 커널 모듈을 자동으로 로드해요. 쿠버네티스와 특히 관련된 것은, 권한 없는 프로세스도 적절한 유형의 소켓을 만들기만 하면 특정 네트워크 프로토콜 관련 커널 모듈이 로드되게 할 수 있다는 점이에요. 이는 공격자가 관리자가 사용되지 않는다고 가정했던 커널 모듈의 보안 허점을 악용하게 할 수 있어요.
특정 모듈이 자동으로 로드되는 것을 방지하려면 노드에서 모듈을 제거하거나 차단 규칙을 추가할 수 있어요. 대부분의 Linux 배포판에서 /etc/modprobe.d/kubernetes-blacklist.conf 같은 파일을 만들어 다음과 같은 내용으로 할 수 있어요.
# DCCP는 필요할 가능성이 낮고, 여러 심각한
# 취약점이 있었으며 잘 유지 관리되지 않음.
blacklist dccp
# SCTP는 대부분의 쿠버네티스 클러스터에서 사용되지 않고, 과거에도
# 취약점이 있었음.
blacklist sctp
모듈 로드를 더 일반적으로 차단하려면 SELinux 같은 Linux 보안 모듈을 사용해 module_request 권한을 컨테이너에 완전히 거부해, 어떤 상황에서도 커널이 컨테이너를 위해 모듈을 로드하지 못하게 할 수 있어요. (파드는 수동으로 로드됐거나 더 권한 있는 프로세스를 대신해 커널이 로드한 모듈은 여전히 사용할 수 있어요.)
네트워크 접근 제한하기 (Restricting network access)
네임스페이스의 네트워크 정책은 애플리케이션 작성자가 다른 네임스페이스의 어떤 파드가 자신의 네임스페이스 안의 파드와 포트에 접근할 수 있는지 제한할 수 있게 해 줘요. 지원되는 많은 쿠버네티스 네트워킹 제공자가 이제 네트워크 정책을 존중해요.
쿼터와 limit range는 사용자가 노드 포트나 로드밸런스된 서비스를 요청할 수 있는지 제어하는 데도 사용할 수 있으며, 이는 많은 클러스터에서 사용자의 애플리케이션이 클러스터 외부에 보이는지 여부를 제어할 수 있어요.
노드별 방화벽, 크로스 토크를 방지하기 위한 클러스터 노드의 물리적 분리, 또는 고급 네트워킹 정책 같은, 플러그인별 또는 환경별로 네트워크 규칙을 제어하는 추가 보호 기능이 사용 가능할 수 있어요.
클라우드 메타데이터 API 접근 제한하기 (Restricting cloud metadata API access)
클라우드 플랫폼(AWS, Azure, GCE 등)은 종종 인스턴스에 로컬로 메타데이터 서비스를 노출해요. 기본적으로 이 API는 인스턴스에서 실행되는 파드가 접근할 수 있으며, 노드의 클라우드 자격 증명이나 kubelet 자격 증명 같은 프로비저닝 데이터를 포함할 수 있어요. 이 자격 증명은 클러스터 안에서 또는 같은 계정의 다른 클라우드 서비스로 권한을 상승시키는 데 사용될 수 있어요.
클라우드 플랫폼에서 쿠버네티스를 실행할 때, 인스턴스 자격 증명에 부여된 권한을 제한하고, 네트워크 정책으로 메타데이터 API에 대한 파드 접근을 제한하고, 프로비저닝 데이터를 시크릿 전달에 사용하지 마세요.
파드가 접근할 수 있는 노드 제어하기 (Controlling which nodes pods may access)
기본적으로 어떤 노드가 파드를 실행할 수 있는지에 대한 제한은 없어요. 쿠버네티스는 파드를 노드에 배치하고, 최종 사용자가 사용할 수 있는 테인트 기반 파드 배치와 퇴거를 제어하는 풍부한 정책 집합을 제공해요. 많은 클러스터에서 워크로드를 분리하기 위한 이러한 정책의 사용은 작성자가 채택하거나 도구를 통해 강제하는 관례가 될 수 있어요.
관리자로서 베타 승인 플러그인 PodNodeSelector를 사용해 네임스페이스 내 파드가 기본 또는 특정 노드 셀렉터를 요구하도록 강제할 수 있고, 최종 사용자가 네임스페이스를 변경할 수 없다면 이는 특정 워크로드의 모든 파드 배치를 강력하게 제한할 수 있어요.
클러스터 컴포넌트를 손상으로부터 보호하기 (Protecting cluster components from compromise)
이 섹션은 클러스터를 손상으로부터 보호하는 몇 가지 일반적인 패턴을 설명해요.
etcd 접근 제한하기 (Restrict access to etcd)
API의 etcd 백엔드에 대한 쓰기 접근은 전체 클러스터에서 root를 얻는 것과 동일하며, 읽기 접근은 꽤 빠르게 권한을 상승시키는 데 사용될 수 있어요. 관리자는 항상 TLS 클라이언트 인증서를 통한 상호 인증 같은 강력한 자격 증명을 API 서버에서 etcd 서버로 사용하고, 오직 API 서버만 접근할 수 있는 방화벽 뒤에 etcd 서버를 격리하는 것이 자주 권장돼요.
주의: 다른 클러스터 내 컴포넌트가 전체 키스페이스에 대한 읽기 또는 쓰기 접근으로 마스터 etcd 인스턴스에 접근하도록 허용하는 것은 cluster-admin 접근을 부여하는 것과 동일해요. 비마스터 컴포넌트에 별도의 etcd 인스턴스를 사용하거나 etcd ACL을 사용해 키스페이스의 부분집합에 대한 읽기 및 쓰기 접근을 제한하는 것이 강력히 권장돼요.
감사 로깅 활성화하기 (Enable audit logging)
감사 로거는 손상 시 나중에 분석하기 위해 API가 수행한 작업을 기록하는 베타 기능이에요. 감사 로깅을 활성화하고 감사 파일을 안전한 서버에 보관하는 것이 권장돼요.
알파 또는 베타 기능에 대한 접근 제한하기 (Restrict access to alpha or beta features)
알파 및 베타 쿠버네티스 기능은 활발히 개발 중이며, 보안 취약점을 초래할 수 있는 제한 사항이나 버그가 있을 수 있어요. 항상 알파 또는 베타 기능이 제공할 수 있는 가치를 보안 상태에 대한 가능한 위험과 비교해 평가하세요. 확실하지 않으면 사용하지 않는 기능을 비활성화하세요.
인프라 자격 증명을 자주 회전하기 (Rotate infrastructure credentials frequently)
시크릿이나 자격 증명의 수명이 짧을수록 공격자가 그 자격 증명을 활용하기 어려워져요. 인증서에 짧은 수명을 설정하고 자동으로 회전하세요. 발급된 토큰의 사용 가능 기간을 제어할 수 있는 인증 제공자를 사용하고 가능하면 짧은 수명을 사용하세요. 외부 통합에서 서비스어카운트 토큰을 사용한다면 그 토큰을 자주 회전할 계획을 세우세요. 예를 들어 부트스트랩 단계가 끝나면 노드 설정에 사용된 부트스트랩 토큰을 취소하거나 그 인가를 제거해야 해요.
활성화하기 전에 서드파티 통합 검토하기 (Review third party integrations before enabling them)
쿠버네티스에 대한 많은 서드파티 통합은 클러스터의 보안 프로필을 변경할 수 있어요. 통합을 활성화할 때 항상 확장이 요청하는 권한을 접근을 부여하기 전에 검토하세요. 예를 들어 많은 보안 통합이 클러스터의 모든 시크릿을 볼 권한을 요청할 수 있는데, 이는 실질적으로 그 컴포넌트를 클러스터 관리자로 만드는 것이에요. 확실하지 않으면 가능하다면 통합을 단일 네임스페이스에서 동작하도록 제한하세요.
파드를 만드는 컴포넌트는 kube-system 네임스페이스 같은 네임스페이스 안에서 그렇게 할 수 있다면 예상외로 강력할 수 있어요. 그 파드들이 서비스어카운트 시크릿에 접근하거나, 그 서비스어카운트가 허용적인 PodSecurityPolicy에 접근이 부여된 경우 상승된 권한으로 실행될 수 있기 때문이에요.
Pod Security admission을 사용하고 어떤 컴포넌트가 privileged 파드를 허용하는 네임스페이스 안에서 Pod를 만들도록 허용한다면, 그 파드가 컨테이너에서 탈출하고 이 넓어진 접근을 사용해 권한을 상승시킬 수 있어요.
신뢰할 수 없는 컴포넌트가 시스템 네임스페이스(kube-로 시작하는 이름)나 권한 상승 가능성을 허용하는 접근 부여가 있는 네임스페이스에서 Pod를 만들도록 허용하면 안 돼요.
저장 시 시크릿 암호화하기 (Encrypt secrets at rest)
일반적으로 etcd 데이터베이스는 쿠버네티스 API를 통해 접근 가능한 모든 정보를 포함할 것이며, 공격자에게 클러스터 상태에 대한 상당한 가시성을 부여할 수 있어요. 항상 잘 검토된 백업 및 암호화 솔루션으로 백업을 암호화하고, 가능하면 전체 디스크 암호화를 고려하세요.
쿠버네티스는 쿠버네티스 API의 정보에 대한 선택적 저장 시 암호화를 지원해요. 이는 쿠버네티스가 객체(예: Secret 또는 ConfigMap 객체)에 대한 데이터를 저장할 때 API 서버가 객체의 암호화된 표현을 쓰도록 보장할 수 있게 해 줘요. 그 암호화는 etcd 백업 데이터에 접근하는 사람도 그 객체의 내용을 볼 수 없게 한다는 뜻이에요. Kubernetes 1.37에서는 커스텀 리소스도 암호화할 수 있어요. CustomResourceDefinitions에 정의된 확장 API에 대한 저장 시 암호화는 v1.26 릴리스의 일부로 쿠버네티스에 추가됐어요.
보안 업데이트 알림 수신 및 취약점 보고 (Receiving alerts for security updates and reporting vulnerabilities)
보안 공지 이메일은 kubernetes-announce 그룹에 가입해 받아보세요. 취약점을 보고하는 방법은 보안 보고 페이지를 참고하세요.
다음 단계 (What's next)
- 쿠버네티스 보안 지침에 대한 추가 정보는 보안 체크리스트
- Seccomp 노드 참조