외부 RBAC 시스템에서 Teleport 역할 생성
Teleport gRPC API를 사용하여 GitHub 또는 AWS Identity and Access Management와 같은 외부 역할 기반 접근 제어(RBAC) 시스템을 기반으로 역할을 자동으로 생성할 수 있습니다.
Teleport gRPC API를 사용하여 GitHub 또는 AWS Identity and Access Management와 같은 외부 역할 기반 접근 제어(RBAC) 시스템을 기반으로 역할을 자동으로 생성할 수 있습니다.
이는 특히 다음에 유용합니다:
- 새 Teleport 클러스터를 설정할 때 Teleport가 접근 제어를 처리하는 동안 기존 권한 레벨이나 카테고리를 유지할 수 있습니다.
- 관리하는 인프라의 RBAC 시스템이 변경될 때 Teleport 클러스터가 최신 상태를 유지하도록 보장합니다. 이렇게 하면 팀이 외부 RBAC 시스템을 재구성해도 Teleport 역할이 예상치 않게 권한을 얻거나 잃지 않습니다.
작동 방식#
이 가이드에서는 Teleport의 API 클라이언트 라이브러리를 사용하여 Teleport 역할을 생성하는 방법을 보여주는 소규모 데모 애플리케이션을 빌드합니다.
애플리케이션은 Teleport Auth 서비스 gRPC API와 Kubernetes API 서버 모두에 인증하고, Kubernetes API 서버에서 역할 바인딩과 클러스터 역할 바인딩을 로드합니다. 각 역할 바인딩과 클러스터 역할 바인딩에 대해 애플리케이션은 전자의 필드를 후자의 필드에 매핑하는 로직을 사용하여 Teleport 역할을 생성합니다.
위험: 이 가이드에서 빌드할 프로그램은 학습 도구로 의도된 것입니다. 프로덕션 Teleport 클러스터에 연결하지 마세요. 대신 데모 클러스터를 사용하세요.
사전 요구 사항#
-
A running Teleport cluster. If you want to get started with Teleport, sign up for a free trial or set up a demo environment.
-
The
tctlandtshclients.Installing `tctl` and `tsh` clients
-
Determine the version of your Teleport cluster. The
tctlandtshclients must be at most one major version behind your Teleport cluster version. Send a GET request to the Proxy Service at/v1/webapi/findand use a JSON query tool to obtain your cluster version. Replace with the web address of your Teleport Proxy Service:$ TELEPORT_DOMAIN= $ TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')" -
Follow the instructions for your platform to install
tctlandtshclients:
-
- 워크스테이션에 Go 버전
[teleport.golang]이상 설치. Go 다운로드 페이지를 참조하세요. 이 가이드를 완료하기 위해 Go에 익숙할 필요는 없지만, 프로덕션 준비가 된 Teleport 클라이언트 애플리케이션을 빌드하려면 Go 지식이 필요합니다.
프로덕션 시나리오에서는 Teleport 역할 생성의 기반으로 사용할 서드파티 RBAC 솔루션이 이미 있을 것입니다. 이 가이드에서는 minikube를 사용하여 로컬 Kubernetes 클러스터를 배포하고 일부 RBAC 리소스를 설정하여 이를 시뮬레이션합니다. 그런 다음 이 Kubernetes 클러스터를 사용하여 Teleport 역할을 생성합니다.
로컬 데모 환경을 실행하려면 워크스테이션에 다음 도구가 설치되어 있는지 확인하세요:
| 도구 | 용도 | 설치 링크 |
|---|---|---|
| minikube | 로컬 Kubernetes 배포 도구 | minikube 설치 |
| Helm | Kubernetes 패키지 관리자 | Helm 설치 |
| kubectl | Kubernetes 관리 CLI | kubectl 설치 |
| Docker | minikube 필수 드라이버 | Docker 시작하기 |
팁: 데모 프로젝트 설정을 계획하지 않더라도, 이 가이드를 따라 외부 RBAC 시스템을 기반으로 Teleport 역할을 자동으로 생성하는 데 사용할 수 있는 라이브러리, 유형, 함수를 확인할 수 있습니다.
To check that you can connect to your Teleport cluster, sign in with tsh login, then
verify that you can run tctl commands using your current credentials.
For example, run the following command, assigning to the domain name of the Teleport Proxy Service in your cluster and to your Teleport username:
$ tsh login --proxy= --user=
$ tctl status
# Cluster (=teleport.url=)
# Version (=teleport.version=)
# CA pin (=presets.ca_pin=)
If you can connect to the cluster and run the tctl status command, you can use your
current credentials to run subsequent tctl commands from your workstation.
If you host your own Teleport cluster, you can also run tctl commands on the computer that
hosts the Teleport Auth Service for full permissions.
1/4단계. Kubernetes 클러스터 설정#
이 단계에서는 로컬 Kubernetes 클러스터를 시작하고 그 안에 역할 기반 접근 제어를 설정합니다. 그런 다음 이 Kubernetes 클러스터를 Teleport 역할 생성의 기반으로 사용합니다.
minikube 시작#
단일 Docker 컨테이너에서 로컬 Kubernetes 클러스터를 부팅하는 Docker 드라이버로 minikube를 시작합니다:
$ minikube start --driver=docker
이 명령은 로컬 Kubernetes 클러스터를 시작하고 컨텍스트(현재 상호작용 중인 Kubernetes 클러스터)를 minikube로 설정해야 합니다. 이를 확인하려면 다음 명령을 실행합니다:
$ kubectl config current-context
minikube
데모 Kubernetes RBAC 리소스 정의#
다음으로 로컬 minikube 클러스터에 RBAC 리소스를 설정하여 Teleport 역할 생성의 기반으로 사용합니다.
Kubernetes에서는 클러스터를 논리적으로 격리된 네임스페이스로 나눌 수 있습니다. 역할은 특정 네임스페이스의 리소스를 조작하기 위한 권한 집합을 정의합니다. 클러스터 역할은 클러스터의 모든 네임스페이스에 적용되는 역할입니다. 역할 바인딩 또는 클러스터 역할 바인딩을 사용하여 역할이나 클러스터 역할을 Kubernetes 사용자 및 그룹에 연결할 수 있습니다.
app-developer 그룹의 사용자가 app 네임스페이스의 파드를 읽고 나열할 수 있는 Kubernetes 역할과 역할 바인딩을 정의합니다. 다음을 pod-reader.yaml 파일에 추가합니다:
apiVersion: v1
kind: Namespace
metadata:
name: app
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: app
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: app
annotations:
'create-teleport-role': 'true'
subjects:
- kind: Group
name: app-developer
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
리소스를 생성합니다:
$ kubectl apply -f pod-reader.yaml
namespace/app created
role.rbac.authorization.k8s.io/pod-reader created
rolebinding.rbac.authorization.k8s.io/read-pods created
다음으로 ops 그룹의 사용자가 모든 네임스페이스의 파드를 읽고, 생성하고, 명령을 실행할 수 있도록 하는 클러스터 역할 및 클러스터 역할 바인딩을 정의합니다. 다음을 pod-ops.yaml 파일에 추가합니다:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-ops
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list", "create", "exec", "logs"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: pod-ops
annotations:
'create-teleport-role': 'true'
subjects:
- kind: Group
name: ops
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: pod-ops
apiGroup: rbac.authorization.k8s.io
리소스를 생성합니다:
$ kubectl apply -f pod-ops.yaml
clusterrole.rbac.authorization.k8s.io/pod-ops created
clusterrolebinding.rbac.authorization.k8s.io/pod-ops created
이 가이드의 뒷부분에서 생성한 Kubernetes RBAC 리소스를 기반으로 Teleport 역할을 자동으로 생성하는 방법을 보여드립니다.
클라이언트 애플리케이션을 위한 RBAC 리소스 정의#
다음으로 API 클라이언트가 생성한 RBAC 리소스를 읽을 수 있는지 확인합니다. 다음 내용으로 rbac-sync.yaml 파일을 생성합니다:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: rbac-sync
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "clusterroles", "rolebindings", "clusterrolebindings"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: rbac-sync
subjects:
- kind: User
name: sync-kubernetes-rbac
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: rbac-sync
apiGroup: rbac.authorization.k8s.io
변경 사항을 적용합니다:
$ kubectl apply -f rbac-sync.yaml
clusterrole.rbac.authorization.k8s.io/rbac-sync created
clusterrolebinding.rbac.authorization.k8s.io/rbac-sync created
2/4단계. Teleport 설정#
이 단계에서는 API 클라이언트 애플리케이션이 Kubernetes 클러스터와 상호작용할 수 있도록 Teleport를 구성합니다.
클라이언트 애플리케이션을 위한 사용자 및 역할 생성#
클라이언트 애플리케이션에 Teleport에 등록된 Kubernetes 클러스터에 대한 정보를 검색하고, 클러스터에 인증하고, Teleport 역할을 생성하거나 업데이트할 수 있는 Teleport 사용자와 역할을 부여합니다.
다음 내용으로 sync-kubernetes-rbac.yaml 파일을 생성합니다:
kind: role
version: v7
metadata:
name: sync-kubernetes-rbac
spec:
allow:
kubernetes_labels:
'*': '*'
kubernetes_users:
- sync-kubernetes-rbac
kubernetes_resources:
- kind: pod
name: '*'
namespace: '*'
rules:
- resources: ['kubernetes_cluster']
verbs: ['read']
- resources: ['role']
verbs: ['create', 'update']
---
kind: user
metadata:
name: sync-kubernetes-rbac
spec:
roles: ['sync-kubernetes-rbac']
version: v2
사용자와 역할을 생성합니다:
$ tctl create -f sync-kubernetes-rbac.yaml
role 'sync-kubernetes-rbac' has been created
user "sync-kubernetes-rbac" has been created
클라이언트 애플리케이션 가장 활성화#
모든 Teleport 사용자와 마찬가지로 Teleport Auth 서비스는 단기 TLS 자격 증명을 발급하여 sync-kubernetes-rbac 사용자를 인증합니다. 이 경우 sync-kubernetes-rbac 역할과 사용자를 가장하여 수동으로 자격 증명을 요청합니다.
자체 호스팅 Teleport Enterprise 배포를 실행 중이고 Auth 서비스 호스트에서 tctl을 사용하는 경우 이미 가장 권한이 있습니다.
sync-kubernetes-rbac에 대한 가장 권한을 사용자에게 부여하려면 다음 YAML 문서를 sync-kubernetes-rbac-impersonator.yaml 파일에 붙여넣어 sync-kubernetes-rbac-impersonator라는 역할을 정의합니다:
kind: role
version: v5
metadata:
name: sync-kubernetes-rbac-impersonator
spec:
allow:
impersonate:
roles:
- sync-kubernetes-rbac
users:
- sync-kubernetes-rbac
sync-kubernetes-rbac-impersonator 역할을 생성합니다:
$ tctl create -f sync-kubernetes-rbac-impersonator.yaml
Assign the sync-kubernetes-rbac-impersonator role to your Teleport user by running the appropriate
commands for your authentication provider:
이제 sync-kubernetes-rbac 역할과 사용자에 대한 서명된 인증서를 생성할 수 있습니다.
Teleport Kubernetes 서비스 설치#
클라이언트 애플리케이션이 요청을 인증한 후 전달하는 Teleport Kubernetes 서비스를 통해 Kubernetes 클러스터와 통신할 수 있도록 합니다. 이 단계는 로컬 minikube 클러스터에서는 엄밀히 필요하지 않지만 Teleport를 사용하여 외부 RBAC 시스템의 API에 안전하게 접근하는 한 가지 방법을 보여줍니다.
Configure Helm to fetch Teleport charts from the Teleport Helm repository:
$ helm repo add teleport (=teleport.helm_repo_url=)
Refresh the local Helm cache by fetching the latest charts:
$ helm repo update
Kubernetes 서비스가 Teleport 클러스터에 참여하는 데 사용할 토큰을 요청합니다:
$ tctl tokens add --type=kube,app,discovery --format=text
이 토큰을 복사하여 Teleport Kubernetes 서비스를 실행할 때 사용합니다.
올바른 Kubernetes 클러스터에 연결되어 있는지 확인합니다(Teleport에 로그인하면 Kubernetes 컨텍스트가 변경됩니다):
$ kubectl config use-context minikube
Switched to context "minikube".
를 Teleport 프록시 서비스의 호스트 및 포트(예: mytenant.teleport.sh:443)로 할당하고 을 앞서 요청한 토큰으로 할당하여 클러스터에 Teleport Kubernetes 서비스를 설치합니다:
$ helm install teleport-agent teleport/teleport-kube-agent \
--set kubeClusterName=minikube \
--set roles="kube\,app\,discovery" \
--set proxyAddr= \
--set authToken= \
--create-namespace \
--namespace=teleport-agent \
--set labels.environment=demo \
--version (=teleport.version=)
몇 초 후 다음 명령을 실행하여 Teleport Kubernetes 서비스를 배포했는지 확인합니다:
$ kubectl -n teleport-agent get pods
Kubernetes 서비스가 실행 중임을 표시해야 합니다:
NAME READY STATUS RESTARTS AGE
teleport-agent-0 1/1 Running 0 22s
tsh는 클러스터가 Teleport에 등록되었음을 나타내야 합니다:
$ tsh kube ls
Kube Cluster Name Labels Selected
----------------- ---------------- --------
minikube environment=demo
3/4단계. 클라이언트 애플리케이션 작성#
이 시점에서 Teleport 역할 생성에 사용할 외부 RBAC 시스템을 설정하고 API 클라이언트가 Kubernetes 클러스터 및 Teleport 클러스터와 상호작용할 수 있도록 Teleport를 구성했습니다. 이 단계에서는 클라이언트 애플리케이션을 작성합니다.
Go 프로젝트 설정#
API 클라이언트 애플리케이션의 소스 코드를 다운로드합니다:
$ git clone --depth=1 https://github.com/gravitational/teleport -b branch/v(=teleport.major_version=)
$ cd teleport/examples/api-sync-roles
이 가이드의 나머지 부분에서는 클라이언트 애플리케이션을 설정하고 Teleport의 API를 사용하여 Teleport 역할을 자동으로 생성하는 방법을 탐색합니다.
클라이언트 애플리케이션의 아이덴티티 파일 내보내기#
sync-kubernetes-rbac 사용자는 Teleport 클러스터와 Kubernetes 클러스터 모두에 연결하기 위해 서명된 자격 증명이 필요합니다. tctl auth sign 명령을 사용하여 API 클라이언트의 자격 증명을 요청합니다.
Teleport 클러스터에 연결#
다음 tctl auth sign 명령은 sync-kubernetes-rbac 사용자를 가장하고, 서명된 자격 증명을 생성하며, 아이덴티티 파일을 로컬 디렉터리에 씁니다:
$ tctl auth sign --user=sync-kubernetes-rbac --out=auth.pem
아이덴티티 파일 auth.pem에는 TLS 및 SSH 자격 증명이 모두 포함됩니다. 클라이언트 애플리케이션은 SSH 자격 증명을 사용하여 프록시 서비스에 연결하고, 이는 Auth 서비스로의 역방향 터널 연결을 설정합니다. 클라이언트 애플리케이션은 이 역방향 터널과 TLS 자격 증명을 사용하여 Auth 서비스의 gRPC 엔드포인트에 연결합니다.
Kubernetes 클러스터에 연결#
클라이언트 애플리케이션이 Kubernetes 클러스터에 인증할 방법도 제공해야 합니다. 이를 위해 Teleport의 인증 기관을 사용하여 sync-kubernetes-rbac 사용자의 자격 증명에 서명합니다. API 클라이언트는 이 자격 증명을 제시하여 Kubernetes 요청을 Kubernetes 클러스터로 프록시하는 Teleport Kubernetes 서비스에 인증합니다.
가 프록시 서비스의 호스트 및 포트를 포함하도록 하여 다음 명령을 실행합니다:
$ tctl auth sign --user=sync-kubernetes-rbac \
--kube-cluster-name=minikube \
--format=kubernetes \
--proxy=https:// \
--out=kubeconfig
임포트#
api-sync-roles 디렉터리에서 이 가이드에서 시연하는 API 클라이언트 프로그램이 포함된 main.go를 엽니다.
클라이언트 애플리케이션이 Go의 표준 라이브러리에서 임포트하는 패키지:
| 패키지 | 설명 |
|---|---|
context |
context.Context 유형을 포함합니다. context.Context는 실패하거나 시간 초과될 수 있는 외부 서비스 연결과 같은 장기 실행 루틴을 제어하기 위한 추상화입니다. 프로그램은 컨텍스트를 취소하거나 타임아웃 및 메타데이터를 할당할 수 있습니다. |
fmt |
인쇄, 문자열 또는 오류를 위한 데이터 형식화 |
io |
I/O 작업 처리(예: 파일 또는 네트워크 소켓 읽기) |
os |
운영 체제와 상호작용(예: 파일 열기) |
time |
시간 처리. Auth 서비스 연결 타임아웃 및 루프에서 검색 로직 실행을 위한 타이커를 정의하는 데 사용합니다. |
클라이언트는 다음 서드파티 코드를 임포트합니다:
| 패키지 | 설명 |
|---|---|
github.com/gravitational/teleport/api/client |
Auth 서비스의 gRPC API에 인증하고 요청을 만들기 위한 라이브러리, teleport로 별칭 지정됨 |
github.com/gravitational/teleport/api/types |
Auth 서비스 API에서 사용되는 유형(예: 애플리케이션 서비스 레코드) |
github.com/gravitational/trace |
표준 라이브러리보다 유용한 세부 정보로 오류 표시 |
google.golang.org/grpc |
gRPC 클라이언트 및 서버 라이브러리 |
k8s.io/api/rbac/v1 |
Kubernetes RBAC API 클라이언트 라이브러리 |
k8s.io/apimachinery/pkg/apis/meta/v1 |
Kubernetes API 클라이언트 라이브러리에 공통적인 코드 |
k8s.io/client-go/kubernetes |
범용 Kubernetes 클라이언트 설정 |
k8s.io/client-go/kubernetes/typed/rbac/v1 |
Kubernetes RBAC API용 유형 |
k8s.io/client-go/tools/clientcmd |
또 다른 범용 Kubernetes 클라이언트 라이브러리 |
상수#
프로그램은 나중에 프로그램 외부에서 구성 가능하게 만들기 쉽도록 눈에 잘 보이는 위치에 상수를 정의합니다:
const (
proxyAddr string = ""
initTimeout = time.Duration(30) * time.Second
identityFilePath string = "auth.pem"
kubeconfigPath string = "kubeconfig"
clusterName string = "minikube"
roleAnnotationKey string = "create-teleport-role"
)
나중에 프로그램에서 이 상수들을 사용합니다. 나중에 변경하고 싶을 수 있는 일부 값을 정의합니다:
| 상수 | 설명 |
|---|---|
proxyAddr |
Teleport 프록시 서비스의 호스트 및 포트(예: mytenant.teleport.sh:443). 클라이언트를 클러스터에 연결하는 데 사용합니다. 이것을 자신의 프록시 서비스 호스트 및 포트로 할당하세요: |
initTimeout |
Teleport 클러스터 연결 타임아웃(30초로 정의됨). |
identityFilePath |
이전에 생성한 Teleport 아이덴티티 파일의 경로. |
clusterName |
RBAC 리소스를 가져올 Kubernetes 클러스터의 이름. 이 가이드에서 클러스터 이름은 minikube입니다. |
roleAnnotationKey |
Kubernetes에서 주석은 리소스에 추가할 수 있는 임의의 키/값 쌍입니다. 이전에 생성한 역할과 클러스터 역할 바인딩에는 여기서 지정하는 주석 키가 있어 클라이언트 애플리케이션이 이를 가져올 수 있습니다. |
Kubernetes RBAC 클라이언트 초기화#
Kubernetes API에 연결하려면 HTTP 클라이언트를 설정해야 합니다. 클라이언트는 kubeconfigPath의 파일에서 클라이언트 인증서, 인증 기관, 개인 키를 로드하여 상호 TLS로 API에 인증합니다. 앞서 가이드에서 Teleport Auth 서비스에서 이를 요청했습니다.
프로그램은 getRBACClient 함수로 Kubernetes API 클라이언트를 설정합니다:
func getRBACClient() (v1.RbacV1Interface, error) {
f, err := os.Open(kubeconfigPath)
if err != nil {
return nil, trace.Wrap(err)
}
kc, err := io.ReadAll(f)
if err != nil {
return nil, trace.Wrap(err)
}
n, err := clientcmd.RESTConfigFromKubeConfig(kc)
if err != nil {
return nil, trace.Wrap(err)
}
c, err := kubernetes.NewForConfig(n)
if err != nil {
return nil, trace.Wrap(err)
}
return c.RbacV1(), nil
}
getRBACClient는 kubeconfigPath에서 Kubernetes 자격 증명 파일을 열고 읽은 다음, 파일을 사용하여 Kubernetes API 클라이언트 구성(clientcmd.RESTConfigFromKubeConfig(kc))을 설정하고, 그것으로 HTTP 클라이언트(kubernetes.NewForConfig(n))를 설정합니다.
마지막으로 프로그램의 나머지 부분이 Kubernetes 클러스터와 상호작용하는 데 사용하는 역할 기반 접근 제어 전용 Kubernetes API 인터페이스를 반환합니다.
Kubernetes 클러스터 역할 바인딩에서 Teleport 역할 생성#
createTeleportRoleFromClusterRoleBinding 함수는 전자의 필드를 후자의 필드로 채워 Kubernetes 클러스터 역할 바인딩에서 Teleport 역할을 생성합니다:
func createTeleportRoleFromClusterRoleBinding(teleport *client.Client, k types.KubeCluster, r rbacv1.ClusterRoleBinding) error {
if e, ok := r.Annotations[roleAnnotationKey]; !ok || e != "true" {
return nil
}
role := types.RoleV6{}
role.SetMetadata(types.Metadata{
Name: k.GetName() + "-" + r.RoleRef.Name + "-" + "cluster",
})
b := k.GetStaticLabels()
labels := make(types.Labels)
for k, v := range b {
labels[k] = []string{v}
}
role.SetKubernetesLabels(types.Allow, labels)
role.SetKubeResources(types.Allow, []types.KubernetesResource{
types.KubernetesResource{
Kind: "pod",
Namespace: "*",
Name: "*",
},
})
var g []string
var u []string
for _, s := range r.Subjects {
if s.Kind == "User" || s.Kind == "ServiceAccount" {
u = append(u, s.Name)
continue
}
if s.Kind == "Group" {
g = append(g, s.Name)
continue
}
}
role.SetKubeGroups(types.Allow, g)
role.SetKubeUsers(types.Allow, u)
if err := teleport.UpsertRole(
context.Background(),
&role,
); err != nil {
return trace.Wrap(err)
}
fmt.Println("Upserted Teleport role:", role.GetName())
return nil
}
예상치 못한 동작을 피하기 위해 이 함수는 Kubernetes 관리 역할과 Teleport Kubernetes 서비스와 같은 내부 시스템용 역할을 무시합니다. 이 함수는 클러스터 역할 바인딩의 메타데이터에서 특정 키 roleAnnotationKey가 있는 주석을 확인하고, 이 키가 "true"로 설정되지 않은 모든 리소스를 무시합니다.
또한 이 프로그램으로 생성한 역할을 빠르게 식별하는 방법이 필요합니다. 이를 위해 이 함수는 클러스터 역할 바인딩을 기반으로 생성하는 모든 역할에 다음 속성을 기반으로 이름을 지정합니다:
- Kubernetes 클러스터 이름
- Kubernetes 역할 이름
- 접미사
-cluster
데모 애플리케이션에서 이 함수는 minikube-pod-ops-cluster라는 Teleport 역할을 생성합니다.
함수의 나머지 부분은 Teleport API 클라이언트의 역할 유형인 types.RoleV6에 클러스터 역할 바인딩을 기반으로 필드를 할당합니다:
| 역할 필드 | 목적 | 할당 방법 |
|---|---|---|
allow.kubernetes_labels |
이 역할을 가진 사용자가 접근할 수 있는 Teleport 등록 Kubernetes 클러스터의 레이블 | 클러스터 역할 바인딩이 속하는 Teleport 등록 Kubernetes 클러스터를 기반으로 |
allow.kubernetes_resources |
이 역할을 가진 사용자가 접근할 수 있는 특정 네임스페이스의 Kubernetes 파드 | 클러스터 역할 바인딩은 네임스페이스에 제한되지 않으므로 모든 네임스페이스에 대한 접근 허용 |
allow.kubernetes_users 및 allow.kubernetes_groups |
이 역할을 가진 Teleport 사용자가 Kubernetes 클러스터와 상호작용할 때 가정할 Kubernetes 그룹 및 사용자 | 클러스터 역할 바인딩에 연결된 사용자 또는 그룹의 이름 제공 |
Kubernetes 역할 바인딩에서 Teleport 역할 생성#
클러스터 역할 바인딩과 마찬가지로 이 프로그램은 Kubernetes 역할 바인딩을 기반으로 Teleport 역할을 생성합니다:
func createTeleportRoleFromRoleBinding(teleport *client.Client, k types.KubeCluster, r rbacv1.RoleBinding) error {
if e, ok := r.Annotations[roleAnnotationKey]; !ok || e != "true" {
return nil
}
role := types.RoleV6{}
role.SetMetadata(types.Metadata{
Name: k.GetName() + "-" + r.RoleRef.Name + "-" + r.Namespace,
})
b := k.GetStaticLabels()
labels := make(types.Labels)
for k, v := range b {
labels[k] = []string{v}
}
role.SetKubernetesLabels(types.Allow, labels)
role.SetKubeResources(types.Allow, []types.KubernetesResource{
types.KubernetesResource{
Kind: "pod",
Namespace: r.Namespace,
Name: "*",
},
})
var g []string
var u []string
for _, s := range r.Subjects {
if s.Kind == "User" || s.Kind == "ServiceAccount" {
u = append(u, s.Name)
continue
}
if s.Kind == "Group" {
g = append(g, s.Name)
continue
}
}
role.SetKubeGroups(types.Allow, g)
role.SetKubeUsers(types.Allow, u)
if err := teleport.UpsertRole(
context.Background(),
&role,
); err != nil {
return trace.Wrap(err)
}
fmt.Println("Upserted Teleport role:", role.GetName())
return nil
}
이 함수의 전반적인 동작은 createTeleportRoleFromClusterRoleBinding과 동일하지만 Kubernetes 역할 바인딩은 Teleport 역할에 필드를 할당하는 방법에서 차이가 있습니다:
- 역할 이름을 설정할 때 이 역할이 적용되는 네임스페이스를 나타내기 위해
-cluster대신 역할 바인딩의 네임스페이스를 접미사로 사용합니다. - 역할의
kubernetes_resources필드에서 값은 모든 네임스페이스에 적용하는 대신 역할 바인딩과 동일한 네임스페이스를 가집니다.
Kubernetes 리소스를 기반으로 Teleport 역할 생성#
이제 개별 Kubernetes RBAC 리소스를 기반으로 Teleport 역할을 생성하는 함수가 있으므로 Kubernetes 클러스터에서 모든 RBAC 리소스를 가져와 이러한 함수를 호출할 수 있습니다:
func createTeleportRolesForKubeCluster(teleport *client.Client, k types.KubeCluster) error {
rbac, err := getRBACClient()
if err != nil {
return trace.Wrap(err)
}
crb, err := rbac.ClusterRoleBindings().List(
context.Background(),
metav1.ListOptions{},
)
if err != nil {
return trace.Wrap(err)
}
for _, i := range crb.Items {
if err := createTeleportRoleFromClusterRoleBinding(teleport, k, i); err != nil {
return trace.Wrap(err)
}
}
rb, err := rbac.RoleBindings("").List(
context.Background(),
metav1.ListOptions{},
)
if err != nil {
return trace.Wrap(err)
}
for _, i := range rb.Items {
if err := createTeleportRoleFromRoleBinding(teleport, k, i); err != nil {
return trace.Wrap(err)
}
}
return nil
}
createTeleportRolesForKubeCluster는 Teleport 클라이언트와 Teleport 등록 Kubernetes 클러스터를 가져옵니다. 앞서 정의한 getRBACClient 함수를 호출하여 Kubernetes 클러스터용 클라이언트를 설정합니다. 그런 다음:
- Kubernetes 클러스터 역할 바인딩을 나열하고 각각에 대해 Teleport 역할을 생성합니다.
- Kubernetes 역할 바인딩을 나열하고 각각에 대해 Teleport 역할을 생성합니다.
클라이언트 초기화 및 애플리케이션 시작#
앞서 선언한 함수들은 Teleport API 클라이언트와 Teleport 등록 Kubernetes 클러스터가 필요하며, 이를 프로그램의 진입점인 main 함수에서 초기화합니다:
func main() {
ctx, cancel := context.WithTimeout(context.Background(), initTimeout)
defer cancel()
creds := client.LoadIdentityFile(identityFilePath)
teleport, err := client.New(ctx, client.Config{
Addrs: []string{proxyAddr},
Credentials: []client.Credentials{creds},
})
if err != nil {
panic(err)
}
fmt.Println("Connected to Teleport")
ks, err := teleport.GetKubernetesServers(context.Background())
if err != nil {
panic(err)
}
for _, k := range ks {
if k.GetCluster().GetName() != clusterName {
continue
}
fmt.Println("Retrieved Kubernetes cluster", clusterName)
if err := createTeleportRolesForKubeCluster(teleport, k.GetCluster()); err != nil {
panic(err)
}
fmt.Println("Created roles for Kubernetes cluster", clusterName)
return
}
panic("Unable to locate a Kubernetes Service instance for " + clusterName)
}
client는 API 클라이언트 설정을 위한 Teleport의 라이브러리입니다. 프로그램은 client.LoadIdentityFile을 호출하여 client.Credentials를 얻어 Teleport 클라이언트를 초기화합니다. 그런 다음 client.Credentials를 사용하여 client.New를 호출하며, 제공된 아이덴티티 파일을 사용하여 Addrs 필드에 지정된 Teleport 프록시 서비스에 연결합니다.
경고: 이 프로그램은 자격 증명이나 Teleport 클러스터 주소를 검증하지 않습니다. 다음을 확인하세요:
- 이전에 내보낸 아이덴티티 파일의 TTL이 만료되지 않았는지
teleport.Config의Addrs필드에 제공한 값이 Teleport 프록시 서비스의 호스트 및 웹 포트를 모두 포함하는지(예:mytenant.teleport.sh:443)
Teleport 클라이언트를 초기화한 후 main 함수는 Teleport에 등록된 모든 Kubernetes 서버(teleport.GetKubernetesServers)를 가져와 지정한 것과 일치하는 등록된 Kubernetes 클러스터가 있는지 확인합니다.
일치하는 Kubernetes 클러스터가 있으면 앞서 정의한 createTeleportRolesForKubeClusters 함수를 호출합니다. 없으면 프로그램은 오류 메시지와 스택 트레이스를 Go의 내장 panic 함수를 호출하여 출력합니다.
4/4단계. 클라이언트 애플리케이션 테스트#
클라이언트 애플리케이션을 테스트하려면 프로젝트 디렉터리 내에서 시작합니다:
$ go run main.go
다음 출력이 표시됩니다:
Connected to Teleport
Retrieved Kubernetes cluster minikube
Upserted Teleport role: minikube-pod-ops-cluster
Upserted Teleport role: minikube-pod-reader-app
Created roles for Kubernetes cluster minikube
다음 명령을 실행하여 새 minikube-pod-ops-cluster 역할을 검사합니다:
$ tctl get roles/minikube-pod-ops-cluster
다음과 유사한 출력이 표시됩니다:
kind: role
metadata:
id: 1678732494974032643
name: minikube-pod-ops-cluster
spec:
allow:
kubernetes_groups:
- ops
kubernetes_labels:
environment: demo
kubernetes_resources:
- kind: pod
name: '*'
namespace: '*'
deny: {}
options:
cert_format: standard
create_host_user: false
desktop_clipboard: true
desktop_directory_sharing: true
enhanced_recording:
- command
- network
forward_agent: false
idp:
saml:
enabled: true
max_session_ttl: 30h0m0s
pin_source_ip: false
ssh_port_forwarding:
remote:
enabled: true
local:
enabled: true
record_session:
default: best_effort
desktop: true
ssh_file_copy: true
version: v7
다음 명령으로 검색할 수 있는 minikube-pod-reader-app 역할과 비교합니다:
$ tctl get roles/minikube-pod-reader-app
생성된 역할:
kind: role
metadata:
id: 1678732495284493075
name: minikube-pod-reader-app
spec:
allow:
kubernetes_groups:
- app-developer
kubernetes_labels:
environment: demo
kubernetes_resources:
- kind: pod
name: '*'
namespace: app
deny: {}
options:
cert_format: standard
create_host_user: false
desktop_clipboard: true
desktop_directory_sharing: true
enhanced_recording:
- command
- network
forward_agent: false
idp:
saml:
enabled: true
max_session_ttl: 30h0m0s
pin_source_ip: false
ssh_port_forwarding:
remote:
enabled: true
local:
enabled: true
record_session:
default: best_effort
desktop: true
ssh_file_copy: true
version: v7
역할 바인딩은 네임스페이스에 지정되어 있으므로 이 역할은 이 역할 바인딩이 적용된 app 네임스페이스의 파드에만 접근을 허용합니다. Kubernetes 서비스는 이 역할을 가진 사용자의 트래픽을 app-developer Kubernetes 그룹을 사용하여 전달합니다.
다음 단계#
Kubernetes RBAC 시스템을 기반으로 Teleport 역할을 생성하는 Teleport API 클라이언트를 구현했습니다. Teleport의 API를 사용하여 GitHub 팀이나 데이터베이스 관리 시스템 내의 그룹과 같은 다른 RBAC 시스템과 상호작용하는 유사한 애플리케이션을 빌드할 수 있습니다.
다음은 클라이언트 애플리케이션을 구축하기 위한 출발점입니다.
Teleport 역할에 대해 자세히 알아보기#
외부 RBAC 솔루션에서 Teleport 역할을 생성하는 효과적인 클라이언트 애플리케이션을 작성하려면 접근을 관리하려는 인프라 리소스에 적용되는 역할 필드를 이해해야 합니다.
다양한 인프라 리소스와 관련된 필드에 대한 가이드는 아래 링크를 참조하세요:
일반적인 지침은 접근 제어 참조를 읽으세요.
Teleport로 클라우드 공급자 등록#
Teleport로 클라우드 공급자 API를 보호하고 API 클라이언트 애플리케이션에게 Teleport 애플리케이션 서비스를 통해 이러한 API에 연결하도록 지시할 수 있습니다. Teleport로 보호된 클라우드 공급자 API를 사용하여 클라우드 공급자의 RBAC 솔루션을 기반으로 Teleport 역할을 생성할 수 있습니다.
클라우드 공급자 API에 대한 Teleport 애플리케이션 서비스 설정 방법 가이드:
예제 참조#
Teleport 코드 저장소에는 프로덕션 준비가 된 Teleport API 클라이언트 예제가 포함되어 있습니다. 현재 Teleport 역할을 생성하는 플러그인을 유지 관리하지 않지만 이러한 예제를 사용하여 구성 파싱, 재시도 및 기타 작업을 구현하는 방법을 확인할 수 있습니다.
단기 자격 증명으로 클라이언트 애플리케이션 프로비저닝#
이 예제에서는 tctl auth sign 명령을 사용하여 작성한 프로그램의 자격 증명을 가져왔습니다. 프로덕션 사용을 위해서는 이러한 자격 증명이 도난당할 위험을 줄이는 머신 및 워크로드 아이덴티티를 통해 단기 자격 증명을 프로비저닝할 것을 권장합니다. 자세히 알아보려면 머신 및 워크로드 아이덴티티 문서를 참조하세요.
