Kubernetes の動作を確認するため、複数の nginx インスタンスを手元の Mac に立ち上げてみます。
Docker for Mac で Kubernetes を有効にする
- Docker アイコン > Preferences > Kubernetes > Enable Kubernetes > ラジオボタンを Kubernetes にする
- Apply
- Install
これで Kubernetes の CLI である kubectl
もインストールされます。
Kubernetes の状態を知るには kubectl get
を使いますが、そもそもどんなリソースがあるか知らないと使えません。ブラウザで情報を閲覧出来る Kubernetes Dashboard をインストールすると便利です。
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.3", GitCommit:"2bba0127d85d5a46ab4b778548be28623b32d0b0", GitTreeState:"clean", BuildDate:"2018-05-21T09:17:39Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.3", GitCommit:"2bba0127d85d5a46ab4b778548be28623b32d0b0", GitTreeState:"clean", BuildDate:"2018-05-21T09:05:37Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
$ kubectl get pods --all-namespaces -l k8s-app=kubernetes-dashboard
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system kubernetes-dashboard-7b9c7bc8c9-9nhlp 1/1 Running 0 4m
$ kubectl proxy
- ブラウザで http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/ を開く
- Kubernetes Dashboard で Skip を選択
- Kubernetes Dashboard が表示される。
上記コマンドの意味:
-
kubectl apply
- 指定されたファイルを元にリソースを設定する。
-
kubectl get
- 指定されたリソースの情報を表示する。
- pods はリソースの種類
- -l (--selector) でフィルタをかけることが出来る。
オートコンプリートの設定
zsh の場合:
echo "if [ $commands[kubectl] ]; then source <(kubectl completion zsh); fi" >> ~/.zshrc # add autocomplete permanently to your zsh shell
用語メモ
- Kubernetes とは、Resource を組み合わせるもの。
- Resource とは、Docker container を組み合わせて使うための色々な部品。
- Node: ホストマシンの事。
- Namespace: リソースを分けて管理するための名前。
- Pod: 一つ以上コンテナ。デプロイの単位。
- Deployment: 同じコンテナを複数作るのに使う。またバージョン管理も出来る。
-
Service: Pod に名前をつけてお互いにアクセス出来るようにする。また外部からアクセス出来るようにする。
- Services without Selectors を使うことで、クラスタと外部のサービスの連携を行う事も出来る。
-
Selector: Pod などを特定するのに使う。
- 選ばれる側のリソースは metadata.labels に辞書形式で定義する。
- 選ぶ側のリソースは selector などで指定する。
Pod を作る
Pod は一つ以上のコンテナをまとめたリソースです。以下に Define a Command and Arguments for a Container の例を示します。
apiVersion: v1
kind: Pod # Kind でリソースの種類を指定する。
metadata:
name: command-demo # kubectl からこの名前で Pod を参照します。
labels:
purpose: demonstrate-command
spec:
containers:
- name: command-demo-container
image: debian
command: ["printenv"]
args: ["HOSTNAME", "KUBERNETES_PORT"]
restartPolicy: OnFailure
このファイルを commands.yaml という名前で保存して kubectl apply -f commands.yaml
を実行するとこの Pod が作成されます。面白い事に引数に URL を指定できるので代わりに:
kubectl apply -f https://k8s.io/examples/pods/commands.yaml
でも動きます。この Pod は printenv HOSTNAME KUBERNETES_PORT を実行するだけの物です。動作状態を確認するには以下のようにします。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
command-demo 0/1 Completed 0 7m
出力結果は kubectl logs
で見れます。
$ kubectl logs command-demo
command-demo
tcp://10.96.0.1:443
Pod を削除するには kubectl delete
を使います。いくつかの方法があります。
kubectl delete pod command-demo # 名前を指定
kubectl delete -f commands.yaml # ファイルを指定
kubectl delete pod/command-demo # kubectl get all の出力を使う
この例では一つの Pod に一つのコンテナを含みました。Pod 内は一つの IP アドレスを共有するため、複数のコンテナを含めるとお互いに localhost で通信出来るそうです。
(注意) ローカルのイメージを使いたい場合は repository name と latest 以外の tag を付ける。
例えば上記の例では
image: debian
のようにしてイメージを指定しているがこの場合リモートの dockerhub のイメージを参照してしまう。自分のマシンにある未公開のイメージを使いたい場合は repository name と latest 以外の tag を付ける必要がある。
リモートを参照してしまう例
hoge
hoge:latest
ローカルを参照出来る例
fuga/hoge:1.0
Deployment を使う
Deployment とは、コンテナをデプロイする時に使うリソースです。以下に Run a Stateless Application Using a Deployment の例を示します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx # template.metadata.labels に記載したラベルを指定します。
replicas: 2 # この数だけ pod を立ち上げます。
template:
metadata:
labels:
app: nginx # 作成する pod に割り振るラベルを指定します。
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
例によってURL を指定して kubectl apply -f https://k8s.io/examples/application/deployment.yaml
でも動きます。動作中は以下のような状態になります。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-75675f5897-bgrph 1/1 Running 0 1m
nginx-deployment-75675f5897-dpv4m 1/1 Running 0 1m
ただ、残念ながら開発マシンから直接から Pod に接続する事は出来ません。Pod ごとに IP が割り振られていますが、ホスト側からは見えないのです。Pod の IP を取得してから、そこでコマンド一発でコンテナを動かせる kubectl run
を使って Kubernetes クラスタの中から curl コマンドで IP にアクセスします。
$ kubectl describe pod nginx-deployment-75675f5897-bgrph | grep IP
IP: 10.1.0.67
$ kubectl run curl --image=byrnedo/alpine-curl -i --rm --tty --restart=Never http://10.1.0.67
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
-
kubectl run: イメージから適当なリソースを作って動かす。
- --image: docker image を指定する。
- -i: 標準出力を開いたままにする。
- --rm: コマンド終了時に作成したリソースを消す。
- --tty: コンテナごとに TTY を割り当てる。
- --restart:
- Always: Deployment を作る。常に再起動する
- OnFailure: Job を作る。失敗時再起動する。
- Never: Pod だけ作る。再起動はしない。
ちなみに、コンテナでコマンドを実行するには kubectl exe
を使います。
$ kubectl exec -it nginx-deployment-75675f5897-bgrph -- cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 7 (wheezy)"
NAME="Debian GNU/Linux"
VERSION_ID="7"
...
Service を使う
さて、このままでは外部からコンテナに接続出来ないため何の役にも立ちません。コンテナと外部を結びつけるには Service の LoadBalancer タイプを使います。
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- name: http
port: 8087 # 公開するポート番号
targetPort: 80 # Pod のポート番号
Service は一連の Pod に名前をつけてお互いに通信出来るようにする物です。例えば上記の yaml を実行すると Kubernetes 内部の DNS に nginx
という名前が登録され、app: nginx のラベルをつけた Pod に nginx という名前でアクセス出来るようになります。この例では Service の 8087 ポートを Pod の 80 ポートに転送しています。
kubectl apply -f service.yaml
kubectl run curl --image=byrnedo/alpine-curl -i --rm --tty --restart=Never http://nginx:8087
Service にはいくつか type があります。この例では LoadBalancer を使っているので、ホストから直接 8087 にアクセス出来ます。ちなみに、本には LoadBalancer はローカル環境で使う事は出来ないと書いてあったのですが、何気なくやってみたら使えました。
curl http://localhost:8087
これでとりあえず複数のインスタンスを立ち上げ外部からアクセスする所までやりました。やり残した事:
- ストレージの設定
- Helm を使う