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)
}
'golang' 카테고리의 다른 글
[golang] kubernetes Operator 만들기 Kubebuilder Controller-runtime 3 - Manager (1) | 2023.11.14 |
---|---|
[golang] kubernetes Operator 만들기 Kubebuilder Controller-runtime 2 - Overview (1) | 2023.11.14 |
[golang] kubernetes Operator 만들기 Kubebuilder Controller-runtime 1 - Controller (0) | 2023.11.14 |
[golang] Golang pointer, routine 포인터, 고루틴 (2) | 2023.11.13 |
[golang] Golang 기초 (2) | 2023.11.13 |