Kubernetes taint、トレランス ポリシー、優先度とプリエンプション、Pod のセキュリティ

染色

テイントは、ラベルとは対照的に、ノードとポッドを反発的にします

汚染ポリシーは、キーと値のペアに汚染タグを埋め込むことによって宣言されます

taint ラベルはキーと値のペアにバインドする必要があります。形式は次のとおりです: key=value:[taint label]

taint の翻訳は汚れの意味です

taint ラベルはキーと値のペアにバインドする必要があります。形式は次のとおりです: key=value:[taint label]

汚染タブを表示する

        kubectl describe nodes [ノード名]

汚染ラベルを設定する

        kubectl taint node [ノード名] キー=値: taint ラベル

汚染タグを削除

        kubectl taint node [ノード名] key=value: taint label-

汚染ラベル

ノードのスケジューリングは、スケジュールごとにスクリーニングしてスコアリングする必要があります

        PreferNoSchedule は、スケジュールを設定しないように試みます。残っている人がいない限り、スケジュールは設定されません。

        NoScheduleはスケジュールを組まず、上映は入れない

        NoExecute エビクション ノード

PreferNoSchedule と NoSchedule は、新しく作成されたポッドに対してのみ有効です。

NoExecute は前後の Pod に対して有効で、delete、

汚染タグを管理する

# 查看污点策略
[root@master ~]# kubectl describe nodes|grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule
Taints:             <none>
Taints:             <none>
Taints:             <none>

# node-0001 设置污点策略 PreferNoSchedule
[root@master ~]# kubectl taint node node-0001 k1=v1:PreferNoSchedule
node/node-0001 tainted
# node-0002 设置污点策略 NoSchedule
[root@master ~]# kubectl taint node node-0002 k2=v2:NoSchedule
node/node-0002 tainted

[root@master ~]# kubectl describe nodes |grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule
Taints:             k1=v1:PreferNoSchedule
Taints:             k2=v2:NoSchedule
Taints:             <none>

 Pod リソース ファイル

# 查看污点策略
[root@master ~]# kubectl describe nodes|grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule
Taints:             <none>
Taints:             <none>
Taints:             <none>

# node-0001 设置污点策略 PreferNoSchedule
[root@master ~]# kubectl taint node node-0001 k1=v1:PreferNoSchedule
node/node-0001 tainted
# node-0002 设置污点策略 NoSchedule
[root@master ~]# kubectl taint node node-0002 k2=v2:NoSchedule
node/node-0002 tainted

[root@master ~]# kubectl describe nodes |grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule
Taints:             k1=v1:PreferNoSchedule
Taints:             k2=v2:NoSchedule
Taints:             <none>

 テイント ポリシーを確認する

# 优先使用没有污点的节点
[root@master ~]# sed "s,myphp,php1," myphp.yaml |kubectl apply -f -
pod/php1 created
[root@master ~]# sed "s,myphp,php2," myphp.yaml |kubectl apply -f -
pod/php2 created
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP            NODE
php1   1/1     Running   0          13s   10.244.3.43   node-0003
php2   1/1     Running   0          5s    10.244.3.44   node-0003

# 最后使用 PreferNoSchedule 节点
[root@master ~]# sed 's,myphp,php3,' myphp.yaml |kubectl apply -f -
pod/php3 created
[root@master ~]# sed 's,myphp,php4,' myphp.yaml |kubectl apply -f -
pod/php4 created
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE     IP            NODE
php1   1/1     Running   0          3m16s   10.244.3.43   node-0003
php2   1/1     Running   0          3m8s    10.244.3.44   node-0003
php3   1/1     Running   0          113s    10.244.1.8    node-0001
php4   1/1     Running   0          9s      10.244.1.9    node-0001

# 不会使用 NoSchedule 节点
[root@master ~]# sed 's,myphp,php5,' myphp.yaml |kubectl apply -f -
pod/php5 created
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE     IP            NODE
php1   1/1     Running   0          3m16s   10.244.3.43   node-0003
php2   1/1     Running   0          3m8s    10.244.3.44   node-0003
php3   1/1     Running   0          113s    10.244.1.8    node-0001
php4   1/1     Running   0          9s      10.244.1.9    node-0001
php5   0/1     Pending   0          5s      <none>        <none>

 エビクション ポリシーを確認する

[root@master ~]# kubectl taint node node-0003 k3=v3:NoExecute
node/node-0003 tainted
[root@master ~]# kubectl describe nodes |grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule
Taints:             k1=v1:PreferNoSchedule
Taints:             k2=v2:NoSchedule
Taints:             k3=v3:NoExecute
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE     IP           NODE
php3   1/1     Running   0          4m19s   10.244.1.8   node-0001
php4   1/1     Running   0          2m35s   10.244.1.9   node-0001
php5   0/1     Pending   0          2m31s   <none>       <none>

 クリーンな構成

[root@master ~]# kubectl delete pod php{3..5}
pod "php3" deleted
pod "php4" deleted
pod "php5" deleted
[root@master ~]# kubectl taint node node-0001 k1=v1:PreferNoSchedule-
node/node-0001 untainted
[root@master ~]# kubectl taint node node-0002 k2=v2:NoSchedule-
node/node-0002 untainted
[root@master ~]# kubectl taint node node-0003 k3=v3:NoExecute-
node/node-0003 untainted
[root@master ~]# kubectl describe nodes |grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule
Taints:             <none>
Taints:             <none>
Taints:             <none>

公差戦略

通常はラベル通りに行うため、ラベルを綴じる必要があります。

許容戦略とは何ですか? 汚染の正反対です. 汚染されたノードでポッドを実行したい場合があります. 汚染ラベルを無視するこのスケジューリング方法は許容と呼ばれます

ノードのテイントを設定する

# 节点 node-0001 设置污点标签 k=v1:NoSchedule
[root@master ~]# kubectl taint node node-0001 k=v1:NoSchedule
node/node-0001 tainted

# 节点 node-0002 设置污点标签 k=v2:NoSchedule
[root@master ~]# kubectl taint node node-0002 k=v2:NoSchedule
node/node-0002 tainted

# 节点 node-0003 设置污点标签 k=v1:NoExecute
[root@master ~]# kubectl taint node node-0003 k=v1:NoExecute
node/node-0003 tainted

[root@master ~]# kubectl describe nodes |grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule
Taints:             k=v1:NoSchedule
Taints:             k=v2:NoSchedule
Taints:             k=v1:NoExecute

完全一致 (等しい)

完全一致戦略

# 容忍 k=v1:NoSchedule 污点
[root@master ~]# vim myphp.yaml
---
kind: Pod
apiVersion: v1
metadata:
  name: myphp
spec:
  tolerations:
  - operator: "Equal"      # 完全匹配键值对
    key: "k"               # 键
    value: "v1"            # 值
    effect: "NoSchedule"   # 污点标签
  containers:
  - name: php
    image: myos:phpfpm
    resources:
      requests:
        cpu: 800m

[root@master ~]# for i in php{1..3};do sed "s,myphp,${i}," myphp.yaml ;done|kubectl apply -f -
pod/php1 created
pod/php2 created
pod/php3 created
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP            NODE
php1   1/1     Running   0          6s    10.244.1.10   node-0001
php2   1/1     Running   0          6s    10.244.1.11   node-0001
php3   1/1     Pending   0          6s    <none>        <none>
[root@master ~]# kubectl delete pod php{1..3}
pod "php1" deleted
pod "php2" deleted
pod "php3" deleted

あいまい一致 (あり)

あいまい一致戦略

# 容忍 k=*:NoSchedule 污点
[root@master ~]# vim myphp.yaml
---
kind: Pod
apiVersion: v1
metadata:
  name: myphp
spec:
  tolerations:
  - operator: "Exists"     # 部分匹配,存在即可
    key: "k"               # 键
    effect: "NoSchedule"   # 污点标签
  containers:
  - name: php
    image: myos:phpfpm
    resources:
      requests:
        cpu: 800m

[root@master ~]# for i in php{1..3};do sed "s,myphp,${i}," myphp.yaml ;done|kubectl apply -f -
pod/php1 created
pod/php2 created
pod/php3 created
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP            NODE
php1   1/1     Running   0          6s    10.244.1.12   node-0001
php2   1/1     Running   0          6s    10.244.2.21   node-0002
php3   1/1     Running   0          6s    10.244.2.22   node-0002
[root@master ~]# kubectl delete pod php{1..3}
pod "php1" deleted
pod "php2" deleted
pod "php3" deleted

すべての染色ラベル

# 容忍所有 node 上的污点
[root@master ~]# vim myphp.yaml 
---
kind: Pod
apiVersion: v1
metadata:
  name: myphp
spec:
  tolerations:
  - operator: "Exists"     # 模糊匹配
    key: "k"               # 键
    effect:                # 没有设置污点标签代表所有
  containers:
  - name: php
    image: myos:phpfpm
    resources:
      requests:
        cpu: 800m

[root@master ~]# for i in php{1..3};do sed "s,myphp,${i}," myphp.yaml ;done|kubectl apply -f -
pod/php1 created
pod/php2 created
pod/php3 created
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP            NODE
php1   1/1     Running   0          36s   10.244.1.15   node-0001
php2   1/1     Running   0          36s   10.244.2.16   node-0002
php3   1/1     Running   0          36s   10.244.3.18   node-0003
[root@master ~]# kubectl delete pod php{1..3}
pod "php1" deleted
pod "php2" deleted
pod "php3" deleted

プリエンプションとプライオリティ

優先度は、他の Pod と比較した Pod の重要性を示します

優先度により、重要な Pod の実行がスケジュールされていることを確認できます

リソースが逼迫している場合は優先順位を使用する

プライオリティとプリエンプションの使い方

優先度クラス PriorityClass を構成する

Pod の作成時に対応する優先度を設定する

優先度の概要

PriorityClass は、優先クラス名から優先整数値へのマッピングを定義するグローバル リソース オブジェクトです。The priority is specified in the value field, which can be an integer value less than 1 billion . 値が大きいほど、優先度が高くなります。

PriorityClass には、次の 2 つのオプション フィールドもあります。

       -globalDefault は、Pod の優先度がゼロの優先度設定がない場合に、デフォルトの優先度状態を設定するために使用されます

        -description は、説明的な情報を構成し、優先度の目的をユーザーに伝えるために使用されます

優先度の概要

優先ポリシー:

        Non-preemptive priority (queue jumping) : スケジューリング段階でスケジューリングと割り当てを優先します. コンテナのスケジューリングが完了すると, 先取りすることはできません. リソースが不足している場合は待つことしかできません.

        プリエンプティブ プライオリティ ( kill ): Pod は強制的にスケジュールされます. リソースが不十分でスケジュールできない場合、スケジューラは優先度の低い Pod のリソースを先取り (削除) して、優先度の高い Pod の動作を確保します.

非先制優先

preemptionPolicy: Never #non-preemptive
value: 500 #value
description: non-preemptive #description

# 定义优先级(队列优先)
[root@master ~]# vim mypriority.yaml
---
kind: PriorityClass
apiVersion: scheduling.k8s.io/v1
metadata:
  name: high-non
globalDefault: false
preemptionPolicy: Never
value: 1000
description: non-preemptive

---
kind: PriorityClass
apiVersion: scheduling.k8s.io/v1
metadata:
  name: low-non
globalDefault: false
preemptionPolicy: Never
value: 500
description: non-preemptive

[root@master ~]# kubectl apply -f mypriority.yaml 
priorityclass.scheduling.k8s.io/high-non created
priorityclass.scheduling.k8s.io/low-non created
[root@master ~]# kubectl get priorityclasses.scheduling.k8s.io 
NAME                      VALUE        GLOBAL-DEFAULT   AGE
high-non                  1000         false            12s
low-non                   500          false            12s
system-cluster-critical   2000000000   false            45h
system-node-critical      2000001000   false            45h

ポッドなし、中、優先度の高い構成

# 无优先级的 Pod
[root@master ~]# cat php1.yaml 
---
kind: Pod
apiVersion: v1
metadata:
  name: php1
spec:
  nodeSelector:
    kubernetes.io/hostname: node-0002
  containers:
  - name: php
    image: myos:phpfpm
    resources:
      requests:
        cpu: "1500m"

# 低优先级 Pod
[root@master ~]# cat php2.yaml 
---
kind: Pod
apiVersion: v1
metadata:
  name: php2
spec:
  nodeSelector:
    kubernetes.io/hostname: node-0002
  priorityClassName: low-non      # 优先级名称
  containers:
  - name: php
    image: myos:phpfpm
    resources:
      requests:
        cpu: "1500m"

# 高优先级 Pod
[root@master ~]# cat php3.yaml 
---
kind: Pod
apiVersion: v1
metadata:
  name: php3
spec:
  nodeSelector:
    kubernetes.io/hostname: node-0002
  priorityClassName: high-non     # 优先级名称
  containers:
  - name: php
    image: myos:phpfpm
    resources:
      requests:
        cpu: "1500m"

 非プリエンプティブ プライオリティの確認

[root@master ~]# kubectl apply -f php1.yaml 
pod/php1 created
[root@master ~]# kubectl apply -f php2.yaml 
pod/php2 created
[root@master ~]# kubectl apply -f php3.yaml 
pod/php3 created
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
php1   1/1     Running   0          9s
php2   0/1     Pending   0          6s
php3   0/1     Pending   0          4s
[root@master ~]# kubectl delete pod php1
pod "php1" deleted
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
php2   0/1     Pending   0          20s
php3   1/1     Running   0          18s

# 清理实验 Pod
[root@master ~]# kubectl delete pod php2 php3
pod "php2" deleted
pod "php3" deleted

先制戦略

[root@master ~]# vim mypriority.yaml
---
kind: PriorityClass
apiVersion: scheduling.k8s.io/v1
metadata:
  name: high
globalDefault: false
preemptionPolicy: PreemptLowerPriority
value: 1000
description: non-preemptive

---
kind: PriorityClass
apiVersion: scheduling.k8s.io/v1
metadata:
  name: low
globalDefault: false
preemptionPolicy: PreemptLowerPriority
value: 500
description: non-preemptive

[root@master ~]# kubectl apply -f mypriority.yaml 
priorityclass.scheduling.k8s.io/high created
priorityclass.scheduling.k8s.io/low created
[root@master ~]# kubectl get priorityclasses.scheduling.k8s.io 
NAME                      VALUE        GLOBAL-DEFAULT   AGE
high                      1000         false            12s
low                       500          false            12s
system-cluster-critical   2000000000   false            45h
system-node-critical      2000001000   false            45h

プリエンプション ポリシーを確認する

# 默认优先级 Pod
[root@master ~]# kubectl apply -f php1.yaml 
pod/php1 created
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
php1   1/1     Running   0          6s

# 高优先级 Pod
[root@master ~]# sed 's,-non,,' php3.yaml |kubectl apply -f - 
pod/php3 created
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
php3   1/1     Running   0          9s

# 低优先级 Pod
[root@master ~]# sed 's,-non,,' php2.yaml |kubectl apply -f - 
pod/php2 created
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
php2   0/1     Pending   0          3s
php3   1/1     Running   0          9s

# 清理实验 Pod
[root@master ~]# kubectl delete pod php2 php3
pod "php2" deleted
pod "php3" deleted
[root@master ~]# kubectl delete -f mypriority.yaml 
priorityclass.scheduling.k8s.io "high-non" deleted
priorityclass.scheduling.k8s.io "low-non" deleted
priorityclass.scheduling.k8s.io "high" deleted
priorityclass.scheduling.k8s.io "low" deleted


要約: プリエンプションがない場合は、キューにジャンプして優先度を確認します. プリエンプションがない場合は、現在実行中のポッドを強制終了してから、優先度を確認します. 優先度が低い場合は、必要に応じて Pod を強制終了できます.

特権コンテナ

コンテナーは名前空間テクノロジによって分離されますが、分離の制限を打ち破り、より高い権限を取得する必要がある場合があります。このようなコンテナーは、特権コンテナーと呼ばれます。

特権コンテナーの実行は危険です

安全性

Pod セキュリティ ポリシーは、Pod の実行方法とアクセスできるものを制御するクラスター レベルのリソースです。

Pod セキュリティ ポリシー サーバーのバージョンは、バージョン v1、22 より低くすることはできません

PodSecurity を確保する

 apiServer はシステムのコア サービスです. 障害が発生すると、K8s はそれを管理および維持できなくなります. 変更する前にリソース ファイルをバックアップしてください.

ポッド セキュリティ ポリシー

無制限の特権

ベースライン 制限が弱く、既知のポリシーによる特権の昇格を禁止する

Pod を保護するための現在のベスト プラクティスに従う、非常に厳格な制限ポリシー

Pod アドミッション コントロール ラベル (MODE)

ポリシー違反を強制すると、Pod が拒否されます

監査ポリシー違反は監査ログをトリガーしますが、ポッドは引き続き受け入れられます

警告 ポリシー違反により、ユーザーに表示される警告メッセージがトリガーされますが、Pod は引き続き受け入れられます

特権コンテナ

コンテナーのホスト名と /etc/hosts ファイルを変更する

[root@master ~]# vim root.yaml
---
kind: Pod
apiVersion: v1
metadata:
  name: root
spec:
  terminationGracePeriodSeconds: 0
  restartPolicy: Always
  hostname: myhost         # 特权,修改主机名
  hostAliases:             # 修改 /etc/hosts
  - ip: 192.168.1.30       # IP 地址
    hostnames:             # 名称键值对
    - registry             # 主机名
  containers:
  - name: linux
    image: myos:v2009
    imagePullPolicy: IfNotPresent
    command: ["/bin/bash"]
    args:
    - -c
    - |
      while true;do
            echo "Hello World."
            sleep 5
      done

[root@master ~]# kubectl apply -f root.yaml 
pod/root created
[root@master ~]# kubectl exec -it root -- /bin/bash
[root@myhost html]# hostname
myhost
[root@myhost html]# cat /etc/hosts
... ...
# Entries added by HostAliases.
192.168.1.30	registry

[root@master ~]# kubectl delete pod root 
pod "root" deleted

ルート特権コンテナー

[root@master ~]# vim root.yaml
---
kind: Pod
apiVersion: v1
metadata:
  name: root
spec:
  terminationGracePeriodSeconds: 0
  restartPolicy: Always
  hostPID: true            # 特权,共享系统进程
  hostNetwork: true        # 特权,共享主机网络
  containers:
  - name: linux
    image: myos:v2009
    imagePullPolicy: IfNotPresent
    securityContext:       # 安全上下文值
      privileged: true     # root特权容器
    command: ["/bin/bash"]
    args:
    - -c
    - |
      while true;do
            echo "Hello World."
            sleep 5
      done

[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
root   1/1     Running   0          26s
[root@master ~]# kubectl exec -it root -- /bin/bash
[root@node-0001 /]# 

# 系统进程特权
[root@node-0001 /]# pstree -p
systemd(1)-+-NetworkManager(510)-+-dhclient(548)
           |                     |-{NetworkManager}(522)
           |                     `-{NetworkManager}(524)
           |-agetty(851)
           |-chronyd(502)
           |-containerd(531)-+-{containerd}(555)
           ... ...

# 网络特权
[root@node-0001 /]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.51  netmask 255.255.255.0  broadcast 192.168.1.255
        ether fa:16:3e:70:c8:fa  txqueuelen 1000  (Ethernet)
        ... ...

# root用户特权
[root@node-0001 /]# mkdir /sysroot
[root@node-0001 /]# mount /dev/sda1 /sysroot
[root@node-0001 /]# chroot /sysroot
sh-4.2# mount -t proc proc /proc
sh-4.2# : 此处已经是 node 节点上的 root 用户了

# 删除特权容器
[root@master ~]# kubectl delete pod root 
pod "root" deleted

ポッド セキュリティ ポリシー

[root@master ~]# sed '36i\    - --feature-gates=PodSecurity=true' -i /etc/kubernetes/manifests/kube-apiserver.yaml
[root@master ~]# systemctl restart kubelet

# 生产环境设置严格的准入控制
[root@master ~]# kubectl create namespace myprod
namespace/myprod created
[root@master ~]# kubectl label namespaces myprod pod-security.kubernetes.io/enforce=restricted
namespace/myprod labeled

# 测试环境测试警告提示
[root@master ~]# kubectl create namespace mytest
namespace/mytest created
[root@master ~]# kubectl label namespaces mytest pod-security.kubernetes.io/warn=baseline
namespace/mytest labeled

# 创建特权容器
[root@master ~]# kubectl -n myprod apply -f root.yaml 
Error from server (Failure): error when creating "root.yaml": host namespaces (hostNetwork=true, hostPID=true), privileged (container "linux" must not set securityContext.privileged=true), allowPrivilegeEscalation != false (container "linux" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "linux" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "linux" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "linux" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
[root@master ~]# 
[root@master ~]# kubectl -n myprod get pods
No resources found in myprod namespace.

[root@master ~]# kubectl -n mytest apply -f root.yaml                                    
Warning: would violate "latest" version of "baseline" PodSecurity profile: host namespaces (hostNetwork=true, hostPID=true), privileged (container "linux" must not set securityContext.privileged=true)
pod/root created
[root@master ~]# 
[root@master ~]# kubectl -n mytest get pods               
NAME   READY   STATUS    RESTARTS   AGE
root   1/1     Running   0          7s
[root@master ~]# 

セキュリティ ルールに準拠する Pod

[root@master ~]# vim nonroot.yaml 
--- 
kind: Pod 
apiVersion: v1
メタデータ: 
  name: 非ルート
spec: 
  terminationGracePeriodSeconds: 0 
  restartPolicy: Always 
  containers: 
  - name: linux 
    image: myos:v2009 
    imagePullPolicy: IfNotPresent 
    securityContext: 
      allowPrivilegeEscalation : false 
      runAsNonRoot: true 
      runAsUser: 99 
      seccompProfile:
        タイプ: "RuntimeDefault"
      機能:
        ドロップ: ["ALL"]
    コマンド: ["/bin/bash"] 
    args: 
    - -c 
    - | 
      本当のことをする
            「Hello World」をエコーし​​ます。
            sleep 30 
      done 

[root@master ~]# kubectl -n myprod apply -f nonroot.yaml 
pod/nonroot created 
[root@master ~]# kubectl -n myprod get pods 
NAME READY STATUS RESTARTS AGE 
nonroot 1/1 Running 0 6s 
[ root@master ~]# kubectl -n myprod exec -it nonroot -- id 
uid=99(nobody) gid=99(nobody) groups=99(nobody)

おすすめ

転載: blog.csdn.net/weixin_55000003/article/details/130373981