阅读 78

Kubernetes自助快速生成kubeconfig

一 背景

在微服务架构中尤其如此,您需要在隔离环境中测试您的应用程序,然后再将其发布给其他团队使用。 当工作负载太重而无法在单台笔记本电脑上运行时,它也很有用(例如:测试机器学习算法)。

在这篇文章中,我们将创建一个命名空间,然后使用 Kubernetes 的基于角色的访问控制 (RBAC) 系统创建一个只能访问该特定命名空间的服务帐户。 最后,我们将导出访问该命名空间所需的配置。

二 相关概念

2.1 RBAC

RBAC里面的几种资源关系图

                  |--- Role --- RoleBinding                只在指定namespace中生效 ServiceAccount ---|                   |--- ClusterRole --- ClusterRoleBinding  不受namespace限制,在整个K8s集群中生效 复制代码

2.2 kubeconfig 介绍

kubeconfig文件保存了k8s集群的集群、用户、命名空间、认证的信息。kubectl命令使用kubeconfig文件来获取集群的信息,然后和API server进行通讯。

注意:用于配置对集群的访问的文件称为kubecconfig文件。也就是说,kubeconfig文件中包含的内容是集群的配置。但是,并不是必须有个文件名字叫kubeconfig

默认情况下,kubectl命令从$HOME/.kube目录下查找一个名字叫做config的文件。可以通过KUBECONFIG环境变量或者--kubeconfig参数来指定其他的kubeconfig文件。

kubeconfig中主要由如下部分组成:

  • clusters (集群)

  • users(用户)

  • context(上下文)

2.2.1 kubeconfig支持多集群、多用户、多认证

在实际的使用中的如下场景:

  • kubelet使用证书认证(kubelet和api server进行认证)

  • 用户使用token进行认证

  • 管理员为不同的用户提供不同的证书

都可以使用kubeconfig来组织起集群、用户、命名空间的信息。同样,也可以使用context在集群和命名空间之间进行切换。

2.2.2 Context的定义

在kubeconfig中,context中将访问一个集群的参数进行分组。访问这个context名称就是访问这个参数组。context就是一组信息的别名,举例来说,当在高德中使用家的地址,公司的地址就是一个别名,就能迅速的定位到具体的地址信息。

每个context都有3个参数:

  1. cluster (集群)

  2. namespace(命名空间)

  3. user(用户)

默认情况下,kubectl命令从current context中来获取参数,然后与集群进行通讯。

三 实战

3.1 创建ns

kubectl create namespace mynamespace 复制代码

3.2 使用权限创建服务账户

cat > access.yaml<< EOF --- apiVersion: v1 kind: ServiceAccount metadata:   name: mynamespace-user   namespace: mynamespace --- kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata:   name: mynamespace-user-full-access   namespace: mynamespace rules: - apiGroups: ["", "extensions", "apps"]   resources: ["*"]   verbs: ["*"] - apiGroups: ["batch"]   resources:   - jobs   - cronjobs   verbs: ["*"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata:   name: mynamespace-user-view   namespace: mynamespace subjects: - kind: ServiceAccount   name: mynamespace-user   namespace: mynamespace roleRef:   apiGroup: rbac.authorization.k8s.io   kind: Role   name: mynamespace-user-full-access EOF 复制代码

如您所见,在 Role 定义中,我们添加了对该命名空间中所有内容的完全访问权限,包括诸如作业或 cronjob 之类的批处理类型。 因为它是一个角色,而不是一个 ClusterRole,所以它将被应用于单个命名空间:mynamespace。 有关 Kubernetes 中角色的更多详细信息,请查看官方文档。

kubectl create -f access.yaml 复制代码

3.3 获取secret

创建sa用户后,系统会为sa创建对应的secret。

我们现在需要做的第一件事是获取服务帐户的秘密名称。运行以下命令并复制密钥的名称。

$ kubectl describe sa mynamespace-user -n mynamespace Name:                mynamespace-user Namespace:           mynamespace Labels:              <none> Annotations:         <none> Image pull secrets:  <none> Mountable secrets:   mynamespace-user-token-tncrk Tokens:              mynamespace-user-token-tncrk Events:              <none> $ skubectl get secret -n mynamespace NAME                           TYPE                                  DATA   AGE mynamespace-user-token-tncrk   kubernetes.io/service-account-token   3      16m 复制代码

我们现在需要获取服务帐户的令牌和证书颁发机构。为此,我们将使用 kubectl 读取它们。现在,由于 Kubernetes 的秘密是 base64 编码的,我们还需要对它们进行解码

3.3.1 获取token

kubectl get secret mynamespace-user-token-xxxxx -n mynamespace -o "jsonpath={.data.token}" | base64 -D kubectl get secret -n mynamespace mynamespace-user-token-tncrk -o "jsonpath={.data.token}" |base64 -D eyJhbGciOiJSUzI1NiIsImtpZCI6Ik1fVDJTS1NhM0V1enlHTGFuN3BfNGZmOVM2bm9RTmdLZjlqWlpnbzA3ZEEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJteW5hbWVzcGFjZSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJteW5hbWVzcGFjZS11c2VyLXRva2VuLXRuY3JrIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Im15bmFtZXNwYWNlLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIzNTcxNDg4YS1mOTc5LTQ1YjMtOTE4ZS1jNjJkYmJhYzlmMjIiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6bXluYW1lc3BhY2U6bXluYW1lc3BhY2UtdXNlciJ9.oTghGOFPxyv0cJhQnrD7NdxPsil2JVZedJw5oIlHvlgY7B5ZMYbwhj9qd01GuZ5mjgiqKQJfndsf0fRziUR2TmgM4BQM-4MP8DJKG4eLW9zJx7pvrnFR-Ktf89AK-jHkmKg-yP7WS940NxeYctANh-sR4LJzJ-tRExNSOx54ZLW-dn4TuDo1pXj1DtOrHJsvhrP0CFaQWNTV1gDlucIKGo4dCU0LRiE1P1bgaHI4GBLTP2ez9VYtG24j9LLksvKWgWHu7zOKJlA2g1UDfgfrhu7dZltrhEbObLvu6hP57gSPSxH94ibSGAGhOWmAobqaxcKvGNqhbNO6KnmCjsFAqg% 复制代码

3.3.2 获取ca

kubectl get secrets mynamespace-user-token-tncrk -n mynamespace  -o "jsonpath={.data['ca\.crt']}" LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeE1URXhOREF5TkRnME5sb1hEVE14TVRFeE1qQXlORGcwTmxvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBS2dPClpZdUdQWFVTc1ZWejBRSmRlTzNLK2JNQjl1TWNkc2xuTUlYdmI5Rmt3WjNCbjRNTHZaYUFrTC9RT2tNdkhEU1MKOTV4RElPTXRDZmJHWElKbEFJZ3YySUpTRUF6YmNNRE5hb2ZwZmpBVXVzUXd6TUhkdjVoRzRJbkg1UzRGdVFMaAp6Vm5jV1lFTDFORDFFZy9hWnMrTDFJemtGSHc1N1J3Q3hBY3dJcDY4azdLeFUyN24yOHYrVzVCY29HVWR0NGVoCkVaYVFOcGpNamRic3dHa1QwQVlLNFNWc1B2dDY5a2RsYlJld3gzYms5UEpYUFRqeWNkNmFMbUtDQk0yU1M0Q3EKbkJUM2NmS2l6ZGFza3VBTkFmWWQ4S0h4NE9rSXBMSHErM2JSeDltWDZYOUpXS1JIWVppM0VMZTVZa1NRcGQ3ZAo3ZXRKVmpsV0pFa3UwS3E5cW5VQ0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZMK2Q0NDdvMmpPbXN4dmE5TG5wTHpWVjdoRlFNQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFCQlRnT2NPeVduWHJ5RTZ2YS9HNGlTU3c0MGZpNUZ2VnY0N0JMT0FBYUFjeURTNzFraQpnYmVERC9maUVSVkxWbi82Z1ZoektkaDRvMHZwaUxjNEZGejBhV1lhQlN6RVpnS1N5YzV5ejVxSndTNlJ4MjhSCmU5dEpsRUFWM3BYbXNTT3ppY2hRdVdiWkQ1NVFTT3ZXaEsvd3AveGxzR3ZEZSt4S0VMUmJTTGJmNzNCZzZvQ1gKTnZWWi9hSmovbk04WXhJOFZidzd1czZpK1FFMVRCVmpWZU1jSGlpTDByUlpnNkhEejY5THR4Qk1kRW9WQlJmbAp6TXdybE5laDJmbzFjTHpsRU1sVHIzUU93ZC9Rd0IyQ1MwcTZVOGRoZ1pVYkpTVmhWMHBCYVFDRmpLTS9jamFpCm96ajcvc2tUYjVhaDVqQVFqbFZBQi83cjlWVHk1U253eUg0QQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==% 复制代码

3.4 创建kubeconfig

我们现在拥有所需的一切。剩下的唯一事情就是使用我们之前收集的数据创建 Kube 配置文件:

apiVersion: v1 kind: Config preferences: {}  # Define the cluster clusters: - cluster:     certificate-authority-data: PLACE CERTIFICATE HERE     # You'll need the API endpoint of your Cluster here:     server: https://YOUR_KUBERNETES_API_ENDPOINT   name: my-cluster  # Define the user users: - name: mynamespace-user   user:     as-user-extra: {}     client-key-data: PLACE CERTIFICATE HERE     token: PLACE USER TOKEN HERE  # Define the context: linking a user to a cluster contexts: - context:     cluster: my-cluster     namespace: mynamespace     user: mynamespace-user   name: mynamespace  # Define current context current-context: mynamespace 复制代码

四 一键脚本

4.1 创建对指定namespace有所有权限的kube-config

#!/bin/bash # # This Script based on  https://jeremievallee.com/2018/05/28/kubernetes-rbac-namespace-user.html # K8s'RBAC doc:         https://kubernetes.io/docs/reference/access-authn-authz/rbac # Gitlab'CI/CD doc:     hhttps://docs.gitlab.com/ee/user/permissions.html#running-pipelines-on-protected-branches # # In honor of the remarkable Windson BASEDIR="$(dirname "$0")" folder="$BASEDIR/kube_config" echo -e "All namespaces is here: \n$(kubectl get ns|awk 'NR!=1{print $1}')" echo "endpoint server if local network you can use $(kubectl cluster-info |awk '/Kubernetes/{print $NF}')" namespace=$1 endpoint=$(echo "$2" | sed -e 's,https\?://,,g') if [[ -z "$endpoint" || -z "$namespace" ]]; then     echo "Use "$(basename "$0")" NAMESPACE ENDPOINT";     exit 1; fi if ! kubectl get ns|awk 'NR!=1{print $1}'|grep -w "$namespace";then kubectl create ns "$namespace";else echo "namespace: $namespace was exist." ;fi echo "--- apiVersion: v1 kind: ServiceAccount metadata:   name: $namespace-user   namespace: $namespace --- kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata:   name: $namespace-user-full-access   namespace: $namespace rules: - apiGroups: ['', 'extensions', 'apps', 'metrics.k8s.io']   resources: ['*']   verbs: ['*'] - apiGroups: ['batch']   resources:   - jobs   - cronjobs   verbs: ['*'] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata:   name: $namespace-user-view   namespace: $namespace subjects: - kind: ServiceAccount   name: $namespace-user   namespace: $namespace roleRef:   apiGroup: rbac.authorization.k8s.io   kind: Role   name: $namespace-user-full-access --- # https://kubernetes.io/zh/docs/concepts/policy/resource-quotas/ apiVersion: v1 kind: ResourceQuota metadata:   name: $namespace-compute-resources   namespace: $namespace spec:   hard:     pods: "10"     services: "10"     persistentvolumeclaims: "5"     requests.cpu: "1"     requests.memory: 2Gi     limits.cpu: "2"     limits.memory: 4Gi" | kubectl apply -f - kubectl -n $namespace describe quota $namespace-compute-resources mkdir -p $folder tokenName=$(kubectl get sa $namespace-user -n $namespace -o "jsonpath={.secrets[0].name}") token=$(kubectl get secret $tokenName -n $namespace -o "jsonpath={.data.token}" | base64 --decode) certificate=$(kubectl get secret $tokenName -n $namespace -o "jsonpath={.data['ca\.crt']}") echo "apiVersion: v1 kind: Config preferences: {} clusters: - cluster:     certificate-authority-data: $certificate     server: https://$endpoint   name: $namespace-cluster users: - name: $namespace-user   user:     as-user-extra: {}     client-key-data: $certificate     token: $token contexts: - context:     cluster: $namespace-cluster     namespace: $namespace     user: $namespace-user   name: $namespace current-context: $namespace" > $folder/$namespace.kube.conf 复制代码

4.2 创建对指定namespace有所有权限的kube-config(在已有的namespace中创建)

#!/bin/bash BASEDIR="$(dirname "$0")" folder="$BASEDIR/kube_config" echo -e "All namespaces is here: \n$(kubectl get ns|awk 'NR!=1{print $1}')" echo "endpoint server if local network you can use $(kubectl cluster-info |awk '/Kubernetes/{print $NF}')" namespace=$1 endpoint=$(echo "$2" | sed -e 's,https\?://,,g') if [[ -z "$endpoint" || -z "$namespace" ]]; then     echo "Use "$(basename "$0")" NAMESPACE ENDPOINT";     exit 1; fi echo "--- apiVersion: v1 kind: ServiceAccount metadata:   name: $namespace-user   namespace: $namespace --- kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata:   name: $namespace-user-full-access   namespace: $namespace rules: - apiGroups: ['', 'extensions', 'apps', 'metrics.k8s.io']   resources: ['*']   verbs: ['*'] - apiGroups: ['batch']   resources:   - jobs   - cronjobs   verbs: ['*'] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata:   name: $namespace-user-view   namespace: $namespace subjects: - kind: ServiceAccount   name: $namespace-user   namespace: $namespace roleRef:   apiGroup: rbac.authorization.k8s.io   kind: Role   name: $namespace-user-full-access" | kubectl apply -f - mkdir -p $folder tokenName=$(kubectl get sa $namespace-user -n $namespace -o "jsonpath={.secrets[0].name}") token=$(kubectl get secret $tokenName -n $namespace -o "jsonpath={.data.token}" | base64 --decode) certificate=$(kubectl get secret $tokenName -n $namespace -o "jsonpath={.data['ca\.crt']}") echo "apiVersion: v1 kind: Config preferences: {} clusters: - cluster:     certificate-authority-data: $certificate     server: https://$endpoint   name: $namespace-cluster users: - name: $namespace-user   user:     as-user-extra: {}     client-key-data: $certificate     token: $token contexts: - context:     cluster: $namespace-cluster     namespace: $namespace     user: $namespace-user   name: $namespace current-context: $namespace" > $folder/$namespace.kube.conf 复制代码

五 总结

使用 kubeconfig 文件来组织有关集群、用户、命名空间和身份认证机制的信息。理解kubeconfig中各字段的含义,配合脚步可以轻松快速的自服务创建自己所需的配置文件。


作者:kaliarch
链接:https://juejin.cn/post/7170192825596772383


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐