kubectl config set-credentials alice --username=alice --password=password
kubectl config set-credentials bob --usrename=bob --password=password
kubectl --user alice create -f pod-privileged.yml 로 파드를 생성하면 해당 pod가 privileged 권한이 있어 생성이 실패하지만 kubectl --user bob create -f pod-privileged.yml 의 경우에는 privileged 권한이 있기 때문에 성공한다.
네임스페이스에서 네트워크 격리 사용
기본적으로 지정됨 네임스페이스의 파드는 누구나 액세스 가능
아래와 같이 모든 클라이언트가 특정 네임스페이스의 모든 파드에 연결 불가하도록 설정
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: # --> 빈 파드 셀렉터는 동일한 네임스페이스의 모든 파드와 매치
13장 실습 관련 주의사항
파드에서 호스트 노드의 네임스페이스 사용
파드의 컨테이너는 일반적으로 별도의 리눅스 네임스페이스에서 실행되므로 프로세스가 다른 컨테이너 또는 노드의 기본 네임스페이스에서 실행 중인 프로세스와 분리된다.
각 파드는 고유한 네트워크 네임스페이스를 사용하기 때문에 고유한 IP와 포트 공간을 얻는다.
각 파드는 고유한 PID 네임스페이스가 있기 때문에 고유한 프로세스 트리가 있으며, 고유한 IPC 네임스페이스도 사용하므로 동일한 파드의 프로세스 간 통신 메커니즘으로 서로 통신할 수 있다.
hostNetwork: true로 설정한 파드는 파드 네트워크 인터페이스 대신 노드 네트워크 인터페이스를 사용한다.
노드 네트워크 네임스페이스를 사용하는 파드 yml
쿠버네티스 컨트롤 플레인 구성 요소가 파드로 배포되면, 해당 파드는
hostNetwork
옵션을 사용하므로 파드 안에서 실행되지 않는 것처럼 동작할 수 있다.호스트 네트워크 네임스페이스를 사용하지 않고 호스트 포트에 바인딩
파드는
hostNetwork
옵션으로 노드의 기본 네임스페이스의 포트에 바인딩할 수 있지만 여전히 고유한 네트워크 네임스페이스를 갖는다.컨테이너의 포트를 정의하는
spec.containers.ports
필드 안에hostPort
속성을 사용해 할 수 있다.위 그림처럼
hostPort
를 사용하는 파드와NodePort
서비스로 노출된 파드를 혼동하면 안된다.파드가
hostPort
를 사용하는 경우 노드포트에 대한 연결은 해당 노드에서 실행 중인 파드로 직접 전달되는 반면NodePort
서비스의 경우 노드포트의 연결은 임의의 파드로 전달된다.또 다른 차이점은
hostPort
를 사용하는 파드의 경우 노드포트는 해당 파드를 실행하는 노드에만 바인딩되는 반면NodePrt
서비스는 이런 파드를 실행하지 않는 노드에서도 모든 노드의 포트를 바인딩한다는 것이다.파드가 특정 호스트 포트를 사용하는 경우 두 프로세스가 동일한 호스트 포트에 바인딩될 수 없으므로 파드 인스턴스 하나만 노드에 스케줄링될 수 있다는 점이 중요내용이다.
pending
상태에 놓이고, 세 개의 파드만 스케줄링된다.노드의 PID와 IPC 네임스페이스 사용
파드의 컨테이너는 노드의 PID와 IPC 네임스페이스를 사용해 컨테이너에서 실행 중인 프로세스가 노드의 다른 프로세스를 보거나 IPC로 이들과 통신할 수 있다.
생성 yaml
위 yml로 파드를 생성하면, 파드는 일반적으로 자체 프로세스만 표시하지만, 이 파드를 실행한 후 컨테이너의 프로세스를 조회하면 노드에서 실행 중인 모든 프로세스가 조회된다.
hostIPC
속성을 true로 설정하면 파드 컨테이너의 프로세스는 노드에서 실행 중인 다른 모든 프로세스와 IPC로 통신할 수도 있다.컨테이너의 보안 컨텍스트 구성
securityContext
속성으로 다른 보안 관련 기능을 파드와 파드의 컨테이너에 구성할 수 있다.컨테이너를 특정 사용자로 실행
securityContext.runAsUser
속성을 설정해야 한다.컨테이너가 루트로 실행되는 것 방지
특권 모드에서 파드 실행
kube-proxy 파드
iptables
규칙을 수정한다.securityContext
속성에서privileged
속성을 true로 설정하면 된다./dev
라는 특별한 파일 디렉터리가 있다./dev
의 파일은 디스크의 일반적인 파일과 다르게 장치와 통신하는 데 사용되는 특별한 파일이다.kubectl exec -it pod-privileged ls /dev
명령을 수행하면 어마어마하게 많은 장치가 출력된다.컨테이너에서 기능 제거
CAP_CHOWN
기능이 포함된다.securityContext.capabilities.drop
속성 아래에 기능을 삭제하면 된다.프로세스가 컨테이너의 파일시스템에 쓰는 것 방지
securityContext.readOnlyRootFileSystem
속성 true로 설정 필요컨테이너가 다른 사용자로 실행될 때 볼륨 공유
supplementalGroups
속성을 지정해 실행 중인 사용자 ID에 상관없이 파일을 공유할 수 있다.fsGroup
과supplementalGroups
는 파드 레벨의 보안 컨텍스트에서 정의된다. (컨테이너 스펙이 아님)fsGroup
을 555로 설정했기 때문에 마운트된 볼륨은 그룹 ID 555가 소유하게 된다.fsGroup
보안 컨텍스트 속성은 프로세스가 볼륨에 파일을 생성할 때 사용되지만,supplementalGroups
속성은 사용자와 관련된 추가 그룹 ID 목록을 정의하는 데 사용된다.PodSecurityPolicy 리소스 소개
PodSecurityPolicy
는 클러스터 수준 리소스로, 사용자가 파드에서 사용할 수 있거나 사용할 수 없는 보안 관련 기능을 정의한다.PodSecurityPolicy
리소스에 구성된 정책을 유지하는 작업은 API 서버에서 실행되는PodSecurityPolicy
어드미션 컨트롤러 플러그인으로 수행된다.누군가 파드 서버 리소스를 API 서버에 게시하면
PodSecurityPolicy
어드미션 컨트롤 플러그인은 구성된PodSecurityPolicies
로 파드 정의의 유효성을 검사한다.파드가 클러스터 정책을 준수하면 승인되고, etcd에 저장된다.
PodSecurityPolicy가 할 수 있는 작업
아래 yml은 호스트 IPC, PID, 네트워크 네임스페이스 사용을 방지하고 권한 있는 컨테이너 실행(10000~11000, 13000~14000 포트 제외한) 대부분의 호스트 포트를 사용하지 못하게 하는 정책이다.
runAsUser, fsGroup, supplementalGroups 정책
허용된 사용자 또는 그룹 ID 목록을 제한하려면
MustRunAs
규칙을 변경해 허용할 그룹 ID를 지정할 수 있다.컨테이너가 사용자 ID 2로만 실행되도록 하고, 기본 파일시스템 그룹과 보조 그룹ID를 2~10 또는 20~30으로 제한하려면 아래와 같이 리소스를 수정한다.
만약 아래 Dockerfile과 같이 사용자 ID를 5로 실행되게 강제한다면 어떻게 될까 ?
위 이미지가 포함된 파드를 배포하면 사용자 ID가 5로 실행될 것으로 예상했지만, 아래 영역때문에 강제로 사용자 ID가 2로 실행되게 된다.
즉
PodSecurityPolicy
를 사용해 컨테이너 이미지에 하드코딩된 사용자 ID를 재정의할 수 있다.컨테이너에 어떤 기능을 추가할지 지정
allowedCapabilities
필드는 파드 작성자가 컨테이너 스펙의securityContext.capabilites
필드에 추가할 수 있는 기능을 지정하는 데 사용된다.모든 컨테이너에 기능 추가
defaultAddCapabilities
필드 아래에 나열된 모든 기능은 배포되는 모든 파드 컨테이너에 추가된다.컨테이너에서 기능 제거
requiredDropCapabilities
필드는 이 필드에 나열된 기능은 모든 컨테이너에서 자동으로 삭제된다.requiredDropCapabilities
필드에 나열된 기능을 명시적으로 추가하는 파드를 만들려고 하면 해당 파드가 거부된다.파드가 사용할 수 있는 볼륨 유형 제한
PodSecurityPolicy
는 적어도emptyDir
,컨피그맵
,시크릿
,다운워드API
,퍼시스턴트볼륨클레임
볼륨 사용을 허용해야 한다.각각의 사용자와 그룹에 다른 PodSeucirtyPolicies 할당
PodSecurityPolicy
는 클러스터 수준의 리소스이므로 특정 네임스페이스를 지정하거나 적용할 수 없다.다른 사용자에게 다른 정책을 할당하는 것은
RBAC 메커니즘
으로 수행된다.클러스터롤 리소스를 만들고 이름으로 개별 정책을 지정해 필요한 만큼 많은 정책을 작성하고 개별 사용자 또는 그룹이 사용할 수 있도록 클러스터롤바인딩을 사용하면 된다.
특권을 가진 컨테이너를 배포할 수 있는 PodSecurityPolicy
PRIV 열에서 볼 수 있듯이 default 정책은 권한 있는 컨테이너를 실행할 수 없지만, privileged 정책은 실행이 가능하다.
클러스터 롤 생성
kubectl create clusterrole psp-default --verb=user --resource=podsecuritypolicies --resource-name=default
kubectl create clusterrole psp-privileged --verb=user --resource=podsecuritypolicies --resource-name=privileged
클러스터 수준 리소스에 대한 액세스 권한을 부여하는 클러스터롤을 바인딩하는 경우 롤바인딩 대신 클러스터롤바인딩을 사용해야 한다.
kubectl create clusterrolebinding psp-all-users --clusterrole=psp-default --group=system:authenticated
kubectl create clusterrolebinding psp-bob --clusterrole=psp-privileged --user=bob
kubectl을 위해 추가 사용자 생성
kubectl config set-credentials alice --username=alice --password=password
kubectl config set-credentials bob --usrename=bob --password=password
kubectl --user alice create -f pod-privileged.yml
로 파드를 생성하면 해당 pod가 privileged 권한이 있어 생성이 실패하지만kubectl --user bob create -f pod-privileged.yml
의 경우에는 privileged 권한이 있기 때문에 성공한다.네임스페이스에서 네트워크 격리 사용
일부 클라이언트 파드만 서버 파드 연결 허용
ingress
네임스페이스간 네트워크 격리
CIDR
아웃바운드 트래픽 제한
egress