본문 바로가기
golang

[golang] go kubernetes client-go를 이용한 쿠버네티스 관리

by weq155 2023. 11. 14.
반응형

 go를 활용한 kubernetes 리소스에 접근하는 방법인 client-go를 사용법에 대해 알아보자.

 

 

Module install

우선 진행하기 위해 사전에 필요한 사항은

  • go 설치
  • kubernetes 환경 (터미널이 사용되는 환경에 .kube/config가 있어야함)

 

준비되었다면 우선 client-go를 설치해보자

go get 명령어를 통해 쉽게 module을 추가 할 수 있다.

https://github.com/kubernetes/client-go <- 자세한 가이드는 Github repo를 참조

// module init
go mod init <projectName>

// ex) k8s.io/client-go@v0.26.10 <- 본인의 kubernetes 버전에 맞춰서 설치하는것이 권장
go get k8s.io/client-go@v0.<k8sVersion>

 

완료되었다면 go.mod에 저렇게 추가가 될 것이다.

 

 

 

config 등록

 

go에서 kubernetes를 사용하기 위해 config를 가져와 적용하는 코드이다. 

https://github.com/kubernetes/client-go/tree/master/examples/out-of-cluster-client-configuration

링크의 main.go의 코드를 복사해서 수정했다.

homedir의 .kube 폴더에서 config를 가져와서 newConfig로 등록한다.

  *config의 dir 주소가 다르다면 수정해야함.

아래 코드로 root dir의 .kube/config에 등록된 클러스터와 연결됨

func main() {
	var (
		client *kubernetes.Clientset
		err    error
	)
	if client, err = getClient(); err != nil {
		fmt.Printf("Error: %s", err)
		os.Exit(1)
	}
	fmt.Printf("test: %+v", client)
}
func getClient() (*kubernetes.Clientset, error) {
	// use the current context in kubeconfig
	config, err := clientcmd.BuildConfigFromFlags("", filepath.Join(homedir.HomeDir(), ".kube", "config"))
	if err != nil {
		return nil, err
	}

	// create the clientset
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		return nil, err
	}
	return clientset, nil
}

 

 

 

Deploy Pod

Deployment를 배포하는 코드를 구성해 보았다.

핵심 코드는

client.AppsV1().Deployments("default").Create(ctx, deployment, metav1.CreateOptions{})

AppsV1() : ApiVersion

Deployments("default") : 생성할 리소스와 네임스페이스

 

*추가로 파일을 읽는데 사용되는 ioutil 라이브러리는 go 1.18 버전이후로 deplicate 되었고 io로 통합됨

if deploymentLabels, err = getService(ctx, client); err != nil {
		fmt.Printf("Error: %s", err)
		os.Exit(1)
	}
	fmt.Printf("deploy finished. Did a deploy with labels: %+v \n", deploymentLabels)
}

func deploy(ctx context.Context, client *kubernetes.Clientset) (map[string]string, error) {
	var deployment *v1.Deployment

	appFile, err := io.ReadFile("app.yaml")
	if err != nil {
		return nil, fmt.Errorf("readfile error: %s", err)
	}
    
	obj, groupVersionKind, err := scheme.Codecs.UniversalDeserializer().Decode(appFile, nil, nil)

	switch obj.(type) {
	case *v1.Deployment:
		deployment = obj.(*v1.Deployment)
	default:
		return nil, fmt.Errorf("Unrecognized type: %s\n", groupVersionKind)
	}

	deploymentResponse, err := client.AppsV1().Deployments("default").Create(ctx, deployment, metav1.CreateOptions{}) //namespace = default
	if err != nil {
		return nil, fmt.Errorf("deployment error: %s", err)
	}
	return deploymentResponse.Spec.Template.Labels, nil
}

 

app.yaml

설치에 사용된 yaml 파일

app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-deploy
  labels:
    app: hello-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-deploy
  template:
    metadata:
      name: hello-deploy
      labels:
        app: hello-deploy
    spec:
      containers:
        - name: hello-deploy
          image: hello/nginx
          ports:
            - containerPort: 3000

 

 

 

Service get

추가로 현재 모니터링 관련 툴 개발을 진행할 예정이라 아주 기본적인 단계로 monitoring 네임스페이스의

실행중인 서비스를 가져오는 코드를 작성해 보았다.

//get svc
func getService(ctx context.Context, client *kubernetes.Clientset) (map[string]string, error) {
	service, err := client.CoreV1().Endpoints("monitoring").List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		return nil, fmt.Errorf("Service not found: %s", err)
	}
	for _, s := range service.Items {
		fmt.Printf("Service Name: %s\n", s.Name)
	}
	return nil, fmt.Errorf("Service not found: %s", err)
}

 

반응형

 

반응형