Skip to content

Instantly share code, notes, and snippets.

@yhirano55
Last active March 10, 2017 08:22
Show Gist options
  • Save yhirano55/d6b9ce43a8eff4cc46eae0b095fd8413 to your computer and use it in GitHub Desktop.
Save yhirano55/d6b9ce43a8eff4cc46eae0b095fd8413 to your computer and use it in GitHub Desktop.

目的

  • Dockerを管理するフレームワーク。Google製。
  • 船の舵をとる人、という意味

構成例

仕組みを知るうえで、欠かせない概念

  • Pod
  • Label
  • Replication Controllers
  • Services

Pod

  • コンテナの集まり
  • 1 Pod 1 Container でも良い
  • Pod内のコンテナは、必ず同一ホストになる
  • ストレージとか、IPアドレスを共有しなければならないコンテナをまとめられる

Label

  • Podにラベルを自由に与えられる
  • たとえば環境を示すラベル(production, development, stagingなど)
  • 役割を示すラベル(Frontend, Backend, Worker, Loggerなど)
  • 1つのPodに複数のラベルが付けられる

Replication Controllers

  • Podのテンプレートから、指定された数のReplicaを作成する仕組み(Replicaは『「複製品」「模造品」「復刻版」』の意)
  • Podの監視をしていて、指定された数より多ければ減らし、少なければ減らす

image

Service

  • L3のプロキシみたいなもの
  • 設定したPodにラウンドロビンでアクセスを分配する

image

いろいろな環境で試せる

image

ただし、環境によって構築方法は異なる。

  • Kubernetesリポジトリの、Getting Started Guideを参照するとよい。
  • GCEで構築するのはめちゃくちゃ楽

知見

資料

Hello, Minikube

ゴール

  • 環境構築
  • Minikubeクラスタの作成
  • 単純なNode.jsアプリをkubernetes上で動作させる

環境構築

前提

  • MacOS
  • Docker for Mac

準備

Install vm-driver: xhyve

$ brew install xhyve
$ brew install docker-machine-driver-xhyve
$ sudo chown root:wheel $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
$ sudo chmod u+s $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
  • docker-machine がインストールされますが気にせずに

Install minikube

$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
  • brew cask install minikube でもインストールできます。
  • 公式チュートリアルだと上記を推奨しています。

Install kubectl

$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
$ chmod +x ./kubectl
$ sudo mv ./kubectl /usr/local/bin/kubectl
  • brew install kubectl でもインストールできます。
  • 公式チュートリアルだと上記を推奨しています。

Minikubeクラスタの作成

$ minikube start --vm-driver=xhyve

作成したクラスタと通信できることを確認します(設定の表示)

$ kubectl cluster-info

Node.jsアプリケーションの作成

  1. hellonode ディレクトリを作成

  2. 以下のJavaScriptを server.js として保存

  3. サーバーを起動

    $ mkdir hellonode $ vim hellonode/server.js $ node hellonode/server.js

var http = require('http');

var handleRequest = function(request, response) {
  console.log('Received request for URL: ' + request.url);
  response.writeHead(200);
  response.end('Hello World!');
};
var www = http.createServer(handleRequest);
www.listen(8080);

Dockerfileの作成

hellonode/Dockerfile を作成します

FROM node:6.9.2
EXPOSE 8080
COPY server.js .
CMD node server.js

Minikubeホストを使用しているため、環境変数をexportします。

$ eval $( minikube docker-env ) 

Minikube Dockerデーモンを使用して、Dockerイメージをビルドします。

$ docker build -t hello-node:v1 .

デプロイメント

Kubernetes Podは、1つないし複数のコンテナのグループであり、管理およびネットワークの目的で一緒に結び付けられています。このチュートリアルのPodには1つのコンテナしかありません。

Kubernetes Deploymentは、ポッドの正常性をチェックし、ポッドのコンテナが終了した場合は再起動します。ポッドの作成とスケーリングを管理するには、デプロイメントをお勧めします。

デプロイする

$ kubectl run hello-node --image=hello-node:v1 --port=8080 

depoloymentを表示する

$ kubectl get deployments

Podを表示する

$ kubectl get pods

クラスタイベントを表示する

$ kubectl get events

kubectlで設定を表示する

$ kubectl config view -o yaml

サービスの作成

デフォルトでは、PodはKubernetesクラスタ内の内部IPアドレスによってのみアクセス可能です(EXPOSEするまで、外部には公開されていない状態)。

hello-nodeコンテナにKubernetesの仮想ネットワークの外部からアクセスできるようにするには、PodをKubernetesサービスとして公開する必要があります。

サービスとして公開する(サービスの作成)

$ kubectl expose deployment hello-node --type=LoadBalancer
  • --type=LoadBalancer フラグは、サービスをクラスタ外に公開することを示します。
  • ロードバランサをサポートするクラウドプロバイダでは、サービスにアクセスするために外部IPアドレスがプロビジョニングされます。

作成したサービスを確認する

$ kubectl get services

ブラウザで展開する

$ minikube service hello-node

ログを表示する

$ kubectl logs <POD-NAME>

出典

https://kubernetes.io/docs/tutorials/stateless-application/hello-minikube/

kubernetesとは

kubernetesは、複数台のサーバーを対象に、複数のコンテナを、ネットワークのルーティングも含め、横断的に管理できるプロダクト(デプロイ/オーケストレーションツール)

kubernetesが提供する機能

  • 関連するコンテナのグルーピング
  • コンテナに割り振られるIPアドレスの管理
  • コンテナ間のネットワークルーティング管理
  • 複数のコンテナを利用した負荷分散
  • コンテナに割り当てるストレージの管理
  • コンテナの監視

kubernetesを構成するコンポーネント

コンポーネント名 説明
apiserver kubernetesを操作するためのAPIを提供する
controller-manager コンテナの状態管理やノードの管理と言った各種管理作業を行う
proxy コンテナへのネットワークルーティングおよび負荷分散を行う
scheduler 各ノードに対しコンテナの割り当てなどを行う
kubelet 各ノード上でのコンテナ作成/削除やボリュームの割り当てなどを行う
kubectl API経由でKubenetesを操作するためのクライアントツール

kubernetesの基本的な構成

image

クラスタ環境の例

image

基本操作

Podを作る

設定ファイルを作る

apiVersion: v1
kind: Pod  ←Podに関する設定ファイルであることを指定
metadata:  ←メタデータに関する情報を指定
  name: httpd  ←Podの名前を指定
  labels:  ←Podに付与するラベルを指定
    app: httpd
spec:
  containers:
  - name: httpd  ←コンテナ名を指定
    image: httpd  ←コンテナを作成する際に使用するイメージを指定
    ports:
    - containerPort: 80  ←コンテナに外部からアクセスできるポートを指定

Podを作る

$ kubectl create -f pod-httpd.yaml
pods/httpd

Podを作成すると、自動的に指定したコンテナが作成される。Podを動かしているノードで「docker ps」を実行すると、コンテナが稼働していることが確認できる。

Podの稼働状況の確認

$ kubectl get pods
NAME      READY     STATUS    RESTARTS   AGE
httpd     0/1       Pending   0          6s

詳しい情報を知りたいときは、 -o yaml オプションを付けると、設定ファイルが確認できる。

永続ストレージを利用する(Volume)

  • 永続ストレージはコンテナ外のストレージをコンテナ内の指定したディレクトリにマウントすることで実現される。
  • 使用できるストレージとしてはノードのローカルファイルシステムやGoogle Compute Engine、Amazon Web Serviceなどのクラウドストレージ、NFS、iSCSIなどから選択可能。

設定例

apiVersion: v1
kind: Pod
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  volumes:
  - name: mysql-storage  ←ボリューム名を指定
    hostPath:
      path: /var/kube-test/mysql-db  ←ボリュームとして使用するローカルファイルシステムのパスを指定
  containers:
  - name: mysql
    image: mysql
    volumeMounts:
    - name: mysql-storage  ←コンテナにマウントするボリューム名を指定
      mountPath: /var/lib/mysql  ←マウント先を指定
    ports:
    - containerPort: 3306
    env:  ←環境変数を指定
    - name: MYSQL_ROOT_PASSWORD
      value: <MySQLのrootパスワード>
  • ローカルファイルシステムを永続ストレージとして指定した場合、Podが実行されるノードが変わるとストレージ上の内容も変わってしまう点には注意。
  • 実行されるノードが変わっても同じデータを参照したい場合はNFSやiSCSIなどを利用するか、もしくはクラウドストレージを利用することになる。

Podに特定のIPアドレスを割り当てる(Services)

  • kubernetesでは、どのPodがどのノードで実行されるかはPodの作成時に決定される。
  • Podが作成されるまではそれぞれのPodにどのIPアドレスが紐付けられるかは分からない。
  • 指定したPodに特定のIPアドレスを割り当てるための「Service」という仕組みが用意されている。

Serviceの設定

apiVersion: v1
kind: Service  ←Serviceの定義であることを指定
metadata:
  name: mysql-master  ←Service名を指定
spec:
  ports:
    - port: 3306  ←Serviceが使用するポート番号を指定
  selector:  ←対象とするPodをラベルで指定
    app: mysql

Serviceの作成

$ kubectl create -f service-mysql.yaml
services/mysql-service

Serviceの確認

$ kubectl get services
NAME           LABELS                                    SELECTOR    IP(S)           PORT(S)
kubernetes     component=apiserver,provider=kubernetes   <none>      10.254.0.1      443/TCP
mysql-master   <none>                                    app=mysql   10.254.31.188   3306/TCP
Serviceに応じた環境変数
  • Serviceを作成すると、各コンテナ内ではそれに応じた環境変数が作成される。
  • 「mysql-master」というServiceの場合、そのServiceにアクセスするためのIPアドレスが「MYSQL_MASTER_SERVICE_HOST」という環境変数に、Serviceが使用するポートが「MYSQL_MASTER_SERVICE_PORT」という環境変数に格納される。
  • MySQLデータベースを使用するアプリケーションを稼動させるPodでは、これらの環境変数を使って接続先データベースのホストを指定するようにすれば良い。

出典

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment