k8sの巻
アーキテクチャ
https://d33wubrfki0l68.cloudfront.net/2475489eaf20163ec0f54ddc1d92aa8d4c87c96b/e7c81/images/docs/components-of-kubernetes.svg
用語一覧
コントロールプレーン
クラスタ全体を管理するやつ
kube-controller-manager
kube-scheduler
kube-apiserver
kubelet
kube-proxy
コンテナランタイム
アプリケーションの最小単位
1Podは1つ以上のコンテナから成る
アプリケーションを水平にスケールする場合は複数のPodを使うべき
ネットワークとストレージはPod内で共有される
マスターとノード間の通信
マスターのAPI(k8sのAPI)を使って通信している
Service
クラスタ内外のPodへの通信を管理?するやつ
オブジェクト
spec(仕様)とstatus(状態)がある
spec
望ましい状態を定義
status
現在の状態を示し、コントロールプレーンがspecと一致するように管理する
マニフェスト
code:yaml
apiVersion: apps/v1
kind: Deployment # オブジェクトの種類
metadata: # オブジェクトを一位に特定するための情報
name: nginx
spec: # オブジェクトの仕様
replicas: 1 # pod数
selector: # 管理対象となるpodのラベル
matchLabels:
app: nginx
strategy: # pod 置き換え時の戦略
rollingUpdate: # rolling update時の設定
maxSurge: 50% # update中に複製したpod数をどれくらい超えて良いか
maxUnavailable: 0% # update中に許容する無効なpod数
type: Recreate # 全てのpodを削除してから新しいpodを作成(基本使うことはなさそう)
template: # podを作るためのテンプレート
metadata: # podにつける情報
labels:
app: nginx
spec: # podの定義
containers:
- name: nginx
image: nginx:alpine
Service
Podへの接続を担当するオブジェクト
以下の種類がある
ClusterIP
k8sクラスタ内での通信で使用する
https://d33wubrfki0l68.cloudfront.net/e786694647b32495c8cd07663f9714dc22f01db3/34991/posts/2018/k8sdojo-09/clusterip.jpg
ExternalIP
指定したノードのIPアドレス:ポートへのトラフィックをPodに転送する
ユースケース
社内ネットワークで特定IPアドレスのみ外部と接続できる状態で、ClusterIPにExternalIPを設定して外部通信できるようにする
NodePort
すべてのノードのポートを使用して、外部サーバーとの間の通信を可能にする
ClusterIPを通して、各ノードのポートにトラフィックが転送される
LoadBalancer
NodePortを作った上で、LBを作って、LB -> NodePortへの通信を転送
ExternalName
外部サービスのエイリアス
ユースケース
外部サービスのドメインが変わったとしても、ExternalNameを修正するだけで済み、Podなどの設定を変える必要がない
Non-Selector
ロードバランシング先を自由に作れるやつ
Service作成時に、Selectorを指定せず、ServiceとEndpointsを個別に作成することで実現
コンテナのヘルスチェック
以下の3種類がある
exec
httpGet
tcpSocket
ReadinessProbe
unhealthyになったら、コンテナがkillされ再作成される
LivenessProbe
unhealthyになったら、serviceのルーティングから外され通信できなくなる
コンテナはkillされない
機密情報
ConfigMap
code:sh
k create cm {name} --from-file={file}
k get cm/{name} -o yaml
Secret
Secretはbase64エンコードされた状態で保存される
code:sh
k create secret generic {name} --from-file={file}
k get secret/{name} -o yaml
引数
-from-env-file
keyとvalueの組み合わせのファイルを指定するときに使う
code:env
key=value
-from-literal
CLIでそのままパラメータを指定するときに使う
code:sh
k create cm {name} --from-literal=key1=value1 --from-literal=key2=value2
Podのステータスについて
initContainersなどがあるかどうかによって色々表示される値が異なる
コマンド
code:sh
# サービス一覧
k get service
# pod一覧
k get pods
# pod削除
k delete pod/{pod}
k delete -f xx.yaml
# podsの詳細
k describe pods
# pods作成
k create -f xx.yaml
k apply -f xx.yaml
# podのコマンドを実行
k exec {pod} -- {command}
# 複数のコンテナから成るpodでのコマンド実行
k exec -it {pod} -c {container} -- {command}
# 複数のpodから成るreplcaSetでのコマンド実行
k exec -it {pod} -- {command}
チュートリアル
multipassでminikube
code:sh
multipass launch -c2 -m4G -d40G -n minikube minikube
multipass shell minikube
kindを使ってdocker上でマルチノードのクラスタを作る code:sh
# 事前にdockerをインストールする必要がある
skanehira@gorilla github.com/skanehira/k8s.vim $ cat config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: test
nodes:
- role: control-plane
- role: worker
- role: worker
skanehira@gorilla github.com/skanehira/k8s.vim $
skanehira@gorilla github.com/skanehira/k8s.vim $ kind create cluster --config=config.yaml
Denoでk8sのAPIを叩く
code:ts
const kubernetes = await autoDetectClient();
const podList = await kubernetes.performRequest({
method: "GET",
path: /api/v1/namespaces/default/pods,
expectJson: true,
});
console.log(podList?.items?.at(0));
kindでメトリクスを取る方法
code:sh
# このままだと証明書チェックで pod を起動できないため、deployment の args に --kubelet-insecure-tls を追加
kubectl edit deployment/metrics-server -n kube-system
リソース制限
各コンテナに対してリソースを制限できる
spec.containers[].resourceにrequests.cpu/memoryとlimits.cpu/memoryを指定して制限する
requests
リソースの下限を指定
空きノードにrequestsで指定したリソース量が存在しない場合はPodが作られない
例えばノードの残メモリが100MBで、Podのrequests.memoryが120MBの場合、Podが作られない
limits
リソースの上限を指定
空きノードに指定したリソース量が存在しなくてもPodが作られる
参考資料
kube-apiserverとetcdのテスト用のパッケージ
LBについて
カスタムリソースを作るやつ
k8s道場