Kubernetes

kubectlを使ったDeploymentの作成

minikube で Kubernetes 環境構築 ( Hyper-V on Windows 10 )

kubectlコマンドの使い方(1.2)

DeploymentとServiceをyamlファイルで定義する

Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what?

目次:

Pod

Podの中には1つ以上のコンテナを配置する。 基本的にPod:コンテナは1:1で作成して問題ないが、コンテナ間でストレージの共有をしたい場合などは同じPodに複数コンテナを配置する。

  • コンテナ 1 つ: Pod1 つに対してコンテナ 1 つは一番標準的なパターン
  • コンテナ 2 つ以上: 同一Pod内のコンテナは 2 種類のリソースを共有する。
    • ネットワーク localhost経由で他のコンテナに接続できる。
    • ストレージ コンテナ間でストレージを共有できる。

Pod自身は自己修復しない。 Podの修復はController(例えばDeployment)の仕事。

定義ファイル

Podの定義。 Pod用に.yamlファイルを書くことはあまりない(はず)。 ※Deployment.yamlファイルにPodテンプレートを書く場所があるので、そこに直接書く形になる。

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
    - name: myapp-container
      image: busybox
      command: ["sh", "-c", "echo Hello Kubernetes! && sleep 3600"]

ReadinessProbe: コンテナがREADYになる条件を指定する

readinessProbeを使う DBコンテナが立ち上がってからアプリのコンテナを立ち上げたいときなどに。

spec:
  containers:
    ...
    # 3000番ポートにつながった時にREADY状態とする場合の例
    readinessProbe:
      tcpSocket:
        port: 3000
      initialDelaySeconds: 5
      periodSeconds: 5

10秒後に必ずREADYになる例

readinessProbe:
  initialDelaySeconds: 10
  periodSeconds: 10
  exec:
    command:
      - "true"

VolumeMounts: ストレージの共有

次のようなことができる。

  • ホストPCのファイルをPodコンテナへ送りたいとき
  • Podコンテナ間でディレクトリを共有したいとき

例:

apiVersion: extensions/v1beta1
kind: Deployment
spec:
  template:
    spec:
      volumes:
        # ConfigMapを利用してファイル共有
        - name: shared-configmap-r
          configMap:
            name: my-configmap
        - name: shared-configmap-rw
          emptyDir: {}
        # 空ディレクトリを作成してファイル共有
        - name: shared-empty
          emptyDir: {}
      initContainers:
        # ConfigMapを利用する場合にファイルの書き込み権限を与えるためにInitContainerを利用する
        - name: copy-file
          image: ellerbrock/alpine-bash-curl-ssl
          command: ['sh', '-c', 'cp -R /pre/* /install']
          volumeMounts:
            - name: shared-configmap-r
              mountPath: /pre/shared-configmap
            - name: shared-configmap-rw
              mountPath: /install/shared-configmap
      containers:
        - name:  my-container
          image: 'ellerbrock/alpine-bash-curl-ssl'
          volumeMounts:
            # ここのファイルはコンテナから読み取り専用
            - name: shared-configmap-r
              mountPath: /shared-configmap-r
            # ここのファイルはコンテナから読み書き可能
            - name: shared-configmap-rw
              mountPath: /shared-configmap-rw
            # ここのファイルはコンテナから読み書き可能
            - name: shared-empty
              mountPath: /shared-empty

例にあるように、ConfigMapをマウントしコンテナから書き込みしたい場合はInitContainerを経由する必要がある。

Deployment

https://kubernetes.io/docs/concepts/workloads/controllers/deployment/

複数のPodを管理するもの。

定義ファイル

設定値の詳細はココ

apiVersion: apps/v1 # 固定値
kind: Deployment # 固定値
metadata:
  name: nginx-deployment # Deploymentの名前
  labels:
    app: nginx # Podテンプレートと合わせる?
spec:
  # レプリカ数
  replicas: 3

  # デプロイメントの履歴の数(デフォルト10)
  revisionHistoryLimit: 1

  # このDeployamentが管理するPodをどう見つけるかの定義
  # 基本はPodテンプレートの`labels`と同じにすれば良い
  selector:
    matchLabels:
      app: nginx

  # Podテンプレート
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.7.9
          # コンテナが開けるポート
          ports:
            - containerPort: 80

initContainers: Pod起動前に実行する処理を書く

ref: Init Containers

PodはinitContainerという初期化専用のコンテナを定義できる。 例えば、「Podが依存しているDBが起動するまで待ちたい」というような場合に便利。

ref:

例:

spec:
  template:
    spec:
      initContainers:
        - name: check-ready
          image: alpine:3.9
          # Podコンテナを起動する前に、db:3306に接続できるまで待機する
          # db側でredinessProbeを指定しておけば、dbがREADYになるまでncコマンドは成功しない
          command: ['sh', '-c', 'until nc -z db 3306 ; do sleep 1; done;']
      containers:
        - name:  app
          image: '***'

Service

Podは壊れたり生まれたりする(そのたびに IP アドレスが変わる)ため、外部からPod(API など)へ接続したいときに困る。 Serviceを介して外部から接続できるようにすると、この問題を解決できる。

定義ファイル

kind: Service
apiVersion: v1
metadata:
  name: my-service # Serviceの名前。他のPodから`http://my-service`で接続できる
spec:
  # デフォルトは`ClusterIP`(クラスタ内部のみ接続可能)
  # `NodePort`にすると、localhost経由でホストPCから接続できる。
  type: ClusterIP

  # どのPodを対象にするか
  selector:
    app: MyApp

  # 公開するポート
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  # 複数ポートを指定する場合は`name`(半角英数字or'-')が必須
  # ports:
  # - name: http
  #   protocol: TCP
  #   port: 80
  #   targetPort: 9376
  # - name: https
  #   protocol: TCP
  #   port: 443
  #   targetPort: 9377

type: NodePort: ホスト PC からlocalhost経由でServiceに接続する

type: NodePortを指定するとホストPCのポート経由でサービスに接続できる。 ローカルPCで動作確認したい場合などに便利。

spec:
  type: NodePort
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080 # 30000-32767の範囲で指定できる。省略した場合はランダムで割り当てられる

動作確認。 以下は、3000 番ポートに接続すると"Hello World!"を返す API のServiceの場合の例。

# Service作成
kubectl apply -f [ファイル名].yaml
# Serviceのポートを調べる
kubectl get services

# ※出力例。この場合は`localhost:32660`で、`Service`の3000番ポートに接続できる
# NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
# app-service   NodePort    10.99.150.192   <none>        3000:32660/TCP   11m
# kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP          10d

# 動作確認
curl localhost:32660
# -> Hello World!

Configure Map

Pod の/etc/config/直下に Key(ファイル名):Value(ファイル内容)の形式で保存される。

# yamlから作成
kubectl create -f config.yaml
# 確認
kubectl get configmap
# 確認(詳細)
kubectl describe configmap test-config

# Podを起動
kubectl create -f pod.yaml
# shを起動してConfigMapのValueを確認
kubectl exec -it test-pod sh
/ # cat /etc/config/test1
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-config
data:
  # key, value形式で設定を記述する
  test1: "11111"
  test2: "22222"
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: example-container
      image: busybox
      # あとからexecで操作するためsleepさせておく
      command: ["sleep", "3600"]
      # ConfigMapをマウントする
      volumeMounts:
        - name: config-volume
          mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        # ConfigMapリソースの名前を指定する(kubectl get configmapで得られる名前)
        name: test-config

ConfigMapを使ってファイルをマウントする

helmを使うと簡単にファイルをPodに置ける。

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-files
  namespace: my-namespace
data:
{{ (.Files.Glob "config/my-files/*").AsConfig | indent 2 }}

Podの初期化

https://qiita.com/petitviolet/items/41aa9abe106a29ba4667

Pod内の複数のコンテナでファイルを共有する

volumesemptyDirを指定するとできる。

spec:
  template:
    spec:
      volumes:
        - name: shared-volume
          emptyDir:
      containers:
      - name: c1
        image: alpile
        command: ["sh","-c"]
        args: ["while true; do sleep 1; done"]
        volumeMounts:
          - name: shared-volume
            mountPath: /hoge/shared # ここのディレクトリは勝手に生成される
      - name: c2
        image: alpile
        command: ["sh","-c"]
        args: ["while true; do sleep 1; done"]
        volumeMounts:
          - name: shared-volume
            mountPath: /hoge/shared # ここのディレクトリは勝手に生成される

イメージのpullを強制する

デフォルトではリモートのイメージが変わったとしてもローカルに同名のイメージがあればそれを使ってしまう。 imagePullPolicy: Alwaysを指定すると、常にリモートのイメージをpullするようになる。

spec:
  template:
    spec:
      containers:
        - name: c1
          image: alpine
          imagePullPolicy: Always  ## この行を追加

Volumeマウント

ローカルのファイルをPodに持っていける。

(例えば)設定ファイルを書く config-test.yaml

aaa: 1
bbb: 2
ccc: 3

ファイルからConfigMapを生成する。

kubectl create configmap config-test --from-file=config-test.yaml
# 生成されたconfigmapの確認
kubectl get configmap config-test -o yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myDeployment
  labels:
    name: myDeployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: myDeployment
    spec:
      # ここで任意の名前にConfigMapを紐づける
      volumes:
      - name: hoge
        configMap:
          name: config-test
      containers:
        - name: my_container
          image: alpine
          # `volumes`で定義した名前を、コンテナのパスと紐づける
          volumeMounts:
          - name: hoge
            mountPath: /etc/config

これで、コンテナの/etc/configconfig-test.yamlを持っていける。

configMapをマウントする場合はコンテナ側からは常に読み取り専用となる。 書き込みたい場合はinitContainerを利用してホスト->InitContainer(configmap)->コンテナ(emptyDir)というようにマウントすれば良い。

コマンドの上書き

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myDeployment
  labels:
    name: myDeployment
spec:
  template:
    spec:
      containers:
        - name: my_container
          image: alpine
          # 元のエントリーポイントを上書きする
          command:
            - echo
            - "hello"

複数コマンドを実行する例:

command: ["sh","-c"]
args: ["echo 'hoge'; /entory-point.sh"]

エントリーポイントのshell実行前に処理を差し込みたいときなどに使える。

便利コマンド

何もしない。デバッグ時にコンテナに入って何かしたいときに使える。

command: ["sh","-c"]
args: ["while true; do sleep 1; done"]

rollout

指定したデプロイメントが完了するまで待つ。

kubectl rollout deployment/[deploymentの名前]

デプロイメントのエラー解析

Failed Deployment

kubectl describe deployment [deployment name] -o yaml

起動時に複数コマンドを実行

containers:
  command: ["/bin/sh","-c"]
  args: ["command one; command two && command three"]

初期化処理をエントリーポイントとは別で実行

postStartを使う。 バックグラウンド実行されるのでechoしてもkubectl logsで見れないので注意。代わりにecho "hoge" > /usr/share/messageとかする。 https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/

apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: nginx
    lifecycle:
      postStart:
        exec:
          # `mkdir hoge`を実行する
          command:
            - mkdir
            - hoge

プライベートレジストリのイメージを指定する

spec:
  imagePullSecrets:
      - name: 'docker-my-registory'

Pod の中に入る

docker exec的な。

# PodのNAMEを確認
kubectl get pod
# 入る
kubectl exec [pod's name] -it bash

コマンド

リソースの表示

kubectl get pods
kubectl get pods -o wide

# podの名前の一覧のみ取得
kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'

PodのコンテナへホストPCのファイルをコピー

# kubectl cp [ホストPCのファイルパス] [namespace]/[PodId]:[コンテナのファイルパス]
kubectl cp ./hoge.txt mynamespace/aaa-6db96b6fd9-l9tr6://aaa.txt

# ディレクトリ配下をすべてコピー
# 末尾スラッシュのありなしは重要
kubectl cp ./fuga mynamespace/aaa-6db96b6fd9-l9tr6://fuga/

Windowsの場合はコンテナのファイルパスは//から始めないとエラーになるので注意。

bash セッション開始

kubectl exec -ti $POD_NAME bash

# bashがないときは直接コマンドを書いたり
kubectl exec -ti $POD_NAME ls
# bashを入れる
kubectl exec -ti $POD_NAME apk add bash
# リソース一覧
kubectl get
# リソースの詳細表示
kubectl logs
# Pod内のコンテナのログ表示
kubectl logs
# Pod内のコンテナでコマンド実行
kubectl exec

podのイベントを確認する

readinessProbeが失敗したときのログとかが見れる。

kubectl describe pod [pod_name]

podが起動する(READYになる)まで待つ

kubectl rollout status [pod_name]

Docker for Windows で試す

参考 https://qiita.com/h-r-k-matsumoto/items/68f694650029ddf7351d

minikube start

Tips

デプロイメントオブジェクトの各フィールドの説明を表示する

kubectl explain deployment
kubectl explain deployment --recursive
kubectl explain deployment.metadata.name

サービスのエンドポイントを取得

kubectl describe services <SERVICE> | grep Endpoints

デプロイメントを一時的に止める

レプリカ数を0にする。

kubectl scale --replicas=0 deployment/<DEPLOYMENT_NAME>

可変なPodのコンテナ名を取得する

# 0番目のPodIdを取得する
kubectl get pods -o jsonpath="{.items[0].metadata.name}"

# 特定のPodIdを取得する
kubectl get pods --selector name=[Podのmetadata.nameの設定値] -o jsonpath="{.items[0].metadata.name}"

これを利用するとPodコンテナに対する操作が簡単にできる

# Podコンテナのログを表示
kubectl logs $(kubectl get pods --selector name=[Podのmetadata.nameの設定値] -o jsonpath="{.items[0].metadata.name}")

# Podコンテナでshセッション開始
kubectl exec -it `kubectl get pods --selector name=$1 -o jsonpath="{.items[0].metadata.name}"` sh

便利なもの

デバッグ用にPodを生成

ellerbrock/alpine-bash-curl-sslbashcurlが使える軽量 Docker イメージ。 API の接続テストなどに使える。

# tmp-podデプロイメントを生成
# `--rm`をつけるとbashセッション終了時にデプロイメントを削除できる
winpty kubectl run -it --rm tmp-pod --image=ellerbrock/alpine-bash-curl-ssl bash

# 例:Serviceの接続テスト
curl app-service:3000

kubectl get

リソースを表示する。

kubectl get all
kubectl get pods

kubectl logsなどでpodの長い名前を毎回入れるのが面倒なとき用。

klog() {
    # $1: string which containts part of pod's name.
    # $c: container name. use if 2 or more containers in pod.
    [ -z $2  ] && c="" || c="-c $2";
    kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}' | grep app | xargs kubectl logs -f $c
}

# 使い方
klog app
klog app mysql

kubectl port-forward

# podの80番をホストの8080番にフォワードする
kubectl port-forward pod-1msdanjksdf3 8080:80

kubectl exec

Podコンテナ内でコマンドを実行する。 オプションを使いたい場合はコマンドの直前に--を書く。

# 基本
kubectl exec -it pod-a837fam3nfa3 sh

# 指定したPodで指定したコマンドを実行する
kubectl exec -it `kubectl get pods --selector name=<podに設定したlabels.name> -o jsonpath="{.items[0].metadata.name}"` <command> ;

# podの名前を部分一致で指定してコマンドを実行する
kubectl exec -it `kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}' | grep $1` bash

# MySQLのクエリを実行
kubectl exec -it `kubectl get pods --selector name=hoge -o jsonpath="{.items[0].metadata.name}"` -- mysql -u root -ppassword -e "sh
ow databases;"

# MySQLのクエリを0.5秒おきに実行
kubectl exec -it `kubectl get pods --selector name=<metadata.name> -o jsonpath="{.items[0].metadata.name}"` -- bash -c 'while :; do mysql -u root -ppassword -e "select * from <db>.<table>"; sleep 0.5 ; done'

# Kafkaトピックを作成
kubectl run -ti --image=gcr.io/google_containers/kubernetes-kafka:1.0-10.2.1 createtopic --restart=Never --rm -- kafka-topics.sh --create \
--topic test \
--zookeeper zk-cs.my-kafka.svc.cluster.local:2181 \
--partitions 1 \
--replication-factor 1

# Kafkaメッセージを監視

# Kafkaメッセージ送信
kubectl run -ti --image=gcr.io/google_containers/kubernetes-kafka:1.0-10.2.1 produce --restart=Never --rm -- kafka-console-producer.sh --topic test --broker-list kafka-0.kafka-hs.my-kafka.svc.cluster.local:9093 done;

# jsonファイルの中身をkafkaのメッセージにして送信
cat hoge.json | jq -c . | xargs -I {} kubectl run -ti --image=gcr.io/google_containers/kubernetes-kafka:1.0-10.2.1 produce --restart=Never --rm -- kafka-console-producer.sh --topic test --broker-list kafka-0.kafka-hs.my-kafka.svc.cluster.local:9093 done;

すべてのリソース(Deployment, Service, ConfigMap)を一括削除

kubectl delete deployments --all
kubectl delete services --all
kubectl delete configmaps --all
kubectl delete namespaces --all

# 一行で
kubectl delete deployments --all; kubectl delete services --all; kubectl delete configmaps --all; kubectl delete namespaces --all;

動くサンプル

Pods

  • ポート 3000 で"Hello World!"を出力する API
  • API に curl を送信するためのコンテナ

Services

  • API を外部に公開するためのサービス

api.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
  labels:
    app: api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: api
          image: hatakoya/hello-express
          ports:
            - containerPort: 3000
        # 環境変数
        env:
          - name: HOGE
            value: "123" # !! 数値は""で囲わないと謎エラーがでる !!

Namespace

namespaceを使うと、複数リソースの一括削除などができる。 デフォルトのnamespaceを設定しておくと便利。

# デフォルトnamespaceの確認
kubectl config view | grep namespace

# デフォルトnamespaceを設定
kubectl config set-context $(kubectl config current-context) --namespace=[namespaceの名前]

# namespaceを作成
kubectl create namespace [namespaceの名前]

# 一時的に違うnamespaceでコマンドを実行
kubectl -n mynamespace get all

サンプル

Couchbase

deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-couch
spec:
  template:
    spec:
      volumes:
        - name: scripts
          configMap:
            name: my-couch-config
      containers:
        - name: my-couch
          image: couchbase
          lifecycle:
            postStart:
              exec:
                command: ["bash", "/etc/scripts/wait_and_insert_data.sh"]
          ports:
            - containerPort: 8091
            - containerPort: 8092
            - containerPort: 8093
            - containerPort: 8094
            - containerPort: 11210
          readinessProbe:
            tcpSocket:
              port: 8091
            initialDelaySeconds: 5
            periodSeconds: 2
          volumeMounts:
            - name: scripts
              mountPath: /etc/scripts

wait_and_insert_data.sh

#!/bin/sh

echo "wait..."
until curl localhost:8091 ; do
   sleep 3
done
echo "ready to start"

# query, index: N1QLの実行に必要
couchbase-cli cluster-init \
    --cluster=`hostname -i` \
    --cluster-username=Administrator \
    --cluster-password=password \
    --services data,query,index

sleep 1

couchbase-cli bucket-create \
    --cluster=`hostname -i` \
    --username=Administrator \
    --password=password \
    --bucket=users \
    --bucket-type=couchbase \
    --bucket-ramsize=100 \
    --enable-flush=1

sleep 3

# SDKから操作するためにはBucketに対応するユーザが必要
couchbase-cli user-manage \
    --cluster=`hostname -i` \
    --username=Administrator \
    --password=password \
    --set \
    --roles=admin \
    --auth-domain=local \
    --rbac-username=users \
    --rbac-password=password
kubectl create configmap my-couch-config --from-file=wait_and_insert_data.sh
kubectl apply -f deployment.yaml

Springアプリケーションを動かす

https://dzone.com/articles/quick-guide-to-microservices-with-kubernetes-sprin

FAQ

kubectl get podsで pending から進まない

エラーメッセージを調べる

kubectl describe pods

ConfigMap "" is invalid: metadata.name: Required value: name or generateName is required

helmテンプレートをnameに使ったときに起こるよう。 printfを使う場合は一度変数に格納し、その変数を参照するようにすると正常に動く。 もちろん値を直接nameに書いてもいい。

NG:

metadata:
    name: {{ printf "%s-%s-config" my app }}

OK:

{{- $name := printf "%s-%s-config" my app -}}
metadata:
    name: {{ $name }}

Proxyを経由しないでPod間通信

no_proxyにサービスの名前を追加する。

export no_proxy=127.0.0.1,localhost,192.168.*,my-app

Pod 間の通信

service で名前解決

https://varu3.hatenablog.com/entry/2018/05/24/200311

Permission denied

./***.shじゃなくbash ***.shで実行する。

sudoを入れる。

apt-get update
apt-get install -y sudo

Helm

https://github.com/helm/helm

Qiitaの日本語記事: (Kubernetes: パッケージマネージャHelm )[https://qiita.com/tkusumi/items/12857780d8c8463f9b9c]

インストール

管理者権限でPowerShellを立ち上げて実行。

choco install kubernetes-helm

初期化。

helm init

テンプレート

チャートのディレクトリ構成は次のようになる。

mychart/
  Chart.yaml
  values.yaml
  charts/
  templates/
  ...

次のコマンドでチャートのひな形を生成する。

helm create mychart
cd mychart

# ゼロから作業するときは最初に生成されたtemplatesを消す
rm -fr templates/*.*

次のコマンドでtemplates配下の.yamlで定義したリソースをまとめて生成できる。

helm install .

# release nameを指定する場合
helm install --name my-release .

# 既存のチャートを削除して再生成
helm install . --name my-release --replace

テンプレートの.yamlを編集したら次のコマンドでコンテナを作りなおす。

helm del hoge --purge
helm install . --name hoge

FAQ

作業ディレクトリを変えたらhelm installできなくなった

新しい作業ディレクトリに移動してからhelm initする。

helm init --upgrade

Web UI(ダッシュボード)

Web UIでリソース管理ができる。 https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/

導入

ダッシュボードUIをデプロイする。

kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended/kubernetes-dashboard.yaml

ダッシュボードにアクセスできるようにする

kubectl proxy

http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/ でアクセスできる。

次に、認証のためにベアラトークンを取得する。 ref: https://github.com/kubernetes/dashboard/wiki/Creating-sample-use:

次の2つのyamlファイル作成し、それぞれkubectl apply -fでデプロイする。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system

ベアラトークンを表示する。

kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')

Name: admin-user-token-***のtokenをコピペしてダッシュボードのベアラトークンに入力する。

FAQ

EXECするとconnection closedになる

Podの中にbashが入っていないコンテナが1つでもあるとダメらしい。

spec:
  containers:
    - name: my-container
      image: apline
      command: ["sh","-c"]
      args: ["apk add bash; while true; do sleep 1; done"]

bashが入っていないコンテナに、最初にbashをインストールするようにしてあげると動く。

VSCode拡張

  • vscode-helm

Pod強制削除

kubectl deleteしたはずなのにSTATUSがTerminatingのまま変わらないときなどに。

kubectl delete pod [pod name] --grace-period=0 --force

DNS問題

https://kubernetes.io/docs/tasks/administer-cluster/dns-debugging-resolution/

kdebug

nslookup google.com
nslookup kubernetes.default
# service
nslookup my-service