はじめに
kubernetesは一般常識になってきているこのご時世なのでざっとまとめてみました。
個人的メモです。
4分類10種類のリソース
まず、よく出てくる以下の用語を覚えましょう
分類 | リソース |
---|---|
ワークロード | Pod, ReplicaSet, Deployment, StatefulSet |
サービス | Service, Ingress |
設定 | ConfigMap, Secret |
ストレージ | PersistentVolume, PersisentVolumeClaim |
(0) minikube
- まず、kubernetesを勉強していく上で環境が必要になります
- minikubeは1台のPC上で仮想的にk8s環境を構築することができる
- k8sはLinux上でコンテナクラスタを構築するためのソフトウェアなので基本的にLinuxでしか動作しない
minikubeのインストール(on Mac)
$ brew install minikube
minikube起動
$ minikube start
(1) Pod (Point of Delivery)
- Podは内部IPアドレスを持つ1つの仮想マシンのような存在
- Pod単位で起動と破棄され、永続データは保持できない一時的な存在
- k8sはコンテナを直接管理するのではなくPodを管理する
- コンテナを直接 WorkerNode にはデプロイできない→ 「必ずPodで抽象化する」
apiVersion : v1
kind : Pod
metadata :
name : nginx
nanmespace : default
labels :
app : nginx
env : study
spec :
containers :
- name : nginx
image : nginx:1.17.2-alpine
-
apiVersion
: Podの場合はv1
-
kind
: Pod -
metadata.labels
: key / valueのペア。グルーピングするために使うことができる -
spec.containers.name
: 名前 -
image
: イメージ名
api versionの全て表示
$ kubectl api-versions
Podの作成
$ kubectl apply -f pod.yaml
PodのIPアドレスを調べる
$ kubectl get pod -o wide
コンテナに入る
$ kubectl exec -it Pod名 sh
#コンテナから出る
$ exit
Podの削除
$ kubectl delete -f pod.yml
雛形を作る
$ kubectl run mydeploy --image nginx --dry_run=client -o yaml > pod.yaml
(2) ReplicaSet(RS)
- 指定したPodを起動し、その数を維持し続けるリソース
- アプリケーションのバージョン毎にRSを生成
- Podの雛形を定義し、Label Selectorという方法で管理対象を選択してRSに制御してもらう
- RSは
spec
にreplicas
,selector
,template
の3つを指定 (⭐️) - replicas : Podの複製数
- selector : label selector (
matchLabels
,matchExpressions
) - template : Pod templateを指定
apiVersion : apps/v1
kind : ReplicaSet
metadata :
name : sample
spec :
replicas : 3
selector :
matchLabels :
app : web
env : study
template :
metadata :
name : nginx
labels :
app : web
env : sudy
spec :
containers :
- name : nginx
image : nginx:1.17.2-alpine
-
spec.selecor.matchLabels
: 指定したLabelと全て一致したものが対象になる。他にはmachExpressions
#RSの取得
$ kubecctl get rs
replica数を減らす
$ kubectl scale --replicas=1 -f replicas.yml
DaemonSet
- ReplicaSetの特殊形
- 全ノードに1Podずつ配置→レピリカ数などは指定できない
- ユースケース
- 各Podが出すログを収集するfluentdや各Podのリソース使用状況やノードの状態をモニタリングするDatadogなど、全Node上で必ず動作している必要のあるプロセスで利用
(3) Deployment
- replicasetを生成・管理(こやつはPodを直接管理していない)
- ローリングアップデート
- ロールバック
-
replicas
,selector
,revisionHistoryLimit
,strategy
,template
- deploymentを変更した際は、新しいRSを作成してPodを置き換えていく
apiVersion : apps/v1
kind : Deployment
metadata :
name : nginx
spec :
replicas : 2
selector :
matchLabels:
app : web
env : study
revisionHistoryLimit : 10
strategy :
type : RollingUpdate
rollingUpdate :
maxSurge : 1
maxUnavailable : 1
template :
metadata :
name : nginx
labels :
app : web
env : sudy
spec :
containers :
- name : nginx
image : nginx:1.17.2-alpine
-
minReadySeconds
: Podが作成されてから使用可能な状態になるまでの待ち時間を指定、デフォは0s -
paused
: Deploymentの変更をポーズさせるかを指定。通常は指定する必要はない -
progressDeadlineSeconds
: Deploymentの処理の最大処理時間を指定する、デフォは600s -
revisionHistoryLimit
: リビジョンの履歴の保持を指定する、デフォ10 -
strategy
: Podを置き換える際の戦略,デフォはRollingUpdate -
maxSurge
: replicasで指定した数よりも増やしていいPodの最大数 -
maxUnavailable
: replicasで指定した数よりも減らしていいPodの最大数
RollingUpdate
strategy:
type : RollingUpdate
rollingUpdate :
maxSurge : 50%
maxUnavailable : 10%
*DeploymentはこのmaxSurge
とmaxUnavailable
を元にRolling Updateを行う
$ kubectl apply -f deploy.yml
$ kubectl get all
$ kubectl rollout history deploy/nginx
#直前に戻す
$ kubectl rollout undo deploy/nginx
#確認
$ kubectl rollout history deploy/nginx
#削除
$ kubectl delete -f deploy.yml
#ロールアウト履歴確認
$ kubectl rollout history TYPE/NAME
#ロールバック
$ kubectl rollout undo TYPE/NAME --to-revision=N
(4) Service
- IPアドレスが変動するPodに対してクライアントがアクセスするために作成するオブジェクト
- 外部に公開
- L4ロードバランサ
- エンドポイントとポートを指定してあげれば通信をPodに流してくれる
- Serviceを動かすには、転送先となるコンテナ(Pod,RS, Deployment)が必要
①ClusterIP
- クラスタ内からのみアクセス可能な仮想IPが割り振られる
- デフォルトはこれ
②NodePort
- k8sクラスタに所属していない端末からPodに通信することができる
- 公開用ポートはデフォルトで30000-32767から採番
- クライアントがノードのIPアドレスと公開用ポートに送った番号はPodのポート番号に変換されてPodにリクエストが送信される
- マニュフェストでは、spec.ports.nodePortで記述
- NodePortは外部のネットワークへポッドを公開できるが可用性が十分ではないため本番環境には適さない
③LoadBlancer
- NodePortのアクセス範囲に加えクラスタ外からも代表IPアドレスとプロトコルのデフォルトポート番号でアクセスできる
- LoadBalancerは可用性であり、HTTPやHTTPSのデフォルトportが利用できるので本番環境に適している
④ExternalName
- クラスタ内から外部のIPアドレスを名前でアクセスできる
apiVersion : v1
kind : Pod
metadata :
name : nginx
labels :
app : web
env : sudy
spec :
containers :
- name : nginx
image : nginx:1.17.2-alpine
---
apiVersion : v1
kind : Service
metadata :
name : web-svc
spec :
type : NodePort
selector :
app : web
env : sudy
ports :
- port : 80
targetPort : 80
nodePort : 30000
-
nodePort
: ノードが待ち受けるポート (クラスタ外からの通信) -
port
: Serviceが待ち受けるポート (クラスタ内からの通信) -
targetPort
: Podが待ち受けるポート(他のPodからの通信)
*k8sでは「30000」に来た通信を「80」に変換してPodに届ける
$ kubectl apply -f service.yml
#ブラウザからアクセス
http://<IP>:30000
(5) StatefulSet
- DBなどのステートフルなアプリケーションのためのリソース
- Deploymenでレプリカされた場合にPodはランダムのIDが付与されるのに対してstatefulSetはPodは順序づけされる
- Podが同名でレプリカされるので永続ボリュームを引き継ぐ
いつ使用するか?
- 安定した永続ストレージが必要な時
- 安定した一意のネットワーク識別子が求められた時
- 規則的で自動化されたローリングアップデートが必要な時
- StatefulSetはvolumechaimTemplateで指定されたchaimそれぞれに1つずつPVが作成され、Podにマウントされる
- StatefulSetが削除されてもPVCは削除されない
- 例えば、DBサーバーとしてPodを立てる際には、StatefulSetを使用(データが消失してはダメだから)
- 逆にAPIサーバーを立てるなら。永続ストレージは必要ない→ Deploymen
apiVersion : apps/v1
kind : StatefulSet
spec : (ほぼDeployment)
updateStrategy :
type : RollingUpdate
serviceName :frontend
template :
volumeChaimTemplates :(PVCテンプレート)
(6) Ingress
- 外部公開
- パスベースのLB
- SSLターミネーション
apiVersion : networking.k8s.io/v1beta1
kind : Ingress
metadata :
name : frontend
spec :
rules :
- http
paths :
- path : /
backend :
serviceName : web-svc
servicePort : 80
$ kubectl apply -f ingress.yml
$ kubectl get ing, svc, deploy
(7) PersisentVolume
- 永続データの実体
- 永続化ボリューム
- クラスタにボリュームを登録するだけのオブジェクトなので、Podから利用するにはPVCを定義する
apiVersion : v1
kind : PersistentVolume
metadata :
name : storage
spec :
storageClassName : host (ストレージの種類)
accessModes : ["ReadWriteMany"]
capacity :
storage : 1Gi
persistentVolumeReclaimPolicy : Retain (削除時動作を定義)
hostPath : :
host : "/data/storage"
type : Directory
- accessModes :
ReadWriteOnly
,ReadOnlyMany
,ReadWriteMany
- persistentVolumeReclaimPolicy :
retain
,delete
,recycle
(8) PersistentVolumeClaim
- 必要なPVがどんなものかを定義
- データ保存先はPVで抽象化して隠蔽
apiVersion : v1
kind : PersistentVolumeClaim
metadata :
name : volume-claim
spec:
storageClassName : slow
accessModes : ["ReadWriteMany"]
resources :
requests :
storage : 1Gi
その他
Taint
- Node Affinityと逆の機能でNodeへPodをスケジュールさせないための機能
- PodをNodeにスケジュールさせない / 実行させない仕組み
Toleration
- PodがNodeについているTaintを容認するかを指定する機能
cordon / uncordon
- 指定したNodeにスケジュールさせないようにするための処理
drain
- Nodeを停止させる前準備として動作しているPodを別Nodeへ退去させるコマンド
PodDisruptionBudget
- Podの最小の有効状態や最大の無効状態の数を指定する
- Podの管理対象はLabelSelectorで指定する
◆ spec.maxUnavailable : Eviction実行時にPodを無効状態にしていい最大数を指定する、絶対値か百分率で指定する
◆ spec.minAvailable : Eviction実行時にPodを無効状態にしていい最小数を指定する、絶対値か百分率で指定する
◆ spec.selector : このBudgetを適用する対象のPodを選択するLabelSelectorを指定
Service Account
- 作成や削除、権限の付与などをkubectlを通して行う
RBAC
Affinity
- Podのスケジュールについて条件を指定
①NodeAffinity : NodeにあるLabelを元にPodのスケジュール
②PodAffinity / Anti-Affinity
③Topology Key
Annotation
- オブジェクトに対してKey / valueの形式でmetadataを登録できる仕組み
- labelとほぼ同じ機能だが、selectorなどで使用されない
kubernetesコンポーネント
etcd
- クラスタ情報の保管庫
- Key-Valueストア
kube-scheduler
- Podの要求しているリソースやNodeのリソースの使用率などをみて適切なNodeを1つ選択し、PodをNodeに紐付ける
- Podに配置決めのみ行う
-
scheduling Framework
: Filter(割り当て可能な場所を見つける)とScore()が主にNodeの決定に影響している
kube-apiserver (C-planeの親玉)
- (1)ユーザー認証
- (2)Validate Request
- (3)Retrieve data
- (4)Update etcd
- (5)scheduler
- (6)kubelet
kube-conroller-manager
- k8sのオブジェクトを処理するコントローラーを実行
- ノード監視が主な仕事
- deployment, replicasett, cronjob, service(オブジェクトに対して1つのコントローラー)
kubelet (各NodeにあるAgent的なもの)
- Podの起動や停止処理を行う、Worker Nodeで稼働するデーモン
- Podを起動・管理するエージェントとも言える
- kube-schedulerによって紐づけられたPodをkubeletが認識して、そのPodを自身のNodeで起動させる
- Podやノードの状態を監視して「apiserver」にレポートを送信
- Node上にあるCNIプラグインを実行
- Static PodをMIrrorPodとしてAPI Serverに登録
※CNIプラグイン
- Podをcluster Networkに参加させるために必要な処理を実行
- (PodにNICをINSERT, NICにIPを割り当てる)
※ Static Pods
- kubeletによって直接管理されるPod
- XXXX
kube-proxy
- コンテナのネットワーク管理
- 実体はiptablesのルールを発行し、パケットの制御している
- Pod間通信、ルーティング