🍳머리말
통신 후 k8s cluster내에 단계별로 접근해보는 예제와 설명글입니다.
📕Prerequisite
📔 k8s cluster
📔 Go lang
📕 공통사항
📔 cluster내 config file 내용 확인 및 저장
k8s api server는 config file을 통해 인증된 사용자와만 통신합니다. 따라서 cluster 외부에서 api server와 통신하기 위해서는 config file 내용이 필요합니다.
주로 cluster config file은 cluster환경이 갖춰진 local computer내에서 /root/.kube/config로써 존재합니다. cat명령어로 내용을 찾아 출력해봅니다.
📔 출력결과
해당 내용을 apiVersion부분부터 복붙해 통신을 시도할 computer의 local 환경에 file을 만들어 저장합니다.
📕 cluster 내 Pod개수 출력하기
📔 code 작성
간단하게 pod개수를 출력하는 code를 작성해봅니다. 해당 code는 k8s docs 내용입니다. config file위치를 적절히 BuildConfigFromFlags에 string형태의 인자로 넘겨줍니다.
package main
import (
"context"
"fmt"
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func main() {
// kubeconfig에서 현재 콘텍스트를 사용한다
// path-to-kubeconfig -- 예를 들어, /root/.kube/config
config, _ := clientcmd.BuildConfigFromFlags("", "kube config file 위치")
// clientset을 생성한다
clientset, _ := kubernetes.NewForConfig(config)
// 파드를 나열하기 위해 API에 접근한다
//Pods()함수 내 인자는 namespace를 정의할 수 있다 ""인 경우 default
pods, _ := clientset.CoreV1().Pods("").List(context.TODO(), v1.ListOptions{})
fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
}
📔 결과
성공적으로 k8s api server와 통신해 cluster내부에 있는 pod개수를 출력하는 모습입니다.
📕 Pod 정보 출력하기
📔 code 작성
특정 namespace의 pod정보를 출력하는 예제입니다. namespace "mskim"의 pod들 중 8번째 pod의 정보를 출력합니다.
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func jsonPrettyPrint(in string) string {
var out bytes.Buffer
err := json.Indent(&out, []byte(in), "", "\t")
if err != nil {
return in
}
return out.String()
}
func main() {
var out io.Writer
enc := json.NewEncoder(out)
enc.SetIndent("", " ")
// kubeconfig에서 현재 콘텍스트를 사용한다
// path-to-kubeconfig -- 예를 들어, /root/.kube/config
config, _ := clientcmd.BuildConfigFromFlags("", "./config")
// clientset을 생성한다
clientset, _ := kubernetes.NewForConfig(config)
// 파드를 나열하기 위해 API에 접근한다
pods, _ := clientset.CoreV1().Pods("mskim").List(context.TODO(), v1.ListOptions{})
fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
terraformPod, _ := json.Marshal(pods.Items[7])
fmt.Printf("items", jsonPrettyPrint(string(terraformPod)))
}
📔 출력결과
json.indent함수를 이용해 json객체를 적절히 출력했습니다.
📕 Pod내 container에 특정 명령어 실행하기
📔 code 작성
원격으로 k8s api server와 통신해 특정 namespace의 pod내 container로 명령어를 실행할 수 있습니다. default namespace의 pod개수, namespace "mskim"의 pod들 중 8번째 pod의 정보, 특정 명령 배열을 실행합니다.
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/remotecommand"
"k8s.io/kubectl/pkg/scheme"
)
func jsonPrettyPrint(in string) string {
var out bytes.Buffer
err := json.Indent(&out, []byte(in), "", "\t")
if err != nil {
return in
}
return out.String()
}
func main() {
var stdin io.Reader
var cmd = [] string{"/bin/bash", "-c", "./terraform init"}
var out io.Writer
var stdout, stderr bytes.Buffer
enc := json.NewEncoder(out)
enc.SetIndent("", " ")
// kubeconfig에서 현재 콘텍스트를 사용한다
// path-to-kubeconfig -- 예를 들어, /root/.kube/config
config, _ := clientcmd.BuildConfigFromFlags("", "./config")
// clientset을 생성한다
clientset, _ := kubernetes.NewForConfig(config)
// 파드를 나열하기 위해 API에 접근한다
pods, _ := clientset.CoreV1().Pods("mskim").List(context.TODO(), v1.ListOptions{})
fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
terraformPod, _ := json.Marshal(pods.Items[7])
fmt.Printf("items", jsonPrettyPrint(string(terraformPod)))
//pod실행 option을 결정한다
option := &corev1.PodExecOptions{
Container: "terraform",
Command: cmd,
Stdin: true,
Stdout: true,
Stderr: true,
TTY: false,
}
if stdin == nil {
option.Stdin = false
}
//요청할 pod, namespace를 지정한다
req := clientset.CoreV1().RESTClient().Post().Resource("pods").Name("terraform-pod").
Namespace("mskim").SubResource("exec")
req.VersionedParams(
option,
scheme.ParameterCodec,
)
exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
err = exec.Stream(remotecommand.StreamOptions{
Stdin: stdin,
Stdout: &stdout,
Stderr: &stderr,
})
if err != nil{
fmt.Println(err)
}
//명령어 실행 결과를 출력한다.
fmt.Println(stdout.String(), stderr.String())
}
*더 나은 내용을 위한 지적, 조언은 언제나 환영합니다.
'Cloud' 카테고리의 다른 글
(kubernetes) - nfs storage사용하기 (1) | 2022.04.29 |
---|---|
(Terraform) - 용어 정리 (0) | 2022.04.28 |
(Terraform) - Window에 설치 (0) | 2022.04.25 |
(Kubernetes) - TLS/SSL secret 생성하기 (0) | 2022.04.19 |
(Kubernetes) - redis cluster statefulset예제 (0) | 2022.04.12 |