Composition으로 시작하기
Composition으로 시작하기 (Get Started with Composition)
이 가이드는 App이라는 새 종류의 커스텀 리소스를 만드는 방법을 보여줍니다. 사용자가 커스텀 리소스 API를 호출해 App을 생성하면, Crossplane이 Deployment와 Service를 만듭니다.
출처: 문서
본문
Crossplane은 이것을 composition이라고 부릅니다. App은 Deployment와 Service로 구성(compose)됩니다.
💡 Tip: 이 가이드는 YAML, YAML+CEL, templated YAML, Python, KCL로 composition을 구성하는 방법을 보여줍니다. 원하는 언어를 선택하면 돼요.
App 커스텀 리소스는 이렇게 생겼습니다.
apiVersion: example.crossplane.io/v1
kind: App
metadata:
namespace: default
name: my-app
spec:
image: nginx
status:
replicas: 2 # Copied from the Deployment's status
address: 10.0.0.1 # Copied from the Service's status
App은 Crossplane 사용자가 앱을 구성하는 데 사용하는 커스텀 API입니다. 사용자가 App을 만들면 Crossplane은 이 Deployment와 Service를 생성합니다.
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: default
name: my-app-dhj3a
labels:
example.crossplane.io/app: my-app # Copied from the App's name
spec:
replicas: 2
selector:
matchLabels:
example.crossplane.io/app: my-app # Copied from the App's name
template:
metadata:
labels:
example.crossplane.io/app: my-app # Copied from the App's name
spec:
containers:
- name: app
image: nginx # Copied from the App's spec
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
namespace: default
name: my-app-03mda
labels:
example.crossplane.io/app: my-app # Copied from the App's name
spec:
selector:
example.crossplane.io/app: my-app # Copied from the App's name
ports:
- protocol: TCP
port: 8080
targetPort: 80
Crossplane은 Kubernetes 위에 구축되므로 사용자는 kubectl이나 Kubernetes 생태계의 다른 도구로 앱을 다룰 수 있습니다.
💡 Tip: Kubernetes 커스텀 리소스는 단지 JSON REST API이므로, 사용자는 REST API를 지원하는 어떤 도구로도 앱을 다룰 수 있어요.
사전 요구 사항 (Prerequisites)
이 가이드에는 다음이 필요합니다.
- 최소 2 GB RAM 이상의 Kubernetes 클러스터
- Kubernetes 클러스터에 설치된 Crossplane v2
커스텀 리소스 만들기 (Create the custom resource)
Crossplane으로 새 종류의 커스텀 리소스를 만드는 단계는 다음과 같습니다.
- App 커스텀 리소스의 스키마 정의
- Crossplane이 앱을 구성하는 방식을 설정하는 데 사용할 함수 설치
- Crossplane이 앱을 구성하는 방식 구성
이 단계를 완료하면 새 App 커스텀 리소스를 사용할 수 있습니다.
스키마 정의하기 (Define the schema)
Crossplane은 composition으로 구동되는 커스텀 리소스를 복합 리소스(composite resource, XR)라고 부릅니다.
📝 참고: Kubernetes는 사용자 정의 API 리소스를 커스텀 리소스라고 부릅니다. Crossplane은 composition을 사용하는 사용자 정의 API 리소스를 복합 리소스라고 부릅니다. 복합 리소스는 커스텀 리소스의 한 종류예요.
새 App 복합 리소스(XR)의 스키마를 정의하려면 이 복합 리소스 정의(Composite Resource Definition, XRD)를 만드세요.
apiVersion: apiextensions.crossplane.io/v2
kind: CompositeResourceDefinition
metadata:
name: apps.example.crossplane.io
spec:
scope: Namespaced
group: example.crossplane.io
names:
kind: App
plural: apps
versions:
- name: v1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
image:
description: The app's OCI container image.
type: string
required:
- image
status:
type: object
properties:
replicas:
description: The number of available app replicas.
type: integer
address:
description: The app's IP address.
type: string
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/composition/xrd.yaml
Crossplane이 XRD를 설정했는지 확인하세요.
$ kubectl get -f https://docs.crossplane.io/latest/manifests/get-started/composition/xrd.yaml
NAME ESTABLISHED OFFERED AGE
apps.example.crossplane.io True 21s
Crossplane이 XRD를 설정했으므로 Kubernetes는 새 App XR에 대한 API 요청을 처리합니다. 이제 Crossplane은 새 App XR에 대한 책임을 알지만, 생성하거나 업데이트할 때 무엇을 해야 하는지는 모릅니다. 함수를 설치하고 composition을 구성해서 Crossplane에 무엇을 해야 하는지 알려줍니다.
함수 설치하기 (Install the function)
누군가 복합 리소스(XR)를 만들거나 업데이트할 때 Crossplane이 무엇을 하는지 구성하기 위해 서로 다른 composition 함수를 사용할 수 있습니다. Composition 함수는 구성 언어 플러그인과 같습니다.
App XR을 Deployment와 Service로 바꾸는 방법을 구성하는 데 사용할 언어를 선택하세요.
- Templated YAML
- YAML
- YAML+CEL
- Python
- KCL
- Pythonic
Helm 차트를 작성해 본 적이 있다면 Templated YAML이 좋은 선택입니다.
templated YAML 지원을 설치하려면 이 composition 함수를 만드세요.
apiVersion: pkg.crossplane.io/v1
kind: Function
metadata:
name: crossplane-contrib-function-go-templating
spec:
package: xpkg.crossplane.io/crossplane-contrib/function-go-templating:v0.9.2
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/composition/fn-go-templating.yaml
Crossplane이 함수를 설치했는지 확인하세요.
$ kubectl get -f https://docs.crossplane.io/latest/manifests/get-started/composition/fn-go-templating.yaml
NAME INSTALLED HEALTHY PACKAGE AGE
crossplane-contrib-function-go-templating True True xpkg.crossplane.io/crossplane-contrib/function-go-templating:v0.9.2 9s
YAML은 작고 정적인 composition에 좋은 선택입니다. 루프나 조건문을 지원하지 않습니다. YAML 지원을 설치하려면 이 composition 함수를 만드세요.
apiVersion: pkg.crossplane.io/v1
kind: Function
metadata:
name: crossplane-contrib-function-patch-and-transform
spec:
package: xpkg.crossplane.io/crossplane-contrib/function-patch-and-transform:v0.8.2
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/composition/fn-patch-and-transform.yaml
Crossplane이 함수를 설치했는지 확인하세요.
$ kubectl get -f https://docs.crossplane.io/latest/manifests/get-started/composition/fn-patch-and-transform.yaml
NAME INSTALLED HEALTHY PACKAGE AGE
crossplane-contrib-function-patch-and-transform True True xpkg.crossplane.io/crossplane-contrib/function-patch-and-transform:v0.8.2 10s
YAML+CEL은 리소스를 일반 YAML로 정의하고 CEL 표현식으로 연결하는 데 좋은 선택입니다. 함수는 리소스 간 의존성을 자동으로 해결합니다. YAML+CEL 지원을 설치하려면 이 composition 함수를 만드세요.
apiVersion: pkg.crossplane.io/v1
kind: Function
metadata:
name: crossplane-contrib-function-kro
spec:
package: xpkg.crossplane.io/crossplane-contrib/function-kro:v0.3.0
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/composition/fn-kro.yaml
Crossplane이 함수를 설치했는지 확인하세요.
$ kubectl get -f https://docs.crossplane.io/latest/manifests/get-started/composition/fn-kro.yaml
NAME INSTALLED HEALTHY PACKAGE AGE
crossplane-contrib-function-kro True True xpkg.crossplane.io/crossplane-contrib/function-kro:v0.3.0 6s
Python은 동적 로직이 있는 composition에 좋은 선택입니다. Python 표준 라이브러리를 모두 사용할 수 있어요. Python 지원을 설치하려면 이 composition 함수를 만드세요.
apiVersion: pkg.crossplane.io/v1
kind: Function
metadata:
name: crossplane-contrib-function-python
spec:
package: xpkg.crossplane.io/crossplane-contrib/function-python:v0.1.0
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/composition/fn-python.yaml
Crossplane이 함수를 설치했는지 확인하세요.
$ kubectl get -f https://docs.crossplane.io/latest/manifests/get-started/composition/fn-python.yaml
NAME INSTALLED HEALTHY PACKAGE AGE
crossplane-contrib-function-python True True xpkg.crossplane.io/crossplane-contrib/function-python:v0.1.0 12s
KCL은 동적 로직이 있는 composition에 좋은 선택입니다. 빠르고 샌드박스 처리됩니다. KCL 지원을 설치하려면 이 composition 함수를 만드세요.
apiVersion: pkg.crossplane.io/v1
kind: Function
metadata:
name: crossplane-contrib-function-kcl
spec:
package: xpkg.crossplane.io/crossplane-contrib/function-kcl:v0.11.2
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/composition/fn-kcl.yaml
Crossplane이 함수를 설치했는지 확인하세요.
$ kubectl get -f https://docs.crossplane.io/latest/manifests/get-started/composition/fn-kcl.yaml
NAME INSTALLED HEALTHY PACKAGE AGE
crossplane-contrib-function-kcl True True xpkg.crossplane.io/crossplane-contrib/function-kcl:v0.11.2 6s
Pythonic (https://github.com/crossplane-contrib/function-pythonic?tab=readme-ov-file#function-pythonic)은 동적 로직이 있는 composition에 뛰어난 선택입니다. 저수준 Crossplane 함수 API의 세부 사항을 숨기는 우아하고 간결한 문법의 Python 클래스 집합을 사용해 Python의 완전한 유연성과 힘을 사용할 수 있어요. 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/get-started/composition/fn-pythonic.yaml
Crossplane이 함수를 설치했는지 확인하세요.
$ kubectl get -f https://docs.crossplane.io/latest/manifests/get-started/composition/fn-pythonic.yaml
NAME INSTALLED HEALTHY PACKAGE AGE
function-pythonic True True xpkg.crossplane.io/crossplane-contrib/function-pythonic:v0.3.0 1m
composition 구성하기 (Configure the composition)
Composition은 복합 리소스(XR)를 만들거나 업데이트할 때 Crossplane이 어떤 함수를 호출할지 알려줍니다. App XR을 만들거나 업데이트할 때 Crossplane이 무엇을 해야 하는지 알려주는 composition을 만드세요.
- Templated YAML
- YAML
- YAML+CEL
- Python
- KCL
- Pythonic
templated YAML을 사용해 Crossplane을 구성하는 composition을 만드세요.
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: app-templated-yaml
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: App
mode: Pipeline
pipeline:
- step: create-deployment-and-service
functionRef:
name: crossplane-contrib-function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: deployment
{{ if eq (.observed.resources.deployment | getResourceCondition "Available").Status "True" }}
gotemplating.fn.crossplane.io/ready: "True"
{{ end }}
labels:
example.crossplane.io/app: {{ .observed.composite.resource.metadata.name }}
spec:
replicas: 2
selector:
matchLabels:
example.crossplane.io/app: {{ .observed.composite.resource.metadata.name }}
template:
metadata:
labels:
example.crossplane.io/app: {{ .observed.composite.resource.metadata.name }}
spec:
containers:
- name: app
image: {{ .observed.composite.resource.spec.image }}
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: service
{{ if (get (getComposedResource . "service").spec "clusterIP") }}
gotemplating.fn.crossplane.io/ready: "True"
{{ end }}
labels:
example.crossplane.io/app: {{ .observed.composite.resource.metadata.name }}
spec:
selector:
example.crossplane.io/app: {{ .observed.composite.resource.metadata.name }}
ports:
- protocol: TCP
port: 8080
targetPort: 80
---
apiVersion: example.crossplane.io/v1
kind: App
status:
replicas: {{ get (getComposedResource . "deployment").status "availableReplicas" | default 0 }}
address: {{ get (getComposedResource . "service").spec "clusterIP" | default "" | quote }}
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/composition/composition-templated-yaml.yaml
YAML을 사용해 Crossplane을 구성하는 composition을 만드세요.
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: app-yaml
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: App
mode: Pipeline
pipeline:
- step: create-deployment-and-service
functionRef:
name: crossplane-contrib-function-patch-and-transform
input:
apiVersion: pt.fn.crossplane.io/v1beta1
kind: Resources
resources:
- name: deployment
base:
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 2
template:
spec:
containers:
- name: app
ports:
- containerPort: 80
patches:
- type: FromCompositeFieldPath
fromFieldPath: metadata.name
toFieldPath: metadata.labels[example.crossplane.io/app]
- type: FromCompositeFieldPath
fromFieldPath: metadata.name
toFieldPath: spec.selector.matchLabels[example.crossplane.io/app]
- type: FromCompositeFieldPath
fromFieldPath: metadata.name
toFieldPath: spec.template.metadata.labels[example.crossplane.io/app]
- type: FromCompositeFieldPath
fromFieldPath: spec.image
toFieldPath: spec.template.spec.containers[0].image
- type: ToCompositeFieldPath
fromFieldPath: status.availableReplicas
toFieldPath: status.replicas
readinessChecks:
- type: MatchCondition
matchCondition:
type: Available
status: "True"
- name: service
base:
apiVersion: v1
kind: Service
spec:
ports:
- protocol: TCP
port: 8080
targetPort: 80
patches:
- type: FromCompositeFieldPath
fromFieldPath: metadata.name
toFieldPath: metadata.labels[example.crossplane.io/app]
- type: FromCompositeFieldPath
fromFieldPath: metadata.name
toFieldPath: spec.selector[example.crossplane.io/app]
- type: ToCompositeFieldPath
fromFieldPath: spec.clusterIP
toFieldPath: status.address
readinessChecks:
- type: NonEmpty
fieldPath: spec.clusterIP
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/composition/composition-yaml.yaml
YAML과 CEL을 사용해 Crossplane을 구성하는 composition을 만드세요. 리소스를 YAML로 정의하고 CEL 표현식으로 연결하면, 나머지는 Crossplane이 처리합니다.
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: app-yaml-cel
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: App
mode: Pipeline
pipeline:
- step: create-deployment-and-service
functionRef:
name: crossplane-contrib-function-kro
input:
apiVersion: kro.fn.crossplane.io/v1alpha1
kind: ResourceGraph
status:
replicas: ${deployment.status.?availableReplicas.orValue(0)}
address: ${service.spec.?clusterIP.orValue("")}
resources:
- id: deployment
template:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
example.crossplane.io/app: ${schema.metadata.name}
spec:
replicas: 2
selector:
matchLabels:
example.crossplane.io/app: ${schema.metadata.name}
template:
metadata:
labels:
example.crossplane.io/app: ${schema.metadata.name}
spec:
containers:
- name: app
image: ${schema.spec.image}
ports:
- containerPort: 80
readyWhen:
- ${deployment.status.?conditions.orValue([]).exists(c, c.type == "Available" && c.status == "True")}
- id: service
template:
apiVersion: v1
kind: Service
metadata:
labels:
example.crossplane.io/app: ${schema.metadata.name}
spec:
selector:
example.crossplane.io/app: ${schema.metadata.name}
ports:
- protocol: TCP
port: 8080
targetPort: 80
readyWhen:
- ${service.spec.?clusterIP.hasValue()}
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/composition/composition-yaml-cel.yaml
💡 Tip: 이 함수는 kro와 동일한 리소스 그래프 문법을 사용하므로 기존 kro 리소스 정의가 수정 없이 동작해요.
Python을 사용해 Crossplane을 구성하는 composition을 만드세요.
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: app-python
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: App
mode: Pipeline
pipeline:
- step: create-deployment-and-service
functionRef:
name: crossplane-contrib-function-python
input:
apiVersion: python.fn.crossplane.io/v1beta1
kind: Script
script: |
def compose(req, rsp):
observed_xr = req.observed.composite.resource
rsp.desired.resources["deployment"].resource.update({
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"labels": {"example.crossplane.io/app": observed_xr["metadata"]["name"]},
},
"spec": {
"replicas": 2,
"selector": {"matchLabels": {"example.crossplane.io/app": observed_xr["metadata"]["name"]}},
"template": {
"metadata": {
"labels": {"example.crossplane.io/app": observed_xr["metadata"]["name"]},
},
"spec": {
"containers": [{
"name": "app",
"image": observed_xr["spec"]["image"],
"ports": [{"containerPort": 80}]
}],
},
},
},
})
observed_deployment = req.observed.resources["deployment"].resource
if "status" in observed_deployment:
if "availableReplicas" in observed_deployment["status"]:
rsp.desired.composite.resource.get_or_create_struct("status")["replicas"] = observed_deployment["status"]["availableReplicas"]
if "conditions" in observed_deployment["status"]:
for condition in observed_deployment["status"]["conditions"]:
if condition["type"] == "Available" and condition["status"] == "True":
rsp.desired.resources["deployment"].ready = True
rsp.desired.resources["service"].resource.update({
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"labels": {"example.crossplane.io/app": observed_xr["metadata"]["name"]},
},
"spec": {
"selector": {"example.crossplane.io/app": observed_xr["metadata"]["name"]},
"ports": [{"protocol": "TCP", "port": 8080, "targetPort": 80}],
},
})
observed_service = req.observed.resources["service"].resource
if "spec" in observed_service and "clusterIP" in observed_service["spec"]:
rsp.desired.composite.resource.get_or_create_struct("status")["address"] = observed_service["spec"]["clusterIP"]
rsp.desired.resources["service"].ready = True
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/composition/composition-python.yaml
💡 Tip: Python으로 직접 함수를 작성할 수도 있어요. 더 큰 구성에는 직접 함수를 작성하는 것이 좋습니다. 직접 함수를 작성하면 여러 Python 파일을 작성할 수 있고, YAML에 Python을 내장하지 않으므로 Python IDE를 사용하기 더 편리해요. Python으로 composition function 작성 가이드를 읽어보세요.
KCL을 사용해 Crossplane을 구성하는 composition을 만드세요.
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: app-kcl
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: App
mode: Pipeline
pipeline:
- step: create-deployment-and-service
functionRef:
name: crossplane-contrib-function-kcl
input:
apiVersion: krm.kcl.dev/v1alpha1
kind: KCLInput
spec:
source: |
observed_xr = option("params").oxr
_desired_deployment = {
apiVersion = "apps/v1"
kind = "Deployment"
metadata = {
annotations = {
"krm.kcl.dev/composition-resource-name" = "deployment"
}
labels = {"example.crossplane.io/app" = observed_xr.metadata.name}
}
spec = {
replicas = 2
selector.matchLabels = {"example.crossplane.io/app" = observed_xr.metadata.name}
template = {
metadata.labels = {"example.crossplane.io/app" = observed_xr.metadata.name}
spec.containers = [{
name = "app"
image = observed_xr.spec.image
ports = [{containerPort = 80}]
}]
}
}
}
observed_deployment = option("params").ocds["deployment"]?.Resource
if any_true([c.type == "Available" and c.status == "True" for c in observed_deployment?.status?.conditions or []]):
_desired_deployment.metadata.annotations["krm.kcl.dev/ready"] = "True"
_desired_service = {
apiVersion = "v1"
kind = "Service"
metadata = {
annotations = {
"krm.kcl.dev/composition-resource-name" = "service"
}
labels = {"example.crossplane.io/app" = observed_xr.metadata.name}
}
spec = {
selector = {"example.crossplane.io/app" = observed_xr.metadata.name}
ports = [{protocol = "TCP", port = 8080, targetPort = 80}]
}
}
observed_service = option("params").ocds["service"]?.Resource
if observed_service?.spec?.clusterIP:
_desired_service.metadata.annotations["krm.kcl.dev/ready"] = "True"
_desired_xr = {
**option("params").dxr
status.address = observed_service?.spec?.clusterIP or ""
status.replicas = observed_deployment?.status?.availableReplicas or 0
}
items = [_desired_deployment, _desired_service, _desired_xr]
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/composition/composition-kcl.yaml
Pythonic을 사용해 Crossplane을 구성하는 composition을 만드세요.
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: app-pythonic
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: App
mode: Pipeline
pipeline:
- step: create-deployment-and-service
functionRef:
name: function-pythonic
input:
apiVersion: pythonic.fn.crossplane.io/v1alpha1
kind: Composite
composite: |
class Composite(BaseComposite):
def compose(self):
labels = {'example.crossplane.io/app': self.metadata.name}
d = self.resources.deployment('apps/v1', 'Deployment')
d.metadata.labels = labels
d.spec.replicas = 2
d.spec.selector.matchLabels = labels
d.spec.template.metadata.labels = labels
d.spec.template.spec.containers[0].name = 'app'
d.spec.template.spec.containers[0].image = self.spec.image
d.spec.template.spec.containers[0].ports[0].containerPort = 80
s = self.resources.service('v1', 'Service')
s.metadata.labels = labels
s.spec.selector = labels
s.spec.ports[0].protocol = 'TCP'
s.spec.ports[0].port = 8080
s.spec.ports[0].targetPort = 80
self.status.replicas = d.status.availableReplicas
self.status.address = s.observed.spec.clusterIP
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/composition/composition-pythonic.yaml
📝 참고: Composition은 여러 함수를 포함할 수 있습니다. 함수는 파이프라인의 앞선 함수 결과를 변경할 수 있으며, Crossplane은 마지막 함수가 반환한 결과를 사용합니다.
💡 Tip: 이 composition을 편집해 다른 종류의 리소스를 포함하게 하려면, Crossplane에 이를 합성할 수 있는 접근 권한을 부여해야 할 수 있어요. 접근 권한 부여 방법은 composition 문서를 읽어보세요.
커스텀 리소스 사용하기 (Use the custom resource)
이제 Crossplane은 App 커스텀 리소스를 이해합니다. App을 만들어 보세요.
apiVersion: example.crossplane.io/v1
kind: App
metadata:
namespace: default
name: my-app
spec:
image: nginx
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/composition/app.yaml
App이 준비되었는지 확인하세요.
$ kubectl get -f https://docs.crossplane.io/latest/manifests/get-started/composition/app.yaml
NAME SYNCED READY COMPOSITION AGE
my-app True True app-yaml 56s
📝 참고:
COMPOSITION열은App이 사용 중인 composition을 보여줍니다. 각 XR 종류에 대해 여러 composition을 만들 수 있어요. XR 페이지에서 Crossplane이 사용할 composition을 선택하는 방법을 읽어보세요.
Crossplane이 Deployment와 Service를 만들었는지 확인하세요.
$ kubectl get deploy,service -l example.crossplane.io/app=my-app
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/my-app-2r2rk 2/2 2 2 11m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/my-app-xfkzg ClusterIP 10.96.148.56 8080/TCP 11m
💡 Tip:
App의 image를 편집해 보세요.
$ kubectl edit -f https://docs.crossplane.io/latest/manifests/get-started/composition/app.yaml
Crossplane이 Deployment의 image를 일치하도록 업데이트합니다. 그런 다음 App을 삭제하세요.
$ kubectl delete -f https://docs.crossplane.io/latest/manifests/get-started/composition/app.yaml
App을 삭제하면 Crossplane이 Deployment와 Service도 삭제합니다.
다음 단계 (Next steps)
관리 리소스(MR)는 바로 사용할 수 있는 Kubernetes 커스텀 리소스입니다. Crossplane에는 거의 모든 클라우드 제공자나 클라우드 네이티브 소프트웨어를 관리하는 데 사용할 수 있는 광범위한 관리 리소스 라이브러리가 있습니다. 관리 리소스 시작하기로 관리 리소스에 대해 더 알아보세요. MR을 composition과 함께 사용할 수 있어요. App composition에 MR을 포함하도록 업데이트해 보세요.
더 알아보기 (Learn more)
- Composition 개념 - composition의 동작 방식 상세
- 관리 리소스 시작하기 - 관리 리소스로 시작하기