11
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Kubernetes で 複数の nginx インスタンスを手元の Mac に立ち上げる

Last updated at Posted at 2018-09-04

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

上記コマンドの意味:

  • 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 に名前をつけてお互いにアクセス出来るようにする。また外部からアクセス出来るようにする。
  • 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 を使う

Yaml 文法

  • 先頭が - で始まるとリスト。[x, y, z] の形式もリスト
  • 途中 : があると辞書。{x: a, y: b, z: c} の形式もリスト
  • より後ろはコメント

参考

11
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?