Open8

Kubernetes - 2021

Tsubasa NagasawaTsubasa Nagasawa
Tsubasa NagasawaTsubasa Nagasawa

ctr で遊ぶ

# ctr コマンドは namespace の概念があり、Kubernetes は k8s.io の namespace を使っている
$ sudo ctr ns list

# namespace 指定しないと何も表示されない
$ sudo ctr images list
$ sudo ctr -n k8s.io images list

# 起動しているコンテナ一覧
$ sudo ctr -n k8s.io containers ls

適当な Pod を起動してみる

# コンテナイメージの pull
$ sudo ctr -n k8s.io images pull gcr.io/knative-samples/helloworld-go:latest
# コンテナの作成
$ sudo ctr -n k8s.io containers create gcr.io/knative-samples/helloworld-go:latest helloworld
# コンテナの起動
$ sudo ctr -n k8s.io task start helloworld -d
# コンテナ起動確認
$ sudo ctr -n k8s.io tasks ps helloworld

# コンテナの停止
$ sudo ctr -n k8s.io tasks kill helloworld
# コンテナの削除
$ sudo ctr -n k8s.io containers rm helloworld
# イメージの削除
$ sudo ctr -n k8s.io images rm gcr.io/knative-samples/helloworld-go:latest

crictl で遊ぶ

$ sudo crictl images list

# 起動しているコンテナ一覧
$ sudo crictl containers ls

trailing dot がない場合に DNS 負荷が上がる問題の再現

curl で適当に名前解決してその時の状態を tcpdump で見る

kubectl run curl-it --rm --restart=Always --image=curlimages/curl:latest -- ash

デバッグコンテナの起動

kubectl debug -n default curl --target=curl --image=<tcpdump_image>

curl Pod の namespace の中で tcpdump コマンドを実行

tcpdump -nn dst port 53

curl の Pod で適当な DNS 名を叩いてみる

kubectl exec -it -n default curl -- ash

curl http://a.b.c

curl http://a.b.c.

Pod の中の resolv.conf を見る

cat /etc/resolv.conf
Tsubasa NagasawaTsubasa Nagasawa
Tsubasa NagasawaTsubasa Nagasawa

Metrics Server のメトリクスはどこから取得しているのか

kubectl proxy

node=
# /stats/summary
curl http://localhost:8001/api/v1/nodes/${node}/proxy/stats/summary?only_cpu_and_memory=true

# /metrics/resource
curl http://localhost:8001/api/v1/nodes/${node}/proxy/metrics/resource

Agones の Allocation の仕組み

node=

TOKEN=$(kubectl config view -o jsonpath='{.users[?(@.name == "${node}")].user.auth-provider.config.access-token}')
APISERVER=$(kubectl config view -o jsonpath='{.clusters[?(@.name == "${node}")].cluster.server}')

curl --header "Authorization: Bearer $TOKEN" --insecure -X POST -H "Content-Type: application/yaml" --data '
apiVersion: allocation.agones.dev/v1
kind: GameServerAllocation
spec:
  selectors:
  - labelSelector:
      matchLabels:
        "agones.dev/fleet": prizm-agones-room
' "$APISERVER/apis/allocation.agones.dev/v1/namespaces/dev1/gameserverallocations"

curl --header "Authorization: Bearer $TOKEN" --insecure "$APISERVER/apis/allocation.agones.dev/v1"
Tsubasa NagasawaTsubasa Nagasawa
Tsubasa NagasawaTsubasa Nagasawa

Kubernetes の Watch API

# まず既存のリソースの一覧を表示してから watch スタート
kubectl get pods -n kube-system --watch
# 既存のリソースの一覧を表示せずに watch スタート
kubectl get pods -n kube-system --watch-only

# 適当に Pod を起動
kubectl run helloworld --rm --restart=Never --image=gcr.io/knative-samples/helloworld-go:latest

# $HOME/.kube/config 内の Baerer トークンの期限が切れてたら更新
kubectl get nodes

node=

# トークンを取得
TOKEN=$(kubectl config view -o jsonpath='{.users[?(@.name == "${node}")].user.auth-provider.config.access-token}')
APISERVER=$(kubectl config view -o jsonpath='{.clusters[?(@.name == "${node}")].cluster.server}')

# default namespace の Pod の resourceVersion を確認
curl $APISERVER/api/v1/namespaces/default/pods --header "Authorization: Bearer $TOKEN" --insecure

# RESOURCE_VERSION=
# curl "$APISERVER/api/v1/namespaces/default/pods?watch=1&resourceVersion=${RESOURCE_VERSION}" --header "Authorization: Bearer $TOKEN" --insecure

# 適当に Pod を起動
kubectl run curl-debugger --rm --restart=Never --image=gcr.io/knative-samples/helloworld-go:latest -- ash

# Pod の雛形を作る
kubectl run curl-debugger --restart=Always --image=gcr.io/knative-samples/helloworld-go:latest -oyaml --dry-run=client

# Deployment の雛形を作る
kubectl create deploy curl-debugger --image=gcr.io/knative-samples/helloworld-go:latest -oyaml --dry-run=client

Metrics Server があることで以下のコマンドでメトリクスが確認できる

kubectl top nodes
kubectl top pods -n kube-system

# Metrics API の確認
kubectl api-resources --api-group='metrics.k8s.io'

kube-apiserver に curl でリクエストを投げる

# $HOME/.kube/config 内の Baerer トークンの期限が切れてたら更新
kubectl get nodes

node=

# トークンを取得
TOKEN=$(kubectl config view -o jsonpath='{.users[?(@.name == "${node}")].user.auth-provider.config.access-token}')
APISERVER=$(kubectl config view -o jsonpath='{.clusters[?(@.name == "${node}")].cluster.server}')

# kube-system 内の Pod の一覧を
curl $APISERVER/api/v1/namespaces/kube-system/pods --header "Authorization: Bearer $TOKEN" --insecure

# Metrics API (Nodes)
curl $APISERVER/apis/metrics.k8s.io/v1beta1/nodes --header "Authorization: Bearer $TOKEN" --insecure

# Metrics API (Pods)
curl $APISERVER/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods --header "Authorization: Bearer $TOKEN" --insecure

cAdvisor のメトリクスを見る

node=

kubectl proxy
curl http://localhost:8001/api/v1/nodes
curl http://localhost:8001/api/v1/nodes/${node}/proxy/metrics/cadvisor

ssh
curl http://localhost:10255/metrics/cadvisor
Tsubasa NagasawaTsubasa Nagasawa
Tsubasa NagasawaTsubasa Nagasawa
  • メルカリさんが VPC-native networking を有効化したクラスターに移行した話 (blog)
  • Kubernetes のコードネームが Seven だった話 (podcast)
  • Kubernetes の歴史 (blog)
  • Admission Webhook の解説 (blog)
  • Kubernetes の Control Plane と Data Plane (document)
  • EKS での kubectl の認証は kubernetes-sigs/aws-iam-authenticator
  • EKS の kubeconfig の中身 (document)
  • Addon Manager のソースコード (source)
  • Addon Manager の日本語解説 (blog)
  • Event Exporter のソースコード (source)
  • クローズドソースのコンポーネントのログに登場する BuildRabbit の話 (slide)
  • CoreDNS がデフォルトの DNS になった KEP
  • CoreDNS のプロジェクトのアナウンス、元々 Go の DNS ライブラリを作っていた人作った (blog)
  • CoreDNS を作る際に影響を受けて内部的にも使っている Caddy
  • CoreDNS を作った人が作った SkyDNS も OpenShift で採用されている (blog)