nokoのブログ

こちらは暫定のメモ置き場ですので悪しからず

Kubernetesについて調べたことメモ

はじめに

  • Kubernetesまわりについて復習したときのメモ

参考

メモ

Docker全般

  • コンテナとは
    • ホストOS上に論理的な区画(コンテナ)を作って、一つのサーバのようにしたもの
  • コンテナの利点
    • アプリケーションのポータビリティ
    • 軽量で高速に動作する
      • サーバ仮想サーバと比較してオーバーヘッドが少ない
  • その他
    • プロキシ配下で使うとき
      • /etc/systemd/system/docker.service.d 配下にconfファイルを作成してフラッシュ & Dockerデーモン再起動

Kubernetes全般

  • オーケストレーション
    • マルチホストで構成されたクラスタでコンテナを運用するのに必要になってくる
      • 起動停止、ホスト間のネットワーク接続、ストレージ管理、どのホストで稼働させるかなどのスケジューリング機能、監視
    • クラスタを構成するノードとリソースの管理
    • アプリケーションのスケジューリング
  • Docker Compose
    • 複数のDockerコンテナをサービスとして定義/実行するための、コマンドラインツール
      • 複数コンテナ/イメージの同時構築・同時実行・ログ表示
    • -> しかし、コンテナの常時監視する機能がない、複数のクラスタにデプロイできない
    • -> Swarmが生まれた
  • Kubernetes
    • コンテナに対応したアプリケーションクラスタ環境上へ自動的にデプロイするためのオープンソースフレームワーク
    • Kubernetesが目指すところ
      • システム構築のための手作業を減らす
      • システムをセルフサービスで運用する
    • エコシステム
      • パッケージ管理: Helm(apt-get的な)
      • モニタリング: Prometheus
      • ログコレクタ: Fluentd
      • 分散KVS: etcd
      • コンテナランタイム: containerd
      • サービスメッシュ: Istio
    • 「宣言的設定」と「APIセントリック」が特徴
    • 分散システム
      • 分散システムの設計と運用は、例外処理との戦い
    • kubectl
      • Kubernetesクラスタの状態を確認したり、構成を変更したりするためのもの
      • 認証
        • ~/.kube/configに書かれている情報をもとにクラスタへ接続する
        • 接続先のサーバ情報や認証情報
      • kubectl コマンド タイプ 名前 フラグ
        • リソース: Kubernetesでは、コンテナアプリケーションであれネットワークであれジョブの実行であれ、全てリソースという抽象化した概念で管理する
        • 名前: リソースには識別するための固有の名前がついている

Kubernetesのサーバ構成

  • ハードウェア構成
    • クラスタを構成するマシンはMasterとNodeの二種類
    • Masterは奇数台。(etcdの特性に起因)

Kubernetesクラスタへのデプロイの仕組み

  • ① Masterに対してデプロイすべきコンテナのイメージや個数などの情報を指示する
    • Masterが提供するAPIサーバーに対してRESTでリクエストを送信(通常はラップしたkubectl)
  • ② Masterは指示された構成情報をetcdに永続化する
  • ③ Masterは情報に基づいて、コンテナをデプロイすべきNodeを決定する
    • MasterのSchedulerが、コンテナなどのリソースをどのNodeにデプロイするかを決定する
  • ④ MasterはNodeに対してコンテナの実行を指示する
    • NodeのKubeletがMasterと通信
  • ⑤ Nodeは必要に応じて指定されたコンテナイメージをpullしたうえで実行する
    • MasterのContoroller Manager
      • 指定したコンテナが、指定した個数だけ稼働しているかチェックしてくれる
      • リソースの変更を監視しており、変更を検知すると必要なコントローラを実行してくれる

Kubernetesコンポーネント

f:id:noko_htn:20200725143009p:plain

  • Master
    • API Server
      • リソース情報を管理するためのフロントエンドのREST API
      • コンポーネントからリソースの情報を受け取りデータストア(etcd)上に格納する
      • API Serverへのアクセスは基本的にkubectl
    • Scheduler
      • PodをどのNodeで動かすかを制御する(Podの配置先の割り当て)
    • Controller Manager
      • クラスタの状態を監視し、あるべき状態を維持する
      • 定義ファイルで指定したものと実際のNodeやコンテナで動作している状態をまとめて管理する
    • データストア(etcd)
      • どのようなPodをどう配置されるかなどの情報を持ち、API Serverから参照される
      • マニュフェストの内容が保存される
  • Node
    • kubelet
      • エージェント
      • Podの定義ファイルに従ってコンテナを実行したりストレージをマウントしたり
        • Nodeのステータスを定期的に監視、API Serverに通知する
    • kube-proxy
      • 様々な中継、変換を行うネットワークプロキシ

Kubernetesのリソース

アプリケーションの実行

  • Pod
    • Kubernetesではコンテナを素の状態でデプロイしない
    • 一個以上のコンテナを包含する「Pod」という単位でデプロイする
    • 「1コンテナ:1プロセス」を守りつつ複数プロセスを協調動作させるための仕組みがPod
    • Pod内の全コンテナが同一のNodeにデプロイされることが保証される
    • Pod内の複数のコンテナで仮想NIC(プライベートIP)を共有する
    • localhostでコンテナ間が通信できる
  • ReplicaSet
    • Deploymentとの使い分けに注意
    • オートヒーリングの機能を実現するためのリソース
    • Podを直接デプロイすることもできるが、Podに障害があっても自動回復しない
    • -> ReplicaSetは、稼働しているPodの数がreplicasと一致しているかどうかをチェックする
    • = クラスタ内で指定された数のPodを起動しておく仕組み
    • クラスタ内にPodをいくつ起動しておくかの値をレプリカ数と呼ぶ
    • もしPodが一つ異常終了したら、すぐに新しい別のPodを一つ起動する
    • Podのヘルスチェック
  • Deployment
    • 単純なアプリケーションのデプロイは、Pod・ReplicaSet・Serviceでいい。
    • -> Podを一つずつ更新していく、ローリングアップデートやロールバックを宣言的に行う仕組み
    • -> Deploymentを利用する場合は、ReplicaSetを明示的に作成せず、Deploymentによって自動的に生成されたものを利用するようになります
    • ReplicaSetの履歴を持つことで、ローリングアップデート・ロールバックを可能にする
    • Deployment作成コマンド
      • kubectl create -f nginx-deployment.yaml --record
  • DaemonSet
    • ReplicaSetは、どのマシンに配置されるが分からないが、どのノードにも配置したいPodがある
    • ログコレクタなど
    • 実はkube-proxyもこのDaemonSetを利用して動いている

ネットワークの管理

  • Service
    • ネットワークを管理する仕組み
    • PodにアサインされるIPはランダムに割り当てられる
    • -> Serviceはあるサービスの入り口となり、複数のPodで構成されるサービスを代表する
    • いくつか種類がある
      • LoadBalancer
        • Serviceに対応するIPアドレス+ポート番号にアクセスすると、複数のPodに対するL4レベルの負荷分散が行われる
    • Cluster IP と External IP
      • Cluster IP: クラスタ内のPod同士で通信するためのプライベートIP。
      • External IP: クラスタの外部に公開するIP。環境変数として参照できる。
    • External Service
      • RDBに接続するなど、PodからKubernetes外のサービスにアクセスするための仕組み
      • 外部サービスをクラスタ内のサービスと同様に扱うことができる
  • Ingress
    • L7の機能を提供

アプリケーション設定情報の管理

  • ConfigMap
    • 環境依存情報をコンテナイメージに含めてしまうと、環境ごとにコンテナイメージをビルドし直すことになり、ポータビリティが損なわれてしまう
    • -> 環境情報はConfigMapに分離しておく
    • ボリュームとしてマウント、環境変数やPod定義のパラメータとして参照する
  • Secret
    • 特殊なConfigMap
    • バイナリデータを格納(Base64エンコード
    • データはメモリ上に展開される(ディスクに書き込まれない)
    • 暗号化された状態でetcdに書き込まれる

バッチジョブの管理

  • Job/CronJob
    • Podは停止=異常終了だが、JobまたはCronJobは停止=ジョブの終了
    • ReplicaSetのバッチジョブ対応版
    • なぜJobを使うのか
      • Node障害時に別のNodeで実行
      • プロセス異常終了時の再起動
        • 処理が成功するまで、JobコントローラがPodを作り直す
      • タイムアウト
      • 実行回数と並列度

その他のリソース

  • ボリューム系
    • emptyDir
      • Podと同じライフサイクル
      • Podの消滅時に削除される
      • -> 同一Pod内の複数コンテナ間でのファイル共有のために利用される
    • 外部ストレージ
      • NFSAWS EBSなど
      • Podの定義の中で、ボリュームの定義 -> コンテナのvolumesMountsの定義から参照し、コンテナ内のマウントパスを指定、もできる
      • -> が、Pod定義が環境依存になるので、PersistentVolumeを使う
    • PersistentVolume
      • 外部ストレージを、Podから見て抽象化
      • 利用フロー
        • インフラ担当がNFSなどを用意
        • -> クラスタ担当がPVとしてKubernetesに登録
        • -> アプリケーション提供者がPVCを作成
        • -> KubernetesがPVCの条件に合致するPVがあればPVCとPVをバインドする
      • -> が、クラスタ管理者がPVを事前に準備しておく必要があるので、ダイナミックプロビジョニングを使う

Kubernetesの運用

拡張性

  • HorizontalPodAutoscaler(HPA)
    • 指定したメトリックをコントローラがチェックし、負荷に応じて必要なPodのレプリカ数になるよう自動でPodを増減する
    • Metric Serverを使ってリソースの使用状況を収集する
    • マニュフェストとしては、kindがHorizontalPodAutoscalerで、scaleTargetRefにスケールするReplicaSetを指定する
    • メトリックの収集は、Nodeで動くkubeletのcAdviserというエージェントで行う
    • メトリックをまとめて管理するのがMetric Server。Podの一つとして動いている。収集したメトリックの情報はメモリ上で管理する。
  • ノードのスケール
    • HPAとCluster Autoscalerは共存できる
    • 自動スケールのメトリックとして、外部のメトリックを使ったりもできる
      • メッセージキューを使うことが多い

運用作業

  • バージョンは、MasterおよびNodeの両方に気を配る必要がある
  • NodeのバージョンがMasterのバージョンより3つ以上古くなると、そのNodeは正しく動作しない場合がある
  • サーバのアップデート=OSや導入しているパッケージのアップデートを指す
  • unattended-upgradesパッケージを使ったり
  • 再起動をどうするかがポイント
    • Cordon/Uncordon/Drain

監視

  • Liveness Probe

その他

  • アドオンコンポーネントのPodはMasterではなくNodeに配置される
  • リソース分離で一番分かりやすいのはクラスタの分離。次に大きいのはNameSpace。
  • User Account と Service Account
    • Kubernetesは「人」を管理する仕組みがない
    • 一般ユーザを管理せず、統合管理できる外部のID管理システムにそれを任せている

Kubernetesの設計のポイント

  • ラベルのルール
    • 本番/開発環境
    • プロジェクト
    • GPU付き
  • リソース分離
    • NameSpace
      • プロジェクト
      • defaultは使わないように?
  • NodeSelector
  • Resource Requests
    • Podをスケジューリングするときは、実際のノードの使用量をチェックするわけではない
  • Limit Range
    • Namespaceで動く一つ一つのPodのリソース上限(総量ではない)
  • ResourceQuota
    • 総量を制限
  • 監視
    • メトリックバックエンド、ログ収集、ログバックエンド、可視化、アラート、サービス監視(外形監視)、オールインワン