simplestarの技術ブログ

目的を書いて、思想と試行、結果と考察、そして具体的な手段を記録します。

Unity:安全な並列処理をする C# Job System について学ぶ

Unity の GDC2018 の英語発表見てるけど、長いな
まずは椿さんことUnityエヴァンジェリストの山村さんのブログ読んでどういう話なのか、知識を増やします。
tsubakit1.hateblo.jp

確かに、過去に Task とスレッドセーフキューを使った実装で、大量のブロックの相互作用をメインスレッドを停止させずに動かしたことありましたね。
simplestar-tech.hatenablog.com

これは確かにメインスレッドは結構余裕をもっていて、バックグラウンド処理が休みなく働いているイメージでした。
C# Job System はメインスレッドも休みなく働くようにスケジューリングできそうです。

Burstコンパイラ
(出典は山村さんのツィート)
scrapbox.io

1Tweetで分かる?Burstコンパイラ
・Mono、IL2CPPに並ぶ第三のコンパイラ
・厳しい条件指定のあるC#下(No GC,Noクラス,Noボクシング,No 例外処理)で最適化したアセンブラを吐く
・吐いたアセンブラはプレビュー出来る
SIMD で最適化 ・数字の精度を落としてさらに高速化

確かに高速になる機械語に翻訳してくれそうなルールですね。

この Burst コンパイラですが
手元の Unity 2018.2.2f1 は、プレビュー版ですが、Package Manager から有効化することができます。
ってことは、使い始めることは出来るってことですね(高速化試したい)

f:id:simplestar_tech:20180821073030j:plain

きっとそうだろうと思ったけど C# Job System では Collider や gameObject が取得できない
え、じゃあ RayCast とかもだめ?

それが C# Job System 用に RaycastCommand が作られているそうです。
Unity - Scripting API: RaycastCommand

なるほど、書式イメージは

1.入力作成
2.並列処理
3.結果利用

の3ステップですね。

■ NativeArray

あ、もしかして GCHandle.Alloc, handle.AddrOfPinnedObject を使わなくてもポインタ利用できる配列ってやつですかね?
ちょっと前 OpenCVC++のまま Unity で使う例を示した時に、WebCamTexture を cvMat として扱う時に使ってたやつです。
simplestar-tech.hatenablog.com

fixed いらずで unsafe ポインタを取得できるって、やるぅ!(C++のようにメモリの順番を使ったコード書ける!やった)
Unity - Scripting API: Unity.Collections.LowLevel.Unsafe.NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr

OnEnable で永続確保、OnDisable で Dispose による開放を行うのが良さそう

■ IJobParallelFor

並列処理するジョブはこのインタフェースを継承して、処理を実装するだけでよい
後は以下に紹介されている例を参考に Schedule, Complete の呼び出しで並列処理が完了する
Unity - Scripting API: IJobParallelFor

ひとまず書式は学べたし、並列処理を行えることも確認できました。

後半の
メッシュの変形やCubeの移動、ポイントクラウドや当たり判定
のデモの紹介が気になった。
github.com

今度はこちらを読むことにします。

AWS:Webページを作ってみる

インスタンスに独自の url を設定できたんだから、その url で Web ページを見てみたくありませんか?
そこで、次の記事を参考にしてみることにしました。

qiita.com

yum update コマンドまでは成功したのですが…

install nginx コマンドには失敗

Amazon Linux Extras を使ってみない?という旨のメッセージが表示される。

Amazon Linux Extras とは何ですか?
Amazon Linux 2 に関するよくある質問

Extras は、安定したオペレーティングシステムで新しいバージョンのアプリケーションソフトウェアを利用可能にする Amazon Linux 2 のメカニズム
Extras は、OS の安定性を確保しつつ、最新のソフトウェアを利用できるようにするうえで役立ちます
Extras の例には、Ansible 2.4.2、memcached 1.5、nginx 1.12、Postgresql 9.6、MariaDB 10.2、Go 1.9、Redis 4.0、R 3.4、Rust 1.22.1 などがあります

もう少し、このメカニズムについて調べて導入してみますかぁ

最小のドキュメントとして読むべきものはこちら
docs.aws.amazon.com

ここの Extras Library (Amazon Linux 2) 項目を参考に手を動かしてみた、まずは list で使えるものを列挙します。

amazon-linux-extras list

おお 21 項目のうち index 3 に nginx という Web ページ作るツールが見つかった
で?

sudo amazon-linux-extras install nginx1.12

こうしたらインストール成功した。
もともと docker はインストールされていたっぽいな
起動に関しては次のコマンドを打ったら、動くらしい(起動書式ってやつ?)

sudo chkconfig nginx on

あとは http の 80 ポート TCP で通信許可するようにセキュリティーグループにルール追加してきます
一応追加する前にアクセスすると?
アクセスできない
セキュリティーグループに HTTP の許可を与えると
アクセスできない

あ、もしかして起動コマンドは先に実行しておくべき?

sudo service nginx start

はいそのとおりでしたー、アクセスできました!
Welcome to Nginx on Amazon Linux のページが表示された

あとは scp というセキュアコピーのプロトコルWindows から安全にファイル操作できたらいいな

ということで WinSCP ソフトを入れるぞ
winscp.net

url とユーザー名 ec2-user で
設定にて privatekey.pem を指定したら OpenSSH 形式だから putty 形式に変換して保存までしてくれて
その putty 形式の privatekey.ppk ファイルを指定したら SCP 通信できることを確認できました。

あと、nginx のディフォルトの htmlファイル群のパスはどこでしたっけ?
/usr/share/nginx/html
ここに index.html があるのがディフォルト設定です。
設定を変更するには /etc/nginx/nginx.conf を編集します。

よし、これで AWS で Web ページを作れたし、編集も自由です。
あとは html の使い方のみ書式を見ていけば完了!

AWS:独自ドメインの購入とインスタンスのIPアドレスとの関連付け

AWS の一つに Route53 というものがある(なんで53なんだ?)

やりたいことは、ついさっき作成した Amazon Linux 2 の AMI からインスタンス化したリソースに
独自ドメインを使った url を割り当てて、その url を使って ssh 接続できるようにしたいというもの

独自ドメインはお金かかるのですが、だいたい 1000円~2000円くらいで 1年間の使用ができる。
ドメインですから、その前に適当な文字列入れて幾千もの url を作成することが可能になります。

さて、具体的な手順だけ知りたくなったので、記載場所を探したところ、ここに書かれていました。

docs.aws.amazon.com

ここに書かれてる手順を踏むだけで、30分後には有効なドメインを取得できました。

インスタンスの IP アドレスと、このドメインの適当な url を関連付ける方法は以下のサイトを参考にしました。

exrecord.net

具体的には、ホストゾーンにレコードセットを作成(A - IPv4 のレコードセット)
そこの Valueインスタンスの IP アドレスを貼り付けるだけで

目的の url を使った ssh 接続ができることを確認しました!

その時の cmd でのコマンド

ssh -i privatekey.pem ec2-user@dokuji.domain.net

AWS:AMIの作り方4-テンプレのAMIで作ったインスタンスから作成

ここまで AMI の作り方の記事を参考に見てきましたが、いよいよ S3 のバケットに AMI に関するファイルを出力する段階になって
ec2-bundle-vol コマンドをキーワードに調べたんですけど

>インスタンス内から ec2-bundle-vol コマンドを実行して、Amazon S3 にアップロードするバンドルを準備します。

インスタンス内から

はい、ということで最初は AWS が提供している AMI を使っていきましょう。

Linux を触るのですけど、二つあって困る

これは、何が違うの?
間違ったの選んだら終わるの?

Amazon Linux 2 のご紹介

既存のAmazon Linuxの後継となるOS
>Amazon Linux 2 は、アマゾン ウェブ サービス (AWS) 上で最適なパフォーマンスを発揮できるように調整された LTS Kernel (4.9)、systemd のサポート、および最新ツール (gcc 7.2.1、glibc 2.25、binutils 2.27) を使用した近代的な実行環境を提供
>PythonMariaDB、Node.js などの一般的なソフトウェアパッケージのより新しいバージョンを含む追加のソフトウェアを、Amazon Linux Extras リポジトリを使用してインストールできます
Red Hat Enterprise Linux 略して RHEL 7 ベースで作られるようになったのが Amazon Linux 2 だとか

「LTS」とは一体何?
長期サポート(LTS)

サポート期間が、従来の2年間から6年間に延長されることになった
通常と比べて長い間サポートされる
Linux KernelのLTSサポート期間が6年に伸びるということはメーカーにとって非常にうれしいニュース

なるほど、これから長いことサーバーを運用していくなら TLS 版のカーネルを利用するのがいいって話か
では Amazon Linux 2 を使っていいんじゃないですかね。

AWSインスタンス作成に進みますが
VPC はディフォルトで一つありますね、なんか vpc-f6f48xxx みたいな適当な名前のやつ
172.31.0.0/16 の CIDR ブロックが指定されていました 172.31.0.0 ~ 172.31.255.255 までのプライベートIPアドレス範囲か?
IPアドレスはクラスBの範囲だもんだが
なんでこんな IPアドレス範囲にしなければならないのかの基準の考え方が不明

まず CIDR は、ブロック単位のIPアドレス割り当て方式よりも、狭い範囲のIPアドレス割り当て範囲を指定できる仕組み
/16 ってのは 実は 2ブロック指定と同じ、8x8だから、そう /16 は固定 bit 数を指定していて、32bit に対する残りの 16 bit の 0.0 ~ 255.255 の範囲を指定するものだそうだ
/24 とかにすれば 0 ~ 255 の範囲を指定することになる、もうちょっと増やすには /23 とかにすれば 0.0 ~ 2.255 と、割り当て範囲を 2倍にするように指定することが可能だそうだ

今なら VPC の話を記憶しやすくなってきました、VPCで設定するのは全部プライベートIPアドレスなので、超自由
docs.aws.amazon.com

そして、適当に IP アドレスの範囲を CIDR 書式で指定しても
AWS によって必ず 5 つの IP アドレスが予約される
0: ネットワークアドレス
1: VPC ルーター用に AWS で予約
2: AWS で予約されています
3: 将来の利用のために AWS で予約されています
255: ネットワークブロードキャストアドレス、予約されている

ということで、VPC 内にインスタンスを作った場合は 4 ~ 連番でプライベート IP アドレスが振られるんじゃないかな?って予想が立ちました。

さて、インスタンス作成に戻って
VPCとサブネットは AWS がディフォルトで用意してくれていたものを選ぶようになっています。
今のところ VPC を切り替えなきゃいけないということもないので、そのままにしました。

インスタンスタイプでスペックが決まりますが、インスタンス数1, コア数1, メモリ1GB
次にストレージを選ぶのですが…Amazon EBS ボリューム?

Amazon EBS ボリューム - Amazon Elastic Compute Cloud
EBS ボリュームは、EC2 インスタンスの運用状況から独立した永続性を持ち、インスタンスにアタッチして利用する
メリット1:作成したボリュームは、同じアベイラビリティーゾーン内の任意の EC2 インスタンスにアタッチできます。別のインスタンスからストレージを利用するのに便利、インスタンス壊れてもストレージ残るので安全
メリット2:インスタンスがシャットダウンされてもデータが維持される限り、ボリュームの使用料が発生する。一緒に削除オプションはディフォルトで入っている
メリット3:暗号化は、すべての EBS ボリュームタイプでサポート、今回は使わない
メリット4:Amazon EBS は、Amazon S3 ボリュームのスナップショット (バックアップ) を作成し、ボリューム内のデータのコピーを EBS に書き込む機能を備えています。
メリット5:柔軟性
EBS ボリュームは、実稼働環境での設定変更をサポートします。サービスを中断せずに、ボリュームタイプ、ボリュームサイズ、IOPS 容量を変更できます

メリット5がすごいね、ハードディスクの容量が足りない状況で足せるのか、いいね。

ところで ストレージの性能指標 IOPSってなに?
Input Output Per Second のこと、100 はかなり遅い、10000 はかなり速い
ディフォルトでは最小の 100 だった

で、そんな EBS ボリュームを 8GiBでストレージに設定

次はタグをつけるかどうか聞かれる
いや、タグだけじゃ具体的に何なのかイメージできないよ
docs.aws.amazon.com

なるほど、めちゃめちゃインスタンスを立ち上げまくった場合に管理とかリストアップとか大変だから、プログラムのリスト内要素のキー名として、いくつかタグ付けておくと管理楽だよって話ですか

ほんと、マシンがプログラムの配列の要素として機能する社会を表す機能ですね。

セキュリティグループの設定で ssh 接続の IP アドレス制限ですが、マイIPを選択すると、今の家の環境のグローバルIPアドレス教えてくれるんですね
がっくし、じゃあ今後自分の IP アドレスを知るときは AWS のセキュリティグループの設定機能を使いますか

よし、これで SSH 接続できるのはこの家からのみになるはず、インスタンスを作って試してみます。
ec2-user がディフォルトユーザーであるとドキュメントにあったので、Amazpn Linux 2 の AMI から作ると ec2-user しか指定することができない

ssh -i privatekey.pem ec2-user@13.113.xx.xx

確かに実家からアクセスできた

そしてちょうど自宅に戻るので、自宅で同じようにアクセスしたところ、しばらくしてタイムアウト
なるほど!

そして、自宅のマイIPからの接続ルールを SSH に追加して、即座に自宅から SSH 接続に成功することを確認しました。
やったね、これでやっと安全に GNU / Linux を触れるようになった

AWS:AMIの作り方3-OpenSSLでX.509 証明書

Amazon のマシンイメージ作りたいだけなんだよ、なんで IAM とか SSL の話ばっかりになるんだよもう

X.509 証明書ってなんですか
なんで 509 なの?
なんで X. なの?

ITU という国際機関が定めたデジタル証明書の標準仕様
X.509は仕様の管理番号とみる
今日ではRFC 5280だそうだ(Request for Commentの5280の仕様を満たす証明システム)

現在ではバージョン3が使用されている
公開鍵とその公開鍵の持ち主の対応関係を保証するための電子署名として機能

CAによって割り当てられた正の整数
発行者が証明書に署名する際に用いるアルゴリズムハッシュ関数MD5SHA-1、SHA-2など。署名アルゴリズムRSA、DSA、ECDSAなど)

OpenSSL と X.509 証明書の関係は?
SSLはセキュアなソケットレイヤーのことで、公開鍵を使った暗号化基盤 PKI を提供するソフトウェアライブラリとして OpenSSL がある
OpenSSL は X.509 はもちろん、SSL に関する機能を提供してくれるとみた(つか X.509 または RFC5280の仕様以外のデジタル署名機能を OpenSSLはサポートしているのか?知らん )

コマンドラインツールとして無料で入手可能で、パスを通しておけばコマンドから適当な秘密鍵を作ったり、その秘密鍵から公開鍵を作ったりできる

よーし、じゃ OpenSSL をダウンロードしてコマンドを使えるようにして
RSA アルゴリズム秘密鍵、公開鍵をコマンドから作る書式を確認してファイル作ればそれが X.509 証明書ってことでいい?

Open SSL 入手先
https://www.openssl.org/

The 1.0.2 series is our Long Term Support (LTS) release, supported until 31st December 2019. とのことで、1.0.2 を手に入れてみた
Windows で動くバイナリ入っているのかなこれ?

入っていない
OpenSSLのソースファイルのみが配布されている。そこからWindows用にコンパイルするのは(開発者でない限り)ハードルが高い
じゃあ
「Shining Light Productions」ここから Windows 版を入手する
Shining Light Productions - Win32 OpenSSL

あれ?
1.1.0 の新しい OpenSSL のインストーラがある
以下の手順を参考に openSSL コマンドを利用できるようにパスまで通しました。
www.atmarkit.co.jp

今は openssl コマンドを打てます。
そこで、次のAWS の公式ドキュメントの説明の通り X.509 証明書を自己署名で 365 日期限で作ってみました。
docs.aws.amazon.com

あれ?
IAMのユーザーごとに設定できる認証情報には SSH 公開鍵のアップロードとあるけど
X.509 証明書と SSH 公開鍵って同一のみなせるのだっけ?


>X.509 証明書に記述された公開鍵

なるほど、同一か
証明書の中身をユーザーの認証情報に貼り付けておくことにした

あ、れ?
無効な SSH publick key だってさ

以下を参考に、手順を洗います。(エラー去ってまたエラー)
docs.aws.amazon.com

ふっふっふ。
なんと自己署名の手順を踏む必要なかったみたいですね。

openssl の以下のコマンドで作った publickey を IAM ユーザーの SSL 公開鍵として登録することに成功しました。

openssl rsa -pubout < privatekey.pem > publickey.pem

具体的には publickey.pem のファイルの中身をテキストコピーして、コンソール画面から貼り付けるだけ
これで invalid publick key のエラーが出ないことを確認しました。

この IAM ユーザーが SSL 通信する際は、元となる秘密鍵があればうまくいくはずです。(たぶん)

これで X.509 証明書をユーザーに設定する作業も完了だぜ(実際はただの公開鍵でしたが…周辺知識も少しは埋まったってもんだ)
IAM作成のための手順は次に進みます。

AWS:AMIの作り方2-IAM ユーザー作成

AMIというAmazon マシンイメージを適当に作りたいだけなのに、やれ権限だのマニフェストファイルを用意しておけなど
なんで一発で作らせないんだこのやろうと思うこのごろ

さて、まずはアクセスキー情報を作るために、IAM ユーザー作成が求められるようになっています。
仕方ないので IAM ユーザー作成の書式から学ぶことにしました。

AWSってサービス一覧を見ると画面を埋め尽くす勢いで項目が並びますが、ここからセキュリティうんたらの先頭付近にある項目
IAM (個別のアクセス管理)の項目を選択
さらにサブメニューにグループ→ユーザー→ロール→ポリシーなどが現れるので、ここのメニューから新規作成を行っていきます。

迷ったらもう一度ベストプラクティスを最初から読み直します。
docs.aws.amazon.com

確かにルートユーザーのアクセスキーをロックして、IAMユーザー作れってある
具体的にIAMユーザー作る手順はこちらと示される
docs.aws.amazon.com
仕方ないから全部読んで、手順通りにユーザーとグループを作成してみることにした。

一応 IAM ダッシュボードで 5つのステップの操作をこなして全部緑チェックの入った状態になりました。
IAMユーザーと管理者グループの作成は完了したことになります。

X.509 証明書?
OpenSSL で作成できるので、作った IAM ユーザーの認証情報に SSL 公開鍵をアップロードすることもあるだろう
https://www.openssl.org/

次 Open SSL の証明書とか公開鍵の話書きます。

AWSのAMIの作り方

Amazon のマシンイメージの略字として AMI というものがあるのですけど、要はどの OS で、どの CPU でコア数はいくつか、どんな感じのストレージにするのかなどを指定するわけです。

UIを直感的に操作して AMI を作れると思ったのですが、初めて登録するときにAMIマニフェストパスを求められるのです。
https://s3.amazonaws.com:443/~ の下にあるアレだよアレ 的な感じで

知らんがな、AMIマニフェストパスってなんぞや?

こちらの記事を参考に調べてみた
AWS: AMI の作り方(Amazon Machine Image)

証明書とかの情報を得るのに、まずはIAMというアクセス管理方法のベストプラクティスを読むことにしました。
docs.aws.amazon.com

AmazonWebサービス利用時にはIDとパスワードを利用するわけですけど
いきなり アクセスキー ID およびシークレットアクセスキー つかうなって話から始まる

そう、まずはコンソールにアクセスするのはIDとパスワードを使うことになる
ただし、AWSにフルアクセスできるようなアクセスキーは作らないと持つことはないと示されている
そして、そんなものを利用する機会はないのだから、絶対に作るなということだそうだ

うわ、作ってたし、Terraform でのインスタンス操作に使っていた…
今後のために削除しました。

で?代わりに IAM ユーザーを作ろうって話になっています。

IAMユーザー作成の前に実はグループを理解しないといけなかったんですよ
グループとは名ばかり、役割とでも言った方がしっくり来るでしょうか?
その役割を IAM ユーザーに設定することで管理を行っていくのです

最初は最低限の権限を持つ IAM ユーザーを作り、少しずつ権限を与えていくような運用にしましょう。
ポリシー概要で各グループやIAMユーザーの権限を確認してセキュリティを保ちます

ユーザーごとにパスワードを定期更新するように指示できる設定もあるそうだよ、管理者にとって便利な機能だね
より安全にワンタイムパスワード認証も取り入れられるとのこと(MFAって呼ぶらしい)

IAMユーザーの話を続けていたけれど、IAMロールってのもあるのですよ
IAMロールをアプリとかインスタンスに設定すればアプリ自体が AWS の別のリソースにアクセスできるようになります

説明わかりずらい、 IAM ユーザーが IAM ロールを引き継ぐことができるという文章があるので、ロールは IAM ユーザーに与えるものとして、混乱しながら読むことにしました。

ところで IAM ユーザーはアクセスキーとシークレットキーの二つを持ち、パスワードを持ちません
さらに管理者からIAMユーザーのアクセスキーを非アクティブ化することができます。
私、仕事で使っているアクセスキーを非アクティブ化されてたので、正しい操作を行ってはじかれるという経験をしてハマったことがありました。初めて AWS 触る人は、自分のアクセスキーがアクティブなのか、インフラ担当に聞いてから作業に入りましょう。

じゃ、そろそろ具体的に IAM ユーザー作成と権限の表示というものを見てみましょう
ということで次の記事に進みます