Kubernetes检查服务帐户权限

nle07wnf  于 2023-02-15  发布在  Kubernetes
关注(0)|答案(4)|浏览(336)

通过Helm图表部署服务时,安装失败,因为不允许tiller服务帐户创建ServiceMonitor资源。
注:

  • ServiceMonitor是Prometheus操作员定义的CRD,用于自动获取Pod中运行容器的指标。
  • Helm Tiller安装在单个名称空间中,RBAC是使用Role和RoleBinding设置的。

我想验证tiller服务帐户的权限。
kubectl具有auth can-i命令,类似这样的查询(见下文)总是返回no

  • kubectl auth can-i list deployment --as=tiller
  • kubectl auth can-i list deployment --as=staging:tiller

检查服务帐户权限的正确方法是什么?
如何启用tiller帐户以创建ServiceMonitor资源?

pdsfdshx

pdsfdshx1#

在尝试了很多东西并在谷歌上搜索了整个宇宙之后,我终于找到了这个关于使用RBAC和PSP保护集群的博客,其中给出了一个如何检查服务帐户访问权限的示例。
正确的命令为:
kubectl auth can-i <verb> <resource> --as=system:serviceaccount:<namespace>:<serviceaccountname> [-n <namespace>]
要检查tiller帐户是否有权创建ServiceMonitor对象:
kubectl auth can-i create servicemonitor --as=system:serviceaccount:staging:tiller -n staging
注意:为了解决tiller帐户的问题,我必须在monitoring.coreos.com apiGroup中添加对servicemonitors资源的权限。更改后,上述命令返回yes(最终),Helm图表安装成功。
更新了tiller-manager角色:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: tiller-manager
  labels:
    org: ipos
    app: tiller
  annotations:
    description: "Role to give Tiller appropriate access in namespace"
    ref: "https://docs.helm.sh/using_helm/#example-deploy-tiller-in-a-namespace-restricted-to-deploying-resources-only-in-that-namespace"
rules:
- apiGroups: ["", "batch", "extensions", "apps"]
  resources: ["*"]
  verbs: ["*"]
- apiGroups:
    - monitoring.coreos.com
  resources:
    - servicemonitors
  verbs:
    - '*'
mzmfm0qo

mzmfm0qo2#

这将显示您在服务帐户prom-stack-grafana上拥有的权限:例如:
kubectl -n监视授权can-i --list --as=系统:服务帐户:监视:prom堆栈图形

ndasle7k

ndasle7k3#

注意:kubectl auth can-i命令有一个边缘情况/gotcha/错误,以避免值得注意的情况。
基本上,可以使用与服务帐户类似的语法命名用户,并且可以欺骗服务帐户。
这让我困惑了好一段时间,所以我想分享它。

alias k=kubectl
k create ns dev 
k create role devr --resource=pods --verb=get -n=dev 
k create rolebinding devrb --role=devr --user=system:serviceaccount:dev:default -n=dev # wrong syntax 
k auth can-i get pods -n=dev --as=system:serviceaccount:dev:default  # right syntax
# yes

(The k auth can-i说yes的事实使我认为我的角色绑定语法是正确的,但它是错误的)
这是正确的:

k delete ns dev
k create ns dev 
k create role devr --resource=pods --verb=get -n=dev 
k create rolebinding devrb --role=devr --serviceaccount=dev:default -n=dev # right syntax 
k auth can-i get pods -n=dev --as=system:serviceaccount:dev:default  # right syntax
# yes

下面是它错误的直观证明:

k create rolebinding devrb1 --role=devr --user=system:serviceaccount:dev:default -n=dev --dry-run=client -o yaml | grep subjects -A 4
# subjects:
# - apiGroup: rbac.authorization.k8s.io
#   kind: User
#   name: system:serviceaccount:dev:default

k create rolebinding devrb2 --role=devr --serviceaccount=dev:default -n=dev --dry-run=client -o yaml | grep subjects -A 4
# subjects:
# - kind: ServiceAccount
#   name: default
#   namespace: dev

如果对命令式rbac命令的语法有疑问,可以通过以下方法快速查找:

  1. www.example.com kubernetes.io/docs
    1.搜索"rbac"
    1.控制+f "kubectl创建角色绑定"在页面上获得正确语法的例子。
14ifxucb

14ifxucb4#

如果你想进行现场测试,请创建一个包含serviceAccount密码的kube配置文件。我已经创建了上面的脚本来自动执行此操作:

#!/usr/bin/env bash

set -euo pipefail

function generate_sa() {
  local sa
  local namespace
  local context
  local target_namespace
  local output_file
  local "${@}"
  sa=${sa:?set sa}
  namespace=${namespace:?set namespace of the service account}
  context=${context:?set context}
  target_namespace=${target_namespace:? set target context namespace}
  output_file=${output_file:-/tmp/kube.conf}

  cluster=$(kubectl config view -o yaml | yq '.contexts.[] | select ( .name == "'"${context}"'") | .context.cluster')
  if [ -z "${cluster}" ]; then
    echo "We didn't find the cluster from context ${context}"
    exit 1
  fi

  server=$(kubectl config view -o yaml | yq '.clusters.[] | select ( .name == "'"${cluster}"'") | .cluster.server')

  secret=$(kubectl get sa "${sa}" -o jsonpath='{.secrets[0].name}' -n "${namespace}")
  ca=$(kubectl get secret/"${secret}" -o jsonpath='{.data.ca\.crt}' -n "${namespace}")
  token=$(kubectl get secret/"${secret}" -o jsonpath='{.data.token}' -n "${namespace}" | base64 --decode)

  cat <<EOF > "${output_file}"
---
apiVersion: v1
kind: Config
clusters:
- name: ${cluster}
  cluster:
    certificate-authority-data: ${ca}
    server: ${server}
contexts:
- name: ${cluster}
  context:
    cluster: ${cluster}
    namespace: ${target_namespace}
    user: system:serviceaccount:${namespace}:${sa}
current-context: ${cluster}
users:
- name: system:serviceaccount:${namespace}:${sa}
  user:
    token: ${token}
EOF

echo >&2 "Now run: export KUBECONFIG=${output_file}"
}

generate_sa "${@}"

然后执行该命令,它将创建一个kubeconfig文件。

generate_sa_config.sh \
  sa=service-account-name \
  namespace=namespace-of-service-account \
  context=kubernetes-cluster-context-name \
  target_namespace=namespace-of-context

别忘了export KUBECONFIG环境变量,现在你就像是真实的的ServiceAccount,可以玩角色了。

相关问题