• Kubernetes之ServiceAccount


    ServiceAccount 是什么

    Service Account为Pod中的进程和外部用户提供身份信息。所有的kubernetes集群中账户分为两类,Kubernetes管理的serviceaccount(服务账户)和useraccount(用户账户)。

    大家都知道api server的集群的入口,对于kunbernetes的api server 是肯定不能随便访问。所以我们必须需要一些认证信息。例如:

    当用户访问集群(例如使用kubectl命令)时,apiserver 会将您认证为一个特定的 User Account(目前通常是admin,除非您的系统管理员自定义了集群配置)。Pod 容器中的进程也可以与 apiserver 联系。 当它们在联系 apiserver 的时候,它们会被认证为一个特定的 Service Account。

    因为kubernetes是高度模块化,所有认证方式和授权方式都可以通过插件的方式让客户自定义的,可以支持很多种。客户端请求的时候首先需要进行认证,认证通过后再进行授权检查,因有些操作需要级联到其他资源或者环境,但是级联环境是否有授权权限,这时候需要准入控制。

    认证插件

    • bearer token  当使用来自 http 客户端的 bearer token 时,API server 期望 Authorization header 中包含 Bearer token 的值。Bearer token 必须是一个字符串序列,只需使用 HTTP 的编码和引用功能就可以将其放入到 HTTP header 中。
    • 客户端证书  客户端请求前需要,需要发送api server的办法的证书,由api server来确认是否他来签署的,引用的文件必须包含一个或多个证书颁发机构,用于验证提交给 API server 的客户端证书。如果客户端证书已提交并验证,则使用 subject 的 Common Name(CN)作为请求的用户名。反过来,api server也要验证客户端的证书,所有对于客户端也应该有一个证书,提供api server 验证,此过程是双向验证。
    • HTTP BASE 认证: 通过用户名+密码方式认证。

    当启用了多个认证模块时,第一个认证模块成功认证后将短路请求,不会进行第二个模块的认证。API server 不会保证认证的顺序。

    用户账户需要哪些信息:

    • user 保护UserName和UID,UserName是标识最终用户的字符串,UID是标识最终用户的字符串,比用户名更加一致切唯一。
    • group 一组将用户和常规用户组相关联的字符串
    • extra  包含其他有用认证信息的字符串列表

    上述是来自集群外部的访问,我们可以理解成是User Account,是给kubernetes集群外部用户,例如(系统管理员、用户/租户等)。Service Account而是给运行在Pod的容器、或者Pod使用的身份认证。

    正常情况下,为了确保kubernetes集群的安全性,Api Server 都会给客户端进行身份认证,但是Pod访问Kubernetes Api Server服务时,也是需要身份认证的。如下图:

     我们在每一个namespace下看到都有一个secret,而我们看svc的时候,api server通过svc的访问访问的,他们的Endpoints是api server。

    $ kubectl  get svc 
    NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
    kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   52d
    $ kubectl describe svc kubernetes 
    Name:              kubernetes
    Namespace:         default
    Labels:            component=apiserver
                       provider=kubernetes
    Annotations:       <none>
    Selector:          <none>
    Type:              ClusterIP
    IP:                10.96.0.1
    Port:              https  443/TCP
    TargetPort:        6443/TCP
    Endpoints:         172.16.138.40:6443,172.16.138.41:6443
    Session Affinity:  None
    Events:            <none>
    $ kubectl get secret  -n default
    NAME                  TYPE                                  DATA      AGE
    default-token-lplp6   kubernetes.io/service-account-token   3         52d
    $ kubectl get secret  -n ingress-nginx
    NAME                                       TYPE                                  DATA      AGE
    default-token-v58zx                        kubernetes.io/service-account-token   3         52d

    每个Namespace下都有一个名为default的默认的 Service Account对象,这个Service Account里面有一个名为Tokens的可以当作Volume一样被Mount到Pod里的secret,当Pod启动时候,这个Secret会自动Mount到Pod的指定目录下,用来完成Pod中的进程访问API server时的身份认证过程。下面可以看到

    $  kubectl describe pod my-demo
    .....
    Volumes:
      appindex:
        Type:          HostPath (bare host directory volume)
        Path:          /data/pod/myapp
        HostPathType:  DirectoryOrCreate
      default-token-lplp6:
        Type:        Secret (a volume populated by a Secret)
        SecretName:  default-token-lplp6
        Optional:    false
    .....

    创建一个serviceaccount

    $ kubectl create serviceaccount jaxzhai
    $ kubectl get sa 
    NAME      SECRETS   AGE
    default   1         52d
    jaxzhai   1         8s
    $ kubectl describe sa jaxzhai
    Name:                jaxzhai
    Namespace:           default
    Labels:              <none>
    Annotations:         <none>
    Image pull secrets:  <none>
    Mountable secrets:   jaxzhai-token-9n5th
    Tokens:              jaxzhai-token-9n5th
    Events:              <none>
    $ kubectl get secret
    NAME                  TYPE                                  DATA      AGE
    default-token-lplp6   kubernetes.io/service-account-token   3         52d
    jaxzhai-token-9n5th   kubernetes.io/service-account-token   3         4m

    这里我们看到Kubernetes集群会自动创建一个token的secert,并被jaxzhai这个serviceaccount引用。

    设置非默认的 service account,只需要在 pod 的spec.serviceAccountName 字段中将name设置为您想要用的 service account 名字即可。

    在 pod 创建之初 service account 就必须已经存在,否则创建将被拒绝。

    您不能更新已创建的 pod 的 service account。

    在pod中使用service account

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-sa-demo
      namespace: default
      labels:
        name: myapp
        tier: appfront
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80
      serviceAccountName: jaxzhai
    
    $ kubectl apply -f myapp-serviceaccount.yaml 
    pod/my-sa-demo created
    $ kubectl describe pod my-sa-demo 
    ......
    Volumes:
      jaxzhai-token-9n5th:
        Type:        Secret (a volume populated by a Secret)
        SecretName:  jaxzhai-token-9n5th
        Optional:    false
    QoS Class:       BestEffort
    ......
  • 相关阅读:
    2016年 CodePen 最热门的前端代码 Top 100
    HttpClientHelper
    .net core mvc 简易登录
    senparc 第三方授权回调,保存授权信息到文件
    盛派微信Sdk .Net Core 初始化注册服务信息
    分享一个gif截图工具
    C# 单例模式
    获取微信AccessToken,保存在内存中,过期后重新获取
    .NET Core WebAPI Swagger使用
    .net Core 读取配置文件参数
  • 原文地址:https://www.cnblogs.com/xzkzzz/p/9889173.html
Copyright © 2020-2023  润新知