Kubernetes 入門
複数ホスト間でもコンテナな環境を統合的に管理することができるKubernetesについて、以下の構成でまとめました。
アーキテクチャ
リソース種類
マニフェストの設定
kubectlの使用方法
トラブルシューティング
監視(Prometheus+Grafana)
EKS固有
Architecture
Components
大きく以下のコンポーネントで構成
Control Plane
kube-apiserver : Kubernetes APIを受けるAPI Server
etcd : 全クラスターのデータを保存する一貫性と高可用性を備えたKVS
kube-scheduler : 新たに作成されて、未割り当て状態のノードを監視し、それらをkube-apiserverにリクエストを送ってスケジューリング
kube-controller-manager : プロセス制御。Node controller, Replication controller, Endpoints controller, Service Account & Token controllersを含む
cloud-controller-manager : クラウド固有の制御ロジックを埋め込み、クラウドプロバイダーAPIとクラスターを関連付け
Node
kubelet : Pod上でコンテナの起動や停止を管理
kube-proxy : Serviceリソースが作られた際にClusteIPやNodePort宛のトラフィックがPodに転送
Container Runtime : コンテナを稼働させるソフトウェア。Docker, containerd, CRI-O等
各コンポーネント詳細については、Kubernetes Components を参照
Diagram

(Reference) Kubernetes Components
Resources
Overview
リソースは大きく以下の5種類。詳細はConceptsを参照。
Workloads : クラスター上にコンテナを起動させるのに利用するリソース
Pod
ReplicaSet
Deployment
StatefulSet
Job
CronJob
Discovery & LB : クラスター上のコンテナに対するエンドポイントの提供やラベルに一致するコンテナのディスカバリーに利用されるリソース
Service : L4ロードバランシング
ClusterIP
NodePort
LoadBalancer
Headless
ExternalName
Ingress : L7ロードバランシング
Config & Storage : コンテナに対して設定ファイル、パスワードなどの機密情報などをインジェクトしたり、永続化ボリュームを提供したりするためのリソース
Secret
ConfigMap
PersistentVolumeClaim
Cluster : セキュリティ周りの設定やクォータの設定等、クラスターの挙動を制御するリソース
Node
NameSpace
PersistentVolume
ResourceQuota
ServiceAccount
Role
ClusterRole
RoleBinding
ClusterRoleBinding
NetworkPolicy
Metadata : クラスター上にコンテナを起動させるのに利用するリソース
LimitRange
HorizontalPodAutoscaler
PodDisruptionBudget
CustomResourceDefinition
(参考) Kubernetes完全ガイド
Example
Workloads
PodがWorkloadsリソースの最小単位となります。Podのマニフェストファイルの例は以下のようになります。
それに対してReplicaSetによりPodのレプリカが作成され、指定した数のPodを維持し続けるようにします。 spec.template,spec.containersでPod定義を行います。
そして、Deploymentが複数のReplicaSetを管理することで、ローリングアップデートやロールバック等を実現します。 spec以下でReplicaSetの定義を行い、spec.template.spec.containers以下でPod定義を行います。
ReplicaSetで起動したインスタンスに対してリクエストを割り振るには、Serviceリソースでロードバランサーの作成を行い、こちらのエンドポイントに対してアクセスすることで可能です。
実際にEKSでKubernetesのクラスターの作成を行い、Auto Scalingで起動したインスタンスをNLBでリクエストを受けるような構成の組み方は以下を参照ください。
EKSを利用してKubernetesでSpring MVCをデプロイ(NLB + Auto Scaling)
Serviceリソース、Secretリソース、Deploymentリソースを使用します。マニフェストファイルのみの概要を説明すると大きく以下の3つに別れます。
NLBの設定
機密情報の受け渡し設定
コンテナ設定
NLBの設定のマニフェストファイルについては以下のようになります。
service-nlb.yaml
機密情報の受け渡し設定のためのマニフェストファイルについては以下のようになります。YAMLファイルとして作成する場合は、Pod上から呼び出す名前の変数名に対してBase64でエンコーディングした値を設定することがポイントとなります。この例では、サンプルのエンドポイントに対してBase64でエンコードしたものを記載していますが、実際にはデコードはかなり容易なため管理には注意ください。
secret-mywebsite.yaml
PodがWorkloadsリソースの最小単位となります。それに対してReplicaSetによりPodのレプリカが作成され、指定した数のPodを維持し続けるようにします。そして、Deploymentが複数のReplicaSetを管理することで、ローリングアップデートやロールバック等を実現します。
Pod定義部分のenv以下でアプリケーションから読み込む環境変数名と先ほどSecretで指定した変数名と関連付けます。Secretリソースの機能を使用せずに直接値を指定する場合は、valueFrom:の代わりにvalue:で目的の値を指定します。
deployment-mywebiste.yaml
Kind
YAMLファイル中のkindで指定するオブジェクトの種類一覧
Binding
ComponentStatus
ConfigMap
Endpoints
Event
LimitRange
Namespace
Node
PersistentVolume
Pod
PodTemplate
ResourceQuota
Secret
ServiceAccount
Service
APIService
ControllerRevision
DaemonSet
Deployment
ReplicaSet
StatefulSet
TokenReview
SubjectAccessReview
CronJob
Job
Lease
ENIConfig
Event
DaemonSet
Deployment
Ingress
NetworkPolicy
PodSecurityPolicy
ReplicaSet
Ingress
NetworkPolicy
RuntimeClass
PodDisruptionBudget
PodSecurityPolicy
ClusterRoleBinding
ClusterRole
RoleBinding
Role
PriorityClass
CSIDriver
CSINode
StorageClass
VolumeAttachment
kubectl api-resources
kubectlからAPIを通して操作できるKubernetesのリソース一覧 (kubectl Version: 1.18.2)
KubernetesのapiVersion
マニフェスト中のapiVersionは、[APIGROUP]/<[APIVERSION]の形式で記載します。[APIGROUP]はkubectl api-resourcesコマンドの結果で各種リソースがどのAPIグループに対応するか確認できます。APIグループが空欄の場合はコアグループに属し、[APIVERSION]のみの形式となります。
(参考) Kubernetesの apiVersion に何を書けばいいか
kubectl
Use case
ローカルからコンテナで稼働しているサービスにアクセス
ローカルマシンのポートからDeployment,Service,Podへポートフォワード。kubectl proxy はローカルマシンのポートとAPIサーバーのポートをポートフォワードするためのもの。
シェルを取得
クラスターの切り替え
コンテキストに登録されているクラスター一覧の取得
現在のコンテキストを確認
コンテキストの切り替え
Others
全namespaceの詳細を把握
-Aで全namespaceの情報、-o wideオプションでより詳細に情報表示
Podのログ確認
コンテナから標準出力された内容を確認できます。
直近1時間のイベント確認
リソースの詳細表示
以下の形式でリソースの詳細を確認できます。例えば、Podの場合、kubectl describe pods deployment-mywebsite-68b6fbcd95-bvjr9コマンドのように実行することでイベントを含めた詳細情報を確認できます。
Useful Links
Get Started
Reference
Cheetsheet
Troubleshooting
共通
以下のコマンドの結果
Podのリスト取得
kubectl get pods -A -o wide
全Pod情報の詳細取得
kubectl describe pods -A
全リソース情報取得
kubectl get "$(kubectl api-resources --namespaced=true --verbs=list -o name | tr "\n" "," | sed -e 's/,$//')" -A
ワーカーノードのリスト取得
kubectl get nodes -o wide
全ワーカーノード情報の詳細取得
kubectl describe nodes
kubectlの接続性の調査 : デバッグレベルを上げてHTTPレイヤーのレベルで確認
kubectl get pods --v=9
ワーカーノードの接続性の調査
kubeletログ
sudo journalctl -u kubelet > kubelet.log
Dockerログ
journalctl -u docker > docker.log
/var/log/messages
Amazon VPC CNI PluginのL-IPAMDの動作の調査
CNI Log Collection Toolより生成した/var/log/aws-routed-eni/aws-cni-support.tar.gz
kubeletログ
sudo journalctl -u kubelet > kubelet.log
RBAC認証テーブルの調査 : IAMユーザーとKubernetesのRBACの関連付けを管理
kubectlコマンドの実行に失敗するマシンにて以下のコマンドの結果
aws sts get-caller-identity
管理者IAMエンティティを使用して以下のコマンドの結果
kubectl describe configmap -n kube-system aws-auth
Podの調査
Pod のログ
kubectl logs <Pod name>
終了した Pod のログ
kubectl logs <Pod name> -p
(EKS) Control Planeのログ
Kubernetes API server component logs (api)
Audit (audit)
Authenticator (authenticator)
Controller manager (controllerManager)
Scheduler (scheduler)
その他確認事項
マニフェストYAMLファイル
Helmチャート
(参照) Amazon EKS control plane logging
Podが起動しない
コンテナログ
アプリケーション側に問題がある場合
アプリケーションから標準出力したログ
kubectl logsコマンド
Kubernetesの設定やリソース設定に問題がある場合
kubectl describeコマンド
コンテナのシェル上で確認
起動したアプリケーションが停止することによるPodの実行停止を避けるために、アプリケーションのENTRYPOINTを上書きして一時的にコンテナを立ち上げ
kubectl run --image=nginx:1.12 --restart=Never --rm -it sample-debug --command -- /bin/sh
ログ収集
ワーカーノード上で以下を実行
一応、CNI ログ収集ツールというのもあるが、基本的にEKS Log Collectorを使用
Useful Links
Amazon VPC CNI Plugin
設計
リソース設計
eksctlコマンドでは、Control Planeに加えて、オプション次第でワーカーノードやVPC環境の作成を行います。
VPC環境は別途CloudFormationやTerraformで管理する場合やマニュアルでカスタマイズした環境を使用する場合にはkubectlとは別に作成するといった対応が可能です。
ワーカーノードを別個管理する場合、--without-nodegroupオプションを指定してノードグループを作成せずにEKSクラスターを作成し、eks create nodegroupコマンドでノードグループの作成を行います。
マニフェスト設計
マニフェストファイルは1つのファイルに複数のリソースを記述することもできます。その場合、上から順に実行されます。途中で文法エラーなどの問題が発生した場合にはそれ以降のリソースは適用されません。
kubectl apply -f ./ -R コマンドとすることで複数のマニフェストファイルを一つのコマンドで適用することもできます。その場合、ファイル名の順に適用されるため、インデックス番号等をつけておくことで順番制御できます。
1つのマニフェストファイルでエラーが発生しても他のマニフェストファイルは実行されます。
リソース間の制御や厳密な実行順序制御をする必要がある場合は、複数のリソースを一つのマニフェストファイルに分けていただき、設定ファイルやパスワードなどConfigMapやSecretリソースなど共通で利用するものはマニフェストファイルを分割するといった形で対応します。 1つのディレクトリで一括管理することや、サブディレクトリごとに管理、もしくはマイクロサービス毎に管理するなど管理体制に合わせて管理方法をわけることもできます。
モニタリング
Container Insightsの導入
用意されたコマンド1つで、CloudWatchエージェントとFluentdをDaemonSetによってPodをサイドカーとして配置することで導入します。
メトリクスとログをCloudWatchに送信できるようにするために、EC2にアタッチされているIAMロールを確認し、こちらにCloudWatchAgentServerPolicyのポリシーをアタッチします。例えば、eksctl-mywebsite-cluster-nodegrou-NodeInstanceRole-XXXXXXXXXXXXのような名前のIAMロールになります。
mywebsite-clusterというクラスター名で、us-west-2のリージョンを使用している場合は、以下のように実行することで導入準備完了です。これはmetric_name{"tag"="value"[,...]} valueのようなPrometheusの形式となります。
Amazon EKS での Container Insights のクイックスタートセットアップ
Control PlaneのメトリクスをPrometheusでグラフ表示
APIサーバーに対して、/metricsのパスにHTTP APIでメトリクスの生データを参照することができます。
Helmを使用するため、インストールしていない場合、Amazon EKS での Helm の使用等参照して利用できるようにしておきます。
MacOSの場合、Homebrewでインストールできます。
brew install コマンド実行後、バージョン確認できます。
Helmのバージョン3には自動でstableレポジトリがインストールされないため、stableレポジトリを追加します。 (参照) (Optional) Set Up Sample Containerized Workloads for Prometheus Metric Testing, Quickstart Guide
Prometheusをインストールします。
Deploymentをポートフォワーディングします。
Podをポートフォワーディングすることでも問題ありません。
http://localhost:9090 にアクセスすることで、Prometheusの画面を見ることができます。
"- insert metric at cursor -"から対象のメトリクスを選択して、"Execute"を選択します。すると、Consoleタブ上に各要素のログが出力されます。 Graphタブに切り替えることでグラフとして見ることができます。
(参照)Prometheus を使用したプレーンメトリクスのコントロール
Prometheus + Grafanaの連携
ユーザー名はAdmin、パスワードは以下のコマンドの出力
アクセス先のELBが出力されます。
Kubernetes cluster monitoring (via Prometheus)のダッシュボードを表示できるようにします。
PrometheusからのデータをGrafanaに取り込むために、画面右側の"+"マークを選択
"Import"を選択
Grafana.com Dashboardに"9135"を入力して"Load"
Folderとして"General"、prometheusの項目に"Prometheus"を選択して"Import"を選択。
同様にして、9144を入れることでKubernetes pod monitoringをインストールできます。 7279を入れることでCoreDNSのダッシュボードをインポートできます。
Container InsightsによるPrometheusメトリクスのモニタリング(Beta版)
こちらはBeta版の機能となりますので、利用の際には十分に理解の上で実施ください。
EC2にアタッチされている、例えば、eksctl-mywebsite-cluster-nodegrou-NodeInstanceRole-XXXXXXXXXXXXのような名前のIAMロールを確認し、CloudWatchAgentServerPolicyのポリシーをアタッチしていなければアタッチする。
以下を実行するのみ。
以下のようにPodが稼働していることを確認できます。
CloudWatchエージェントで他のワークロードからメトリクスを取得するために、prometheus-eks.yamlをダウンロードしてきて、追加で取得するメトリクスの設定を記載します。
logs.metrics_collected.prometheus.emf_processor.metric_declaration[]以下に以下を追記します。
元からあったリソースは削除して編集後の内容を適用します。
JMX Exporter等を利用することで、Container InsightsがJVMやTomcatなどからもPrometheusのメトリクスを取得できるようになります。
JMX Exporterのエージェントファイルをダウンロードしてきます。
JAVA_OPTSの環境変数の設定を行います。
setenv.sh
JMX Exporterの設定ファイルを作成します。ここでは、ドキュメントの例をそのまま使用していますが、詳細はJMX ExporterのREADMEを参照
config.yaml
次にwarファイルをTomcatで稼働させていたWebアプリケーションのDockerfileの編集を行います。
元のDockerfileは以下の内容でした。
こちらに以下の4行を追加します。
変更後のDockerfileは以下の内容になります。
上記内容からDockerイメージを作成して、Kubernetesのクラスターにデプロイします。
すると、以下のようにPodに対して9404番ポートにアクセスすることで、Prometheus形式のメトリクスが取得できるようになっていることを確認できます。
この9494番ポートはprometheus-configのConfigMapで定義されています。
また、Podの定義にPrometheusのサービスディスカバリー用のアノテーションを追加します。
prometheus.io/scrape
Podをスクレーピングの対象にするか
prometheus.io/port
Prometheusメトリクスを取得できるポート
prometheus.io/path
Prometheusメトリクスが/metricsのパスで取得できない場合に取得
例えば、Deploymentリソースを使用している場合、以下のように定義します。
GrafanaにKubernetes JMX Dashboardを追加します。前述の要領で11131を追加して読み込むことで監視可能です。
EKS
ConfigMap
aws-authはkube-systemのnamespaceに属するConfigMapでIAMエンティティをRBACを関連付け。EKSクラスターにアクセス可能なIAMユーザーやIAMロールの追加に使用 クラスターのユーザーまたは IAM ロールの管理
IAMユーザーやIAMロールにsystem:mastersのグループに追加することで管理者権限を付与
ConfigMap中で以下に対応付けを記載します。
IAMユーザー : mapUsers
IAMロール : mapRoles
DaemonSet
aws-nodeはkube-systemのnamespaceに属し、Podを起動し、Amazon VPC CNI PluginというNetworking Pluginが呼び出される。
Amazon VPC CNI Pluginは以下の2つで構成
CNI Plugin
ホストネットワークの接続 (例: インターフェイスと仮想イーサネットペアの設定) とPod名前空間への正しいインターフェイスの関連付け
L-IPAMD (Local IP Address Managed Daemon)
インスタンスへの Elastic Network Interface の接続
Elastic Network Interface へのセカンダリ IP アドレスの割り当て
スケジュールされた際に Kubernetes ポッドに割り当てるために各ノードにおける IP アドレスの「ウォームプール」の維持
CNI
コンテナにおけるネットワークインターフェイスを構成するプラグイン
種類
Calico : レイヤー3の仮想ネットワークを構成可能
Cilium : 負荷分散、プロトコルのフィルタリングが可能
CNI-Genie : 複数NICに異なるプラグインを割り当て、同時利用が可能
Contiv : ポリシーベースの管理、ACL、QoS
Infoblox : 複数のrktホストに対応
Linen : 仮想スイッチを作成し、VXLANを構成可能
Multus : 複数のCNIプラグインのグループ化が可能
Nuage : オーバーレイネットワークを提供。Mesos, Kubernetes, OpenShiftに対応
Romana : フラットなL2,L3に対応
Silk : L3オーバーレイネットワークを提供
Weave : オーバーレイネットワークを提供
(参考) Docker実践ガイド 第2版
Kubernetes Dashboard
Kubernetes Dashboardではメトリクスサーバーを使用するためデプロイ。
Dashboardのデプロイ
Dashboardへのユーザーのアクセス制限があるため、eks-admin サービスアカウントおよびクラスターロールバインディングを作成して、管理者レベルのアクセス権限による接続をします。
eks-admin-service-account.yaml
認証のためのトークンを取得します。
プロキシでローカルからブラウザでアクセスできるようにします。
以下のURLにアクセスします。
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#!/login
認証方法でKubeconfigとTokenが選択できますので、Tokenを選択肢、先程取得したトークンを貼り付けて、サインインします。
(参考) チュートリアル: Kubernetes ダッシュボード (ウェブ UI) のデプロイ
Addon
Operation
補完
補完システムをアクティベートする。
補完を有効にする。
予め、補完システムをアクティベートしておかないと以下のエラーになる。
Links
GitHub
Tools
Best Practice
Architecture
Get Started
Last updated