Japan Container Days v18.12 参加レポート

# まとめ

- Japan Container Daysと銘打っているがほぼほぼKubernetesの話題
- オーケストレーションツールのデファクトはKubernetesとなった
- Kubernetesを使用する大きなメリットは主に以下
    - ポータビリティ
    - 拡張性
    - エコシステム
- 利用形態として大きく分けて2パターン
    - アプリケーション(自社サービス)の実行基盤として
    - 自社エンジニアの開発基盤として
        - 利用者にコンテナを意識させるかは企業に依るようだ(kubectlを使用させるか、等)
        - 開発基盤としてはやはりCI/CDの話が多い
            - GitLab・Jenkins等と組み合わせたGitOpsを実現している事例は多い
- クラウドサービスとの親和性も高い
    - 次回のカンファレンスは「Cloud Native Day」として開催
    - 多くのセッションがAWS/GCPなどのクラウドサービスでの事例
    - アプリケーションのコンテナ化として特徴的なものにマイクロサービスがあるが、これはAWS等クラウドサービス上でのアプリケーション実行も同様
    - VM上で直接アプリケーションを動かすこととの大きな違いは、コンテナ(K8s)では同じマニフェストファイルを使うことでプラットフォームに関係なく同じ環境で動作させることができること(ポータビリティ)、余剰リソースのあるノードを効率的に使用できる、等
- Docker単体の話についても多少あり
    - セキュリティ
    - Dockerfileの書き方
    - ツール類
        - sternについては[sternを使ったpodのログ出力](https://qiita.com/zaki-lknr/items/189bae27d2f5320cdfd2)にまとめた

# スライドまとめ

こちら→ [Japan Container Days v18.12 スライドまとめ](https://qiita.com/zaki-lknr/items/2e4d17f0b0e595139862)

# 受講メモ

## [K1] 基調講演

### Evolving Cloud Native Landscape

コンテナ戦争はおわってk8sが他をしのいでデフォルトのオーケストレータになった。

---

Cloud Native Landscape
いろんなセッションで出てくる図はこちら: https://github.com/cncf/landscape

---

KubeEdge: Kubernetes + Edge Nodes
https://github.com/kubeedge/kubeedge

---

Serverless + Nodeless

Nodeless k8s: Kubernetes + Virtual Kubelet(キューブレット)

https://github.com/virtual-kubelet/virtual-kubelet

---

来年はK8sのイベントをTokyoで！

### Microservices on k8s at Mercari

https://speakerdeck.com/tcnksm/microservices-platform-on-kubernetes-at-mercari

<script async class="speakerdeck-embed" data-id="5ce5dcf2ea464d0d97b41ecbc6841273" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>

- なぜコンテナ
    - 安全なリリースによる高速化
        - Immutable Infrastructure
            - 一度デプロイしたサーバには手をくわえない。変更したさいは作り直す
        - カナリアリリース
    - VMに対して…
        - 起動が高速
        - ポータビリティ (ローカル→本番とか)
        - Better utilization: 小さなサービスをたくさんリリースする。VMだと余剰リソースがつらい。コンテナだとやりやすい。

-  なぜk8s
    - 拡張性
    - エコシステム

- k8sでやってくれること
    - RSでレプリカ
    - LB by service
- やってくれないこと
    - ソースのビルド(ソースのビルドしてyaml書いたりは利用者)
    - アプリケーションレベルのサービス (提供するのは連携する仕組みのみ)
    - モニタリングやアラームなど (監視系)
    - 設定関連 (yamlくらい)

- k8s extension
    - Custom controller
    - Custom Resource Definition
    - Admission webhook
    - これらを使うことで、メルカリサービスに特化した抽象レイヤーができる


- k8sのエコシステム

    - k8sのシステムレイヤー
    - 自分たちにあったプロダクトを組み合わせて自分たちにあった中小レイヤを作成できる。(クリスが出したマップ)
    - このような拡張性の高さとエコシステム、この辺が選定理由。

-  エコシステムで解決できない問題
    -  自分たちでがんばる。(がんばれる)

- Certificate Expiry Monitor 
    - Lets Encrypt使ってるけど期限がきれたら。。。
    - mercari/certificate-expiry-monitor-controller こんなの作って自動化した


### Kubernetesによる機械学習基盤への挑戦（Preferred Networks）

<iframe src="//www.slideshare.net/slideshow/embed_code/key/HOaF4FFWFsbiKK" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/pfi/kubernetes-125013757" title="Kubernetesによる機械学習基盤への挑戦" target="_blank">Kubernetesによる機械学習基盤への挑戦</a> </strong> from <strong><a href="https://www.slideshare.net/pfi" target="_blank">Preferred Networks</a></strong> </div>

-  なぜk8s
    - セキュリティ・プライバシー機能
    - スケジューリング
    - 柔軟・容易な拡張
    - エコシステム

PFNの機械学習基盤の要件をカバー。
やはりメルカリさんと同じような感じ。

- 多種多様な実験環境

    - HARBOR (プライベートDockerレジストリ)
    - Node SelectorでCPU/GPUを選択

小規模データはNFS
大規模はHadoop

- マルチテナント
    - ユーザ・プロジェクトごとの環境
    - Prometheusで統計とってる
    - 自由度の担保
        - kubectl exec(実行中podに入ってデバッグも)許容する
- 機械学習としてのトレンド
    - Kubeflow

###  LINEエンジニアを支えるCaaS基盤の今とこれから

https://www.slideshare.net/linecorp/line-engineer-caas

- プライベートクラウド開発
- CaaS基盤

社内の開発基盤に Iaas + Managed Middleware + CaaS

- PaaS
    - Herokuのようなk8sベースのPlatform as a Service
    - ユーザはk8sを意識しない。
- PaaSの限界・・・
    - 複数のコンテナで構成されるシステムの基盤としてはつかいづらい
    - アプリが依存する複数のミドルウェアのデプロイ先
    - 野良k8sが乱立(Private Cloudユーザが管理している)

- 野良k8sの課題
    - 品質
        - 監視されないクラスタ
        - HA考慮なし
        - アップグレードされない
    - 運用コスト
        - デプロイ
        - 障害対応

うまくいってるところもあるけど、ナレッジが分散化してしまう。 →  マネージドなk8sが必要

- KaaS
    - k8sクラスタ(privateクラウド連携・障害綱領・パフォーマンス)
    - 使う人・運用するソフトウェア

これらが重要

- どのようにk8sを実現？
    - Rancher 2.xベース
        - すべての機能を使ってるわけでないので、Rancherを直接使わせていない。
        - Rancherをk8sの管理に特化している。
- できていること。。
    - 100クラスタ・2000ノード以上のサポートし、プロダクションサポート

- FaaS
    - Event駆動！
    - これで任意のプログラムを動かせるのがいい！
    - 運用ツールの半分以上はビジネスロジックでない。
    - LINEではKnativeで実現。

### Cloud Nativeの未来とIBMの取組み

https://www.slideshare.net/capsmalt/jkdv1812keynoteibmcapsmalt

- Cloud Native
    - スピードと柔軟性(スケーリング・メンテナンス)
    - 今までは絶対止めないシステム
    - ↓
    - 絶対止めないビジネス(復元力！)

- Watson on k8s
    - k8sでうごかすようになって、世界のどこでも動かせるようになった。(ポータビリティ)

### ZOZOTOWNシステムリプレイスにおけるKubernetes活用

https://speakerdeck.com/tsurumi/zozotown-replace-kubernetes

- 経緯
    - 長年の運用でレガシー化。さらなる成長のためモダンなものに切り替えたい
    - リプレースはまだ未完了。ごくわずか。段階的にやってる。

- 目的
    - 柔軟で堅牢なシステムを作る

- 行ったこと
    - パブリッククラウドへ。
    - 手作業部分の自動化

- なぜk8s
    - とっつきやすかった
    - デファクトスタンダード
    - マネージドサービスで提供されてた
        - azure
        - gcp
        - aws

zozoではazure使用 (zozoのオンプレ環境と親和性が高かった(オンプレに近い環境に移行しやすかった)

- ACS/AKS/ACS Engine
    - ACS EngineはACS/AKSと同等の環境を構築できるOSS
    - ACS Engineをzozoで使用

※初めての人はAKSがおすすめ

- スケール
    - Azure仮想マシンスケールセット
    - k8sが動いてる仮想マシンをスケールさせることができるらしい

k8sクラスタを分散・・・東日本と西日本でクラスタ分離

## [1CL] IBM Kubernetes の全貌と始め方

https://speakerdeck.com/takara9/ibm-kubernetesfalsequan-mao-toshi-mefang

- IBMのK8s製品とサービス
    - ICP: IBM Cloud Private
    - IKS: IBM Cloud Kubernetes Service

IKS中心に発表。アカウント無料発行中！

- IBM Cloud グローバルネットワーク
    - 世界42DC中31DCでK8sサービス使用可能
    - そのうち18DC(Tokyo含む)でマルチゾーン構築可能(複数のゾーンのノードを配置するクラスが作れる)

- IaaS
    - k8sのマネージドサービス
        - Grafana
        - Kibana
    - ダッシュボードからメトリクスとか監視画面
    - バージョンアップは1nodeずつ

## [1E1] Kubernetes がもたらす分散システムの脅威との戦い

https://speakerdeck.com/koudaiii/v18-dot-12-number-containerdaysjp

- 分散システムの技術的な課題について
- Wantedlyではステージングごとにクラスタを作成
    - マニフェストファイルはyaml形式なのでポーティングが簡単なので
- kubectl 使いにくい(特にデベロッパにとって)
    - コマンド多すぎ
    - wrapper作った
- 認証・認可
    - RBAC(あーるばっく)とGitHubのTeamsを使った認可
- 分散システムの非同期処理
    - podのterminateとserviceの切り離しが非同期
        - posが停止しているのにリクエストがくる場合がある
        - pre stopにsleepを入れて切り離しのバッファを持たせる

## [1C3] - (1/2) 初心者がk8sでWPを運用するまでの学習事例

https://speakerdeck.com/yasuhiro1711/chu-xin-zhe-gak8sdewpwoyun-yong-surumadefalsexue-xi-shi-li

- 学習の仕方
    - おうちk8sでクラスター学習
        - マネージドサービスではいろいろ隠蔽されていて理解が深まらない場合がある
    - 公式トレーニング
        - GCP: [チュートリアル  |  Kubernetes Engine  |  Google Cloud](https://cloud.google.com/kubernetes-engine/docs/tutorials?hl=ja)
        - AWS: [Amazon EKS とは - Amazon EKS](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/what-is-eks.html)
    - 書籍
        - 黄色本: [コンテナ・ベース・オーケストレーション Docker/Kubernetesで作るクラウド時代のシステム基盤](https://www.amazon.co.jp/dp/B079Q6S12G)
        - オライリー: [入門 Kubernetes](https://www.amazon.co.jp/dp/4873118409/)

- ググるとヒットするのはほぼ構築法。運用の情報がない。
    - 構築して終わりにならないように。
- 課題
    - モノリシックなアプリをどこまでマイクロサービス化するか

## [1C3] - (2/2) 高レイテンシwebサーバのGKE構築とbeta機能アレコレのハナシ

https://www.slideshare.net/junpayment/webgke-beta

- CPUリソースの効率化について
    - なぜ7cpuにしたか
    - request resourceを7cpu、Perl側プロセスもワーカー数を7に設定
    - n1-standard-8の8cpuで動作させると、1pod/1nodeで動作し1cpuがkube-system配下のpod枠となる
    - (よくわからなかった)

## [1C5] - (1/4) Docker ComposeとSwarmオーケストレーション概要

https://www.slideshare.net/zembutsu/1-c5-docker-compose-orchestration

- Compose: network/volume、あまりドキュメントがない
- Docker Compose: Composeファイル(yaml)をベースにオーケストレーション

- Docker Swarm vs Docker Swarm Mode
    - 名前似てるけど別モノなので注意

- 雑にオーケストレーションしたい場合はswarmおすすめ

## [1C5] - (2/4) オンプレだってここまでできる Kubernetes で作る自前PaaS

https://speakerdeck.com/yuhara/managed-kubernetes-on-premises

- Kubernetes Client Python (SDK)を使ったツールの作成
- クラスター外にGitLabを構築
    - Gitリポジトリ・コンテナレジストリを使用
    - GitLabにcommit/pushすることでPipeline実行
    - ステージごとにtag指定することで、develop/staging/productionと使い分け
- k8sのコマンドラインツールは使わずにGit操作のみで完結させる
    - push/commitで回す(コンテナを意識させない)
- Gitの内容が真とする考え方
- GitOps

## [2WA] 2020年のコンテナはこうなる！？コンテナプラットフォームのこれまでとこれから

- コンテナ、普及してる？
    - Yes:3 / No:2
    - Yes意見
        - 知ってる/取り組み始めた/使ってみたくらいの人は多そう
        - 「これからDocker使ってみたい」くらいの人はもうあまり聞かなくなった
        - 来場者アンケートは9割使ってる (そりゃそうだ笑)
        - 本番環境で使ってる人はまだそうでもないかも
    - No意見
        - まだ話が通じない人がそこそこ
        - コンテナ＝仮想マシンと思ってる人
        - コンテナに入ってsshしてる
        - コンテナの概念が通じない
- コンテナらしく使うとは？
    - クラウドネイティブ
    - コンテナを使うからこそできること、そのメリットをどう生かせるか
    - Mesos/Rancherとか
- 重要なのはマイクロサービス
    - マイクロサービスらしいものにはどうすればいいのか、という情報があまりない感じ
    - マイクロサービスっぽく作るには、組織もマイクロサービスに合わせて変わる必要がある
        - チーム間コミュニケーション
    - システムを組織にあわせるという日本式のやり方は、実はマイクロサービスと相性はいまいち
    - 「組織を変えないとマイクロサービスにたどり着かない」
- 本番環境でのハードル
    - コンテナネイティブアプリケーション、やっぱり難しい
    - その辺はユーザに浸透しない
    - 動きの軽快なweb系ならともかく、エンタープライズ側はまだまだハードルが高い
    - エンタープライズだと本番環境で必要なもの
        - マインドセット
        - カルチャー
        - ヒストリー
    - これらがそろわないと進まない。彼らは慎重すぎる！
    - １年くらい準備・試用して、じゃあやろう、みたいな感じ
        - それじゃ遅すぎる
    - ただ、今はいいチャンスだと思う
    - そこまでの意思決定をできる人も少ない
    - 技術以外のハードル
    - コンテナでしきれないもの
        - DBとか
    - そういうの解決しないと。よりステートレスなものにしていく必要がある
    - 使ってる人はマネージドサービス使ってるのではないか。そうであれば敷居は低い
    - ログ・メトリクス、どう動かすか
    - DBはVMでやるか。じゃあ結局ぜんぶVMでよくね？みたいになりそう
    - ステートフルなものをどうするか
    - 試すのは簡単。
    - amazonのマネージドで動かして、うん、うごくね、まではいける
    - でも、運用が、、、

- ぜんぶk8s一本勝ちになってるけど、それぞれのプロダクトってどうなる？(差別化)
    - 草野さん
        - 全体的に差別化は３つ
            - k8sをリーディングする(OpenShiftとか)
            - k8s運用を助ける (コンサル？)
            - k8sのカスタム・独自リソースを乗せる
        - というパターンが多い
        - Cloud Foundryは真ん中 ウォッシュ？
        - 昨日の脆弱性、その日のうちにアップデートできる？
        - そういうのを助けると差別化になるよね

    - 吉瀬さん
        - k8s最強だと思ってる
            - 拡張性
            - カスタマイズ
        - k8sってもうOSだよね
        - 「あなたが思ってるk8sってどのk8sです？」
        - コンテナを動かすとk8sを動かすはイコールじゃない
        - (そもそもk8sを使う必要がない場合ある)

    - 木村さん
        - これから動かすには容易性(開発・運用)
        - ベンダーロックを避けるハイブリッド対応
        - DBはk8sで動かないというのは安全
        - OpenShiftはpostgresとか普通に動かせます
        - それVMと何がちがうの？と言われても実はそんなにちがいない
        - DBってスケールできるの？そういうのをサポートするツールが発達するかも
        - vmよりk8sの方がクリーン

    - 千葉さん
        - エコシステム
        - 運用を見据えてログやメトリクスをどうするか、というのは重要
        - アラートの種類
        - GitLabとの連携とか
        - Rancherからはコードの管理はGitLab, pipelineで連携させる
        - オールインワンよりエコシステムで幸せになりたい

    - 五十嵐さん
        - 私はk8s の一本勝ちでいいとおもう
        - このままk8sの1っ本勝ちになるはず
        - 拡張性の高さはk8sにもうかなわない、流れは止まらない
        - 生のk8sを使っている
        - これ、デプロイとそのアップデートが大変
        - k8sのカスタマイズ機能で自動化してる
        - やっぱk8sは難しいよね、学習コストは高い
        - インフラエンジニアはいいけど、デベロッパに学習コストを割くか？それは難しい
        - これを解決できればよさそう
        - フレームワークはあったほうがいい

- 今後知っておくべき技術

    - 五十嵐さん
        - ストレージとサービスメッシュ
        - meshはIstio
        - これから成熟期になってくはず

    - 千葉さん
        - Istio、サービスメッシュは予想よりリリースがはやい。
        - 来週のkubeconみたいなイベント、コミュニティでどれだけ早くキャッチアップできるか
        - ↑ must
        - 一押し: knative、rancher(でぃお？りお？)、やべぇ、聞き取れない

    - 木村さん
        - mesh以外では、CoreOSのテクノロジー
        - OpenShiftでは次verい向けてCoreOSのべくとにっく？
        - VMを作ってCoreOSのイメジを指定すれば全部セットアップされる
        - master/nodeeもワンクリックでupdateできるよてい、運用を容易にする
        - こういうのをk8sにもたらす
        - k8s

    - 吉瀬さん
        - やっぱりサービスメッシュ

    - 草野さん
        - NoOpsかな (※ 最後にこの場所でセッションする予定。あ僕のとなりにいた…)
        - Cloud Native ビルドパック？
        - KNative (k8sを抽象化して楽にするもの)

## [2EL] コードを書くことに集中したい全てのアプリ開発者に贈るKubernetesの話

- https://twitter.com/SIOScorporation/status/1070834400047247360
- https://speakerdeck.com/yoshiaki_mizukura/kubernetes-tips-for-all-application-engineers-who-want-to-focus-on-coding

- 開発者にとってのメリット
    - 実行環境のパッケージ化
    - 環境感の差異を減らせる
        - 開発では動くけど本番は、、とか
        - バグの再現性とか、、
    - ミドルウェア環境を含めたコード化
    - Immutableな実行環境

    - k8sを使うことでアプリ外部の環境依存に悩まされなくなり迅速なデリバリができる。
    - 結果より多くのトライアンドエラーができる

- webアプリ開発におけるコンテナ利用について
    - 従来
        - 開発者がそれぞれPCに環境作ってリポジトリにpush、テスト環境でビルドとデプロイ、本番でビルドとデプロイ
    - コンテナ環境だと
        - Dockerfile/Manifestを作成、ビルド、push
        - 実行環境もバージョン管理できる
    - 欠点。。Docker/Kubernetsの学習コスト(ポイントは絞れるけど)

- デプロイ環境差異へのアプローチ
    - 原則： コンテナイメージに環境情報を持たせない(環境変数に切り出し)
        - 設定ファイルが環境変数を読めればConfigMapで
        - 読めなければ、envsubstなどのテンプレート化
- Logging
    - Docker loggin driver、標準でいろいろある
    - 例えばfluentd logging driverを使えばElasticsearchへ集約、Kibanaで可視化
        - OpenShiftもデフォルトの動作はこれ
    - アプリのログはファイル出力でなくstdoutへ！
    - ミドルウェアのログも同様にstdoutへ！
    - k8sリソースのlabelは適切に設定する
- HTTPセッション管理
    - コンテナに限らないけど、、、どこにセッションデータを保持するか
    - 可能な限りアプリの外部に保持し、アプリをステートレスにしておくのが望ましい
    - Statefullなアプリもk8sのSticky Session機能を使って改修せずに動作させることができる
        - service (L4 Load Balancing)
        - Ingress (L7 LB)
- サービスメッシュ
    - マイクロサービスの複雑さ。。サービス間の通信は複雑！
    - 考慮する必要のあることは多い！

    - ライブラリやF/Wでの対応は重い。

- ツール紹介
    - stern
        - 標準のログ表示はコンテナ単位でのログ確認なので、pod再起動とかで対象が変わるので正直使いづらい
        - sternこれを使うと、pod指定をlabel指定やregexpでできる。namespace横断
        - pod差作成でid変わっても追従してくれる
    - docker command-line completion
        - docker
            - mac/win(ps)用
        - k8s
            - kube-prompt
        - コマンド打たなくても結果をサジェストしてくれる
    - freshpod
        - イメージの更新を検知してPodを再デプロイしてくれる
            - OpenShiftのImageStreamと同等機能かな？

## [2W1] Dockerセキュリティ: 今すぐ役に立つテクニックから，次世代技術まで

- https://twitter.com/_AkihiroSuda_/status/1070189244814000128
- https://www.slideshare.net/AkihiroSuda/docker-125002128

Dockeを使うことでアプリに脆弱性があってもその影響範囲を限定することができる。

- イメージ作成するときに気を付けること
    - Dockerfileの中からプライベートなGitリポジトリやS3にアクセスするには、ビルド中にcopy/addで鍵を入れてgit cloneとかしてあとで削除すればよさそうだけど、、、
    - 鍵を含む中間レイヤーができるため、イメージをパブリックなとこにpushすれば鍵が漏れる。
    - Docker 18.09から利用可能な docker build --secretおよびdocker buiild --sshを使う
    - 古いDockerの場合は…(でもverupしよう)
        - マルチステージビルド
        - docker build --squash (レイヤをまとめる)
        - historyに残らない特殊なbuild-argを目的外利用する　(あまりおすすめしない)

- イメージスキャナ
    - Clair, Microscanner, Anchore, Dagdaなどスキャナがある
    - ただし、すべての脆弱性が見つかるわけではない
    - 脆弱性が必ずしも問題ではない場合もある
    - イメージスキャナ比較(参考情報): https://kubedex.com/follow-up-container-scanning-comparison/
        - どれが良いとは一概には言えない
        - 誤検知もあるので、あまり過信せず、なるべく依存パッケージを減らしシンプルなイメージを作るのが良い

- Dockerソケット
    - DockerデーモンがRESTAPIを待ち受けるソケット
    - dockerグループに一般ユーザを追加すると一般ユーザでもdockerコマンドを使用できるが、ホストのroot権限を与えることに等しいので注意
    - インターネットへTCPをlistenするなら、TLSの設定を必須
        - TLSの設定方法: https://docs.docker.com/engine/security/https …難しい！
    - Docker 18.09 では、export DOCKER_HOST=ssh://username@hostname すればTLSの代わりにsshを用いてリモートDockerホストに接続できる
        - 古いDockerでもssh -Lで代用可能

## [2E2] - (1/2) 改めてDockerfileのベストプラクティスを振り返ろう

マルチステージビルドだけは覚えて帰ろう！

https://www.slideshare.net/ssuser1f3c12/introduce-that-best-practices-for-writing-dockerfiles

- Dockerfile
    - MAINTAINERはdeprecatedになってる (命令語は実質17種)
- Dockerfileのベストプラクティスとは
    - 公式ドキュメントにある https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
    - 「26分で読める」とあるが、分量的にそれはちょっと
    - 内容の9割は「ガイドライン」と「命令語の使い方」
    - General guidelines and recommendations
        - ステートレス(ephemeral)なコンテナを作ること
        - docker buildはどこでビルドされるのか理解すること
        - Dockerfileがなくてもパイプライン処理もできる
        - .dockerignoreを使用して余計なファイルを含めない事
        - マルチステージビルドを使う
        - あると便利だが必須でないものは入れない(net-toolsやvimなど)
        - 1アプリケーション1コンテナが原則
        - レイヤ数をできるだけ減らす
            - レイヤ数とサイズが増えるのはRUN,ADD,COPY
            - レイヤ数とサイズはdocker historyで確認
            - 詳細に見れるツールもある https://github.com/orisano/dlayer
        - 複数行の引数はソートする
        - ビルドキャッシュを活用
            - ADD,COPYは対象ファイルのハッシュで差分の有無を見ている(タイムスタンプは関係ない)
            - RUNは文字列が一致しているかどうか(apt updateなどもキャッシュする)
    - Dockerfile instructions
        - FROM: とにかく小さいイメージをベースに(公式的にはAlpineが推奨)
        - RUN: 可能な限り1回にまとめる
        - CMD: 基本的にはデフォルトコマンドの指定。コマンドが固定であればENTRYPOINTを使う
        - ADD/COPY: シンプルなCOPY(イメージ追加機能のみ)をまずは推奨
            - ADDはtar展開やリモートからファイル取得することもできる