하나의 YAML 파일에서 여러 종류의 Kubernetes API에 대해 client-go to 'kubectl apply'를 직접 사용하는 것
나는 사용하고 있고 모든 것이 잘 된다.
공식 쿠버네티스 대시보드에 대한 매니페스트(YAML)가 있습니다:
나는 이 매니페스트를 Go 코드로 모방하고 싶다. 클라이언트-go를 사용한다.
패키지에 정의된 올바른 API 유형으로 YAML 바이트를 약간(언) 마스할링해야 한다는 것을 이해합니다:
클러스터에 단일 API 유형을 성공적으로 편집했습니다. 이러한 다양한 유형을 지원하는 리소스가 있습니까?
현재 해결 방법은 ---를 구분 기호로 사용하여 YAML 파일을 분할하는 것입니다
csplit /path/to/recommended.yaml /---/ '{*}' --prefix='dashboard.' --suffix-format='%03d.yaml'
다음으로, 나는 생성된 새로운 (14) 부분을 루프하고, 그들의 바이트를 읽고, UniversalDeserializer의 디코더에 의해 반환되는 객체의 유형을 켜고, 내 k8s 클라이언트 세트를 사용하여 정확한 API 메서드를 호출한다.
새로운 버전의 대시보드를 클러스터에 업데이트하기 위해 프로그래밍 방식으로 이 작업을 수행하고자 합니다. 메트릭스 서버 및 기타 여러 리소스에 대해서도 이 작업을 수행해야 합니다. 대체 방법은 컨테이너 이미지에 kubectl이 설치된 내 코드를 발송하고 직접 호출하는 것이지만, kubectl이 사용할 수 있도록 kube config를 디스크에 쓰거나 인라인으로 전달해야 한다는 것을 의미한다.
이 문제가 도움이 된다는 것을 알게 되었습니다: 암호 해독기는 여기서 살아요:
고객에게 노출되어 있습니다:
kubectl에서 사용하는 RunConvert 방법도 살펴봤습니다. 출력을 얻기 위해 자신의 것을 제공할 수 있다고 가정해 보겠습니다?
RunConvert가 감가상각 경로에 있는 것 같습니다
[client-go] 태그가 지정된 다른 질문들도 살펴보았지만 대부분 오래된 예제를 사용하거나 단일 정의된 YAML 파일을 사용하며 그 이후로 API가 변경되었습니다.
편집: 두 개 이상의 클러스터에 대해 이 작업을 수행해야 하고 프로그래밍 방식으로 클러스터를 생성하기 때문에(AWS EKS API + CloudFormation/), 여러 AWS 계정에 걸쳐 여러 클러스터 컨텍스트에서 생성하는 오버헤드를 최소화하고자 합니다. 이상적으로, 클라이언트 세트를 생성하는 데 관련된 유일한 인증 단계는 클러스터 데이터(이름, 지역, CA 인증서 등)를 사용하여 토큰을 얻는 것입니다. 한동안 aws-iam-authenticator가 출시되지 않았지만 타사 역할 교차 계정 역할 및 외부 ID를 사용할 수 있도록 하는 내용이 포함되어 있습니다. IMO, 이것은 애플리케이션(이러한 클러스터에 추가 기능을 생성하고 적용하는 백엔드 API)이 상호 작용해야 하는 다른 AWS 서비스가 있기 때문에 (및 )를 사용하는 것보다 더 깨끗합니다.
편집: 최근에 발견했습니다. 높은 수준에서 클라이언트-go보다 사용이 확실히 간단하지만, 이 동작을 지원하지는 않습니다.
YAML 파일을 Kubernetess로 역직렬화하는 방법을 알아낸 것처럼 들리지만, 문제는 각 Kind에 대한 특별한 코드를 작성하지 않고 동적으로 배치하는 것입니다.
와 직접 상호 작용하여 이를 달성합니다. 구체적으로, 경유.
내 코드에는 다음과 같은 것이 있다:
import (
meta "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/restmapper"
)
func createObject(kubeClientset kubernetes.Interface, restConfig rest.Config, obj runtime.Object) (runtime.Object, error) {
// Create a REST mapper that tracks information about the available resources in the cluster.
groupResources, err := restmapper.GetAPIGroupResources(kubeClientset.Discovery())
if err != nil {
return nil, err
}
rm := restmapper.NewDiscoveryRESTMapper(groupResources)
// Get some metadata needed to make the REST request.
gvk := obj.GetObjectKind().GroupVersionKind()
gk := schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}
mapping, err := rm.RESTMapping(gk, gvk.Version)
if err != nil {
return nil, err
}
namespace, err := meta.NewAccessor().Namespace(obj)
if err != nil {
return nil, err
}
// Create a client specifically for creating the object.
restClient, err := newRestClient(restConfig, mapping.GroupVersionKind.GroupVersion())
if err != nil {
return nil, err
}
// Use the REST helper to create the object in the "default" namespace.
restHelper := resource.NewHelper(restClient, mapping)
return restHelper.Create(namespace, false, obj)
}
func newRestClient(restConfig rest.Config, gv schema.GroupVersion) (rest.Interface, error) {
restConfig.ContentConfig = resource.UnstructuredPlusDefaultContentConfig()
restConfig.GroupVersion = &gv
if len(gv.Group) == 0 {
restConfig.APIPath = "/api"
} else {
restConfig.APIPath = "/apis"
}
return rest.RESTClientFor(&restConfig)
}
나는 내 프로젝트 중 하나에서 이 일을 해낼 수 있었다. 제대로 작동하려면 의 apply 명령어의 소스 코드를 많이 사용해야 했습니다.
https://github.com/billiford/go-clouddriver/blob/master/pkg/kubernetes/client.go#L63
'개발하자' 카테고리의 다른 글
FastAPI에서 동일한 앱에서 다른 API를 호출하는 방법은 무엇입니까? (1) | 2023.09.24 |
---|---|
주피터 노트북 셀의 내용을 이미지로 내보내기 (0) | 2023.09.23 |
스크립트 열거값을 배열로 입력합니다 (0) | 2023.09.22 |
TypeScript에서 "not assignable to parameter of type never" 오류는 무엇인가? (0) | 2023.09.21 |
주피터 노트북의 테마를 변경하시겠습니까? (0) | 2023.09.21 |