nazolabo

フリーランスのWebエンジニアが近況や思ったことを発信しています。

SSH先のdockerをローカルからシームレスに使用する(SSHでDOCKER_HOSTを指定する)

何がしたいの?

例えば「MacBook Air で開発しているけどスペックが低いので Docker で動かすものはデスクトップPCで動かしたい」というようなケースに使います。

docker をリモートで動かす

まずリモートの Docker を用意します。私は Windows なので Hyper-V で作りました。Docker のバージョンはリモートもローカルも最新が良いです。最低でも 18.09 以上が必要かと思われます。

対象の環境に SSH で入れるようにしておいて、SSH で入るユーザーが sudo なしで docker コマンドを叩ける必要があります。 sudo usermod -aG docker myuser のようにして SSH 対象ユーザーを docker グループに所属させましょう。

docker コマンド内で SSH 鍵のプロンプトは出せないので、事前に ssh-add しておきましょう。

ここまでで、設定が問題なければ以下の方法で起動すると思います。

docker -H ssh://user@remote-host run -d -P nginx

-H の部分は、環境変数 DOCKER_HOST で指定が可能です。

docker-compose 対応

Docker for Mac 標準の docker-compose ではうまく動かなかったので(多分 このあたりの都合 )、docker-compose は pip で入れました。pip で入れただけでも動かない場合は pip install cryptography==2.4.2 が必要かもしれません。

また、 docker-compose は .ssh/config を読んでくれないっぽいので(1.25.0 時点)、DOCKER_HOST はそれを考慮して書いてください。

ボリュームマウントは SSH 先のホストに対して行われます。マウント先は SSH 先のホストのディレクトリ構成に合わせて記述してください。ローカルと同期したい場合は別途自前で同期する必要があると思います。

※ 2020-06-04 追記 : docker-py 4.2.0 で .ssh/config を読むようになったようなので、それが取り込まれている docker-compose 1.26.0 では読み込むことができるのではないかと思います。(未検証)

ユースケース

ローカルとボリュームマウントが基本的にできないので、アプリケーションコードを Docker コンテナ内で実行するようなケースには向いていません。特殊な構成のアプリケーションで実行に Docker がどうしても必要という場合は、この方法は避けたほうが良いです。

ローカルで編集しないもの、DB やキャッシュサーバーのようなものだけ Docker で起動し、アプリケーションはローカルで起動する、といったケースにはすぐに使用できると思います。この場合も設定ファイルを送り込むことができないので、設定ファイルが必要なもの(Elasticsearch など)は設定ファイルを入れるための Dockerfile を書いて、それ経由で起動するのが良いかと思われます。

現代の一般的な構成の Web アプリケーションでは、Docker でアプリケーションそのものを実行するメリットはあまりないので、この構成は十分実用的かと思われます。

そもそもSSH先で開発すればいいのでは?VSCodeのRemote-SSHもあるし…

あっはい…

一応ローカルに開発中のファイルを置いておけるので、外出先で開発したくなった場合にそれをそのまま使えるというメリットはありますが、まあ適当に作業中ブランチをpush/pullすればいいだけですね…

2019年トップツイート振り返り

Twitter Analyticsから各月のトップツイートについて振り返ってみます。

1月

ありません

2月

今でもこういう感想だし、下手に並列化するより直列でそのまま流したほうが(個別のジョブの時間が長すぎる場合以外は)速いという認識なのですが、皆様どうしてるのでしょうか。

3月

EntityやらValueObjectとかってのはDDDの表現手法の一つであって、本質としてDDDが目指してるものってそこじゃないでしょ?みたいな話でした。

4月

自分もそれなりにTerraform書いている量では多い自信があるのですが、こうやって具体例がまとめられている書籍は今までなかったのでとても良い内容でした。

現在はさらに内容を充実させた 実践Terraform AWSにおけるシステム設計とベストプラクティス が出ているようなので、そちらを読むのが良いのではないかと思われます。(私はまだ買ってないです…)

実践Terraform AWSにおけるシステム設計とベストプラクティス (技術の泉シリーズ(NextPublishing))

実践Terraform AWSにおけるシステム設計とベストプラクティス (技術の泉シリーズ(NextPublishing))

5月

通信レイヤーを使ってサービスを分離するのは規模が大きくないと難しいですが、モノリシックなプロダクトでも内部構造は分離できる構造になっていると変更に強いしテストも書きやすいしという話です。マイクロサービスが目指したいものが何なのかを考えて導入しましょう。

6月

リモートワーク論についてはいろいろあるのですが、自然にリモートワークをするにはオフィスを提供しても提供しなくても何も変わらないというような環境がベストではないかと思います。そのためにはオンラインにリソースを集中させる必要がありますし、顔を合わせないとできないことを最小限にする必要もあります。

7月

Terraform人気ですね。ACMDNS検証周りは内部でオーダーが勝手に変わるらしく突然差分が発生するというやつです。最近は諦めてここだけ手動でやっています。管理するメリットないし…。

8月

2019後半は本当に何もしていないので、2019年のアウトプットのほとんどはここに凝縮されています。12月の登壇内容と併せてご覧いただければと思います。

9月

リモートワーク大好きマンです。身も蓋もない話なのですが、できる人はできるしできない人はできないみたいな結論に行き着きます。そして多くの人はどちらかといえば「できない」ほうです。主語が大きいですが根拠はあるのでどこかで書けたらと思います。

10月

大きめの企業で「誰々さんを新たな役員に任命!」みたいなのって、大きく会社の方向性を変えたいという意思でもあると思うので、当然決断するのは大変だし、失敗することも多いと思うし、それでも決断するのはすごいなーという話です。私には無縁の内容ですが…。

なお、このツイートの次はこんな内容です。

11月

元ネタがあります

12月

これについては年が明けたら詳しく書きます。それではよいお年を。

OKRでありがちな間違い2点

ドキュメント(OKRはGoogleのものではありませんが…)ちゃんと読もうシリーズ第二弾です。(第三弾は多分ないです)

Google re:Workに書いてある内容のうち、間違った運用をされてそうな2点をピックアップしてみました。

一部に独自の解釈が含まれていますので、詳細は上記リンクなどを参照してください。またre:Workに書いてある内容ベースなので、OKRの正しい解釈としてはもう少し違う可能性があります。

1. 「OKR は、従業員を評価するためのツールではありません。」

評価するためのツールではないということは、OKRで評価しちゃ駄目なの?

普通に解釈したらそうなるのではないでしょうか。

なんで駄目なの?

OKRは、達成率が60%~70%が理想的とされています。簡単には達成できないような目標を設定して大きな成果を上げるのが目的だからです。しかしそれを個人の評価にしてしまうと、達成できなかった場合にマイナスにしてしまう可能性があります。達成できるかできないか微妙な目標で達成できなくてマイナスというのは理不尽なのではないでしょうか。

また、OKRでは、目標を達成できなくてもその過程で個人は大きな進化をするだろうとしています。「大きな目標に対して努力をする」ということが既に成果になっていて、それは評価されるべき内容となっているので、OKRの達成と個人の評価は関係がないということがわかります。

2. 「OKR は、社内共有のタスク管理ツールではありません。」

タスク管理ツールじゃないの?

そもそもOもKRもタスクではないのでタスク管理ツールではありません。

OにもKRにもタスクを入れないなら、OとKRの違いって何なの?

Oには数値ではない(定性的な)大きな目標を入れ、KRにはOを達成するための具体的な(定量的な)数値指標を入れる、とされています。

Oには会社規模であれば「世界一の〇〇を作る」みたいな感じの、とにかくすごそうな内容を入れておくのが良いでしょう。チームであればもう少しフォーカスを絞って「UIを改善する」とか「利益率を上げる」とかでもいいでしょう。

KRは、Oを達成するための具体的な数値を指定します。OKRの達成はKRの数値を0.0~1.0の範囲で評価できる状態にするというのがありますので、数値で評価できないものはKRにはなりません。

そうはいってもKRに具体的な話を書きたいんだけど…

「なお、OKR はチェックリストではありません。」ともあります。詳細はそこを読んでいただきたいのですが、あくまで「チームをどうしたか」を決める指針であり、具体的な内容を並べる場所ではありません。

まとめ

  • OKRで評価するのはやめましょう。
  • Oには大きな到達点、KRにはタスクではなく結果から見える数値指標を採用しましょう。
  • OKRのフォーマットが合わない場合はそこから外れても別にいいとは思いますが、その場合はOKRとは名乗らず「我々の手法」として利用しましょう。組織に合わせた適切なフォーマットを使用するのが一番です。

TerraformのWorkspaceはstaging/productionの切り替えに使うべきではない

Workspaceって何だっけ?

簡単に言うと「同一のtfファイル群を別のtfstateとして扱う、それを切り替える」機能です。

なんでだめなの?

公式がそう言っているからです。

In particular, organizations commonly want to create a strong separation between multiple deployments of the same infrastructure serving different development stages (e.g. staging vs. production) or different internal teams. In this case, the backend used for each deployment often belongs to that deployment, with different credentials and access controls. Named workspaces are not a suitable isolation mechanism for this scenario. State: Workspaces - Terraform by HashiCorp

どういうこと?

公式の言い分としては、「全く同じ環境のコピーを作るならいいけど、そうじゃない場合(staging/productionのような)は資格情報とか認証情報とか合わないから使えないよ」ということです。これは例えばstagingとproductionで別のAWSアカウントを使用している場合に該当すると思います。この場合は向いていないのが直感的に理解できるかと思います。

また、公式では「その場合は再利用可能なモジュールを使うべき」としています。つまり、部分的にモジュール化したものを組み合わせて別の構成として取り扱うべきとしています。これであればどのような構成でも部分的にモジュールを組み合わせて使う形になるので、自由な構成を組むことが可能です。

現実では小さい環境であれば片方の環境からコピペして必要なところだけ書き換えて新しい環境を作る、という感じでも最初のうちは困らないことが多いと思いますが、環境が増えそうであれば早めにモジュール化していくのが良いでしょう。

公式が言ってたらダメなの?使えるから使っても良くない?

以下は私の独自見解になります。

大前提として「stagingとproductionのtfstateは分けるべき」と考えています。これはapply時の影響範囲を狭めることができるためです。

その上で、私としては「そんなにstagingとproductionって同一環境ではないのでは?」というような理由で、Workspaceをその用途に使うべきではないのではと思っております。

The Twelve-Factor Appでは、外部環境は本番環境と開発環境のギャップがないようにすべきとされています。これは「開発環境ではローカルメモリに保存するけど本番はMemcached」のような、プロトコルレベルで違うようなものを使うと、それによるアダプターの実装の差異による思わぬ事故が発生する可能性があるためです。

一方で、外部リソースはアタッチされたリソースとして扱うというのもあり、そこでは「リソースを簡単に切り替えることができるようにしておく」とされています。

つまり、「アプリケーションレベルでは常に同一の対象に対してアクセスしているように振る舞うが、その先の通信対象が何なのかはアプリケーションが関与しない」ということです。これは問題が発生したときに責任がどちらにあるのか明確になり、性能限界などでの差し替え時にも容易に差し替えることができるためスケールしやすいアプリケーションになります。

これを踏まえた上で、一般的によくあるケースとして「本番ではメールを送信したいがstagingではメールを送りたくない」といったケースがあります。この場合、本番では普通のメールサーバーを構築します(外部のサービスを使うかもしれません)が、stagingでは「送信したメールを全て吸収してWeb上で表示してくれるサービスに送る」というようなことをすることがあります。具体的にはMailHogMailtrap.ioといったようなものです。私は前者を使うことが多いので、前者用のインスタンスをstagingのみで組み込んでおくということをします。

同様に、AWSでは「stagingではシンプルなRDSを使うが、本番ではAuroraクラスタを組む」というようなケースもよくあります。これも大幅に設定が変わる内容になります。Auroraクラスタまでいかなくても、DBのパラメーターを細かく変えることはあると思いますので、それをWorkspaceでどうにかするのはなかなか大変ではないかと思います。

上記の観点から、そもそもWorkspaceでstaging/productionのような「似てるようで用途が違うもの」の切り替えには向いていないのではないかと思います。が、これらを理解した上で「それでもWorkspaceで切り替えるのがベストだ!」となるのであれば、それでもいいかもしれません。

それじゃWorkspaceって何のためにあるの?

公式では以下のようになっています。

A common use for multiple workspaces is to create a parallel, distinct copy of a set of infrastructure in order to test a set of changes before modifying the main production infrastructure. For example, a developer working on a complex set of infrastructure changes might create a new temporary workspace in order to freely experiment with changes without affecting the default workspace. State: Workspaces - Terraform by HashiCorp

簡単に言うと、「インフラの変更のテスト用にもう1つ作っておいてそこで試すため」とあります。Terraformは実際にapplyする時の挙動は当然apply先のクラウドサービスに依存していますので、applyするまでどうなるかわからないということは多々あります。そのような場合を試すのにはベストなケースだと思います。

同様に、「本番環境と全く同じものを作って、そこでないと発生しないようなバグのテストをする」というようなケースにも良いのではないかと思います。

どちらにしても、「Workspaceを切り替えて複数環境を作れるようにする(しておく)」というのは設計上欠かせない要素になります。必要な設定を切り出しておいて、いつでもWorkspaceで切り替えれる状態を作っておくようにしましょう。

まとめ

  • 公式がそう言っているのでなるべく従いましょう。
  • stagingとproductionってそこまで同一環境ではないので、公式が言ってなくても向いていないのではないかと思います。
  • Workspace機能自体は常に使える準備をしておきましょう。

UUUM System Meetupで登壇させて頂きました #sysuuum

uuum.connpass.com

スライド

これは何か?

あまり良いとは言えない状態のプロダクトを良い状態まで改善していった時に気にした点について紹介しています。

個別の技術については世にいくらでも情報があるので今回は省略しましたが、どこかのタイミングで個別に取り上げていくかもしれません。

ビジネスとの判断

会社というのはお金を生み出さないと継続できないものなので、ビジネスを止めないで改善していくことが望ましいです。

一方で、ある程度止めないといけない場合も存在しますが、それでもビジネスを止める期間を最小限にするというのがエンジニアに要求されていると思っております。

「エンジニアが快適に作業するため」ではエンジニアの自己満足になってしまいますので、それがどうビジネスに繋がるのかをちゃんと説明する義務があると考えております。もちろん多くの場合は間接的に繋がるのですが、内容によっては今やるべきではないというようなこともあると思います。

先にやるか、後にやるか

ビジネスを止めずに〜とは言ったものの、ある程度は先に行う必要があります。

一番は「データベースなどのストレージが止まる可能性があるもの」で、これはデータ量が大きくなればなるほど停止しての作業が困難になります。ここに該当する作業は真っ先に行ったほうが良いです。必然的にインフラ要因のものは最速で問題がないかチェックすべきでしょう。

具体的にやる項目

今回は「私が行うなら〜」という観点でいくつか紹介しました。ここに書いていない項目もありますし、そもそも私も完璧ではないので抜けているような内容があるかもしれません。そのあたりは柔軟に対応していくのが良いかと思います。

とはいえ、ほとんどが基本的なことだと思いますし、また形式的にやるだけではなく継続的に意味のある改善していないような環境では、現代において他の優秀なサービスの成長に勝てることもないと思います。

今回話さなかったこと

質疑応答であったのですが、あくまで第一段階として行う話として話しました。もちろんここから設計方針とか深い話まで行けるといいですが、最初にやることとしてはこのあたりから考えるのがいいのではないかなと思います。

まとめ

スライドの最後にも書きましたが、そもそも最初にやっておけば苦労しない話なので、最初から高いレベルで環境整備を行いましょう。特にlintレベルは後から上げるのは本当に大変です…。

UUUMの皆様、退職した身にも関わらず、このような機会を用意していただきありがとうございます。

UUUMではエンジニアも募集していますので、興味がある方は応募してみると良いかと思います。ここで話したような内容はちゃんと実践されている環境です。他の方の紹介でもありましたが、労働環境としても常識的な労働時間でリモートワークも可能ですので、非常に働きやすいのではないかと思います。

職業Webエンジニアにおける「実績」と「やりきる力」

※私はWeb系のエンジニアです。以下「エンジニア」というのは「Web系のプログラマー」と読み替えて頂くのが適切な場合があります。

経歴の浅い人にキャリアについて相談された時に「まず目の前のプロジェクトをちゃんとやりきったほうがいいよ」と言うようにしています。

エンジニアにおける「やりきった状態」とは

Web系プロジェクトというのはリリースしたら終わりではなく、運用に乗ってある程度安定した状態になって初めて「十分な品質で世に送ることができた」と言えます。

運用に乗せてみると「負荷に耐えられない」「必要な機能を満たしていない」といった問題が現れることがよくあります。たいていの場合はそのまま運用を継続することはできませんので改修することになります。こうしてリリース時の機能が安定して運用できるようになった状態で「やりきった」と言えるのではないかと思います。

ただし、初期の想定を大幅に超えるデータ量やアクセス数により限界になった、というようなケースはここでは別の話になると思います。あくまで「初期の想定通りのものがリリースできているか」という点になります。

やりきっていない成果とは

やりきった状態に達していない場合、極端な話「何も手を付けていない」と「完成していたが世に出なかっただけ」の違いはわかりません。また、「完成していたが世に出なかっただけ」だとしても、それが本当に「十分な品質だったか」を判断することは本人にも不可能です。

極端な例だと、明らかに大して関わっていない巨大有名プロジェクトに短期間いただけで「あれは私が作った」というケースもありますが、さすがにそこまでいかなくても、実際まともに機能するものではなかったとか、その人が退職した後にすべて作り直されたというようなケースは多々存在します。

見えていない作業

やりきっていない成果には、「見えていない作業」が抜けている場合があります。

例えば「レビューの指摘に対応する」「周辺環境を成果に合わせて変更する」「想定以上のデータがあった場合の負荷に対応する」「実際の利用率を高い状態にする」「テストを書いて品質が高い状態でリリースする」というようなものです。

現代は雑なコードを書いてとりあえず動いていれば良いという時代ではなく、継続性の高いコードを書くことが要求されます。たとえ瞬間的なリリース直後の状態で問題なくても、その後誰も手がつけられないようなコードを書いてしまっている場合は「やりきっていない」と言って良いのではないかと思います。「リリース時の想定で動いているじゃん」と言いたいところですが、リリース時に「その後継続して機能改修する」というのを想定していない人は誰もいないのではないかと思います。

プロジェクトから逃げない

例えば巨大なプロジェクトだったり炎上しているようなものだと、つい逃げたくなりがちです。

ビジネスというのは(最終的に)お金を生むためのもので、そのためにプロダクトというのは完成してからがスタートで、それが利用されなくてはいけません。

利用される段階にまで達しなかったプロダクトというのはビジネス的には価値がないものとなります。エンジニアとして何かを得た可能性はあっても、それを途中で投げ出すというのは会社から見ると何の意味もありません。

エンジニア界隈で何らかの評価を得られるかもしれませんが、会社から評価を得られるのは「ビジネスになるプロダクトを作り上げた人」です。さらにそれを連続して達成すると、「この人なら安心して任せられる」という評価に繋がり、次の大きなポジションへと繋がります。

技術力?

この相談を受けた時に、「技術力を上げたい」という相談がセットでついてくることが多いです。漠然と「今後どうしたらいいのかわからない」という不安から来るようです。

現実的な業務におけるエンジニアの作業内容は「要件をまとめて、それを適切に実装する」ということです。もちろん場合によっては技術的に難易度が高いものも登場しますが、ほとんどの日常業務で登場することは稀です。

技術的に難易度が高いものを学ぶのが不要だというわけではなく、多くの会社でビジネスとしての比重が高いのは「日常的に比率の高い作業を確実にこなせる人材」です。まずはそれをできるようになってからでいいのではないでしょうか。

まとめ

自分のキャリアもちゃんとしていないのに他人のキャリアの相談を受ける身分なのだろうかという疑問はありつつも、最近こういうことについて何度か話したので考えをまとめてみました。

なんだかんだで「やりきることが困難な状態」というのは、周りのサポートが良くない場合というのが一番多いと思いますので、チームが一丸となって問題解決に取り組める環境だと良いのではないかと思います。チームビルディング大事。

主観が強い内容ですが、「やりきる」重要性というのはエンジニアとか関係なく大事なのかなーと思います。創作界隈でも「下手でもいいから世に出す」みたいなのはよく言われてる内容なので、結局そういうことなのかなと思います。

退職しました

  • from: UUUM株式会社(2015.06-2019.10)
  • to: まだないしょ

在籍期間中に会社の技術ブログに書いた記事は以下になります。