Kubernetes之ServiceAccount+Secret相关概念

     https://blog.csdn.net/BigData_Mining/article/details/88529157  

       API Server作为Kubernetes网关,是访问和管理资源对象的唯一入口,其各种集群组件访问资源都需要经过网关才能进行正常访问和管理。每一次的访问请求都需要进行合法性的检验,其中包括身份验证、操作权限验证以及操作规范验证等,需要通过一系列验证通过之后才能访问或者存储数据到etcd当中。如下图:
Kubernetes之ServiceAccount+Secret相关概念

每一个用户对API资源进行操作都需要通经过以下三个步骤:

第一步:对客户端访问进行认证操作,确认是否具有访问k8s权限
    token(共享秘钥)
    SSL(双向SSL认证)
....通过任何一个认证即表示认证通过,进入下一步
第二步:授权检查,确认是否对资源具有相关的权限
    ABAC(基于属性的访问控制)
    RBAC(基于角色的访问控制)
    NODE(基于节点的访问控制)
    WEB HOOK(自定义HTTP回调方法的访问控制)
第三步:准入控制(对操作资源相关联的其他资源是否有权限操作)

Kubernetes只对以下的API请求属性进行检查

user - username,uid
group - user group 
"extra"- 额外信息
API - API资源的对象 
Request path - 请求资源的路径(k8s使用resultful风格接口的API) 
 http://Node_IPaddr:6443/apis/apps/v1/namespaces/namespaces_name/resource_name/
HTTP 请求动作 - HTTP verbs get,post,put,和delete用于非资源请求
HTTP 请求动作映射到 API资源操作-  get,list,create,update,patch,watch,proxy,redirect,delete,和deletecollection用于请求resource
Resource -被访问(仅用于resource 请求)的resource 的ID或名字- *对于使用resource 的请求get,update,patch,和delete,必须提供resource 名称。
Subresource - 正在访问的subresource (仅用于请求resource )
Namespace - 正在访问对象的命名空间(仅针对命名空间的请求资源)
API group - 正在访问的API组(仅用于请求资源)。空字符串指定核心API组。

Secret解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用。

一、Secret

1、Secret类型

Secret有三种类型:
Opaque:base64编码格式的Secret,用来存储密码、密钥等;但数据也通过base64 –decode解码得到原始数据,所以加密性很弱。
kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。
kubernetes.io/service-account-token: 用于被serviceaccount引用。serviceaccout创建时Kubernetes会默认创建对应的secret。Pod如果使用了serviceaccount,对应的secret会自动挂载到Pod目录/run/secrets/ kubernetes.io/serviceaccount中。

2、Opaque Secret

Opaque类型的数据是一个map类型,要求value是base64编码格式

$ echo -n "admin" | base64
YWRtaW4=
$ echo -n "1f2d1e2e67df" | base64
MWYyZDFlMmU2N2Rm
secrets.yml

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  password: MWYyZDFlMmU2N2Rm
  username: YWRtaW4=

创建secret:kubectl create -f secrets.yml。

# kubectl get secret
NAME                  TYPE                                  DATA      AGE
default-token-cty7p   kubernetes.io/service-account-token   3         45d
mysecret              Opaque

注意:其中default-token-cty7p为创建集群时默认创建的secret,被serviceacount/default引用。

如果是从文件创建secret,则可以用更简单的kubectl命令,比如创建tls的secret

kubectl create secret generic helloworld-tls   --from-file=key.pem   --from-file=cert.pem

kubernetes.io/service-account-token: 用于被serviceaccount引用。serviceaccout创建时Kubernetes会默认创建对应的secret。Pod如果使用了serviceaccount,对应的secret会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中。

二、ServiceAccount

User Accounts 与 Service Accounts

Kubernetes区分普通帐户(user accounts)和服务帐户(service accounts)的原因

-普通帐户是针对(人)用户的,服务账户针对Pod进程。
-普通帐户是全局性。在集群所有namespaces中,名称具有惟一性。
-通常,群集的普通帐户可以与企业数据库同步,新的普通帐户创建需要特殊权限。服务账户创建目的是更轻量化,允许集群用户为特定任务创建服务账户。
-普通帐户和服务账户的审核注意事项不同。
-对于复杂系统的配置包,可以包括对该系统的各种组件的服务账户的定义。

Token controller

TokenController作为controller-manager的一部分运行。异步行为

-观察serviceAccount的创建,并创建一个相应的Secret 来允许API访问。
-观察serviceAccount的删除,并删除所有相应的ServiceAccountToken Secret
-观察secret 添加,并确保关联的ServiceAccount存在,并在需要时向secret 中添加一个Token。
-观察secret 删除,并在需要时对应 ServiceAccount 的关联

需要使用–service-account-private-key-file 参数选项将Service Account 密匙(key)文件传递给controller-manager中的Token controller。key用于 Service Account Token签名。同样,也需要使用–service-account-key-file 参数选项将相应的(public key)公匙传递给kube-apiserver ,公钥用于在认证期间验证Token。

Service Account Controller
Service Account Controller在namespaces里管理ServiceAccount,并确保每个有效的namespaces中都存在一个名为“default”的ServiceAccount。

什么是serviceaccount
Service Account 用来访问 kubernetes API,通过 kubernetes API 创建和管理,每个 account 只能在一个 namespace 上生效,存储在 kubernetes API 中的 Secrets 资源。kubernetes 会默认创建,并且会自动挂载到 Pod 中的 /run/secrets/kubernetes.io/serviceaccount 目录下。
Service account是为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的。它与User account不同

1.User account是为人设计的,而service account则是为Pod中的进程调用Kubernetes API而设计;
  2.User account是跨namespace的,而service account则是仅局限它所在的namespace;
  3.每个namespace都会自动创建一个default service account
  4.Token controller检测service account的创建,并为它们创建secret
  5.开启ServiceAccount Admission Controller后
        1.每个Pod在创建后都会自动设置spec.serviceAccount为default(除非指定了其他ServiceAccout)
        2.验证Pod引用的service account已经存在,否则拒绝创建
        3.如果Pod没有指定ImagePullSecrets,则把service account的ImagePullSecrets加到Pod中
        4.每个container启动后都会挂载该service account的token和ca.crt到/var/run/secrets/kubernetes.io/serviceaccount/  

当创建 pod 的时候,如果没有指定一个 service account,系统会自动在与该pod 相同的 namespace 下为其指派一个default service account。而pod和apiserver之间进行通信的账号,称为serviceAccountName。如下:

[ ~]# kubectl get pods
NAME                     READY     STATUS    RESTARTS   AGE
filebeat-ds-hxgdx        1/1       Running   1          34d
filebeat-ds-s466l        1/1       Running   2          34d
myapp-0                  1/1       Running   0          3h
myapp-1                  1/1       Running   0          3h
myapp-2                  1/1       Running   0          4h
myapp-3                  1/1       Running   0          4h
pod-vol-demo             2/2       Running   0          2d
redis-5b5d6fbbbd-q8ppz   1/1       Running   1          2d
[-master ~]# kubectl get pods/myapp-0 -o yaml |grep "serviceAccountName"
 serviceAccountName: default
[-master ~]# kubectl describe pods myapp-0
Name:               myapp-0
Namespace:          default
......
Volumes:
 ......
 default-token-j5pf5:
   Type:        Secret (a volume populated by a Secret)
   SecretName:  default-token-j5pf5
   Optional:    false

从上面可以看到每个Pod无论定义与否都会有个存储卷,这个存储卷为default-token-*** token令牌,这就是pod和serviceaccount认证信息。通过secret进行定义,由于认证信息属于敏感信息,所以需要保存在secret资源当中,并以存储卷的方式挂载到Pod当中。从而让Pod内运行的应用通过对应的secret中的信息来连接apiserver,并完成认证。每个 namespace 中都有一个默认的叫做 default 的 service account 资源。进行查看名称空间内的secret,也可以看到对应的default-token。让当前名称空间中所有的pod在连接apiserver时可以使用的预制认证信息,从而保证pod之间的通信。
验证

相关推荐