kakakakakku blog

Weekly Tech Blog : Keep on Learning 👍

GitHub リポジトリのスター数を時系列グラフとして取得できる「starcharts」

「starcharts」を使うと GitHub リポジトリの「スター数⭐」を時系列グラフ(SVG フォーマット)として取得できる.GitHub リポジトリの README.md に載せることもできて便利!

github.com

kakakakakku/redash-hands-on を例にすると

「starcharts」の URL (starchart.cc) に kakakakakku/redash-hands-on のようにリポジトリ情報を追加すれば OK!以下に載せたような時系列グラフを取得できる.少しずつ増えてて 250 スター⭐までもう少し!

https://starchart.cc/kakakakakku/redash-hands-on.svg

関連サービス

時系列グラフは必要なく現在のスター数⭐を表示するだけで良いなら「Shields.io」も使える!関連サービスとして載せておく.

kakakakakku.hatenablog.com

PodDisruptionBudget (PDB) と kubectl drain --timeout オプションを組み合わせる

Kubernetes で PodDisruptionBudget (PDB) を使うと,kubectl drain コマンドでノードをドレインするときなどに Kubernetes クラスター内に起動しておく「最低限必要な Pod 数」を設定できる.よって,Kubernetes を使ったサービスの可用性を高める戦略としてよく使われる.

以下のドキュメントを読むと「自発的な混乱 (Voluntary Disruptions)」と「非自発的な混乱 (Involuntary Disruptions)」という表現があり,既に紹介した「ノードをドレインするとき」は,管理者が運用として「自発的に」行うため「自発的な混乱 (Voluntary Disruptions)」に該当する.例えば「カーネルパニック (a kernel panic)」は突発的に発生するため「非自発的な混乱 (Involuntary Disruptions)」に該当する.

kubernetes.io

前提 : kubectl drain コマンド

今回使う kubectl drain コマンドの基本的な流れは以下の記事にまとめてある.前提として合わせて読んでもらえると良いかと!

kakakakakku.hatenablog.com

検証内容 : kubectl drain コマンド + PDB + リソース不足

今回は「kubectl drain コマンドでノードをドレインしたときに PodDisruptionBudget (PDB) に設定した最低限必要な Pod 数を満たすリソースがノードに不足していた場合」という少し複雑な状況での挙動を検証する.検証する前の予想としては「デッドロック的な挙動になる?」もしくは「タイムアウト的な挙動になる?」と考えていた.

検証環境

今回は kind を使って,Mac 上に検証用の Kubernetes クラスター(複数ノード構成)を構築する.バージョンは v1.19.1 を使う.各ノードは「1 GiB メモリ」を使えるようにしてある.

$ kubectl get nodes
NAME                 STATUS   ROLES    AGE     VERSION
kind-control-plane   Ready    master   4m      v1.19.1
kind-worker          Ready    <none>   3m30s   v1.19.1
kind-worker2         Ready    <none>   3m30s   v1.19.1

$ kubectl describe nodes kind-worker | grep -A 6 Allocatable:
Allocatable:
  cpu:                2
  ephemeral-storage:  41021664Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             989764Ki
  pods:               110
  
$ kubectl describe nodes kind-worker2 | grep -A 6 Allocatable:
Allocatable:
  cpu:                2
  ephemeral-storage:  41021664Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             989764Ki
  pods:               110

そして「メモリ 300 MiB (requests.memory: 300Mi)」を要求する Pod「6個」を Deployment 経由で作る.以下の kubectl get pods コマンドの結果からもわかる通り,各ノードに「3 Pod ずつ」デプロイされている.

$ kubectl apply -f deployment.yaml
deployment.apps/sandbox-drain-timeout-nginx created

$ kubectl get pods -o custom-columns=Name:metadata.name,STATUS:status.phase,NODE:spec.nodeName | sort -k 3
Name                                          STATUS    NODE
sandbox-drain-timeout-nginx-f57cbc6cb-94z9s   Running   kind-worker
sandbox-drain-timeout-nginx-f57cbc6cb-gcvh8   Running   kind-worker
sandbox-drain-timeout-nginx-f57cbc6cb-kxw2l   Running   kind-worker
sandbox-drain-timeout-nginx-f57cbc6cb-8cxxt   Running   kind-worker2
sandbox-drain-timeout-nginx-f57cbc6cb-vksh8   Running   kind-worker2
sandbox-drain-timeout-nginx-f57cbc6cb-z5f6n   Running   kind-worker2

構成をザッと図解すると以下のようになる.

f:id:kakku22:20210224003614p:plain

検証 1 : PDB なしで kubectl drain コマンドを実行する

まずは PodDisruptionBudget (PDB) なしで kubectl drain コマンドを実行して kind-worker ノードをドレインする.すると kind-worker ノードで起動していた Pod「3個」が削除 (eviction) される.そして kind-worker ノードのステータスは SchedulingDisabled になり,新しく Pod をスケジューリングしないようになる.今回 kind-worker2 ノードにリソース(メモリ)が不足しているため,スケジューリングされている Pod は全て Pending になっている.

$ kubectl drain kind-worker --ignore-daemonsets
node/kind-worker cordoned
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-94z9s
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-kxw2l
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-gcvh8
pod/sandbox-drain-timeout-nginx-f57cbc6cb-gcvh8 evicted
pod/sandbox-drain-timeout-nginx-f57cbc6cb-kxw2l evicted
pod/sandbox-drain-timeout-nginx-f57cbc6cb-94z9s evicted
node/kind-worker evicted

$ kubectl get nodes
NAME                 STATUS                     ROLES    AGE   VERSION
kind-control-plane   Ready                      master   12m   v1.19.1
kind-worker          Ready,SchedulingDisabled   <none>   11m   v1.19.1
kind-worker2         Ready                      <none>   11m   v1.19.1

$ kubectl get pods -o custom-columns=Name:metadata.name,STATUS:status.phase,NODE:spec.nodeName | sort -k 3
Name                                          STATUS    NODE
sandbox-drain-timeout-nginx-f57cbc6cb-f6qth   Pending   <none>
sandbox-drain-timeout-nginx-f57cbc6cb-nvlkf   Pending   <none>
sandbox-drain-timeout-nginx-f57cbc6cb-nzpbt   Pending   <none>
sandbox-drain-timeout-nginx-f57cbc6cb-8cxxt   Running   kind-worker2
sandbox-drain-timeout-nginx-f57cbc6cb-vksh8   Running   kind-worker2
sandbox-drain-timeout-nginx-f57cbc6cb-z5f6n   Running   kind-worker2

構成をザッと図解すると以下のようになる.

f:id:kakku22:20210224003647p:plain

次の検証をするためにノードと Deployment を同じ構成に戻しておく.

$ kubectl uncordon kind-worker

$ kubectl delete -f deployment.yaml

$ kubectl apply -f deployment.yaml

$ kubectl get pods -o custom-columns=Name:metadata.name,STATUS:status.phase,NODE:spec.nodeName | sort -k 3
Name                                          STATUS    NODE
sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp   Running   kind-worker
sandbox-drain-timeout-nginx-f57cbc6cb-hxz7h   Running   kind-worker
sandbox-drain-timeout-nginx-f57cbc6cb-xdvc9   Running   kind-worker
sandbox-drain-timeout-nginx-f57cbc6cb-2kq98   Running   kind-worker2
sandbox-drain-timeout-nginx-f57cbc6cb-m9cbb   Running   kind-worker2
sandbox-drain-timeout-nginx-f57cbc6cb-vcwjv   Running   kind-worker2

検証 2 : PDB ありで kubectl drain コマンドを実行する

次は PodDisruptionBudget (PDB) ありで kubectl drain コマンドを実行して kind-worker ノードをドレインする.まず,PodDisruptionBudget (PDB) のマニフェストを作る.今回は Deployment 経由で作られる Pod「6個」に対して「最低限必要な Pod 数 (minAvailable)」を「4」に設定している.他には maxUnavailable という設定値も使える.

apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: sandbox-drain-timeout-pdb
spec:
  minAvailable: 4
  selector:
    matchLabels:
      app: nginx

マニフェストを適用しておく.

$ kubectl apply -f pdb.yaml
poddisruptionbudget.policy/sandbox-drain-timeout-pdb created

$ kubectl get poddisruptionbudgets
NAME                        MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
sandbox-drain-timeout-pdb   4               N/A               2                     40s

さっそく kubectl drain コマンドを実行すると,「検証 1」と同じように kind-worker ノードで起動していた Pod「3個」が削除 (eviction) される.しかし PodDisruptionBudget (PDB) に minAvailable: 4 と設定しているため,Pod(今回は sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp)を削除 (eviction) することができず,自動的にリトライをしている.以下の結果では Cannot evict pod というメッセージが繰り返し表示されていて,ターミナルも待機状態のままになっている.

$ kubectl drain kind-worker --ignore-daemonsets
node/kind-worker cordoned
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-hxz7h
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-xdvc9
error when evicting pod "sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp
error when evicting pod "sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp
error when evicting pod "sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
pod/sandbox-drain-timeout-nginx-f57cbc6cb-hxz7h evicted
pod/sandbox-drain-timeout-nginx-f57cbc6cb-xdvc9 evicted
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp
error when evicting pod "sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp
error when evicting pod "sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.

(中略)

evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp
error when evicting pod "sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.

(続く...)

$ kubectl get pods -o custom-columns=Name:metadata.name,STATUS:status.phase,NODE:spec.nodeName | sort -k 3
Name                                          STATUS    NODE
sandbox-drain-timeout-nginx-f57cbc6cb-fr9cq   Pending   <none>
sandbox-drain-timeout-nginx-f57cbc6cb-pntw8   Pending   <none>
sandbox-drain-timeout-nginx-f57cbc6cb-9d8qp   Running   kind-worker
sandbox-drain-timeout-nginx-f57cbc6cb-2kq98   Running   kind-worker2
sandbox-drain-timeout-nginx-f57cbc6cb-m9cbb   Running   kind-worker2
sandbox-drain-timeout-nginx-f57cbc6cb-vcwjv   Running   kind-worker2

待っても待ってもリトライが続くため,以下のドキュメントを確認したところ,今回設定しなかった kubectl drain コマンドの --timeout オプションのデフォルト値は 0s となり,無限にリトライを続ける挙動になっていた.なるほど!

The length of time to wait before giving up, zero means infinite

Kubectl Reference Docs

構成をザッと図解すると以下のようになる.

f:id:kakku22:20210224003710p:plain

次の検証をするためにノードと Deployment を同じ構成に戻しておく.

$ kubectl uncordon kind-worker

$ kubectl delete -f deployment.yaml

$ kubectl apply -f deployment.yaml

$ kubectl get pods -o custom-columns=Name:metadata.name,STATUS:status.phase,NODE:spec.nodeName | sort -k 3
Name                                          STATUS    NODE
sandbox-drain-timeout-nginx-f57cbc6cb-s4btz   Running   kind-worker
sandbox-drain-timeout-nginx-f57cbc6cb-ssscp   Running   kind-worker
sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh   Running   kind-worker
sandbox-drain-timeout-nginx-f57cbc6cb-cdkcp   Running   kind-worker2
sandbox-drain-timeout-nginx-f57cbc6cb-g6v7p   Running   kind-worker2
sandbox-drain-timeout-nginx-f57cbc6cb-hvgm2   Running   kind-worker2

検証 3 : PDB ありで kubectl drain --timeout コマンドを実行する

kubectl drain コマンドはデフォルトでリトライを続ける挙動になっていることを確認できたため,最後は --timeout オプションを設定して挙動を確認する.今回はサンプルとして「30秒」にする.すると最後に global timeout reached: 30s というメッセージが表示されて kubectl drain コマンドがエラーを返している.結果としては「検証 2」と同じになる.なるほど!

$ kubectl drain kind-worker --ignore-daemonsets --timeout 30s
node/kind-worker cordoned
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-s4btz
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-ssscp
error when evicting pod "sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh
error when evicting pod "sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
pod/sandbox-drain-timeout-nginx-f57cbc6cb-s4btz evicted
pod/sandbox-drain-timeout-nginx-f57cbc6cb-ssscp evicted
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh
error when evicting pod "sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh
error when evicting pod "sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh
error when evicting pod "sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh
error when evicting pod "sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod default/sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh
There are pending pods in node "kind-worker" when an error occurred: error when evicting pod "sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh": global timeout reached: 30s
pod/sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh
error: unable to drain node "kind-worker", aborting command...

There are pending nodes to be drained:
 kind-worker
error: error when evicting pod "sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh": global timeout reached: 30s

$ kubectl get pods -o custom-columns=Name:metadata.name,STATUS:status.phase,NODE:spec.nodeName | sort -k 3
Name                                          STATUS    NODE
sandbox-drain-timeout-nginx-f57cbc6cb-5xs7k   Pending   <none>
sandbox-drain-timeout-nginx-f57cbc6cb-jlckx   Pending   <none>
sandbox-drain-timeout-nginx-f57cbc6cb-tx6xh   Running   kind-worker
sandbox-drain-timeout-nginx-f57cbc6cb-cdkcp   Running   kind-worker2
sandbox-drain-timeout-nginx-f57cbc6cb-g6v7p   Running   kind-worker2
sandbox-drain-timeout-nginx-f57cbc6cb-hvgm2   Running   kind-worker2

まとめ

kubectl drain コマンドを試しているときにふと気になり,今回は「kubectl drain コマンドでノードをドレインしたときに PodDisruptionBudget (PDB) に設定した最低限必要な Pod 数を満たすリソースがノードに不足していた場合」という少し複雑な状況での挙動を検証した.ドキュメントに書いてあるとは言え,kubectl drain コマンドのデフォルトはリトライを続けて,--timeout オプションを設定するとタイムアウト時間を決めることができた.今後も積極的に検証していくぞー!

kubectl コマンドを使って Label や Annotation を削除する

kubectl コマンドを使って Label(ラベル) や Annotation(アノテーション)を削除する場合,削除用のオペレーションはなく,キー名の末尾に - を付けて登録をする必要がある.具体的には bar- や description- というキー名を指定すると削除できる.以下のドキュメント「kubectl Command Reference」にも載っている.今回は kind で構築した Kubernetes v1.19.1 のクラスターを使って検証した内容をまとめておく!

$ kubectl label pods foo bar-

$ kubectl annotate pods foo description-

Kubectl Reference Docs

Label を削除する : Node と Pod

まず,Node kind-worker に Label my-label=hello を登録する.kubectl get コマンドで --label-columns もしくは -L オプションを使うと指定したラベルを表示できる.ポイントは Label を削除する部分で kubectl label nodes kind-worker my-label- というコマンドになる.my-label- を指定している.

# Node
$ kubectl label nodes kind-worker my-label=hello
node/kind-worker labeled

$ kubectl get nodes kind-worker -L my-label
NAME          STATUS   ROLES    AGE   VERSION   MY-LABEL
kind-worker   Ready    <none>   5m    v1.19.1   hello

$ kubectl label nodes kind-worker my-label-
node/kind-worker labeled

$ kubectl get nodes kind-worker -L my-label
NAME          STATUS   ROLES    AGE    VERSION   MY-LABEL
kind-worker   Ready    <none>   6m    v1.19.1

Pod でも同じように確認する.Label を削除するときは kubectl label pods nginx my-label- というコマンドになる.

# Pod
$ kubectl label pods nginx my-label=hello
pod/nginx labeled

$ kubectl get pods nginx -L my-label
NAME    READY   STATUS    RESTARTS   AGE   MY-LABEL
nginx   1/1     Running   0          20s   hello

$ kubectl label pods nginx my-label-
pod/nginx labeled

$ kubectl get pods nginx -L my-label
NAME    READY   STATUS    RESTARTS   AGE   MY-LABEL
nginx   1/1     Running   0          40s

Annotation を削除する : Node と Pod

次に Node kind-worker に Annotation my-annotation=hello を登録する.kubectl get コマンドのオプションで Annotation を表示することはできないため,今回は custom-columns フォーマットを使う.ポイントは Annotation を削除する部分で kubectl annotate nodes kind-worker my-annotation- というコマンドになる.my-annotation- を指定している.

# Node
$ kubectl annotate nodes kind-worker my-annotation=hello
node/kind-worker annotated

$ kubectl get nodes kind-worker -o custom-columns=Name:metadata.name,ANNOTATIONS:metadata.annotations.my-annotation
Name          ANNOTATIONS
kind-worker   hello

$ kubectl annotate nodes kind-worker my-annotation-
node/kind-worker annotated

$ kubectl get nodes kind-worker -o custom-columns=Name:metadata.name,ANNOTATIONS:metadata.annotations.my-annotation
Name          ANNOTATIONS
kind-worker   <none>

Pod でも同じように確認する.Annotation を削除するときは kubectl annotate pods nginx my-annotation- というコマンドになる.

# Pod
$ kubectl annotate pods nginx my-annotation=hello
pod/nginx annotated

$ kubectl get pods nginx -o custom-columns=Name:metadata.name,ANNOTATIONS:metadata.annotations.my-annotation
Name    ANNOTATIONS
nginx   hello

$ kubectl annotate pods nginx my-annotation-
pod/nginx annotated

$ kubectl get pods nginx -o custom-columns=Name:metadata.name,ANNOTATIONS:metadata.annotations.my-annotation
Name    ANNOTATIONS
nginx   <none>

簡単!便利!Keynote や PowerPoint で「アニメーション GIF」を作ろう!

ブログに載せる「アニメーション GIF」を作るときに Keynote や Microsoft PowerPoint を使えば,簡単に「アニメーション付きスライド」を「アニメーション GIF」にエクスポートできる.知っておくと便利!

どんなものを作れるのか

サンプルとして Keynote を使って「アニメーション付きスライド」を「アニメーション GIF」にエクスポートした.オブジェクトのサイズを変更したり,オブジェクトをフェードインさせたり,表現力を高められるぞー!

f:id:kakku22:20210209111605g:plain

Keynote の場合

「アニメーション付きスライド」を作ったら ファイル ➔ 書き出す ➔ アニメーション GIF と選択する.さらに「解像度」や「フレームレート」も設定できる.比較的ファイルサイズが大きくなるため,調整するときに使う.

support.apple.com

f:id:kakku22:20210209111702p:plain

Microsoft PowerPoint の場合

「アニメーション付きスライド」を作ったら ファイル ➔ エクスポート ➔ GIF と選択する.ドキュメントを読むと PowerPoint for Microsoft 365 と PowerPoint for Microsoft 365 for Mac でサポートされている機能だった.手元にある PowerPoint 2019 for Mac では使えなかった.

support.microsoft.com

まとめ

Keynote や Microsoft PowerPoint を使えば,簡単に「アニメーション GIF」を作れる!便利!

昨日の記事に載せた「アニメーション GIF」も実は Keynote を使っていて,少しファイルサイズが大きくなったため「解像度 : 中」に落としてある.より複雑なサンプルとして載せておく!

f:id:kakku22:20210210163033g:plain

簡単に Docker Hub の情報を取得できる Docker Hub CLI Tool(hub-tool コマンド)

「Docker Hub CLI Tool(hub-tool コマンド)」を使うと,Docker Hub の情報取得を CLI で行えるようになる.2020年12月にリリースされて,2021年1月に OSS として GitHub リポジトリも公開された.個人的には「イメージタグを検索する hub-tool tag ls コマンド」が便利すぎて頻繁に使っている.他には「レート制限の状況を確認する hub-tool account rate-limiting コマンド」も便利!

github.com

なお Docker Blog の記事を読むと,hub-tool コマンドの機能は将来的に Docker CLI に組み込まれる可能性があり,現時点ではフィードバックを集めるためにあくまで「実験用」としてリリースしているとのこと.詳しくは以下に載っている.

This does mean that this tool is going to be an experiment so we do expect it to go away sometime in 2021. We plan to use the lessons we learn here to make something awesome as part of the Docker CLI.

www.docker.com

www.docker.com

準備 1 : hub-tool コマンドをインストールする 🧪

Docker Desktop のリリースノートにも載っている通り,Docker Desktop Community 3.0.0 からデフォルトで同梱されているため,Docker Desktop を使っていれば,特にインストールをしなくても hub-tool コマンド v0.2.0 を使える.GitHub リポジトリを見ると,最新バージョンは v0.3.0 までリリースされている.今回はインストールされている v0.2.0 を使う.

$ hub-tool version
Version:    v0.2.0
Git commit: 0edf43ac9091e7cac892cbc4cbc6efbafb665aa4

準備 2 : ログインする(Two-Factor Authentication 対応)🧪

最初に hub-tool login コマンドでログインをしておく.Docker Hub の「Two-Factor Authentication (2FA)」にも対応している.ただし 2FA を有効化している場合,hub-tool コマンドを実行する度に OPT (One Time Password) の入力が求められるため,正直言って使いにくいと思う.関連する Issue も出ている.

# Two-Factor Authentication なし
$ hub-tool login kakakakakku
Password:
Login Succeeded

# Two-Factor Authentication あり
$ hub-tool login kakakakakku
Password:
2FA required, please provide the 6 digit code: 123456
Login Succeeded

準備 3 : 必要ならエイリアスを設定する 🧪

何となく hub-tool という名前に違和感があり,GitHub 関連の hub コマンドにも似ている.GitHub 関連だと,現在は gh コマンドがよく使われていることもあり,個人的に dh というエイリアスを設定して使っている.

$ alias dh=hub-tool

コマンド一覧 🧪

現状だと hub-tool コマンドに関するドキュメントはなさそうで,hub-tool help コマンドから使えるコマンドを整理した.

  • hub-tool account
    • info
    • rate-limiting
  • hub-tool help
  • hub-tool login
  • hub-tool logout
  • hub-tool org
    • ls
    • teams
    • members
  • hub-tool repo
    • ls
    • rm
  • hub-tool tag
    • ls
    • rm
    • inspect
  • hub-tool token
    • activate
    • create
    • deactivate
    • inspect
    • ls
    • rm
  • hub-tool version
$ hub-tool help
A tool to manage your Docker Hub images

Usage:
  hub-tool
  hub-tool [command]

Available Commands:
  account     Manage your account
  help        Help about any command
  login       Login to the Hub
  logout      Logout of the Hub
  org         Manage organizations
  repo        Manage repositories
  tag         Manage tags
  token       Manage Personal Access Tokens
  version     Version information about this tool

Flags:
  -h, --help      help for hub-tool
      --verbose   Print logs
      --version   Display the version of this tool

Use "hub-tool [command] --help" for more information about a command.

hub-tool account コマンド 🧪

hub-tool account info コマンドを実行すると Docker Hub のアカウント情報を取得できる.hub-tool account rate-limiting コマンドを実行すると「レート制限」の状況を確認できる.また --format json オプションを使うと JSON 形式で結果を取得できるため,API 連携などをするときに便利!

$ hub-tool account info
Username:   kakakakakku
Full name:  kakakakakku
Company:    Tech Blogger
Location:   Tokyo
Joined:     5 years ago
Plan:       free
Limits:
  Seats:        1
  Private repositories: 1
  Parallel builds:  1
  Collaborators:    unlimited
  Teams:        unlimited

$ hub-tool account rate-limiting
Limit:     200, 6 hours window
Remaining: 200, 6 hours window

$ hub-tool account info --format json

$ hub-tool account rate-limiting --format json

hub-tool help コマンド 🧪

コマンド一覧を確認するときに紹介したため割愛する.

hub-tool login コマンド 🧪

準備 2 で紹介したため割愛する.

hub-tool logout コマンド 🧪

hub-tool logout コマンドを実行すると,ログアウトできる.ポイントは Docker Hub のウェブサイトではなく,あくまで hub-tool コマンドとしてログアウトするところ.

$ hub-tool logout
Logout Succeeded

hub-tool org コマンド 🧪

hub-tool org コマンドを使うと,Docker Hub の Organizations や Teams の情報を取得できる.現在は Free プランで個人的に使っているため,取得できる情報がなかった.残念!

$ hub-tool org ls

$ hub-tool org teams my-org

$ hub-tool org members my-org

docs.docker.com

hub-tool repo コマンド 🧪

hub-tool repo コマンドを使うと,リポジトリ一覧を取得したり,リポジトリを削除できる.hub-tool repo ls コマンドを iTerm2 で実行すると REPOSITORY の部分がリンク形式になっていて,直接ブラウザを開けるようになっている.細かい工夫もあって便利!

$ hub-tool repo ls
REPOSITORY                             DESCRIPTION                                              LAST UPDATE      PULLS    STARS    PRIVATE
kakakakakku/mysql-world-database       Dockerized MySQL pre-loaded world database 🐳          42 hours ago     1244     0        false
kakakakakku/cfn-lint                   Dockerized CloudFormation Linter (cfn-lint) 👮         2 weeks ago      1597     0        false
kakakakakku/htmllint-cli               Dockerized htmllint-cli ✏️                           3 months ago     993      0        false
kakakakakku/apex                       Dockerized Apex 🐳                                     20 months ago    308      0        false
kakakakakku/git                        Dockerized Git Command 🐙                              20 months ago    15       0        false
kakakakakku/rubocop                    Dockerized RuboCop 👮                                  21 months ago    1060     0        false
kakakakakku/gin-example                gin-example                                              2 years ago      24770    0        false
kakakakakku/foodcritic                 Dockerized Foodcritic 🍕                               2 years ago      975      0        false
kakakakakku/docker-hands-on-nginx      docker-hands-on-nginx                                    2 years ago      19       0        false
kakakakakku/mkr                        Dockerized mkr 🐟                                      2 years ago      264      0        false
kakakakakku/amazonlinux-bats           Dockerized Bats for Amazon Linux 👾                    2 years ago      33       0        false
kakakakakku/mysql-56-world-database    Deprecated : Use kakakakakku/mysql-world-database:5.6    3 years ago      27       0        false
kakakakakku/mysql-57-world-database    Deprecated : Use kakakakakku/mysql-world-database:5.7    3 years ago      433      0        false
kakakakakku/httpd                      My sandbox : httpd                                       5 years ago      110      1        false
kakakakakku/nginx                      My sandbox : nginx                                       5 years ago      68       1        false

hub-tool tag コマンド 🧪

hub-tool tag コマンドを使うと,指定したリポジトリのタグ一覧を取得したり,タグを削除したり,タグに紐付くイメージの詳細情報を取得できる.特に hub-tool tag ls コマンドは便利で,Docker Hub に公開されているオフィシャルリポジトリも対象にできるため,例えば「nginx リポジトリのタグを調べたい」という場面で使える.今までは毎回 Docker Hub のウェブサイトを確認していた.

他にもオプションはある.--all オプションを使えば,全タグを取得できるし,--platforms オプションを使えば,対応しているプラットフォームも取得できるし,--sort オプションを使えば,最終更新日とタグ名でソートもできる.

$ hub-tool tag ls kakakakakku/mysql-world-database
TAG                                        DIGEST                                                                     STATUS    LAST UPDATE     LAST PUSHED    LAST PULLED    SIZE
kakakakakku/mysql-world-database:latest    sha256:872265c1d95ef7d501a63d2b6b185570173be3b658d3ea9f8b43c020bbc143cc    active    42 hours ago    42 hours       13 minutes     154.7MB
kakakakakku/mysql-world-database:5.7       sha256:98eb9d7f531ed1cbbe42c03ca08fd703d24f02117573d2c144d847f94d6b225d    active    42 hours ago    42 hours       13 minutes     154.7MB
kakakakakku/mysql-world-database:5.6       sha256:985fb7485de021a5fc8bd50b106b27b3f495d9f63e4245854118dd72eca32784    active    42 hours ago    42 hours       13 minutes     103.1MB
kakakakakku/mysql-world-database:8.0       sha256:62db58969cd30fdd82617d8f6dcf35abb09a835b1d05007a0753591a855f26ae    active    42 hours ago    42 hours       13 minutes     159.4MB
kakakakakku/mysql-world-database:5.5       sha256:d100ead4d2eacf74ad110b5f1ad3d87e2e410d66a7f5da26b0b6af7ade585141    active    42 hours ago    42 hours       13 minutes     66.16MB

$ hub-tool tag ls nginx
TAG                           DIGEST                                                                     STATUS    LAST UPDATE      LAST PUSHED    LAST PULLED       SIZE
nginx:latest                  sha256:073effa4d56e0c870597a8e49c7effee02e27c9c65e93cdfcaea34e41615141d    active    2 days ago       2 days         7 minutes         421.3MB
nginx:stable-perl             sha256:8176da19df2afbc068b9be824d11ff1482b5bdc6cd5cf7268f7e64c9c617e1c7    active    2 days ago       2 days         17 minutes        506.1MB
nginx:stable                  sha256:b0e24622e0717d4453ae834cafc39aa8888fe9a55f9a362b13cc7035fa3f3344    active    2 days ago       2 days         11 minutes        421MB
nginx:perl                    sha256:869af316fec24f6b347537a69e07850481b4fbfece958967c909b7b20831a57e    active    2 days ago       2 days         6 minutes         506.4MB
nginx:mainline-perl           sha256:e311064b5b2d9af752ad4147a132ab16ac19874ecc2243ab98523d9f59b38f45    active    2 days ago       2 days         6 minutes         506.4MB
nginx:mainline                sha256:1a53eb723d17523512bd25c27299046cfa034cce309f4ed330c943a304513f59    active    2 days ago       2 days         7 minutes         421.3MB
nginx:1.19.6-perl             sha256:f998053942a5e45c6f5aa4e0516174727e3a2da7c76b8e3656a9173a692b4e88    active    2 days ago       2 days         6 minutes         506.4MB
nginx:1.19.6                  sha256:dd19f44b5a3c4b53947a10fe507afaa4f05e1b8ca64f95f33642d68c974d2b55    active    2 days ago       2 days         7 minutes         421.3MB
nginx:1.19-perl               sha256:869af316fec24f6b347537a69e07850481b4fbfece958967c909b7b20831a57e    active    2 days ago       2 days         6 minutes         506.4MB

(中略)

100/325 listed, use --all flag to show all

$ hub-tool tag ls --platforms --sort name=desc nginx
TAG                           DIGEST                                                                     STATUS    LAST UPDATE      LAST PUSHED    LAST PULLED       SIZE       OS/ARCH
nginx:stable-perl             sha256:8176da19df2afbc068b9be824d11ff1482b5bdc6cd5cf7268f7e64c9c617e1c7    active    2 days ago       2 days         22 minutes        506.1MB    linux/ppc64le,linux/mips64le,linux/arm/v5,linux/arm64/v8,linux/s390x,linux/arm/v7,linux/amd64,linux/386
nginx:stable-alpine-perl      sha256:0c85226446a083d92fbf432faee51d12933eafdcf13eb0b7d06fc465368ae908    active    7 weeks ago      7 weeks        34 minutes        124.8MB    linux/amd64,linux/arm/v6,linux/s390x,linux/386,linux/arm/v7,linux/arm64/v8,linux/ppc64le
nginx:stable-alpine           sha256:da3716611fb965f3fda1f3281882baeb2760ca8bb7317f1d22ed45e75570827b    active    7 weeks ago      7 weeks        7 minutes         64.99MB    linux/amd64,linux/arm/v7,linux/arm64/v8,linux/arm/v6,linux/s390x,linux/ppc64le,linux/386

(中略)

100/325 listed, use --all flag to show all

hub-tool tag inspect コマンドは,v0.3.0 でプラットフォームを指定できるようになったり,出力結果も変更されているため,最新バージョンで使う方が良さそう.CLI でイメージの詳細情報を取得できるのは便利!

$ hub-tool tag inspect nginx

hub-tool token コマンド 🧪

hub-tool token コマンドを使うと,Docker Hub のアクセストークンを管理できる.アクセストークンを作ったり,一覧を取得したり,削除することもできる.

$ hub-tool token create --description sandbox1
Personal Access Token successfully created!
(中略)

$ hub-tool token create --description sandbox2
Personal Access Token successfully created!
(中略)

$ hub-tool token ls
DESCRIPTION    UUID                                    LAST USED    CREATED       ACTIVE
sandbox2       11111111-1111-1111-1111-111111111111    Never        20 seconds    true
sandbox1       22222222-2222-2222-2222-222222222222    Never        40 seconds    true

hub-tool version コマンド 🧪

準備 1 で紹介したため割愛する.

まとめ

「Docker Hub CLI Tool(hub-tool コマンド)」を使うと,Docker Hub の情報取得を CLI で行えるようになる.特に hub-tool tag ls コマンドは便利だと思う!Docker Blog の記事に載っている通り,あくまで「実験用」としてリリースされているとは言え,Docker Desktop にデフォルトで同梱されているし,使ってみてはいかがでしょうか!