お茶漬けびより

"あなたに教わったことを、噛んでいるのですよ" 五等分の花嫁 7巻 「最後の試験が五月の場合」より

日記「『Design It! 10章 設計判断を可視化する』 を読みなおした」

この本『Design It!』 は、すでに一度読んだことあるけど(といっても第Ⅲ部はほとんど読んでない)後半はとにかく読み終えなきゃという気持ちが強かったので中身の理解が半々ですぐに忘れてしまった。前半も時間が経ちすぎてあんまり覚えてないので最近気になったとこを読み直し中。 内容も難しいので、メモとしてここに残しておきます。

読書メモ

  • アーキテクチャの詳細を一つの図で捉えることは不可能
    • 複数のビューを作成する
    • ソフトウェア・システムを説明するためのビューは、Google マップのように様々な視点から見れるようにする
  • 要素責務ビュー
    • 要素と責務が一覧できるビュー
    • プロジェクトによってはこれだけで済む
    • 基本的には情報が欠けているので、注釈や表形式、説明文などを記述して責務を説明する
  • 絞り込みビュー
    • 一部の要素の詳細を表示するビュー
    • 詳細度によってはモジュールごとの関係や保守性について知ることができる
      • 例えば、一部のモジュールが相互に依存しておりそのモジュールのテストがしづらいなど
  • 品質特性ビュー
    • アーキテクチャが特定の品質特性をどう実現するかを示す
    • 例えば、可用性を示す場合は、冗長パターンがビューで示される
  • アーキテクチャのラフスケッチ
    • 精密さには欠けるが素早い反復と形式張らないコミュニケーションには有用
      • また、自分のアイデアを膨らませるためにも使える
    • 設計が固まってきたら正確なモデルを描く
  • 素晴らしい図は、アーキテクチャを誰でも触れられるものにする
    • 素晴らしい図を作成するためにすべきこと
      • 図に関連するメタモデルを要約した凡例を作成する
      • 説明的なタイトルを追加する
      • テキスト注釈を追加する
      • 表記法を一貫する
      • パターンをわかりやすくする
    • 素晴らしい図を作成するために避けるべきこと
      • UML のような表記法を知っていることを前提にする
      • すべてを一つの図に含める
      • 白黒で印刷すると意味がなくなる書き方をする
      • 意味のない飾りや多種多様な形、線を使い過ぎる
      • 説明文を省略する
    • 叙述的散文でアーキテクチャについてのストーリーを語る
      • 物事を客観的な説明によって順に並べた文章のこと
      • 11 章で詳しく説明される
  • 図を上手く描いて、上手く使えば、アイデアを発展させることができ、ステークホルダーとの共有もできる。
    • また、品質特性についての設計判断を行うことができるようになる
  • 6 章や 8 章を理解しておくと理解が深まりそう

感想

この本を読んでから、品質特性について意識しないといけないという気持ちが強まっているので、図から品質特性の設計判断ができるのは勉強になった。 見方に合わせて図(ビュー)を変えるのは何となく分かっていたつもりだけどこれを読んで腑に落ちた感じ。

最近は最初の設計段階では紙に書くことが多く、人に説明する必要が出てきたり、考慮すべきことが増えてきたらツールを使ってビューを作ってる。 ツールは、VSCode で使える Draw.io拡張機能が手軽で便利。昔は PlantUML で書いてたけど、最初に使うには手軽とは思えないし、モデルの配置が思い通りにいかないので使いづらい。状況によっては PlantUML を使うのがいいのかもしれないけどあまり思いつかない。

詳細度を変える話で、設計ドキュメントをまとめておくときにフォルダ構造を詳細度に合わせるといいのかもなと思った。深くなれば詳細になっていくようにしておけば、何も知らない人は知りたい詳細度に合わせてドキュメントを探しやすい?

marketplace.visualstudio.com

おしまい

日記「仮想マシンとコンテナについて調べたこと」

仮想マシンとコンテナについて調べたので分かった範囲で残します。

仮想マシンについて

複数のOSを使いたい場合、仮想化の手段としては大きく2つあると思ってた。それは、OSの仮想化とマシンの仮想化。調べるとOSの仮想化というのはなくて、コンテナという技術だった。コンテナ技術がOSの仮想化のように書いてある記事も見かけたけど、コンテナについて調べていくとそれは違うんじゃないかなぁという印象。これは後述する。

コンテナを仮想化に含めないとすると、結局複数のOSを使いたい場合は仮想マシンしかない。

マシンの仮想化には大きく分けて2種類あるけどそのどちらのソフトウェアもハイパーバイザと呼ばれている。そのハイパーバイザには Type1, と Type2 の2種類がある。

Type1 はベアメタル・ハイパーバイザやネイティブ・ハイパーバイザと呼ばれている。ハードウェア上で動くのでこのソフトウェアがホストOSになる。Hyper-VKVM, VMWare vSphere, Xen など。

Type2 はホスト型ハイパーバイザと呼ばれている。ホストOS(WindowsmacOS, Linux など)の上で動くソフトウェア。Oracle VirtualBoxVMware Workstation は Type2 らしい。

ホストOSはハードウェア上で動く唯一のOSのことで、ゲストOSはその上で動くOSのことだと認識してる。なので、Type1 のハイパーバイザはそれ自身がホストOSになると理解している。

で、Hyper-Vが Type1 ってことは、Hyper-V を有効にしたり、WSL2 を使ったりするとホストOSだった Windows もゲストOSになるってことで、つまりハイパーバイザを介して動くようになる。これがどういうことかというとゲームするときに多少なりとも影響出るんじゃないのかな。対戦ゲームとかするならゲームするPCと開発用PCはわけたほうがいいのかな。

Hyper-Vパーティションと呼ばれる領域で仮想マシンを分けていて、ルートとなるパーティション(親パーティション/ルートパーティション)が必ず一つ存在するらしい。これはもともと入れてた Windows が親パーティションに割り当てられる(?)。この親パーティションは他の子パーティションを作成したり、子パーティションからのデバイスへのアクセス要求を処理したりする。

コンテナ

コンテナ技術について調べたけどまだ理解しきれてない感じがある。 コンテナには2種類ある。アプリケーションコンテナとシステムコンテナ。Docker で流行ってるコンテナはアプリケーションコンテナのことで、システムコンテナは古くからあるコンテナ技術らしい。

アプリケーションコンテナというのは、1機能1コンテナとして扱う。プロセス単位で扱うのは厳密には正しくないそうだけど正直よく分かってない。 システムコンテナは、仮想OSと呼ぶ方が近いのかもしれない。正直こっちもよく分かってない。システムコンテナの場合は、1コンテナに複数の機能が混ざってもいい。

コンテナはホストOSのカーネルを利用するので、同種類のOSじゃないとダメ。例えば、Linux の上に Windows のコンテナを立ち上げることはできない。Windows の方で Docker が使えるのは、昔は、 Hyper-V 上で Moby VM という仮想マシンを作ってそれを使って Docker が動いてた。今は WSL2 を使って Docker を使えるようになっている。WSL2 は Hyper-V 上で動く Linux カーネルのため、通常の Linux 上で動かす Docker と変わりない。

Docker で使われているコンテナの仕様は Open Container Initiative(OCI)によって標準化されている。コンテナイメージや、ランタイム、レジストリなどが定められている。そのため、この仕様に則っていれば Docker に限らずにコンテナ化することができるし、コンテナイメージを作って共有することができる。

システムコンテナのほうはこの仕様とは関係ないので Docker や同じ仕様で作られたイメージを使うことはできない(?)。Linux だと LXC/LXD などで作れる。

アプリケーションコンテナとシステムコンテナが共通しているのは、namespace や cgroup のような Linux カーネルの機能を使ってコンテナを実現している点。Linuxカーネルの互換性が高いのでそこに依存している。イメージ側が最新のカーネルにしかない機能を使っているいて、ホストOSのカーネルにその機能がないなら動かない。

おわりに

調べれば調べるほどわからなくなっていくけど前よりは理解している状態になったかなという感じ。これ以上はそれぞれのアプリを実際に使って理解を深めていくしかないかな。とくにコンテナ側は Docker や Kubernetes, LXD/LXC とか使ってみないとしっくりこない。あと Linux 側の知識がなくて理解できてない部分もあるかな。

参照した資料

仮想マシンに関して

仮想マシンとOS仮想化とは似て非なるもの | Think IT(シンクイット)

ハイパーバイザー (hypervisor) とは | Red Hat

Hyper-Vの実装--親パーティション | 日経クロステック(xTECH)

Hyper-V のアーキテクチャ | Microsoft Docs

Hyper-V のアーキテクチャ | Microsoft Docs

コンテナに関して

雲になったコンピュータ: コンテナーの世界!(1) -Virtuozzo、Soralis、Linux(LXC)、そしてDocker- 

Linux Containers - LXD - イントロダクション

各仮想化技術の違いをざっと理解するッ!! - Qiita

コンテナってなんだろう― 「コンテナ」の概要を知る | Think IT(シンクイット)

Linux Containers - LXD - イントロダクション

コンテナ技術入門 - 仮想化との違いを知り、要素技術を触って学ぼう - エンジニアHub|Webエンジニアのキャリアを考える!

Docker

Software Design 2021年12月号|技術評論社

イラストでわかるDockerとKubernetes (Software Design plus) | 徳永 航平 |本 | 通販 | Amazon

図解即戦力 仮想化&コンテナがこれ1冊でしっかりわかる教科書 | 五十嵐 貴之, 薄田 達哉 |本 | 通販 | Amazon

Dockerコンテナの仕組み -namespace、cgroup、overlayfs- - ネットワークエンジニアを目指して

俺は Linux コンテナについてなんにも解っていなかった 〜 haconiwa で学ぶ Linux コンテナ (1) 〜 | iret.media

Docker Engineとは何か

コンテナユーザなら誰もが使っているランタイム「runc」を俯瞰する[Container Runtime Meetup #1発表レポート] | by Kohei Tokunaga | nttlabs | Medium

[翻訳] Dockerについてよくある勘違い|TechRacho by BPS株式会社

【メモ】ion-menu に配置した ion-item に button を指定しても反応しない

最近また Ionic を触りだしたのですが、その中で詰まったことがあったので小まめに公開していきたいと思います。 Ionic を触りだした人の役に立てば幸いです(もちろんそれ以外の人にも)。

結論

<ion-menu> に指定する contentId はその <ion-menu> 内にあるコンテンツのIDを指定してはいけない

発生した問題

f:id:pickles-ochazuke:20210912214727p:plain

メニューを横から出して遷移したいページに飛べるようなメニューを作りたくて、以下のような HTML を書きました。 クリックの内容は仮実装でコンソールログを出力するだけです。

<ion-app>
  <ion-menu contentId="main">
    <ion-content id="main">
      <ion-item button (click)="onClick()">
        <ion-icon name="home"></ion-icon>
        <ion-label>Home</ion-label>
      </ion-item>
    </ion-content>
  </ion-menu>

  <ion-router-outlet id="main"></ion-router-outlet>
</ion-app>

ですが、 <ion-item> をクリックしても何も反応しません。

解決方法

<ion-menu> 内にある <ion-content id="main">id="main" を削除するか、別の ID に変更します。つまり、以下のようになります。

<ion-app>
  <ion-menu contentId="main">
    <ion-content>
      <ion-item button (click)="onClick()">
        <ion-icon name="home"></ion-icon>
        <ion-label>Home</ion-label>
      </ion-item>
    </ion-content>
  </ion-menu>

  <ion-router-outlet id="main"></ion-router-outlet>
</ion-app>

※手探りで要素を見て自分なりに解釈したので、今から説明するのは正しい説明ではないかもしれないです。

<ion-menu>contentId に指定したコンテンツを対象に表示するため、指定するのが必須なのですが、<ion-menu> 内のコンテンツ(今回だと <ion-content>) にするとメニュー(というよりメニューを構成する一部の要素)がその上に表示されるような感じになってしまうため、<ion-item> がクリック出来なくなるようです。

解決策としては、<ion-menu> 内のコンテンツの ID を指定せずに、正しいコンテンツの ID を指定する。です。 意図的にしていたわけではなかったのでただの凡ミスなのですが、この経験で少し Ionic を理解した気になりました。

おわりに

今回はたまたま ionic start で作成するスタータープロジェクトにサイドメニューを作ってあるプロジェクトがあったのでそれと見比べたりいじったりで発見することが出来ました。 Ionic のスタータープロジェクトはちょっとしたテクニックがあるので勉強になります。

Ionic のプロジェクトを Bitbucket のパイプラインで Firebase にデプロイする

Ionic のプロジェクトを Bitbucket のパイプラインで Firebase にデプロイする

突然ですが、オグリのどんぶりが届きました。海鮮丼食べたいです。

f:id:pickles-ochazuke:20210712041547j:plainf:id:pickles-ochazuke:20210712041550j:plain

最近ちまちまと Ionic を触っています。PWA の対応(これは Angular の機能) やスマホ向けにビルドできたりするのでなにか簡単なものを作ってリリースしてみたい気持ちが高まっています。その中で CI/CD を使えるようになりたかったので試してみました。参考になれば幸いです。

公開することを目的にしているので確認は少し手抜きです。間違いやもっといい方法があれば教えていただけたらと嬉しいです。

概要

  • Ionic でプロジェクトを作る
  • Bitbucket にプッシュ
  • パイプラインの作成
  • Firebase にデプロイ
  • パイプラインでデプロイ

Ionic でプロジェクトを作る

Ionic のインストールは動作確認してないのでこれでいけるかわかりません。 公式に従えば問題ないと思います。

npm install -g @ionic/cli

ionicframework.com

プロジェクトを作ります。

ionic start myApp blank --type=angular --capacitor

なぜか自分の環境ではエラーが出ます。Angular のほうで使ってる karma-jasmine-html-reporter が要求する jasmine-core のバージョンが合ってないようです。 なので、バージョンを変えます。package.json を開いて、次のように変更します。

- "jasmine-core": "~3.7.1",
+ "jasmine-core": "~3.8.0",

npm install をして、一応 npm audit fix を強制的にしておきます。

npm install
npm audit fix --force

ionic serve で実行して動くことを確認します。

ionic serve

Bitbucket にプッシュ

Bitbucket にプッシュするために Bitbucket 側にリポジトリを作成します。

bitbucket.org

リポジトリ名を作成したプロジェクトの名前と同じようにしておきます。

f:id:pickles-ochazuke:20210712034712p:plain

f:id:pickles-ochazuke:20210712034821p:plain

リポジトリのURLをコピーします(ページのコピーをすると git clone がついてきます)。

git init
git remote add origin https://xxxx@bitbucket.org/xxxx/myapp.git

Ionic のプロジェクトをプッシュしてリポジトリに反映させます。

git add --all
git commit -m "first commit"
git push -u origin master

プッシュができたらF5でページをリロードして、プッシュしたファイルが表示されることを確認します。

パイプラインの作成

ここからは Bitbucket 側の操作です。 左のメニューから Repository setting > [PIPELINES] Settings を選択し、Pipelines Settings を開きます。 Enables Pipelines を有効側にします。

f:id:pickles-ochazuke:20210712034734p:plain

Configure bitbucket.pipeline.yml ボタンをクリックしてパイプラインのファイルを作成してもらいます。 ボタンを押しても作成してもらえるわけではなさそうなので、左のメニューから Deployments を選択してページを移動します。 すると bitbucket.pipeline.yml の内容が編集できるページが開きます。

f:id:pickles-ochazuke:20210712035152p:plain

右下に Commit file があるので、それをクリックしてコミットします。 コミットをするとパイプラインが動くようになって、先ほどコミットした内容で実行されます。 数秒待つと以下のようなページが表示されて成功していることを確認できます(失敗する場合は緑の箇所が赤くなっています)。

f:id:pickles-ochazuke:20210712035214p:plain

パイプラインを動かせることを確認しました。次は、Ionic プロジェクト側に戻って Firebase にデプロイする準備をします。

Firebase にデプロイ

まずは、先ほどコミットされたパイプラインの内容を反映させるため、リモートの内容を反映させます。

git pull

Firebase にデプロイするためにまずは Firebase の環境を作ります。 まずは、 Firebase のページに移動し、プロジェクトを作成します(ここでは myApp にしました)。

firebase.google.com

f:id:pickles-ochazuke:20210712035240p:plain

ここでは npm の firebase/cli を使用するので、以下のようにしてツールを取得します。 ログインもしておきます。

npm install -g firebase-tools
firebase login

ちなみに、長期間ログインして放置しているとログイン状態でも firebase を操作できなくなります。 その場合は、一度 firebase logout でログアウトして、再度ログインすれば問題ないと思います。

ログインできたら、次のコマンドで Firebase の初期化を行います。

firebase init

するといくつか質問されるので、答えていきます。

? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confir
m your choices.
◉ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
? Please select an option:
❯ Use an existing project
❯ myapp-3c20c (myApp)
? What do you want to use as your public directory? www
? Configure as a single-page app (rewrite all urls to /index.html)? (y/N) n
? Set up automatic builds and deploys with GitHub? (y/N) n

初期化に完了すると .firebaserc, firebase.json が作成されます。 準備ができたので、次のコマンドでデプロイできるか確認します。

ionic build --prod
firebase deploy --only hosting

デプロイが確認できたらコミットしておきましょう。

パイプラインでデプロイ

最後です。ローカルから手動でデプロイできることが確認できたので、次はパイプラインでデプロイします。 まず、Git のリモート側とローカル側の情報を同期しておきましょう。

次に CI 環境でデプロイするために次のコマンドで Firebase にトークンを発行してもらいます。

firebase login:ci

コマンドを叩くとブラウザが開き、認証画面が表示されるので許可します。 許可したら、コマンドを実行したターミナルに戻り、出力されたトークンをメモしておきます。

ここから Bitbucket 側で操作しますが、master ブランチではなく別のブランチで作業します。左のメニューから ブランチ を選択し、右上にある Create branch ボタンをクリックしてブランチを作成します。ブランチ名は configure-deploy-pipeline にしました。

f:id:pickles-ochazuke:20210712035319p:plain

ブランチを作成したらソースのページに移動し、ブランチを configure-deploy-pipeline に切り替えます。

f:id:pickles-ochazuke:20210712035439p:plain

切り替えたら bitbucket-pipelines.yml を選択します。 bitbucket-pipelines.yml の内容が表示されたら右側にある 編集 ボタンをクリックして編集のページに移動します。

そして、一番下にある内容を次のように書き換えます。PROJECT_ID は人によって異なるので、Firebase で確認して自身の環境に合わせて変更してください。

    - step:
        name: 'Deployment to Production'
        deployment: production
        script:
          - npm install -g @ionic/cli
          - npm install
          - npx ionic build --prod
          - pipe: atlassian/firebase-deploy:1.2.0
            variables:
              FIREBASE_TOKEN: xxxxxxxx
              PROJECT_ID: 'myapp-xxxx'
              MESSAGE: 'Deploying myApp'
              EXTRA_ARGS: '--only hosting'
              DEBUG: 'true'

また、一番上に使用するイメージの情報が書かれているのですが、これを node 14.17 を使いたいので次のように変更します。

- image: atlassian/default-image:2
+ image: node:14.17

編集が完了したらコミットボタンを押してコミットします。 Pipelines のページに飛んで、一番上にある Status をクリックすると何が行われているか確認できます(左側にステータス、右側にログが出力されるページに飛ぶ)。

f:id:pickles-ochazuke:20210712035507p:plain

f:id:pickles-ochazuke:20210712035610p:plain

成功したら master(main) ブランチにマージしておきます。ブランチ のページからマージするブランチを選択し(configure-deploy-pipeline)、マージ ボタンをクリックして、マージします。

f:id:pickles-ochazuke:20210712035851p:plain

最後にデプロイが成功しているか Deployments ページで確認し、Firebase のプロジェクトの Hosting 側でもデプロイされていることが確認できると思います。

エンジニアのためのマネジメントキャリアパスを読んだ

最近エクストリームプログラミングを身に着けたい気持ちが高まっています。

どういう本か

プログラマーシステムエンジニア(自分はプログラマーの中にシステムエンジニアが含まれていると思っているけど)の人がテックリードやマネージャ、チームリーダー、経営幹部(CTO)へと登っていくために必要なスキルや心構えのようなことを各役職ごとに書かれています。主に管理職になるための参考書です。

新社会人の人や経験が浅い人などにはまだ必要ない本に思えるかもしれませんが、そんなことはありません。1章では自分が成長するためには上司とどう向き合っていけばいいか書かれていますし、2章ではメンターにとっての心構えですが、この話は後輩への指導に役立つと思います。3章のテックリードでは技術とビジネスにどう向き合っていくか、コミュニケーション能力はどうして必要なのかが読んでいると伝わってきます。

会社によってはテックリードやメンタリングのような制度はないでしょうが(実際自分のところではない)似たような仕組みはあるのではないでしょうか。ですので、今その立場でなくてもここでの内容を頭の片隅に置いておき仕事で意識することで、先行して身につけておくことができると思います。テックリードがなくてもプロジェクトマネージャ(リーダー)という役割はあると思うので3章のテックリードの話はきっと役立ちます。

感想

自分がこの本を読んで感じたことは、次の5つです。

  • 伝達するスキルが必要
  • チームで成果を最大にするために行動すること
  • 技術的なスキルとビジネス的なスキルを身につけること
  • プロジェクト管理のスキルを身につけること
  • 相手を理解し、相手に合わせて行動すること

「伝達するスキル」というのは、会話やプレゼンテーション、文書を書くスキルのことです。

「チームで成果を最大にするために行動すること」というのは、自分だけの生産性を高めるのではなく、メンバーの生産性が最大化するようにメンバーの様子に気を配ったり、作業が並行して進められるようにタスクを分割したり、面倒な作業を自動化するなどといったチームが円滑に作業を進められるように動くことです。ただサポートをするのではなく、プロジェクトが進むように優先順位やスケジュールの調整などのような点も気にしないといけません。

「技術的なスキルとビジネス的なスキルを身につけること」というのは、アーキテクチャを設計するためのスキル、ビジネスを実現するための技術への深い理解、ビジネス要件の理解というような能力が必要だということです。

「プロジェクト管理のスキルを身につけること」というのは、チームで成果を最大化することと被るのですが、大きなタスクを定期的に製品として提供(デリバリ)できるようにタスクを細かく分割し、それをメンバーで並行して作業できるように分担したり、作業の優先順位をつけてプロダクトの価値が最大化するように調整したり、客先や会社の要望を調整したりなどといった能力が必要だということです。

「相手を理解し、相手に合わせて行動すること」というのは、メンバーはもちろんのこと、客先の人や会社への報告などをプロジェクトが円滑に回るように行動するということです。

自分は最近プロジェクトマネージャを担当することが出てきたのですが、正直プロジェクト管理能力は足りていないと実感しており、特にスケジュールや見積もりというのがどうも苦手でアジャイルのような手法が世の中に浸透している中スケジュールや見積もりなんて当たりっこない、必要ないと半ば諦めていたのですが、この本を読んで当てることが大事なのではなく、今の進捗が全体のどのあたりなのか、あとどれぐらいかを大まかに把握するために必要ということが書いてあり、もう少し精度を上げるために努力しようと思い直しました(あとアジャイルでも見積もることはするので自分の考えは間違っていることは理解していました)。

また、将来自分がどうなりたいかを知るための本としても有効で、特にテックリードの章は自分が目指したい人物像(そこまではっきり目指しているかというと微妙ですが)に当てはまるのでこれを参考に行動していきたいと思いました。

後半の 6, 7, 8 章は自分にはまだ早いと感じたので飛ばしたので、また時間が経てば読み直そうと思います。

最後に管理職になるのは抵抗があったのですが、この本を読んで管理職になる機会があればなってみて、そのときに考えたらいいかなと思いました。