Google Kubernetes Engine (GKE) 道場 -入門編- に参加してきました!
フルマネージドな Kubernetes である GKE の概要や各機能について学習します。GKE の基礎的な内容から実運用で役立つベスト プラクティスについて学習します。
12/3に、Google Kubernetes Engine (GKE) 道場 -入門編- のハンズオンに参加しました。
そこでの内容を自分なりにまとめてみました。
コンテナ・Kubernetes とは
コンテナとは?
コンテナとは、あらゆる環境で実行するために必要なすべての要素を含む、ソフトウェアのパッケージです。パッケージにすることで、コンテナはオペレーティングシステムを仮想化し、プライベート データセンターからパブリッククラウド、開発者個人のノートパソコンまで、どこでも実行できます。
仮想マシンとコンテナ〜仕組みの違い
仮想マシン
- ハードウェアレベルで仮想化
- ホストマシンと独立したOSを持つ
コンテナ
- OSレベルでの仮想化
- ホストOSのカーネルを利用
コンテナの特徴
軽量
仮想マシンに比べて軽量でシンプル
数十ミリ秒で起動
ポータビリティ
様々な実行環境に対応し、デプロイメントが用意
効率性
リソース使用量が少ないコンピュートリソースを細分化し、効率的に利用可能
コンテナに関する用語
-
コンテナイメージ
- コンテナの元となるイメージ
- アプリケーション実行時に必要なファイル・設定を記載
- 複数レイヤーで構成され、再利用性・効率性が高い
-
Dockerfile
- コンテナイメージをビルドするための指示書
- ステップごとの命令文、環境変数・依存関係などを指定
-
コンテナレジストリ
- コンテナイメージの保存・管理場所
- プライベート・パブリック アクセス制御
本番環境でコンテナ利用するには
- スケーリング
- 障害復旧
- 負荷分散
- コンテナ間通信
- アップデート
Kubernetes(K8s)とは
- OSSのコンテナオーケストレーションシステム
- GoogleのBorg論文から始まり、CNCFで開発
Go言語で書かれている - "Run Anywhere"
オンプレ、クラウド、手元のパソコンでも
Kubernetesが主にできること
- コンテナを適切に実行する
- コンテナのスケジューリング(実行する場所)
- (負荷が増えたら)オートスケーリング
- (壊れたら)オートヒーリング
- (無停止で新しいアプリに置き換え)ローリングアップデート
- バッチ実行
宣言型モデルによる設定
- YAMLまたはJSONによる設定(マニフェスト)
- 「手続き」ではなく、何を達成したいか「結果」だけを宣言する
- Kubernetesはマニフェストの宣言を常に維持しようとするため、自動でシステムのあるべき状態を維持できる(e.g.オートヒーリング)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas:2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
↑ replicas: 2
Kubernetesのアーキテクチャ
- コントロールプレーン
- 管理プロセスとデータベース(API server/Scheduler/Controller manager/etcd)
- ノード
- コンテナアプリケーション(Pod)を実行するワーカーマシン
Kubernetesの基本的なリソース
Kubernetesリソースとは、APIで作成されるオブジェクトやエンティティ
Pod
Kubernetesのデプロイ単位。1つまたは複数のコンテナが含まれる
Deployment
Podのレプリカ数や世代管理を宣言的に管理するためのリソース
Service
Podをクラスタの内部/外部に公開するためのリソース
Ingress/Gateway
L7レイヤーで負荷分散するためのリソース
Pod
- Kubernetesがアプリケーションを管理する単位
- 1つ、または複数のコンテナを入れて実行
複数のコンテナをまとめるパターン- 関連するコンテナ
- 補助する役割のコンテナ(サイドカー)
Deploymentによる設定、管理
- Pod数を維持(Replicaset)
replicas: 2
の場合、Podを2つ管理 - Podの中のコンテナイメージを指定
- 無停止アップデート/ロールバック
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
labels:
name: web
app: demo
spec:
replicas: 2
templete:
metadata:
labels:
app: demo
spec:
containers:
- name: web
image: gcr.io/***/hello-app:v1
ports:
- containerPort: 5000
name: http
protocol: TCP
Service
アプリケーションのエンドポイントを提供する
- TCP/UDPをサポート(L4レベル)
- iptables/eBPFによるトラフィックコントロール
Service Types
- ClusterIP(主にクラスタ内からのアクセス)
- NodePort(クラスタ外からアクセス)
- LoadBalancer(クラスタ外からアクセス、L4ロードバランサ)
- headless(主にクラスタ内からのアクセス、Pod IPの返却)
- ExternalName(クラスタ内から外部アクセス、外部DNS名のエイリアスとして利用)
apiVersion: v1
kind: Service
metadata:
name: web
labels:
name: web
app: demo
spec:
selector:
name: web
type: LoadBalancer
posts:
- port: 80
targetPort: 5000
protocol: TCP
Ingress
アプリケーションのエンドポイントを提供する
- L7での負荷分散を提供
- パスベースルーティングなどHTTPのルーティングを実装可能
apiVersion: v1
kind: Ingress
metadata:
name: test-ingress
spec:
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: test
servicePort: 80
kubectlコマンドによる操作と管理
# podの一覧
kubectl get pods
# ノードの一覧
kubectl get nodes
#設定(マニフェスト)の適用
kubectl apply -f deployment.yaml or ./manifests/(ディレクトリ)
#ログ
kubectl logs -f mynginx-XXXXX
Google Kubernetes Engine(GKE)概要
Google Kubernetes Engine(GKE)
Googleが提供するマネージドなKubernetesサービス
- ワンクリックでKubernetesを構築
- 運用の手間を軽減するオートヒーリング、オートアップグレード、リリースチャネル
- ロギング、モニタリングなどGoogle Cloudの各種サービスとのネイティブな連携
- エンタープライズでの利用を前提としたSLAの設定、HIPAA、PCI-DSSといったセキュリティ基準への準拠
自前運用のKubernetes
- コントロールプレーンの構築&管理
- ワーカーノード構築&管理
- セキュリティ&ネットワーク各種設定
- パッチ管理&アップグレード
- モニタリング
- スケーリングなど
GKE - スタンバイモード
- クラスタの自動アップグレード
- 4次元自動スケーリング
- ノードの自動修復
- リージョナルクラスタ
+ Multi Cluster Gateway - 柔軟なメンテナンス設定
-
セキュリティベストプラクティス
- 限定公開クラスタ
- ネットワークポリシー
- Confidential GKEノード
- Binary Authorization
- VPC-SCなど
GKE - Autopilotモード
- コントロールプレーンだけでなくノードもGoogle Cloudが管理
- 本番ワークロードに適したベストプラクティスを初期適用
- セキュリティ
- ワークロード
-
ワークロードフォーカス
Pod単位での課金、PodへのSLA
GKEが提供する運用自動化
GKEは全てを自動化
K8sをスケーラブルに使うために必要なものが全て自動化されている
- 自動修復
- 問題があるノードを自動的に入れ替え
- 自動アップグレード
- Kubernetesバージョンを自動的に更新
- 自動スケールアウト/スケールイン
- 需要に応じてノード数を自動的に増減
- 自動プロビジョニング
- リソースに最適なノードプールを自動で作成・削除
Node Pool
- Node Poolは同じ設定のNode(Compute Engineインスタンス)で構成されるグループ
- 同じマシンスペック、同じOS、同じGKEバージョン
- Node数の増減やNodeのアップグレードなどはNode Pool単位で行う
- 各種自動化機能のサポート
- 自動修復、自動スケール、自動アップグレード
自動修復
NodeがUnhealthyな状態になっていることを検知し、自動的に修復プロセスを開始数r
NodeがUnhealthyと判断される例
- 約10分間、NodeがNotReadyステータスを報告
- 約10分間、Nodeがステータスを何も報告しない
- 長時間(約30分間)、DiskPressureステータスを報告、等
修復が必要なNodeが検知されると、対象のNodeをDrain後に再作成される
自動アップグレード
GKEではControl PlaneをGoogleが管理しており、自動的にパッチ適用・アップグレードされるがNodeについては自動もしくは手動でのアップグレードを選択可能(Autopilotは自動のみ)
1. リリースチャンネルを指定したクラスタ
- Control Plane: 自動
- Node: 自動
- GKE Autopilotはリリースチャンネルに登録される
2. 静的にバージョンを指定したクラスタ
- Control Plane: 自動
- Node: 自動 or 手動
- Nodeのアップグレードタイミングを自分でコントロールしたい場合は手動
リリースチャンネル
バージョニングとアップグレードを行う際のベストプラクティスを提供する仕組み
リリースチャンネルに新しいクラスタを登録すると、GoogleによりCotrol PlaneとNodeのバージョンとアップグレードサイクルが自動的に管理される
利用できる機能と更新頻度の異なる、以下3つのチャンネルがある
- Rapid ... 最新のバージョンが利用可能。検証目的での利用を推奨(SLA対象外)
- Regular ... 機能の可用性とリリースの安定性のバランス
- Stable ... 新機能よりも安定性を優先する場合
メンテナンスの時間枠と除外
-
メンテナンスの時間枠
自動メンテナンスを許可する時間枠- 32日周期で最低48時間必要
- 各時間枠は4時間以上連続した時間
-
メンテナンスの除外
自動メンテナンスを禁止する時間枠
使い方の例:
- 週末を避ける
- 大型セールやイベント期間中を避ける
- 一時的にアップグレードを延期する
HPA - Horizontal Pod Autoscaler
ワークロードのCPUやメモリの消費量等に応じて、自動的にPod数を増減させる機能
CPU/メモリ以外にも、カスタム指標や外部指標を使ったオートスケールもサポート
API versionにより、利用可能なメトリクスが異なる
- autoscalling/v1: CPU利用率のみ
- autoscalling/v2beta2: カスタムメトリクスや外部メトリクスをサポート
複数のメトリクスを利用する場合、各メトリクスで算出されたレプリカのうち最大値を選択する
VPA - Vertical Pod Autoscaler
実行中のワークロードを分析し、CPUやメモリのrequests/limits値の推奨値算出やリソース値を自動更新する機能
VPAの更新モード(UpdateMode):
- Off: 推奨値を算出するのみ
- Initial: Podの作成時に割り当て、既存Podの再起動無し
- Auto: 既存Podの再起動あり
急激なトラフィック増に対処する場合は、VPAではなくHPAを利用することを推奨
VPAを使う場合はまずupdateMode: Offで推奨値の算出から始めてみる
CA - Cluster Autoscaler
ワークロードの需要に応じてNode Pool内のNode数を自動で増減させる機能
- Node Pool内のNode数が不足しPodのスケジューリングができない場合Nodeを追加
- Nodeの使用率が低く、Node Pool内Node数を少なくしてもすべてのPodスケジューリングが可能な場合Nodeを削除
NAP - Node Auto Provisioning
ワークロードにフィットするNode Poolを自動的に作成・削除する
ノードのサイジングを含めたリソース管理をGKEに任せることができ、またワークロードにあったサイズのマシンをプロビジョニングするためインフラリソースを効率的に活用可能
GKE AutopilotではNAPを利用しPodに必要なNodeを自動的にプロビジョニングしている
PodやNodeを事前にスケールする
HPAやCAを設定していたとしても急激なトラフィック増にたいしてスケーリングが間に合わないケースもある
ある程度トラフィックが増えるタイミングが予測可能な場合は事前にPodやNodeを増やすことでリソースを効率的に扱うことができる
Discussion