Open8
Kubernetes - 2021
- 詳説 OCIコンテナランタイム youki
- メルカリさんが GKE Sandbox (gVisor) を使っている (slide)
- ctr
- crictl
- nerdctl
- containerd & Lima: Open source alternative to Docker for Mac
- kubelet の image gc でディスク容量 85% の閾値を超えるとコンテナイメージをお掃除
- inode が枯渇する可能性があるが、kubelet の gc に任せて今は問題が出ていない
- pause コンテナのソースコード
- https://www.ianlewis.org/en/almighty-pause-container
- Is the pause container necessary?
- PID namespace の分離について
- Kubernetes における名前解決と ndots の問題
- ndots 5 となった背景
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
- Metrics Server の改善 (kubernetes-sigs/metrics-server#627)
- Metrics Server v0.3.6 だと kubelet の
/stats/summaryから取得 (source) - Metrics Server v0.5.1 もまだ kubelet の
/stats/summaryから取得 (source) -
kubernetes-sigs/metrics-server#777 から
/metrics/resourceに変更 - netd の役割について
- Compute Engine persistent disk CSI Driver への移行について (document)
- In-tree Storage Plugin (e.g.
kubernetes.io/gce-pd) から CSI (e.g.pd.csi.storage.gke.io) への自動移行の KEP - Metrics API は Aggregated API (source)
- Custom Resource Definition vs Aggregated API
- Agones における Aggregated API の例 (source, source)
- Node Problem Detector
- Node Problem Detector と連携した自動修復
- PFN さんの独自自動修復
- Dockershim の廃止
- containerd は 2016 年 12 月に Docker Engine から切り離されて開始したプロジェクト (blog)
- containerd/stargz-snapshotter によるコンテナの起動時間を改善 (slide, slide)
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"
- kube-proxy の Event ベースの iptables ルールの更新 (source)
- The Life of a Kubernetes Watch Event - Wenjia Zhang & Haowei Cai, Google
- Kubelet watches necessary secrets/configmaps instead of periodic polling #64752
- Watch API - etcd3
- Watch API でやっていること (document)
- Kubernetes Resource Version
- l7-default-backend のソースコード (source)
- Ingress の DefaultBackend の説明 (document)
- Metrics Server のアーキテクチャ (document)
- Consider implementing loadbalancing in kube-aggregator to allow better support for HA #764
- Add high availability configuration #805
- EKS だとアドオンを自分で入れないといけない (document)
- metrics-server の前は heapster が使われていた (tweet)
- How to autoscale Metrics Server?
- Addon Resizer のソースコード (source)
- Addon Resizer についての日本語解説 (blog)
- cAdvisor は kubelet 組み込み
- kubelet の
--read-only-port(document) - cAdvisor によるコンテナメトリクスの収集をやめて CRI (Container Runtime Interface) がその責務を負うべき KEP
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
- event-exporter の補足: Event リソースはデフォルトで 1 時間で自動的に削除される (kube-apiserver の
--event-ttlオプション) - metrics-agent の中身は open-telemetry/opentelemetry-collector
- kube-dns/dnsmasq-nanny/sidecar のソースコード (source)
- kube-dns-autoscaler の中身は kubernetes-sigs/cluster-proportional-autoscaler
- kube-proxy のメインの処理 (source)
- Static Pods がなぜ必要かの議論となぜセキュリティリスクとならないか (kubernetes/kubeadm#1541)
- OpenTelemetry についての日本語解説 (blog)
- メルカリさんが 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)