2018年6月1日金曜日

Ruby で erb を普通に使う方法

概要

Sinatra などで HTML を返却するときに erb を使いますが普通の Ruby スクリプト内でも使えます

環境

  • macOS 10.13.4
  • Ruby 2.5.1p57

サンプル

  • vim test.rb
require 'erb'

erb = ERB.new(File.read("./doc.erb"))
@title = 'hoge'
ret = erb.result(binding)
puts ret
  • vim doc.erb
@title => <%= @title %>

で実行すると test.rb で @title 変数に設定した 値が表示されると思います
ヒアドキュメントでも同じようなことはできますが、erb を使ったほうがきれいに書けるケースもあると思います

trim_mode をつかう場合

ERB.new する際に第三引数で trim する文字列を指定します

  • vim test.rb
require 'erb'

erb = ERB.new(File.read("./doc.erb"), nil, '-')
@titles = ['hoge', 'hoge1', 'hoge2']
ret = erb.result(binding)
puts ret
  • vim doc.erb
<%- @titles.each { |title| -%>
@title is <%= title %>
<%- } -%>

2018年5月31日木曜日

Sinatra でコントローラを分離する方法

概要

app.rb など一つのファイルにいろいろなルーティングを実装するとファイルを分けたくなると思います
今回はその方法を紹介したいと思います
おそらく王道の方法かなと思います

環境

  • macOS 10.13.4
  • Ruby 2.5.1p57
  • Sinatra 2.0.1

各種ファイルの準備

  • bundle init
  • vim Gemfile
gem "sinatra"
  • bundle install --path vendor
  • touch config.ru
  • mkdir controllers
  • touch controllers/home.rb
  • touch controllers/admin.rb
  • mkdir views
  • touch views/home.erb
  • touch views/admin.erb

今回は分離するコントローラは controllers というディレクトリで管理することにします
全体の構成は以下のとおりです

.
├── .bundle
│   └── config
├── Gemfile
├── Gemfile.lock
├── config.ru
├── controllers
│   ├── admin.rb
│   └── home.rb
└── views
    ├── admin.erb
    └── home.erb

3 directories, 8 files

config.ru の作成

Sinatra でコントローラを分ける場合、パスごとに処理するコントローラを Rack::URLMap という機能を使って定義します
今回は 2 つのルーティングを違うコントローラを使って処理します

require './controllers/home.rb'
require './controllers/admin.rb'

run Rack::URLMap.new({
        '/' => Home,
        '/admin' => Admin
})

作成した Rack::URLMap を run することを忘れないようにしてください
home.rb に Home クラスを admin.rb に Admin クラスを後で定義します

home.rb の作成

先程定義した / ルーティングを処理するクラスを定義します

  • vim controllers/home.rb
require 'sinatra/base'

class Home < Sinatra::Base
        set :root, File.join(File.dirname(__FILE__), '..')
        set :views, Proc.new { File.join(root, "views") } 

        get '/' do
                erb :home
        end

        get '/users' do
                'users'
        end
end

今回は 2 つの処理を記載しました
/ に対する処理と /users に対する処理です
ついでにテンプレートも作成します

  • vim views/home.erb
home

とりあえず文字列を返すようにします
作成したクラスは必ず Sinatra::Base を継承します
また今回のようにコントローラをアプリケーションの直下ではなく controllers といったサブディレクトリに配置する場合には Sinatra の :root:views の書き換えが必要になります

set :root, File.join(File.dirname(__FILE__), '..')
set :views, Proc.new { File.join(root, "views") } 

何をしているかというと home.rb の一つ上位のディレクトリを :root に設定しかつ :root 配下にある views というディレクトリをテンプレートを定義するディレクトリとして設定しています
デフォルトだとこれがコントローラクラスの直下になっています

admin.rb の作成

今度は /admin 配下を処理する Admin クラスを定義します

  • vim controllers/admin.rb
require 'sinatra/base'

class Admin < Sinatra::Base
        set :root, File.join(File.dirname(__FILE__), '..')
        set :views, Proc.new { File.join(root, "views") } 

        get '/' do
                erb :admin
        end

        get '/users' do
                'admin users'
        end
end
  • vim views/admin.erb
admin

先程の home.rb とほぼ同じように定義されていることがわかります
が、admin.rb/admin 配下のルーティングを処理します
なので上記の場合、処理するパスとしては /admin/admin/users が対象になります
このように URLMap で定義したパスはコントローラ内の実装では省略することができます

動作確認

  • bundle exec rackup config.ru

で起動しましょう
localhost:9292 で起動します
確認するパスとしては以下の 4 つです

  • / -> home が返ってくる
  • /users -> users が返ってくる
  • /admin -> admin が返ってくる
  • /admin/users -> admin users が返ってくる

となれば OK です
上記以外のパスにアクセスした場合は Sinatra のデフォルトの 404 ページが返ってくると思います

ちょっとしたテクニック

「404 や 500 ページは共通のページを出したい」
「コントローラクラスに毎回 :root:views を定義するのは面倒」
という場合には Base クラスを作成しましょう

  • vim controllers/base.rb
require 'sinatra/base'

class Base < Sinatra::Base
        set :root, File.join(File.dirname(__FILE__), '..')
        set :views, Proc.new { File.join(root, "views") } 
end

そして home.rb で継承するクラスを Base クラスに変更すれば OK です

  • vim controllers/home.rb
require './controllers/base.rb'

class Home < Base
        get '/' do
                erb :home
        end

        get '/users' do
                'users'
        end
end

こうすることで毎回定義する必要がなくなります
また、先程少し出てきた 404 ページの処理などもこの base.rb に記載すれば継承した home.rb などで実装する必要がなくなります

また rspec と組み合わせたテストを行いたい場合は spec_helper.rb で app メソッドを定義する際に Rack::URLMap を返すようにすれば OK です
各種コントローラクラスの require も忘れないようにしてください

module RSpecMixin
  include Rack::Test::Methods

  def app
    Rack::URLMap.new({
      '/' => Home,
      '/admin' => Admin
    })
  end
end

最後に

Sinatra でコントローラを分離する方法を紹介しました
おそらくこれが王道の方法だと思います

このあたりの処理は Sinatra では自分で実装するしかありません
が、rails などを使えばフレームワーク側で全部やってくれるものもあります
ただ、rails の場合はルーティングを追加すると実装するべき関数も勝手にいろいろ定義されるのでやりすぎちゃう感もあります
この辺りは自分のやりたいことに合わせて選択すれば良いかなと思います

参考サイト

2018年5月30日水曜日

Mac で Android の動画撮影をしよう

概要

android-tool という定番ソフトを使えば簡単に撮影することできます

環境

  • macOS 10.13.4
  • android-tool 1.66
  • Huawei p9 lite

事前準備

今回使用する端末は SIM フリー版の Huawei p9 lite です
事前にデベロッパーモード+ USB デバッグを ON にしておきましょう

  • 設定アプリ -> 端末情報 -> ビルド番号

を 7 回タップすれば OK です
そして

  • 設定アプリ -> 開発向けオプション -> USB デバッグ

のトグルを ON にしましょう
何度か確認が出ますがすべて許可してください

android-tool のインストール

  • brew cask install androidtool

zip をダウンロードして .app を配置しても OK です

起動する

まずは android-tool を起動しましょう
ミッションコントロールとか Spotlight から起動すれば OK です
android_tool1.png

こんな感じになった Mac に端末を接続しましょう
Android 側に許可するかどうか確認するダイアログが出たら許可するを選択してください
問題なく認識されると以下のように表示が変わります
android_tool2.png

動画を撮影する

で撮影してみようと思ったのですがどうやら High Sierra だと現状動作しないようです、、、

開発も止まっているようで修正は厳しいと思います
adb コマンドを使えばできるようですが、p9 lite には screenrecord コマンドがないので動きません

仕方ないので p9 lite の動画撮影機能を使う

はじめからこれを使えば良かったのですが p9 lite には純正の録画機能があるようです

使い方は簡単で電源ボタン+ボリュームアップボタンを長押ししましょう
すると録画開始画面になるので「有効」を選択します
(ちなみに Android から Mac へのファイルの転送は Android File Transfer を使っています)

3, 2, 1 のカウントダウン後に録画が開始されます
終了したい場合は再度「電源ボタン+ボリュームアップボタン」を押せば OK です
撮影したデータは Pictures -> Scrrenshots 配下にあります
android_tool4.png

マイクも有効になるのでしゃべると声が入ってしまうので注意してください

最後に

androidtool をつかう予定でしたがどうやら High Sierra では動作しないということがわかったので急遽 p9 lite に標準で搭載されている録画アプリを使ってみました
他にも探せば同じようなアプリが出てくるのでマイクの録音をしたくない場合などには別のアプリを使ってみてください

2018年5月29日火曜日

macOS High Sierra に ngrok をインストールして使ってみる

概要

ngrok は簡単に言えば localhost で動作しているアプリをインターネットに公開することができるツールです
主にはテスト等で使用します

環境

  • macOS 10.13.4
  • ngrok 2.2.8

ngrok のインストール

  • brew cask install ngrok

使ってみる

とりあえず localhost で何かアプリを動作させてみましょう
何でも OK なので適当に docker で動かします

  • docker run -d -p 8080:80 nginx

この 8080 ポートを ngrok を使ってインターネットからアクセスできるようにしてみます

  • ngrok http 8080

するとターミナルが以下のような表示なります
ここで表示されている ngrok.io のアドレスにアクセスしてみましょう
ngrok1.png

すると以下のようにちゃんと nginx のデフォルト画面が表示されると思います
ngrok2.png

更にターミナルには nginx のログが表示されています
ngrok3.png

終了する場合は Ctrl+c で終了できます

最後に

macOS に ngrok をインストールして使ってみました
ngrok にはアカウントの登録機能があるようですが、この機能はアカウント登録なしで使えるようです

何に使うのかですが、例えば OGP タグの動作確認などあります
localhost だと動作しない場合にドメインを降ることで OGP タグの動作を確認することができます

かなり便利なので覚えておいて損はないと思います

参考サイト

2018年5月28日月曜日

標準ライブラリの net/http を使ったサンプル集

概要

net/http は Ruby に標準でインストールされている HTTP のクライアントライブラリです
Ruby にはいろいろな HTTP のクライアントライブラリがありますがこれは標準で使えます
gem をインストールするまでもない場合は net/http を使えば OK です
簡単な使い方のサンプルを紹介します

環境

  • macOS 10.13.4
  • Ruby ruby 2.5.1p57

とりあえず GET する

require 'net/https'

uri = URI.parse 'https://kaka-request-dumper.herokuapp.com/'
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new uri.request_uri
res = http.request req
pp res.body

GET 時にクエリストリングを設定する

require 'net/https'

uri = URI.parse 'https://kaka-request-dumper.herokuapp.com/'
p = { "key" => "value" }
uri.query = URI.encode_www_form(p)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new uri.request_uri
res = http.request req
pp res.body

ヘッダを設定する

require 'net/https'
require 'json'

uri = URI.parse 'https://kaka-request-dumper.herokuapp.com/'
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new uri.request_uri
req['X-Test-Header'] = 'test_header'
res = http.request req
pp JSON.parse(res.body)['headers']['HTTP_X_TEST_HEADER']

req にハッシュとして追加すれば OK です
Content-Type などは専用のメソッドがあります

  • req.content_type = 'text/xml'

レスポンスヘッダを取得する

require 'net/https'

uri = URI.parse 'https://kaka-request-dumper.herokuapp.com/'
p = { "key" => "value" }
uri.query = URI.encode_www_form(p)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new uri.request_uri
res = http.request req
res.each_header { |k,v|
  p "#{k} => #{v}"
}
p res['content-length']
pp res.body

res.eachEnumerator が返ってくるので注意

POST する

require 'net/https'
require 'json'

uri = URI.parse 'https://kaka-request-dumper.herokuapp.com/'
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new uri.request_uri
res = http.request req
pp JSON.parse(res.body)['method']

パラメータ付きで POST する

require 'net/https'
require 'json'

uri = URI.parse 'https://kaka-request-dumper.herokuapp.com/'
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new uri.request_uri
req.content_type = 'application/json'
req.body = { 'test_key' => 'test_value' }.to_json
res = http.request req
pp JSON.parse(res.body)['body']

XML をボディに設定する

require 'net/https'
require 'json'

uri = URI.parse 'https://kaka-request-dumper.herokuapp.com/'
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new uri.request_uri
req.content_type = 'text/xml'
req.body = '<Root><Name>bob</Name><Age>30</Age></Root>'
res = http.request req
pp JSON.parse(res.body)['body']

DELETE をコールする

require 'net/https'
require 'json'

uri = URI.parse 'https://kaka-request-dumper.herokuapp.com/'
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Delete.new uri.request_uri
res = http.request req
pp JSON.parse(res.body)['method']

http にアクセスしたい場合

net/https の代わりに net/http を require し

  • http.use_ssl = true

の設定を削除すればそれ以外のコードをそのまま使えます

最後に

net/http の簡単な使い方を紹介しました
他にもいろいろな使い方があるので詳細は公式のドキュメントを見ることをおすすめします

2018年5月27日日曜日

xmlsimple で xml_out を使ってハッシュから XML を生成する場合のコツ

概要

Ruby の xmlsimple ライブラリを使ってハッシュから XML を生成してみました
基本的な使い方から使う際のポイントを紹介します

環境

  • macOS 10.13.4
  • Ruby 2.5.1p57
  • xmlsimple 1.1.5

xml_out のサンプル

とりあえずサンプルです
今回は AWS の route53 でゾーンを作成するために必要な XML CreateHostedZoneRequest を作成してみます
ハッシュを定義してそれを食わすことで XML を出力しています

require 'xmlsimple'

body = { 
  '@xmlns' => 'https://route53.amazonaws.com/doc/2013-04-01/',
  'Name' => ['content' => ''],
  'CallerReference' => ['content' => ''],
  'HostedZoneConfig' => {
    'Common' => ['content' => ''],
    'PrivateZone' => ['content' => ''],
  },
  'DelegationSetId' => ['content' => ''],
  'VPC' => {
    'VPCId' => ['content' => ''],
    'VPCRegion' => ['content' => ''],
  }
}

options = {
  'AttrPrefix' => true,
  'RootName' => 'CreateHostedZoneRequest',
  'ContentKey' => 'content'
}

puts XmlSimple.xml_out(body, options)

結果は以下のようになります
どうしてこうなるのか詳細を説明します

<CreateHostedZoneRequest xmlns="https://route53.amazonaws.com/doc/2013-04-01/">                                                  
  <Name></Name>
  <CallerReference></CallerReference>
  <HostedZoneConfig>
    <Common></Common>
    <PrivateZone></PrivateZone>
  </HostedZoneConfig>
  <DelegationSetId></DelegationSetId>
  <VPC>
    <VPCId></VPCId>
    <VPCRegion></VPCRegion>
  </VPC>
</CreateHostedZoneRequest>

説明

XML に変換する対象のハッシュ body はとりあえずおいておきます

XmlSimple では hash -> XML の変換ルールを options で定義します
今回は AttrPrefix, RootName, ContentKey の 3 つの設定をしています
他にも様々な設定ルールがあります
(サイトは CPAN のドキュメントになります)

その中でも上記 3 つのオプションはよく使うと思います
それぞれ説明すると

  • AttrPrefix・・・@ で始まるキーがあった場合はそれを XML のタグとして使用せず属性として使用する
  • RootName・・・XML のルートドキュメントの名前を指定します、これを指定しない場合は <opt> になってしまいます
  • ContentKey・・・XML の値として使用するデータを明示的に指定することができます

となります
ここで body とそれぞれのオプションの効果を見ていきます
まず冒頭の '@xmlns' => 'https://route53.amazonaws.com/doc/2013-04-01/' ですがこれは AttrPrefix の効果でタグにはなりません
ルートの位置で定義しているのでルートの属性情報として使用されます

  • <CreateHostedZoneRequest xmlns="https://route53.amazonaws.com/doc/2013-04-01/">

次にハッシュの各所に定義してある ['content' => ''] ですが、これは ContentKey が影響します
このオプションの値とハッシュ内で使われている値がどちらも content になっているのがわかると思います
つまりこの content の値で指定したデータが XML に出力されたときのタグないのデータになるわけです
ContentKey は必須ではないですが、タグに属性が入る場合はほぼ必須になると思います
またデータとなるキーがわかりやすくもなるので使うことをおすすめします

最後に RootName ですがこれは生成したい XML ルートを指定するだけです

Tips

XML declaration を定義したい

例えば <?xml version='1.0' standalone='yes'?> の情報です
XML の先頭に付与する情報になります
XmlDeclaration というオプションが使えるのでそれを使います
先頭に追加したい文字列を直接指定することで追加することができます

options = {
  'AttrPrefix' => true,
  'RootName' => 'CreateHostedZoneRequest',
  'ContentKey' => 'content',
  'XmlDeclaration' => '<?xml version=\'1.0\' standalone=\'yes\'?>'                                                                
}

xml_in は可逆ではない

例えば今回生成できた XML をそのまま xml_in メソッドに投げも同じハッシュを得ることはできません

out = XmlSimple.xml_out(body, options)
pp XmlSimple.xml_in(out)
{"xmlns"=>"https://route53.amazonaws.com/doc/2013-04-01/",
 "Name"=>[{}],
 "CallerReference"=>[{}],
 "HostedZoneConfig"=>[{"Common"=>[{}], "PrivateZone"=>[{}]}],
 "DelegationSetId"=>[{}],
 "VPC"=>[{"VPCId"=>[{}], "VPCRegion"=>[{}]}]}

当然と言えば当然ですが上記のようになります
ハッシュからデータを取得するときに気をつけるのはデータの部分が必ず配列に格納されている点ですデータが 1 つしかなくても配列に入ります

最後に

Ruby の xmlsimple を使ってハッシュから XML を生成してみました
結構クセのある使い方をするのとドキュメントが少ないのが辛い点です

ハッシュから XML に変換するのであればこの方法でも良いですが単純に XML を欲しいだけであれば nokogiri や rexml でも生成できます
もしくは erb を使って XML をテンプレート化すればそこからでも XML 情報を生成することができます

今回紹介した方法も XML を生成する手段の一つにしかすぎませんので各自の環境にあった最適な方法を選択するようにしてください

2018年5月26日土曜日

Ubuntu16.04 に kubernetes をインストールしてみた

概要

Ubuntu に kubernetes をインストールしてみました
今回はクラウドは使わず localhost の lxd 上に必要なコンポーネントをデプロイしています

環境

  • Ubuntu 16.04
  • conjure-up 2.5.6
  • kubernetes 1.10
  • lxd 3.0.0 (required)

snapd のインストール

  • apt -y install snapd

conjure-up のインストール

  • snap install conjure-up --classic

一旦ログアウトして再度ログインしましょう
conjure-up の設定を反映させます

lxd のインストール

今回は localhost に対して kubernetes 環境を構築するので lxd が必要になります
lxd 上に必要なコンポーネントをデプロイします

  • snap install lxd

lxd の初期化

  • lxd init

いろいろ聞かれます
3 箇所で設定を変更しています

  • Name of the storage backend to use -> dir
  • What IPv6 address should be used? -> none
  • Would you like LXD to be available over the network? -> yes

あとはすべてデフォルトを設定しています

Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:                                                             
Name of the new storage pool [default=default]:
Name of the storage backend to use (btrfs, ceph, dir, lvm, zfs) [default=zfs]: dir                                               
Would you like to connect to a MAAS server? (yes/no) [default=no]:                                                               
Would you like to create a new local network bridge? (yes/no) [default=yes]:                                                     
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:                                       
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: none                                  
Would you like LXD to be available over the network? (yes/no) [default=no]: yes                                                  
Address to bind LXD to (not including port) [default=all]:
Port to bind LXD to [default=8443]:
Trust password for new clients:
Again:
No password set, client certificates will have to be manually trusted.Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:

Error: Failed to create network 'lxdbr0': Failed to run: dnsmasq ... みたいなエラーが出る場合はすでに 53 ポートをバインドしているプロセスがあります (参考)
例えば bind などを動かしている場合はエラーになるので停止してあげます

  • systemctl stop bind9

ユーザの作成

conjure-up コマンドは root ユーザでは実行できないのでコマンドを実行する専用のユーザを作成します

  • adduser conjure
Adding user `conjure' ...
Adding new group `conjure' (1000) ...
Adding new user `conjure' (1000) with group `conjure' ...
The home directory `/home/conjure' already exists.  Not copying from `/etc/skel'.
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
Changing the user information for conjure
Enter the new value, or press ENTER for the default
        Full Name []: 
        Room Number []: 
        Work Phone []: 
        Home Phone []: 
        Other []: 
Is the information correct? [Y/n] Y

こんな感じで作成すれば OK です
パスワードなど対話形式で聞かれますので適当に設定してください

あと lxd のグループに追加し sudo ができるようにします

  • usermod -a -G lxd conjure
  • gpasswd -a conjure sudo

移行の作業は作成した conjure ユーザで行います

kubernetes のインストール

  • su - conjure
  • conjure-up kubernetes

対話形式でインストールします
矢印の上下で「Kubernetes Core」を選択して Enter でインストールしましょう
ubuntu_kube1.png

どの環境を使用するか選択する画面になるので、今回は「localhost」を選択します
lxd が起動していれば localhost が選択できるようになっています
選択できない場合は lxd が起動しているか conjure ユーザが lxd グループに所属しているなど調べてください
ubuntu_kube2.png

ネットワークブリッジとストレージプールを選択します
とりあえずそのままで OK です
TAB でカーソルを Save に合わせて Enter で次に行きます
ubuntu_kube3.png

ネットワークプラグインは flannel を選択します
ubuntu_kube4.png

sudo のパスワードを入力します
ubuntu_kube5.png

各コンポーネントをデプロイする設定をします
ここもデフォルトで OK です
ubuntu_kube6.png

デプロイされるので待ちましょう
ubuntu_kube7.png

以下の画面にならないでエラーになってしまう場合は ufw をオフにしてみてください

  • ufw disable

lxd 上に各コンポーネントのデプロイが完了するまで待ちましょう
各コンポーネント間で連携チェックをしながらデプロイされるので、ここは割りと時間がかかります
maintenance や blocked のステータスを繰り返しますが active になるまで辛抱強く待ちます
ubuntu_kube8.png

すべて active になれば次に進みます
Quit でインストールを完了します
ubuntu_kube9.png

動作確認

kubectl コマンドが使えるので確認してみます

  • kubectl --kubeconfig=.kube/config cluster-info

これでダッシュボードの IP の情報や各コンポーネントのエンドポイントが表示されると思います

また lxc list コマンドで lxd 上に各コンポーネントがデプロイされていることも確認できると思います

+---------------+---------+-----------------------+------+------------+-----------+
|     NAME      |  STATE  |         IPV4          | IPV6 |    TYPE    | SNAPSHOTS |
+---------------+---------+-----------------------+------+------------+-----------+
| juju-6e5d3b-0 | RUNNING | 10.156.235.117 (eth0) |      | PERSISTENT | 0         |
+---------------+---------+-----------------------+------+------------+-----------+
| juju-de4886-0 | RUNNING | 10.156.235.71 (eth0)  |      | PERSISTENT | 0         |
|               |         | 10.1.82.0 (flannel.1) |      |            |           |
|               |         | 10.0.113.1 (lxdbr0)   |      |            |           |
+---------------+---------+-----------------------+------+------------+-----------+
| juju-de4886-1 | RUNNING | 172.17.0.1 (docker0)  |      | PERSISTENT | 0         |
|               |         | 10.156.235.35 (eth0)  |      |            |           |
|               |         | 10.1.5.1 (cni0)       |      |            |           |
|               |         | 10.1.5.0 (flannel.1)  |      |            |           |
+---------------+---------+-----------------------+------+------------+-----------+

おまけ kubernetes-master のエンドポイントにアクセスする

今回だと lxdbr0 の IP が振られてしまっているため Ubuntu からしかアクセスできません
が SSH のポートフォーワードを使えばクライアントマシンにアクセスすることでエンドポイントにアクセスすることができます

  • ssh -N -L localhost:6443:10.156.235.71:6443 root@kube -i /path/to/secret.pem

これで https://localhost:6443 で master の API 一覧を確認することができます
ちなみにパスワードは

  • kubectl --kubeconfig=.kube/config config view

で確認できます
ちなみにダッシュボード URL が長いのですが

  • https://10.156.235.71:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy

ubuntu_kube10.png
でアクセスできます (IP の部分は各自の lxdbr0 の IP に変更してください)
ログインするには

  • kubectl -n kube-system get secret
  • kubectl -n kube-system describe secret default-token-bwmbd

で表示されるトークンを入力してください

最後に

Ubuntu16.04 上に kubernetes をインストールしてみました
嵌りポイントは少しありましたが割りとスムーズにインストールできました
過去に minikube を使った構築方法を紹介しましたが mac がない場合には今回の方法を使うと良いと思います

次回はこの環境にコンテナを立てたりしたいと思います

参考サイト