专栏首页Liusy01k8s之ServiceAccount

k8s之ServiceAccount

导读

上一篇说了k8s的RBAC授权模式,今天就来简单看一下其中涉及到的ServiceAccount。

简介

k8s创建两套独立的账号系统,原因如下:

(1)User账号给用户用,Service Account是给Pod里的进程使用的,面向的对象不同

(2)User账号是全局性的,Service Account则属于某个具体的Namespace

(3)User账号是与后端的用户数据库同步的,创建一个新用户通常要走一套复杂的业务流程才能实现,Service Account的创建则需要极轻量级的实现方式,集群管理员可以很容易地为某些特定任务创建一个Service Account

(4)对于一个复杂的系统来说,多个组件通常拥有各种账号的配置信息,Service Account是Namespace隔离的,可以针对组件进行一对一的定义,同时具备很好的“便携性”

Controller Manager创建了ServiceAccount Controller和Token Controller这两个安全相关的控制器。其中ServiceAccount Controller一直监听Service Account和Namespace的事件,如果在一个Namespace中没有default Service Account,那么Service Account会给Namespace创建一个默认(default)的Service Account。

如果Controller manager进程在启动时指定API Service私钥(service-accountprivate-key-file参数),那么Controller manager会创建Token Controller,Token Controller也监听Service Account事件。

当我们在API Server的鉴权过程中启用了Service Account类型的准入控制器,即在kube-apiserver启动参数中包括下面的内容时:

--admission_control=ServiceAccount

则针对Pod新增或修改的请求,Service Account准入控制器会验证Pod里的Service Account是否合法:

(1)如果spec.serviceAccount域没有被设置,则Kubernetes默认为其指定名称为default的Service Account。

(2)如果指定了spec.serviceAccountName并且不是default,如果此Service Account不存在,则该Pod操作失败。

(3)如果在Pod中没有指定ImagePullSecrets,那么这个spec.serviceAccount域指定的Service Account的ImagePullSecrets会自动加入到该Pod中。

(4)给Pod添加一个特殊的Volume,在该Volume中包含ServiceAccount Secret中的Token,并将Volume挂载到Pod中所有容器的指定目录下(/var/run/secrets/kubernetes.io/serviceaccount)。

ServiceAccount

ServiceAccount是一种账号,给运行在Pod里面的进程提供必要的身份证明。

做过业务系统的同学应该都知道系统中会有一种叫做角色的定义,角色是拥有某些权限的集合,而上一篇说到的Role就是这个角色,而这个ServiceAccount就相当于是拥有某个角色的账号,也就拥有了某些权限。

为了确保k8s集群的安全,API Server都会对客户端进行安全认证。在Pod中访问API Server服务时,是以Service方式访问名为Kubernetes这个服务的,是以类似HTTP Token的新认证方式:Service Account Auth,Pod在调用API Server时,在Http Header中传递了一个Token字符串,类似于之前提到的Http Token认证方式,有以下几处不同:

(1)Token内容来自Pod指定路径下的一个文件(文件名为token),由Kubernetes Controller进程用API Server的私钥(--service-account-private-zkey-file指定的私钥)签名指定生成的一个JWT Secret。

(2)通过HTTPS方式与API Server建立连接后,会用Pod里指定路径下的一个CA证书(文件名为ca.crt)验证API Server发来的证书,验证是否为CA证书签名的合法证书。

(3)API Server收到Token后,采用自身私钥(service-accountkey-file指定,如果没有指定,则默认采用tls-private-key-file指定的参数)对Token进行合法性验证。

上面的认证过程中所涉及的Pod中的以下三个文件:token、ca.crt、namespace,三个文件都在/run/secrets/kubernetes.io/serviceaccount目录下

这三个文件由于参与到Pod进程和API Server认证的过程中,起到了类似Secret(私密凭据)的作用,所以被称为Kubernetes Secret对象,Secret从属于Service Account资源对象,一个Service Account对象里面可以包括多个不同的Secret对象,分别用于不同目的的认证活动。

一个Secret也是有这三样东西:

查看Service Account详细信息

kubectl describe serviceaccounts

查看Secret

kubectl get secrets

在每个Namespace下都有一个名为default的默认Service Account对象,在这个ServiceAccount里面有一个名为Tokens的可以当做Volume被挂载到Pod里的Secret,当Pod启动时,这个Secret会自动被挂载到Pod的指定目录下,用来协助完成Pod中的进程访问API Server时的身份鉴权。

一个ServiceAccount可包含多个Secret

其中

(1)名为Tokens的Secret用于访问API Server的Secret,也被称为Service Account Secret。

(2)名为imagePullSecrets的Secret用于下载容器镜像时的认证过程,通常镜像库运行在Insecure模式下,所以这个为空

(3)用户自定义的其他Secret,用于用户的进程。

如果一个Pod在定义时没有指定spec.serviceAccountName属性,则会默认赋值为default,可进行如下指定:

apiVersion: v1
kind: Pod
metadata:
  name: pod
spec:
  containers:
  - name: podtest
    image: nginx
  serviceAccountName: myServiceAccount

创建ServiceAccount

apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-admin
  namespace: kube-system

将这个ServiceAccount跟ClusterRole进行绑定:

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard-admin
  labels:
    k8s-app: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard-admin
  namespace: kube-system

这样ServiceAccount就拥有了ClusterRole的权限

在Pod中使用ServiceAccount

apiVersion: v1
kind: Pod
metadata:
  name: pod
  namespace: kube-system
spec:
  containers:
  - name: podtest
    image: nginx
  serviceAccountName: kubernetes-dashboard-admin

结尾

秋风吹落叶,天气微凉,注意保暖!

本文分享自微信公众号 - Liusy01(Liusy_01),作者:Liusy01

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-11-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • k8s基础概念及术语

    上一篇简单介绍了一下k8s是什么以及如何使用kubeadm快捷安装,今儿来聊一下k8s的几个基础概念及术语。k8s中的资源都可以使用yaml文件进行描述。(文章...

    Liusy
  • 深入理解Pod(二)

    将应用所需的配置信息与程序进行分离,可以使应用程序更好的被复用,通过不同的配置实现更灵活的功能。如果将应用打包成镜像,再用环境变量或者外挂文件的方式挂载配置,在...

    Liusy
  • 详解volatile关键字和原子引用

    开始了解一下Java高并发的东东,这个东西因为Liusy所在的厂也不是互联网大厂,平时工作上的内容也就是进行CRUD业务处理,并不涉及高并发的业务...

    Liusy
  • VUE+WebPack前端游戏设计:实现外星人的动态下滑特效

    望月从良
  • MySql - InnoDB - 事务 , Php版

    (出处:https://cloud.tencent.com/developer/user/1148436/activities) 1,前序 由于要重构APP(...

    林冠宏-指尖下的幽灵
  • 聊聊springboot2的ScheduledTasksEndpoint

    本文主要研究下springboot2的ScheduledTasksEndpoint

    codecraft
  • 如何合理构造一个Uploader工具类(设计到实现)

    本文将带你基于ES6的面向对象,脱离框架使用原生JS,从设计到代码实现一个Uploader基础类,再到实际投入使用。通过本文,你可以了解到一般情况下根据需求是如...

    coder_koala
  • 实现一个promise之完成对x的处理并测试

    完成之后,promise官方推荐了一个测试方法,只有通过测试才算符合标准的promise:

    wade
  • 将文件拖到此处,点击上传

    达达前端
  • Egret语法DataGroup使用案例

    class Main extends egret.DisplayObjectContainer{ public constructor() { ...

    苦咖啡

扫码关注云+社区

领取腾讯云代金券