誤字脱字がたくさんあると思うが、記念に貼っておく。
画像の部分は貼れなかったorz
-
Dockerfileの命令をKubenetesで上書き、記載のうまい分離方法
-
DockerとPodのネットワークについて
-
spec.containers.commandで指定されたコマンドはプロセスID=1で実行される。SIGKILLシグナルを送信しても、停止できないので、sh -c でシェルを起動してsleepコマンドを実行する
-
ワンライナーとリソース
-
kubectl run でdeployment
-
kubectl expose でService
-
ENTRYPOINT=command,CMD=args
-
command: ["/bin/sleep"] プロセスID=1で実行。SIGKILLシグナルでもプロセスは停止できない
-
args: ["3600"]
-
シェルから別プロセスを起動する
-
command: ["sh", "-c"]
-
args: ["$(sleep 3600)"]
-
停止する kubectl exec --it sample-job -- sh -c 'kill -9 `pgrep sleep`'
-
PodとEmptyの実験
-
service とエンドポイントのIPとポート番号について
-
k descirbe serivce nginx-svcでエンドポイントはIPとポート番号 これは「PodのIPである」
-
serivceでselectorの設定がうまくいってないと、空になる
get フィルター シェル変数に入れるときに便利
-
go-templateを使う
-
kubectl get pods -o go-template='{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'
コンテナ内でコマンドを実行
-
kubectl exec -it sample-pod -- ls /tmp
-
kubectl exec -it sample-pod bash
port-foward
-
kubectl port-forward sample-pod 8888:80
-
サービスやデベロップメントに的することも可能
-
1つのPodのみ転送される
kubectl logs
-
標準出力、標準エラーのログを表示する
-
リアルタイム
-
kubectl logs -f sample-pod
-
時間指定、タイムスタンプ
-
kubectl logs --since=1h,--tail=10 --timestamps=true
-
app=sample-appラベルを出力
-
kubectl logs --selector app=sample-pod
sternコマンドのインストール 色付きで kubectl logs
プラグインのインストール
-
kubectl krew install パッケージ
Podが起動しないときの対応
-
kubectl logsでコンテナログを確認
-
kubectl describeでのEventsの項目
-
kubectl run -itでコンテナのシェル上で確認する
名前解決、サービスディスカバリー
Workdirディレクトリ
-
DockerfileのWORKDIR命令
-
spec.containers.workingDirで上書きすることができる。
ReplicaSet
-
セルフヒーリング
-
Podの増減の確認
-
kubectl describe replicaset sample-rs
-
ラベルがappを表示する(app:sample-rs)
-
k get pod - L app
-
スケーリング
-
方法1
-
kubectl appy -f sample-rs.yaml
-
方法2
-
kubectl scale repliaset sample-rs --replias 5
Development
-
Replicasetを管理
-
ローリングアップデートでは
-
Rev 1のReplicaSetとRev 2のReplicaSetが共存する
-
ローリングアップデート
-
状況確認
-
kubedtl rollout status
-
変更履歴
-
kubectl rollout history deployment sample-deployment
-
kubectl rollout history deploymnet sample-deployment --revision 1
-
古いReplicasetと新しいReplicasetが確認できる
-
kubectl get replicasets
-
新しいReplicaset上でコンテナが起動したことや、ヘルスチェックを行ってくれる
-
kubectl rollout undo deployment sample-deployment --to-revision 1
-
一つ前のReplicasetが起動する
-
実際のロールバック
-
アップデート戦略
-
1 strategy.type:Recreate
-
1度すべてのPodを削除してから再度Podを作成する
-
2 strategy.type:RollingUpdate(デフォルト)
-
MaxSurge 余分なPod数
-
MaxUnavalible 一度に停止可能なPod数
DaemonSet
-
fluentdの利用とか、各ノードで1つのPodを起動させる
-
アップデート戦略
-
onDelete
-
Podの再作成(停止など)で更新される。即時でない
-
RollingUpdate
-
maxSurgeは設定不可(1つのPodが最大なので)、デフォルトはmaxUnavaliable=1
StatefulSet
-
データベースなどステートフルなワークロードに適している
-
スケールアウト、イン
-
ReplicaSetと違い、変更があった場合は、連番で0から変更していく(マスターノードに向いている)
-
スケールインは連番で最後の番号から削除する
-
ライフサイクル
-
ReplicaSetと違い、複数のPodを並行して作成はできず、1つずつ作成を行う(前のPodがReady状態になってから)
-
spec.podMnagementPolicyでデフォルトのOrderReadyからParallelに変更すると、並行してReady状態になる
-
アップデート戦略
-
onDelete(デフォルト)
-
RollingUpdate
-
1つずつPodのアップデートを行う
-
MaxSurge,MaxUnavailableは不可
Job
-
コンテナを利用して、一度限りの処理を実行させるリソース バッチ処理
-
Podの停止が正常終了と期待される用途に向いている
-
rsync,S3へのアップロードなど
-
restartPolicy
-
never Podの障害したら、新しいPodを起動する
-
意図的にcommandプロセスを終了させると、「新たなPod」が起動される
-
onFailure 再度、同一のPodを利用してJobを再開する
-
spec
-
completions: 1 成功回数1で終了する
-
parallelism: 1 並列実行
-
backoffLimit:0 失敗を許容する回数
-
成功の有無に関わらず、必ず1回実行
-
N並列で実行 タスク型のジョブ(成功回数)
-
completions=5,paralleism=3
-
3並列で実行1-->30秒後に2Pod生成(成功回数が後2なので3つは必要ない)
-
N並列での実行 ワークキュー型のJob=並列数で実行したい
-
成功回数を指定しない。並列数だけを指定数
CronJob
-
構造
-
CronJob-->Job-->Pod
-
同時実行に関する制御
-
spec.concurrencyPolicy
-
allow 前のJobの動作に関係なく、新しくjobを作成
-
Forbid 前のJobが終了していない場合に次のJobは実行しない
-
Replace 前のJobをキャンセルし、Jobを開始する
-
spec.startingDeadlineSeconds
-
開始時刻が遅れた場合に許容できる時間
-
CronJobの履歴 Jobに紐付いたPodは残っている
-
successfulJobsHistoryLimit: 5
-
failedJobsHistoryLimit: 3
-
Service
-
deploymentoを作成
-
seviceを作成
-
情報 ラベルを持ったポッド
-
カスタムカラム
-
k get pod -l app=sample-app -o custom-columns="NAME:{metadata.name},IP:{status.podIP}"
-
josn出力 jqコマンド
-
k get po nginx-deployment-595bdfc79f-b67zp -o json | jq '.status.hostIP'
-
ほぼ均等にロードバランシングされるかチェック 一時的なコンテナを作る
-
k run --image=amsy810/tools:v2.0 --restart=Never --rm -i testpod --command -- curl -s http://10.101.10.142:8080
-
払い出されるIPアドレス(ClusterIP)はServiceの作成のたびに変わる
-
つまり、IPアドレスでハードコーディングをしない
-
Service名を使って上記の例を実行する
-
k run --image=amsy810/tools:v2.0 --restart=Never --rm -i testpod --command -- curl -s http://sample-clusterip:8080
-
clusterIP サービス
-
ExternalIP Service
NodePort
-
nodeのIP:nodeportでアクセスできた
-
nodeport
-
すべてのnodeで受け付けるポート番号
-
Nodeportへの通信は自動的にClusterIPにルーティングされる
LoadBlancer service
-
metalbというものがある。LAN内のIPを払い出す
-
振り分けるNodeに障害があれば、そのノードに対してトラフィックを転送しないようにする
-
port
-
LBが払い出す仮想IPのポート
-
targetport
-
コンテナのポート
-
nodeport
-
ノード全部で待ち受けるポート
-
Nodeをスケールさせても、仮想IPで分散される
serviceの他のこと
-
2段階ロードバランシング LoadBalancer Service、NodePort Service
-
ロードバランサー⇒ノード⇒さらにバランシング⇒Pod
-
spec.externalTrafficPolicyの2つの設定
-
cluster(デフォルト) ノードに到達後にPodも含めて、再ロード・バランシング
-
3つのPodに均等的に転送される
-
確かに、同じノードにリクエストを投げると、リプライするPodが違う
-
local 再ロード・バランシングをしない
-
疑問
-
Aのノードにリクエストが来る⇒ノードをまたいでロード・バランシングされるので、3つのすべてのノードに到達する⇒無駄ではないか?3つとも応答をことなる応答を返して、アプリケーションは混乱しない?
-
Headless service
-
追記
-
通常のheadless DNS Round RobinでPodのIP アドレスが直接返ってくる
-
StatefulSetの場合のみ、Pod名の名前解決が可能 sample-statefulset-headless-0.sample-headless.default.svc.cluster.local---> 10.8.0.30
-
対象となるここの「Pod」のIPアドレスが直接返ってくるサービス
-
各Pod名でIPアドレスを取得できる
-
ClusterIPなどの複数Podに対するエンドポイントが払い出される
-
Statefulsetを使った実験
-
一時コンテナでdigでPod名だとIPアドレスが返る
-
Podに対して名前解決を行う
-
spec.hostname
-
spec.subdomain: Headless Service名と同じにする
-
ExternalName Servcie
Ingressリソース
-
基本
-
ingress contoller
-
「Contollerの機能」と「L7 LB機能」の両方を持っている
-
ingressリソースに必要なのは、Serviceリソース
-
パスベースのルーティング
-
経由してくるトラフィクにはXFFヘッダが付与されて、クライアンとIPが参照できる
-
serviceをNodePortで外部に公開できる
-
手順
-
Servcieをサービス分だけ作る type:NodePort
-
なぜか、同じ8888だけど、selectorがあるので、振り分けるPodがわかる
-
openssl
-
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout ~/tls.key -out ~/tls.crt -subj "/CN=sample.example.com"
-
service nodeport で作る
-
ingressリソースを作る
-
IngressClassでingressを分割する
-
(結果)
-
192.168.2.204:30166としてNodePortと方法しか出来かかった
-
したかったことは、host:で指定したURLでアクセスするか、INGRESS_IP/path1でアクセスする
-
Host=192.168.2.204 Path=/ From=sample-ingress-apps-2 ClientIP=10.244.3.1 XFF=
環境変数
-
環境変数 静的設定
-
env:
-
Podの情報
-
コンテナのリソース情報
-
envでresourceFieldRefで参照する
Secret
-
作成には4つのパターン
-
--from-file
-
--from-env-file
-
--from-literal
-
--f マニフェスト
-
マニフェストを作る
-
jqで確認
-
k get secret sample-db-auth -o json | jq .data.username
-
証明書を使う type=tls
-
Dockerレジストリタイプのsecret
-
k create secret docker-registory でResigtryサーバとの認証情報を作る
-
Pod内のimagePullSecretsでsecretを参照する
-
Basic認証タイプのsecret
-
SSH認証タイプのSecret
-
--from-fileオプションでキーファイルを指定する
-
secretの利用方法
-
環境変数として渡す envで特定のキーで1つずつ定義する
-
secret全体を変数として展開する
-
-
Volumeとしてマウントする
-
ファイルを用意して、ファイルにシークレット情報を書き込んで、マウントする
-
1つのキーを指定してマウントする
-
Secret全体をマウントする
configmap
-
--from-file nginx.conf
-
k get configmap sample-configmap -o json | jq .data
-
--from-literal リテラル
-
k create configmap --save-config web-config --from-literal=connection.max=100 --from-literal=connection.min=10
-
ConfigMapの利用
-
環境変数として渡す
-
-
configMapKeyRef:でKeyを指定して値を取り出す
-
確認 k exec -it sample-configmap-single-env -- env | grep CONNECTION_MAX
-
すべてのキーを渡す
-
-
Volumeとしてマウントする
-
キーのみをマウントする nginx.confをキーとして、内容をnginx-sample.confに書き込む
-
-
ConfigMap全体をマウントする
-
/config配下に nginx.confやtest.shがある
-
ConfigMapのスクリプトを実行する(マウント方式)
-
動的なConfigMapの更新
-
Volumeマウントでは kubeletのsync loopタイミング 60秒がデフォルトで、変更がある場合は入れ替える→Podの再起動が必要ない
-
環境変数の場合は、kubectl rollout restartでPodを再起動して、更新させる
Volume
-
以下プラグイン
-
emptyDir
-
Pod用の一時的な領域 ホスト領域をマウントする
-
medium:Memoryと指定するとtmpfsのメモリ領域を利用できる
-
hostpath
-
ホスト上の任意の領域をマウントできる
-
-
downwardAPI
-
Podの情報をファイルとして配置する
-
Podの情報
-
FieldRef
-
コンテナのリソース
-
resourceFiledRef
-
projected
PVとPVC
-
Dynamic Provisioningを使わないケースでは、type/environment/speedのラベルをつけて、ボリュームを指定できるようにしておく
-
アクセスモード
-
RWO
-
ROX
-
RWX
-
Reclaim Policy
-
Delete 実体は削除
-
Retain 実体は保持。再度マウントするときは、新しいPVCを作成しなくてはならない
-
PodからPVCを利用する
-
Dynamic Provisioning
-
PVCが発行されたタイミングで動的にPVが作成される→事前にPVを作成しなくてもよい。容量の無駄が生じない
-
手順
-
1 storageclassを作成する GCPではstandardというストレージクラスが作成されている
-
2 PVCを作成する
-
PVCを作成すると、PVが払いだされるので、Podがないと無駄になるので、以下のオプションで制御
-
StorageClass
-
volumeBindingMode:WaitForFirstConsumer でPodにアタッチされるタイミングでPVが作成
-
CephのRDBを使うケース
-
StorageClassにProvisiorを設定する
-
StorageClass
-
PersitentVolumeClainResizeによるボリュームの拡張
-
StorageClass
-
allowVolumeExpansion:trueを追加する
-
Podは再起動せずに、ファイルシステムの拡張が行われる
-
まとめ
-
とりあえず、動的と性的の手順を理解する
-
StorageClassのprovisionerが大事
-
pvのstorageclassは任意でOK?
-
storageClass
-
ストレージの実装ごとに管理するためのリソース
-
クラスとはPVがどのような特徴をもっているかを示す。
-
StatefulSetでPersistentVolumeClaim(volumeClaimTemplates)
-
volumeClaimTemplateを使用すると、別途PVCを定義しなくても、自動で作成される
-
replicas:2だとPVCが2つ作成されて、それぞれにPVが作成される
-
volumeMountsのオプション
-
ReadOnlyマウント hostpathで使う
-
リソースの制限
-
Deploymentのcontainersで指定する(コンテナ単位で可能)
-
cpuとメモリ
-
requests
-
リソースの下限 ほしい この基準を満たさないと、スケジューリングされない
-
limits
-
リソースの上限 ノードに指定したリソースが残っていなくてもスケジュールリングされる
-
Ephemeral Storageのリソース制限
-
消費する
-
コンテナの出力ログ(kubectl logs)、EmptyDir(Podで共有)、書き込みレイヤー
-
requests: ephemeral-storage : "1024Mi"
-
limits: ephemeral-storage: "2048Mi"
-
この値を超えると,PodはEvict(退避)される
-
EmptyDirは複数のPodに設定されているLimitsの合計を超過した場合にEvictされる
-
システムに割り当てられているリソース
-
kube-reserved
-
システムコンポーネントやコンテナランタイムへのリソース
-
kube-system
-
OSに深く関わるデーモンなどのリソース
-
User Allocated = actual usage - (kube-reserved + kube-system)
-
Eviction Mangerというコンポーネント
-
システム全体が高負荷にならないように管理する
-
Eviction Threholdを超過しないようにしている
-
soft SIGTERMシグナルが送られてPodの停止
-
hard SIGKILLを送られてPodが停止する
-
GPUなども、RequestsやLimitsが設定できるよになった
-
複数コンテナ利用時のリソースの割当
-
max(sum(containers[*],max(initContainers[*])がPodのリソース値になる
ClusterAutoscaler(CA)
-
Podが起動できるノードが存在しない場合、ノードを新規に追加する
-
Pending状態のPodができたタイミングで初めて Cluster Autoscalerが発動する
-
リリースによるスケジューリングはRequests(下限)を基準に実施
-
よって、コンテナのリソース消費量が考慮されなく、この基準で想定外でスケールする可能性がある
-
実際の使用量は10mなので、Request(下限)を超えてスケールしてしまう
-
Requestsが低いケースでも、逆にlimitsとの開きがあると、高負荷なのにスケールしないケースがある
LimitRange(リソース)によるリソース制限
-
最小値や最大値、デフォルト値
-
設定可能なリソース
-
Pod,Container,PVC(ストレージサイズの制限)
-
コンテナに対するLimitRange
-
コンテナにリクエストを100mやって、LimitRangeリソースがminで125mなのでPodが生成されなかった
-
podのリソースを調べる
-
get pod sample-pod -o json | jq ".spec.containers.resources"
-
Podに対するLimitRange
-
typeにPod
-
コンテナが利用しているリソース合計をもとに、max/minのリソースを制限
-
PVCに対するLImitRange
-
type:PersistenVolumeClaim
-
一定容量以上のボリュームが作成されないようにする
QoS Class [Pod]
-
Request/Limitsに応じて、PodにはQoS Classが設定される
-
Statusに設定される
-
oom scoreを設定するときに利用される。
-
OOM Killerによって、プロセスが停止される際の優先度の値。-1000(優先度高い)〜1000(優先度低い)
-
kube システムは-999
-
この順で停止される。
-
BestEffort(request/limisが未指定 1000),Burstable、Guranteed(両方設定で同じ値 -998)
-
QoS ClassをGuraranteedにすれば、負荷増大による周辺Podheno影響を避けられる
-
デメリットは集約率が低くなる
-
Burstable
-
RequestsとLimitsとの乖離がある場合。最悪のケースではノードが高負荷になる可能性がある
ResourceQuotaでのNamespaceのリソースクオータ制限
-
すでに作成されているリソースへは影響しない
-
クオータにかけれるもの
-
コンピュータリソース
-
ストレージリソース
-
APIリソース数
-
クオータのスコープがある
-
2つ
-
作成可能なリソース数の制限
-
新旧の記法がある
-
リソース使用量の制限
-
requestsとlimits
HorizontalPodAutoscalaer(HPA) Pod(DeploymentのReplica数)
-
PodにRequestが設定しなくてはならない
-
必要なレプリカ数
-
ceil(sum(podの現在のCPU使用率)/ targetAverageUtilization)
-
スケールアウトの式
-
avg(Podの現在のCPU使用率) /targetAverageUtilization > 1.1
-
スケールインの式
-
avg(Podの現在のCPU使用率)/targetAverageUtiliztion < 0.9
-
実施方法
-
kubectl autoscale deployment sample-deployment --cpu-percet=50,--min=1,--max=10
-
CPU以外にカスタムメトリクスを使ってスケールさせることが可能
-
Resource
-
Object
-
External
-
spec.behaviorフィールド
-
一定期間内に増減可能なレプリカ数を制限するように定義する
-
複数のポリシーを設定できる
-
selectPolicyをmaxするなどして、複数のポリシーを選択する
-
StabilizationWindowSeconds
-
レプリカ数の頻繁に増減してしまうのを防ぐ、スパイクによるレプリカ数の急減や急増をさけるための設定
VerticalPodAutoscaler(VPA)
-
CPUとメモリのリソースの割り当てを自動的にスケーリングする
-
算出される推定値のパラメータ
-
Lower Bound Requestsの推定値の下限
-
Upper Bound
-
Target Requestsの推定値
-
Uncapped Target リソース制約を無視した場合のRequestsの推定値
-
Max Allowed 割り当ての上限
-
Min Allowed 割り当ての下限
-
クラウド環境でないとできないみたい
ヘルスチェック
-
コンテナごとに行われる。どれか1つでも失敗したときは、Pod全体が失敗する
-
3種類のヘルスチェック
-
Liveness
-
コンテナが正常稼働しているか 失敗したらコンテナを再起動する
-
Readiness
-
バックエンドのデータベースとの接続が正常であるか?
-
Startup
-
Podの初回起動が完了したかの確認 他のProbeを実行し始めない
-
3種類のヘルスチェック方式
-
exec コマンド実行し、終了コードが0でなければ失敗
-
livenessProbe
-
exec:
-
command: ["test","-e","test.txt]
-
gRPC
-
コンテナ内に/bin/grpc_headth_probeバイナリーを入れておく
-
httpGet HTTP GET リクエストを実行し、Status Codeが200〜399でなければ失敗
-
HTTP GET リクエストはkubeletから実施される
-
HTTP HEADERも可能
-
tcpSocket TCPセッションが確立できなければ失敗
-
テスト liveness Probe
-
sample-healthcheckのPodを作る
-
liveness probe はindex.htmlの存在
-
kubectl exec -it sample-healthckeck -- rm -f /usr/share/nginx/html/index.html
-
kubectl get pod sample-healthckeck --watch
-
ReadinessProbeを無視したサービスの作成
-
spec
-
type:ClusterIP
-
publishNotReadAdddresses:true
-
いつ使うのか?
-
statefulsetでHeadless Serviceを利用しているときに、PodがReadyになっていなくてもクラスタを組むために各Podの名前解決が必要になる
コンテナのライフサイクルと再起動(restartPolicy)
-
コンテナのプロセス停止、ヘルスチェックの失敗(liveness Probeの失敗)
-
Always
-
コマンドの正常終了や異常終了かんけいなく、再起動する
-
OnFailure
-
コマンドが失敗したときに、再起動する
-
Never
-
正常終了の場合はCompleted状態、異常終了の場合はError
-
テスト
-
Alwaysにして、command:でexit 1にしたら、再起動を繰り返した
init Containers
-
initContainersは
-
複数実行すると上から実行される
-
Containersは
-
同時並列にコンテナが起動される
-
実験
-
initContainersで2つのコンテナでファイルを作る
-
起動後と終了直前にコマンドを実行する(postStart,preStop)
-
最低1回は実行されるが、複数回実行される可能性がる
-
起動時に必要なファイルの配置などは、Entrypointの中か、intiContainersの中で行う
-
実験
-
preStopではPodがTerminatingしている状態のときに実行されていた
Podの安全な停止とタイミング
-
起動中のPodの削除要求→Kubernetes APIサーバへ
-
非同期に「preStop処理+SIGTERM処理」
-
「Serviceからの除外処理」
-
Pod終了時のライフサイクル
-
Runinng --> Terminating -- preStop処理など -->SIGTERM処理 --> SIGKILL処理(SIGTERMでもだめなら)
-
terminationGracePeriodSeconds(デフォルト30秒)
-
preStop処理とSIGTERM処理はこの間に完了させるのが望ましい
-
kubectl --grace-periodオプションでterminationGracePeriodSecondsを変更して削除ができる
-
--forceオプション --grace-period 0 オプションも自動的に付与される
ノードの排出処理によるPodの退避(drain)
-
ノードの状態
-
SchedulingEnabledとShedulingDisabled
-
スケジューリング対象からの除外と復帰
-
除外 (既存のPodには影響はなし)
-
kubectl cordon node-name
-
復帰
-
kubectl uncordon node-name
-
ノードの排出処理でのPodの退避
-
ノードを停止するときに使う
-
気をつけること
-
preStop設定
-
gracefulPeriodの設定
-
アプリケーション側でのSGITERMシグナルハンドリング
-
Podについて
-
単体のPodは削除されるだけ
-
Depolymentならセルフ・ヒーリングされる 新しいノードでPodが起動し、新しいローカルストレージもアタッチされる(ローカルストレージは移動できない)
-
PodDisruptionBudget(PDB)リソースによる安全な退避(eviction)
-
Podの停止することができる数を制限する
-
なぜか?Deploymentでレプリカ数が同時に排出されると、サービス断が生じる
-
マッチするPodの最小起動数
-
spec.minAvailable=1 1つのPodは最低でも1つ起動している必要がある
-
spec.MaxUavailable 最大の停止数を指定
フィルタリングとスコアリング
-
スケジューリング
-
フィルタリング=Podが割り当て可能なノードかを計算する
-
スコアリング=フィルタイングされた後にノード一覧を順位付けし、最も適したノードを選択する
マニフェストによるスケジューリング
-
Affinity=特定の条件に一致する
-
Anti-Affinity 特定の条件に一致しない
ビルトインノードラベルとラベルの追加
-
ノードのビルトインラベルの確認
-
k get nodes -o json | jq ".items | .metadata.labels"
-
手動でラベルを追加する
-
ディスクの種別、CPUの速度、CPUの世代、プロダクション/ステージング/開発
-
k label node mutomasa disktype=sdd cpuspec=high
Node Affinity
-
nodeSelectorよりも高度にスケジューリングが可能
-
nodeSelector:
-
disktype: ssd
-
Podを特定のノード上へスケジューリングするポリシー
-
必須スケジューリングポリシー
-
requiredDuringSchedulingIgnoredDuringExecution
-
優先的に考慮されるスケジューリングポリシー
-
preferredDuringSchedulingIgnoredDuringExecution
-
matchExpressions:
-
- key: disktype
-
operator: IN
-
values:
-
- sdd
-
-
必須条件の中にnodeSelecctorTerms配列(OR条件)
-
その中に - matchExpressonsの配列(AND条件)
-
優先条件の中にも記載できる
MatchExpressionのオペレータとset-based条件
-
Keyラベル、オペレータ、valuesの3要素からなる
-
オペレーター
-
In A In [B,...] いずれかに一致
-
NotIn いずれにも一致しない
-
Exists A Exists []ラベルが存在するか
-
DoesNotExist
-
Gt
-
Lt
Node Anti-Affinity
-
Node Affinityのspec.affinity.nodeAffinityの条件部分を否定形の「オペレータ」を指定することで実現する
-
operator: NotIn
Inter-Pod Affinity
-
「特定のPod」が実行されているドメイン(ノード、ゾーンなど)上へPodをスケジューリングするポリシー
-
Pod定義内でspec.affinity.podAffinity
-
topologyKey=どの範囲(ドメイン)をスケジューリング対象にするか
-
app=sample-appのラベルを持つPodが実行されているノードのkubernetes.io/hostnameと同じ値を持つノードのスケジューリングする
-
NodeAffinityと同様に、
-
RequireDuringSchedulingIgnoreDuringExecutionとpreferredDuringSchedulingIgnoreDuringExcecutionがある
Inter-Pod Anti-Affinity
-
Node Anti-Affinityと違い、spec.affinity.podAntiAfinityが指定できる
TopologySpreadConstraints
-
トポロジを意識して筋斗に分散配置するスケジューリングを行う
-
maxSkew
-
ゾーンごとのPodの合計数の差分が1の制約を受けるようになる
-
ゾーンはラベルでは topologyKey:topology.kuberenetes.io/zoneとなって判断する
TainsとToleraations
-
特定のnodeにpodをscheduleしないための仕組みだ。
-
Pod側が提示(Tolerations)してノード側が許可するような形でスケジューリングされる
-
Node Affinityの場合は、「スケジューリング時のみ」で、後から合致しなくてもノードに残り続けていた
-
しかし、Tains/Tolerationsは、条件に合致したPodをそのノード上から追い出すことも可能になる
-
用途
-
対象のノードを特定の用途向けの専用ノードにする場合
-
tainsの付与
-
Key:Value:Effect
-
Effectは
-
PreferNoSchedule 可能なかぎりスケジューリングしない
-
NoSchedule スケジューリングしない(すでにスケジューリングされているものはそのまま)
-
NoExecute 実行を許可しない すでにスケジューリングされているPodは停止される(排出?)
-
kubectl taint node -l kubernets.io/os=linux env=prd:NoSchedule
-
確認する
-
kubectl describe node mutomasa
-
envをkeyとするTaintsを削除
-
kubectl taint node node-name env-
-
tolerationsをPodに設定
ServeAccount(Podのためのアカウント)
-
Serviceaccontを作成すると、Tokenと証明書が入ったsecretが自動的にできる
-
トークン
-
PodへのServiceaccountの割り当て
-
マウントされる領域
-
APIへの認証を Tokenとcacertを指定して、defautl namespaceで動作しているPodリストを取得
-
システムコンポーネント
-
クライアントライブラリーを使用(client-go)してAPIと通信する。
-
認証方式が1つある
-
1 ServcieAccountのトークンを利用する in-Cluster Config
-
pod に割り当てたServiceaccountで
-
config, err := rest.InClusterConfig()
-
clientset, err := kubernetes.NewForConfig(config)
-
config, err := cliientcmd.BuildCOnfigFromFlags("", *kubeconfig)
-
clientset, err := kubernetes.NewForConfig(config)
RBAC
-
roleで権限、serviceaccountなどのuserに対してroleを「紐付ける RoleBiding」で権限を付与する
-
レベル
-
Namespaceレベルのリソース RoleとRoleBinding
-
Clusterレベルのリソース ClusterRoleとCluserRoleBinding
-
Node,Namespace,PVなどのClusterスコープのリソース
-
/versin,/healthzなどのAPIの情報を取得するnonResourceURLに対する権限が設定できる
-
RoleとCluserRoleで
-
apiGroups、resources、verbs(権限)
-
注意 deplymentリソースは extensions/v1beta,extensions/v1beta1,apps/v1と変遷したため、複数ある
-
deployment/scaleを指定しないと、レプリカ数を変更するスケーリングができない
-
Roleの作成
-
rulesでリソースと権限を定義する
-
ClusterRoleのAggregation
-
複数のClusterRoleの定義を読み込む。ラベルを元に行われる
-
集約する側のclusterroleにかかれているルールは反映されない
-
プリセットされているClusterRole
-
k8sのコンポーネントもRBACを利用しているので、system:で始まるClusterRoleがある
-
RoleBindingとClusterRoleBinding
-
roleBindingの作成
-
roleRefでロールを指定
-
subjectでロールを紐付けるUserやServiceAccountを指定する
-
演習
-
上記のroleとサービスアカウントの権限を確認する
-
Podを作成 sereviceAccoutNameを指定する
-
-
コンテン内でdeployを作成する(権限あり)
-
kubectl exec -it sample-kubectl -- kubectl create deployment nignx --image=nginx:1.16
-
権限外なのでPodの表示はできない
SecurityContext
-
個々のコンテナに対するセキュリティ設定
-
特権コンテナの作成(linxu capabilites)がホストと同等の権限をもつ
-
Capabilitiesの付与
-
RootファイルシステムのReadOnlyの有効化
PodSecurityContext
-
Pod(すべてのコンテナ)に対するセキュリティ設定
-
コンテナが実行するEntrypointの実行ユーザの変更
-
runAsUser:65534
-
nobodyユーザでコンテナのコマンドを実行する
-
runAsNonRoot
-
rootユーザでの実行を拒否する
-
fsGroup: 1001
-
setgidが設定されて、マウントされたボリュームでGIDが1001になっている
-
通常はボリュームをマウントするとroot:rootになっている
-
sysctl カーネルパラメータの設定
-
カーネルパラメータはPod内のコンテナで共有される
-
securityContext
-
sysctls:
-
-name net.core.somaxconn
-
values: "12345"
PodSecurityPolicy
-
securitycontextで設定できる値を制限する
NetworkPolicy(リソース)
-
IngressとEgressから成り立っている
-
NetworkPolicyはネームスペースごとに作成する必要がある
-
ingressとexgressのルールごとに、3種類のPolicyを設定する
-
podSelector 特定Podからの通信を許可
-
namespaceSlector 特定のNamespace上のPod
-
ipBlock 特定のCIDR(IPアドレス)からの通信を許可
-
方式
-
クラウド インバウンドは拒否、アウトバウンドはすべて許可
-
特定のラベルを持つPodからの通信を許可する
認可・認証/Admission Control
3/39 PodPreset(リソースのひとつ)
-
Admission Controlの1つ
-
LimitRangegaPodのResource周りを埋め込むの対して、PodPresetはConfig&Storageリソースのデフォルト値を埋め込む
-
ラベルで環境変数を埋め込む
-
ラベルで/var/log/領域にPersistent Volumeを割り当てる
-
PodPreset登録後に、Podが起動する
-
4つの値
-
env
-
envFrom
-
volumes
-
volumeMounts
-
演習
Secretリソースの暗号化
-
kubesec
-
Keryingと暗号鍵を作成
-
LANG=C gpd --gen-key
-
kubesecと暗号鍵でシークレットを暗号化
-
復号化
-
LANG=C kubesec decrypt -i sample-db-auth.yaml
Helm
-
設定可能なパラメータを表示
-
helm show valus bitnami/thanos
-
インストールコマンドでパラメータを指定 --set
-
helm install test-thanos bitnami/thanos --set
-
values.yamlで指定
-
helm install test-thanos bitnami/thanos --values values.yaml
-
インストールしたchartのテスト
-
helm test test-thanos
-
設定値とテンプレートからマニフェストを作られる
-
helm template test-thanos bitnami/thanos
-
仕組み
-
chartはインストール後にはReleaseとして管理
-
Secretとしてデータは保存されるので、別途データベースは必要ない
-
一覧
-
helm list
-
chartのアンインストール(Releaseのアンインストール)
-
helm uninstall test-thanos
-
独自のchartを作成
-
helm crate sample-charts
-
リソーステンプレートが作らえる
kustomize
-
値を上書きしていくことで、最終的な設定にしていく
-
用途
-
環境ごとにマニフェストを用意
-
特定のフィールドを上書きする
クラスタへのrejoin手順
マスターノード
-
リセット
-
kubeadm reset
-
トークンのはっこう
-
kubeadm token create
-
証明書のダイジェスト
-
-
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
参加するノード
-
sudo kubeadm join 192.168.2.200:6443 --discovery-token mdqiz6.fzzlioxwe6puj8pt --discovery-token-ca-cert-hash sha256: 59daabd49cfdc762338e21ee3140b4c8e0ff44f67f671def488313ec92a2cbab
-
-
flannelのインストール
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml