前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >权限认证之ServiceAccount

权限认证之ServiceAccount

作者头像
用户9822880
发布2022-06-13 15:07:55
2890
发布2022-06-13 15:07:55
举报
文章被收录于专栏:3分钟云计算

号里很多瓜友问我,Kubernetes中的应用程序是如何访问kubernetes中的资源对象的?

我想了下这个问题,觉得可以先从"SA"谈起。

权限管理是Kubernetes和OpenShift的核心功能之一。Kubenetes本身提供了一系列的安全机制,比如认证(Authentication)、授权(Authorization)、准入控制(Admission Control)认证(Authentication)、授权(Authorization)、准入控制(Admission Control)。但是它本身并不管理用户的信息,用户的身份信息管理是以插件形式存在的,比如管理员可以配置HTpasswd、KeyStone、LDAP、GitHub等登录验证方式。自然人用户可以获取相应的Token来去访问API Server. 那么在系统中运行的程序进程该如何访问API Server呢?

注:在Kubernetes/OpenShift云计算系统中,所有的用户(自然人用户,程序用户)都需要和API Server进行交互,只有认证、授权、准入控制通过后,这些用户才能使用相应的资源(API)。API Server类似门禁一样保证了后端etcd中的数据安全。

为了解决此问题,Kubernetes 引入了ServiceAccount(SA)的概念。我们以OpenShift为例。

注:Pod是Kubernetes/OpenShift系统中最小基本单元,它里面可包含多个容器服务。

SA以Namespace(命名空间)划分,我们新建一个Namespace,叫做test,如下:

代码语言:javascript
复制
$ oc new-project test
$ oc get sa
NAME       SECRETS   AGE
builder    2         3m20s
default    2         3m20s
deployer   2         3m20s

注:在OpenShift中,oc = kubectl

可以看到有三个SA被默认创建了,那它们分别起什么作用呢?

先来查看下它们被赋予的权限:

代码语言:javascript
复制
$ oc get rolebinding
NAME                    ROLE                               AGE
admin                   Cl
usterRole/admin                  15m
system:deployers        ClusterRole/system:deployer        15m
system:image-builders   ClusterRole/system:image-builder   15m
system:image-pullers    ClusterRole/system:image-puller    15m

可以看到,SA builder 被赋予了system:image-builder 的权限。我们再去看下system:image-builder可以做什么。

代码语言:javascript
复制
$ oc describe rolebinding system:image-builders 
Name:         system:image-builders
Labels:       <none>
Annotations:  openshift.io/description:
                Allows builds in this namespace to push images to this namespace.  It is auto-managed by a controller; remove subjects to disable.
Role:
  Kind:  ClusterRole
  Name:  system:image-builder
Subjects:
  Kind            Name     Namespace
  ----            ----     ---------
  ServiceAccount  builder  test

可以看到,system:image-builder 可以做一些imagestream的创建、更新等操作。

代码语言:javascript
复制
$ oc describe clusterrole system:image-builder
Name:         system:image-builder
Labels:       rbac.authorization.k8s.io/aggregate-to-admin=true
              rbac.authorization.k8s.io/aggregate-to-edit=true
Annotations:  openshift.io/description:
                Grants the right to build, push and pull images from within a project.  Used primarily with service accounts for builds.
              rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
  Resources                               Non-Resource URLs  Resource Names  Verbs
  ---------                               -----------------  --------------  -----
  imagestreams                            []                 []              [create]
  imagestreams.image.openshift.io         []                 []              [create]
  imagestreams/layers                     []                 []              [get update]
  imagestreams.image.openshift.io/layers  []                 []              [get update]
  builds                                  []                 []              [get]
  builds.build.openshift.io               []                 []              [get]
  builds/details                          []                 []              [update]
  builds.build.openshift.io/details       []                 []              [update]

类似地,SA deploer 可做一些pod部署的操作。

代码语言:javascript
复制
$ oc describe rolebinding system:deployers
Name:         system:deployers
Labels:       <none>
Annotations:  openshift.io/description:
                Allows deploymentconfigs in this namespace to rollout pods in this namespace.  It is auto-managed by a controller; remove subjects to disa...
Role:
  Kind:  ClusterRole
  Name:  system:deployer
Subjects:
  Kind            Name      Namespace
  ----            ----      ---------
  ServiceAccount  deployer  test

$ oc describe clusterrole system:deployer
Name:         system:deployer
Labels:       <none>
Annotations:  openshift.io/description: Grants the right to deploy within a project.  Used primarily with service accounts for automated deployments.
              rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
  Resources                           Non-Resource URLs  Resource Names  Verbs
  ---------                           -----------------  --------------  -----
  pods                                []                 []              [create get list watch]
  events                              []                 []              [create list]
  imagestreamtags                     []                 []              [create update]
  imagetags                           []                 []              [create update]
  imagestreamtags.image.openshift.io  []                 []              [create update]
  imagetags.image.openshift.io        []                 []              [create update]
  replicationcontrollers              []                 []              [delete get list update watch]
  replicationcontrollers/scale        []                 []              [get update]
  pods/log                            []                 []              [get]

简单概括如下:

ServiceAccount

作用

builder

构建Pod, 镜像流

deployer

部署Pod

default

Pod中默认使用该SA

我们知道要访问API Server,是需要证书、Token的,那SA是如何获取这些证书的呢?

我们看一下这个Pod中默认使用的SA: default.

代码语言:javascript
复制
$ oc describe sa default
Name:                default
Namespace:           test
Labels:              <none>
Annotations:         <none>
Image pull secrets:  default-dockercfg-7n87s
Mountable secrets:   default-dockercfg-7n87s
                     default-token-n9f6q
Tokens:              default-token-m29km
                     default-token-n9f6q
Events:              <none>

查看下这个default-dockercfg-7n87s 中都有些什么。

代码语言:javascript
复制
$ oc describe secret default-dockercfg-7n87s
Name:         default-dockercfg-7n87s
Namespace:    test
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: default
              kubernetes.io/service-account.uid: 6942fa8f-3ddf-4b6a-8bde-5a50e647f7cf
              openshift.io/token-secret.name: default-token-m29km
              openshift.io/token-secret.value:
                eyJhbGciOiJSUzI1NiIsImtpZCI6IkpseHB5c0tySnRtdXZjSFlvckNPTlVUZXMyaFFmM3F1cUtZdFNMQ3Nza2sifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiw...

Type:  kubernetes.io/dockercfg

Data
====
.dockercfg:  6723 bytes

使用get 指令获取详细的数据信息:

代码语言:javascript
复制
$ oc get  secret default-dockercfg-7n87s -o yaml
apiVersion: v1
data:
  .dockercfg: eyIxNzIuMzAuNTkuMTA1OjUwMDAiOnsidXNlcm5hbWUiOiJzZX...
kind: Secret
metadata:
...

把上面data中的数据用base64 解析出来,得到如下结果:

代码语言:javascript
复制
{
    "172.30.59.105:5000":{
        "username":"serviceaccount",
        "password":"eyJhbGciOiJSUzI1NiIsImtp...",
        "email":"serviceaccount@example.org",
        "auth":"c2VydmljZWFjY291bnQ6ZXlKaGJHY2lPaUpTVX..."
    },
    "image-registry.openshift-image-registry.svc.cluster.local:5000":{
        "username":"serviceaccount",
        "password":"eyJhbGciOiJSUzI1NiIsImtp...",
        "email":"serviceaccount@example.org",
        "auth":"c2VydmljZWFjY291bnQ...“
    },
    "image-registry.openshift-image-registry.svc:5000":{
        "username":"serviceaccount",
        "password":"eyJhbGciOiJSUzI1...",
        "email":"serviceaccount@example.org",
        "auth":"c2VydmljZWFjY291bnQ6ZX..."
    }
}

可以看到,这个secret(default-dockercfg-7n87s)存储了访问内部镜像仓库的auth 信息。

代码语言:javascript
复制
$ oc get svc -n openshift-image-registry 
NAME                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)     AGE
image-registry            ClusterIP   172.30.59.105   <none>        5000/TCP    31h
image-registry-operator   ClusterIP   None            <none>        60000/TCP   31h

既然上面的secret 是用来拉取镜像的,那么另一个应该就是来访问API Server的吧,我们来验证下:

代码语言:javascript
复制
$ oc get secret default-token-n9f6q -o yaml
apiVersion: v1
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FU...
  namespace: dGVzdA==
  service-ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...
  token: ZXlKaGJHY2lPaUpTVXpJMU5...
metadata:
  annotations:
...

$ echo -n "dGVzdA=="|base64 -D
test

可以看到该secret中包含了 API Server的CA公钥证书,所在的namespace,访问服务所需的证书,身份验证的Token信息。

我们部署一个pod来看下,它是如何被使用的。

代码语言:javascript
复制
$ cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'echo Hello OpenShift! && sleep 3600']
    
$ oc create -f pod.yaml 
pod/myapp-pod created

mac:~ jianzhang$ oc get pods
NAME        READY   STATUS    RESTARTS   AGE
myapp-pod   1/1     Running   0          2m32s

可以看到该Pod默认使用了default SA,并挂载default-token-n9f6q 到容器内部的 /var/run/secrets/kubernetes.io/serviceaccount目录下。该Pod中的应用程序可以读取这个挂载的Token 来访问API Server了!

代码语言:javascript
复制
mac:~ jianzhang$ oc get pods myapp-pod -o yaml
apiVersion: v1
kind: Pod
metadata:
... 
  name: myapp-pod
  namespace: test
...
spec:
  containers:
  - command:
    - sh
    - -c
    - echo Hello OpenShift! && sleep 3600
    image: busybox
    imagePullPolicy: Always
    name: myapp-container
    resources: {}
    securityContext:
      capabilities:
        drop:
        - MKNOD
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-n9f6q
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  imagePullSecrets:
  - name: default-dockercfg-7n87s
  nodeName: ...
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
 ...

最后,可以用下面的curl指令去试下看看会返回什么。祝大家5.20快乐!

代码语言:javascript
复制
$ oc rsh myapp-pod 
/ # ls
bin   dev   etc   home  proc  root  run   sys   tmp   usr   var
/ # ls /var/run/secrets/kubernetes.io/serviceaccount
ca.crt          namespace       service-ca.crt  token
/ # TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
/ # curl -H "Authorization: Bearer $TOKEN" --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt "https://openshift.default.svc.cluster.local/oapi/v1/users/-" 
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 3分钟云计算 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档