k8s on windows on KVM
k8s on windows on KVM
KVM上にインストールしたWindows 10 pro の上で、k8s (docker の kubernates機能 or minikube )を起動できるのか検証してみました。
結論から言うと、dockerは無理だった。minikubeはできた。
という結果になりました。
検証環境
WindowsでHyper-Vを有効化
まずは、Hyper-Vを有効にする。
コントロールパネル
-> プログラムと機能
-> Windowsの機能の有効化または無効化
で、Hyper-V を有効化して、windowsを再起動する。
docker for windows でk8sを試す
Install Docker Desktop on Windows | Docker Documentation
上記より、dockerをダウンロードしてインストールする
インストールが完了したら再起動の儀式をする。
docker起動
自動起動してくるので起動完了まで待つ。
Hyper-V上に、docker用のVMが作られる。(非常に時間がかかった)
起動してこない場合は、Docker Desktopを実行する。 起動完了すると、タスクバーに、Dockerが確認できる。
kubernatesを有効化する
タスクバーのDockerアイコンよりsettingを実行。
kubernatesを有効化する。
いつまでたっても処理が完了せず、ずっと放置していたらタイムアウトしてエラーになった。
どうやらダメらしい。
Hyper-Vの上のdocker VMに接続するが、接続しても真っ黒画面のままで何か動いている気配なし。
Dockerをfactoryリセットして何度か試すが、Dockerすらまともに起動してこない状態になった。
無理そう(無茶そう)なので諦める。
minikube を試す
インストール
以下よりminikube minikube-windows-amd64.exe
をダウンロードする。
Releases · kubernetes/minikube · GitHub
以下よりkubectlをダウンロードする。
kubectlのインストールおよびセットアップ - Kubernetes
それぞれのコマンドを任意の場所に配置して、環境変数でPATHを通す。
minikubeの起動
minikube start --vm-driver=hyperv
Hyper-Vを有効にしていても、有効にしろとエラーが出たので、forceをつけて起動した。
minikube start --vm-driver=hyperv --force
Hyper-V 上に、minikubeという名前のVMが自動で作られる。
ちなみに、このVMには、user=docker
, password=tcuser
でログインできる。
VM作成されたが、しばらくするとコマンドはエラーになった・・・
VMが起動してくるのが遅すぎてエラーになった模様??
C:\opt>minikube start --vm-driver=hyperv --force * minikube v1.7.3 on Microsoft Windows 10 Pro 10.0.18363 Build 18363 * Using the hyperv driver based on user configuration ! 'hyperv' driver reported an issue: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe Get-WindowsOptionalFeature -FeatureName Microsoft-Hyper-V-All -Online failed: * Suggestion: Start PowerShell as Administrator, and run: 'Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All' * Documentation: https://minikube.sigs.k8s.io/docs/reference/drivers/hyperv/ * Creating hyperv VM (CPUs=2, Memory=2000MB, Disk=20000MB) ... * X Unable to start VM. Please investigate and run 'minikube delete' if possible: creating host: create host timed out in 120.000000 seconds * * minikube is exiting due to an error. If the above message is not useful, open an issue: - https://github.com/kubernetes/minikube/issues/new/choose C:\opt>
一度stopしてからもう一度startしたらいけた。ただし数分待った。希望が見えた。
minikube stop
C:\opt>minikube start --force * minikube v1.7.3 on Microsoft Windows 10 Pro 10.0.18363 Build 18363 * Using the hyperv driver based on existing profile ! 'hyperv' driver reported an issue: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe Get-WindowsOptionalFeature -FeatureName Microsoft-Hyper-V-All -Online failed: * Suggestion: Start PowerShell as Administrator, and run: 'Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All' * Documentation: https://minikube.sigs.k8s.io/docs/reference/drivers/hyperv/ * Reconfiguring existing host ... * Starting existing hyperv VM for "minikube" ... * Preparing Kubernetes v1.17.3 on Docker 19.03.6 ... * Launching Kubernetes ... * Enabling addons: dashboard, default-storageclass, storage-provisioner * Done! kubectl is now configured to use "minikube" C:\opt>
C:\opt>minikube status host: Running kubelet: Running apiserver: Running kubeconfig: Configured
dashboardが見れるか確認。
minikube dashboard
勝手にブラウザが立ち上がり、ダッシュボードが見れた。しかし、描画がすごく遅い。
podの起動
C:\opt>kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.10 deployment.apps/hello-minikube created C:\opt>kubectl expose deployment hello-minikube --type=NodePort --port=8080 service/hello-minikube exposed C:\opt>kubectl get pods NAME READY STATUS RESTARTS AGE hello-minikube-797f975945-2cz52 1/1 Running 0 10h
立ち上がったので、接続してみる。
URLを調べて、ブラウザで接続する。
C:\opt>minikube service hello-minikube --url http://192.168.187.8:31775
無事接続できた。
まとめ
AppleWatch WatchKitでHelloWorld
AppleWatch用のHelloWorldを表示するアプリをサクッと作るメモです。
開発環境
- Xcode 10.3
- Apple Watch Series 4
Xcodeプロジェクトを作る
まずは、Xcodeでプロジェクトを作ります。
File -> New -> Project
から、watchOS を選択してiOS App with WatchKit App を選択します。
入力項目を埋めます。 HelloWorldを表示する程度のアプリなので、Notification Scene や、Complicationは不要です。 Unit Testsもしないですが、チェックつけるだけつけておきます。
Next で、プロジェクトの保存場所を聞かれるので、好きな場所に作ってプロジェクト作成は完了です。
実装
次に実装します。実装としていますが、ソースは書かないでポチポチするだけです。 xcodeで、WatchKitAppの、interface.storyboardを選択すると、アプリ画面が表示されます。
画面上の方のLibraryからLabelを選び、アプリの上にドラッグ&ドロップします。
Labelを貼り付けたら、Labelをクリックして、右のツールボックスから、「Attribute inspector」の設定を開き、Textに「HelloWorld」を入力して、実装は完了です。
シミュレーターを起動する。
schema、シミュレーターを設定して実行します。実行するとシミュレーター上で作成したアプリのインストールが行われ、アプリが自動的に起動してきます。
たまに、AppleWatch側シミュレーターでアプリインストールが空振りすることがあったので、自動起動してこないときは、もう一度起動してみると良いと思います。
実機でアプリを起動する(実機にアプリをインストールする)
接続すると、IPhoneとAppleWatch上で、デバイスを信用するか認証が走りますので、承認します。
承認すると、Device and Simurator
で、実機が選択できるようになります。
実機を選択して、シミュレーター同様に起動して、完了です。
アプリ起動時に、証明書(署名)関連のエラーが出て起動できない場合は、証明書を作成します。
メニューの Xcode -> Preferences -> Accounts -> 「+」ボタン -> AppleID -> continue
そして、AppleIDを入力。
Manage Certificates
をクリックすると証明書を作成できる画面に行くので、証明書を作成します。
証明書をアプリに設定します。
General設定画面を開き、Targets から、iOSアプリ、WatchKitApp、WatchKitExtension の3つの、署名設定で、Teamを設定します。 私は、iOSアプリしか設定せず、Watchアプリにも設定しなければいけないことに気づかず、署名エラーが全然解消できず、ハマりました。
あとは、アプリを起動すれば次はエラーは解消されて、アプリインストールが始まり、起動できるようになるはずです。
以上で、AppleWatchで、HelloWorldを表示する簡単なアプリの実装と起動は完了です。
XcodeのUIがコロコロ変わるので、数年前の情報通りに実装できないのと、
署名周りでハマりました。
これらさえ攻略できれば数分で簡単にHelloWorldくらいは表示できると思います。
fish shell を導入した時のメモ書き
fish3
fishを導入した時のメモ書き。
インストール
brewで簡単にインストールできます
brew install fish
brewでインストールしていると最後に
You will need to add: /usr/local/bin/fish to /etc/shells.
と出るので、
/etc/shells
に/usr/local/bin/fish
を書きます。
デフォルトshellにしたい人は、
chsh -s /usr/local/bin/fish
を実行します。
fishの設定ファイル
bashでいう.bashrc
のようなshellの設定ファイルは、
~/.config/fish/conf.d
の下に配置するようです。
プラグインマネージャー
fishのプラグインマネージャーはいくつかあるみたいですが、fishermanを使ってみます。
GitHub - jorgebucaran/fisher: A package manager for the fish shell
READMEにしたがって導入していきます。
curl https://git.io/fisher --create-dirs -sLo ~/.config/fish/functions/fisher.fish
fisher -version fisher version 3.1.1 ~/.config/fish/functions/fisher.fish
3.1.1が入りました。
fisherというコマンドが使えるようになり、fisher add
でプラグインを追加できます。
githubで公開されているプラグインならなんでもインストールできるようです。
fisher add
の後にgitリポジトリ名を指定するとインストールできます。
<https://github.com/jethrokuan/fzf>
をインストールしたい場合は、
fisher add jethrokuan/fzf
とコマンドを打つとインストールできます。
themeを変える
このサイトにテーマ例が色々載っています。 oh-my-fish/Themes.md at master · oh-my-fish/oh-my-fish · GitHub
cbjohnsonを入れてみました。
fisher add oh-my-fish/theme-cbjohnson
プラグインを入れる
fzf
Ctrl + r
でのコマンドの再帰検索が楽になる。
brew install fzf fisher add jethrokuan/fzf
fish_config
fishの設定ができる便利なコマンド。python3が必要なので事前にインストールしておきます。 コマンドを叩くとブラウザで設定画面が上がってきますのでブラウザで設定変更できるようです。
Macで、USBメモリーにISOイメージを書き込む
Macで、OSインストーラーなどのISOイメージを、USBメモリーに書き込みたい時。
USBメモリをMacに挿してから、diskutil list
コマンドでデバイス名を確認する。
この例では、/dev/disk2がUSBメモリです。(TOSHIBA製のUSBメモリー使ってます。)
» diskutil list /dev/disk0 (internal): ... /dev/disk1 (synthesized): ... /dev/disk2 (external, physical): #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *15.5 GB disk2 1: DOS_FAT_32 TOSHIBA 15.5 GB disk2s1
次に、diskutil eraseDisk
コマンドでUSBメモリーをフォーマットします。
第1引数が、フォーマット、第2引数が、任意の名前、第3引数がデバイスです。
diskutil eraseDisk MS-DOS INSTALLER /dev/disk2
補足ですが、使えるフォーマットは以下で調べられます。
» diskutil listFilesystems Formattable file systems These file system personalities can be used for erasing and partitioning. When specifying a personality as a parameter to a verb, case is not considered. Certain common aliases (also case-insensitive) are listed below as well. ------------------------------------------------------------------------------- PERSONALITY USER VISIBLE NAME ------------------------------------------------------------------------------- APFS APFS (or) APFSI Case-sensitive APFS APFS (Case-sensitive) ExFAT ExFAT MS-DOS MS-DOS (FAT) MS-DOS FAT12 MS-DOS (FAT12) MS-DOS FAT16 MS-DOS (FAT16) MS-DOS FAT32 MS-DOS (FAT32) (or) FAT32 HFS+ Mac OS Extended Case-sensitive HFS+ Mac OS Extended (Case-sensitive) (or) HFSX Case-sensitive Journaled HFS+ Mac OS Extended (Case-sensitive, Journaled) (or) JHFSX Journaled HFS+ Mac OS Extended (Journaled) (or) JHFS+ Free Space 空き領域 (or) FREE
USBメモリーをunmountします。
diskutil unmountDisk /dev/disk2
最後に、dd
でISOイメージをUSBメモリーに書き込みます。
書き込み先を間違えないように注意。
sudo dd if=/tmp/ubuntu-19.04-live-server-amd64.iso of=/dev/disk2 bs=4096
これで少し待てば完了です。
書き込みが終わると、Macのデスクトップ上に突然「マウントできないディスクだ」という感じのエラーが突然でました・・・。マウントしようとした模様です。
spring boot + micrometer.io + prometheusで簡単メトリクス監視
最近、prometheusを使い始めましたので、java(spring boot)でメトリクス収集のスタンダードとなりつつあるmicrometer.ioを調べてみました。
はじめに
micrometer.ioは、javaアプリの性能監視用メトリクスを収集して任意のモニタリングサービスと連携してくれるライブラリです。
prometheusやinfluxDBと連携してとっても簡単に性能モニタリングや性能監視ができます。
連携できるサービスは Spring Boot Reference Guide に記載されています。
micrometer.ioでは、
サーブレット周りのメトリクス(リクエスト数やレスポンスタイム、ステータスコードごとのレスポンス数)、WebFlux、datasource、schedulerなどなどのメトリクスが取得可能です。
spring bootでmicrometerを使う場合は、dependencyにmicrometerを追加するだけで、AutoConfigurationによって諸々Bean生成&AOPされ、コードを一切書かずにメトリクス収集できてしまいます。
使ってみた範囲では、サーブレット周りのメトリクスは、dependency追加だけで収集してくれました。
任意のメソッドの処理速度を測りたい場合は、アノテーション(たぶん@Timed)を付与するだけで取れちゃうそうです。
また、spring boot 2からは、micrometerがbootに統合され、bootでのメトリクス収集のデファクトになっています。
試してみた
各種ソフトウェアのバージョンなど
次のソフトウェアバージョンで試してみました。
- Java ... java1.8
- spring boot ... 1.5.10
- micrometer ... 1.0
- prometheus ... 2.2.0 rc1
また、お試し用に、簡単なRestサービスを作りサーブレットのメトリクスを取ってみました。
gradleやmaven のdependency設定
gradleやmaven のdependencyに以下を追加します。
- micrometer-spring-legacy
- spring boot 1.5ではmicrometerを引っ張る必要があります。2.0からは不要かな?
- micrometer-registry-prometheus
- prometheusと連携するために追加します。これと次のactuatorを組み合わせてprometheus用のエンドポイントが自動作成されます。
- spring-boot-starter-actuator
- prometheus用のエンドポイントはactuatorを利用します。
gradleだと以下のような設定になります。
dependencies { compile('org.springframework.boot:spring-boot-starter-actuator') compile('org.springframework.boot:spring-boot-starter-web') compile('io.micrometer:micrometer-spring-legacy:latest.release') compile('io.micrometer:micrometer-registry-prometheus:1.0.0') testCompile('org.springframework.boot:spring-boot-starter-test') }
prometheusエンドポイントの認証設定 (actuatorの認証設定)
application.propertiesやymlで、prometheusエンドポイントの認証設定を行います。
デフォルトでは認証がかかっていますが、お試しなので、認証を解除しておきます。
actuatorを利用してprometheus用のエンドポイントが作られていますので、以下で認証を解除できます。
endpoints.prometheus.sensitive=false
以上の設定だけで、メトリクスが収集され、prometheus向けのエンドポイントができあがります。
エンドポイントは/prometheusです。
メトリクスを見てみる
ローカルでアプリを動かした場合は、localhost:8080/prometheusに接続するとprometheus向けのメトリクスが参照できます。
次のようなメトリクスが取れます。
サンプルとして、/demo/sleep(ランダムスリープするAPI)と/greeting(hello worldを返却するだけ)を作成しており、何回かアクセスした後に、メトリクスを参照しています。
http_server_requests_seconds_{count,max,sum}がHTTPリクエストのメトリクスです。 その他にもCPUやメモリ、Javaヒープのメトリクスなどなどがデフォルトで取得できます。
prometheusの設定
prometheusで、監視対象として作成したエンドポイント(/prometheus)を追加します。
設定ファイル(prometheus.yml)で以下のような設定を追加すれば完了です。
scrape_configs: - job_name: 'spring' metrics_path: '/prometheus' scrape_interval: 30s static_configs: - targets: ['localhost:8080']
まとめ
spring boot とmicrometerを組み合わせることで、dependencyの追加と、application.properties/yml の設定だけでコードは一切書かずにメトリクスを取れてしまいます。 めちゃめちゃ簡単です。
micrometer以外では、prometheusオフィシャルのsimpleclientでもうちょっと違うメトリクスが取得できます。用途に合わせてsimpleclientと組み合わせたりして使うとよいとおもいます。 prometheusにはzipkinプラグインがありますので、これも調べたいと思います。
また、WebFluxのメトリクス取得や、scheduler, datasourceのメトリクスがどんなものが取得できるのかも試したいですね。
今回試したサンプルアプリはgithubに登録してあります。
GitHub - ikeda-mk/prometheus-micrometer-demo
AWS API Gateway + lambda で任意のHTTPステータスコードを返却する
API Gateway + lambda で、任意のHTTPステータスコードを返却したい場合、次のことを行えば任意ステータスコードを返却できるようになります。
- lambda で例外を throw する
- API Gateway のIntegration Response(統合レスポンス)の設定で、lambdaのエラーメッセージとHTTPステータスコードをマッピングする
lambdaが正常終了した場合は、正規表現チェックの対象にならないようなので、lambdaは例外スローする必要があります。
lambda ファンクション作成
まずは、次のようなlambdaファンクションを作成してみます。 名前は、"test_lambda_function"としました
- パラメータに、key1 または、key2が含まれていないと例外をthrow
- key2が整数ではない場合、例外throw
# -*- coding: utf-8 -*- import json import types def lambda_handler(event, context): print("Received event: " + json.dumps(event, indent=2)) if not "key1" in event: raise Exception("Parameter error. Missing field 'key1'.") if not "key2" in event: raise Exception("Parameter error. Missing field 'key2'.") if not type(event["key1"]) is types.UnicodeType: raise Exception("Parameter error. 'key1' is not a UnicodeType") try: # key2が整数ではない場合、例外throw return 10 + event["key2"] except Exception as e: raise Exception("Internal error. " + e.message)
API Gateway を作成する。
次のように、先ほど作成したlambdaファンクションを実行するAPI Gateway を作成します。 demoというリソースを作成し、POSTメソッドを作成しています。
API Gateway で Method Responseを設定する
Method Responseの設定画面で、HTTPステータスに400(バッドリクエスト)と500(サーバーエラー)を追加します。
API Gateway で Integration Responseの設定
Integration Responseの設定画面で、Integration Responseを追加します。 次の2つの設定を追加します。
- lambdaの例外メッセージに"Parameter error"という文字列が含まれていた場合に、400を返却
- lambdaの例外メッセージに"Internal error"という文字列が含まれていた場合に、500を返却
二つ設定が終わると、以下のようになります。
ここまでの設定で、任意ステータスコードが返却できる簡単な設定が完了しました。
テストしてみる
デプロイし動作確認してみます。
正常系
正しいJSONパラメータでHTTPのPOSTリクエストを実行し、200が返却されることを確認してみます。
$ curl -d '{"key1": "aaa", "key2": 100}' \ > -i -H "Content-type: application/json" -X POST \ > https://l43dvdh5bj.execute-api.ap-northeast-1.amazonaws.com/devel/demo HTTP/1.1 200 OK Content-Type: application/json Content-Length: 3 Connection: keep-alive ### (中略) ### 110
パラメータエラー(400)を確認
key2を設定していないリクエストを実行し400が返却されることを確認します。
$ curl -d '{"key1": "aaa"}' \ > -i -H "Content-type: application/json" -X POST \ > https://l43dvdh5bj.execute-api.ap-northeast-1.amazonaws.com/devel/demo HTTP/1.1 400 Bad Request Content-Type: application/json Content-Length: 219 ### (中略) ### {"stackTrace": [["/var/task/lambda_function.py", 13, "lambda_handler", "raise Exception(\"Parameter error. Missing field 'key2'.\")"]], "errorType": "Exception", "errorMessage": "Parameter error. Missing field 'key1'."}
インターナルサーバーエラー(500)を確認
インターナルサーバーエラーが発生するようにkey2に文字列を入力し、500が返却されることを確認します。
$ curl -d '{"key1": "aaa", "key2": "bbb"}' \ > -i -H "Content-type: application/json" -X POST \ > https://l43dvdh5bj.execute-api.ap-northeast-1.amazonaws.com/devel/demo HTTP/1.1 500 Internal Server Error Content-Type: application/json ### (中略) ### {"stackTrace": [["/var/task/lambda_function.py", 21, "lambda_handler", "raise Exception(\"Internal error. \" + e.message)"]], "errorType": "Exception", "errorMessage": "Internal error. unsupported operand type(s) for +: 'int' and 'unicode'"}
レスポンスBodyを修正する。
このままでは、レスポンスのJsonに、スタックトレースがそのまま出力され、かっこ悪いので、レスポンスを編集してみます。
API Gateway の Integration Response で Mapping Template を定義することで修正できます。
デフォルトでは、以下のパラメータがJsonレスポンスに設定されています。 * stackTrace ... スタックトレースがそのまま設定 * errorType ... Exceptionのクラス名(型) * errorMessage ... Exceptionのメッセージ
errorMessageのみ出力するように設定してみます。
デプロイし、確認してみます。
lavigne:~ mak$ curl -d '{"key1": "aaa"}' \ > -i -H "Content-type: application/json" -X POST \ > https://l43dvdh5bj.execute-api.ap-northeast-1.amazonaws.com/devel/demo HTTP/1.1 400 Bad Request Content-Type: application/json Content-Length: 62 ### (中略) ### { "errorMessage": "Parameter error. Missing field 'key2'." }
openstack havana on ubuntu 13.10 (cinder)
openstackとりまとめページ http://init0.hatenablog.com/entry/2013/10/05/232939
LVMの設定
まずは、cinder用に VGを作成します。
nova 用に、ディスクパーティションを用意できる人用
ディスクに空きパーティションがある人は、一般的な方法で、VGを作成する。
- vgの名称は、cinder-volumes とする。
- cinderのデフォルト設定では、「cinder-volumes」を使うため。
# pvcreate /dev/sdb1 # vgcreate cinder-volumes /dev/sdb1 # vgdisplay --- Volume group --- VG Name cinder-volumes System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 1 VG Access read/write VG Status resizable MAX LV 0 Cur LV 0 Open LV 0 Max PV 0 Cur PV 1 Act PV 1 VG Size 50.00 GiB PE Size 4.00 MiB Total PE 12799 Alloc PE / Size 0 / 0 Free PE / Size 12799 / 50.00 GiB VG UUID H14HUP-XwkY-EeQt-tqpT-iNGG-abOt-gmBo2x
空きパーティションがない人向け
cinder用に使える空きパーティションがない場合は、ddでファイルを作成し、ループバックマウントして無理やりVGを作成する。
- 再起動するたびに、losetupしないといけないので、/etc/rc.localに、losetupを記載すると便利。
# dd if=/dev/zero of=/home/cinder01.img bs=1024 count=10000000 # losetup -f /home/cinder01.img # pvcreate /dev/loop0 Physical volume "/dev/loop0" successfully created # vgcreate cinder-volumes /dev/loop0 Volume group "cinder-volumes" successfully created
DB作成
cinder用にDBを作成します。
- 事前に、stack@localhost、stack@% というユーザは作成済みです。
- cinderという名称で、DBを作成
- stackユーザに、cinder DBを操作する全権限を付与する。
# mysql -u root -p mysql> CREATE DATABASE cinder; mysql> GRANT ALL PRIVILEGES ON cinder.* TO 'stack'@'localhost'; mysql> GRANT ALL PRIVILEGES ON cinder.* TO 'stack'@'%';
cinderインストール・設定
インストール
# aptitude install cinder-volume cinder-api cinder-scheduler
設定ファイル変更
- /etc/cinder/cinder.conf
- DBへの接続設定を追加する。
以下を追加
[database] sql_connection = mysql://stack:stack@localhost/cinder
- /etc/cinder/api-paste.ini
- keystoneへの接続設定を記載する
# 省略 [filter:authtoken] paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory auth_host = 127.0.0.1 auth_port = 35357 auth_protocol = http admin_tenant_name = service admin_user = cinder admin_password = cinder # 省略
DBにスキーマ登録
# cinder-manage db sync
keystoneの設定
- cinderユーザ作成
keystone user-create \ --name=cinder \ --pass=cinder \ --email=cinder@example.com
- cinderユーザにroleを付与
- serviceテナントのadminとしてロールを作成。
- tenant-id, user-id, role-idを事前に調べ、user-role-addの引数で渡す。
# keystone tenant-list | grep service | 63db5b3fccf04d66b87091d5fbe771b7 | service | True | # keystone user-list | grep cinder | 300f04f6e9ac442d81ef3ea87fa969c1 | cinder | True | cinder@example.com | # keystone role-list | grep admin | 58489d413e69439699875718d1407307 | admin | keystone user-role-add \ --tenant-id 63db5b3fccf04d66b87091d5fbe771b7 \ --user-id 300f04f6e9ac442d81ef3ea87fa969c1 \ --role-id 58489d413e69439699875718d1407307
- REST API バージョン1用のendpointを作成
keystone service-create --name=cinder --type=volume \ --description="Cinder Volume Service" # keystone service-list | grep cinder | 29c2d484d0f64a768423d90c5515b787 | cinder | volume | Volume Service | keystone endpoint-create \ --service-id= 29c2d484d0f64a768423d90c5515b787 \ --publicurl=http://192.168.0.110:8776/v1/%\(tenant_id\)s \ --internalurl=http://192.168.0.110:8776/v1/%\(tenant_id\)s \ --adminurl=http://192.168.0.110:8776/v1/%\(tenant_id\)s
- REST API バージョン2用のendpointを作成
keystone service-create --name=cinderv2 --type=volumev2 \ --description="Cinder Volume Service V2" # keystone service-list | grep cinderv2 | a9bbd40f7f9a46debd1f53511fc15d6c | cinderv2 | volumev2 | Cinder Volume Service V2 | keystone endpoint-create \ --service-id=a9bbd40f7f9a46debd1f53511fc15d6c \ --publicurl=http://192.168.0.110:8776/v2/%\(tenant_id\)s \ --internalurl=http://192.168.0.110:8776/v2/%\(tenant_id\)s \ --adminurl=http://192.168.0.110:8776/v2/%\(tenant_id\)s
cinderの再起動
service cinder-api restart service cinder-volume restart service cinder-scheduler restart
動作確認
cinderコマンドを使い、volumeを作成・削除する。
# cinder create --display-name vol01 1 # cinder list +--------------------------------------+-----------+--------------+------+-------------+----------+-------------+ | ID | Status | Display Name | Size | Volume Type | Bootable | Attached to | +--------------------------------------+-----------+--------------+------+-------------+----------+-------------+ | 521c6a82-0aac-4418-a6b4-b458353c6039 | available | vol01 | 1 | None | false | | +--------------------------------------+-----------+--------------+------+-------------+----------+-------------+ # cinder delete vol01
novaのVMインスタンスにvolumeをアタッチする。
VM起動
nova boot --image ubuntu13.04-qcow2 --flavor 2 --key-name default vm01
volume作成 + アタッチ
nova volume-create --display-name vol01 1 # nova volume-list | grep vol01 | awk '{ print $2 }' 1e3534f0-e3c4-4147-82ec-c2cd9a86bd8f nova volume-attach vm01 1e3534f0-e3c4-4147-82ec-c2cd9a86bd8f /dev/vdb
VM上でアタッチされたボリュームを使用する
- アタッチされたボリュームにパーティションを作成
root@vm01:~# fdisk -l /dev/vdb Disk /dev/vdb: 1073 MB, 1073741824 bytes 16 heads, 63 sectors/track, 2080 cylinders, total 2097152 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000 Disk /dev/vdb doesn't contain a valid partition table root@vm01:~# fdisk /dev/vdb Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel Building a new DOS disklabel with disk identifier 0xcc49baf5. Changes will remain in memory only, until you decide to write them. After that, of course, the previous content won't be recoverable. Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite) Command (m for help): n Partition type: p primary (0 primary, 0 extended, 4 free) e extended Select (default p): p Partition number (1-4, default 1): Using default value 1 First sector (2048-2097151, default 2048): Using default value 2048 Last sector, +sectors or +size{K,M,G} (2048-2097151, default 2097151): Using default value 2097151 Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks.
- ファイルシステム作成
root@vm01:~# mkfs.ext4 /dev/vdb1 mke2fs 1.42.5 (29-Jul-2012) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 65536 inodes, 261888 blocks 13094 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=268435456 8 block groups 32768 blocks per group, 32768 fragments per group 8192 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (4096 blocks): done Writing superblocks and filesystem accounting information: done
- ファイルシステムをマウントする
root@vm01:~# mount /dev/vdb1 /mnt/
- ファイルを作成する。
root@vm01:~# ls /mnt/ lost+found root@vm01:~# echo "HELLO" > /mnt/hello.txt
- アンマウントする。
root@vm01:~# umount /mnt root@vm01:~#
volumeデタッチ
nova volume-detach vm01 1e3534f0-e3c4-4147-82ec-c2cd9a86bd8f
別のVMに作成済みvolumeをアタッチする
# nova boot --image ubuntu13.04-qcow2 --flavor 2 --key-name default vm02 # nova volume-attach vm02 `nova volume-list | grep vol01 | awk '{ print $2 }'` /dev/vdb
VM上でファイルシステムをマウント
- マウントし、別VMで作成したファイルが存在するか確認
ubuntu@vm02:~$ mount /dev/vdb vdb vdb1 ubuntu@vm02:~$ mount /dev/vdb1 /mnt/ mount: only root can do that ubuntu@vm02:~$ sudo su - root@vm02:~# mount /dev/vdb1 /mnt/ root@vm02:~# ls /mnt/ hello.txt lost+found root@vm02:~# cat /mnt/hello.txt HELLO