命名空间的专用节点

Ysa*_*sak 3 kubernetes

在 Kubernetes 中,我们有多个环境,由不同的命名空间分隔。我想确保一组节点仅由特定的命名空间/环境使用。

  1. 特定标签的节点应拒绝所有不属于命名空间的 Pod
  2. 来自特定命名空间的 Pod 应始终选择配置了标签的节点。

有什么方法可以实现呢?听说过改变 webhook 准入控制器,任何人都有一个示例,看看它是如何工作的。

Arg*_*dhu 5

您可以使用 mutating webhook 来改变来自特定命名空间的传入 pod 请求,以在 pod 规范中添加节点关联性节点选择器。

这里nodeSelector是准入控制器的一个例子。有关如何使用它的完整指南。

准备API服务器

假设您的集群已使用 kubeadm 进行部署,则 kube-apiserver.yaml 文件是 Kubernetes API 服务器的配置清单。它位于 /etc/kubernetes/manifests 中。在 --admission-control= 标志中添加 PodNodeSelector 准入控制器

然后给节点添加标签

kubectl label node kubeprod01 env=production
Run Code Online (Sandbox Code Playgroud)

然后在命名空间的注释中使用该标签。

apiVersion: v1
kind: Namespace
metadata:
  annotations:
    scheduler.alpha.kubernetes.io/node-selector: env=production
Run Code Online (Sandbox Code Playgroud)

通过改变 webhook 添加节点关联性的示例。

func mutatePods(ar v1beta1.AdmissionReview, o *options) *v1beta1.AdmissionResponse {
    var reviewResponse = &v1beta1.AdmissionResponse{
        Allowed: true,
    }

    podResource := metav1.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}
    if ar.Request.Resource != podResource {
        glog.Errorf("expect resource to be %s", podResource)
        return nil
    }

    raw := ar.Request.Object.Raw
    pod := v1.Pod{}
    // glog.V(2).Infof("Object: %v", string(raw))
    if err := json.Unmarshal(raw, &pod); err != nil {
        glog.Error(err)
        return nil
    }

    addPodAffinityPatch := fmt.Sprintf(`[
         {"op":"add","path":"/spec/affinity","value":{"nodeAffinity":{"preferredDuringSchedulingIgnoredDuringExecution":[{"preference":{"matchExpressions":[{"key":"%s","operator":"NotIn","values":["%s"]}]},"weight":1}]}}}
    ]`, o.PodAffinityKey, o.PodAffinityValue)

    glog.V(2).Infof("patching pod")
    reviewResponse.Patch = []byte(addPodAffinityPatch)
    pt := v1beta1.PatchTypeJSONPatch
    reviewResponse.PatchType = &pt

    return reviewResponse
}
Run Code Online (Sandbox Code Playgroud)