Composition에서 연결 정보(Connection Details) 노출하기
Composition에서 연결 정보(Connection Details) 노출하기 (Connection Details Composition)
이 가이드는 복합 리소스(XR)의 연결 정보(connection details)를 노출하는 방법을 보여 줍니다. 복합 리소스는 여러 리소스를 구성(compose)할 수 있기 때문에 노출하는 연결 정보는 종종 구성된 리소스(composed resources)들의 연결 정보를 합친 집계(aggregate) 형태가 됩니다.
출처: 문서
본문
권장하는 방법은 Composition에 쿠버네티스 Secret 리소스를 포함하여 다른 리소스들의 연결 정보를 집계하고 XR을 위해 노출하는 것입니다.
참고 Crossplane v1은 XR을 위한 연결 정보를 자동으로 생성하는 기능을 포함했습니다. Crossplane v2는 이 기능을 XR에 대해서만 제거합니다. 관리 리소스(MR)는 이 변경의 영향을 받지 않으며 여전히
writeConnectionSecretToRef필드를 통해 연결 정보를 지원합니다.Crossplane v1에서 XR 연결 정보를 지정하는 방법에 대해 더 알아보려면 v1 connection details 문서 페이지를 참고하세요.
예시 개요 (Example overview)
이 가이드는 UserAccessKey 복합 리소스를 생성하여 복합 리소스가 연결 정보를 노출하는 방법을 보여 줍니다. 이 XR은 여러 액세스 키를 가진 AWS IAM 사용자를 나타냅니다.
사용자가 UserAccessKey를 생성하면 크로스플레인은 AWS에 IAM User와 두 개의 AccessKeys를 프로비저닝합니다. 각 AccessKey는 username과 password 같은 자체 연결 정보를 생성합니다. UserAccessKey는 또한 composed resources의 집계된 연결 정보를 노출하는 Secret 리소스를 구성하여, 사용자와 애플리케이션이 그것을 소비할 수 있게 합니다.
UserAccessKey XR 예시는 다음과 같습니다.
apiVersion: example.org/v1alpha1
kind: UserAccessKey
metadata:
namespace: default
name: my-keys
배후에서 크로스플레인은:
- AWS IAM User와 두 개의 AccessKeys(composed resources)를 생성합니다.
- 두 AccessKeys의 연결 정보를 수집합니다.
- 그것들을 Secret에서 UserAccessKey의 연결 정보로 노출합니다.
복합 리소스의 연결 정보 Secret은 다음과 같습니다.
apiVersion: v1
kind: Secret
metadata:
namespace: default
name: my-keys-connection-details
data:
user-0:
password-0:
user-1:
password-1:
사용자와 애플리케이션은 이 Secret을 읽어 UserAccessKey 연결 정보를 소비할 수 있습니다.
팁 이 가이드의 패턴은 연결 정보를 노출해야 하는 모든 복합 리소스에 적용됩니다. 예를 들어:
- 데이터베이스 연결 문자열과 자격 증명
- 클러스터 클라이언트 인증서와 키 데이터
- 서비스와 ingress의 애플리케이션 엔드포인트
사전 요구 사항 (Prerequisites)
이 가이드에는 다음이 필요합니다.
- 쿠버네티스 클러스터
- 쿠버네티스 클러스터에 설치된 크로스플레인
- 자격 증명과 함께 설치·구성된 provider-aws-iam
팁 AWS 프로바이더를 설정하려면 Get Started with Managed Resources 가이드를 따르되, provider
provider-aws-iam:v2.3.0을 사용하세요. 프로바이더 설치와 자격 증명 구성 단계를 완료한 후 이 가이드로 돌아오세요.
복합 리소스 빌드 (Build the composite resource)
연결 정보를 노출하는 복합 리소스를 만들려면 다음 단계를 따르세요.
- 복합 리소스의 스키마 정의
- 사용할 Composition 함수 설치
- Composition이 연결 정보를 노출하는 방법 구성
이 단계를 완료한 후 복합 리소스를 사용할 수 있습니다.
스키마 정의 (Define the schema)
CompositeResourceDefinition(XRD)은 복합 리소스를 정의합니다.
이 예시에서는 UserAccessKey 복합 리소스에 대한 XRD를 만듭니다.
apiVersion: apiextensions.crossplane.io/v2
kind: CompositeResourceDefinition
metadata:
name: useraccesskeys.example.org
spec:
group: example.org
names:
kind: UserAccessKey
plural: useraccesskeys
scope: Namespaced
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
writeConnectionSecretToRef:
type: object
properties:
name:
type: string
kubectl apply -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/xrd.yaml
팁 이 XRD 스키마는 사용자가 XR 연결 정보 secret의 이름을 선택적으로 설정할 수 있게 해 주는
.spec.writeConnectionSecretToRef.name필드를 정의합니다.Cluster범위 XRD의 경우.spec.writeConnectionSecretToRef.namespace필드를 추가하여 사용자가 secret의 네임스페이스도 지정할 수 있게 할 수 있습니다.
이제 쿠버네티스 API가 UserAccessKey 복합 리소스에 대한 요청을 서비스합니다.
함수 설치 (Install the function)
Composition 함수는 리소스를 구성하고 연결 정보를 노출하는 데 도움이 되는 일반적인 기능을 제공합니다. 이 가이드는 여러 함수로 연결 정보를 구성하는 방법을 보여 줍니다. 아래 탭에서 사용할 언어를 선택하세요.
YAML — YAML 지원을 설치하려면 이 Composition 함수를 만드세요.
apiVersion: pkg.crossplane.io/v1
kind: Function
metadata:
name: function-patch-and-transform
spec:
package: xpkg.crossplane.io/crossplane-contrib/function-patch-and-transform:v0.10.0
kubectl apply -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/fn-patch-and-transform.yaml
크로스플레인이 함수를 설치했는지 확인하세요.
kubectl get -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/fn-patch-and-transform.yaml
NAME INSTALLED HEALTHY PACKAGE AGE
function-patch-and-transform True True xpkg.crossplane.io/crossplane-contrib/function-patch-and-transform:v0.10.0 8s
Templated YAML — Helm 차트 작성에 익숙하다면 Templated YAML이 좋은 선택입니다. 템플릿 YAML 지원을 설치하려면 이 Composition 함수를 만드세요.
apiVersion: pkg.crossplane.io/v1
kind: Function
metadata:
name: function-go-templating
spec:
package: xpkg.crossplane.io/crossplane-contrib/function-go-templating:v0.11.2
kubectl apply -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/fn-go-templating.yaml
kubectl get -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/fn-go-templating.yaml
NAME INSTALLED HEALTHY PACKAGE AGE
function-go-templating True True xpkg.crossplane.io/crossplane-contrib/function-go-templating:v0.11.2 15s
Python — Python 지원을 설치하려면 이 Composition 함수를 만드세요.
apiVersion: pkg.crossplane.io/v1
kind: Function
metadata:
name: function-python
spec:
package: xpkg.crossplane.io/crossplane-contrib/function-python:v0.2.0
kubectl apply -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/fn-python.yaml
kubectl get -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/fn-python.yaml
NAME INSTALLED HEALTHY PACKAGE AGE
function-python True True xpkg.crossplane.io/crossplane-contrib/function-python:v0.2.0 12s
KCL — KCL 지원을 설치하려면 이 Composition 함수를 만드세요.
apiVersion: pkg.crossplane.io/v1
kind: Function
metadata:
name: function-kcl
spec:
package: xpkg.crossplane.io/crossplane-contrib/function-kcl:v0.11.6
kubectl apply -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/fn-kcl.yaml
kubectl get -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/fn-kcl.yaml
NAME INSTALLED HEALTHY PACKAGE AGE
function-kcl True True xpkg.crossplane.io/crossplane-contrib/function-kcl:v0.11.6 6s
Pythonic — Pythonic(https://github.com/crossplane-contrib/function-pythonic) 지원을 설치하려면 이 Composition 함수를 만드세요.
apiVersion: pkg.crossplane.io/v1
kind: Function
metadata:
name: function-pythonic
spec:
package: xpkg.crossplane.io/crossplane-contrib/function-pythonic:v0.3.0
kubectl apply -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/fn-pythonic.yaml
kubectl get -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/fn-pythonic.yaml
NAME INSTALLED HEALTHY PACKAGE AGE
function-pythonic True True xpkg.crossplane.io/crossplane-contrib/function-pythonic:v0.3.0 1m
이 가이드는 또한 function-auto-ready를 사용합니다. 이 함수는 composed resources가 건강할 때 자동으로 ready로 표시합니다.
apiVersion: pkg.crossplane.io/v1
kind: Function
metadata:
name: function-auto-ready
spec:
package: xpkg.crossplane.io/crossplane-contrib/function-auto-ready:v0.6.0
kubectl apply -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/fn-auto-ready.yaml
Composition 구성 (Configure the composition)
Composition은 복합 리소스에 대한 리소스 구성 방법을 크로스플레인에 알려줍니다. 이 가이드는 또한 복합 리소스의 연결 정보를 노출하기 위한 composed Secret 리소스를 포함합니다.
일반적인 패턴은:
- Composed resources가 자신의 연결 정보를 개별 Secrets에 씁니다.
- Composition이 함수 실행 시 그 연결 정보를 읽습니다.
- Composition이 XR을 위한 집계된 연결 정보를 나타내는 composed Secret을 만듭니다.
팁 복합 리소스의 연결 정보 secret은 원하는 모든 데이터를 포함할 수 있고 필요에 따라 변환할 수 있습니다. 관리 리소스의 연결 정보에만 국한되지 않습니다.
ConfigMaps나Services같은 임의의 쿠버네티스 리소스를 포함한 모든 composed resource의 데이터를 포함할 수 있습니다.
UserAccessKey 복합 리소스에 대한 연결 정보를 노출하는 Composition을 만듭니다.
이 예시에서 Composition은 두 개의 AccessKey 관리 리소스를 생성하고 그 자격 증명을 복합 리소스의 연결 정보 Secret으로 노출합니다.
YAML:
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: useraccesskeys-patch-and-transform
spec:
compositeTypeRef:
apiVersion: example.org/v1alpha1
kind: UserAccessKey
mode: Pipeline
pipeline:
- step: patch-and-transform
functionRef:
name: function-patch-and-transform
input:
apiVersion: pt.fn.crossplane.io/v1beta1
kind: Resources
writeConnectionSecretToRef:
patches:
- type: FromCompositeFieldPath
fromFieldPath: spec.writeConnectionSecretToRef.name
toFieldPath: name
resources:
- name: user
base:
apiVersion: iam.aws.m.upbound.io/v1beta1
kind: User
spec:
forProvider: {}
- name: accesskey-0
base:
apiVersion: iam.aws.m.upbound.io/v1beta1
kind: AccessKey
spec:
forProvider:
userSelector:
matchControllerRef: true
writeConnectionSecretToRef:
name: accesskey-secret-0
connectionDetails:
- name: user-0
type: FromConnectionSecretKey
fromConnectionSecretKey: username
- name: password-0
type: FromConnectionSecretKey
fromConnectionSecretKey: password
patches:
- type: FromCompositeFieldPath
fromFieldPath: metadata.name
toFieldPath: spec.writeConnectionSecretToRef.name
transforms:
- type: string
string:
type: Format
fmt: "%s-accesskey-secret-0"
- name: accesskey-1
base:
apiVersion: iam.aws.m.upbound.io/v1beta1
kind: AccessKey
spec:
forProvider:
userSelector:
matchControllerRef: true
writeConnectionSecretToRef:
name: accesskey-secret-1
connectionDetails:
- name: user-1
type: FromConnectionSecretKey
fromConnectionSecretKey: username
- name: password-1
type: FromConnectionSecretKey
fromConnectionSecretKey: password
patches:
- type: FromCompositeFieldPath
fromFieldPath: metadata.name
toFieldPath: spec.writeConnectionSecretToRef.name
transforms:
- type: string
string:
type: Format
fmt: "%s-accesskey-secret-1"
- step: ready
functionRef:
name: function-auto-ready
kubectl apply -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/composition-patch-and-transform.yaml
이 Composition이 연결 정보를 노출하는 방법:
- 각 composed AccessKey는
writeConnectionSecretToRef가 설정되어 있습니다. 이것은 각 AccessKey가 자격 증명을 개별 Secret에 쓰도록 지시합니다. - 각 AccessKey는
connectionDetails를 정의하여 어떤 키가 XR의 집계된 연결 정보 secret에 포함되어야 하는지 지정합니다. - 각 연결 정보 항목의
name필드는 집계된 secret에서 키 이름을 설정합니다. fromConnectionSecretKey필드는 composed resource의 개별 연결 secret에서 읽을 키를 지정합니다.- 함수의 입력에는 연결 secret을 만들 위치를 지정할 수 있는 최상위
writeConnectionSecretToRef섹션이 포함되어 있습니다. writeConnectionSecretToRef섹션의 patches는 XR의.spec.writeConnectionSecretToRef.name필드에서 secret 이름을 읽습니다.- 함수는 XR의 composed resources에 XR의 집계된 연결 정보를 나타내는 Secret 객체를 자동으로 포함합니다.
- 이 Secret을 직접 만들거나 구성할 필요가 없습니다. 자동으로 처리됩니다.
Templated YAML:
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: useraccesskeys-go-templating
spec:
compositeTypeRef:
apiVersion: example.org/v1alpha1
kind: UserAccessKey
mode: Pipeline
pipeline:
- step: render-templates
functionRef:
name: function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
---
apiVersion: iam.aws.m.upbound.io/v1beta1
kind: User
metadata:
annotations:
{{ setResourceNameAnnotation "user" }}
spec:
forProvider: {}
---
apiVersion: iam.aws.m.upbound.io/v1beta1
kind: AccessKey
metadata:
annotations:
{{ setResourceNameAnnotation "accesskey-0" }}
spec:
forProvider:
userSelector:
matchControllerRef: true
writeConnectionSecretToRef:
name: {{ $.observed.composite.resource.metadata.name }}-accesskey-secret-0
---
apiVersion: iam.aws.m.upbound.io/v1beta1
kind: AccessKey
metadata:
annotations:
{{ setResourceNameAnnotation "accesskey-1" }}
spec:
forProvider:
userSelector:
matchControllerRef: true
writeConnectionSecretToRef:
name: {{ $.observed.composite.resource.metadata.name }}-accesskey-secret-1
---
apiVersion: v1
kind: Secret
metadata:
name: {{ dig "spec" "writeConnectionSecretToRef" "name" "" $.observed.composite.resource}}
annotations:
{{ setResourceNameAnnotation "connection-secret" }}
{{ if eq $.observed.resources nil }}
data: {}
{{ else }}
data:
user-0: {{ ( index $.observed.resources "accesskey-0" ).connectionDetails.username }}
user-1: {{ ( index $.observed.resources "accesskey-1" ).connectionDetails.username }}
password-0: {{ ( index $.observed.resources "accesskey-0" ).connectionDetails.password }}
password-1: {{ ( index $.observed.resources "accesskey-1" ).connectionDetails.password }}
{{ end }}
- step: ready
functionRef:
name: function-auto-ready
kubectl apply -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/composition-go-templating.yaml
이 Composition이 연결 정보를 노출하는 방법:
- 각 composed AccessKey는
writeConnectionSecretToRef가 설정되어 있습니다. 이것은 각 AccessKey가 자격 증명을 개별 Secret에 쓰도록 지시합니다. - Composition은 복합 리소스의 연결 정보를 나타내는 명시적인
Secret리소스를 만듭니다. - Secret의 이름은
dig함수를 사용하여 XR의.spec.writeConnectionSecretToRef.name필드가 존재하면 읽어서 설정합니다. - 크로스플레인은 각 AccessKey의 연결 정보를 관찰하고 함수 실행 시 Composition에서 사용할 수 있게 만듭니다.
- Secret은
$.observed.resources를 통해 관찰된 composed resources에서 연결 정보를 읽습니다. {{ if eq $.observed.resources nil }}검사는 composed resources가 아직 생성 중인 초기 단계를 처리합니다.- function-go-templating에서 연결 정보는 이미 base64로 인코딩되어 있으므로 Secret의 data 필드에 직접 사용합니다.
Python:
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: useraccesskeys-python
spec:
compositeTypeRef:
apiVersion: example.org/v1alpha1
kind: UserAccessKey
mode: Pipeline
pipeline:
- step: render-python
functionRef:
name: function-python
input:
apiVersion: python.fn.crossplane.io/v1beta1
kind: Script
script: |
def compose(req, rsp):
# Get observed composite resource
oxr = req.observed.composite.resource
oxr_name = oxr["metadata"]["name"]
# IAM User
rsp.desired.resources["user"].resource.update({
"apiVersion": "iam.aws.m.upbound.io/v1beta1",
"kind": "User",
"spec": {
"forProvider": {}
}
})
# Access Key 0
rsp.desired.resources["accesskey-0"].resource.update({
"apiVersion": "iam.aws.m.upbound.io/v1beta1",
"kind": "AccessKey",
"spec": {
"forProvider": {
"userSelector": {
"matchControllerRef": True
}
},
"writeConnectionSecretToRef": {
"name": f"{oxr_name}-accesskey-secret-0"
}
}
})
# Access Key 1
rsp.desired.resources["accesskey-1"].resource.update({
"apiVersion": "iam.aws.m.upbound.io/v1beta1",
"kind": "AccessKey",
"spec": {
"forProvider": {
"userSelector": {
"matchControllerRef": True
}
},
"writeConnectionSecretToRef": {
"name": f"{oxr_name}-accesskey-secret-1"
}
}
})
# Secret representing the composite resource's connection details
secret_resource = {
"apiVersion": "v1",
"kind": "Secret",
"metadata": {}
}
# If a secret name was provided then use it
secret_name = ""
if "writeConnectionSecretToRef" in oxr["spec"] and "name" in oxr["spec"]["writeConnectionSecretToRef"]:
secret_name = oxr["spec"]["writeConnectionSecretToRef"]["name"]
secret_resource["metadata"]["name"] = secret_name
# Only add data if we have connection details to populate
data = {}
if "accesskey-0" in req.observed.resources:
accesskey0_conn = req.observed.resources["accesskey-0"].connection_details
if "username" in accesskey0_conn:
data["user-0"] = accesskey0_conn["username"].decode("utf-8")
if "password" in accesskey0_conn:
data["password-0"] = accesskey0_conn["password"].decode("utf-8")
if "accesskey-1" in req.observed.resources:
accesskey1_conn = req.observed.resources["accesskey-1"].connection_details
if "username" in accesskey1_conn:
data["user-1"] = accesskey1_conn["username"].decode("utf-8")
if "password" in accesskey1_conn:
data["password-1"] = accesskey1_conn["password"].decode("utf-8")
if data:
secret_resource["stringData"] = data
rsp.desired.resources["connection-secret"].resource.update(secret_resource)
- step: ready
functionRef:
name: function-auto-ready
kubectl apply -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/composition-python.yaml
이 Composition이 연결 정보를 노출하는 방법:
- 각 composed AccessKey는
writeConnectionSecretToRef가 설정되어 있습니다. 이것은 각 AccessKey가 자격 증명을 개별 Secret에 쓰도록 지시합니다. - Composition은 복합 리소스의 연결 정보를 나타내는 명시적인
Secret리소스를 만듭니다. secret_name은 XR의.spec.writeConnectionSecretToRef.name필드가 존재하는지 확인한 후에만 설정됩니다.- 크로스플레인은 각 AccessKey의 연결 정보를 관찰하고 함수 실행 시 Composition에서 사용할 수 있게 만듭니다.
- Secret은
req.observed.resources["accesskey-0"].connection_details를 통해 관찰된 composed resources에서 연결 정보를 읽습니다. if "accesskey-0" in req.observed.resources검사는 composed resources가 아직 생성 중인 초기 단계를 처리합니다.- function-python에서 연결 정보는 평문 바이트(plaintext bytes)입니다. Secret에 저장하려면
.decode("utf-8")로 문자열로 변환한 후 secret의stringData필드를 사용해 저장합니다.
KCL:
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: useraccesskeys-kcl
spec:
compositeTypeRef:
apiVersion: example.org/v1alpha1
kind: UserAccessKey
mode: Pipeline
pipeline:
- step: render-kcl
functionRef:
name: function-kcl
input:
apiVersion: krm.kcl.dev/v1alpha1
kind: KCLInput
spec:
source: |
oxr = option("params").oxr
ocds = option("params").ocds
user = {
apiVersion = "iam.aws.m.upbound.io/v1beta1"
kind = "User"
metadata.annotations = {
"krm.kcl.dev/composition-resource-name" = "user"
}
spec.forProvider = {}
}
accesskey0 = {
apiVersion = "iam.aws.m.upbound.io/v1beta1"
kind = "AccessKey"
metadata.annotations = {
"krm.kcl.dev/composition-resource-name" = "accesskey-0"
}
spec.forProvider.userSelector.matchControllerRef = True
spec.writeConnectionSecretToRef.name = "${oxr.metadata.name}-accesskey-secret-0"
}
accesskey1 = {
apiVersion = "iam.aws.m.upbound.io/v1beta1"
kind = "AccessKey"
metadata.annotations = {
"krm.kcl.dev/composition-resource-name" = "accesskey-1"
}
spec.forProvider.userSelector.matchControllerRef = True
spec.writeConnectionSecretToRef.name = "${oxr.metadata.name}-accesskey-secret-1"
}
secret = {
apiVersion = "v1"
kind = "Secret"
metadata.name = oxr?.spec?.writeConnectionSecretToRef?.name or ""
metadata.annotations = {
"krm.kcl.dev/composition-resource-name" = "connection-secret"
}
data = {
"user-0" = ocds["accesskey-0"]?.ConnectionDetails?.username or ""
"user-1" = ocds["accesskey-1"]?.ConnectionDetails?.username or ""
"password-0" = ocds["accesskey-0"]?.ConnectionDetails?.password or ""
"password-1" = ocds["accesskey-1"]?.ConnectionDetails?.password or ""
} if ocds else {}
}
items = [user, accesskey0, accesskey1, secret]
- step: ready
functionRef:
name: function-auto-ready
kubectl apply -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/composition-kcl.yaml
이 Composition이 연결 정보를 노출하는 방법:
- 각 composed AccessKey는
writeConnectionSecretToRef가 설정되어 있습니다. 이것은 각 AccessKey가 자격 증명을 개별 Secret에 쓰도록 지시합니다. - Composition은 복합 리소스의 연결 정보를 나타내는 명시적인
Secret리소스를 만듭니다. - Secret의 이름은
?.선택적 체이닝(optional chaining) 연산자를 사용하여 XR의.spec.writeConnectionSecretToRef.name필드가 존재하면 읽어서 설정합니다. - 크로스플레인은 각 AccessKey의 연결 정보를 관찰하고 함수 실행 시 Composition에서 사용할 수 있게 만듭니다.
- Secret은
ocds["accesskey-0"]?.ConnectionDetails?.username을 통해 관찰된 composed resources에서 연결 정보를 읽으며, 연결 정보가 아직 존재하지 않는 경우를 처리합니다. if ocds else {}는 composed resources가 아직 생성 중인 단계를 처리합니다.- function-kcl에서 연결 정보는 이미 base64로 인코딩되어 있으므로 Secret의 data 필드에 직접 사용합니다.
Pythonic:
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: useraccesskeys-pythonic
spec:
compositeTypeRef:
apiVersion: example.org/v1alpha1
kind: UserAccessKey
mode: Pipeline
pipeline:
- step: render-pythonic
functionRef:
name: function-pythonic
input:
apiVersion: pythonic.fn.crossplane.io/v1alpha1
kind: Composite
composite: |
class Composite(BaseComposite):
def compose(self):
self.connectionSecret = self.spec.writeConnectionSecretToRef
user = self.resources.user('iam.aws.m.upbound.io/v1beta1', 'User')
user.spec.forProvider = {}
for ix in range(2):
key = self.resources[f"access-key-{ix}"]('iam.aws.m.upbound.io/v1beta1', 'AccessKey')
key.spec.forProvider.user = user.status.atProvider.id
key.spec.writeConnectionSecretToRef.name = f"{self.metadata.name}-accesskey-{ix}"
self.connection[f"user-{ix}"] = key.connection.username
self.connection[f"password-{ix}"] = key.connection.password
kubectl apply -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/composition-pythonic.yaml
이 Composition이 연결 정보를 노출하는 방법:
- 각 composed AccessKey는
writeConnectionSecretToRef가 설정되어 있습니다. 이것은 각 AccessKey가 자격 증명을 개별 Secret에 쓰도록 지시합니다. - 크로스플레인은 각 AccessKey의 연결 정보를 관찰하고 함수 실행 시 Composition에서 사용할 수 있게 만듭니다.
- Secret은
connection.username과connection.password를 통해 AccessKey의 연결 정보를 읽습니다. - 함수는 XR의
spec.writeConnectionSecretToRef가 존재하면 그것으로 연결 Secret 이름을 설정합니다. - 함수는 XR의 composed resources에 XR의 집계된 연결 정보를 나타내는 Secret 객체를 자동으로 포함합니다.
- 이 Secret을 직접 만들거나 구성할 필요가 없습니다. 자동으로 처리됩니다.
- function-pythonic에서 연결 정보의 base64 인코딩과 디코딩은 자동으로 처리됩니다.
복합 리소스 사용 (Use the composite resource)
Composition은 이제 UserAccessKey 복합 리소스에 대한 연결 정보 구성 방법을 지정합니다.
실제 동작을 보려면 UserAccessKey를 생성하세요.
apiVersion: example.org/v1alpha1
kind: UserAccessKey
metadata:
namespace: default
name: my-keys
spec:
writeConnectionSecretToRef:
name: my-keys-connection-details
kubectl apply -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/my-keys.yaml
복합 리소스가 준비되었는지 확인하세요.
kubectl get -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/my-keys.yaml
NAME SYNCED READY COMPOSITION AGE
my-keys True True useraccesskeys-go-templating 45s
참고 AWS가 IAM 리소스를 프로비저닝하는 데 1분 정도 걸릴 수 있습니다. 복합 리소스는 모든 composed resources가 건강해지면
READY가 됩니다.
연결 정보 검증 (Verify the connection details)
복합 리소스는 Secret을 통해 연결 정보를 노출합니다. 크로스플레인이 Secret을 만들었는지 확인하세요.
crossplane CLI를 사용하여 모든 composed resources(연결 정보 Secret 포함)를 함께 확인할 수 있습니다.
팁 Crossplane CLI 설치와 사용 방법은 Crossplane CLI 문서를 참고하세요.
crossplane beta trace useraccesskey.example.org/my-keys
NAME SYNCED READY STATUS
UserAccessKey/my-keys (default) True True Available
├─ AccessKey/my-keys-14c0578cad85 (default) True True Available
├─ AccessKey/my-keys-e420789d13a3 (default) True True Available
├─ User/my-keys-c63b530f8e68 (default) True True Available
└─ Secret/my-keys-connection-details (default) - -
my-keys 복합 리소스는 IAM User와 두 개의 IAM AccessKeys를 만들었고, 복합 리소스의 집계된 연결 정보를 포함하는 Secret도 생성되었습니다.
복합 리소스의 집계된 연결 정보 Secret을 확인하세요.
kubectl get secret -n default -l crossplane.io/composite=my-keys
NAME TYPE DATA AGE
my-keys-586e2994bda1 Opaque 4 5m37s
팁 복합 리소스의 연결 정보 Secret은 편리한 조회를 위해
crossplane.io/composite=my-keys라벨을 가집니다. XR에.spec.writeConnectionSecretToRef.name을 설정했다면Secret은 그 정확한 이름을 가집니다.
복합 리소스의 연결 정보 Secret이 모든 예상 자격 증명을 포함하는지 확인하세요.
kubectl get secret -n default -l crossplane.io/composite=my-keys -o jsonpath='{.items[0].data}' | jq
다음과 같은 출력이 보여야 합니다.
{
"password-0": "",
"password-1": "",
"user-0": "",
"user-1": ""
}
값 중 하나를 디코딩하여 예상 데이터를 포함하는지 확인하세요.
kubectl get secret -n default -l crossplane.io/composite=my-keys -o jsonpath='{.items[0].data.user-0}' | base64 -d
연결 정보 구성 방법 이해 (Understanding how composing connection details works)
복합 리소스의 연결 정보를 노출하는 데는 두 가지 접근 방식이 있습니다.
수동 구성 (Manual composition) — 대부분의 함수
function-go-templating, function-python, function-kcl 같은 함수를 사용하면 Secret 리소스를 수동으로 구성합니다.
- 리소스 구성: Composition에서 평소처럼 IAM User, AccessKeys 같은 composed resources를 만듭니다. 이 리소스들은 연결 정보를 Secret에 노출합니다.
- writeConnectionSecretToRef 설정: 연결 정보를 저장해야 하는 각 composed resource는 Composition에서
writeConnectionSecretToRef가 설정되어 있어야 합니다. - 관찰된 연결 정보: 크로스플레인은 각 composed resource의 실제 상태를 관찰하고, 그 연결 정보를 포함하여 함수 실행 시 이 데이터를 사용할 수 있게 만듭니다.
- 결합된 Secret 구성: composed resources의 관찰된 연결 정보에서 읽어 XR을 위해 노출하려는 중요한 연결 정보를 결합하는 Secret 리소스를 구성합니다. XR 소비자가 이 secret의 이름을 지정할 수 있게 하는 것을 고려하세요.
- 일시적 상태 처리: XR이 처음 생성될 때 composed resources 및/또는 그 연결 정보가 아직 존재하지 않을 수 있습니다. Composition은 접근하기 전에 리소스와 그 연결 정보가 존재하는지 검사하여 이러한 경우를 처리해야 합니다.
자동 집계 — function-patch-and-transform
function-patch-and-transform은 composed resources에서 연결 정보를 자동으로 관찰하고, v1 동작과의 역호환성을 유지하기 위해 집계된 연결 secret을 만듭니다.
Secret 리소스를 직접 수동으로 구성할 필요는 없습니다.
- 리소스 구성: Composition에서 평소처럼 IAM User, AccessKeys 같은 composed resources를 만듭니다. 이 리소스들은 연결 정보를 Secret에 노출합니다.
- writeConnectionSecretToRef 설정: 연결 정보를 저장해야 하는 각 composed resource는 Composition에서
writeConnectionSecretToRef가 설정되어 있어야 합니다. - connectionDetails 정의: 각 composed resource에서
connectionDetails필드를 사용하여 집계된 secret에 포함할 연결 secret 키를 정의합니다. - Secret 구성: 필요에 따라 함수 입력에
writeConnectionSecretToRef섹션을 추가하여 집계된 secret의 이름과 네임스페이스를 설정합니다. 필요하면 XR의 데이터를 사용해 이 값들을 구성하도록 patches를 사용하세요.
자동 집계 — function-pythonic
function-pythonic은 composed resources에서 연결 정보를 자동으로 관찰하고, v1 동작과의 역호환성을 유지하기 위해 집계된 연결 secret을 만듭니다.
Secret 리소스를 직접 수동으로 구성할 필요는 없습니다.
- 리소스 구성: Composition에서 평소처럼 IAM User, AccessKeys 같은 composed resources를 만듭니다. 이 리소스들은 연결 정보를 Secret에 노출합니다.
- writeConnectionSecretToRef 설정: 연결 정보를 저장해야 하는 각 composed resource는 Composition에서
resource.spec.writeConnectionSecretToRef가 설정되어 있어야 합니다. - connection 정의: 각 composed resource에 대해
self.connection[key] = resource.connection[key]를 사용하여 집계된 secret에 원하는 연결 secret 값을 할당합니다. - Secret 구성: XR의
self.connectionSecret필드를 설정하여 집계된 secret의 기본 이름과 네임스페이스를 덮어씁니다.
문제 해결 (Troubleshooting)
복합 리소스의 연결 정보 Secret이 비어 있음
원인:
- Composed resources에
writeConnectionSecretToRef가 설정되지 않음 - Composed resources가 아직 ready/healthy하지 않음
- (function-patch-and-transform) composed resources에
connectionDetails필드 누락 - (수동 구성) Composition에서 초기 nil 상태를 올바르게 처리하지 않음
해결책:
- 모든 composed 관리 리소스에
writeConnectionSecretToRef가 설정되었는지 확인 - composed resources가 ready가 될 때까지 대기 (
kubectl get으로 READY 열 확인) - composed resource가 실제로 연결 정보를 생성하는지 확인:
kubectl get secret <name> -o yaml - (function-patch-and-transform) 각 composed resource에 원하는 secret 키를 매핑하는
connectionDetails섹션이 있는지 확인 - (수동 구성) Composition 로직에 nil/empty 검사를 추가하여 아직 존재하지 않을 수 있는 데이터 접근을 보호
연결 정보가 올바르게 인코딩되지 않음
원인: Composition 로직에서 결합된 secret 데이터를 올바르게 인코딩하지 않음
해결책: 이는 수동 구성 방식에만 적용됩니다. 사용하는 함수에 대해 연결 정보 데이터가 올바르게 인코딩되었는지 확인하세요. 예를 들어 function-python은 연결 정보를 base64 인코딩 문자열로 변환해야 하지만, function-go-templating과 function-kcl의 연결 정보는 이미 이렇게 인코딩되어 있어 변환 로직이 필요 없습니다.
function-patch-and-transform과 function-pythonic은 composed 연결 secret을 자동으로 생성할 때 인코딩을 처리합니다.
Secret에 빈 네임스페이스가 있음
원인: Cluster 범위 XR의 Secret 네임스페이스를 설정하지 않아서 an empty namespace may not be set when a resource name is provided 같은 오류가 발생함
해결책: Cluster 범위 XR이 Secret 같은 네임스페이스 범위 리소스를 구성할 때는 리소스에 네임스페이스를 명시적으로 설정해야 합니다. Composition에서 XR 소비자가 네임스페이스 값을 지정할 수 있게 하는 것을 고려하세요. Namespaced XR은 크로스플레인이 비어 있는 composed resource의 네임스페이스를 기본적으로 XR의 네임스페이스로 설정하므로 이 문제가 없습니다.
정리 (Clean up)
복합 리소스를 삭제하여 정리합니다.
kubectl delete -f https://docs.crossplane.io/latest/manifests/guides/connection-details-composition/my-keys.yaml
복합 리소스를 삭제하면 크로스플레인은 다음을 삭제합니다.
- AWS의 composed IAM User와 AccessKeys
- composed resources의 개별 Secrets
- 복합 리소스의 연결 정보 Secret
중요 프로바이더를 제거하거나 컨트롤 플레인을 종료하기 전에 복합 리소스를 삭제하세요. 더 이상 실행 중이 아니면 composed resources를 정리할 수 없으므로 수동으로 삭제해야 합니다.