KubernetesでServiceAccountを作成してcurlで情報を取得する

普段は kubectl を使って manifest file を apply したりするけど今回は curl で情報を取得したくなった。

全体的な流れ

  1. ClusterRole を作成する
  2. ServiceAccount を作成
  3. 1.で作成した ClusterRole と 2.で作成したServiceAccountを紐づける
  4. apply
  5. curl に必要な api url, tokenを取り出す
  6. curl

実際にやってみる

1. ClusterRole を作成する

今回は特定の namespace ではなく cluster にまたがってアクセスしたかったので Role ではなく ClusterRole を使用しています。

manifest ファイルはこんな感じ

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: hoge-role
rules:
  - apiGroups: [""]
    resources: ["*"]
    verbs: ["list", "watch", "get"]

2. ServiceAccount を作成する

apiVersion: v1
kind: ServiceAccount
metadata:
  name: hoge-user
  namespace: kube-system

3. 1.で作成したClusterRole と 2.で作成したServiceAccountを紐づける

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: hoge-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: hoge-role
subjects:
- kind: ServiceAccount
  name: hoge-user
  namespace: kube-system

4. apply

最終的なマニフェストファイルがこちら

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: deploy-role
rules:
  - apiGroups: [""]
    resources: ["*"]
    verbs: ["list", "watch", "get"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: hoge-user
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: hoge-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: hoge-role
subjects:
- kind: ServiceAccount
  name: hoge-user
  namespace: kube-system

あとは kubectl apply -f ~~~ で終わり

5. curl に必要な api url, tokenを取り出す

まずは API URL

$ export CURRENT_CONTEXT=$(kubectl config current-context)
$ export CURRENT_CLUSTER=$(kubectl config view -o go-template="{{\$curr_context := \"$CURRENT_CONTEXT\" }}{{range .contexts}}{{if eq .name \$curr_context}}{{.context.cluster}}{{end}}{{end}}")
$ export API_URL=$(echo $(kubectl config view -o go-template="{{\$cluster_context := \"$CURRENT_CLUSTER\"}}{{range .clusters}}{{if eq .name \$cluster_context}}{{.cluster.server}}{{end}}{{end}}"))

TOKEN はこれ

$ export TOKEN=`echo $(kubectl get secret -n kube-system -o go-template='{{index .data "token" }}' $(kubectl get sa hoge-user -n kube-system -o go-template="{{range .secrets}}{{.name}}{{end}}")) | base64 --decode`

6. curl

$ curl ${API_URL}/api  --header "Authorization: Bearer $TOKEN" --insecure

curl ではなく kubectl を使う

# certificate authority data を出力する
$ export BASE64_CA=$(echo $(kubectl get secret -n kube-system -o go-template='{{index .data "ca.crt" }}' $(kubectl get sa hoge-user -n kube-system -o go-template="{{range .secrets}}{{.name}}{{end}}")))

# clusterの設定を作成
$ kubectl config set-cluster hoge --server=${API_URL} 
$ kubectl config set clusters.hoge.certificate-authority-data ${BASE64_CA}

# 認証情報の作成
$ kubectl config set-credentials hoge-user --token=${TOKEN}

# コンテキストの作成
$ kubectl config set-context hoge-ctx --cluster=hoge --user=hoge-user
$ kubectl config use-context hoge-ctx