一年半前のk8sのお勉強メモ

誤字脱字がたくさんあると思うが、記念に貼っておく。

画像の部分は貼れなかった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

  1. 標準出力、標準エラーのログを表示する
  2. リアルタイム
    • kubectl logs -f sample-pod
  3. 時間指定、タイムスタンプ
    • kubectl logs --since=1h,--tail=10 --timestamps=true
  4. app=sample-appラベルを出力
    • kubectl logs --selector app=sample-pod
sternコマンドのインストール 色付きで kubectl logs
 

プラグインのインストール

  • kubectl krew install パッケージ
 

Podが起動しないときの対応

  1. kubectl logsでコンテナログを確認
  2. kubectl describeでのEventsの項目
  3. kubectl run -itでコンテナのシェル上で確認する
 

名前解決、サービスディスカバリー

  • k exec -it sample-pod -- cat /etc/resolv.conf
    • get service -n kube-systemでも DNS/53で確認できる
  • クラス外のDNS
 
Workdirディレクト
  • DockerfileのWORKDIR命令
    • spec.containers.workingDirで上書きすることができる。
 

ReplicaSet

  • セルフヒーリング
    • Podの増減の確認
    • kubectl describe replicaset sample-rs
  • ラベルがappを表示する(app:sample-rs)
    • k get pod - L app
  • スケーリング
    • 方法1 
      • sed -i -e 's|replicas 3|replicas: 4|' sample-rs.yaml
      • 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'
  • ほぼ均等にロードバランシングされるかチェック 一時的なコンテナを作る
  • 払い出されるIPアドレス(ClusterIP)はServiceの作成のたびに変わる
    • つまり、IPアドレスでハードコーディングをしない
    • Service名を使って上記の例を実行する
  • clusterIP サービス
  • ExternalIP Service
 

NodePort

  • ノード上にPodがない場合は、リクエストに応答できない。LoadBlancer Serviceの場合は別途ヘルスチェック用のNodePortが割り当てられるため、Podが存在しないノードにはロードバランサーからのリクエスト転送されなくなる
  • 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アドレスが直接返ってくるサービス
    • DNSラウンドロビンを使って、エンドポイントを提供する
    • 通常は、クラスタDNSPod名による名前解決は出来ない仕様となっている
      • ClusterIPなどの複数Podに対するエンドポイントが払い出される
    • Statefulsetを使った実験
    • Podに対して名前解決を行う
      • spec.hostname
      • spec.subdomain: Headless Service名と同じにする
  • ExternalName Servcie
    • Servcie名から外部ドメイン宛のCNAMEを返すことが可能
    • Service名と別の名前で解決したい
    • 外部サービスとの疎結合性の確保が可能
      • アクセス先を切り替えるにはアプリケーションの設定を変更しなくても、ExternalName serviceの変更を行うだけで可能になる
      • その後に、内部DNSによる名前解決(CNAMEを解決)をする
 

Ingressリソース

  • 基本
    • ingress contoller
      • 「Contollerの機能」と「L7 LB機能」の両方を持っている
    • ingressリソースに必要なのは、Serviceリソース
    • パスベースのルーティング
    • コントローラはingressリソースをwatchしている
    • 経由してくるトラフィクにはXFFヘッダが付与されて、クライアンとIPが参照できる
    • serviceをNodePortで外部に公開できる
  • 手順
    • Servcieをサービス分だけ作る type:NodePort
    • なぜか、同じ8888だけど、selectorがあるので、振り分けるPodがわかる
    • openssl
    • service nodeport で作る
    • ingressリソースを作る
      • pathでserviceの名前を指定する
      • serviceでpodのセレクタで振り分ける
      • host-->protocol-->path-->service
      • エラーが出てこれで対応した
        • kubectl delete -A ValidatingWebhookConfiguration ingress-nginx-admission
  • 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=
 

環境変数

 

Secret

  • 作成には4つのパターン
    • jqで確認
      • k get secret sample-db-auth -o json | jq .data.username
  • 証明書を使う type=tls
      • openssl req -x509 -nodes -days 360 -newkey rsa:2048 -keyout ~/tls.key -out ~/tls.crt -subj "/CN=sample.mutomasa.home"
    • 秘密鍵と証明書ファイルからsecretを作成する
      • k create secret tls --save-config tls-sample --key ~/tls.key --certt ~/tls.crt
    • ingresstlsを使う
        • - hosts:
        • - sample.mutomasa.home
        • secretName: tls-sample
  • 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によるボリュームの拡張
    • 対応しているボリュームプラグインは決まっているがRDBもOK
    • 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
      • リクエストが受け付けることができるか 失敗したら”Ready状態でなくなり”Serviceからトラフィックを流さない(Podを再起動しない)
      • バックエンドのデータベースとの接続が正常であるか?
    • 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をスケジューリングするポリシー
Inter-Pod Anti-Affinity
  • Node Anti-Affinityと違い、spec.affinity.podAntiAfinityが指定できる
 
TopologySpreadConstraints
  • トポロジを意識して筋斗に分散配置するスケジューリングを行う
  • maxSkew
 
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に設定
    • 上の例で言えば、Podに- key: "env" operator: "Equal" value:"prd" effect:"NoSchedule”を記載
    • オペレータは2つ
      • Equal: KeyとValueが等しい
      • Exists: Keyが存在する
      • env=prdを持ったPodでないとこのnodeにPodをスケジューリングしない
    •  
 
ServeAccount(Podのためのアカウント)
  • Serviceaccontを作成すると、Tokenと証明書が入ったsecretが自動的にできる
    • トークンを元にして、k8s APIへの認証情報として利用することができる
    • PodへのServiceaccountの割り当て
  • マウントされる領域
    • トークンや証明書が配置されて、Pod上のアプリケーションはこれらを利用して、指定されたServcieaccountの権限でk8sを操作できる
  • 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)
        • 2 kubeconfigの認証情報を指定する クラスタ外からAPIに接続したい
          • 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
 
NetworkPolicy(リソース)
  • IngressとEgressから成り立っている
  • NetworkPolicyはネームスペースごとに作成する必要がある
  • ingressとexgressのルールごとに、3種類のPolicyを設定する
    • podSelector 特定Podからの通信を許可 
    • namespaceSlector 特定のNamespace上のPod
    • ipBlock 特定のCIDR(IPアドレス)からの通信を許可
  • 方式
  • 特定のラベルを持つPodからの通信を許可する
 
認可・認証/Admission Control
  • Admission Control
    • 認証と認可を得て、リクエストの内容を許可するかどうかの判断、登録
    • 受け取ったリソースに改変を行って登録が可能
    • プラグイン形式になっている
 
3/39 PodPreset(リソースのひとつ)
  • Admission Controlの1つ
  • LimitRangegaPodのResource周りを埋め込むの対して、PodPresetはConfig&Storageリソースのデフォルト値を埋め込む
    • ラベルで環境変数を埋め込む
    • ラベルで/var/log/領域にPersistent Volumeを割り当てる
  • PodPreset登録後に、Podが起動する
  • 4つの値
    • env
    • envFrom
    • volumes
    • volumeMounts
  • 演習
    • /etc/kubernetets/manifest/api-server.yamlでオプションを追加しないとだめだ
 
 
Secretリソースの暗号化
  • kubesec
  • Keryingと暗号鍵を作成
    • LANG=C gpd --gen-key
  • kubesecと暗号鍵でシークレットを暗号化
    • LANG=C kubesec encrypt -i --key=pgp:BCD3CA9713A01978811FC8FF7973584A5C24F412 sample-db-auth.yaml
  • 復号化
    • 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のインストール