跳到主要内容

策略实践:只允许部分账号创建公网 Ingress

创建策略

使用 kubectl apply 以下两个 YAML:

constraint-template.yaml
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: blockpublicingress
spec:
crd:
spec:
names:
kind: BlockPublicIngress
validation:
openAPIV3Schema:
type: object
properties:
allowedUins:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package blockpublicingress

is_qcloud_ingress(ingress) = true {
not ingress.spec.ingressClassName
}
is_qcloud_ingress(ingress) = true {
ingress.spec.ingressClassName == ""
}
is_qcloud_ingress(ingress) = true {
ingress.spec.ingressClassName == "qcloud"
}
is_qcloud_ingress(ingress) = true {
not ingress.metadata.annotations["kubernetes.io/ingress.class"]
}
is_qcloud_ingress(ingress) = true {
ingress.metadata.annotations["kubernetes.io/ingress.class"] == ""
}
is_public_ingress(ingress) = true {
not ingress.metadata.annotations["kubernetes.io/ingress.subnetId"]
}
is_public_ingress(ingress) = true {
ingress.metadata.annotations["kubernetes.io/ingress.subnetId"] == ""
}
is_qcloud_ingress(ingress) = true {
ingress.metadata.annotations["kubernetes.io/ingress.class"] == "qcloud"
}
is_tke_user(userinfo) = true {
userinfo.groups[_] == "tke:users"
regex.match("^\\d+-\\d+$", userinfo.username)
}
get_uin(userinfo) = uin {
split(userinfo.username, "-", parts)
uin := parts[0]
}
is_uin_allowed(uin, allowed_uins) {
allowed_uins[_] == uin
}

violation[{"msg": msg}] {
input.review.kind.kind == "Ingress"
regex.match("^(extensions|networking.k8s.io)$", input.review.kind.group)
regex.match("^(CREATE|UPDATE)$", input.review.operation)
ingress := input.review.object
is_qcloud_ingress(ingress)
is_public_ingress(ingress)
userinfo := input.review.userInfo
is_tke_user(userinfo)
uin := get_uin(userinfo)
not is_uin_allowed(uin, input.parameters.allowedUins)
msg := sprintf("User '%v' is not allowed to create Ingress resources", [uin])
}

创建 Ingress 注意事项

  1. 如果在控制台创建 Ingress,且集群是当前子账号创建的,会使用 admin 权限,将不受此策略限制。
  2. 如果通过 kubectl 创建,获取 kubeconfig 时也需要使用子账号的 kubeconfig。

效果

如果使用的子账号不在 allowedUins 列表中,创建公网 Ingress 时将会报错。

控制台报错:

kubectl apply 报错:

Error from server (Forbidden): error when creating "STDIN": admission webhook "validation.gatekeeper.sh" denied the request: [block-public-ingress] User '100009022548' is not allowed to create Ingress resources