harukin721

主に学習記録 🔗 wantedly.com/id/harukin721

Kubernetes完全ガイド 【第2版】 読書会2 Part4

これの続き。Part4

第14章 マニフェストの汎用化を行うオープンソースソフトウェア

マニフェストの汎用化

Kubernetes では YMAL形式で書かれたマニフェストを作成し kubectl を使って適用するのが一般的。

システムが大規模になってくると類似したマニフェストを大量に作らなければならず、再利用や一括変更といったことが困難になってくるので汎用化の考え方が必要。

Helm

Kubernetes のパッケージマネージャー

Helm が管理している公式 Chart はそれぞれの成熟度に合わせて stable と incubator に分かれている。

  • `helm test` コマンドで Helm Chart が適切に動作しているか確認できる
  • `helm template` コマンドで Helm のテンプレートから YMAL形式のマニフェストを生成することができる
    • 生成するマニフェストの出力のみで Kubernetes  クラスタへの適用はされない
    • CI/CD パイプラインを GitOps で組んだ場合にアプリケーションを直接インストールせずに、テンプレートエンジンとして Helm を使うことができる
    • Helm クライアントは Chart と values の組み合わせを Releaseとして管理し Secrets としてデータを扱うので別途DBを用意しなくてよい。

Kustomize

Kubernetes コミュニティの sig-cli が提供しているマニフェストテンプレーティングツール

Kustomize の設定は `kustomization.yaml` ファイルを利用する。

複数マニフェストの結合(resources-sample/kustomization.yaml)

resources:
- sample-deployment.yaml
- sample-lb.yaml

`kubectl kustomize resources-sample/ `コマンドを実行するとマニフェスト生成

Namespace の上書き(namespace-sample/kustomization.yaml)

namespace: sample-namespace
resources:
- sample-deployment.yaml
- sample-lb.yaml

`kubectl kustomize namespace-sample/ `コマンドを実行すると metadata.namespace が指定された状態で生成

Prefix と Suffix の付与(name-sample/kustomization.yaml)

namePrefix: prefix-
nameSuffix: -suffix
resources:
- sample-deployment.yaml
- sample-lb.yaml

`kubectl kustomize name-sample/ `コマンドを実行すると `prefix-<NAME>suffix` にそれぞれ置換される。

他にも commoLabels と commonAnnotations を利用して、すべてのリソースに対して共通のメタデータ(ラベル、アノテーション)を付与することもできる。

images によるイメージの上書き(image-sample/kustomization.yaml)

images:
- name: nginx
newName: samplpe-nginx
newTag: v2.0
resources:
- sample-deployment.yaml
- sample-lb.yaml

リソースで使われるイメージを置換することができる。

name にマッチするイメージはすべて置換されるので複数の Deployment などがある場合はすべてに影響することもある。

 

Overlayによる値の上書き(production/kustomization.yaml)

メタデータ系のフィールド以外、その他の細かな設定に関しては Overlay 機能を使ってリソースに対してパッチを当てて変更することが可能。

production や staging ごとにレプリカ数や CPU やメモリの値を変えることができる。

bases:
- ../resources-sample/
patchesStrategicMerge:
- ./patch-replicas.yaml
images:
- name: nginx
newTag: production

下記 Deployment のレプリカ数をのパッチを当てるマニフェスト

apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: 100

Kustomize に関連する kubectl サブコマンド 

$ kubectl <apply|get|describe|diff> -k resources-sample/

第15章 モニタリング

Kubernetes における監視

Kubernetes では複数の Node で大量コンテナが起動しており `kubectl top` コマンドを使って、メトリクスを見るだけで Kubernetes クラスタを運用していくのは困難なので監視ツールを導入することになる。

DataDog(SaaS)

様々なミドルウェアSaaSパブリッククラウドとの連携機能などが用意されていて、時系列で様々なメトリクスを収集 / 可視化 / モニタリングすることが可能。

Kubernetes 上にデプロイする際は DaemonSet を利用してDatadog Agent を各Node 上で起動する(環境によってサイドカーパターンも)。

デプロイされた Agent は各ホストの CPU 使用率やディスク使用率といったメトリクスや、各Node 上のコンテナのメトリクスも取得する。

www.udemy.com

Prometheus(OSS)

Datadog とは違い、利用するための課金要素はないが運用コストやサーバー側のマシンリソースが必要となる。Datadog と同様に時系列で様々なメトリクスを収集 / 可視化 / モニタリングすることが可能。

Prometheus Server を中心に Alert Manager / Exporter / Push Gateway から構成されている。

  • Prometheus Server : メトリクスの収集と保存などを行う
  • Exporter : 各種ミドルウェアから監視項目のデータ抽出を行う
  • Push Gateway : Push 型のアーキテクチャで Prometheus にメトリクス送信を行う
    • バッチ系システムのメトリクスは Pull 型と相性が悪い
    • 各プログラムからメトリクスを送信(Push)されて Prometheus がメトリクスを収集(Pull)する。
  •  Alert Manager : Prometheus Server がモニタリング閾値を超えたと判断するとアラートのリクエストを送る
    • メール通知や Slack通知、PagerDuty 通知などへ通知する
    • 通知の無効化や、類似したアラートが連続した際の重複排除も可能
    • これらの可視化には Grafana がよく利用される

第16章 コンテナログの集約

コンテナ上で起動するアプリケーションは、基本的に標準出力と標準エラー出力にログを出力するようにしておく。Kubernetes では `kubectl logs` コマンドで表示できる。

クラスタ上で起動しているすべてのコンテナのログをクラスタ外部のサービスに転送する仕組みを利用することができる。中長期的にログを安定保存するには、ログを集約してクラスタ外部に転送することで、後からいつでも利用できるようにしておく。

Fluentd によるログ集約

Kubernetes に組み込んで利用するには DaemonSet を利用して各Nodeに Fluentd の Pod を 1つずつ起動する。DaemonSet が作成する各Node の Fluentd Pod は同じ Node 上に起動している全コンテナのログを取得して転送する。

Docker コンテナの標準出力に出力されたログが Node 上の `/var/log/containers` に出力されて、配下のログファイルを Fluentd Pod が tail プラグインを使って読み出して転送している。

Fluentd の他にも Datadog Logs や Grafana Loki によるログ集約

  • Datadog Logs : Datadog Agent が直接コンテナの標準出力から出力されたログを収集し、Datadog の SaaS サーバーに対して転送を行う
  • Grafana Loki : Prometheus ライクなログ集約を行う OSS
    • DaemonSet で展開される promtail と呼ばれるエージェントがログを収集し、Deployment で展開される Loki にデータを集約する仕組み
    • Loki ではデータの集約以外にもクエリの実行も担当する
    • Loki に集約されたログデータは Grafana を経由して可視化できる

第17章 Kubernetes環境での CI/CD

実際に運用を行う際には手動で kubectl コマンドを実行するのは避けるべきであり、ヒューマンエラーの発生やスケールしないといった課題がある。

そのため自動で CI/CD パイプラインを構築するのが推奨される。

GitOps(Git を用いた CI/CD)

アプリケーションのアップデート、Deployment などのリソースが使用する Docker イメージの変更のような Kubernetes クラスタの操作を Git リポジトリを介して行うことで、手動でのマニフェスト変更や `kubectl apply` コマンドの実行をなくすことが可能。

www.weave.works

ArgoCD(Git を実現するための CD ツール)

あらかじめ指定したリポジトリを監視し Kubernetes クラスタに対してマニフェストを適用する。

Application リソースを作成することで特定のリポジトリの特定のパスにあるファイルを Kubernetes クラスタに適用する仕組みとなっている。

この本も読む。

book.impress.co.jp

第18章 マイクロサービスアーキテクチャとサービスメッシュ

マイクロサービスアーキテクチャは、システム個々の機能をサービスとして切り出し、サービス同士を gRPC や RESTful API などで連携することでシステム全体を構成する、疎結合アーキテクチャ。これに対して、システム全体を 1つのサービスで実現する構成をモノリシックアーキテクチャ

メリット

  • サービス同士をつなぐ gRPC や RESTful API のインターフェースの仕様が決まっていれば、それに従う以外は各サービスのプログラム言語やFWなどの技術を自由に選定可能
  • サービス同士が疎結合に保たれていれば、サービスごとの開発規模や性能をスケールさせることができる
  • サービスごとに独立してアップデートできるので、リリースサイクルを短縮することが可能
  • 障害の影響範囲をそのサービスにとどめることができる

デメリット

  • システムを複数マイクロサービスに適切に分割することが困難
  • マイクロサービス間の依存関係などの把握、マイクロサービス間のトラフィックのレイテンシやエラーレートのモニタリングが困難

サービスメッシュ

マイクロサービス間に張り巡らされたメッシュ状の通信やその経路を制御する考え方

代表的なものに Istio がある。AWS だと App Mesh 

基本的な仕組みは Pod 間の通信経路にプロキシを挟むことでトラフィックのモニタリングやトラフィックコントロールを行うもの。(既存のアプリケーションに手を加える必要がない)

www.udemy.com

第19章 Kubernetesアーキテクチャを知る

Kubernetes クラスタは 8つのコンポーネント(+1 つのオプション)から構成され kube-apiserver を中心とした分散システムとなっている。

  • etcd
    • 分散 Key-Value Store(KVS)
    • 冗長性を担保するためにクラスタを組み込むことが可能
    • Kubernetes クラスタに登録されるすべての情報が保存されている
    • `etcdctl snapshot` コマンドで etcd クラスタの状態をバックアップ
  • kube-apiserver
  • kube-scheduler
    • 起動する Node 情報(spec.nodeName)が未割り当ての Pod を検知し kube-apiserver にリクエストして更新することでスケジューリングを行う
    • Kubernetes Node のステータスや Node Affinity などの条件に合致するかを判断して起動する Node を選定する
    • リーダー選出の仕組みを持ち、1台だけがリーダーとなり書き込むを行うことによって冗長化が可能
  • kube-controller-manager
    • 様々なコントローラーを実行するコンポーネント
    • Deployment や ReplicaSet の状態を監視しながら、必要に応じて ReplicaSet や Pod を作成する
    • リーダー選出の仕組みを持ち、1台だけがリーダーとなり書き込むを行うことによって冗長化が可能
  • kubelet
    • Kubernetes Node 上で動作するコンポーネント
    • コンテナランタイムと連携し、コンテナの起動や停止などの管理を行う
      • kube-apiserver 経由で Pod が登録
      • kube-scheduler によって Pod が起動される Node が決定
      • kubelet が検知して、自身の Node で起動すべきコンテナを起動
    • 自身 Node に静的に起動させたいコンテナがある場合は kube-scheduler 依存せずに起動が可能 > static pod

kubernetes.io

  • kube-proxy
    • Kubernetes Node 上で動作するコンポーネント
    • Service リソースが作られた際に ClusterIP や NodePort 宛のトラフィックが Pod に正常に転送されるようにする
    • 3種の転送方式
      • ユーザースペースでの処理(userspace モード)
      • iptablesでの処理(iptablesモード)
      • IPVSでの処理(ipvsモード)
  • CNI(Container Network Interface) Plugin
    • 複数の Kubernetes Node で構成された Kubernetes クラスタ内に分散配置された Pod が相互に疎通可能なネットワークを構築する Plugin 
    • 代表的な Plugin に Flannel などがある
  • kube-dns(CoreDNS)
  • cloud-controller-manager
  • CRD(CustomResourceDefinition)とOperator
    • 独自のリソースを追加して、Kubernetes を拡張することが可能

www.udemy.com

zoetrope.github.io

第20章 Kubernetesとこれから

Kubernetes は CNCF によりオープンな開発が行われており、並行して標準化も進められている。

主にコンテナイメージフォーマット / コンテナランタイム / コンテナストレージ / コンテナネットワークに関する標準化が進められている。

おわり

業務時間内に読書会の時間をいただいたのでその時のメモを出した。

この書籍はこれからも辞書的に使わせていただきます。ありがとうございました。

参考

book.impress.co.jp