InfoGrab DocsInfoGrab Docs

쿠버네티스 접근 문제 해결

요약

이 페이지에서는 쿠버네티스에서 발생하는 일반적인 문제와 이를 우회하거나 해결하는 방법을 설명합니다. 에이전트가 재시작 후 Teleport 클러스터에 다시 조인하지 못하고 다음과 유사한 오류를 보고합니다: Teleport는 각 컴포넌트의 인증서에 서명하기 위해 인증 기관(CA)을 사용합니다.

이 페이지에서는 쿠버네티스에서 발생하는 일반적인 문제와 이를 우회하거나 해결하는 방법을 설명합니다.

에이전트가 "no authorities for hostname" 오류로 클러스터에 조인하지 못하는 경우#

증상#

에이전트가 재시작 후 Teleport 클러스터에 다시 조인하지 못하고 다음과 유사한 오류를 보고합니다:

ssh: handshake failed: ssh: no authorities for hostname

설명#

Teleport는 각 컴포넌트의 인증서에 서명하기 위해 인증 기관(CA)을 사용합니다. 컴포넌트가 클러스터에 처음 조인할 때, 클러스터의 CA가 서명한 인증서를 발급받아 상태 디렉터리에 저장합니다. 컴포넌트가 재시작되면 상태 디렉터리에 저장된 인증서를 사용해 클러스터에 다시 조인합니다.

이 오류는 컴포넌트가 Teleport 클러스터에 다시 조인하려 할 때, 클러스터의 CA가 변경되어 컴포넌트의 인증서가 더 이상 유효하지 않을 때 발생합니다.

이는 클러스터의 CA가 순환(rotate)되거나 클러스터가 재생성 또는 이름이 변경될 때 발생할 수 있습니다.

해결 방법#

에이전트가 새 인증서를 요청하고 클러스터에 다시 조인할 수 있도록 에이전트의 상태를 초기화해야 합니다.

에이전트의 상태를 삭제하는 절차는 에이전트가 쿠버네티스 내부에서 실행 중인지 외부에서 실행 중인지에 따라 다릅니다.

쿠버네티스 외부에서 실행 중인 에이전트 (단독 실행)#

에이전트가 쿠버네티스 외부에서 실행 중인 경우, 상태 디렉터리는 기본적으로 /var/lib/teleport/proc에 위치합니다. 다음 명령으로 상태 디렉터리를 삭제할 수 있습니다:

sudo rm -rf /var/lib/teleport/proc

그런 다음 에이전트를 재시작합니다:

sudo systemctl restart teleport

쿠버네티스 내에서 실행 중인 에이전트 (teleport-kube-agent)#

Teleport 11부터 teleport-kube-agent Pod의 상태는 설치 네임스페이스에 존재하는 쿠버네티스 시크릿(이름: {pod-name}-state)에 저장됩니다. 상태를 삭제하려면 다음 단계를 따르세요:

# teleport-kube-agent Pod의 시크릿 가져오기
$ kubectl get secret -o name -n teleport-agent | grep "state"
teleport-agent-0-state
teleport-agent-1-state

# 시크릿 삭제
$ kubectl delete secret -n teleport-agent teleport-agent-0-state teleport-agent-1-state

/var/lib/teleport를 컨테이너에 마운트하고 있다면, 컨테이너 내부의 /var/lib/teleport/proc 콘텐츠를 정리한 후 컨테이너를 재시작하세요.

상태가 삭제되면 각 에이전트 Pod를 재시작하세요.

GKE Autopilot 클러스터에 연결할 수 없는 경우#

GKE Warden authz [denied by user-impersonation-limitation]: impersonating system identities are not allowed

증상#

Teleport에서 GKE Autopilot 클러스터를 구성한 후, 쿠버네티스 객체를 가져오려는 모든 시도가 다음과 유사한 오류로 실패합니다:

또는 다음과 같은 오류가 발생합니다:

GKE Autopilot denies requests that impersonate "system:masters" group
Note

이 문제는 GKE Autopilot 클러스터에만 영향을 미칩니다. 표준 GKE 클러스터를 사용 중이라면 이 문제는 해당되지 않습니다.

설명#

표준 쿠버네티스 클러스터와 달리, Autopilot 클러스터는 시스템 아이덴티티를 임퍼소네이션하는 요청을 금지합니다. 이는 사용자나 그룹을 임퍼소네이션할 수 있을 경우 클러스터의 컨트롤 플레인에 접근하여 관리 작업을 수행하는 것을 방지하는 보안 기능입니다. GKE Autopilot 보안에 대해 자세히 알아보기.

Teleport는 사용자를 대신하여 쿠버네티스 객체를 가져오기 위해 임퍼소네이션을 사용합니다. 이는 사용자의 아이덴티티를 Impersonate-User 헤더에, 사용자가 사용할 수 있는 모든 쿠버네티스 그룹을 Impersonate-Group 헤더에 담아 쿠버네티스 API 서버에 요청을 보내는 방식으로 수행됩니다.

system:masters는 모든 클러스터에 내장된 쿠버네티스 그룹이므로, 관리자가 이를 사용하여 클러스터의 컨트롤 플레인에 대한 관리 접근 권한을 얻는 것이 일반적입니다. 하지만 Autopilot 클러스터는 이 그룹을 임퍼소네이션하는 것을 금지하며, 대신 다른 그룹을 사용하도록 요구합니다.

해결 방법#

위 설명에 따라, 해결책은 Teleport에서 임퍼소네이션에 사용할 다른 그룹을 구성하는 것입니다. 이는 역할의 kubernetes_groups 매개변수를 Autopilot 클러스터가 임퍼소네이션을 허용하는 그룹으로 설정하여 수행할 수 있습니다.

teleport-kube-agent 차트는 대상 클러스터가 GKE 클러스터임을 감지하면 system:masters 그룹과 동일한 접근 수준을 가진 쿠버네티스 그룹을 구성합니다. 이 그룹의 기본 이름은 cluster-admin이지만, adminClusterRoleBinding.name 매개변수를 설정하여 이름을 변경할 수 있습니다.

쿠버네티스 그룹은 non-GKE 클러스터에 차트를 설치할 때 자동으로 생성되지 않으므로, 직접 그룹을 생성했거나 adminClusterRoleBinding.create 매개변수를 true로 설정하여 차트를 설치한 경우가 아니라면 kubernetes_groups 매개변수를 cluster-admin으로 변경하지 마세요.

그룹은 임퍼소네이션에 사용되기 전에 클러스터 내에 구성되어 있어야 한다는 점에 유의하는 것이 중요합니다. 그룹이 구성되지 않은 경우, 임퍼소네이션 요청은 403 Forbidden 오류로 실패하며 사용자는 클러스터에 접근할 수 없습니다.

non-Autopilot 클러스터에서 임퍼소네이션에 계속 system:masters 그룹을 사용하기로 선택한 경우, system:masters 접근 권한을 부여하는 Teleport 역할이 GKE Autopilot 클러스터에 접근하는 데 사용될 수 없도록 해야 합니다.

예를 들어, 다음 역할을 가진 사용자는 모든 쿠버네티스 클러스터에서 system:masters 그룹을 임퍼소네이션할 수 있습니다:

kind: role
version: v7
metadata:
  name: k8s-admin
spec:
  allow:
    kubernetes_labels:
      '*': '*'
    kubernetes_groups: ["system:masters"]

kubernetes_labels의 와일드카드 *는 사용자가 Teleport 클러스터 내 모든 쿠버네티스 클러스터에 접근할 수 있도록 허용합니다. 이 역할로 사용자가 GKE Autopilot 클러스터에 접근하지 못하도록 하려면, 클러스터를 Autopilot 클러스터로 식별하는 라벨을 사용하여 teleport-kube-agent 차트를 설치할 수 있습니다. 예를 들면:

$ PROXY_ADDR=teleport.example.com:443
$ CLUSTER=cookie
# values.yaml 파일 생성
$ cat > values.yaml << EOF
authToken: "${TOKEN}"
proxyAddr: "${PROXY_ADDR}"
roles: "kube,app,discovery"
joinParams:
  method: "token"
  tokenName: "${TOKEN}"
kubeClusterName: "${CLUSTER}"
labels:
  "type" : "autopilot"
EOF
# values.yaml 설정으로 Helm 차트 설치
$ helm install teleport-agent teleport/teleport-kube-agent \
  -f values.yaml \
  --create-namespace \
  --namespace=teleport-agent \
  --version (=teleport.version=)

Teleport 에이전트 Pod가 실행 중인지 확인하세요. 준비 완료된 컨테이너 하나를 가진 Teleport 에이전트 Pod 하나가 표시되어야 합니다:

$ kubectl -n teleport-agent get pods
NAME               READY   STATUS    RESTARTS   AGE
teleport-agent-0   1/1     Running   0          32s

이제 클러스터에 라벨이 지정되었으므로, k8s-admin 역할을 두 개의 역할로 나눌 수 있습니다. 하나는 모든 non-Autopilot 클러스터에 대한 접근을 허용하고, 다른 하나는 Autopilot 클러스터에 대한 접근만 허용합니다.

kind: role
version: v7
metadata:
  name: k8s-admin-non-gke-autopilot
spec:
  allow:
    kubernetes_labels_expression: 'labels["type"] != "autopilot"'
    kubernetes_groups: ["system:masters"]
---
kind: role
version: v7
metadata:
  name: k8s-admin-gke-autopilot
spec:
  allow:
    kubernetes_labels_expression: 'labels["type"] == "autopilot"'
    kubernetes_groups: ["cluster-admin"]

역할이 생성되면 평소와 같이 사용자에게 할당할 수 있지만, 즉시 적용되려면 사용자가 로그아웃 후 다시 로그인해야 합니다.

kubectl 1.30 이상에서 Pod에 exec할 수 없는 경우#

pods "<pod_name>" is forbidden: User "<user>" cannot get resource "pods/exec" in API group "" in the namespace "<namespace>"

증상#

kubectl을 버전 1.30 이상으로 업그레이드한 후, Pod에 exec하려는 시도가 다음과 유사한 오류로 실패합니다:

pods "<pod_name>" is forbidden: User "<user>" cannot get resource "pods/exec" in API group "" in the namespace "<namespace>"

설명#

쿠버네티스 1.30부터 kubectl exec 명령은 쿠버네티스 API 서버와 통신할 때 SPDY 프로토콜 대신 WebSocket 프로토콜을 사용하도록 변경되었습니다. 이 변경은 SPDY 프로토콜이 지원 중단됨에 따라 kubectl exec 명령의 성능과 안정성을 향상시키기 위해 이루어졌습니다.

WebSocket은 SPDY의 드롭인 대체제로 의도되었지만, pods/exec 리소스에 대한 접근을 create verb만으로 제한하도록 RBAC가 구성된 쿠버네티스 클러스터에는 호환성이 깨지는 변경을 일으켰습니다. 이전에는 SPDY 프로토콜이 GET(쿠버네티스 RBAC에서 get에 매핑됨) 또는 POST(쿠버네티스 RBAC에서 create에 매핑됨) 중 하나를 사용하여 연결을 생성할 수 있도록 허용했습니다.

WebSocket 프로토콜에서는 kubectl exec 명령이 연결을 생성할 때 항상 GET 메서드를 사용합니다. 즉, RBAC 정책이 create verb만 허용하는 경우 연결이 거부됩니다.

해결 방법#

이 문제를 해결하려면 pods/exec (하위)리소스에 대해 get verb를 허용하도록 RBAC 정책을 업데이트하세요. 이는 사용자에게 접근 권한을 부여하는 ClusterRole 또는 Role을 수정하여 수행할 수 있습니다.

예를 들어, create verb로 pods/exec 리소스에 대한 접근을 부여하는 ClusterRole이 있다면, get verb도 허용하도록 업데이트하세요:

- apiGroups: [""]
  resources: ["pods/exec"]
  verbs: ["create", "get"]

ClusterRole이 업데이트되면, kubectl 버전 1.30 이상을 사용하여 Pod에 exec할 수 있습니다.

헬스 체크: 쿠버네티스 클러스터에 접근할 수 없음#

증상#

쿠버네티스 클러스터가 unhealthy로 보고되며, Teleport와 쿠버네티스 클러스터 API 간의 모든 호출이 실패합니다.

설명#

Teleport 쿠버네티스 서비스가 쿠버네티스 클러스터에 대해 여러 차례 헬스 체크를 수행했지만 응답을 받지 못했습니다.

쿠버네티스 클러스터 API 엔드포인트 /selfsubjectaccessreviews/readyz에 대한 호출이 HTTP 상태 코드 없이 오류를 반환했습니다.

해결 방법#

쿠버네티스 클러스터와 네트워크의 근본 원인을 조사하세요.

쿠버네티스 클러스터의 상태를 확인하세요.

kubectl cluster-info
kubectl get --raw /readyz

네트워크 및 방화벽 규칙을 확인하세요.

  • 네트워크가 올바르게 구성되어 있습니까?
  • 보안 그룹을 확인하세요
  • 네트워크 정책을 확인하세요

헬스 체크: 필요한 쿠버네티스 권한 누락#

증상#

쿠버네티스 클러스터가 unhealthy로 보고되며, impersonate users, impersonate groups, impersonate service accounts, get pods와 같은 하나 이상의 쿠버네티스 권한이 누락되어 있습니다.

설명#

Teleport 쿠버네티스 서비스가 쿠버네티스 클러스터에 대해 헬스 체크를 수행했으며, 필요한 쿠버네티스 클러스터 기능이 거부되었다는 응답을 받았습니다.

쿠버네티스 클러스터에 ClusterRole이 누락되었거나, 부분적인 ClusterRole로 구성되어 있습니다. Teleport에는 4가지 쿠버네티스 SelfSubjectAccessReview 권한이 필요합니다:

  • 사용자 임퍼소네이션
  • 그룹 임퍼소네이션
  • 서비스 계정 임퍼소네이션
  • Pod 가져오기

해결 방법#

쿠버네티스 클러스터에 4가지 권한을 가진 ClusterRoleClusterRoleBinding을 추가하세요.

$ kubectl config use-context <your-kube-context>
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: teleport-impersonation
rules:
  - apiGroups:
      - ""
    resources:
      - users
      - groups
      - serviceaccounts
    verbs:
      - impersonate
  - apiGroups:
      - ""
    resources:
      - pods
    verbs:
      - get
  - apiGroups:
      - "authorization.k8s.io"
    resources:
      - selfsubjectaccessreviews
    verbs:
      - create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: teleport
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: teleport-impersonation
subjects:
  - kind: ServiceAccount
    name: teleport-serviceaccount
    namespace: default
EOF

ClusterRoleBinding은 환경에 따라 다를 수 있습니다.

Teleport 쿠버네티스에서 임퍼소네이션 활성화하기도 참고하세요.

헬스 체크: 상태 코드와 함께 비정상 쿠버네티스 클러스터 감지됨#

증상#

쿠버네티스 클러스터가 unhealthy로 보고되며, Teleport가 쿠버네티스 클러스터로부터 오류 상태 코드가 포함된 응답을 받았습니다.

설명#

Teleport 쿠버네티스 서비스가 쿠버네티스 클러스터에 대해 여러 차례 헬스 체크를 수행했고 응답을 받았습니다.

권한 엔드포인트 /selfsubjectaccessreviews에 대한 호출은 실패했고, 쿠버네티스 클러스터의 /readyz 엔드포인트에 대한 호출은 오류 상태 코드가 포함된 응답을 반환했습니다. 이 오류 상태 코드는 쿠버네티스 클러스터 내 컴포넌트가 비정상 상태임을 나타냅니다.

해결 방법#

kubectl을 사용하여 쿠버네티스 클러스터 오류 상태 코드를 진단하세요.

kubectl cluster-info
kubectl get --raw /readyz

헬스 체크: 쿠버네티스 권한을 확인할 수 없음#

증상#

쿠버네티스 클러스터가 unhealthy로 보고되며, Teleport가 헬스 체크 엔드포인트로부터 혼재된 응답을 받았습니다.

설명#

Teleport 쿠버네티스 서비스가 쿠버네티스 클러스터에 대해 여러 차례 헬스 체크를 수행했고 응답을 받았습니다.

권한 엔드포인트 /selfsubjectaccessreviews에 대한 호출은 실패했고, 쿠버네티스 클러스터의 /readyz에 대한 호출은 성공했습니다. 쿠버네티스 클러스터 컴포넌트는 정상 작동 중이며, 쿠버네티스 SelfSubjectAccessReview API에 대한 호출을 무언가가 차단하고 있습니다.

해결 방법#

kubectl을 사용하여 쿠버네티스 클러스터를 진단하세요.

kubectl cluster-info
kubectl get --raw /readyz

쿠버네티스 접근 문제 해결

Teleport v18.9
원문 보기
요약

이 페이지에서는 쿠버네티스에서 발생하는 일반적인 문제와 이를 우회하거나 해결하는 방법을 설명합니다. 에이전트가 재시작 후 Teleport 클러스터에 다시 조인하지 못하고 다음과 유사한 오류를 보고합니다: Teleport는 각 컴포넌트의 인증서에 서명하기 위해 인증 기관(CA)을 사용합니다.

이 페이지에서는 쿠버네티스에서 발생하는 일반적인 문제와 이를 우회하거나 해결하는 방법을 설명합니다.

에이전트가 "no authorities for hostname" 오류로 클러스터에 조인하지 못하는 경우#

증상#

에이전트가 재시작 후 Teleport 클러스터에 다시 조인하지 못하고 다음과 유사한 오류를 보고합니다:

ssh: handshake failed: ssh: no authorities for hostname

설명#

Teleport는 각 컴포넌트의 인증서에 서명하기 위해 인증 기관(CA)을 사용합니다. 컴포넌트가 클러스터에 처음 조인할 때, 클러스터의 CA가 서명한 인증서를 발급받아 상태 디렉터리에 저장합니다. 컴포넌트가 재시작되면 상태 디렉터리에 저장된 인증서를 사용해 클러스터에 다시 조인합니다.

이 오류는 컴포넌트가 Teleport 클러스터에 다시 조인하려 할 때, 클러스터의 CA가 변경되어 컴포넌트의 인증서가 더 이상 유효하지 않을 때 발생합니다.

이는 클러스터의 CA가 순환(rotate)되거나 클러스터가 재생성 또는 이름이 변경될 때 발생할 수 있습니다.

해결 방법#

에이전트가 새 인증서를 요청하고 클러스터에 다시 조인할 수 있도록 에이전트의 상태를 초기화해야 합니다.

에이전트의 상태를 삭제하는 절차는 에이전트가 쿠버네티스 내부에서 실행 중인지 외부에서 실행 중인지에 따라 다릅니다.

쿠버네티스 외부에서 실행 중인 에이전트 (단독 실행)#

에이전트가 쿠버네티스 외부에서 실행 중인 경우, 상태 디렉터리는 기본적으로 /var/lib/teleport/proc에 위치합니다. 다음 명령으로 상태 디렉터리를 삭제할 수 있습니다:

sudo rm -rf /var/lib/teleport/proc

그런 다음 에이전트를 재시작합니다:

sudo systemctl restart teleport

쿠버네티스 내에서 실행 중인 에이전트 (teleport-kube-agent)#

Teleport 11부터 teleport-kube-agent Pod의 상태는 설치 네임스페이스에 존재하는 쿠버네티스 시크릿(이름: {pod-name}-state)에 저장됩니다. 상태를 삭제하려면 다음 단계를 따르세요:

# teleport-kube-agent Pod의 시크릿 가져오기
$ kubectl get secret -o name -n teleport-agent | grep "state"
teleport-agent-0-state
teleport-agent-1-state

# 시크릿 삭제
$ kubectl delete secret -n teleport-agent teleport-agent-0-state teleport-agent-1-state

/var/lib/teleport를 컨테이너에 마운트하고 있다면, 컨테이너 내부의 /var/lib/teleport/proc 콘텐츠를 정리한 후 컨테이너를 재시작하세요.

상태가 삭제되면 각 에이전트 Pod를 재시작하세요.

GKE Autopilot 클러스터에 연결할 수 없는 경우#

GKE Warden authz [denied by user-impersonation-limitation]: impersonating system identities are not allowed

증상#

Teleport에서 GKE Autopilot 클러스터를 구성한 후, 쿠버네티스 객체를 가져오려는 모든 시도가 다음과 유사한 오류로 실패합니다:

또는 다음과 같은 오류가 발생합니다:

GKE Autopilot denies requests that impersonate "system:masters" group
Note

이 문제는 GKE Autopilot 클러스터에만 영향을 미칩니다. 표준 GKE 클러스터를 사용 중이라면 이 문제는 해당되지 않습니다.

설명#

표준 쿠버네티스 클러스터와 달리, Autopilot 클러스터는 시스템 아이덴티티를 임퍼소네이션하는 요청을 금지합니다. 이는 사용자나 그룹을 임퍼소네이션할 수 있을 경우 클러스터의 컨트롤 플레인에 접근하여 관리 작업을 수행하는 것을 방지하는 보안 기능입니다. GKE Autopilot 보안에 대해 자세히 알아보기.

Teleport는 사용자를 대신하여 쿠버네티스 객체를 가져오기 위해 임퍼소네이션을 사용합니다. 이는 사용자의 아이덴티티를 Impersonate-User 헤더에, 사용자가 사용할 수 있는 모든 쿠버네티스 그룹을 Impersonate-Group 헤더에 담아 쿠버네티스 API 서버에 요청을 보내는 방식으로 수행됩니다.

system:masters는 모든 클러스터에 내장된 쿠버네티스 그룹이므로, 관리자가 이를 사용하여 클러스터의 컨트롤 플레인에 대한 관리 접근 권한을 얻는 것이 일반적입니다. 하지만 Autopilot 클러스터는 이 그룹을 임퍼소네이션하는 것을 금지하며, 대신 다른 그룹을 사용하도록 요구합니다.

해결 방법#

위 설명에 따라, 해결책은 Teleport에서 임퍼소네이션에 사용할 다른 그룹을 구성하는 것입니다. 이는 역할의 kubernetes_groups 매개변수를 Autopilot 클러스터가 임퍼소네이션을 허용하는 그룹으로 설정하여 수행할 수 있습니다.

teleport-kube-agent 차트는 대상 클러스터가 GKE 클러스터임을 감지하면 system:masters 그룹과 동일한 접근 수준을 가진 쿠버네티스 그룹을 구성합니다. 이 그룹의 기본 이름은 cluster-admin이지만, adminClusterRoleBinding.name 매개변수를 설정하여 이름을 변경할 수 있습니다.

쿠버네티스 그룹은 non-GKE 클러스터에 차트를 설치할 때 자동으로 생성되지 않으므로, 직접 그룹을 생성했거나 adminClusterRoleBinding.create 매개변수를 true로 설정하여 차트를 설치한 경우가 아니라면 kubernetes_groups 매개변수를 cluster-admin으로 변경하지 마세요.

그룹은 임퍼소네이션에 사용되기 전에 클러스터 내에 구성되어 있어야 한다는 점에 유의하는 것이 중요합니다. 그룹이 구성되지 않은 경우, 임퍼소네이션 요청은 403 Forbidden 오류로 실패하며 사용자는 클러스터에 접근할 수 없습니다.

non-Autopilot 클러스터에서 임퍼소네이션에 계속 system:masters 그룹을 사용하기로 선택한 경우, system:masters 접근 권한을 부여하는 Teleport 역할이 GKE Autopilot 클러스터에 접근하는 데 사용될 수 없도록 해야 합니다.

예를 들어, 다음 역할을 가진 사용자는 모든 쿠버네티스 클러스터에서 system:masters 그룹을 임퍼소네이션할 수 있습니다:

kind: role
version: v7
metadata:
  name: k8s-admin
spec:
  allow:
    kubernetes_labels:
      '*': '*'
    kubernetes_groups: ["system:masters"]

kubernetes_labels의 와일드카드 *는 사용자가 Teleport 클러스터 내 모든 쿠버네티스 클러스터에 접근할 수 있도록 허용합니다. 이 역할로 사용자가 GKE Autopilot 클러스터에 접근하지 못하도록 하려면, 클러스터를 Autopilot 클러스터로 식별하는 라벨을 사용하여 teleport-kube-agent 차트를 설치할 수 있습니다. 예를 들면:

$ PROXY_ADDR=teleport.example.com:443
$ CLUSTER=cookie
# values.yaml 파일 생성
$ cat > values.yaml << EOF
authToken: "${TOKEN}"
proxyAddr: "${PROXY_ADDR}"
roles: "kube,app,discovery"
joinParams:
  method: "token"
  tokenName: "${TOKEN}"
kubeClusterName: "${CLUSTER}"
labels:
  "type" : "autopilot"
EOF
# values.yaml 설정으로 Helm 차트 설치
$ helm install teleport-agent teleport/teleport-kube-agent \
  -f values.yaml \
  --create-namespace \
  --namespace=teleport-agent \
  --version (=teleport.version=)

Teleport 에이전트 Pod가 실행 중인지 확인하세요. 준비 완료된 컨테이너 하나를 가진 Teleport 에이전트 Pod 하나가 표시되어야 합니다:

$ kubectl -n teleport-agent get pods
NAME               READY   STATUS    RESTARTS   AGE
teleport-agent-0   1/1     Running   0          32s

이제 클러스터에 라벨이 지정되었으므로, k8s-admin 역할을 두 개의 역할로 나눌 수 있습니다. 하나는 모든 non-Autopilot 클러스터에 대한 접근을 허용하고, 다른 하나는 Autopilot 클러스터에 대한 접근만 허용합니다.

kind: role
version: v7
metadata:
  name: k8s-admin-non-gke-autopilot
spec:
  allow:
    kubernetes_labels_expression: 'labels["type"] != "autopilot"'
    kubernetes_groups: ["system:masters"]
---
kind: role
version: v7
metadata:
  name: k8s-admin-gke-autopilot
spec:
  allow:
    kubernetes_labels_expression: 'labels["type"] == "autopilot"'
    kubernetes_groups: ["cluster-admin"]

역할이 생성되면 평소와 같이 사용자에게 할당할 수 있지만, 즉시 적용되려면 사용자가 로그아웃 후 다시 로그인해야 합니다.

kubectl 1.30 이상에서 Pod에 exec할 수 없는 경우#

pods "<pod_name>" is forbidden: User "<user>" cannot get resource "pods/exec" in API group "" in the namespace "<namespace>"

증상#

kubectl을 버전 1.30 이상으로 업그레이드한 후, Pod에 exec하려는 시도가 다음과 유사한 오류로 실패합니다:

pods "<pod_name>" is forbidden: User "<user>" cannot get resource "pods/exec" in API group "" in the namespace "<namespace>"

설명#

쿠버네티스 1.30부터 kubectl exec 명령은 쿠버네티스 API 서버와 통신할 때 SPDY 프로토콜 대신 WebSocket 프로토콜을 사용하도록 변경되었습니다. 이 변경은 SPDY 프로토콜이 지원 중단됨에 따라 kubectl exec 명령의 성능과 안정성을 향상시키기 위해 이루어졌습니다.

WebSocket은 SPDY의 드롭인 대체제로 의도되었지만, pods/exec 리소스에 대한 접근을 create verb만으로 제한하도록 RBAC가 구성된 쿠버네티스 클러스터에는 호환성이 깨지는 변경을 일으켰습니다. 이전에는 SPDY 프로토콜이 GET(쿠버네티스 RBAC에서 get에 매핑됨) 또는 POST(쿠버네티스 RBAC에서 create에 매핑됨) 중 하나를 사용하여 연결을 생성할 수 있도록 허용했습니다.

WebSocket 프로토콜에서는 kubectl exec 명령이 연결을 생성할 때 항상 GET 메서드를 사용합니다. 즉, RBAC 정책이 create verb만 허용하는 경우 연결이 거부됩니다.

해결 방법#

이 문제를 해결하려면 pods/exec (하위)리소스에 대해 get verb를 허용하도록 RBAC 정책을 업데이트하세요. 이는 사용자에게 접근 권한을 부여하는 ClusterRole 또는 Role을 수정하여 수행할 수 있습니다.

예를 들어, create verb로 pods/exec 리소스에 대한 접근을 부여하는 ClusterRole이 있다면, get verb도 허용하도록 업데이트하세요:

- apiGroups: [""]
  resources: ["pods/exec"]
  verbs: ["create", "get"]

ClusterRole이 업데이트되면, kubectl 버전 1.30 이상을 사용하여 Pod에 exec할 수 있습니다.

헬스 체크: 쿠버네티스 클러스터에 접근할 수 없음#

증상#

쿠버네티스 클러스터가 unhealthy로 보고되며, Teleport와 쿠버네티스 클러스터 API 간의 모든 호출이 실패합니다.

설명#

Teleport 쿠버네티스 서비스가 쿠버네티스 클러스터에 대해 여러 차례 헬스 체크를 수행했지만 응답을 받지 못했습니다.

쿠버네티스 클러스터 API 엔드포인트 /selfsubjectaccessreviews/readyz에 대한 호출이 HTTP 상태 코드 없이 오류를 반환했습니다.

해결 방법#

쿠버네티스 클러스터와 네트워크의 근본 원인을 조사하세요.

쿠버네티스 클러스터의 상태를 확인하세요.

kubectl cluster-info
kubectl get --raw /readyz

네트워크 및 방화벽 규칙을 확인하세요.

  • 네트워크가 올바르게 구성되어 있습니까?
  • 보안 그룹을 확인하세요
  • 네트워크 정책을 확인하세요

헬스 체크: 필요한 쿠버네티스 권한 누락#

증상#

쿠버네티스 클러스터가 unhealthy로 보고되며, impersonate users, impersonate groups, impersonate service accounts, get pods와 같은 하나 이상의 쿠버네티스 권한이 누락되어 있습니다.

설명#

Teleport 쿠버네티스 서비스가 쿠버네티스 클러스터에 대해 헬스 체크를 수행했으며, 필요한 쿠버네티스 클러스터 기능이 거부되었다는 응답을 받았습니다.

쿠버네티스 클러스터에 ClusterRole이 누락되었거나, 부분적인 ClusterRole로 구성되어 있습니다. Teleport에는 4가지 쿠버네티스 SelfSubjectAccessReview 권한이 필요합니다:

  • 사용자 임퍼소네이션
  • 그룹 임퍼소네이션
  • 서비스 계정 임퍼소네이션
  • Pod 가져오기

해결 방법#

쿠버네티스 클러스터에 4가지 권한을 가진 ClusterRoleClusterRoleBinding을 추가하세요.

$ kubectl config use-context <your-kube-context>
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: teleport-impersonation
rules:
  - apiGroups:
      - ""
    resources:
      - users
      - groups
      - serviceaccounts
    verbs:
      - impersonate
  - apiGroups:
      - ""
    resources:
      - pods
    verbs:
      - get
  - apiGroups:
      - "authorization.k8s.io"
    resources:
      - selfsubjectaccessreviews
    verbs:
      - create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: teleport
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: teleport-impersonation
subjects:
  - kind: ServiceAccount
    name: teleport-serviceaccount
    namespace: default
EOF

ClusterRoleBinding은 환경에 따라 다를 수 있습니다.

Teleport 쿠버네티스에서 임퍼소네이션 활성화하기도 참고하세요.

헬스 체크: 상태 코드와 함께 비정상 쿠버네티스 클러스터 감지됨#

증상#

쿠버네티스 클러스터가 unhealthy로 보고되며, Teleport가 쿠버네티스 클러스터로부터 오류 상태 코드가 포함된 응답을 받았습니다.

설명#

Teleport 쿠버네티스 서비스가 쿠버네티스 클러스터에 대해 여러 차례 헬스 체크를 수행했고 응답을 받았습니다.

권한 엔드포인트 /selfsubjectaccessreviews에 대한 호출은 실패했고, 쿠버네티스 클러스터의 /readyz 엔드포인트에 대한 호출은 오류 상태 코드가 포함된 응답을 반환했습니다. 이 오류 상태 코드는 쿠버네티스 클러스터 내 컴포넌트가 비정상 상태임을 나타냅니다.

해결 방법#

kubectl을 사용하여 쿠버네티스 클러스터 오류 상태 코드를 진단하세요.

kubectl cluster-info
kubectl get --raw /readyz

헬스 체크: 쿠버네티스 권한을 확인할 수 없음#

증상#

쿠버네티스 클러스터가 unhealthy로 보고되며, Teleport가 헬스 체크 엔드포인트로부터 혼재된 응답을 받았습니다.

설명#

Teleport 쿠버네티스 서비스가 쿠버네티스 클러스터에 대해 여러 차례 헬스 체크를 수행했고 응답을 받았습니다.

권한 엔드포인트 /selfsubjectaccessreviews에 대한 호출은 실패했고, 쿠버네티스 클러스터의 /readyz에 대한 호출은 성공했습니다. 쿠버네티스 클러스터 컴포넌트는 정상 작동 중이며, 쿠버네티스 SelfSubjectAccessReview API에 대한 호출을 무언가가 차단하고 있습니다.

해결 방법#

kubectl을 사용하여 쿠버네티스 클러스터를 진단하세요.

kubectl cluster-info
kubectl get --raw /readyz