- 投稿日:2020-11-13T22:29:59+09:00
Docker for Macに付属のKubernetesにmetrics-serverをHelmでインストールする
概要
タイトルのとおり Docker for Mac に付属の Kubernetes クラスタに metrics-server を Helm を使ってインストールする方法のメモです。
インストール方法
基本的には下記のコマンドを実行するだけです。
$ helm repo add bitnami https://charts.bitnami.com/bitnami $ helm install metrics-server bitnami/metrics-server --namespace kube-system --set rbac.create=false --set apiService.create=true --set extraArgs.kubelet-insecure-tls=trueそれぞれのコマンドは下記を実行しています。
- helm に bitnami のリポジトリを追加(追加済みの場合は不要です)
- metrics-server をインストール1
これで少し待つと
kubectl top node
等でメトリクスが取得可能となります。$ kubectl top node NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% docker-desktop 521m 8% 1363Mi 19%
地味に難しかったのがコマンド引数に
--kubelet-insecure-tls
を指定する方法です。metrics-serverにはextraArgs
が用意されているのですが、デフォルトが[]
というのを見てextraArgs[0]=kubelet-insecure-tls
のように指定すると--0=kubelet-insecure-tls
に変換されてしまい動きません。 ↩
- 投稿日:2020-11-13T21:01:05+09:00
Win10-HomeでDockerしたらVirtualBoxが挙動不審になった件
Windows10-Home にて Docker と VirtualBox を共存させるために Hyper-V を無効化しました。
ここに経過と手順を残します。
要点
・Docker を使うと Hyper-V が有効になり VirtualBox が正常に動かなくなる(ことがある)
・Win10-Home であっても Hyper-V は使える。
---- ただし「Windowsの機能」からは設定変更できない
---- コマンドラインから設定できる・本来は VirtualBox の 6 以降は Hyper-V と共存できるというはなしもある。
・(Hyper-Vの切り替えはBIOS/UEFIには無いみたい)
環境
Win10-Home
VirtualBox 6.1※Win10 上には Linuxシェル(WSL2)導入済み
紛らわしいですがVirtualBoxとWindows Subsystem for Linux (たぶんWSL2です)
両方使ってる環境他のバージョンは割愛
症状と経過
VirtualBoxでUbuntu20.04を使ってました。
その後、新たにホストOS側(つまりWin10のほう)に Docker を導入しました。
→ VirtualBox 上の Ubuntu20.04 の挙動がおかしくなる。
(端末でmakeとか操作するとOSが落ちるとかそんなん。詳しくはwasureta)「そういえば『Docker いれると Hyper-V が有効化される』と聞いた覚えが......」
とにかくHyper-Vを無効化 → VirtualBoxのUbuntu20.04は再び安定しましたとさ。
注意事項
「Win10-Home では Hyper-V は使えない(?)」という誤情報(?)が見つかります。
おそらく WSL との兼ね合いから Win10-Home でも Hyper-V が使えるように 後から変わったのだと思います。
(※WSLを有効化したからHyper-Vが使えるようになったという可能性もある。)ただし、2020年10月現在、GUI からは Hyper-V の設定できませんでした。
↑ このように Win10-Pro では Hyper-V チェックボックスが出現しますが、 Win10-Home では出現しないようです。
したがってコマンドラインから設定する必要がある。
Hyper-V を off るコマンド
PowerShell(管理者実行)bcdedit /set hypervisorlaunchtype off再起動
UEFI に Hyper-V 設定欄なかったっけ
昔はBIOSとかUEFIで有効/無効を切り替えてた気がする。勘違いでしょうか。
- 投稿日:2020-11-13T18:47:42+09:00
Dash(+Docker)で機械学習アプリを作ってみたpart3 ~実践編~
はじめに
PythonのWebアプリフレームワークDashを用いて簡単な機械学習アプリを作成したため、その学習記録として本記事を書きました(成果物はこちら)。前記事(part2)ではDashアプリ作成での基本となるLayoutとCallbackについて紹介しました。本記事では応用例として、実際に私が作ったアプリの一部を取り上げて紹介したいと思います。下のように、テーブルデータに対してチェックボックスで選択した分析結果を表示させるアプリを実装します。
動作環境についてはこちら(part1)をご覧ください。また本記事ではデータ加工にPandasを使用しておりますが、Pandasの知識がなくてもほぼ問題なく読めると思います。準備
実際に作成したアプリではcsvファイルなどをアップロード機能をつけましたが、今回は用意したデータを直接読み込むことにします。sample_data.csvの部分は、適当なサイズのお好きなテーブルデータで試してみてください(ペアプロットを実装するため数値変数は2つ以上あった方が良いです)。本記事ではKaggleのタイタニックコンペのデータ(train.csv)を使用します。
<ディレクトリ構成> Dash_App/ ├ sample_data.csv ├ app.py ├ Dockerfile └ docker-compose.ymlLayout, Callback以外の部分は以下のようにしておきます。
app.pyimport dash import dash_core_components as dcc import dash_html_components as html from dash.dependencies import Input, Output, State import pandas as pd import plotly.express as px import plotly.figure_factory as ff # データの読み込み data = pd.read_csv('src/sample_data.csv') external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css'] app = dash.Dash(__name__, external_stylesheets=external_stylesheets) ################################################################ Layout部分 ################################################################ ################################################################ Callback部分 ################################################################ if __name__ == '__main__': app.run_server(host='0.0.0.0', port=5050, debug=True)Layout部分の作成
今回はチェックボックス(
dcc.RadioItems()
)とボタン(html.Button()
)を使用してみようと思います。公式サイトにサンプルコードが載っているため、使いたいものを探してサンプルを真似て実装していくのが良いと思います。例えばdcc.RadioItems()
のサンプルコードをみてみると、下のようになっています。
見てみると引数options
で選択肢を設定し、それぞれの選択肢にlabel
(表示されるテキスト)とvalue
を指定していることがわかります。さらに次の引数value
で'MLT'を指定した結果’Montreal’にチェックがついていることから、引数value
では初期値を設定することができ、UI操作によって選択された値にvalue
が上書きされることが想像できます(読み解くよりも実際に動かしながら確認する方が断然早いですが...)。
サンプルコードを真似ながら、Layout部分は以下のように作成してみました。value
の初期値は設定せず、設定した選択肢のvalue
はわかりやすく'AAA', 'BBB', 'CCC'としました。app.pyapp.layout = html.Div(children=[ html.H3('Step5: 数値変数の分析'), html.H5('分析方法を選択し、実行を押してください'), # チェックボックス部分 dcc.RadioItems( id='num_analysis_selection', options=[ {'label': '統計量一覧', 'value': 'AAA'}, {'label': 'ペアプロット', 'value': 'BBB'}, {'label': '相関行列', 'value': 'CCC'} ] ), # ボタン部分 html.Button(id="num_analysis-button", n_clicks=0, children="実行", style={'background': '#DDDDDD'}), # 結果を表示させる部分 html.Div(id='num_result') ])この状態でアプリを起動すると、下のように表示されます。当然ですが今のままではボタンを押しても何も起こらないため、次の節からCallbackで動きを付けていきたいと思います。
Callback部分
動作確認
続いてCallback部分を書いていきます。データを使用する前に、まずは簡単な動作確認から行っていきます。app.pyのLayout部分の下に、以下のようにCallbackを書いてみます。
app.py@app.callback( Output(component_id='num_result', component_property='children'), [Input(component_id='num_analysis_selection', component_property='value')] ) def num_analysis(input): return inputこの状態でアプリを動かしてみると、チェックをつけた選択肢の
value
の値がボタンの下に表示されていることが確認できます。前記事(part2)の復習になりますが、動きとしては①Inputで指定したdc.ReadItems()
のvalue
の値が関数num_analysis()
の引数(input
)として渡され、②この関数の返り値(input
)がOutputで指定したhtml.Div(id='num_result')
の引数children
に渡されていることになります。
動きが確認できたら、実際に読み込んだデータを使っていきたいと思います。今回は選択内容によって異なる処理をするため、入力値を使ってif文で条件分岐させていきます。Tableの描画
まずは、「統計量一覧」が選択された場合の処理を書いていきます。具体的には、Pandasで
describe()
メソッドを行った結果の表を描画させたいと思います。Dashで表を描画させる方法は聞くつもあるようですが、ここでは最もシンプルなhtml.Table
を使います。公式チュートリアルのサンプルコードを見てみると、
やや複雑ですが、generate_table()
と言う関数を作っているみたいです。今回は、この関数のreturnの部分を使って下のように実装してみました。app.py@app.callback( Output(component_id='num_result', component_property='children'), [Input(component_id='num_analysis_selection', component_property='value')] ) def num_analysis(input): if input == 'AAA': describe = data.describe() return html.Table([ html.Thead( html.Tr([html.Th(col) for col in describe.columns]) ), html.Tbody([ html.Tr([ html.Td(describe.iloc[i][col]) for col in describe.columns ]) for i in range(len(describe)) ]) ])「統計量一覧」を選択すると、下のように表が描画できていると思います。
Plotlyの図を描画する
続けて、ペアプロットと相関行列(ヒートマップ)の描画を実装していきます。Dashの美味しいところは、なんと言ってもPlotlyのインタラクティブでカッコ良い図を使用できることなので、Plotlyの公式サイトから探していきます。基本的な流れは同様のため、ペアプロットの方のみ見ていきます。
DashでPlotlyの図を描画する方法は、基本的にはPlotlyでfig.show()
としているところを、dcc.Graph(figure=fig)
に変えるだけです。それでは、ヒートマップ部分も合わせて実装していきます。app.py@app.callback( Output(component_id='num_result', component_property='children'), [Input(component_id='num_analysis_selection', component_property='value')] ) def num_analysis(input): # 統計量一覧の描画 if input == 'AAA': describe = data.describe() return html.Table([ html.Thead( html.Tr([html.Th(col) for col in describe.columns]) ), html.Tbody([ html.Tr([ html.Td(describe.iloc[i][col]) for col in describe.columns ]) for i in range(len(describe)) ]) ]) # ペアプロットの描画 elif input == 'BBB': fig = px.scatter_matrix( data, dimensions=['Pclass', 'Age', 'Parch', 'Fare'], color='Survived' ) return dcc.Graph(figure=fig) # 相関係数(ヒートマップ)の描画 elif input == 'CCC': corr = data[['Pclass', 'Age', 'Parch', 'Fare']].corr().round(4) fig = ff.create_annotated_heatmap( z=corr.values, x=list(corr.columns), y=list(corr.index), colorscale='Oranges', hoverinfo='none' ) return dcc.Graph(figure=fig)これで、ペアプロットと相関行列も描画できるようになったかと思います。
Stateを使ってボタンを機能させる
最後にもう1ステップ。現時点では、チェックボックスで選択した瞬間に図の描画が開始され、下にある実行ボタンが機能していません。これを、選択したあと実行ボタンを押すことで結果が反映されるように修正していきます。これには、Callbackの中でStateという機能を使っていきます。一度if文以下をコメントアウトして、Callback部分を下のように修正します。
app.py@app.callback( Output(component_id='num_result', component_property='children'), [Input(component_id='num_analysis-button', component_property='n_clicks')], [State(component_id='num_analysis_selection', component_property='value')] ) def num_analysis(n_clicks, input): return 'n_clicks:{}, input:{}'.format(n_clicks, input)Inputにボタンを指定し、元々InputだったチェックボックスをStateに書き換えました。こうすることにより、Stateによって指定された部分はアクションがあった時点では反映されず、Inputで指定された部分にアクションがあった際に同時に反映されるようになります。この際、関数に渡される引数がボタン由来(
n_clicks
)とチェックボックス由来(input
)の2つになっていることに注意してください。ちなみにn_clicks
にはボタンが押された回数が入ります。試しに上の状態でアプリを起動すると、実行ボタンを押すたびにn_clicksの値が増え、inputには'AAA'などが入っていることが確認できるかと思います。
Stateの仕組みが理解できたところで、num_analysis(n_clicks, input)
の関数の中身をif文以下に戻します。今回はn_clicks
は特に使用しないので、これで完成になります。最後にもう一度完成したコードを載せておきます。app.pyimport dash import dash_core_components as dcc import dash_html_components as html from dash.dependencies import Input, Output, State import pandas as pd import plotly.express as px import plotly.figure_factory as ff external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css'] data = pd.read_csv('src/dash/titanic_train.csv') app = dash.Dash(__name__, external_stylesheets=external_stylesheets) app.layout = html.Div(children=[ html.H3('Step5: 数値変数の分析'), html.H5('分析方法を選択し、実行を押してください'), # チェックボックス部分 dcc.RadioItems( id='num_analysis_selection', options=[ {'label': '統計量一覧', 'value': 'AAA'}, {'label': 'ペアプロット', 'value': 'BBB'}, {'label': '相関行列', 'value': 'CCC'} ] ), # ボタン部分 html.Button(id="num_analysis-button", n_clicks=0, children="実行", style={'background': '#DDDDDD'}), # 結果を表示させる部分 html.Div(id='num_result') ]) @app.callback( Output(component_id='num_result', component_property='children'), [Input(component_id='num_analysis-button', component_property='n_clicks')], [State(component_id='num_analysis_selection', component_property='value')] ) def num_analysis(n_clicks, input): if input == 'AAA': describe = data.describe() return html.Table([ html.Thead( html.Tr([html.Th(col) for col in describe.columns]) ), html.Tbody([ html.Tr([ html.Td(describe.iloc[i][col]) for col in describe.columns ]) for i in range(len(describe)) ]) ]) # ペアプロットの描画 elif input == 'BBB': fig = px.scatter_matrix( data, dimensions=['Pclass', 'Age', 'Parch', 'Fare'], color='Survived' ) return dcc.Graph(figure=fig) # 相関係数(ヒートマップ)の描画 elif input == 'CCC': corr = data[['Pclass', 'Age', 'Parch', 'Fare']].corr().round(4) fig = ff.create_annotated_heatmap( z=corr.values, x=list(corr.columns), y=list(corr.index), colorscale='Oranges', hoverinfo='none' ) return dcc.Graph(figure=fig) if __name__ == '__main__': app.run_server(host='0.0.0.0', port=5050, debug=True)おわりに
実践編として、簡単なテーブルデータ分析アプリを実装しました。機械学習やデータ分析のアプリを作る場合、ほとんどが今回のように「PandasやScikit-learnでデータを加工する → DashやPlotlyに合うように値を渡す」という作業の繰り返しになりますので、色々と試してみてください。次の記事(ラスト)では、作成したアプリをDockerを使ってHerokuにデプロイする方法を紹介したいと思います。長くなってしまいましたが、ありがとうございました。
- 投稿日:2020-11-13T18:36:32+09:00
コマンドでWordpressのsiteurlを変更する
経緯
とあるサイトの改修をするため、DockerでWordpress環境を構築しlocalhost:8000 で立ち上げたもののCSSが反映されず、
siteurl
を変更する必要がありました。
リポジトリのREADMEには「sequelpro」を使って変更する手順が記載されていたのですが、「sequelpro、接続できない問題!」が発生しまして。。。(ググって見た所どうやら認証方式が変わったとか)
なのでsequelproを使わず、コマンドからDockerに接続しsiteurl
を変更することに。
普段この辺りを触る機会がめったにないので備忘録として残したいと思います!Dockerへ接続
sudo docker psコマンドを実行するとコンテナIDが表示されるので、
docker-compose.yml
に記載されている、対象DBのコンテナIDを確認します。
そして下記コマンドを実行し、sudo docker exec -it {コンテナID} /bin/bash
root@コンテナID:/#
のようなプロンプトが表示されていれば接続成功!です。DBへ接続
docker-compose.yml
に記載されている、MYSQL_USER:
とMYSQL_DATABASE:
を確認し以下コマンドを実行。mysql -u {データベースユーザ名} -p {データベース名}そうしたら、
{データベースのパスワード}
の入力を求められるのでMYSQL_PASSWORD:
に記載されているパスワードを入力します。設定の確認
下記コマンドを実行すれば、現在設定されている
seiteurl
とhome
の2つを確認することができます。
siteurl
のみは,"home"
を省いてください。(逆も同じ)select * from wp_options where option_name in ("siteurl","home");設定の変更
現状の設定が確認できれば、設定を変更していきます。
update wp_options set option_value="{正しいURL}" where option_name in ("siteurl");
seiteurl
とhome
両方変更する場合は、最後の記述を,where option_name in ("siteurl","home");
としてください。設定の確認
最後に、きちんと変更できているか確認して終了になります。
select * from wp_options where option_name in ("siteurl");表示された
siteurl
が更新したものになっていればOKです!
そしてサイトのTOP画面や管理画面に戻ってきちんと表示されていることを確認してください。接続から抜ける
コマンドで
exit
と打ってDBとdockerそれぞれの接続から抜けてください。以上、突如発生する困った・・・!!の対処方法でした!
参照
MySQL: Sequel ProでMySQLに接続できない時
WordPressの一般設定でサイトURLを誤って変更した時の戻し方
- 投稿日:2020-11-13T14:14:03+09:00
Dockerでherokuにデプロイ(Rails6、MySQL)
1 前提条件
1 クレジットカード登録済みのherokuアカウント
2 docker環境で作成したRailsアプリ(credentials:editを編集する場合はDockerfileにRUN apt-get install -y vimを追加) *こちらの記事を参考https://qiita.com/croquette0212/items/44378e01de18f62d01df
3 heroku cliインストール済み2 config/environments/development.rbに下記を記載
Rails.application.confiture do (略) config.hosts.clear (略) end3 コンテナ停止&server.pidを削除
$ docker-compose stop $ rm -f tmp/pids/server.pid4 heroku準備
$ cd ディレクトリ名 $ heroku login --interactive $ heroku container:login $ heroku create アプリ名5 herokuのデータベース設定をMySQLに変更
$ heroku addons:add cleardb $ heroku config:set DATABASE_URL=`heroku config:get CLEARDB_DATABASE_URL | sed -- s/mysql/mysql2/`6 herokuにデプロイ
*heroku container:release webの前にheroku run rails db:migrateをするとbash: rails: command not foundのエラーが出ることがあるようです。
$ heroku container:push web $ heroku container:release web $ heroku run rails db:migrate $ heroku open
- 投稿日:2020-11-13T05:29:13+09:00
docker 上の composer 経由で指定位置に laravel プロジェクトを用意するメモ
結論: どうやって実現するか
※ docker は事前にインストール・起動済みとします。(コダワリがなければ Docker Desktop https://www.docker.com/products/docker-desktop や WSL2 上に Docker をインストールして使えるようにしとけば OK です。)
例えば、
~/Documents/tmp/laravel-project-via-composer
という laravel プロジェクトを作るなら以下。% cd ~/Documents/tmp % docker run --rm -i -t -v $PWD:/app composer create-project --prefer-dist laravel/laravel laravel-project-via-composer
- laravel プロジェクトを配置したいディレクトリに移動して
- そのディレクトリで
composer
のオフィシャルイメージを使って、 laravel プロジェクトを準備するこれだけ。
(なんなら、
-i -t
も不要だが、出力が見やすくなるので入れてる。)これで
~/Documents/tmp/laravel-project-via-composer
に用意される。
$PWD
を任意のディレクトリすれば、コマンドの発行元ディレクトリはどこでも良いので、% cd ~/Documents/tmp
も要らない。(が、うっかりミスとか怖いから、個人的にはcd
してからコマンド実行したい派。)念の為に書くと
$PWD:/app
の右辺が/app
となっているのは https://github.com/composer/docker/blob/fbef2df32932859094b4cd3fb072f1e93a7fa1f8/2.0/Dockerfile#L60 にて、WORKDIR /app
となっているから。※つまり、もし、何らかの理由で将来 composer の Docker image の WORKDIR の位置が変わったら同様にコマンド発行時のパスも変更することになる。(使う image の Dockerfile を読むの大切。)
なぜこの方法を使うのか
- ローカルの環境の PHP や Composer のバージョンとか気にしたくない
- anyenv とかでも管理できるけど、 OpenSSL のバージョン齟齬とかで面倒…
- build するより docker image 使ったほうが早い
- 多くの場合、本来的目的は、 build をしたいのではなく、 laravel プロジェクトを用意したいだけ
- laravel プロジェクト用意した後に、 WEB App 実行用の Dockerfile や docker-compose 用ファイルは別途用意したら良い
たぶん、他のある程度有名な FW やパッケージマネージャーがあるなら同様の考え方で WEB App の下準備ができるはず。(ハードウェアとの通信が必要とか、そういうのは別のお話。)
ハードウェアトラブルや、ハードウェアの乗り換えとかで、いちいちローカル環境を整備するコストを考えると馬鹿らしいので、使えるものは使うと便利かも知れませんよ?というお話でした。
ちなみに
laravel/installer
をインストールしてlaravel new hoge
という選択肢も当然にあるのですが、 docker 使って開発環境用意するだけなら composer の image 使って実行した方が楽やん?って思ってます。知らんけど。
- 投稿日:2020-11-13T01:04:56+09:00
ft_server | 42tokyo subject
はじめに
42の課題です。Dockerfileを作ります。
作りたいイメージの概要
ブログ作りする時の環境構築って感じですかね。
- OS debian:buster - サーバー nginx - DB mariaDB (mysqlの派生でdebian:busterに対応しているもの) - ブログソフトウェア wordpress - MySQL管理ツール phpmyadmin何ができればいいか?
- localhost:8080 で welcome nginxと表示される
- localhost:8080/wordpress でwordpressの登録画面表示
- localhost:8080/phpmyadminで管理画面表示
- https:// が http://にリダイレクトされる
大まかな作り方の流れ
空のOSを持ってきて、その中で動作確認してメモしながら作っていく。
めちゃくちゃ良い参考記事:効率的に安全な Dockerfile を作るには
debian:buster
のイメージを持ってくる- そのコンテナ中で作業
- commitでコンテナをイメージにする → どこまで作業したかメモ
- 2に戻る
- 完成したらそれをDockerfileにする
最初から作っていく
nginx でローカルサーバーを立てる
OSイメージにnginxをインストールするだけのDockerfileを用意。
CMD nginx -g 'daemon off;'
は、nginxをdaemon化(background実行)する事を防ぐ為のもの。
これがないと、コンテナが一瞬で終了してしまいます。
ProcessがForegroundで動いていないとContainerは終了するらしいです。
これに対するアプローチはいろいろあって、shellで無限ループ作ったりsupervisor使ったりあるそうです。
参考: Docker 事始め#OS FROM debian:buster #install nginx RUN apt-get update && apt-get install -y nginx CMD nginx -g 'daemon off;'以下でも可。
#OS FROM debian:buster #install nginx RUN apt-get update && apt-get install -y nginx RUN echo "daemon off;" >> /etc/nginx/nginx.conf CMD ["nginx"]以下のコマンドでサーバーを立ち上げます。
$ docker build -t test . #testという名前のイメージを作成 $ docker run -d -p 8080:80 test #8080ポートと80ポートをつなげてコンテナを作成http://localhost:8080 を見ると
Welcome nginx !
と表示される。次のコマンドでこのコンテナに入って次はwordpressを入れていきます!
コンテナで作業 → イメージをつくる → コンテナで作業する → イメージを作る
次の繰り返し# コンテナを起動する $ docker run -d -p 8080:80 [image_name] #CONTAINER_IDを確認 $ docker ps #コンテナに入る $ docker exec -it [CONTAINER_ID] /bin/bash > #作業 > exit #コンテナから抜ける #終了したCONTAINER_IDを確認 $ docker ps -a #イメージの名前を指定してイメージに保存 $ docker commit [CONTAINER_ID] [image_name] .....