2022年1月24日月曜日

k8s負荷試験(作成中)

 <攻撃ツール>
1: ボトルネックになりえないこと

以下、負荷ツールを使って調査を行う。

①Jmeter

②locust

③Gremlin




<Podレベル>
2: 想定レイテンシでレスポンスを返せること

HPAを無効(Pod単体)にして、resourceのrequestとlimitの値を増やしてどこまで要求を満たすか確認

   ->アプリケーションに問題があってレイテンシが超過する場合はアプリケーションのチューニングが必要


3: 想定スループットを満たせること

HPAを無効にしてPodを手動でスケールアウトしていき、どこまでスループットを伸ばせるかを確認。

①各PodのCPU使用率
特定のPodだけCPU使用率が偏ってる場合はルーティングポリシーの再確認

②各Podのレイテンシ
一つ前の「想定レイテンシでレスポンスを返せること」に戻って確認
攻撃側のCPU使用率
攻撃ツールのスケールアップ、スケールアウト


4: 突然のスパイクに対応できること
5: ノードレベルの障害、ダウンを想定した設定になっていること
6: 配置が想定どおりに行われていること
7: 新バージョンリリースがダウンタイム無しで可能なこと
8: 長時間運転で問題が起こり得ないこと



<クラスタレベル>
9: Pod
の集約度が適切であること
10:
配置するPodの特性に合わせたノードになっていること
11:
突然のスパイクに対応できること
12:
クラスタの自動アップグレードの設定が適切であること
13: Preemptible
ノードの運用が可能であるか


calicoインストール(再)

参照:
https://projectcalico.docs.tigera.io/getting-started/kubernetes/helm


worker nodeを新規で入れ替えたら、Master NodeからWorker Nodeに対して

Podの配布(スケジューリング)ができていないことが判明

以下の内容をみるとCNI(Calico)の問題っぽい。














<Helmでの導入>


1)レポジトリを追加する

helm repo add projectcalico https://docs.projectcalico.org/charts





2)インストールを実施

helm install calico projectcalico/tigera-operator --version v3.21.4




3)進捗状況を確認

watch kubectl get pods -n calico-system



argoCD(github:自作マニュフェスト)

 以下、自作のnginxのマニュフェストをargoCD経由でデプロイしてみる。












githubのパスを” ./ “にする。





















以下、デプロイができていることが把握できる。







Network Policy

参照先:
https://kubernetes.io/ja/docs/concepts/services-networking/network-policies/


<稼働条件>

Calico(ネットワーク用のPod)を利用していること。



Network policyについて:

Pod間のネットワークの許可及び拒否などを行えるリソース


 - Ingress         :入力に対してのルールを決める

 - Egress          :出力に対してのルールを決める

 - podSelector :podSelector(特定のPodを許可

                               —>{}は、全て適応という意味 


検証:


1)Ingress/Egressの全てのトラフィックを拒否するマニュフェストを作成して検証を行う。












2)適応後、他のPodに対してcurlコマンドを実施してみたがTimeoutになる




3)上記のnetworkPolicyを削除後に、改めてcurlを実施



2022年1月17日月曜日

2022年1月15日土曜日

Node Portについて(補足)

参照:
https://kubernetes.io/ja/docs/tutorials/services/source-ip/



NodePort:

クライアントからのトラフィックをnode portサービスで受信したら

対象のClusterIPNAT変換される仕組み。



各種Workloadsリソースについて

以下の図は、各種Workloadsの上位リソース、下位リソース関係を表す。



k8sアップグレード(for Raspberry pi)

参照:
https://v1-22.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/



課題:

以下、k8sのバージョンが古い(2022/01現在)ので最新版にアップデートをしてみます。






アップグレード中での影響について:

バージョンアップ中は、稼働中のPodが停止するなどの悪影響は起きない。

マスターノード単体の場合は、更新が完了するまで、worker nodeへの出来ないことを考慮する必要がある。



手順:

コントロールプレーン x1、worker node x2の構成になので

以下の順に、アップグレードを行う。


1)コントロールプレーンのアップグレードを行う

①レポジトリの更新を行う。

apt update








②アップグレードのリストを表示する。

apt-cache madison kubeadm











③対象のバージョンにkubeadmのアップグレードを行う。

apt-mark unhold kubeadm && \

apt-get update && apt-get install -y kubeadm=1.23.1-00 && \

apt-mark hold kubeadm










④kubeadmバージョンの確認を行う

kubeadm version




⑤アップグレード方法を確認する

kubeadm upgrade plan

(以下のアップグレードの適応方法が記載されている。)















































⑥アップグレードの実施を行う

kubeadm upgrade apply v1.23.1












⑦kubeadmのアップグレードが成功すると、以下の表示が出て完了となる。









⑧kubelet&kubectlのアップグレードを行う。

(公式には記載がないがworker Nodeとバージョンを揃えたいので実施)

apt-mark unhold kubelet kubectl && \

apt-get update && apt-get install -y kubelet=1.23.1-00 kubectl=1.23.1-00 && \

apt-mark hold kubelet kubectl



⑨kubeletを再起動する

sudo systemctl daemon-reload

sudo systemctl restart kubelet




2)Worker Node(1台目)のアップグレードを行う

①対象のworker nodeにスケジュールを禁止にする。

注意:コントロールプレーンで実施


kubectl drain rasp-node1.local --ignore-daemonsets







②rasp-node1.localにログインして、アップグレードを行う。


apt-mark unhold kubelet kubectl && \

apt-get update && apt-get install -y kubelet=1.23.1-00 kubectl=1.23.1-00 && \

apt-mark hold kubelet kubectl













③kubeletを再起動する

sudo systemctl daemon-reload

sudo systemctl restart kubelet



④対象のworker Nodeをオンラインの状態にする

注意:コントロールプレーンで実施


kubectl uncordon rasp-node1.local 






3)Worker Node(2台目)のアップグレードを行う

①上記のworker nodeと同様の作業を行う。



4)バージョンの確認を行う

対象のバージョン(1.23.1)になっていることが把握dけいる。

(以下のバージョンは、kubeletのバージョンを表す)














Pod Security Policies(廃止) ->PodSecurity

 参照:

https://kubernetes.io/docs/concepts/security/pod-security-admission/

https://kubernetes.io/blog/2021/12/09/pod-security-admission-beta/

https://qiita.com/uesyn/items/cf47e12fba5e5c5ea25f


機能:

クラスタ(NameSpace)の範囲でセキュリティを適応する機能として

Pod Security Policiesがあるがver 1.25で廃止されてPodSecurityに変更される


ポイント:

以下のようにNameSpaceにラベルにルールを記載することでセキュリティが追加される。

(NameSpaceのデフォの作成時点では、関連したラベルがないのでセキュティの設定はされてない)



ポリシーは、ラベルを介して名前空間に適用されます。これらのラベルは次のとおりです。

例)

pod-security.kubernetes.io/<MODE(enforce | audit | worn)>: <LEVEL(privileged | baseline | restricted)> 

pod-security.kubernetes.io/<MODE(enforce | audit | worn)>-version: <VERSION>(オプション、デフォルトは最新)


<MODE>

enforce:ポリシー違反により、Podは拒否されます。

audit     :ポリシー違反は、監査ログに記録されたイベントへの監査注釈の追加をトリガーしますが、それ以外の場合は許可されます。

warn     :ポリシー違反はユーザー向けの警告をトリガーしますが、それ以外の場合は許可されます。


<LEVEL>

privileged   : オープンで無制限

baseline     : 制限を最小限に抑えながら、既知の特権昇格をカバーします

restricted   : 高度に制限され、既知および未知の特権エスカレーションに対して強化されます。



検証:

公式内容を参考に、コマンドベースでの検証を行ってみる。


1)検証用のnamespaceを作成する。

kubectl create namespace pod-security-test


2)ラベリングを行う。

(以下のラベルは、Podの作成を拒否することを表している。)

kubectl label namespace pod-security-test pod-security.kubernetes.io/enforce=restricted


3)対象のNameSpaceにラベルが付与されたとを確認

















4)試しに、指定したNameSpaceにデプロイを行うと。

kubectl -n  pod-security-test run test --dry-run=server --image=busybox --privileged



5)以下、メッセージが出て作成が失敗に終わります。




6)ラベルの上書きを行ってみる。

kubectl label --overwrite ns pod-security-test \

  pod-security.kubernetes.io/enforce=privileged \

  pod-security.kubernetes.io/warn=baseline \

  pod-security.kubernetes.io/audit=baseline



7)再度、デプロイを実施する。

以下、デプロイが出来てることが把握できる。






以下のようにマニュフェストの作成でも実施可能である。







カーネルのパラメータ変更(sysctls利用パターン)

sysctls:
カーネルのパラメータの変更が可能になる。



以下、例になる。


①safe(変更しても危険度が低いカーネルの値)

  ->変更可能

②Unsafe(変更しても危険度が高いカーネルの値)

  ->公式ページを見て変更方法を探ってみたがオンプレ(Raspberry pi)での実施は出来ていない。




カーネルの変更(initContainer利用パターン)

podを供給しているnodeに影響がない状態で、initContainerを利用したカーネルの変更が可能である。



検証:

1)initContainersを利用して、sysctlコマンド(カーネルの修正用途)を使えば

対象のカーネルの値を変更することができる。




































2)上記、デプロイをしたPodに対して、対象のカーネルが変更されているいことが把握できる。






3)念の為、worker nodeにて、変更したカーネルの値を確認してみると

特に影響が出ていないことが把握できる。



sysctlコマンド

参照:
https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/



sysctlコマンド:

カーネルを設定時に利用するコマンド



1)master/worker nodeにログインする。


2)以下のsysctlコマンドで取得可能なリスト(カーネルのパラメータ)を取得する。

sudo sysctl -a



















3)以下のファイルの修正を行う。

/etc/systemd/system/kubelet.service.d/10-kubeadm.conf



EFS(Dockerfile)の記載について注意

  Dockerfileにefsのマウントパス宛に、ファイルコピーを行うと ECSのサービス作成時に、コンテナのデプロイ失敗に(container run time error)になるので 別経由で、EFSにファイルをコピーした方が良い!! <Dockerfile> ...