Docker Context
読む時間の目安: 4 分
はじめに
本ガイドでは コンテキスト(context)というものが、いかに簡単に、単一の Docker CLI から複数 Swarm クラスターを、そして複数 Kubernetes クラスター、各 Docker ノードを操作できるかを示します。
1 つの Docker CLI に対しては、複数のコンテキスト(context)を持たせることができます。
各コンテキストには、さまざまなクラスターやノードの管理に必要となる、エンドポイント情報やセキュリティ情報が含まれています。
docker context
コマンドを使うと、そういったコンテキストを簡単に設定したり切り替えたりすることができます。
その例として、会社で利用するノート PC 上において、1 つの Docker クライアントから 2 つのコンテキスト、dev-k8s と prod-swarm の利用設定が必要であるとします。
dev-k8s は、開発環境上の Kubernetes クラスターの設定管理を行うものであり、エンドポイントデータやセキュリティ情報が含まれています。
一方 prod-swarm は、本番環境上の Swarm クラスター管理を一手に引き受けているものとします。
コンテキストの設定を一度行ってしまえば、トップレベルのコマンドdocker context use <コンテキスト名>
を実行するだけで、コンテキストを簡単に切り替えられるようになります。
Docker Context を利用し、開発アプリをクラウド上にデプロイする方法については、Azure 上の Docker コンテナーのデプロイ や ECS 上への Docker コンテナーのデプロイ を参照してください。
前提条件
本ガイドの利用例を進めていくためには、以下が必要になります。
- トップレベルコマンド
context
をサポートしている Docker クライアント。
docker context
を実行して、Docker クライアントがコンテキストをサポートしていることを確認してください。
また以下のいずれかが必要です。
- Docker Swarm クラスター
- 単独エンジンによる Docker クラスター
- Kubernetes クラスター
コンテキストの意味
コンテキストとは、複数プロパティが組み合わせれたものです。 そこには以下の情報が含まれます。
- 名前
- エンドポイント設定
- TLS 情報
- オーケストレーター
コンテキストというものがどのようなものに見えるかは、default コンテキストを見てみれば一番よくわかります。
$ docker context ls
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
default * Current... unix:///var/run/docker.sock swarm
上の結果より、「default」という単一のコンテキストがあることがわかります。
これは Swarm クラスターとやりとりするものとして設定されていて、ローカルの Unix ソケット/var/run/docker.sock
を利用して実現するものとなっています。
ここには Kubernetes のエンドポイントは設定されていません。
NAME
列の横に示されるアスタリスクは、そのコンテキストがアクティブであることを表わします。
これはつまりdocker
コマンドがすべて、この「default」コンテキストに対して実行されることを意味します。
DOCKER_HOST
やDOCKER_CONTEXT
といった環境変数を使うか、コマンドラインから--context
や--host
フラグを指定することで、その対象をオーバーライドすることができます。
さらに詳しく見るにはdocker context inspect
を実行します。
この例においては、default
というコンテキストを確認しています。
$ docker context inspect default
[
{
"Name": "default",
"Metadata": {
"StackOrchestrator": "swarm"
},
"Endpoints": {
"docker": {
"Host": "unix:///var/run/docker.sock",
"SkipTLSVerify": false
}
},
"TLSMaterial": {},
"Storage": {
"MetadataPath": "\u003cIN MEMORY\u003e",
"TLSPath": "\u003cIN MEMORY\u003e"
}
}
]
このコンテキストでは、オーケストレーター(metadata.stackOrchestrator
)として「swarm」を利用しています。
また /var/run/docker.sock
にあるローカル Unix ソケットを使い、利用可能なエンドポイントとの間でやりとりを行うように設定されています(Endpoints.docker.Host
)。
そして TLS 検証を必要とする設定もあります(Endpoints.docker.SkipTLSVerify
)。
新たなコンテキストの生成
新たなコンテキストを生成するにはdocker context create
コマンドを実行します。
以下の例では「docker-test」というコンテキストを生成するものとし、以下を設定するものとします。
- デフォルトのオーケストレーターを Swarm とします。
- ローカル Unix ソケット
/var/run/docker.sock
に対してコマンド実行するものとします。
$ docker context create docker-test \
--default-stack-orchestrator=swarm \
--docker host=unix:///var/run/docker.sock
Successfully created context "docker-test"
新たなコンテキストは~/.docker/contexts/
配下のmeta.json
内に保存されます。
コンテキストを新規に生成すると、~/.docker/contexts/
に専用のサブディレクトリが生成され、それぞれのmeta.json
が保存されるものです。
メモ: デフォルトのコンテキストは、手動で生成したコンテキストとは、多少違った動きをします。 デフォルトのコンテキストには、設定ファイル
meta.json
が存在しません。 そしてその時点の設定に基づいて、動的に設定が更新されます。 たとえばコマンドkubectl config use-context
を実行して、現在の Kubernetes 設定を切り替えたとします。 この場合 Docker のデフォルトコンテキストは、新たに Kubernetes エンドポイントに対応して、動的にコンテキスト自体を更新します。
新たに生成したコンテキストは、docker context ls
やdocker context inspect <コンテキスト名>
により確認することができます。
以下のコマンドは新たな設定を生成するものであり、/home/ubuntu/.kube/config
に保存されている既存の kubeconfig を使って、デフォルトのオーケストレーターを Kubernetes とする設定を行うものです。
これを動作させるためには、/home/ubuntu/.kube/config
に Kubernetes の適切な設定ファイルが存在している必要があります。
kubeconfig に複数のコンテキストが設定されている場合、現在のコンテキスト(kubectl config current-context
)が用いられます。
$ docker context create k8s-test \
--default-stack-orchestrator=kubernetes \
--kubernetes config-file=/home/ubuntu/.kube/config \
--docker host=unix:///var/run/docker.sock
Successfully created context "k8s-test"
システム上にあるコンテキストをすべて確認するにはdocker context ls
を実行します。
$ docker context ls
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
default * Current unix:///var/run/docker.sock https://35.226.99.100 (default) swarm
k8s-test unix:///var/run/docker.sock https://35.226.99.100 (default) kubernetes
docker-test unix:///var/run/docker.sock swarm
カレントなコンテキストはアスタリスク(”*“)により示されます。
別のコンテキストへの切り替え
docker context use
コマンドを利用すれば、コンテキストの切り替えをすばやく行うことができます。
以下のコマンドはdocker
CLI が「k8s-test」コンテキストを利用するように切り替えるものです。
$ docker context use k8s-test
k8s-test
Current context is now "k8s-test"
処理結果を確認するため、コンテキストをすべて一覧表示して、「k8s-test」コンテキストにアスタリスク(”*“)がついているかどうかを見てみます。
$ docker context ls
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
default Current DOCKER_HOST based configuration unix:///var/run/docker.sock https://35.226.99.100 (default) swarm
docker-test unix:///var/run/docker.sock swarm
k8s-test * unix:///var/run/docker.sock https://35.226.99.100 (default) kubernetes
docker
コマンドはこれ以降、「k8s-test」コンテキストに定義されたエンドポイントを操作対象とします。
コンテキストの設定は、環境変数DOCKER_CONTEXT
を使って行うこともできます。
これはdocker context use
によって設定されたコンテキストをオーバーライドします。
以下の中から適切なコマンドを選んで、環境変数を利用したdocker-test
コンテキストの設定を行います。
Windows PowerShell の場合
> $Env:DOCKER_CONTEXT=docker-test
Linux の場合
$ export DOCKER_CONTEXT=docker-test
docker context ls
を実行すると、「docker-test」コンテキストが現在のアクティブコンテキストであることがわかります。
またグローバルな--context
フラグを使うとDOCKER_CONTEXT
環境変数によるコンテキスト指定ををオーバーライドします。
たとえば以下は、コマンドに対して「production」というコンテキストを指定します。
$ docker --context production container ls
Docker Context のインポート、エクスポート
docker context
コマンドでは、Docker クライアントがインストールされている別のマシンにおいて、コンテキストを簡単にインポート、エクスポートすることができます。
docker context export
コマンドを使うと、既存のコンテキストをファイルにエクスポートします。
そのファイルは、docker
クライアントがインストールされている別のマシンにインポートすることができます。
デフォルトでコンテキストは ネイティブな Docker Context としてエクスポートされます。
これはdocker context
コマンドを使って、インポートエクスポートができるものです。
エクスポートしたコンテキストに Kubernetes エンドポイントが含まれている場合、その Kubernetes 部分のコンテキストも export
、import
操作を通じて含まれることになります。
エクスポートにあたっては Kubernetes 部分のコンテキストだけをエクスポートすることもできます。
これにより、ネイティブな kubeconfig ファイルが生成され、そのファイル内容は、kubectl
がインストールされている他のホスト上において~/.kube/config
ファイルへ手動でマージすることができます。
Kubernetes 部分のコンテキストだけをエクスポートし、これをインポートする場合は、docker context import
コマンドは使えません。
エクスポートされた Kubernetes 設定をインポートするには、既存の kubeconfig ファイルに対して、手動でマージする以外に方法はありません。
ネイティブな Docker コンテキストのエクスポートとインポートを以降に示します。
ネイティブな Docker コンテキストのエクスポートとインポート
以下の例では「docker-test」という既存のコンテキストをエクスポートします。
これはコンテキストをdocker-test.dockercontext
というファイルに出力します。
$ docker context export docker-test
Written file "docker-test.dockercontext"
エクスポートしたファイルの中身を確認します。
$ cat docker-test.dockercontext
meta.json0000644000000000000000000000022300000000000011023 0ustar0000000000000000{"Name":"docker-test","Metadata":{"StackOrchestrator":"swarm"},"Endpoints":{"docker":{"Host":"unix:///var/run/docker.sock","SkipTLSVerify":false}}}tls0000700000000000000000000000000000000000000007716 5ustar0000000000000000
このファイルは、別のホスト上においてdocker context import
を使ってインポートできます。
対象とするホストには、Docker クライアントがインストールされている必要があります。
$ docker context import docker-test docker-test.dockercontext
docker-test
Successfully imported context "docker-test"
コンテキストがインポートできたかどうかはdocker context ls
により確認します。
インポートするコマンドの記述書式はdocker context import <コンテキスト名> <コンテキストファイル>
です。
次は、コンテキストの Kubernetes 部分のみをエクスポートする例です。
Kubernetes コンテキストのエクスポート
Kubernetes コンテキストがエクスポートできるのは、エクスポートするコンテキスト内に Kubernetes エンドポイントが設定されている場合に限ります。
Kubernetes コンテキストのインポートにはdocker context import
を使うことはできません。
この手順では--kubeconfig
フラグを使って Kubernetes 部分のコンテキスト のみ をエクスポートします。
コンテキスト名は既存のk8s-test
であり、これを「k8s-test.kubeconfig」というファイルに出力します。
cat
コマンドを実行すれば、適正な kubeconfig ファイルとして出力されていることがわかります。
$ docker context export k8s-test --kubeconfig
Written file "k8s-test.kubeconfig"
エクスポートしたファイルが、適正な kubectl 設定であることを確認します。
$ cat k8s-test.kubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data:
<Snip>
server: https://35.226.99.100
name: cluster
contexts:
- context:
cluster: cluster
namespace: default
user: authInfo
name: context
current-context: context
kind: Config
preferences: {}
users:
- name: authInfo
user:
auth-provider:
config:
cmd-args: config config-helper --format=json
cmd-path: /snap/google-cloud-sdk/77/bin/gcloud
expiry-key: '{.credential.token_expiry}'
token-key: '{.credential.access_token}'
name: gcp
上の内容を、別のマシン上の~/.kube/config
ファイルにマージします。
コンテキストの更新
既存のコンテキストにおいて項目を更新するにはdocker context update
を実行します。
以下の例は、既存のk8s-test
コンテキストにおいて「Description」という項目を更新するものです。
$ docker context update k8s-test --description "Test Kubernetes cluster"
k8s-test
Successfully updated context "k8s-test"