初めての etcdctl と kubectl get の正体

kindで作ったk8s clusterをみてたらcontrol planeでetcdが走ってることに気づいたのでetcdの中身を見てみました。ずっとみてみたかった。

# control planeに入る

kindはdockerでk8s cluster作るのでdocker commandでアクセスできます

```r
$ docker ps | grep control-plane
9c0986d6b85e   kindest/node:v1.29.2         "/usr/local/bin/entr…"   4 days ago     Up 3 days   0.0.0.0:30001->30001/tcp, 127.0.0.1:55841->6443/tcp    kind-control-plane

$ docker exec -it  kind-control-plane bash
root@kind-control-plane:/#
```

この記事は以降ずっとこのcontrol planeの中で作業します


# install etcdctl

`etcd-client` を調べるの結構大変だったので、ここだけ調べに来た人は **いいね** していって！

```rb
apt install etcd-client
```

```racket
# etcdctl version
etcdctl version: 3.4.23
API version: 3.4
```

source code: https://github.com/etcd-io/etcd/tree/main/etcdctl


# etcd
psで見ると etcd はこのコマンドで起動している様子です

```rb
etcd \
   --advertise-client-urls=https://10.201.0.2:2379 \
   --cert-file=/etc/kubernetes/pki/etcd/server.crt \
   --client-cert-auth=true \
   --data-dir=/var/lib/etcd \
   --experimental-initial-corrupt-check=true \
   --experimental-watch-progress-notify-interval=5s \
   --initial-advertise-peer-urls=https://10.201.0.2:2380 \
   --initial-cluster=kind-control-plane=https://10.201.0.2:2380 \
   --key-file=/etc/kubernetes/pki/etcd/server.key \
   --listen-client-urls=https://127.0.0.1:2379,https://10.201.0.2:2379 \
   --listen-metrics-urls=http://127.0.0.1:2381 \
   --listen-peer-urls=https://10.201.0.2:2380 \
   --name=kind-control-plane \
   --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt \
   --peer-client-cert-auth=true \
   --peer-key-file=/etc/kubernetes/pki/etcd/peer.key \
   --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt \
   --snapshot-count=10000 \
   --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt \
```

# etcdctl 認証方法
証明書を適当に当てたら接続できました。まず `get --prefix /registry/pods/default` を叩いてみると、バイナリっぽい結果が取得できました

```rb
etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  get --prefix /registry/pods/default
```
```react
/registry/pods/default/apache-7bdd4c55dc-8hnsk
k8s

v1Pod�
�

apache-7bdd4c55dc-8hnskapache-7bdd4c55dc-default"*$c1427fb3-1fab-40cc-a1af-511fd495b2702�Ϩ�Z
appapacheZ
pod-template-hash
7bdd4c55dcjR

ReplicaSetapache-7bdd4c55dc"$9bc35985-0d27-4822-a9bf-722832a5828b*apps/v108��
kube-controller-managerUpdatev�Ϩ�FieldsV1:�
�{"f:metadata":{"f:generateName":{},"f:labels":{".":{},"f:app":{},"f:pod-template-hash":{}},"f:ownerReferences":{".":{},"k:{\"uid\":\"9bc35985-0d27-4822-a9bf-722832a5828b\"}":{}}},"f:spec":{"f:containers":{"k:{\"name\":\"apache\"}":{".":{},"f:image":{},"f:imagePullPolicy":{},"f:name":{},"f:resources":{},"f:terminationMessagePath":{},"f:terminationMessagePolicy":{}}},"f:dnsPolicy":{},"f:enableServiceLinks":{},"f:restartPolicy":{},"f:schedulerName":{},"f:securityContext":{},"f:terminationGracePeriodSeconds":{}}}B��
kubeletUpdatev�Ƭ�FieldsV1:�
�{"f:status":{"f:conditions":{"k:{\"type\":\"ContainersReady\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:status":{},"f:type":{}},"k:{\"type\":\"Initialized\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:status":{},"f:type":{}},"k:{\"type\":\"PodReadyToStartContainers\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:status":{},"f:type":{}},"k:{\"type\":\"Ready\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:status":{},"f:type":{}}},"f:containerStatuses":{},"f:hostIP":{},"f:hostIPs":{},"f:phase":{},"f:podIP":{},"f:podIPs":{".":{},"k:{\"ip\":\"10.244.1.3\"}":{".":{},"f:ip":{}}},"f:startTime":{}}}Bstatus�
�
kube-api-access-pbcxjk�h
...
```


aliasを作ります。

```rb
alias etcdctl='etcdctl --endpoints=https://127.0.0.1:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt '
```

これで簡単に打てるようになりました
```rb
etcdctl get --prefix /registry/pods/default
```

## etcdctl 認証skip方法？

なお、`etcdctl get -h` をみるとinsecure optionsがあるので、skipもできそう。
```racket
# etcdctl get -h
NAME:
	get - Gets the key or a range of keys

USAGE:
	etcdctl get [options] <key> [range_end] [flags]

OPTIONS:
      --consistency="l"			Linearizable(l) or Serializable(s)
      --from-key[=false]		Get keys that are greater than or equal to the given key using byte compare
  -h, --help[=false]			help for get
      --keys-only[=false]		Get only the keys
      --limit=0				Maximum number of results
      --order=""			Order of results; ASCEND or DESCEND (ASCEND by default)
      --prefix[=false]			Get keys with matching prefix
      --print-value-only[=false]	Only write values when using the "simple" output format
      --rev=0				Specify the kv revision
      --sort-by=""			Sort target; CREATE, KEY, MODIFY, VALUE, or VERSION

GLOBAL OPTIONS:
      --cacert=""				verify certificates of TLS-enabled secure servers using this CA bundle
      --cert=""					identify secure client using this TLS certificate file
      --command-timeout=5s			timeout for short running command (excluding dial timeout)
      --debug[=false]				enable client-side debug logging
      --dial-timeout=2s				dial timeout for client connections
  -d, --discovery-srv=""			domain name to query for SRV records describing cluster endpoints
      --discovery-srv-name=""			service name to query when using DNS discovery
      --endpoints=[127.0.0.1:2379]		gRPC endpoints
      --hex[=false]				print byte strings as hex encoded strings
      --insecure-discovery[=true]		accept insecure SRV records describing cluster endpoints
      --insecure-skip-tls-verify[=false]	skip server certificate verification (CAUTION: this option should be enabled only for testing purposes)
      --insecure-transport[=true]		disable transport security for client connections
      --keepalive-time=2s			keepalive time for client connections
      --keepalive-timeout=6s			keepalive timeout for client connections
      --key=""					identify secure client using this TLS key file
      --password=""				password for authentication (if this option is used, --user option shouldn't include password)
      --user=""					username[:password] for authentication (prompt if password is not supplied)
  -w, --write-out="simple"			set the output format (fields, json, protobuf, simple, table)
```


# etcdctl get を叩いてみる

適当にnamespaceにしたら動いた
```r
etcdctl get --prefix /registry/namespace
```
```racket
/registry/namespaces/default
k8s

v1	Namespace�
�
default"*$0a71856f-8592-4fed-bf5e-b0c096e108f12����Z&

kube-apiserverUpdatev����FieldsV1:I
G{"f:metadata":{"f:labels":{".":{},"f:kubernetes.io/metadata.name":{}}}}B
...
```

例としてこういうコマンドが使えるそうです

```rb
etcdctl get --prefix /registry/nodes
etcdctl get --prefix /registry/pods
etcdctl get --prefix /registry/services
etcdctl get --prefix /registry/configmaps
etcdctl get --prefix /registry/secrets
```




# etcdctl watch
watchコマンド面白そうということで試してみた。
まずserviceをwatchします。なんの表示もされません。

```rb
etcdctl watch --prefix /registry/services
```
ここで svc1 を作成してみた瞬間、logが増えます

```racket
# etcdctl watch --prefix /registry/services
PUT
/registry/services/specs/kube-system/svc1
k8s

v1Service�
�
svc1
    kube-system"*$14abcf92-74a8-4018-9b00-92b82cccf1cb2����b�
0kubectl.kubernetes.io/last-applied-configuration�{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"svc1","namespace":"kube-system"},"spec":{"ports":[{"port":80}],"type":"ClusterIP"}}
��
kubectl-client-side-applyUpdatev����FieldsV1:�
�{"f:metadata":{"f:annotations":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration":{}}},"f:spec":{"f:internalTrafficPolicy":{},"f:ports":{".":{},"k:{\"port\":80,\"protocol\":\"TCP\"}":{".":{},"f:port":{},"f:protocol":{},"f:targetPort":{}}},"f:sessionAffinity":{},"f:type":{}}}Bl

TCPPP(
      10.96.120.46"	ClusterIP:NoneBRZ`h�
                                            SingleStack�
                                                        10.96.120.46�IPv4�Cluster
"
```

作成したsvcの内容が出力されました。

`kubectl.kubernetes.io/last-applied-configuration` に使ったyamlが出てます。

なるほどねぇ、こうしてetcdがcluster全体の情報を持ってるのね



# PUT / DELETE と GET を深掘り
## PUT
成功すると `OK` がかえる
```racket
# etcdctl put my-key my-value
OK
```

## GET
なるほど、getするとkeyが1行目、2行目以降がvalueとして出力されるのか。

```racket
# etcdctl get my-key
my-key
my-value
```

出力方式は `-w` `--write-out=` optionで変えられる様子。

```rb
  -w, --write-out="simple"			set the output format (fields, json, protobuf, simple, table)
```

### GET の出力オプション
#### Simple
```racket
# etcdctl get my-key -w simple
my-key
my-value
```
#### fields
これはyaml用ですね。

```racket
# etcdctl get my-key -w fields
"ClusterID" : 12364629819942928568
"MemberID" : 9010542669943343927
"Revision" : 602770
"RaftTerm" : 3
"Key" : "my-key"
"CreateRevision" : 602750
"ModRevision" : 602750
"Version" : 1
"Value" : "my-value"
"Lease" : 0
"More" : false
"Count" : 1
```

##### yq に通してみる
yq 入れる
```rb
apt-get install yq -y
```
parse成功！ これならkey/valueが見えて良い！
```racket
# etcdctl get my-key -w fields | yq
{
  "ClusterID": 12364629819942928000,
  "MemberID": 9010542669943344000,
  "Revision": 605406,
  "RaftTerm": 3,
  "Key": "my-key",
  "CreateRevision": 602750,
  "ModRevision": 602750,
  "Version": 1,
  "Value": "my-value",
  "Lease": 0,
  "More": false,
  "Count": 1
}

```
#### json
jsonの場合はkey/valueともにbase64 encodedです。

```racket
# etcdctl get my-key -w json
{"header":{"cluster_id":12364629819942928568,"member_id":9010542669943343927,"revision":602785,"raft_term":3},"kvs":[{"key":"bXkta2V5","create_revision":602750,"mod_revision":602750,"version":1,"value":"bXktdmFsdWU="}],"count":1}
```

`base64 --decode` すると値が見れます。

```racket
# etcdctl get my-key -w json | jq -r '.kvs[0].key' | base64 -d
my-key

# etcdctl get my-key -w json | jq -r '.kvs[0].value' | base64 -d
my-value

```
#### protobuf
```racket
# etcdctl get my-key -w protobuf

������˫��䛘��}��$
my-key��$��$ my-value 
```
#### table
これは見れなかった
```racket
# etcdctl get my-key -w table
Error: table not supported as output format
```

## value を json にしてみる
### PUT
```racket
# etcdctl put my-json '{"key": "value"}'
OK
```

### GET
#### json with -w simple

simple だとkeyが邪魔で jq に通せません。でもkey/valueの値がそのまま見れて便利。


```rb
$ etcdctl get my-json
my-json
{"key": "value"}
```

headerを消せば json になるけど、不格好ではある
```json
$ etcdctl get my-json | tail -1 | jq
{
  "key": "value"
}

$ etcdctl get my-json | sed '1d' | jq
{
  "key": "value"
}
```

#### json with -w json
これは綺麗に出ますし付随する詳細情報も見れますが、肝心のkey/valueがbase64 encodedで不便。基本的にsdkから使うもの、そしてyaml推奨なんだと想像

```json
$ etcdctl get my-json  -w json | jq
{
  "header": {
    "cluster_id": 12364629819942928000,
    "member_id": 9010542669943344000,
    "revision": 603706,
    "raft_term": 3
  },
  "kvs": [
    {
      "key": "bXktanNvbg==",      // <--- my-json
      "create_revision": 602545,
      "mod_revision": 602545,
      "version": 1,
      "value": "eyJrZXkiOiAidmFsdWUifQ=="   // <---- {"key": "value"}
    }
  ],
  "count": 1
}
```

## DELETE 
成功すると 1 が返る。PUTは `OK` なのになんで？

```rb
$ etcdctl del my-key
1

$ etcdctl del my-json
1
```


# k8sが使うetcd keys と `kubectl get` の正体
scriptを作って全部リストしてみました
## all etcd keys
```sh
#!/bin/bash
auth="--endpoints=https://127.0.0.1:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt"
etcdctl $auth get --prefix / -w json | jq -r '.kvs[].key' | while read line; do
    echo "$line" | base64 -d
    echo
done
```

。。。が、もっと簡単なコマンドがありました。

```rb
etcdctl get --prefix / --keys-only
etcdctl get --prefix / -w fields  | grep Key
```

scriptの実行結果です。非常に長いです。

```rb
$ bash b
/registry/apiregistration.k8s.io/apiservices/v1.
/registry/apiregistration.k8s.io/apiservices/v1.admissionregistration.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.apiextensions.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.apps
/registry/apiregistration.k8s.io/apiservices/v1.authentication.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.authorization.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.autoscaling
/registry/apiregistration.k8s.io/apiservices/v1.batch
/registry/apiregistration.k8s.io/apiservices/v1.certificates.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.coordination.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.discovery.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.events.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.flowcontrol.apiserver.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.networking.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.node.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.policy
/registry/apiregistration.k8s.io/apiservices/v1.rbac.authorization.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.scheduling.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.storage.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1beta3.flowcontrol.apiserver.k8s.io
/registry/apiregistration.k8s.io/apiservices/v2.autoscaling
/registry/clusterrolebindings/cluster-admin
/registry/clusterrolebindings/kindnet
/registry/clusterrolebindings/kubeadm:cluster-admins
/registry/clusterrolebindings/kubeadm:get-nodes
/registry/clusterrolebindings/kubeadm:kubelet-bootstrap
/registry/clusterrolebindings/kubeadm:node-autoapprove-bootstrap
/registry/clusterrolebindings/kubeadm:node-autoapprove-certificate-rotation
/registry/clusterrolebindings/kubeadm:node-proxier
/registry/clusterrolebindings/local-path-provisioner-bind
/registry/clusterrolebindings/system:basic-user
/registry/clusterrolebindings/system:controller:attachdetach-controller
/registry/clusterrolebindings/system:controller:certificate-controller
/registry/clusterrolebindings/system:controller:clusterrole-aggregation-controller
/registry/clusterrolebindings/system:controller:cronjob-controller
/registry/clusterrolebindings/system:controller:daemon-set-controller
/registry/clusterrolebindings/system:controller:deployment-controller
/registry/clusterrolebindings/system:controller:disruption-controller
/registry/clusterrolebindings/system:controller:endpoint-controller
/registry/clusterrolebindings/system:controller:endpointslice-controller
/registry/clusterrolebindings/system:controller:endpointslicemirroring-controller
/registry/clusterrolebindings/system:controller:ephemeral-volume-controller
/registry/clusterrolebindings/system:controller:expand-controller
/registry/clusterrolebindings/system:controller:generic-garbage-collector
/registry/clusterrolebindings/system:controller:horizontal-pod-autoscaler
/registry/clusterrolebindings/system:controller:job-controller
/registry/clusterrolebindings/system:controller:legacy-service-account-token-cleaner
/registry/clusterrolebindings/system:controller:namespace-controller
/registry/clusterrolebindings/system:controller:node-controller
/registry/clusterrolebindings/system:controller:persistent-volume-binder
/registry/clusterrolebindings/system:controller:pod-garbage-collector
/registry/clusterrolebindings/system:controller:pv-protection-controller
/registry/clusterrolebindings/system:controller:pvc-protection-controller
/registry/clusterrolebindings/system:controller:replicaset-controller
/registry/clusterrolebindings/system:controller:replication-controller
/registry/clusterrolebindings/system:controller:resourcequota-controller
/registry/clusterrolebindings/system:controller:root-ca-cert-publisher
/registry/clusterrolebindings/system:controller:route-controller
/registry/clusterrolebindings/system:controller:service-account-controller
/registry/clusterrolebindings/system:controller:service-controller
/registry/clusterrolebindings/system:controller:statefulset-controller
/registry/clusterrolebindings/system:controller:ttl-after-finished-controller
/registry/clusterrolebindings/system:controller:ttl-controller
/registry/clusterrolebindings/system:coredns
/registry/clusterrolebindings/system:discovery
/registry/clusterrolebindings/system:kube-controller-manager
/registry/clusterrolebindings/system:kube-dns
/registry/clusterrolebindings/system:kube-scheduler
/registry/clusterrolebindings/system:monitoring
/registry/clusterrolebindings/system:node
/registry/clusterrolebindings/system:node-proxier
/registry/clusterrolebindings/system:public-info-viewer
/registry/clusterrolebindings/system:service-account-issuer-discovery
/registry/clusterrolebindings/system:volume-scheduler
/registry/clusterroles/admin
/registry/clusterroles/cluster-admin
/registry/clusterroles/edit
/registry/clusterroles/kindnet
/registry/clusterroles/kubeadm:get-nodes
/registry/clusterroles/local-path-provisioner-role
/registry/clusterroles/system:aggregate-to-admin
/registry/clusterroles/system:aggregate-to-edit
/registry/clusterroles/system:aggregate-to-view
/registry/clusterroles/system:auth-delegator
/registry/clusterroles/system:basic-user
/registry/clusterroles/system:certificates.k8s.io:certificatesigningrequests:nodeclient
/registry/clusterroles/system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
/registry/clusterroles/system:certificates.k8s.io:kube-apiserver-client-approver
/registry/clusterroles/system:certificates.k8s.io:kube-apiserver-client-kubelet-approver
/registry/clusterroles/system:certificates.k8s.io:kubelet-serving-approver
/registry/clusterroles/system:certificates.k8s.io:legacy-unknown-approver
/registry/clusterroles/system:controller:attachdetach-controller
/registry/clusterroles/system:controller:certificate-controller
/registry/clusterroles/system:controller:clusterrole-aggregation-controller
/registry/clusterroles/system:controller:cronjob-controller
/registry/clusterroles/system:controller:daemon-set-controller
/registry/clusterroles/system:controller:deployment-controller
/registry/clusterroles/system:controller:disruption-controller
/registry/clusterroles/system:controller:endpoint-controller
/registry/clusterroles/system:controller:endpointslice-controller
/registry/clusterroles/system:controller:endpointslicemirroring-controller
/registry/clusterroles/system:controller:ephemeral-volume-controller
/registry/clusterroles/system:controller:expand-controller
/registry/clusterroles/system:controller:generic-garbage-collector
/registry/clusterroles/system:controller:horizontal-pod-autoscaler
/registry/clusterroles/system:controller:job-controller
/registry/clusterroles/system:controller:legacy-service-account-token-cleaner
/registry/clusterroles/system:controller:namespace-controller
/registry/clusterroles/system:controller:node-controller
/registry/clusterroles/system:controller:persistent-volume-binder
/registry/clusterroles/system:controller:pod-garbage-collector
/registry/clusterroles/system:controller:pv-protection-controller
/registry/clusterroles/system:controller:pvc-protection-controller
/registry/clusterroles/system:controller:replicaset-controller
/registry/clusterroles/system:controller:replication-controller
/registry/clusterroles/system:controller:resourcequota-controller
/registry/clusterroles/system:controller:root-ca-cert-publisher
/registry/clusterroles/system:controller:route-controller
/registry/clusterroles/system:controller:service-account-controller
/registry/clusterroles/system:controller:service-controller
/registry/clusterroles/system:controller:statefulset-controller
/registry/clusterroles/system:controller:ttl-after-finished-controller
/registry/clusterroles/system:controller:ttl-controller
/registry/clusterroles/system:coredns
/registry/clusterroles/system:discovery
/registry/clusterroles/system:heapster
/registry/clusterroles/system:kube-aggregator
/registry/clusterroles/system:kube-controller-manager
/registry/clusterroles/system:kube-dns
/registry/clusterroles/system:kube-scheduler
/registry/clusterroles/system:kubelet-api-admin
/registry/clusterroles/system:monitoring
/registry/clusterroles/system:node
/registry/clusterroles/system:node-bootstrapper
/registry/clusterroles/system:node-problem-detector
/registry/clusterroles/system:node-proxier
/registry/clusterroles/system:persistent-volume-provisioner
/registry/clusterroles/system:public-info-viewer
/registry/clusterroles/system:service-account-issuer-discovery
/registry/clusterroles/system:volume-scheduler
/registry/clusterroles/view
/registry/configmaps/default/kube-root-ca.crt
/registry/configmaps/kube-node-lease/kube-root-ca.crt
/registry/configmaps/kube-public/cluster-info
/registry/configmaps/kube-public/kube-root-ca.crt
/registry/configmaps/kube-system/coredns
/registry/configmaps/kube-system/extension-apiserver-authentication
/registry/configmaps/kube-system/kube-apiserver-legacy-service-account-token-tracking
/registry/configmaps/kube-system/kube-proxy
/registry/configmaps/kube-system/kube-root-ca.crt
/registry/configmaps/kube-system/kubeadm-config
/registry/configmaps/kube-system/kubelet-config
/registry/configmaps/local-path-storage/kube-root-ca.crt
/registry/configmaps/local-path-storage/local-path-config
/registry/configmaps/ns11/kube-root-ca.crt
/registry/configmaps/ns12/kube-root-ca.crt
/registry/configmaps/ns2/kube-root-ca.crt
/registry/controllerrevisions/kube-system/kindnet-79d5bc7777
/registry/controllerrevisions/kube-system/kube-proxy-65bbdcdfff
/registry/controllerrevisions/ns12/ds-6d59468b47
/registry/csinodes/kind-control-plane
/registry/csinodes/kind-worker
/registry/csinodes/kind-worker2
/registry/daemonsets/kube-system/kindnet
/registry/daemonsets/kube-system/kube-proxy
/registry/daemonsets/ns12/ds
/registry/deployments/default/apache
/registry/deployments/default/nginx
/registry/deployments/kube-system/coredns
/registry/deployments/local-path-storage/local-path-provisioner
/registry/deployments/ns12/deploy
/registry/deployments/ns2/nginx
/registry/endpointslices/default/clusterip-svc-j9gct
/registry/endpointslices/default/kubernetes
/registry/endpointslices/default/lb-lvddk
/registry/endpointslices/default/nodeport-svc-b9bhq
/registry/endpointslices/kube-system/kube-dns-w796z
/registry/endpointslices/ns2/clusterip-ck8pf
/registry/endpointslices/ns2/lb-56mht
/registry/events/ns11/myapp.180567633d325f92
/registry/flowschemas/catch-all
/registry/flowschemas/endpoint-controller
/registry/flowschemas/exempt
/registry/flowschemas/global-default
/registry/flowschemas/kube-controller-manager
/registry/flowschemas/kube-scheduler
/registry/flowschemas/kube-system-service-accounts
/registry/flowschemas/probes
/registry/flowschemas/service-accounts
/registry/flowschemas/system-leader-election
/registry/flowschemas/system-node-high
/registry/flowschemas/system-nodes
/registry/flowschemas/workload-leader-election
/registry/leases/kube-node-lease/kind-control-plane
/registry/leases/kube-node-lease/kind-worker
/registry/leases/kube-node-lease/kind-worker2
/registry/leases/kube-system/apiserver-c7uylvfxlbqccnk6myfkwetzze
/registry/leases/kube-system/kube-controller-manager
/registry/leases/kube-system/kube-scheduler
/registry/masterleases/10.201.0.2
/registry/minions/kind-control-plane
/registry/minions/kind-worker
/registry/minions/kind-worker2
/registry/namespaces/default
/registry/namespaces/kube-node-lease
/registry/namespaces/kube-public
/registry/namespaces/kube-system
/registry/namespaces/local-path-storage
/registry/namespaces/ns11
/registry/namespaces/ns12
/registry/namespaces/ns2
/registry/networkpolicies/ns2/allow-nginx
/registry/pods/default/apache-7bdd4c55dc-8hnsk
/registry/pods/default/apache-7bdd4c55dc-llw62
/registry/pods/default/apache-7bdd4c55dc-nrhsn
/registry/pods/default/nginx-7854ff8877-4gbcb
/registry/pods/default/nginx-7854ff8877-4p27n
/registry/pods/default/nginx-7854ff8877-htlhw
/registry/pods/default/nginx-7854ff8877-mkgcv
/registry/pods/default/nginx-7854ff8877-pt5wk
/registry/pods/kube-system/coredns-76f75df574-rt9xx
/registry/pods/kube-system/coredns-76f75df574-vxtpq
/registry/pods/kube-system/etcd-kind-control-plane
/registry/pods/kube-system/kindnet-bjpx8
/registry/pods/kube-system/kindnet-m6g6m
/registry/pods/kube-system/kindnet-ww6vb
/registry/pods/kube-system/kube-apiserver-kind-control-plane
/registry/pods/kube-system/kube-controller-manager-kind-control-plane
/registry/pods/kube-system/kube-proxy-cbx5k
/registry/pods/kube-system/kube-proxy-hgrq8
/registry/pods/kube-system/kube-proxy-hnxcv
/registry/pods/kube-system/kube-scheduler-kind-control-plane
/registry/pods/local-path-storage/local-path-provisioner-7577fdbbfb-lpfqz
/registry/pods/ns11/myapp
/registry/pods/ns12/deploy-7df57ccbd-8678f
/registry/pods/ns12/deploy-7df57ccbd-lz8lk
/registry/pods/ns12/ds-pdvfw
/registry/pods/ns12/ds-sv9fg
/registry/pods/ns2/nginx-7854ff8877-4wgsv
/registry/priorityclasses/system-cluster-critical
/registry/priorityclasses/system-node-critical
/registry/prioritylevelconfigurations/catch-all
/registry/prioritylevelconfigurations/exempt
/registry/prioritylevelconfigurations/global-default
/registry/prioritylevelconfigurations/leader-election
/registry/prioritylevelconfigurations/node-high
/registry/prioritylevelconfigurations/system
/registry/prioritylevelconfigurations/workload-high
/registry/prioritylevelconfigurations/workload-low
/registry/ranges/serviceips
/registry/ranges/servicenodeports
/registry/replicasets/default/apache-7bdd4c55dc
/registry/replicasets/default/apache-7c5f54c97
/registry/replicasets/default/nginx-7854ff8877
/registry/replicasets/kube-system/coredns-76f75df574
/registry/replicasets/local-path-storage/local-path-provisioner-7577fdbbfb
/registry/replicasets/ns12/deploy-7df57ccbd
/registry/replicasets/ns2/nginx-7854ff8877
/registry/rolebindings/kube-public/kubeadm:bootstrap-signer-clusterinfo
/registry/rolebindings/kube-public/system:controller:bootstrap-signer
/registry/rolebindings/kube-system/kube-proxy
/registry/rolebindings/kube-system/kubeadm:kubelet-config
/registry/rolebindings/kube-system/kubeadm:nodes-kubeadm-config
/registry/rolebindings/kube-system/system::extension-apiserver-authentication-reader
/registry/rolebindings/kube-system/system::leader-locking-kube-controller-manager
/registry/rolebindings/kube-system/system::leader-locking-kube-scheduler
/registry/rolebindings/kube-system/system:controller:bootstrap-signer
/registry/rolebindings/kube-system/system:controller:cloud-provider
/registry/rolebindings/kube-system/system:controller:token-cleaner
/registry/roles/kube-public/kubeadm:bootstrap-signer-clusterinfo
/registry/roles/kube-public/system:controller:bootstrap-signer
/registry/roles/kube-system/extension-apiserver-authentication-reader
/registry/roles/kube-system/kube-proxy
/registry/roles/kube-system/kubeadm:kubelet-config
/registry/roles/kube-system/kubeadm:nodes-kubeadm-config
/registry/roles/kube-system/system::leader-locking-kube-controller-manager
/registry/roles/kube-system/system::leader-locking-kube-scheduler
/registry/roles/kube-system/system:controller:bootstrap-signer
/registry/roles/kube-system/system:controller:cloud-provider
/registry/roles/kube-system/system:controller:token-cleaner
/registry/serviceaccounts/default/default
/registry/serviceaccounts/kube-node-lease/default
/registry/serviceaccounts/kube-public/default
/registry/serviceaccounts/kube-system/attachdetach-controller
/registry/serviceaccounts/kube-system/bootstrap-signer
/registry/serviceaccounts/kube-system/certificate-controller
/registry/serviceaccounts/kube-system/clusterrole-aggregation-controller
/registry/serviceaccounts/kube-system/coredns
/registry/serviceaccounts/kube-system/cronjob-controller
/registry/serviceaccounts/kube-system/daemon-set-controller
/registry/serviceaccounts/kube-system/default
/registry/serviceaccounts/kube-system/deployment-controller
/registry/serviceaccounts/kube-system/disruption-controller
/registry/serviceaccounts/kube-system/endpoint-controller
/registry/serviceaccounts/kube-system/endpointslice-controller
/registry/serviceaccounts/kube-system/endpointslicemirroring-controller
/registry/serviceaccounts/kube-system/ephemeral-volume-controller
/registry/serviceaccounts/kube-system/expand-controller
/registry/serviceaccounts/kube-system/generic-garbage-collector
/registry/serviceaccounts/kube-system/horizontal-pod-autoscaler
/registry/serviceaccounts/kube-system/job-controller
/registry/serviceaccounts/kube-system/kindnet
/registry/serviceaccounts/kube-system/kube-proxy
/registry/serviceaccounts/kube-system/legacy-service-account-token-cleaner
/registry/serviceaccounts/kube-system/namespace-controller
/registry/serviceaccounts/kube-system/node-controller
/registry/serviceaccounts/kube-system/persistent-volume-binder
/registry/serviceaccounts/kube-system/pod-garbage-collector
/registry/serviceaccounts/kube-system/pv-protection-controller
/registry/serviceaccounts/kube-system/pvc-protection-controller
/registry/serviceaccounts/kube-system/replicaset-controller
/registry/serviceaccounts/kube-system/replication-controller
/registry/serviceaccounts/kube-system/resourcequota-controller
/registry/serviceaccounts/kube-system/root-ca-cert-publisher
/registry/serviceaccounts/kube-system/service-account-controller
/registry/serviceaccounts/kube-system/service-controller
/registry/serviceaccounts/kube-system/statefulset-controller
/registry/serviceaccounts/kube-system/token-cleaner
/registry/serviceaccounts/kube-system/ttl-after-finished-controller
/registry/serviceaccounts/kube-system/ttl-controller
/registry/serviceaccounts/local-path-storage/default
/registry/serviceaccounts/local-path-storage/local-path-provisioner-service-account
/registry/serviceaccounts/ns11/default
/registry/serviceaccounts/ns12/default
/registry/serviceaccounts/ns2/default
/registry/services/endpoints/default/clusterip-svc
/registry/services/endpoints/default/kubernetes
/registry/services/endpoints/default/lb
/registry/services/endpoints/default/nodeport-svc
/registry/services/endpoints/kube-system/kube-dns
/registry/services/endpoints/ns2/clusterip
/registry/services/endpoints/ns2/lb
/registry/services/specs/default/clusterip-svc
/registry/services/specs/default/exname
/registry/services/specs/default/kubernetes
/registry/services/specs/default/lb
/registry/services/specs/default/nodeport-svc
/registry/services/specs/default/slack
/registry/services/specs/kube-system/kube-dns
/registry/services/specs/kube-system/svc1
/registry/services/specs/kube-system/svc2
/registry/services/specs/ns11/myapp
/registry/services/specs/ns2/clusterip
/registry/services/specs/ns2/lb
/registry/storageclasses/standard
$
```

----

# おまけの `etcdctl -h`

databaseの管理コマンドっぽいですね。role/memberとかがあるのが最近っぽい。

```rb
# etcdctl -h
NAME:
	etcdctl - A simple command line client for etcd3.

USAGE:
	etcdctl [flags]

VERSION:
	3.4.23

API VERSION:
	3.4


COMMANDS:
	alarm disarm		Disarms all alarms
	alarm list		Lists all alarms
	auth disable		Disables authentication
	auth enable		Enables authentication
	check datascale		Check the memory usage of holding data for different workloads on a given server endpoint.
	check perf		Check the performance of the etcd cluster
	compaction		Compacts the event history in etcd
	completion bash		Generate the autocompletion script for bash
	completion fish		Generate the autocompletion script for fish
	completion powershell	Generate the autocompletion script for powershell
	completion zsh		Generate the autocompletion script for zsh
	defrag			Defragments the storage of the etcd members with given endpoints
	del			Removes the specified key or range of keys [key, range_end)
	elect			Observes and participates in leader election
	endpoint hashkv		Prints the KV history hash for each endpoint in --endpoints
	endpoint health		Checks the healthiness of endpoints specified in `--endpoints` flag
	endpoint status		Prints out the status of endpoints specified in `--endpoints` flag
	get			Gets the key or a range of keys
	help			Help about any command
	lease grant		Creates leases
	lease keep-alive	Keeps leases alive (renew)
	lease list		List all active leases
	lease revoke		Revokes leases
	lease timetolive	Get lease information
	lock			Acquires a named lock
	make-mirror		Makes a mirror at the destination etcd cluster
	member add		Adds a member into the cluster
	member list		Lists all members in the cluster
	member promote		Promotes a non-voting member in the cluster
	member remove		Removes a member from the cluster
	member update		Updates a member in the cluster
	migrate			Migrates keys in a v2 store to a mvcc store
	move-leader		Transfers leadership to another etcd cluster member.
	put			Puts the given key into the store
	role add		Adds a new role
	role delete		Deletes a role
	role get		Gets detailed information of a role
	role grant-permission	Grants a key to a role
	role list		Lists all roles
	role revoke-permission	Revokes a key from a role
	snapshot restore	Restores an etcd member snapshot to an etcd directory
	snapshot save		Stores an etcd node backend snapshot to a given file
	snapshot status		Gets backend snapshot status of a given file
	txn			Txn processes all the requests in one transaction
	user add		Adds a new user
	user delete		Deletes a user
	user get		Gets detailed information of a user
	user grant-role		Grants a role to a user
	user list		Lists all users
	user passwd		Changes password of user
	user revoke-role	Revokes a role from a user
	version			Prints the version of etcdctl
	watch			Watches events stream on keys or prefixes

OPTIONS:
      --cacert=""				verify certificates of TLS-enabled secure servers using this CA bundle
      --cert=""					identify secure client using this TLS certificate file
      --command-timeout=5s			timeout for short running command (excluding dial timeout)
      --debug[=false]				enable client-side debug logging
      --dial-timeout=2s				dial timeout for client connections
  -d, --discovery-srv=""			domain name to query for SRV records describing cluster endpoints
      --discovery-srv-name=""			service name to query when using DNS discovery
      --endpoints=[127.0.0.1:2379]		gRPC endpoints
  -h, --help[=false]				help for etcdctl
      --hex[=false]				print byte strings as hex encoded strings
      --insecure-discovery[=true]		accept insecure SRV records describing cluster endpoints
      --insecure-skip-tls-verify[=false]	skip server certificate verification (CAUTION: this option should be enabled only for testing purposes)
      --insecure-transport[=true]		disable transport security for client connections
      --keepalive-time=2s			keepalive time for client connections
      --keepalive-timeout=6s			keepalive timeout for client connections
      --key=""					identify secure client using this TLS key file
      --password=""				password for authentication (if this option is used, --user option shouldn't include password)
      --user=""					username[:password] for authentication (prompt if password is not supplied)
  -w, --write-out="simple"			set the output format (fields, json, protobuf, simple, table)

```


# Conclusion
**kubectl get系のコマンドは、このetcdの結果をwrapして表示していると思えばよさそう** ですね。例えば `kubectl get ns` は `etcdctl get --prefix /registry/namespaces/ --keys-only` の結果をリストしてると思っていい気がします。

勉強になったぜ〜〜〜