Upgrade to Pro — share decks privately, control downloads, hide ads and more …

コンテナ時代にインフラエンジニアは何をするのか

gree_tech
September 18, 2020

 コンテナ時代にインフラエンジニアは何をするのか

GREE Tech Conference 2020 で発表された資料です。
https://techcon.gree.jp/2020/session/Session-4

gree_tech

September 18, 2020
Tweet

More Decks by gree_tech

Other Decks in Technology

Transcript

  1. 2 •グリー入社前 ◦ 組み込みソフト企業 ◦ 携帯電話向けプラットフォームの開発 •2012年より グリーインフラ部門 ◦ 開発環境の構築、運用

    ◦ デプロイツール・フロー改善 ◦ 商用サービス部門向き合いのインフラ構築・運用・相談 ◦ 最近の主なフィールドは AWS や GCP 2 自己紹介 駒﨑 拓斗
  2. 1. init オプション付きで起動する 1. pid=host オプション付きで起動する 1. user=1000:1000 オプション付きで起動する 1.

    sig-proxy=true オプション付きで起動する 4 次のコマンドは Ctrl+C で停止できません run のオプションで停止可能にできます。効果があるものを全て選んでください Q1. Docker クイズ $ docker run --rm busybox sleep 10000 $ docker run --rm --init busybox sleep 10000 $ docker run --rm --pid=host busybox sleep 10000 $ docker run --rm --user=1000:1000 busybox sleep 10000 $ docker run --rm --sig-proxy=true busybox sleep 10000
  3. 5 5 ⓘ Start presenting to display the poll results

    on this slide. Ctrl+c で停止可能なのはどれ? (複数選択)
  4. 1. init オプション付きで起動する 1. pid=host オプション付きで起動する 1. user=1000:1000 オプション付きで起動する 1.

    sig-proxy=true オプション付きで起動する 6 次のコマンドは Ctrl+C で停止できません run のオプションで停止可能にできます。効果があるものを全て選んでください Q1. 簡易解説 $ docker run --rm busybox sleep 10000 $ docker run --rm --init busybox sleep 10000 $ docker run --rm --pid=host busybox sleep 10000 $ docker run --rm --user=1000:1000 busybox sleep 10000 $ docker run --rm --sig-proxy=true busybox sleep 10000 PID1 のプロセスは明示的にハンドルしない限 り INT や TERM シグナルで停止しない 軽量 init プロセスを PID1 とし、 コマンドをその子として実行するオプション → init 経由でシグナルが伝わり停止する ホストと PID namespace を共有するオプション → PID1 でなくなりシグナルが伝わり停止する uid:gid を指定するオプション → 特に本件では関係ない シグナルの伝搬を指定するオプション → デフォルトで true 、本件では指定しても意味がな い 逆に false にすると Ctrl+C で KILL が送信され停止する
  5. 1. Service type: ExternalName を作成し Pod から Service 名で参照 $

    curl https://greetech/ 2. そのままの名前で参照 $ curl https://greetech.example.com/ 3. そのままの名前 (末尾 . 付き)で参照 $ curl https://greetech.example.com./ 7 Kubernetes の ある Pod から 外部サービス https://greetech.example.com にアクセスします 最も少ない DNS トラフィックが期待できるのは次のうちどれでしょう ※ 一般的な初期設定の Kubernetes クラスタにおいて Pod - クラスタ内 DNS サーバ間 Q2. Kubernetes クイズ apiVersion: v1 kind: Service metadata: name: greetech spec: type: ExternalName externalName: greetech.example.com. ※同一 namespace
  6. 8 8 ⓘ Start presenting to display the poll results

    on this slide. DNS トラフィックが少ないのは?
  7. 1. Service type: ExternalName を作成し Pod から Service 名で参照 $

    curl https://greetech/ 2. そのままの名前で参照 $ curl https://greetech.example.com/ 3. そのままの名前 (末尾 . 付き)で参照 $ curl https://greetech.example.com./ 9 Kubernetes の ある Pod から 外部サービス https://greetech.example.com にアクセスします 最も少ない DNS トラフィックが期待できるのは次のうちどれでしょう ※ 一般的な初期設定の Kubernetes クラスタにおいて Pod - クラスタ内 DNS サーバ間 Q2. 簡易解説 apiVersion: v1 kind: Service metadata: name: greetech spec: type: ExternalName externalName: greetech.example.com. ※同一 namespace # 標準的な resolv.conf (EKS) nameserver 10.100.0.10 search default.svc.cluster.local svc.cluster.local cluster.local ec2.internal options ndots:5 search リスト、ndots: 5 が特徴 → 名前に含まれるドットが5より少なければ search リストを順番にためすよ、の意 ドット<5 なので search リストの先頭 greetech.default.svc.cluster.local. に問い合わせ、 返された CNAME greetech.example.com. に問い合わせ ドット<5 なので search リストの先頭から greetech.example.com.default.svc.cluster.local. , greetech.example.com.svc.cluster.local. , greetech.example.com.cluster.local. , greetech.example.com.ec2.internal. , と問い合わせた後、 greetech.example.com. に問い合わせ FQDN なので greetech.example.com. に問い合わせ
  8. •アプリケーション担当者/チーム (アプリチーム) ◦ あるサービスのビジネスロジックを担当する ◦ カスタマーに対し サービスを開発、運用する ◦ 典型的には、サーバアプリケーション開発者チーム •インフラストラクチャ担当者/チーム

    (インフラチーム) ◦ アプリチームに対し基盤を提供、開発、運用する ◦ 複数のサービスを受け持ち、共通課題を横串で担当する ▪ 横串で受け持つことで、コスト・リソースの最適化を狙う •理想的にはワンチームでプロダクトが作れたらよい、が ◦ 複数事業をさばくため 12 アプリチームとインフラチーム 背景: 本日の "インフラエンジニア" について
  9. •サービスを提供するインフラは絶えず変化 •ベアメタルから VM、コンテナへ •2020 現在グリーでは ◦ オンプレミス・パブリッククラウド併用中 ◦ さらにパブリッククラウドへ移行中 13

    グリーグループのインフラの歩み 背景: Web サービスインフラの移り変わり ベアメタル オンプレ VM パブリッククラウド VM サーバレス コンテナ
  10. •ベアメタル時代 ◦ サーバ調達、インベントリ管理、OS 設定、プロビジョニング、... ◦ 監視・アラートシステム 内製 •VM 時代 初期

    ◦ プロビジョニングツールの導入 ◦ Infrastructure as Code による自動化 ◦ 構造はそのまま クラウドへの "リフト" が行われた •VM 時代 後期 ◦ パブリッククラウドの活用 ▪ プログラマブル / 宣言的な構築 により自動化がさらに進む ▪ クラウドに合わせた設計の浸透 ▪ スケーリング操作など一部運用がアプリチーム側へ 14 インフラのデリバリー・運用の変化 これまでの変化 (ホストベース時代)
  11. •実用的なコンテナ基盤の普及 ◦ アプリチームからもコンテナが身近なものに ▪ docker-compose ▪ Cloud Run ▪ AWS

    copilot (ecs-cli) ▪ Kubernetes •マネージド Kubernetes の大きなインパクト 15 コンテナ時代へ
  12. 16 消えるインフラ業務、残る生まれるインフラ業務 マネージド Kubernetes の出現 ランタイム / Lib 更新したい VM

    イメージ作り直してもらえます か サーバにつなげる 最小限の E2E 環境がほしい 構築とデプロイお願いします デプロイツールの改修を … Dockerfile をちょいと FROM php:7.4-apache 、と クラスタぽちぽち、 Deployment に Service に Ingress 書いて、apply 、と
  13. •たしかに 一部の既存業務は ほぼなくなった ◦ VM イメージ管理 ◦ デプロイツール ◦ オートスケーリング設定

    •引き続きやってくモノ・新しく生まれるモノ ◦ サイト信頼性エンジニアリング (SRE) 関連 ▪ 可観測性の面でより重要度が高まる ◦ データストアやネットワーク、CDN などの専門知識 ◦ 本番運用に耐えるための Kubernetes 自体の知識 ◦ これまでも VM やパブリッククラウドの登場による変化はあったが Kubernetes による変化はそれよりかなり大きい 17 消えるインフラ業務、残る生まれるインフラ業務 マネージド Kubernetes の出現
  14. •(少なくとも今のとこは) まだまだ •例. 冒頭のクイズの領域 ◦ Q1. Docker クイズ (The PID1

    Problem) ▪ Dockerfile の書き方を気をつける問題、nodejs で遭遇しがち ◦ Q2. Kubernetes クイズ (dnsPolicy ClusterFirst の設定) ▪ 名前解決のお作法に気をつける問題 ◦ しかし全くビジネスロジックには関係無い ▪ アプリチームが頑張るところだろうか? ▪ 組織として横串で共有すべきノウハウの類 •"アプリチームに基盤を提供する" 仕事の本質は同じ ◦ が、どこまでが基盤なの? 18 Kubernetes でインフラの業務範囲はどんどん縮小する? これから仕事減りそう?
  15. 19 ホストベースのころ 19 PHP : アプリチーム CI : アプリチーム Deploy

    : インフラチーム apache : インフラチーム VM : インフラチーム LB : インフラチーム ︙ チーム担当範囲の境界はどこだ これから Dockerfile : アプリチーム...? ちょっとインフラ? CI/CD : アプリ?インフラ? K8s : インフラチーム...? とアプリチーム...? ︙ 従来型分担とのアンマッチ
  16. •現状は双方からコミット •コミュニケーションを大事に •サービスの時期によって柔軟に ◦ 弊社ケース ▪ 初期はインフラチーム率高め ▪ 安定運用 &

    K8s 習熟度向上してくるとアプリチーム率高め ▪ 境界のあいまいさは許容 21 インフラチーム / アプリチームの壁を越えてコミュニケーション 現時点の状況 Dockerfile インフラチーム アプリチーム K8s manifest K8s Cluster Config Dockerfile インフラチーム アプリチーム K8s manifest K8s Cluster Config Dockerfile インフラチーム アプリチーム K8s manifest K8s Cluster Config CI/CD CI/CD CI/CD むしろ、従来の構造のチームにキッチリ 合わせようとしてしまうと Kubernetes 的/クラウドネイティブ的 なソフトを活かせなくなる可能性も
  17. •グリーでは現状 ホストベース環境が主流 ◦ コンテナ/Kubernetes に向けて即組織刷新とかはない •いま 2020 年、両方やらなくちゃいけない •Kubernetes との向き合い方には気をつける

    ◦ コンテナ管理ツール ではなく プラットフォームとして ◦ 今までのやり方を延長するより、段を登ってみる ◦ さらにプラットフォームのためのプラットフォームでもある ◦ プラットフォームの意図を汲む 22 従来のホストベース環境も両方見ていく 現時点の状況
  18. • Dokcer も Kubernetes も関係無しに 実現するとしたら? ◦ 環境ごとに VPC を分ける

    VPC ごとの DNS サーバを使って レコードを切り替える ◦ AWS Route53 など 23 例. 23 DNS 管理者の帽子 「自前 DNS サーバでコントロールしよう」 アプリから外部サービス API を参照する。 Production / QA / Develop の 環境ごとに参照先を切りかえたい… どうやって実現しようか
  19. • Dokcer コンテナ的なお作法で 実現するとしたら? ◦ コンテナ内で環境変数を参照させ 実行環境で環境変数に参照先ドメインを流し込む ◦ コンテナ内に全パターンの config

    を埋めておき、 環境変数で config パスを切り替える 24 例. 24 Docker の帽子 「APP_PORT_TCP_ADDR 環境変数を 参照させよう」 DNS 管理者の帽子 「自前 DNS サーバでコントロールしよう」 アプリから外部サービス API を参照する。 Production / QA / Develop の 環境ごとに参照先を切りかえたい… どうやって実現しようか
  20. • Kubernetes のお作法で 実現するとしたら? ◦ コンテナ内の名前は固定してよい Service リソースで流し込む ◦ または

    Docker のとこで挙げたパターンもよい 25 例. 25 Kubernetes の帽子 「Service リソース名を参照させよう」 「もしくは環境変数でもよい」 Docker の帽子 「APP_PORT_TCP_ADDR 環境変数を 参照させよう」 DNS 管理者の帽子 「自前 DNS サーバでコントロールしよう」 アプリから外部サービス API を参照する。 Production / QA / Develop の 環境ごとに参照先を切りかえたい… どうやって実現しようか
  21. •帽子のかぶりわけ ◦ 範囲を明確に認識出来ている状態 •まずは一番上の帽子をかぶる ◦ だめなら下の帽子をかぶりなおす ◦ どの帽子をかぶっているかを忘れない •柔軟なプラットフォームほど 帽子を見失いがち

    •作る側に回るときにも必要 26 このプラットフォームはどう使われることを想定しているのか プラットフォームの意図を汲む Kubernetes の帽子 「Service リソース名を参照させよう」 「もしくは環境変数でもよい」 Docker の帽子 「APP_PORT_TCP_ADDR 環境変数を 参照させよう」 外部サービスの参照先を 環境ごとに切りかえたい … DNS 管理者の帽子 「自前 DNS サーバでコントロールしよう」
  22. •アンラーニングで新しい帽子を手に入れる ◦ 既存知識との境界を認識する、引きずらない ▪ 既存知識の活用・応用はあとからでいい •多くの場合、高次の帽子が "筋がいい" が ◦ ときには帽子をかぶりわける

    ◦ プラットフォームの機能が十分でないとき ◦ あえて違う作法を選ぶとき •帽子を混ぜない!どっちつかずは運用混乱を招く ◦ どっちつかずの例. ▪ ingress-controller で LB を作成したが、別の方法で設定追加 ▪ external-dns で作成したレコードと手動作成したレコード混在して参照させる 27 新しい帽子を手に入れる・帽子をかぶりわける どっちつかずの帽子
  23. •コンテナ・クラウドネイティブ時代も変わらないもの ◦ アプリチームがビジネスに集中できる基盤を提供する ◦ 横串でノウハウ・サービスを展開する •ホストベース時代とコンテナ時代の構造の違いを認識 ◦ どちらにもマッチするチームは難しい ◦ (気持ちは)

    チームの柵を越えていく •インフラの階層ごとに頭を切り替える ◦ インフラ領域も確実に抽象化層が増えた ◦ 帽子をかぶりわけるように ◦ どの階層の話なのか? をはっきり 28 移行期のインフラエンジニアとして ホストベース時代からコンテナ時代へ
  24. 29 29 ⓘ Start presenting to display the poll results

    on this slide. よろしければ教えて下さい皆様の担当領域は?
  25. 30

  26. 31 Q1. Docker クイズ (The PID1 Problem) 資料 参考リンク •

    "Docker/Kubernetes で PID 1 問題を回避する" https://text.superbrothers.dev/200328-how-to-avoid-pid-1- problem-in-kubernetes/ • "PID1 は、カーネルから特別扱いされてるって本当ですか?" https://speakerdeck.com/superbrothers/pid1-ha- kanerukara-te-bie-xi-isareterututeben-dang-desuka • "Docker and Node.js Best Practices" > Node.js was not designed to run as PID 1 which leads to unexpected behaviour … https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#handling-kernel-signals • Google Cloud "PID 1、シグナル処理、ゾンビプロセスの適切な処理" https://cloud.google.com/solutions/best- practices-for-building-containers?hl=ja#signal-handling • docker アプリが適切な signal handling をしていない場合に、アプリの適切な終了処理ができなかったり、実行環境・ア プリによっては fork したプロセスが回収されずゾンビ大量発生などの問題を招く • 現実的には nodejs や LL の簡易サーバ、crond などで遭遇しがち • 自分のアプリが適切に handling できているかについては、クイズのように docker run してみて Ctrl+C や docker stop / docker kill --signal="TERM" のようにしてみると簡単に確認できる • 対応については、alpine ベースであれば apk で tini (軽量 init プロセス) を入れてしまうのが便利 $ docker run --rm busybox sleep 10000
  27. 32 Q2. Kubernetes クイズ (dnsPolicy ClusterFirst の設定) 資 料 参考リンク

    • "RESOLV.CONF(5)" https://linuxjm.osdn.jp/html/LDP_man-pages/man5/resolv.conf.5.html • "Kubernetes Documentation >..> DNS for Services and Pods" https://kubernetes.io/docs/concepts/services- networking/dns-pod-service/#srv-records • GitHub "update docker's resolv.conf file with options ndots:5" https://github.com/kubernetes/kubernetes/pull/10266 • GREE Engineer's blog "スマホゲームの API サーバにおける EKS の運用事例 > DNS の名前解決に失敗する" https://labs.gree.jp/blog/2020/01/20271/#anker612 • "Amazon EKS での DNS 障害のトラブルシューティング" https://aws.amazon.com/jp/premiumsupport/knowledge- center/eks-dns-failure/ • まずは resolv.conf(5) man の options ndots 項を参照のこと • Kubernetes 固有の問題。ふつうの(?) Linux 環境であれば ndots: 5 が入っていることはそうそう無いので、 curl https://greetech.example.com/ で何も問題ない • Kubernetes では、SRV レコードによるサービスディスカバリの利便性のためにこういう設定になっている (下記 github の kubernetes/kubernetes リンクも参照) • クイズで問題のある例として挙げた方法では、IPv6 が有効な場合 AAAA レコードにも問い合わせを行い、1つの名前解決 だけで 10 以上のクエリが発生する場合がある # 標準的な resolv.conf (EKS) nameserver 10.100.0.10 search default.svc.cluster.local svc.cluster.local cluster.local ec2.internal options ndots:5 search リスト、ndots: 5 が特徴 → 名前に含まれるドットが5より少なければ search リストを順番にためすよ、の意