Kubernetes-ServiceAccountおよびRBAC権限制御の詳細な説明

1つ、ServiceAccount

1.ServiceAccountの概要

まず、Kubernetesのアカウントは、ユーザーアカウントとサービスアカウントに分けられます。デザインと使用法は次のとおりです。

  • UserAccountは、運用および保守やクラスター管理者など、kubernetesクラスター外のユーザーによって使用されます。kubectlコマンドを使用する場合、UserAccountが使用されます。UserAccountはグローバルです。クラスタ内のすべての名前名の中で、名前は一意であり、ユーザーはデフォルトでadminです。

    ユーザー名はkubeconfigで表示できます

    [root@Centos8 ~]# cd ~/.kube/
    [root@Centos8 .kube]# ls
    cache  config  http-cache
    [root@Centos8 .kube]# cat config
    ...
      users:
      - name: kubernetes-admin
    ...
  • ServiceAccountは、Podで実行されているプログラムによって使用されるID認証です。Podコンテナのプロセスは、ServiceAccountアカウントを使用してAPI Serverにアクセスする必要があります。ServiceAccountは、それが配置されている名前名にのみ制限され、デフォルトのサービスアカウントは、各名前付けが作成されるときに自動的に作成されます。ポッドの場合、サービスアカウントが指定されていない場合、ポッドはデフォルトのサービスアカウントを使用します。

2.シークレットとSAの関係(ServiceAccount)

Kubernetesは、2つのカテゴリに分けられたシークレットリソースを設計しました。1つは、上記のSAであるServiceAccountのkubernetes.io/service-account-tokenです。SAが作成されるたびに、シークレットが作成されます。 1つは、ユーザー定義の機密情報Opaqueです。

3.デフォルトのサービスアカウント

ServiceAccountは、それが配置されているネームスペースにのみ制限されるため、ネームスペースを作成すると、デフォルトのSAが自動的に作成され、SAが作成されると、対応するシークレットも作成されます。次の操作が検証されます。

名前名を作成する

[root@Centos8 .kube]# kubectl create ns vfan
namespace/vfan created

SAを表示

[root@Centos8 .kube]# kubectl get sa -n vfan
NAME      SECRETS   AGE
default   1         67s

SAの秘密を見る

[root@Centos8 .kube]# kubectl describe sa default -n vfan
Name:                default
Namespace:           vfan
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   default-token-wwbc8
Tokens:              default-token-wwbc8
Events:              <none>

[root@Centos8 ~]# kubectl get secret -n vfan
NAME                  TYPE                                  DATA   AGE
default-token-wwbc8   kubernetes.io/service-account-token   3      3m15s

ご覧のとおり、SAはnsが作成されるときにデフォルトで作成され、SAはデフォルトでタイプkubernetes.io/service-account-tokenのシークレットを作成ます。

ポッドを作成する

vim pods.yaml

apiVersion: v1
kind: Pod
metadata:
  name: test-sa
  namespace: vfan
spec:
  containers:
  - name: test-sa
    image: nginx:1.2.1
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
[root@Centos8 rbac]# kubectl create -f pods.yaml 
pod/test-sa created

[root@Centos8 rbac]# kubectl get pod -n vfan
NAME      READY   STATUS    RESTARTS   AGE
test-sa   1/1     Running   0          12s

[root@Centos8 rbac]# kubectl describe pod test-sa -n vfan
...
Containers:
  test-sa:
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-wwbc8 (ro)
Volumes:
  default-token-wwbc8:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-wwbc8
    Optional:    false
...

SAを指定しない場合、nsの下の現在のポッドはデフォルトで「デフォルト」のSAを使用し、対応するシークレットはポッドの/var/run/secrets/kubernetes.io/serviceaccount/ディレクトリに自動的にマウントされます。 ID認証に使用される情報は、ポッドで取得されます。

ポッドコンテナに入り、SAを確認します

[root@Centos8 rbac]# kubectl exec -it test-sa -n vfan -- /bin/bash
root@test-sa:/# cd /var/run/secrets/kubernetes.io/serviceaccount/
root@test-sa:/var/run/secrets/kubernetes.io/serviceaccount# ls
ca.crt  namespace  token

### 可以看到有三个文件,作用分别为
    ca.crt:根证书,用于Client端验证API Server发送的证书
    namespace:标识这个service-account-token的作用域空间
    token:使用API Server私钥签名的JWT,用于访问API Server时,Server端的验证

4.カスタムSAを使用する

SAを作成する

[root@Centos8 rbac]# kubectl create sa vfansa -n vfan
serviceaccount/vfansa created

[root@Centos8 rbac]# kubectl get sa -n vfan
NAME      SECRETS   AGE
default   1         19m
vfansa    1         7s

[root@Centos8 rbac]# kubectl describe sa vfansa -n vfan
Name:                vfansa
Namespace:           vfan
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   vfansa-token-9s8f7
Tokens:              vfansa-token-9s8f7
Events:              <none>

[root@Centos8 rbac]# kubectl get secret -n vfan
NAME                  TYPE                                  DATA   AGE
default-token-wwbc8   kubernetes.io/service-account-token   3      19m
vfansa-token-9s8f7    kubernetes.io/service-account-token   3      49s

同様に、SAが手動で作成された後、対応するシークレットが自動的に作成されます

ポッドを更新し、新しく作成したSAを使用します

vim pods.yaml

apiVersion: v1
kind: Pod
metadata:
  name: test-sa
  namespace: vfan
spec:
  containers:
  - name: test-sa
    image: nginx:1.2.1
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
  serviceAccountName: vfansa    # 加入此参数
[root@Centos8 rbac]# kubectl create -f pods.yaml 
pod/test-sa created

[root@Centos8 rbac]# kubectl describe pod test-sa -n vfan
...
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from vfansa-token-9s8f7 (ro)
Volumes:
  vfansa-token-9s8f7:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  vfansa-token-9s8f7
    Optional:    false
...

5.イメージプルシークレットをServiceAccountに追加します

著者の以前のブログ:シークレットの紹介とデモンストレーション(https://www.cnblogs.com/v-fan/p/13269433.html)で、シークレットを使用してプライベートミラーウェアハウスのログイン情報を保存できることが言及されました。同様に、ログインせずに画像を取得する効果を実現するために、作成したシークレットをSAに直接バインドできます。バインドが完了した後、このSAのポッドを使用している限り、ログインなしで画像を取得する効果を実現できます。

docker-registryの秘密を作成する

[root@Centos8 rbac]# kubectl create secret docker-registry myregistrykey --docker-server=hub.vfancloud.com --docker-username=admin --docker-password=admin@123 [email protected] -n vfan
secret/myregistrykey created

[root@Centos8 rbac]# kubectl get secret -n vfan
NAME                  TYPE                                  DATA   AGE
default-token-wwbc8   kubernetes.io/service-account-token   3      62m
myregistrykey         kubernetes.io/dockerconfigjson        1      7s
vfansa-token-9s8f7    kubernetes.io/service-account-token   3      43m

docker-registryの秘密をSAに追加します

kubectl edit sa vfansa -n vfan

apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2020-08-30T03:38:47Z"
  name: vfansa
  namespace: vfan
  resourceVersion: "471829"
  selfLink: /api/v1/namespaces/vfan/serviceaccounts/vfansa
  uid: 8a44df93-b2d6-4e61-ad2e-25bc5852f66e
secrets:
- name: vfansa-token-9s8f7
imagePullSecrets:   #添加此字段
- name: myregistrykey

SAの画像プルシークレットを表示

[root@Centos8 rbac]# kubectl describe sa vfansa -n vfan 
Name:                vfansa
Namespace:           vfan
Labels:              <none>
Annotations:         <none>
Image pull secrets:  myregistrykey  #已添加成功
Mountable secrets:   vfansa-token-9s8f7
Tokens:              vfansa-token-9s8f7
Events:              <none>

このとき、このSAを使用するポッドである限り、docker-registryからイメージをプルできます。同様に、このシークレットをデフォルトのSAに追加して、同じ効果を実現できます。

二、RBAC

1.RBACの紹介

Kubernetesでは、すべてのリソースオブジェクトはAPIオブジェクトを介して操作され、etcdに格納されます。etcdの操作は、kube-apiserverにアクセスして実現する必要があります。上記のサービスアカウントは、実際にはAPIServerの認証プロセスであり、承認メカニズムはRBAC(ロールベースのアクセス制御)によって実現されます。

2.RoleとClusterRole

RBAC APIでは、Roleは一連のルール権限を表し、権限は増加するだけです(累積された権限)。最初はリソースなしで多くの権限がありますが、RBACによって削減されます。役割は名前名で定義され、ClusterRoleこれはクラスターレベルです。

以下に役割を定義します。

vimroles.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: test-role
  namespace: vfan
rules:
- apiGroups: [""]  # 为空表示为默认的core api group
  resources: ["pods"] # 数据源类型
  verbs: ["get","watch","list"] #赋予的权限

上記の役割戦略は、vfanという名前の名前名で、ポッドが取得、監視、および一覧表示のアクセス許可を持っていることを意味します

ClusterRoleには、Roleと同じ権限と役割制御機能があります。違いは、ClusterRoleがクラスターレベルにあることです。次の目的で使用できます。

  • クラスターレベルのリソース制御(ノードアクセス許可など)
  • リソース以外のエンドポイント(たとえば、ディレクトリまたはファイルへのアクセス:/ healthz)
  • すべての名前空間リソース制御(ポッド、展開など)

vim clusterroles.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: test-clusterrole
rules:
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get","create","list"]

上記のクラスターロールポリシーは、クラスターサービス全体を取得、作成、および一覧表示するためのアクセス許可があることを示しています。

以下の作成を開始します

## 创建role
[root@Centos8 rbac]# kubectl create -f roles.yaml 
role.rbac.authorization.k8s.io/test-rbac created

[root@Centos8 rbac]# kubectl get role -n vfan 
NAME        AGE
test-rbac   27s

## 创建cluster role
[root@Centos8 rbac]# kubectl get clusterrole -n vfan
NAME                                                                   AGE
admin                                                                  141d
cluster-admin                                                          141d
edit                                                                   141d
flannel                                                                141d
ingress-nginx                                                          90d
ingress-nginx-admission                                                90d
system:aggregate-to-admin                                              141d
system:aggregate-to-edit                                               141d
system:aggregate-to-view                                               141d
test-clusterrole                                                       30s

ご覧のとおり、ロールとクラスタロールは正常に作成されていますが、今回は多くのクラスタロールが作成されており、システムで始まるものはすべてシステムで使用され、プラグインがインストールされると自動的に追加されます。自分でクラスターの役割を作成する場合は、不明確にならないように、システムで開かないように注意してください。

3.RoleBindingとClusterRoleBinding

RoleBindingは、ロールで定義されたアクセス許可をユーザーまたはユーザーグループに付与できます。RoleBindingには、リソースタイプ(ユーザー、グループ、またはサービスアカウント)に付与されるさまざまなタイプのアクセス許可を含む一連のアクセス許可リスト(サブジェクト)が含まれます。バインドされているロールへの参照。RoleBindingは特定の名前名内での承認に適しており、ClusterRoleBindingはクラスター内での承認に適しています。

RoleBindingを作成する

vim rolebindings.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: test-rolebinding
  namespace: vfan
subjects:
- kind: User    # 权限资源类型
  name: vfan    # 名称
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role    #要绑定的Role的类型(可以是Role或ClusterRole)
  name: test-role   # Role的名称
  apiGroup: rbac.authorization.k8s.io

この戦略は、test-roleという名前のロールのアクセス許可リソースがvfanという名前のユーザーに割り当てられていることを示しています。vfanはvfan名前名にのみ作用します。

RoleBindingは、ClusterRoleを参照して、現在の名前名でユーザー、ユーザーグループ、またはSAを承認することもできます。この操作により、管理者はクラスター全体でいくつかの共通のClusterRolesを定義し、異なる名前名でRoleBindingバインディングを使用できます。

vim rolebindings2.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: test-rolebinding2
  namespace: vfan
subjects:
- kind: User
  name: vfan
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: test-clusterrole
  apiGroup: rbac.authorization.k8s.io

上記の戦略は、test-clusterroleという名前のClusterRoleのリソース権限がvfanという名前のユーザーに割り当てられていることを示しています。ClusterRoleは割り当てられていますが、Roleは単一の名前空間にのみ作用するため、このリソースポリシーはvfan名前空間に対してのみ有効です。

ClusterRoleBindingを作成します

vim clusterrolebindings.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: test-clusterrolebinding
subjects:
- kind: Group
  name: vfan
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: test-clusterrole
  apiGroup: rbac.authorization.k8s.io

上記の戦略は、名前がtest-clusterroleであるClusterRoleのリソース権限が、グループ名がvfanであるユーザーグループに割り当てられることを示しています。このユーザーグループの下のすべてのユーザーは、クラスター全体のtest-clusterroleでリソース権限を持っています。

練習:ユーザーを作成して、vfanという名前のNameSpaceのみを管理できます

1.システムユーザーを作成します

[root@Centos8 rbac]# useradd vfan
[root@Centos8 rbac]# su - vfan 

## 进入vfan用户测试访问k8s集群
[vfan@Centos8 ~]$ kubectl get pod 
The connection to the server localhost:8080 was refused - did you specify the right host or port?

デフォルトでは絶対にアクセスできません。アクセスする場合は、vfanユーザーのアクセス証明書を作成する必要があります。

2.vfanユーザーのアクセス証明書を作成します

## 下载证书生成工具 cfssl
[root@Centos8 bin]# wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
[root@Centos8 bin]# wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
[root@Centos8 bin]# wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64

## 改名,给执行权限
[root@Centos8 bin]# mv cfssl_linux-amd64 cfssl
[root@Centos8 bin]# mv cfssljson_linux-amd64 cfssljson
[root@Centos8 bin]# mv cfssl-certinfo_linux-amd64 cfssl-certinfo
[root@Centos8 bin]# chmod +x *
[root@Centos8 bin]# ll -h 
总用量 19M
-rwxr-xr-x 1 root root 9.9M 3月  30 2016 cfssl
-rwxr-xr-x 1 root root 6.3M 3月  30 2016 cfssl-certinfo
-rwxr-xr-x 1 root root 2.2M 3月  30 2016 cfssljson
[root@Centos8 bin]# mkdir /usr/local/vfancert
[root@Centos8 bin]# cd /usr/local/vfancert/

CA証明書署名要求JSONファイルを作成します

vim vfan-csr.json

{
  "CN": "vfan",     # 用户名称,必填
  "hosts": [],      # 主机地址,不填表示所有主机都可使用
  "key": {
    "algo": "rsa",  # 加密算法
    "size": 2048
},
  "names": [
    {
       "C": "CN",
       "L": "BeiJing",
       "O": "Ctyun",
       "ST": "BeiJing",            
       "OU": "System"
    }
  ]
}

アクセス証明書の作成を開始します

[root@Centos8 vfancert]# cd /etc/kubernetes/pki/
[root@Centos8 pki]# cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /usr/local/vfancert/vfan-csr.json | cfssljson -bare vfanuser
2020/09/02 22:08:51 [INFO] generate received request
2020/09/02 22:08:51 [INFO] received CSR
2020/09/02 22:08:51 [INFO] generating key: rsa-2048
2020/09/02 22:08:51 [INFO] encoded CSR
2020/09/02 22:08:51 [INFO] signed certificate with serial number 191102646650271030964539871811792985454770130197
2020/09/02 22:08:51 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").

## 创建成功,pki目录下多出vfanuser-key.pem、vfanuser.pem和vfanuser.csr文件
[root@Centos8 pki]# ls
vfanuser.csr
vfanuser-key.pem
vfanuser.pem

3.vfanユーザー用のクラスター構成ファイルを生成します

## 设置api server的环境变量
[root@Centos8 vfancert]# export KUBE_APISERVER="https://192.168.152.53:6443"

## 创建kubeconfig文件,以下详细参数信息可通过kubectl config set-cluster --help查看
[root@Centos8 vfancert]# kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --server=${KUBE_APISERVER} --kubeconfig=vfan.kubeconfig
Cluster "kubernetes" set.

## 配置文件生成
[root@Centos8 vfancert]# ls
vfan-csr.json  vfan.kubeconfig

## 设置客户端参数,绑定用户信息至kubeconfig中
[root@Centos8 vfancert]# kubectl config set-credentials vfanuser \
> --client-certificate=/etc/kubernetes/pki/vfanuser.pem \
> --client-key=/etc/kubernetes/pki/vfanuser-key.pem \
> --embed-certs=true \
> --kubeconfig=vfan.kubeconfig
User "vfanuser" set.

## 设置上下文参数
[root@Centos8 vfancert]# kubectl config set-context kubernetes \
> --cluster=kubernetes \
> --user=vfan \
> --namespace=vfan \
> --kubeconfig=vfan.kubeconfig
Context "kubenetes" created.

4. RoleBindingを実行して、権限が有効であることを確認します

vim vfanrolebind.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: test-rolebinding
  namespace: vfan
subjects:
- kind: User
  name: vfan
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: test-rbac   # 绑定上文中创建的名称为 test-rbac 的Role,具体权限,往上翻下哈
  apiGroup: rbac.authorization.k8s.io

kubeconfigファイルをvfanユーザーのホームディレクトリの.kubeにコピーします

[root@Centos8 vfancert]# mkdir -p /home/vfan/.kube
[root@Centos8 vfancert]# cp vfan.kubeconfig /home/vfan/.kube/config
[root@Centos8 vfancert]# cd /home/vfan/.kube/
[root@Centos8 .kube]# ls
config

## 修改文件所有者
[root@Centos8 vfan]# chown -R vfan:vfan .kube/

kubectlが構成情報を読み取れるようにコンテキストを切り替えます

[vfan@Centos8 .kube]$ kubectl config use-context kubernetes --kubeconfig=config 
Switched to context "kubernetes".

権限のテストを開始します

[vfan@Centos8 .kube]$ kubectl get pod 
No resources found.

[vfan@Centos8 .kube]$ kubectl get svc 
Error from server (Forbidden): services is forbidden: User "vfan" cannot list resource "services" in API group "" in the namespace "vfan"

ポッドを取得することはできますが、サービスを取得することはできません。前のロールでは、ポッドのアクセス許可を取得、監視、および一覧表示することしかできないと明確に述べられていたためです。

vfan名前空間の下にテストデプロイメントを作成します

## root用户下创建
[root@Centos8 k8sYaml]# kubectl run deployment test-vfan --replicas=3 --image=nginx:1.2.1 --namespace=vfan

[root@Centos8 k8sYaml]# kubectl get pod -n vfan 
NAME                         READY   STATUS    RESTARTS   AGE
deployment-7b89b946d-5dtvp   1/1     Running   0          17s
deployment-7b89b946d-jpr5v   1/1     Running   0          17s
deployment-7b89b946d-r8k4l   1/1     Running   0          17s

## 前往vfan用户查看
[vfan@Centos8 .kube]$ kubectl get pod 
NAME                         READY   STATUS    RESTARTS   AGE
deployment-7b89b946d-5dtvp   1/1     Running   0          67s
deployment-7b89b946d-jpr5v   1/1     Running   0          67s
deployment-7b89b946d-r8k4l   1/1     Running   0          67s

ご覧のとおり、vfanユーザーはポッドを取得するときに名前を指定しなかったため、対応するポッドを表示することもできます。したがって、vfanユーザーのデフォルトの名前はvfanであることが証明できます。

おすすめ

転載: blog.51cto.com/mageedu/2553145