kuwana-kbの開発/学習ブログ

プログラミング、クラウドインフラのWeb開発/学習ブログ

「Docker実践ガイド 第2版」 書評

こんばんは、kuwana-kbです。
私のいるチームではDockerを用いた開発を行っているのですが、お恥ずかしいことに私はDockerのことをよくわかっていませんでした。
Dockerに関するタスクはチームの人にお願いしていたのですが、いつまでも任せっきりはチームとして健全じゃないな…という思いもありました。

そこで今回は「Docker実践ガイド 第2版」です。
本書を通じてDockerの基礎を学んで参りましたので書評として投稿したいと思います。

Docker実践ガイド 第2版 (impress top gear)

Docker実践ガイド 第2版 (impress top gear)

ざっくりと3行でいうと

  • Dockerを実戦形式で学べる本
  • Dockerの基礎から近年話題のKubernetesまで網羅されている
  • Webエンジニアだけでなく、IT管理者にもおすすめ

この本の紹介

この本は、Dockerコンテナの実行環境の構築および管理手法について実践形式で解説した本です。解説の対象は主に以下になります。

  • Docker
  • Dockerfile
  • Docker Community Edition, Docker Enterprise Edition
  • Docker管理ツール(Docker Compose, Docker Machine, Private Registry)
  • ネットワーキング(Docker Swarm)
  • コンテナ用OS(CoreOS, RancherOS)
  • オーケストレーションツール(Kubernetes

では、次に各章のざっくりとした紹介です。

第1章 Dockerとは?

この章では、主にDockerの特徴について解説がなされています。物理ホストや仮想化技術との比較を通じて、コンテナ技術の魅力が理解できるでしょう。また、近年のIT業界の歴史というコンテキストから、Dockerの優位性や課題が解説されている点も興味深いです。

第2章 Docker導入前の事前準備

この章では、Dockerを導入する前に検討すべき事柄や前提知識に関しての解説がなされています。事前準備というと「個人」としてどういうツールや環境を用意しておくべきかと思うかもしれません。しかし、ここで述べられているのは「エンタープライズ」レベルでの事前準備です。
したがって、この章で解説される内容は、企業内のシステム管理者やIT管理者といった方向けの情報といえるでしょう。

第3 ~ 10章 実践

ここからは「この本の紹介」で上げた技術・ツールを実践していきます。すべての項目においてサンプルコードが記載されています。ただし、2つ注意点があります。 1. サンプルコードの実行環境がCentOSであること 2. 物理ホストが3台ほど必要になる場合があること(docker swarm, kubernetes等) 個人で行う場合の代替案については後ほど触れたいと思います。

この本のポイント

2019年初頭のコンテナ技術に関する最新情報が載っている

本書は2019/02/18に出たばかりの本のようで、この書評を書いている時点(2019/03/16)では、コンテナ技術に関する最新情報や今に至るまでの歴史的背景が掲載されています。 この点は、これまでコンテナ技術にあまり触れてこなかった私のような人間にとっては嬉しいことです。

また、解説対象がDocker、コンテナ専用OS、DockerCE/EE(コミュニティ版・エンタープライズ版)、オーケストレーションツールと幅広い点も魅力です。特にDocker CE, EEの解説はあまりネット上には載っていないので、社内オンプレでDockerを構築・運用するような部署(IT管理者やインフラエンジニアでしょうか?)の方には嬉しいのではないでしょうか。

コンテナの便利さを実感

サンプルコードを実行すると、すぐにコンテナを作れます。 wordpress + mariadbの環境をわずか数コマンドで構築できたときは、その便利さに驚きました。
以下は、私が実際に作ってみた時のツイートです。

実行環境に注意が必要

先程も述べましたが、実行環境には注意が必要です。 私の場合はDocker for Mac でサンプルコードを試したのですが、いくつか動作しないものがありました。 これはDockerの仕様上、仕方ない部分のようですが注意が必要です。*1

上記のようにMac(おそらくwindowsも)だとつまづくポイントがあるので、できれば書籍と同じCentOSの環境で学習することをおすすめします。

また、物理ホストを3台使用した例などもあって、個人でやるには難易度が高いものもありました。 こちらについては、私はクラウドインフラで代用しました。 具体的にはkubernetesの環境構築において、GCP(Google Cloud Platform)のGKE(Google Kurbenetes Engine)を使用しました。 (自分でノードの設定等をする必要がないので完全な代替ではないのですが…)

GKEを使って思ったのは、マネージドサービスって構築が楽…!ということです。 本書は物理ホストで作業する前提のため、マスターノードやワーカーノードの作業が細かく書かれていたのですが、 そういった作業を一切意識する必要なく簡単にkubernetesを用いた環境構築ができてしまいました。

まとめ

「Docker実践ガイド 第二版」は解説の幅が広く、IT管理者やサーバーエンジニアの方も満足行く内容だと感じました。 一方でクラウドのマネージドサービスを使用する前提で、とりあえずDockerを使えるようになりたい!という人には、本書は情報過多かもしれません。(もちろん知っておいて損にはなりませんが!)

本書は、Dockerについて実戦形式で学びたい方、Dockerの導入を自社で検討されている方におすすめできる本だと思います。

*1:おそらくこちらの公式ドキュメントの記載されている内容が原因 Mac OS X — Docker-docs-ja 1.12.RC2 ドキュメント

「リーダブルコード」 書評

こんばんは、kuwana-kbです。
この1ヶ月間Goの学習をしていまして、ある程度すらすらと書けるようになってきたかな〜と感じています。
ただ、「自分の書くコードが他者からみるとどうなのか…?」という部分が気になっていまして、 そんな悩みを解決すべく「リーダブルコード」を読んでみました。

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

ざっくりと3行でいうと

 * コードの「読みやすさの基本定理」を教えてくれる本
 * 技術書の中ではとても読みやすい
 * 身につけるのはそう簡単ではなく、「リーダブルコード」とは長い付き合いになりそう

この本の紹介

この本は、読みやすいコードとは何か?実現するためにどういう技法があるか?を解説した本です。解説の対象となるのは変数/関数の名前といった表面的な部分からコード全体の設計に至るまで、と多角的に読みさすさに関して言及しています。

多くのエンジニアが読んでいる人気の書籍のようです。社内SNSで「エンジニアになりたての頃に読んでおくべき本あります?」と質問したところ、この「リーダブルコード」が一番人気でした。

では、次に各部のざっくりとした紹介です。

第一部 表面上の改善

まずは簡単に実践可能な、コードの表面上の改善から話は始まります。 識別子の適切な命名や優れたコメントを書くことで、コードの読みやすさを改善していく方法の話がメインです。 構造的な変更を含まないため、コード改善のとっかかりとして始めやすい技法だと思いました。

第二部 ループとロジックの単純化

次はコードを動かすための制御フロー・論理式・変数についてのお話です。 なかでも、以下の技法はすぐに取り入れたいと思いました。 ・「論理式を書く順番は変動値<固定値にする(口語的で読みやすいため)」 ・「ネストを避けるために直線的なコードにする」

第三部 コードの再構成

ここからは「コードの再構成」ということで、よりマクロな話になります。 具体的にはそのコードの主目的を定義して、処理の中で無関係なコードを抽出して別の関数にするといった技法です。 例えば、URLを生成する関数において、正規表現を行う処理は別の関数としてまとめる、といった感じ。 無関係な処理かどうかを識別して、適切な粒度で汎用化する必要があるので体得するには時間がかかりそうな印象を受けました。

第四部 選抜テーマ

この部では、これまでの部で解説された技法を以下のテーマに適用する過程を紹介してくれます。

  • 「テストと読みやすさ」
  • 「『分/時間カウンタ』を設計・実装する」

技法はわかったけど実際どういう基準で適用するの?という疑問点が解消されるでしょう。

この本のポイント

1.カジュアルで読みやすい

これまで読んだ技術書の中でかなり読みやすい方だったと思います。 個人的に技術書というと表現が堅く、腰を据えて読むものという印象がありますが、 本書は読者に優しく語りかけるような語り口で、かつコミカルな挿絵もありスイスイと読み進められました。 内容も200ページと長すぎず、2日あれば読み終えられるような長さだったのが良かったです。

2.読むに易く、行うに難し

読みやすいのは良いことなんですが、本書で解説されている技法を身につけるのはそう簡単ではないとも感じました。 例えば言語の技術書であれば、1ページ毎に「読む→サンプルコード書く→応用してオリジナルで書く」といった形で実践していけば、本を読み終わる頃にはある程度力がつきます。 しかし、本書は読みやすい一方で実践の場は自分で見つけないといけません。 そして、以下のツイートのとおり結構難易度が高いと思います。

読んだはいいけど結局身についていない、という状態に陥りやすそうな印象を受けました。

3.読みやすいコードを身につけるには

本書では様々な技法が紹介されますが、根本的には 「このコードは他の人が理解できるか?」 を自問し続けることが何よりも大切だと感じました。

なので、「実装すべき機能のコードを書き上げられた!すぐにコミット!」ではなく、 「コミットの前に一度読み直してみよう」と、読み手の視点になってコードを見直す習慣を付ける所から始めるのがよいのかなと。 そして、もし見直す中で理解に詰まるコードがあったら、この「リーダブルコード」を手にとって適応できる技法がないか探してみる。

そういった日々の積み重ねによって、ようやく読みやすいコードが身につくのではないかと感じました。

まとめ

「リーダブルコード」を通じて読みやすいコードとはなにかを具体的にイメージできるようになりました。 しかし、本書を読み終えただけでは読みやすいコードを書くためのスタート地点にたったに過ぎないでしょう。 実際に読みやすいコードを自分で書けるようなるには、本書を読むだけではなく「実践して他者からフィードバックをもらう」を繰り返す必要があると感じています。

ということで、読みやすいコードを身につけるため、今後も「リーダブルコード」にはお世話になりそうです。

「Goプログラミング実践入門」 書評

こんばんは、kuwana-kbです。
前回の「スターティングGo言語」でGoの基礎を一通り学習したので、次は実際のWebアプリ開発について学びたいと考えました。
そこで今回は、「Goプログラミング実践入門」という本を読んで実践したのでまとめたいと思います。

ざっくりと3行でいうと

 * HTTPの基礎からGoによる実装/テスト/デプロイまで学べたよ!
 * Goを用いてRESTful APIや掲示板アプリ作れたよ!
 * 一通りGoの文法を理解した人でアプリケーション開発をしてみたいという人におすすめだよ!

この本の概要

この本では、Goを用いてWebアプリケーションを開発していきます。全体の流れとしては、Webアプリケーションとはなにか?から始まり、Goによる実装、テスト、デプロイをサンプルコードとともに説明してくれます。 本の構成は3部構成です。一部ずつ詳しくみていきましょう。

第一部 Go言語とWebアプリの親和性

一部の前半では、Webアプリケーションとはなにか?HTTPとはなにか?の解説から始まります。Goの入門書なのにそこからなの…?と感じるかもしれません(私は感じました笑)。しかし、ここで「Webアプリケーション」とはなにかを定義したことによって、この後の部で作るものの全体像が明確になったと感じます。また、HTTPの説明も後の方で作ることになるRESTful APIの実装に役立ちました。

一部の後半では早速Goを用いた「掲示板アプリ」の開発にとりかかります。いきなりすごい量のサンプルコードにびっくりすると思います。初学者の場合、全部理解するのは難しいかもしれませんが、第二部以降で詳しい解説があるので、細かいことは気にせずに説明通りに動かしてみると面白いと思います。

第二部 Webアプリ開発の基本テクニック

ここからがGoの解説です。Webアプリ開発においてよく使われるnet/http、テンプレートエンジン、データベースなどの解説がなされます。第二部を読み終え時、第一部で見た「掲示板アプリ」のソースコードがほとんど理解できるようになっていることでしょう。

第三部 リアルな開発への準備

ここからよりGoの実践的な解説に入っていきます。Web上でよく使われているjsonの処理方法、開発プロセスで重要となるテスト/デプロイ、そしてGoの特徴の一つである並行処理をWebアプリケーションにどう活かすかといった解説がなされていています。

本の概要は以上です。

この本のよかった点

1.ゼロからGoでWebアプリを作れる

この本1冊でGo製の掲示板アプリ、REST API、モザイク処理アプリの開発ができます。解説を読んで写経をするだけでも、実践的な力が身につくと思います。私は今仕事でGoを使っているのですが、業務で役立つ知識をこの開発を通して得られました。

2.標準パッケージの基礎力が身につく

1と関連するのですが本書におけるWebアプリ開発では、基本的に標準パッケージを使っていきます。解説の仕方が、「まずは一回標準パッケージで実装してみてその後にサードパーティ製のパッケージで実装してみる」という手法なので、標準パッケージでどこまでできるか、サードパーティ製にはどういう利便性があるのかが明確に理解できました。標準パッケージを理解するの大事!

3.図の解説がわかりやすかった

本書では細かな実装視点の解説も充実しているのですが、マクロなアプリケーション全体の解説も充実しています。

f:id:kuwana-kb:20190306235508p:plain
サーバのリクエスト処理(サンプル)
↑は私の雑な図で申し訳ないのですが、こういったアプリケーション全体のデザインに関する解説が随所にあります。今自分がどの部分を作っていて、どこと関連性があるのかがわかりやすかったです。

いまいちだった点

本書の内容にはとても満足しています。が、唯一不満だった点があります。それは…文章が読みづらい、ということです。訳がいけないのか原文がいけないのかは分からないですが、説明が回りくどかったり、関数AとBの説明が逆だったり、サンプルコードが間違っていたり…ちょっと校正の品質に難があると言わざるをえないです。この点を除けば本当にいい本なのに…!

まとめ

前回書評を上げた「スターティングGo言語」では、Goの基礎力が養えました。 今回の「Goプログラミング実践入門」は、その次のステップに最適な本といえます。これまで得たGoの知識が、この本を読み終える頃にはWebアプリケーションという一つの形になっていると思います。(実際に「デプロイ」の章ではherokuやGCPを通じてweb上に公開することになるので、本当に形になります!)

「Goプログラミング実践入門」はGoでWebアプリを作ってみたい人、Goの入門を学習し終えた人におすすめの本です!

スターティングGo言語 書評

「スターティングGo言語」を読み終えたのでまとめます。

スターティングGo言語 (CodeZine BOOKS)

スターティングGo言語 (CodeZine BOOKS)

本のざっくりとした紹介

この本はGoの初学者を対象とした入門書です。構成としては開発環境の構築からはじまり、大部分は言語の基本やパッケージの解説がなされる形になっています。言語を通じてアプリケーションを作るといった実践的な内容というよりは、Goの仕様の解説書に近しいでしょう。

なぜ読んだか

理由は以下の2点です。

  • Goの仕様を体系的に理解したかったら
  • interfaceがよくわからなかったから

これまで私が得たGoの知識は、Tour of Go と UdemyのGo講座がメインでした。特にUdemyの酒井さんのGo講座はとても実践的で、プログラミング歴そのもの浅い私にとって最高の教材でした。ただ、この講座は実践寄りな分、Goの細かな仕様や各パッケージの使い方については軽く触れて終わってしまいます。

現役シリコンバレーエンジニアが教えるGo入門

Goの知識が浅い私は、開発が行き詰まった時はQiitaの記事等を見て都度解決していたのですが、どうしても対処療法的になってしまっていたことに頭を悩ませていました。 今回の「スターティングGo言語」は、基礎的な文法からGo特有のややこしい仕様に至るまで、体系的にGoの仕組みを学べそうと踏んで読むに至りました。

この本のよかった点

1.サンプルコードが豊富

サンプルコードが豊富です。説明を読んでよくわからない部分も、とりあえず動かしてみることで理解することができました。

2.よく使うパッケージや機能の解説が充実している

log, net/http, strconv, json といったwebアプリケーション開発で利用するパッケージの解説が充実しています。また、冒頭で説明した通り私はinterfaceがよくわかっていなかったのですが、本書の解説を通じて理解できるようになりました。interfaceの章の解説だけでなく、パッケージの章においても度々「このパッケージでは〜〜のinterfaceが使用されていて〜」といった形で多角的にinterfaceの説明がなされている点がとても良かったです。

3.筆者のGoに対する意見が面白い

こういった解説書は、言語の解説ばかりで退屈になりがちです。また、解説だけであれば公式ドキュメントで十分かもしれません。しかし、本書ではGoの設計思想やコードの書き方に関する筆者の意見が随所にあり、公式ドキュメントとは十分な差別化が図られていると感じました。

印象に残った内容

今までなぜ最後の要素にカンマをつけるのか謎だったのですが、本書にはしっかりとその点の解説がありました。「こうすれば動く」といった手順の説明だけでなく、「なぜ動くのか」という理由にまで言及されているのは納得感がありますよね。

注意すべき点

初めてプログラミング言語を学ぶ人にはつらいかもしれない

本書では、説明文として「Javaでいうと〜」といった表現が度々登場します。Goの特徴を従来の言語と比較して解説しているわけです。その意味で、Goがはじめて学習するプログラミング言語の場合、読み進めるのが苦痛に感じる方もいるかもしれません。
ちなみに解説の中でbitとオーバーフローの項目があったのですが、これが前回書評を書いた「プログラムはなぜ動くのか」で得た知識領域の話でして、読んでおいてよかったなと思いました。プログラムの基礎を知りたいという方は、こちらも合わせて読むのも良いと思いますよ。

まとめ

本書を読み終えて得られたことの1つは、標準パッケージに関する知識の深掘りができたということです。たくさんのサンプルコードを通じて動作を確認することで、使えるパッケージの幅が広がったと感じます。


そしてもう1つは、こうした標準パッケージの動作とソースコードの確認を通じて、インターフェース、構造体、メソッドの関連性への理解が深まったと感じます。例えば、「io.Readerを引数として受け取るbufio.Scanner()で、なぜ*os.File型を受け取ることができるのか」といった内容は、本書を読んでようやく理解できるようになりました。知識が深まりGoに関する視界が広がった分、Goを書くのがより一層楽しくなってきたと感じています。

スターティングGo言語は、Goで開発をするときに傍に置いておきたいと思えるような一冊です。 Goの学習をこれから進める方、Goの基礎を深めたい方にお薦めします。

プログラムはなぜ動くのか 書評

「プログラムはなぜ動くのか 第2版」を読み終えたのでまとめます。

プログラムはなぜ動くのか 第2版 知っておきたいプログラムの基礎知識

プログラムはなぜ動くのか 第2版 知っておきたいプログラムの基礎知識

本のざっくりとした紹介

この本はメモリ、OS、ハードウェアといった低レイヤーの観点から、 プログラムをクリックしてから実際に動作するまでの流れを詳しく解説した本です。
流れを追っていく中で、エンジニアにとって馴染みのある2進数やポインタ、コンパイルといった仕組みを、 低レイヤーの観点からわかりやすく解説してくれています。

なぜ読んだか

プログラミングを学んでいく上で避けて通れないものの1つに、「ポインタ」があります。 ポインタでググると「特定のメモリ領域を表現する」といった内容で、C言語を用いた例がよく見受けられます。
プログラミング初学者の私としては、C言語をそもそも知らないし、ハードウェアの構造もよくわかっていないので、 解説を読んでもしっくり来ることがありませんでした。 本書を通じてポインタの理解を深めることが第一の目的でした。

印象に残った内容

読んだ中で特に印象に残った内容を2つ挙げます。

1つめはポインタの型宣言について。

形式として覚えていた型宣言にもちゃんと理由があったことに驚き。

2つめは低レイヤーでの抽象化について。

プログラミングにおいても様々な手法で抽象化を試みますが、低レイヤーでも抽象化がなされていました。 この抽象化によって我々エンジニアはハードウェアやシステムコールを意識することなくプログラミングに集中できているのですね。

この本の良いところ

  • プログラマ(エンジニア)が読むという前提で書かれているので、必要以上にハードウェアに寄った専門的な単語がなく、読みやすい本でした。
  • 解説の中にC言語アセンブリ言語が登場しますが、言語の解説も入っているので問題なく理解できました。(※)
  • 2進数やポインタ、コンパイルといった仕組みを低レイヤーの動作を含めて理解を深めることができました。

本書を通じて当初の目的であったポインタの理解に加え、今まであやふやだった低レイヤーの知識を補完できました。 この日経ソフトウェアさんが出版する「なぜ」シリーズは今回で3冊目ですが、どれも安定してわかりやすいのでおすすめです。

ポインタがよくわからない…という方やプログラムの低レイヤーが気になる方はぜひ読んでみてください。

goroutineとsync.WaitGroup

goroutine と sync.WaitGroupを試してみた

goroutineは並列処理を実行するための機能で、実態はスレッド。 sync.WaitGroupはgoroutineの処理が完了するまでmainの処理を待つメソッド。

以下実際に試したサンプル

package main
 
import (
   "fmt"
   "sync"
   "time"
)
 
func normal(s string) {
   for i := 0; i < 5; i++ {
      time.Sleep(100 * time.Millisecond)
      fmt.Println(s)
   }
}
 
func goroutine(s string, wg *sync.WaitGroup) {
   //1つのwg.Add()につき、1つのwg.Done()を実行する必要がある
   defer wg.Done()
   for i := 0; i < 5; i++ {
      time.Sleep(100 * time.Millisecond)
      fmt.Println(s)
   }
}
 
func main() {
   /*
   //goによって、処理を並列実行することができる
   //goはmainの処理が完了する前に並列を開始しないといけないので、処理の前に置くこと
   //また、goroutineの処理が終わらなくとも、mainの処理が完了した時点で処理は終了する
   go goroutine("World")
   normal("Hello")
   */
 
   //goroutineの処理を実行するために、並列処理を待つための仕組みがある
   var wg sync.WaitGroup
   wg.Add(1)
   normal("hello")
   go goroutine("world", &wg)
   wg.Wait()
}