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

はてなリモートインターンシップ2023 コンテナオーケストレーション講義資料

Hatena
October 18, 2023

はてなリモートインターンシップ2023 コンテナオーケストレーション講義資料

Hatena

October 18, 2023
Tweet

More Decks by Hatena

Other Decks in Programming

Transcript

  1. ίϯςφΦʔέετϨ
    ʔγϣϯ
    #hatenaintern)*)+
    !

    View full-size slide

  2. この講義で学んでほしいこと
    • コンテナオーケストレーションの⽬的と主な機能
    • デファクトスタンダードであるKubernetesの特徴と各機能
    • インターンの中でKubernetesを使うために最低限の操作⽅法
    !

    View full-size slide

  3. コンテナオーケストレーションとは
    !

    View full-size slide

  4. コンテナ
    • Docker: Build/Ship/Run
    • 1プロセス1コンテナ
    • 1つの⼤きなサービスを実現するために多くのコンテナを⽤
    いることも
    • マイクロサービス
    • 可⽤性を⾼めるための⽔平スケーリング
    !

    View full-size slide

  5. コンテナオーケストレーションとは
    複数のコンテナを管理し、協調させて動かすためのツール
    • コンテナ同⼠が通信できるようにする
    • ⾃動化によりコンテナ管理コストを減らす
    • ⾼い可⽤性を維持する
    !

    View full-size slide

  6. コンテナオーケストレーションツールが持つ
    主な機能
    • コンテナ配置のスケジューリング
    • 負荷分散/サービスディスカバリー
    • セルフヒーリング/ヘルスチェック
    • オートスケーリング
    !

    View full-size slide

  7. コンテナ配置のスケジューリング
    • コンテナの実⾏数を指定し、その数だけコンテナを⽴てる
    • システムの負荷をみて、どのマシンにコンテナを⽴てるかを⾃
    動で選択する
    !

    View full-size slide

  8. 負荷分散/サービスディスカバリー
    • 複数のコンテナに負荷を分散して可⽤性を⾼める
    • サービスディスカバリー
    • 動的にコンテナが⼊れ替わるクラスター内で特定のコンテナ
    を⾒つけて通信するための仕組み
    • コンテナは⽣存期間が⽐較的短く、IPアドレスも頻繁に変わ

    !

    View full-size slide

  9. セルフヒーリング
    • マシンに障害が発⽣した場合
    • 正常なマシンにコンテナを配置し直す
    • コンテナに障害が発⽣した場合
    • 必要な分だけコンテナを⽴て直す
    • コンテナ障害を検知するためのヘルスチェック
    !

    View full-size slide

  10. オートスケーリング
    これらのスケーリングを、負荷状況に応じて⾃動で⾏う
    • コンテナのスケールイン‧スケールアウト(コンテナ数の増
    減)
    • コンテナのスケールアップ‧スケールダウン(CPUやメモリの
    割り当ての増減)
    • マシンクラスターのスケールイン‧スケールアウト
    !"

    View full-size slide

  11. Kubernetesとは
    !!

    View full-size slide

  12. Kubernetesとは
    • kubernetes, k,s
    • Googleの内製コンテナ管理ツールをOSS化したもの
    • コンテナオーケストレーションツールのデファクトスタンダー

    • パブリッククラウドでプラットフォームが提供されている
    • AWS EKS, Google Cloud GKE, Azure AKS
    !"

    View full-size slide

  13. Kubernetesで何ができるのか?
    コンテナオーケストレーションツールとして持つべき機能を⼀通り兼ね備えている
    • 宣⾔的な構成管理
    • コンテナ配置のスケジューリング
    • 負荷分散/サービスディスカバリー
    • セルフヒーリング/ヘルスチェック
    • オートスケーリング
    ここからはKubernetesの⾔葉でこれらを説明していく
    !"

    View full-size slide

  14. 宣⾔的な構成管理
    Kubernetesは宣⾔的な構成管理を実現している
    • 期待する状態を設定ファイルに記述する
    • 設定ファイルを適⽤すると、以前の状態に依存せずに宣⾔した状態
    になる
    • 例)コンテナを常に3つ⽴てたいと記述すると3つ⽴つ。2つに変更
    するとどれか1つのコンテナが停⽌する
    対照的なのは、現状からの差分を命令として記述する⽅式
    !"

    View full-size slide

  15. Kubernetesの構成
    !"

    View full-size slide

  16. Cluster
    • マスターノードとワーカーノードで構成される
    • マスターノード
    • コントロールプレーン
    • クラスタの管理を担当
    • パブリッククラウドではマネージドに提供される
    • ワーカーノード
    • データプレーン
    • コンテナを実⾏するためのコンピューティングリ
    ソースの集まり
    • 詳細は後述
    !"

    View full-size slide

  17. Pod
    • デプロイの最⼩単位
    • Podは1つ以上のコンテナから構成される
    • メインのアプリケーションコンテナとそれを
    補助するサブコンテナから構成される
    !"

    View full-size slide

  18. サイドカーパターン
    • podのデザインパターンとして
    のサイドカーパターン
    • サブコンテナはメインコンテ
    ナをサポートするような役割
    を担う
    • (例) Proxy, ログ転送, 監視エ
    ージェント
    !"

    View full-size slide

  19. ワーカーノード
    • 複数のPod(コンテナ)を実⾏するためのコン
    ピューティングリソース
    • 物理or仮想のサーバー
    • kubeletプロセスが起動していてマスターノ
    ードのAPIとやりとりをする
    • クラウド環境では台数などを⾃動的に調整す
    るする仕組みを導⼊している場合が多い
    !"

    View full-size slide

  20. Kubernetesのリソース
    !"

    View full-size slide

  21. リソースのカテゴリ
    • Workloads
    コンテナの実⾏に関するリソース
    • Service
    コンテナを外部公開するようなエンドポイントを提供するリソース
    • Config&Storage
    設定‧機密情報‧永続化ボリュームなどに関するリソース
    • Cluster
    セキュリティやクォータなどに関するリソース
    • Metadata
    クラスタ内の他のリソースを操作するためのリソース
    Namespaceという仮想的なクラスタの分離機能
    !"

    View full-size slide

  22. Workloadsカテゴリ
    コンテナの実⾏に関するリソース
    • Pod
    1つ以上のコンテナから構成されている
    Pod内に含まれるコンテナは同じネットワーク内に存在し同⼀IPを持つ
    • Replicaset
    Podのレプリカを作成して指定した数のPodを維持する(セルフヒーリ
    ング)
    同じアプリケーションが動作している複数のPodが展開される
    !!

    View full-size slide

  23. Workloadsカテゴリ
    • Deployment
    複数のReplicasetを管理してローリングアップデートやロールバックなどを可能にする
    !"

    View full-size slide

  24. Workloadsカテゴリ
    以下、今回のハンズオンでは利⽤なし
    • Job
    コンテナを利⽤してワンオフの処理を実⾏させるリソース
    • CronJob
    スケジュールされた時間にjobを実⾏するリソース
    !"

    View full-size slide

  25. Serviceカテゴリ
    コンテナを外部公開するようなエンドポイントを提供するリソース
    受信したトラフィックを複数のPodにロードバランシングする
    • Service
    • L)ロードバランサ
    • サービスディスカバリ
    • Ingress
    • L;ロードバランサ
    !"

    View full-size slide

  26. kubernetesクラスタ内の通信
    • 同じPod内のコンテナに通信する場合はlocalhost宛に通信する
    • 別のPod内のコンテナに通信する場合はPodのIP宛に通信する
    • podのIP宛の通信は可能だがアプリケーションからIPを指定すると実運
    ⽤上で課題が発⽣する
    • PodのIPはPodが⼊れ替わる度に異なるIPが割り当てられる
    • Podが停⽌した場合にサービス断が発⽣する
    • トラフィックが増えてもpodを増やして解決できない
    !"

    View full-size slide

  27. Service ロードバランサ
    • 複数のPodに対するトラフィックのロードバランシング(負荷分散)を⾏う
    • 1回⽬のリクエストはpodJが受け取り2回⽬のリクエストはpodQが受け取り…
    • これによりpodJつあたりの負荷を分散することができる
    • ロードバランシングの⼊り⼝となるエンドポイントを提供
    • エンドポイントには単⼀の仮想IPが割り当てられる
    • エンドポイントの種類は⽤途によって様々
    • ClusterIP (内部向け)
    • NodePort (外部向け)
    • LoadBalancer(外部向け)
    • etc
    !"

    View full-size slide

  28. Service サービスディスカバリ
    • 動的にPodが⼊れ替わるクラスター内で情報を
    登録、発⾒するための仕組み
    • クラスタ内DNSの利⽤が推奨されている
    • ロードバランシングの⼊り⼝となるエンドポイ
    ントがクラスタ内DNSに⾃動的に登録される
    • accountサービスは account.hatena-
    intern-2023.svc.cluster.local という
    形式でDNS Aレコードに割り当てられる
    • account(service名).hatena-
    intern-z{z|(namespace名).svc(リソースの
    種類)
    !"

    View full-size slide

  29. Ingress
    • Ingress
    • L)のロードバランサ
    • 実装は様々 (AWS ALB, Google Cloud GCLB, クラスタ内
    Nginx)
    • Ingressリソースが登録されると実体が構築される
    • HTTPSの終端
    !"

    View full-size slide

  30. リソース管理について
    !"

    View full-size slide

  31. Manifest
    • リソース定義が書かれたYAML
    • kubectl apply -f によってk7sクラスタに適

    • これにより宣⾔的なコードによる管理が可能となる
    !"

    View full-size slide

  32. リソース制限
    • Podに対して割り当てるCPUやメモリの制限を⾏うことができ

    • 要求と制限
    • 下限と上限を指定できる
    • ノードにPodを配置する際に考慮される
    !"

    View full-size slide

  33. ヘルスチェック
    • Podが正しく動作しているか確認するための仕組み
    • Liveness Probe
    • アプリケーションが起動し、コンテナが正しく動作しているかどうか
    • チェックが通らなかったときはPodを再起動する
    • Readiness Probe
    • Podがリクエストを受け付ける準備ができているかどうか
    • チェックが通ったときにトラフィックを受け⼊れる
    !!

    View full-size slide

  34. 可⽤性と拡張性について
    !"

    View full-size slide

  35. 可⽤性
    • セルフヒーリング
    • Replicasetがコンテナのプロセス監視を⾏

    • チェックに失敗するとManifestで設定した
    レプリカ数を維持するように働く
    • Node障害時にもPodを正常なNodeにスケ
    ジュールし直す
    !"

    View full-size slide

  36. 負荷に対する拡張性
    • ⽔平オートスケール
    • Horizontal Pod Autoscaler (HPA)
    • CPU等のメトリクスを参照してPodのレプリカを⾃動で追加する
    • 垂直オートスケール
    • Vertical Pod Autoscaler (VPA)
    • CPU, メモリの使⽤量を分析してリクエスト値を提案したり⾃動的に更
    新したりする
    !"

    View full-size slide

  37. ハンズオンで利⽤するツール紹介
    !"

    View full-size slide

  38. Minikube
    • ローカル環境でKubernetesのクラスターを⽴ち上げるのにオス
    スメ
    https://minikube.sigs.kHs.io/docs/start/
    • Kubernetesのバージョンを指定してクラスターを構築できる
    • 他にもkindといったツールなどでもローカルでクラスター構築
    が可能
    !"

    View full-size slide

  39. Kustomize
    • https://github.com/kubernetes-sigs/kustomize
    • k6sのマニフェストの構成をカスタマイズするためのツール
    • Dev, Stg, Prd等の複数の環境分Manifestを書くのは冗⻑なの
    で、共通のベースとなるマニフェストを作りつつ環境毎の差分
    をパッチファイルとして管理できるようになる

    kustomization.yaml
    にどのマニフェストを使うか、secret
    やconfigの設定などを記述する
    !"

    View full-size slide

  40. Skaffold
    • https://skaffold.dev/
    • ファイルの変更を検知してコンテナイメージのビルド、kGs環境
    へ反映するツール
    • skaffold.yaml に対象となるファイル、dockerイメージ、
    マニフェストを記述する
    !"

    View full-size slide

  41. Kubernetesハンズオン
    !"

    View full-size slide

  42. アジェンダ
    • 第⼀部 Hatena-Intern-./.0環境で遊ぼう
    • 第⼆部 記法変換サービスの追加
    !"

    View full-size slide

  43. 第⼀部
    Hatena-Intern-)*)+環境で遊ぼう
    !"

    View full-size slide

  44. この時間はハンズオンです
    • ⼀緒に⼿を動かして⼿元のKubenetes環境を触ってみましょう
    • codespaces環境を使います
    !!

    View full-size slide

  45. サービスの構成
    !"

    View full-size slide

  46. マニフェストの構成
    k8s
    ├── account
    │ ├── app.yaml
    │ ├── config
    │ │ └── schema.sql
    │ ├── db.yaml
    │ ├── kustomization.yaml
    │ ├── secret
    │ │ └── ecdsa-private.pem
    │ └── test.yaml
    ├── blog
    │ ├── app.yaml
    │ ├── config
    │ │ └── schema.sql
    │ ├── db.yaml
    │ ├── kustomization.yaml
    │ ├── secret
    │ │ └── account-ecdsa-public.pem
    │ └── test.yaml
    ├── kustomization.yaml
    ├── namespace.yaml
    ├── renderer-go
    │ ├── app.yaml
    │ └── kustomization.yaml
    └── system
    └── sa.yaml
    • k8s ディレクトリがマニフェスト置き場
    • account/blog/renderer-goとマイクロサービスごと
    にディレクトリを分ける
    • kustomization.yaml がkustomizeの設定ファイル
    !"

    View full-size slide

  47. k"s/blog/kustomization.yaml
    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    resources:
    - app.yaml
    - db.yaml
    - test.yaml
    secretGenerator:
    - name: blog-app-secret
    files:
    - secret/account-ecdsa-public.pem
    configMapGenerator:
    - name: blog-app-env-vars
    literals:
    # (snip)
    - name: blog-db-schema-config
    files:
    - config/schema.sql
    !"

    View full-size slide

  48. 確認
    % make up
    • 8080番ポートは⾃動でポートフォワードされるようになっていますが、ポートフォワード
    されていない場合、別のターミナルを開き、以下のコマンドでポートフォワードできま
    す。
    % kubectl port-forward service/blog 8080:8080 # ϩʔΧϧͷ8080ϙʔτ΁
    ͷ௨৴Λblog service ͔Βෛՙ෼ࢄ͞Ε͍ͯΔpodͷ8080ϙʔτʹసૹ͢Δ
    Podが起動すると、⾃動でブラウザが開くので開いてブログを作成してみましょう。
    開かない場合、vscodeのterminalのPORTSタブから8080ポートを追加してあげてください。
    !"

    View full-size slide

  49. サービスが起動していることを確認する
    contextの切り替え
    % kubectl config use-context hatena-intern-2023
    % kubectl get pods
    !"

    View full-size slide

  50. Podが起動する様⼦を⾒よう
    • services/blog/templates/index.html を書き換えて、
    変更が反映されることを確認しましょう
    別の端末で実⾏してPodの状態を⾒る
    % kubectl get pods -w
    % kubectl describe pods
    !"

    View full-size slide

  51. デバッグ
    # Podͷৄࡉ৘ใͷදࣔɻpod͕ىಈ͠ͳ͍৔߹͸ಛʹ"Events:"ཝʹ஫໨
    % kubectl describe pod blog
    # ωʔϜεϖʔε্ʹ͋ΔϦιʔεͷ৘ใΛදࣔ
    % kubectl get all
    # ىಈ͍ͯ͠ΔPodͰγΣϧΛىಈ͢Δ
    % kubectl exec -it svc/account -c account !" /bin/sh
    • 起動しているプロセスは?
    !
    ps
    • blogサービスにアクセス
    !
    wget -q -O - blog:8080

    !
    nslookup blog
    !"

    View full-size slide

  52. 第⼆部
    記法変換サービスの追加
    !"

    View full-size slide

  53. 記法変換サービス renderer
    • services/renderer-ts にある実装をk*s上で動かす
    • デフォルトでは services/renderer-go が動いている
    • k8s/renderer-go を参考に、k8s/renderer-ts を追加
    !"

    View full-size slide

  54. マニフェスト
    • 追加するマニフェスト
    • k8s/renderer-ts/kustomization.yaml
    • k8s/renderer-ts/app.yaml
    • 編集するマニフェスト
    • skaffold.yaml
    • k8s/kustomization.yaml
    • k8s/blog/kustomization.yaml
    !"

    View full-size slide

  55. マニフェストの追加
    % cp -R k8s/renderer-go k8s/renderer-ts
    % sed -i -e 's/renderer-go/renderer-ts/g' k8s/renderer-ts/*.yaml
    • k8s/renderer-go ディレクトリをコピーして k8s/
    renderer-ts を作成
    • マニフェスト内の renderer-go を renderer-ts に置き換え
    !!

    View full-size slide

  56. マニフェストの編集
    skaffold.yaml
    apiVersion: skaffold/v2beta5
    kind: Config
    metadata:
    name: hatena-intern-2023
    build:
    artifacts:
    # (snip)
    - image: hatena-intern-2023-renderer-go
    context: services/renderer-go
    - image: hatena-intern-2023-renderer-ts #
    !
    context: services/renderer-ts #
    !
    local:
    # (snip)
    • services/renderer-ts のdockerイメージのビルドとk2sクラスタへの反映がされるようにする
    !"

    View full-size slide

  57. マニフェストの編集
    k"s/kustomization.yaml
    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    namespace: hatena-intern-2023
    resources:
    - namespace.yaml
    - account
    - blog
    - renderer-go
    - renderer-ts #
    !
    !"

    View full-size slide

  58. マニフェストの編集
    k"s/blog/kustomization.yaml
    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    # (snip)
    configMapGenerator:
    - name: blog-app-env-vars
    literals:
    - MODE=development
    - DATABASE_DSN=root@(blog-db:3306)/intern_2023_blog?time_zone=UTC&parseTime=true&loc=UTC
    - ACCOUNT_ADDR=account:50051
    - RENDERER_ADDR=renderer-ts:50051 #
    !
    - name: blog-test-env-vars
    # (snip)
    • blogサービスの記法変換サービスへの向き先をrenderer-goからrenderer-tsに変
    える
    !"

    View full-size slide

  59. Podが正常に起動しない場合
    • kubectl get pods を実⾏して各Podが正しく起動している
    かどうか確認する
    • kubectl describe pod renderer-ts で詳細情報を確認
    • なぜ正常に起動しないか原因を探ろう
    !"

    View full-size slide

  60. 実際にrenderer-tsが動くことを確認する
    • kubectl get pods よりすべてのPodが正常に起動しているこ
    とを確認
    • ブログにアクセスし、記事を作成し renderer-ts サービスが
    動くことを確認
    !"

    View full-size slide

  61. 変更点をpushしておく
    ここらへんはご⾃由にという感じですが、今回の変更点をコミットしてpushしておき、
    いつでもtypescript実装に変更可能にしておくと今後のインターンに便利だと思います。
    私はuse-renderer-ts-arthur-cっていうブランチでpushしておくので、もし今回のハン
    ズオンで⼿元でうまく動かなかった⼈がいても、このブランチを参考にすることで今後
    のインターンでts使いたくなった時にrenderer-ts化できると思います。
    % git switch -c use-renderer-ts-arthur-1
    % git add k8s/ skaffold.yaml
    % git commit -m'rendererΛtypescript࣮૷ʹมߋ'
    % git push origin use-renderer-ts-arthur-1
    !"

    View full-size slide

  62. データベースを覗いてみよう
    おまけコーナー。アプリケーション開発に役に⽴つと思います。
    % mysql -u root -h 127.0.0.1 -P 3306 intern_2023_blog
    MySQL [intern_2023_blog]> show tables;
    +----------------------------+
    | Tables_in_intern_2023_blog |
    +----------------------------+
    | blogs |
    | entries |
    | sessions |
    | users |
    +----------------------------+
    MySQL [intern_2023_blog]> select count(*) from blogs;
    +----------+
    | count(*) |
    +----------+
    | 0 |
    +----------+
    接続できない場合、ポートの転送ができていない可能性があります。以下のコマンドでポートフォワードしてください
    # ϙʔτͷసૹ
    % kubectl port-forward svc/blog-db 3306:3306
    !"

    View full-size slide

  63. まとめ
    • コンテナオーケストレーションの⽬的と主な機能を紹介した
    • デファクトスタンダードであるKubernetesの概観と基本的な機
    能を紹介した
    • ハンズオンを通して、Kubernetesを体験した
    !"

    View full-size slide