2018年3月17日土曜日

minikube のデフォルトで使える heapster なる監視ツールを使う方法

概要

minikube にはデフォルトで監視ツールが付いています
デフォルトだと disabled になっているだけなので enabled にしてあげるだけで使えます

環境

  • macOS 10.13.2
  • minikube 0.25.0
  • kubectl 1.9.2
  • VertualBox 5.1.30r118389

有効化

  • minikube addons enable heapster

起動確認

  • kubectl get po,svc -n kube-system
NAME                                       READY     STATUS    RESTARTS   AGE
po/heapster-fjmp7                          1/1       Running   0          3m
po/influxdb-grafana-fzzpn                  2/2       Running   0          3m
po/kube-addon-manager-minikube             1/1       Running   1          5h
po/kube-dns-54cccfbdf8-5mwdc               3/3       Running   3          5h
po/kubernetes-dashboard-77d8b98585-58pbv   1/1       Running   1          5h
po/storage-provisioner                     1/1       Running   1          5h

NAME                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
svc/heapster               ClusterIP   10.101.196.99    <none>        80/TCP              3m
svc/kube-dns               ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP       5h
svc/kubernetes-dashboard   NodePort    10.99.27.61      <none>        80:30000/TCP        5h
svc/monitoring-grafana     NodePort    10.99.68.139     <none>        80:30002/TCP        3m
svc/monitoring-influxdb    ClusterIP   10.100.191.113   <none>        8083/TCP,8086/TCP   3m

dashboard やら dns のアドオンも起動していますが、とりあえず全部 Running になれば OK です

UI 確認

  • minikube addons open heapster

で監視用の UI が起動します
heapster1.png

Grafana + influxdb でできているようです
Chronograf は使っていないようです

admin しかいないので必要であればユーザ登録しましょう
左上の Home から Cluster と Pods のメトリックがいきなり見れるので切り替えてみましょう
heapster2.png

ネームスペースごとに別れているようです
追加したコンテナも自動で監視が始まります

最後に

minikube で heapster という監視ツールを使ってみました
内部的には Grafana + influxdb のようです

とりあえずサクっとメトリックを見たいだけであればこれで十分かなと思います
あとは細かいアラートの設定や自分でみたいメトリックのカスタマイズをすれば良いのかなと思います

2018年3月16日金曜日

kubernetes 上でコンテナのスケールアウトを試してみた

概要

前回 kubernetes 上に DockerHub で公開しているイメージからコンテナをデプロイしてみました
今回はデプロイしたコンテナをスケールアウトしてみたいと思います

環境

  • macOS 10.13.2
  • minikube 0.25.0
  • kubectl 1.9.2
  • VertualBox 5.1.30r118389

スケールアウト

scale コマンドを使います
スケールアウトするコンテナ数は replicas で指定します

  • kubectl scale deployments/request-dumper --replicas=4

kubectl get deployments でスケールアウトしているか確認してみましょう

NAME             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
request-dumper   4         4         4            4           32m

こんな感じで数字の部分が 4 になっていれば OK です
kubectl get pods -o wide でコンテナの一覧を確認することができます

ロードバランシング

kubernetes はデフォルトでロードバランシングの機能があります

まず service を作成しましょう

  • kubectl expose deployment/request-dumper --type="NodePort" --port 4567

そしてホスト側でバインドしているポートを取得します

  • export NODE_PORT=$(kubectl get services/request-dumper -o go-template='{{(index .spec.ports 0).nodePort}}')

あとはこのポートにアクセスすれば勝手にバランシングしてくれます

  • curl $(minikube ip):$NODE_PORT

要するにいつものように service を定義すれば expose した deployment 配下にあるコンテナを自動でバランシングしてくれます

念のため kubectl logs -f [container_name] でログを確認しながらやるとちゃんとバランシングされていることがわかると思います

スケールダウン

最後にスケールダウンしてみましょう
と言ってもスケールアウトと同じです

  • kubectl scale deployments/request-dumper --replicas=2

これで kubectl get deployments/request-dumper で確認しましょう

NAME             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
request-dumper   2         2         2            2           47m

こんな感じでコンテナ数がスケールダウンしているのがわかります
deployments でイベントを確認してもスケールダウンしているのがわかります

  • kubectl describe deployments/request-dumper
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  51m   deployment-controller  Scaled up replica set request-dumper-5d75b447 to 1
  Normal  ScalingReplicaSet  22m   deployment-controller  Scaled up replica set request-dumper-5d75b447 to 4
  Normal  ScalingReplicaSet  5m    deployment-controller  Scaled down replica set request-dumper-5d75b447 to 2

最後に

kubernetes 上でコンテナのスケールアウト/ダウンを試してみました
ロードバランシングがデフォルトで付いているのは嬉しい点かなと思います

docker swarm の場合は haproxy などを使ってバランシングするのが定石ですが kubenetes ではそれらが不要になります
また今回紹介したロードバランシング以外にも External Load Balancer という機能もあるようです

2018年3月15日木曜日

kubernetes 上で Docker Hub にあるイメージからコンテナを立ち上げる

概要

前回 minikube を使ってローカル上に kubernetes 環境を構築してみました
今回はその上に Docker Hub で既に公開済みのイメージを使ってコンテナを立ち上げてみたいと思います

環境

  • macOS 10.13.2
  • minikube 0.25.0
  • kubectl 1.9.2
  • VertualBox 5.1.30r118389

コンテナの起動

  • kubectl run request-dumper --image=kakakikikeke/request-dumper

run コマンドを使います
ポイントは --image で DockerHub にあるイメージを指定するところ
リポジトリ名 (index.docker.io) を省略しているのは minikube ノードのデフォルトのレジストリが DockerHub になっているためです

$ minikube ssh
                         _             _            
            _         _ ( )           ( )           
  ___ ___  (_)  ___  (_)| |/')  _   _ | |_      __  
/' _ ` _ `\| |/' _ `\| || , <  ( ) ( )| '_`\  /'__`\
| ( ) ( ) || || ( ) || || |\`\ | (_) || |_) )(  ___/
(_) (_) (_)(_)(_) (_)(_)(_) (_)`\___/'(_,__/'`\____)

$ docker info | grep Registry
Registry: https://index.docker.io/v1/

あとはコンテナが起動するまで待ちます

  • kubectl get pods

外部からアクセスできるようにする

Running になったらコンテナにアクセスできるようにしましょう
expose コマンドを使います

  • kubectl expose deployment/request-dumper --type="NodePort" --port 4567

--port=4567 はコンテナで LISTEN しているポートを指定します
今回のアプリは Sinatra アプリで 4567 で LISTEN しているので、それを指定します
サービスの一覧を確認してノード側にバインドされているポートを確認します

  • kubectl get services
NAME             TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
kubernetes       ClusterIP   10.96.0.1     <none>        443/TCP          4h
request-dumper   NodePort    10.96.100.5   <none>        4567:30604/TCP   50s

今回は 30604 でバインドしていました
ちなみに以下のコマンドを使うことでポート部分だけを取得することができます

  • kubectl get services/request-dumper -o go-template='{{(index .spec.ports 0).nodePort}}'

この結果を変数に入れて使えば同じコマンドでアクセスし続けることも可能です

動作確認

curl でも叩いてみます

  • curl $(minikube ip):30604

これでアクセスできると思います
試しに service を削除してみるとアクセスできなくなると思います

  • kubectl delete service request-dumper

最後に

kubernetes 上に DockerHub で公開されているイメージを引っ張ってきてコンテナを起動してみました
特に考える点もなくそのまま素直に使うことができました

現在は minikube 1 台構成なので別のノードを追加して複数ホストでコンテナのデプロイも試してみたいなと思います
と思ったのですが minikube では現在マルチノード機能はないようです
https://github.com/kubernetes/minikube/issues/94

執筆次点では絶賛開発中だったのでそのうち対応されるかもしれません

2018年3月14日水曜日

minikube を使って kubernetes に入門してみた

概要

minikube はローカルで kubernetes クラスタを構築することができるツールです
今回は VirtualBox と minikube を使ってローカル環境に kubernetes 環境を構築してみました

環境

  • macOS 10.13.2
  • minikube 0.25.0
  • kubectl 1.9.2
  • VertualBox 5.1.30r118389

minikube インストール

brew を使って簡単にインストールできます

  • brew cask install minikube

インストールできたか確認してみましょう

  • brew cask info minikube
  • minikube version

minikube コマンドおよび kubectl コマンドが使えるようになっています

minikube ノードを起動する

minikube ノードは kubernetes 内で起動するマスターノードになります
今回ノードを作成する環境は VirtualBox にしています
minikube は VirtualBox 以外の仮想環境 (virtualbox xhyve vmwarefusion hyperkit) もサポートしているので VirtualBox 以外が良いという場合は別の環境を準備してそちらに構築しても OK です

  • minikube start
Starting local Kubernetes v1.9.0 cluster...
Starting VM...
Downloading Minikube ISO
 142.22 MB / 142.22 MB [============================================] 100.00% 0s
Getting VM IP address...
Moving files into cluster...
Downloading localkube binary
 162.38 MB / 162.41 MB [============================================]  99.98% 0s
 0 B / 65 B [----------------------------------------------------------]   0.00%
 65 B / 65 B [======================================================] 100.00% 0s
Setting up certs...
Connecting to cluster...
Setting up kubeconfig...
Starting cluster components...
Kubectl is now configured to use the cluster.
Loading cached images from config file.

--vm-driver というオプションで VM を管理するインフラを指定します
デフォルトだと「virtualbox」が指定されるようです
ISO のダウンロードが始まり minikube 内で VM が起動します

これで VirtualBox 上に minikube というノードが構築されます

  • VBoxManage list runningvms

"minikube" {43f30a82-89d7-4341-bc66-adad08d6b21c}

kubectl get nodes しても確認することができます

NAME       STATUS    ROLES     AGE       VERSION
minikube   Ready     <none>    58m       v1.9.0

とりあえずコンテナを構築してみる

ノードが構築できたらとりあえずコンテナを作ってみましょう

deployment の作成 (コンテナも起動)

deployment はコンテナ定義になります
run コマンドを使うことで deployment の作成とコンテナの起動を同時に行えます

  • kubectl run hello-minikube --image=k8s.gcr.io/echoserver:1.4 --port=8080

今回は echoserver という Web アプリのイメージを使います
8080 ポートでアプリが起動するようにオプションを付与しています

  • kubectl get deployments

これで deployment ができているか確認しましょう

service の作成

service は deployment の上位的な概念でコンテナのスケールやバランシングを行います
今回は作成したコンテナを外部に公開するために使います

  • kubectl expose deployment hello-minikube --type=NodePort

NodePort はコンテナにアクセスのにノードのポートを使ってアクセスすることが出来るタイプです

  • kubectl get services

とするとサービスの一覧を確認することができます

動作確認

あとはコンテナにアクセスしてみましょう

  • kubectl get pod

でコンテナが起動していることを確認して

  • curl $(minikube service hello-minikube --url)

でアクセスしてみましょう
今回の Web アプリはリクエスト情報をダンプするようなアプリなのでヘッダやボディの情報が返ってくると思います

今度は動きを確認しながら別のコンテナを起動してみる

deployment と service の動きをもう少し確認してみたいと思います
今後は別のコンテナを起動してみましょう
まずは deployment だけ作成してみます

  • kubectl run kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1 --port=8080

google-samples/kubernetes-bootcamp は簡単な nodejs アプリです
8080 で LISTEN するようにします

この状態ではコンテナ外部からアプリにアクセスすることはできません
なので今度はコンテナに直接入ってみます

  • kubectl get pods

で起動したコンテナの名前を確認しましょう
そして exec コマンドを使って bash を起動しコンテナに入ってみます

  • kubectl exec -it kubernetes-bootcamp-5dbf48f7d4-bt9b5 bash

これでコンテナに入れると思います
コンテナ内で直接アプリにアクセスできることを確認しましょう

  • curl localhost:8080

これだとノード経由でコンテナにアクセスできないので、そのために serivce を定義してあげます

  • kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080

これで kubectl get services を確認すると 8080 ポートがノード側のポートに動的にバインドされているのが確認できます
ノード側は今回は minikube しかないので minikube のポートにアクセスしています

NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes            ClusterIP   10.96.0.1       <none>        443/TCP          1h
kubernetes-bootcamp   NodePort    10.110.89.189   <none>        8080:32127/TCP   2m

あとはバインドされたノード側のポートにアクセスすればコンテナにアクセスできるようになります

  • curl $(minikube ip):32127

後処理

service -> deployment -> minikube 停止とすれば OK です

  • kubectl delete service hello-minikube
  • kubectl delete deployment hello-minikube
  • minikube stop

当然ですが service を delete した段階ではコンテナは削除されず deployment を削除したタイミングでコンテナも削除されます

Tips

minikube の管理用 UI を開く

  • minikube dashboard

ラベルを指定して pod を取得する (ラベルは describe service で取得できます)

  • kubectl get pods -l run=kubernetes-bootcamp

最後に

minikube を使ってローカルに kubernetes を試せる環境を構築してみました
かなり簡単に kubernetes を試せるようになったなと感じました

実際にプロダクジョンに適用する場合は minikube ではなく kubeadm という管理ツールがあるのでそれを使ってちゃんとサーバを構築してください

あとは minikube と kubectl コマンドが混同しないようにしましょう
kubectl は kubernetes クラスタ内に存在するコンテナやサービスの操作に使います
minikube は kubernetes クラスタ自体の操作に使うコマンドになります

docker swarm に慣れてしまっている人でも基本的な概念などは似ているのでそこまで取っ付きにくくないかなと思います
機能的には kubernetes のほうが多いので複雑なコンテナマネージメントをやりたい場合には kubernetes を使うことになると思います

参考サイト

2018年3月13日火曜日

Hulu を 2 年 3ヶ月間使ってみた感想

概要

実は Hulu を 2 年間以上使っていたのでその感想をまとめてみました
Good, Bad に分けて書いています
一応上に書いている項目ほどより Good より Bad という感じにしています

環境

  • Hulu 2015/12 から使用
  • 主な視聴デバイス
    • Google Chrome Cast
    • スマホ (iPhone, iPad, Android)
    • Mac Book Air

Good

  • 視聴できるデバイスが豊富に用意されている
    • iPhone, Android アプリが ChromeCast にも対応していたのは嬉しい
  • 無料期間が終了した次の日から月額課金の開始になるのがいい
    • 31 日に申し込んだからと言って次月の 1 日から課金開始ということにはならない
  • 暇な時間を映画やドラマ鑑賞で潰せる
  • 見たいドラマや映画があったときにいつでも見直せる
  • プロ野球のライブ配信をしてくれている
    • もしかしたらもう終了しているかも
    • ただなぜかライブ配信は ChromeCast に対応していない
  • 海外のドラマや映画はかなり充実している
  • オリジナルコンテンツが結構おもしろい (シリコンバレーなど)

Bad

  • 1 アカウントで複数デバイスの同時再生ができない
    • Netflix などは一番下のプランでも同時再生 2 デバイスまではいける
    • 家族で 1 アカウントを共有するスタイルだったので視聴履歴などが共有されてしまう (複数申し込めという話ですが、、、)
  • happyon.jp 事件
    • 日本法人への完全システム移行による有名なドメイン変更
    • 自分のデバイスでは大きく影響を受けたデバイスはなかったが、アプリの更新と再ログインが結構面倒で大変だった
    • というのも使っているデバイスが複数台あったのでアプリの更新とログインをその分行う必要があったので大変だった
    • あと移行当初はかなり重い状態が続き動画の画質が悪くなったなどの問題があった (最近はほとんどなくなったと思う)
  • 回線が重いとほぼ再生できない
    • これはどちらかというと自分の環境の問題かもしれないがインターネットの回線が重くなると動画が再生できない状況になる
    • というのも回線が専有回線ではなくマンションタイプのような共有回線だったので夕方から夜にかけてのゴールデンタイム中は回線が混むためほぼ動画の再生は不可能だった
    • 後述にある Bad で見なくなったという項目があるが、それの原因はこれかもしれない
  • 洋画の英語字幕がほしかった
  • 生活リズムがおかしくなった
    • 一時期海外ドラマにハマってしまい 1 日中ぶっ通しで見てしまう状況が続き生活リズムが崩れた (単純に自分のせいですが、、、)
    • 時間を決めて何時以降は強制的に見れないようになる、みたいな機能があると実は嬉しいかも
    • これと併せて外に出る機会が少なくなった気がする
    • 月額課金をしているせいか、見なければいけないという衝動にかられ無駄に見てしまう
  • 実はあまり見ていないということに気づく
    • ハマると永遠と見続けてしまうのですが、そうじゃない場合は意外と Hulu を見ていないということに気がついた
    • 少ないときだと 1 ヶ月の間で全く見ないという月もあった
    • 見たいコンテンツがなくなったというのが一番の原因かなと思うが、自分の場合は環境の変化 (家族が増えた) も原因の 1 つだと思う
    • 止めよう止めようと思った時期が結構あったが月額 1,000 円程度なのでダラダラと続けてしまっている

総括

一言でいうと良いサービスだと思います
他の人に薦めても恥ずかしくない有料コンテンツだと思います
ただ、料金や機能を考えると Netflix や AmazonPrime の方が良い点は多いかなと思います
配信されているコンテンツの総数は Hulu の方が多い印象ですが、アニメに限っては Netflix の方が強いイメージがあったり AmazonPrime に関しては EC サービスの Amazon.com 自体の恩地を受けれるのも大きいかなと思います

それぞれメリット・デメリットはあると思うので自分にあった動画配信サービスを選択してくださいというのが全てですが、料金もそこまで高額ではないので、いろんなサービスを転々として試してみるのもいんじゃないないかと思います

自分のこの機会にいい加減別サービスに移行してみようと思います

2018年3月10日土曜日

Swift4 でアラートを表示する方法

概要

UIAlertController を使います
いろいろとサンプルは転がっているので備忘録として残して残しておきます

環境

  • macOS 10.13.2
  • Xcode 9.2 (9C40b)

サンプルコード

func showAlert() {
    let alert = UIAlertController(title: "Let's play the game.", message: "You have not got history yet.", preferredStyle: UIAlertControllerStyle.alert)
    let ok = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)
    alert.addAction(ok)
    self.present(alert, animated: true, completion: nil)
}

これを画面が遷移した直後に表示したい場合は viewDidLoad ではなく viewDidAppear でコールしましょう
例えば以下のような感じです

override func viewDidAppear(_ animated: Bool) {
    if results.isEmpty {
        showAlert()
    }
}

viewDidLoad でコールすると Warning: Attempt to present * on * whose view is not in the window hierarchy という警告が表示されアラートが表示されないので注意してください

2018年3月9日金曜日

Xcode9 で UITableView に出てくるなぞのスペースを削除する方法

概要

UITableView を Storyboard で配置するとセルの周りになぞのスペースが入っています
左端に寄せたい場合などには邪魔になるので削除方法を紹介します

環境

  • macOS 10.13.2
  • Xcode 9.2 (9C40b)

使用するコード

以下の簡単な UITableView を使ったサンプルコードを準備しました

ViewController.swift

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!
    let data = ["ピカチュウ", "カイリュウ", "ヤドラン", "ピジョン", "コダック"]

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        let label = cell.viewWithTag(1) as! UILabel
        label.text = data[indexPath.row]
        return cell
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
}

storyboard から UITableView を IBOutlet を紐付けています
また、UITableViewDelegate, UITableViewDataSource を継承して最低限の cellForRowAtIndexPath と numberOfRowsInSection を実装しています

Main.storyboard

storyboard は以下のような感じです

uitable_remove_space1.png

やったこととしては

  • UITableView を配置
  • UITableView 内に UITableViewCell を配置
  • 「cell」という identifier を設定
  • Cell 内に UILabel を配置し背景をわかりやすいように色付け
  • UILabel に Tag = 1 を設定
  • UILabel に constraints を追加、上下左右に余白 0 の位置を指定
  • Outlets で ViewController に delegate と dataSource を紐付け

になります

これでとりあえず実行すると以下のようになぞのスペースができています
uitable_remove_space2.png

なぞというわけではないですがデフォルトでは Cell 内にマージンを作ってくれるようです
自分は不要なケースが多いので削除するのですが Xcode9 でやり方を知らなかったのでその方法を紹介します

削除方法

UILabel に設定した constraints を選択します
そして「Trailing Space to」を選択します
uitable_remove_space3.png

そして「First Item」を「Superview.Trailing」にします
すると Constant が 15 になっているのでこれを 0 にします
uitable_remove_space4.png

するとマージンがなくなります
今のは右側のマージンを削除したので、これと同じことを左、上下に対して行います

左
uitable_remove_space5.png

上
uitable_remove_space6.png

下
uitable_remove_space7.png

これで再度起動すると以下のようになります
uitable_remove_space8.png

ただこのままだとセルを区切るための線が一番左に行っていません
なので UITableViewCell の「Separator Inset」を「Custom」にし Left の値を 0 にすることで線も一番左まで行きます

最後に

UITableView で出来てしまうマージンを削除する方法を紹介しました
これを UIView でやればその中にコンポーネントを入れることができます

やってみて気づいたのですが、たぶん削除する必要はないかなと思っています
1 からセルをカスタマイズしたい場合には一度 UIView でマージンを潰したあとでデザインするのはありだと思います