kubectl top pod と docker stats メモリー使用量の違いは、メモリー使用量にPage Cache(active)が含まれているためですがメモリを基準にさまざまな制御を行う事ってありますよね。これはライブアップ実施後の確認の間に書いてランチを食べれていない。
はじめに
kubernetes API にアクセスする時には様々な方法がある。kubectl や curl などでも行う事ができる。でも、kubectl 使うことが一般的だとは思う。しかし、もう少し複雑な事をさせたいと思ったらのなら何かしらのプログラミング言語で実施したくなります。Kubernetes APIにアクセスするにはk8s.io/client-goを使うのはわりと自然な流れかと思います。今回、やりたいこととしてはkubernetes APIから取得したデーターを基にメモリの使用量を取得したいと思ってます。
さっそく、本題
今回は本当にお腹空いてる。
kubectl top pod -n <ns>
ちなみに詳細を知りたい場合には
kubectl top pod -n <ns> -v9
などを記載しているといい感じになる。
今回は GitHub - kubernetes/metrics: Kubernetes metrics-related API types and clients を利用してメモリの使用量を確認したいと思います。最終的なコードはこちらになります。
package main import ( "fmt" "os" "path/filepath" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/util/homedir" metrics "k8s.io/metrics/pkg/client/clientset/versioned" ) func main() { var kubeconfig string //empty, assuming inClusterConfig kubeconfig, ok := os.LookupEnv("KUBECONFIG") if !ok { kubeconfig = filepath.Join(homedir.HomeDir(), ".kube", "config") } config, err := clientcmd.BuildConfigFromFlags("", kubeconfig) if err != nil { panic(err) } mc, err := metrics.NewForConfig(config) if err != nil { panic(err) } podMetrics, err := mc.MetricsV1beta1().PodMetricses(metav1.NamespaceAll).List(metav1.ListOptions{}) if err != nil { fmt.Println("Error:", err) return } for _, podMetric := range podMetrics.Items { podContainers := podMetric.Containers for _, container := range podContainers { memQuantity, ok := container.Usage.Memory().AsInt64() if !ok { return } msg := fmt.Sprintf("Container Name: %s \n Memory usage: %d", container.Name, memQuantity) fmt.Println(msg) } } }
遊ぶ
環境情報
環境構築はとても大切です。kubeadm や minikube など他にも様々な手段がある。が 今回は Kindを利用します。
$ go version go version go1.14.5 linux/amd64 $ docker version 4290ms Client: Version: 19.03.8 API version: 1.40 Go version: go1.13.8 Git commit: afacb8b7f0 Built: Tue Jun 23 22:26:12 2020 OS/Arch: linux/amd64 Experimental: false Server: Engine: Version: 19.03.11 API version: 1.40 (minimum version 1.12) Go version: go1.13.12 Git commit: 77e06fd Built: Mon Jun 8 20:24:59 2020 OS/Arch: linux/amd64 Experimental: false containerd: Version: v1.2.13 GitCommit: 7ad184331fa3e55e52b890ea95e65ba581ae3429 runc: Version: 1.0.0-rc10 GitCommit: docker-init: Version: 0.18.0 GitCommit: fec3683 $ kind --version # https://kind.sigs.k8s.io/docs/user/quick-start/ kind version 0.8.1
環境構築
クラスタ-の構築
$ kind create cluster --name metrics Creating cluster "metrics" ... ✓ Ensuring node image (kindest/node:v1.18.2) 🖼 ✓ Preparing nodes 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 Set kubectl context to "kind-metrics" You can now use your cluster with: kubectl cluster-info --context kind-metrics Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/ # kubeconfig の書き込み $ kind get kubeconfig --name metrics > kubeconfig.yaml # kubeconfing の確認 $ kubectl version --kubeconfig=kubeconfig.yaml Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.0", GitCommit:"9e991415386e4cf155a24b1da15becaa390438d8", GitTreeState:"clean", BuildDate:"2020-03-25T14:58:59Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.2", GitCommit:"52c56ce7a8272c798dbc29846288d7cd9fbae032", GitTreeState:"clean", BuildDate:"2020-04-30T20:19:45Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
metrics-server の導入
観測用のPodのデプロイ
$ kubectl create deployment nginx --image=nginx deployment.apps/nginx created $ kubectl get pod NAME READY STATUS RESTARTS AGE nginx-f89759699-k2vc7 1/1 Running 0 39s
kubernetes v1.11からはmetrics serverを動かしてやればいいのですが いまいち上手く取得できないので こちらのIssue を参考にしたのがこちらです。
$ kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.3.7/components.yaml clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator configured rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader configured apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io unchanged serviceaccount/metrics-server unchanged deployment.apps/metrics-server configured service/metrics-server configured clusterrole.rbac.authorization.k8s.io/system:metrics-server configured clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server unchanged
実行
$ kubectl top pod -A NAMESPACE NAME CPU(cores) MEMORY(bytes) default nginx-f89759699-k2vc7 0m 3Mi kube-system coredns-66bff467f8-k85lw 3m 8Mi kube-system coredns-66bff467f8-xlnz5 3m 8Mi kube-system etcd-metrics-control-plane 24m 55Mi kube-system kindnet-55z2v 2m 9Mi kube-system kube-apiserver-metrics-control-plane 41m 260Mi kube-system kube-controller-manager-metrics-control-plane 15m 39Mi kube-system kube-proxy-whtdr 1m 12Mi kube-system kube-scheduler-metrics-control-plane 4m 15Mi kube-system metrics-server-697bddf786-55sq9 1m 13Mi local-path-storage local-path-provisioner-bd4bb6b75-8qfzn 11m 9Mi $ go run main.go Container Name: coredns Memory usage: 9060352 Container Name: kube-proxy Memory usage: 13139968 Container Name: etcd Memory usage: 57958400 Container Name: kube-controller-manager Memory usage: 40906752 Container Name: local-path-provisioner Memory usage: 9605120 Container Name: kube-apiserver Memory usage: 273580032 Container Name: kube-scheduler Memory usage: 16199680 Container Name: coredns Memory usage: 8982528 Container Name: kindnet-cni Memory usage: 9945088 Container Name: nginx Memory usage: 3526656 Container Name: metrics-server Memory usage: 14118912
コード解説
は後で書くのと取得値がkubectl top pod と違う件はラーメン屋から帰ってきてから書きます。とりあえず、公開しておきます。
最終成果物
workspace_2020/blog/metrics at master · nwiizo/workspace_2020 · GitHub