深入分析集群安全机制

文章目录

安全概述

  • 在任何提供资源或服务的系统上,认证和授权是两个不可或缺的功能,认证用于身份鉴定,即Authentication;授权用于实现权限分配,即Authorization。

  • API Server 作为 Kubernetes 集群系统的网关,是访问及管理资源对象的唯一入口,其它所有需要访问集群资源的组件,包括kube-controller-manager、kube-scheduler、kubelet和kube-proxy等集群基础组件、CoreDNS等集群的附件组件以及此前使用的kubectl 命令等,都需要经过此网关才能进行集群访问和管理。

  • 以上这些客户端均要经由 API Server 访问或改变集群状态并完成数据存储,并由它对每一次的访问请求都需要进行合法性的检验,其中包括身份鉴别、操作权限验证、Admission Control以及操作规范验证等,所有检测均正常完成且对象配置信息合法性检验无误之后才能访问或存入数据于后端存储系统etcd中。

  • 客户端认证操作由 API Server 配置的一个到多个认证插件完成。收到请求后,API Server依次调用为其配置的认证插件来认证客户端身份,直到其中一个插件可以识别出请求者的身份为止。

  • 授权操作也由一个到多个授权插件进行,它负责确定那些通过认证的用户是否有权限执行发出的资源操作请求,如创建、读取、删除等。随后,通过授权检测的用户所发出的操作请求还要经由一个或多个准入控制插件遍历检测,比如检查目标Namespace资源对象是否存在、检查是否违反系统资源限制等等,其中任何的检查失败都会导致该操作失败。

kubernetes通过一系列机制来实现集群的安全控制,其中包括API Server的认证授权、准入控制机制及保护敏感信息的Secret机制等。集群的安全性必须考虑如下几个目标:
1、保证容器与其所在宿主机的隔离
2、限制容器给基础设施或其他容器带来的干扰
3、最小权限原则—合理限制所有组件的权限,确保组件只执行它被授权的行为,通过限制单个组件的能力来限制它的权利范围
4、明确组件间边界的划分
5、划分普通用户和管理员的角色
6、在必要时允许将管理员权限赋予给普通用户
7、允许拥有Secret数据(Keys,Certs,Passwords)的应用在集群中运行。

安全流程:认证(Authentication 代表是谁)->授权(Authorization 能干什么)->Admission Control(做条件控制)
在这里插入图片描述

下面分别从 Authentication、Authorization、Admission Control、 Secret和Service Account 等方面来说明集群的安全机制。

API Server 认证管理

Kubernetes 集群中所有资源的访问和变更都是通过 Kubernetes API Server REST API 实现的,所以集群安全的关键点就在于如何识别并认证客户端身份(Authentication) ,以及随后访问权限的授权 (Authorization) 这两个关键问题。

任一 kubernetes API Server的访问都属于以下三种方式之一:

  • 证书方式访问的普通用户或进程,包括运维人员及 cubectl、kubelets 等进程;
  • 以Service Account 方式访问的 Kubernetes 的内部服务进程;服务账号(ServiceAccount)是提供给集群中的程序使用,以Secret资源保存凭据,挂载到pod中,从而允许集群内的服务调用k8s API。
  • 以匿名方式访问的进程。

Kubernetes 集群提供了以下用户身份认证方式:

  1. HTTPS 证书认证:基于 CA 根证书签名的双向数字证书认证方式
  2. HTTP Bearer Token (JWT Token)认证:通过一个 Bearer Token 识别合法用户。Service Account就是这种认证方式。我们都知道Service Account是和一个Secret对象紧密关联的,在Secret中就有一个加密的Token,这个Token就是一个JWT Token。
  3. OpenID Connect Token 第三方认证:通过第 OIDC 协议进行认证
  4. Webhook Token 认证:通过外部 Webhook 服务进行认证
  5. Authenticating Proxy 认证:通过认证代理程序进行认证

在这里插入图片描述
每一个kubectl命令背后都有一个kubeconf文件在支持,关于kubeconf文件的详情参见:Mastering the KUBECONFIG file

身份认证策略

Kubernetes 使用身份认证插件利用客户端证书、持有者令牌(Bearer Token)、身份认证代理(Proxy) 或者 HTTP 基本认证机制来认证 API 请求的身份。HTTP 请求发给 API 服务器时, 插件会将以下属性关联到请求本身:

  • 用户名:用来辩识最终用户的字符串。常见的值可以是 kube-admin 或 jane@example.com。
  • 用户 ID:用来辩识最终用户的字符串,旨在比用户名有更好的一致性和唯一性。
  • 用户组:取值为一组字符串,其中各个字符串用来标明用户是某个命名的用户逻辑集合的成员。 常见的值可能是 system:masters 或者 devops-team 等。
  • 附加字段:一组额外的键-值映射,键是字符串,值是一组字符串;用来保存一些鉴权组件可能 觉得有用的额外信息。

与其它身份认证协议(LDAP、SAML、Kerberos、X509 的替代模式等等)都可以通过 使用一个身份认证代理或 身份认证 Webhoook来实现。

认证流程

注:认证器的执行顺序为随机的,图中流向不代表固定顺序

HTTPS 证书认证

CA证书认证原理

在CA机构颁发给授权者的CA证书中绑定了证书拥有者的公钥和身份信息,并带有CA机构的的数字签名;在证书中也包含了 CA机构的名称,以便于依赖方从授信库中找到 CA机构的证书,用CA机构证书的公钥来验证CA证书上的数字签名。

CA机构为其颁发的CA证书申请者利用CA证书进行的非法行为承担举证责任。因此CA机构会严格核实申请者身份,并且通过公私钥、数字签名等技术来核实申请者利用CA证书进行非法操作时,来验证该CA证书确实由该机构颁发。

CA证书认证流程

1. 认证前准备
  1. 服务器端(客户端)(CA证书申请者) :
    • 生成自己的公/私钥对
    • 基于申请信息(如域名、申请者信息、公钥)生成CA证书申请文件CSR
    • 将CSR文件发给CA机构,向CA机构申请CA证书
  2. CA机构
    • 收到客户端或服务端的CSR
    • 要求申请者提交各种材料,核实申请者身份,确保是合法用户。CA机构会通过线上、线下多种手段验证申请者提供信息的真实性,如组织是否存在、企业是否合法(比如要求提交组织机构代码证或营业执照)、该组织是否拥有本域名的所有权等。
    • CA机构向申请者颁发CA证书,其中包含:
      • 申请者公钥、申请者组织信息、签发机构CA信息、有效时间、证书序列号等信息的明文
      • 同时还会包含一个签名和签名产生的算法:首先使用散列函数计算公开的明文信息的信息摘要,然后采用CA的私钥对信息摘要进行加密,密文即为签名。
    • 另外,CA机构向申请者颁发CA证书的同时,还会发送CA机构的证书。
  3. 服务器端(客户端):收到颁发给自己的CA证书,以及CA机构的证书。将CA机构的证书发送给客户端(服务器端)。客户端(服务器端)收到CA机构证书后,将其放到证书授信库中,授信库中的CA机构证书用于在线交换数据时对传递过来的服务器端(客户端)CA证书进行校验。通常情况下若CA机构是国际公认的权威CA机构,则该CA机构的证书会被预置到客户端浏览器(服务器端JDK)的授信库中,无需该步操作。若不是CA机构,则该步骤不能省略。
2. HTTPS通信CA证书认证过程
单向认证
  1. 客户端向服务端发起HTTPS请求。
  2. 服务端收到请求,向客户端发送服务器的CA证书,同时发送服务器端支持的加密套件,加密套件包含非对称算法和对称加密算法,用于对交换的业务数据进行加解密,JDK内置了一系列加密套件,可分别在服务器端和客户端配置支持的加密套件列表。
  3. 客户端校验服务器证书。客户端收到服务器的CA证书,从证书中找到CA机构,然后从授信库中找到该机构的CA证书,用机构CA证书中的公钥对服务器CA证书中的签名进行验签,以核实服务器CA证书是否为该机构颁发的合法CA证书,若授信库中找不到CA机构证书或验签失败,则中断请求,否则执行下一步。
  4. 客户端生成用于对业务数据加密的对称密钥发送给服务器:
    (1) 加密套件协商:根据自己支持的加密套件,结合服务器端支持的加密套件,选择一个两端都支持的加密套件,然后从该加密套件中,选择一个对称加密算法,生成一个随机对称密钥;
    (2) 再用服务器的公钥对生成的对称密钥进行加密并将密文发送给服务器。客户端和服务器端之后交换的业务数据,都以对称密钥来加密。
  5. 服务器接收对称加密密钥:客户端收到对称密钥数据后,用私钥解密,得到对称密钥明文。
  6. 客户端发送请求到服务器,处理逻辑包括:
    (1) 利用对称密钥对请求明文加密得到请求密文;
    (2) 将请求密文发送给服务器。
  7. 服务器收到请求,执行以下操作:
    (1) 利用对称密钥进行解密,得到请求明文;
    (2) 处理业务请求,生成响应数据明文
    (3) 用对称密钥对响应数据明文加密得到响应密文
    (4) 生成数字签名:对响应数据明文采取指定的摘要算法计算摘要,之后自己的私钥对得到的摘要进行加密,生成数字签名
    (5)将响应密文和数字签名一并发送给客户端。
  8. 客户端收到响应,执行以下操作:
    (1) 用对称密钥界面响应数据,得到响应明文
    (2) 响应报文验签(防篡改校验):同时用服务器端的公钥解密数字签名,得到信息摘要1,并用与服务器端采用同样的摘要算法对响应明文计算摘要得到信息摘要2,最后对比摘要1是否与摘要2一致,若二者一致,说明服务器端的响应报文没有被篡改过,响应结束。
双向认证(与单向的主要区别是请求报文多了数字签名)
  1. 客户端向服务端发起HTTPS请求。
  2. 服务端收到请求,向客户端发送服务器的CA证书,同时发送服务器端支持的加密套件,加密套件包含非对称算法和对称加密算法,用于对交换的业务数据进行加解密,JDK内置了一系列加密套件,可分别在服务器端和客户端配置支持的加密套件列表。
  3. 客户端校验服务器证书。客户端收到服务器的CA证书,从证书中找到CA机构,然后从授信库中找到该机构的CA证书,用机构CA证书中的公钥对服务器CA证书中的签名进行验签,以核实服务器CA证书是否为该机构颁发的合法CA证书,若授信库中找不到CA机构证书或验签失败,则中断请求,否则执行下一步。
  4. 服务器端校验客户端证书:客户端向服务器发送客户端证书进行校验,校验方式与客户端校验服务器证书的逻辑相同。
  5. 客户端生成用于对业务数据加密的对称密钥发送给服务器:
    (1) 加密套件协商:根据自己支持的加密套件,结合服务器端支持的加密套件,选择一个两端都支持的加密套件,然后从该加密套件中,选择一个对称加密算法,生成一个随机对称密钥;
    (2) 再用服务器的公钥对生成的对称密钥进行加密并将密文发送给服务器。客户端和服务器端之后交换的业务数据,都以对称密钥来加密。
  6. 服务器接收对称加密密钥:客户端收到对称密钥数据后,用私钥解密,得到对称密钥明文。
  7. 客户端发送请求到服务器,处理逻辑包括:
    (1) 利用对称密钥对请求明文加密得到请求密文;
    (2) 生成数字签名:对请求明文采取指定的摘要算法计算摘要,之后自己的私钥对得到的摘要进行加密,生成数字签名
    (3) 将请求密文及数字签名发送给服务器。
  8. 服务器收到请求,执行以下操作:
    (1) 利用对称密钥进行解密,得到请求明文;
    (2) 请求报文验签(防篡改校验):用客户端的公钥解密数字签名,得到信息摘要1,并用与客户端采用同样的摘要算法对响应明文计算摘要得到信息摘要2,最后对比摘要1是否与摘要2一致,若二者一致,说明客户端的请求报文没有被篡改过。
    (3) 处理业务请求,生成响应数据明文
    (4) 用对称密钥对响应数据明文加密得到响应密文
    (5) 生成数字签名:对响应数据明文采取指定的摘要算法计算摘要,之后自己的私钥对得到的摘要进行加密,生成数字签名
    (6)将响应密文和数字签名一并发送给客户端。
  9. 客户端收到响应,执行以下操作:
    (1) 用对称密钥界面响应数据,得到响应明文
    (2) 响应报文验签(防篡改校验):同时用服务器端的公钥解密数字签名,得到信息摘要1,并用与服务器端采用同样的摘要算法对响应明文计算摘要得到信息摘要2,最后对比摘要1是否与摘要2一致,若二者一致,说明服务器端的响应报文没有被篡改过,响应结束。

k8s使用https(x509 CA 证书)认证

k8s使用TLS双向认证,APIServer启动时使用–client-ca-file指定客户端的证书文件,用作请求的认证。

HTTP Bearer token 认证(即jwt token)

HTTP Bearer token 认证原理

参见:

定义:为了验证使用者的身份,需要客户端向服务器端提供一个可靠的验证信息,称为Token,这个 Token 被放在 HTTP header 头里,通常是一个有一定长度的难以被篡改的字符串,由Json数据格式组成,通过hash散列算法生成一个字符串,所以称为Json Web Token(Json表示令牌的原始值是一个Json格式的数据,web表示是在互联网传播的,token表示令牌,简称JWT)。

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

Although JWTs can be encrypted to also provide secrecy between parties, we will focus on signed tokens. Signed tokens can verify the integrity of the claims contained within it, while encrypted tokens hide those claims from other parties. When tokens are signed using public/private key pairs, the signature also certifies that only the party holding the private key is the one that signed it.
(JSON Web令牌(JWT)是一种开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地传输JSON对象信息。此信息可以被验证和信任,因为它是数字签名的。JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。

虽然JWT可以被加密,以提供双方之间的保密性,但我们将重点关注签名令牌。签名令牌可以验证其中包含的声明的完整性,而加密令牌可以向其他方隐藏这些声明。当使用公钥/私钥对对令牌进行签名时,签名还证明只有持有私钥的一方才是签名方。)

JWT结构

JWT分为三部分:

  • header(头部)
  • playload(有效载荷)
  • Signature(签名)
header(头部)

header(头部),包括typ和alg两部分,结构如下:

{
 #类型,固定为jwt
"typ" : "JWT",
# 签名算法,如SHA256、HmacSHA256,SHA256表示直接加密,HmacSHA256表示用秘钥进行加密。
"alg" : "HS256"
}

对上述json串进行Base64Url 编码后,得到JWT token的第一部分。

playload(有效载荷)

The second part of the token is the payload, which contains the claims. Claims are statements about an entity (typically, the user) and additional data. There are three types of claims: registered, public, and private claims.
(令牌的第二部分是有效载荷,其中包含claims。claims是关于实体(通常是用户)和其他数据的声明。有三种类型claims:注册声明, 公开声明和私人声明

  • 注册声明:这些声明是一组预定义的声明,不是强制性但是推荐的,以提供一组有用的、可互操作的声明。其中一些是:iss(发行者)、exp(到期时间)、sub(主题)、aud(受众)和其他。
    请注意,声明名称只有三个字符,因为JWT是紧凑的。
  • 公开声明:使用JWT的人可以随意定义这些声明。但为了避免冲突,它们应该在IANA JSON Web令牌注册表中定义,或者定义为包含抗冲突命名空间的URI。
  • 私人声明:这些是自定义声明,是为了在同意使用它们的各方之间共享信息而创建的,既不是注册声明也不是公开声明。

payload举例:

{
  "sub": "1234567890",
  "exp": 1300819380,
  "name": "John Doe",
  "admin": true
}

对上述json串进行Base64Url 编码后,得到JWT token的第二部分。
注意:对于已签名的令牌,此信息虽然受到保护,防止篡改,但任何人都可以读取。除非加密,否则不要将机密信息放入JWT的有效载荷或标头元素中。

Signature(签名)

To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.

For example if you want to use the HMAC SHA256 algorithm, the signature will be created in the following way:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

The signature is used to verify the message wasn’t changed along the way, and, in the case of tokens signed with a private key, it can also verify that the sender of the JWT is who it says it is.

(
要创建签名部分,您必须获取编码的标头、编码的有效负载、密钥和标头中指定的算法,并对其进行签名。
例如,如果要使用HMAC SHA256算法,则将按以下方式创建签名:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

签名用于验证消息在发送过程中没有被更改,并且,在使用私钥签名的令牌的情况下,它还可以验证JWT的发送者是它所说的人。
)

将所有内容放在一起,生成JWT Token字符串

Putting all together
The output is three Base64-URL strings separated by dots that can be easily passed in HTML and HTTP environments, while being more compact when compared to XML-based standards such as SAML.

The following shows a JWT that has the previous header and payload encoded, and it is signed with a secret.
在这里插入图片描述
If you want to play with JWT and put these concepts into practice, you can use jwt.io Debugger to decode, verify, and generate JWTs.

在这里插入图片描述


输出是三个由点分隔的Base64 URL字符串,可以在HTML和HTTP环境中轻松传递,与基于XML的标准(如SAML)相比更紧凑。

  • A=base64UrlEncode(header);
  • B=base64UrlEncode(payload);
  • TEMP=base64UrlEncode(header) + “.” + base64UrlEncode(payload);
  • C=HMACSHA256(TEMP,secret);
  • 最终的JWT token串=A+"."+B+"."+C;

下面显示了一个JWT,它编码了前一个报头和有效载荷,并用密钥签名。
在这里插入图片描述
如果您想玩JWT并将这些概念付诸实践,可以使用JWT。io调试器,用于解码、验证和生成JWT。
在这里插入图片描述

JSON Web令牌如何工作?

在身份验证中,当用户使用其凭据成功登录时,将返回一个JSON Web令牌。由于令牌是凭证,因此必须非常小心地防止安全问题。通常,您不应将令牌保存的时间超过所需的时间。

由于缺乏安全性,您也不应将敏感会话数据存储在浏览器存储中。
Whenever the user wants to access a protected route or resource, the user agent should send the JWT, typically in the Authorization header using the Bearer schema. The content of the header should look like the following:

当用户想要访问受保护的路由或资源时,用户代理都应该发送JWT,通常将其放置在Authorization请求头中。Authorization请求头内容应如下所示:

Authorization: Bearer token字符串

在某些情况下,这可以是无状态授权机制。服务器的受保护路由将检查Authorization标头中是否存在有效的JWT,如果存在,则允许用户访问受保护的资源。如果JWT包含必要的数据,则可以减少查询数据库以获取某些操作的需要,尽管情况并非总是如此。

注意,如果您通过HTTP头发送JWT令牌,则应尽量防止它们变大。某些服务器不接受超过8 KB的标头。如果您试图在JWT令牌中嵌入太多信息,例如通过包含所有用户的权限,则可能需要另一种解决方案,例如 Auth0 Fine-Grained Authorization

如果令牌是在Authorization标头中发送的,则跨源资源共享(CORS)不会成为问题,因为它不使用cookie。

JSON Web令牌(JWT)优势

让我们来谈谈JSON Web令牌(JWT)与简单Web令牌(SWT)和安全断言标记语言令牌(SAML)相比的优势。

由于JSON不像XML那么冗长,所以在编码时,它的大小也更小,使得JWT比SAML更紧凑。这使得JWT成为在HTML和HTTP环境中传递的好选择。

安全性方面,SWT只能使用HMAC算法由共享密钥对称签名。然而,JWT和SAML令牌可以使用X.509证书形式的公钥/私钥对进行签名。与签名JSON的简单性相比,使用XML数字签名签名XML而不引入晦涩的安全漏洞是非常困难的。

JSON解析器在大多数编程语言中都很常见,因为它们直接映射到对象。相反,XML没有自然的文档到对象映射。这使得使用JWT比使用SAML断言更容易。

关于使用,JWT在互联网规模上使用。这突出了在多个平台(尤其是移动平台)上客户端处理JSON Web令牌的方便性。

k8s中使用HTTP Bearer token 认证

这种认证方式是专为k8s节点准备的,避免每个节点都要手动配置TLS证书,在apiserver启动时指定–enable-bootstrap-token-auth参数来启用这种认证方式,详细说明见官方文档:
启动引导令牌

bearertoken的认证方式是在请求头里放入bearer令牌,令牌的格式为 [a-z0-9]{6}.[a-z0-9]{16}。第一个部分是令牌的 ID;第二个部分 是令牌的 Secret。对应http请求头的格式是:

Authorization: Bearer xxxxxx.xxxxxxxxxxxxxxxx

ServiceAccount(SA)认证

启用方式为APIServer命令使用–service-account-key-file参数指定一个为token签名的PEM秘钥文件。

SA认证是jwt形式的认证,使用方式与bearer token类似,也是放在请求头里,内容为Base64编码,header格式为:

Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo0NTk0LCJ1c2VybmFtZSI6InlpbndlbnFpbiIsImV4cCI6MTU3MDY3NDEyNywiZW1haWwiOiIifQ.djC2w5l3IiXYv7slZtGzlMzLc3_oPuR1M0dM9FwoaUU

token哪里来呢?答案就是ServiceAccount。

SA是一种面向集群内部应用需要调用APIServer的场景所设计的认证方式。在创建ServiceAccount资源时,可以显示地设置标签将ServiceAccount绑定给某Deploy/sts/pod,也可以在Deploy/sts/pod的声明文件里显示指定ServiceAccount。ServiceAccount会自动创建Secret资源,token秘钥存放其中。

在相应的容器层面,token信息是一个secret对象,该对象在pod启动时会被挂载进容器中,包含3个文件:

  • namespace文件:指明命名空间
  • ca.crt文件:APIServer的公钥证书,容器用来校验APIServer
  • token文件: 存放在Secret里的JWT token
    在集群上找一个例子,以kube-proxy举例:

Service Account采用的就是JWT Token,Service Account是和一个Secret对象紧密关联的,在Secret中就有一个加密的Token字段,这个Token就是一个JWT Token。

在Kubernetes中通过以下方式使用JWT token

  1. 通过在HTTP Authroziation 头部添加Bear JWTToken来传递JWT token
    Authorization: Bearer xxxxxx.xxxxxxxxxxxxxxxx
  2. 该Token采用的是RS256非对称加密的算法进行加密
  3. 每个Bearer Token都对应一个用户名,存储在api-server能访问的一个文件中,文件路径需要通过为 API Server 服务设置–token-auth-file=SOMEFILE 指定。该文件为 CSV 文本文件格式,每行内容都由以 下字段组成:
    token , user, uid [, groupnames)
    对其中各字段说明如下
    • token:必填, Token 字符串
    • user: 必填,用户名
    • uid:必填,用户 ID
    • groupnarnes:可选,用户组列表,如果有多个组,则必须使用双引号
      Token 文件 例如下
      3lada4fd-adec-460c-809a-9e56ceb75269,admin,1
      a3974741-f7b6-4796-8d9f-907d8f94e37b, john,2 ,“groupl , group2,group3”
  4. 该token使用私钥加密,通过 API Server 启动参数--service-account-key-file设置私钥文件,如果没有指定该参数 ,则会采用 API Server 自己的私钥进行加密。另外,如果 API Server 设置了启动参数--service-account-lookup=true, API Server 就会验证 Token 是否在 tcd 中存在,如果已从 etcd 中删 除,则将注销容器中 Token的有效性.
    kubernetes需要PKI(public key infrastructure,公钥基础设施)证书来基于TLS的安全的认证。
  5. k8s使用x509证书中CN(Common Name)以及(Organization)字段对应k8s中的user和group(要为用户包含多个组成员身份,需在证书中包含多个组织字段),将Authentication和RBAC Authorization结合到了一起,巧妙地将Control Plane中的各个核心User和Group、与操作权限(ClusterRole)进行了绑定(ClusterRoleBinding)。

WebhookToken认证

Webhook 身份认证是一种用来验证持有者令牌的回调机制。

  • --authentication-token-webhook-config-file 指向一个配置文件,其中描述 如何访问远程的 Webhook 服务。
  • --authentication-token-webhook-cache-ttl 用来设定身份认证决定的缓存时间。 默认时长为 2 分钟。

配置文件使用 kubeconfig 文件的格式。文件中,clusters 指代远程服务,users 指代远程 API 服务 Webhook。下面是一个例子:

# Kubernetes API 版本
apiVersion: v1
# API 对象类别
kind: Config
# clusters 指代远程服务
clusters:
  - name: name-of-remote-authn-service
    cluster:
      certificate-authority: /path/to/ca.pem         # 用来验证远程服务的 CA
      server: https://authn.example.com/authenticate # 要查询的远程服务 URL。必须使用 'https'。

# users 指代 API 服务的 Webhook 配置
users:
  - name: name-of-api-server
    user:
      client-certificate: /path/to/cert.pem # Webhook 插件要使用的证书
      client-key: /path/to/key.pem          # 与证书匹配的密钥

# kubeconfig 文件需要一个上下文(Context),此上下文用于本 API 服务器
current-context: webhook
contexts:
- context:
    cluster: name-of-remote-authn-service
    user: name-of-api-sever
  name: webhook

当客户端尝试在 API 服务器上使用持有者令牌完成身份认证( 如前所述)时, 身份认证 Webhook 会用 POST 请求发送一个 JSON 序列化的对象到远程服务。 该对象是 authentication.k8s.io/v1beta1 组的 TokenReview 对象, 其中包含持有者令牌。 Kubernetes 不会强制请求提供此 HTTP 头部。

要注意的是,Webhook API 对象和其他 Kubernetes API 对象一样,也要受到同一 版本兼容规则约束。 实现者要了解对 Beta 阶段对象的兼容性承诺,并检查请求的 apiVersion 字段, 以确保数据结构能够正常反序列化解析。此外,API 服务器必须启用 authentication.k8s.io/v1beta1 API 扩展组 (–runtime-config=authentication.k8s.io/v1beta1=true)。

POST 请求的 Body 部分将是如下格式:

{
  "apiVersion": "authentication.k8s.io/v1beta1",
  "kind": "TokenReview",
  "spec": {
    "token": "<持有者令牌>"
  }
}

远程服务应该会填充请求的 status 字段,以标明登录操作是否成功。 响应的 Body 中的 spec 字段会被忽略,因此可以省略。 如果持有者令牌验证成功,应该返回如下所示的响应:

{
  "apiVersion": "authentication.k8s.io/v1beta1",
  "kind": "TokenReview",
  "status": {
    "authenticated": true,
    "user": {
      "username": "janedoe@example.com",
      "uid": "42",
      "groups": [
        "developers",
        "qa"
      ],
      "extra": {
        "extrafield1": [
          "extravalue1",
          "extravalue2"
        ]
      }
    }
  }
}

而不成功的请求会返回:

{
  "apiVersion": "authentication.k8s.io/v1beta1",
  "kind": "TokenReview",
  "status": {
    "authenticated": false
  }
}

HTTP 状态码可用来提供进一步的错误语境信息。

以上摘自官方文档Webhook 令牌身份认证

OpenID Connect Token 第三方认证

p385-p389
https://blog.csdn.net/kaikevin01/article/details/78885594

https://zhuanlan.zhihu.com/p/158937640
https://zhuanlan.zhihu.com/p/89020647
https://blog.csdn.net/it_lihongmin/article/details/122463522
https://baijiahao.baidu.com/s?id=1741213567884461841&wfr=spider&for=pc

https://blog.csdn.net/weixin_34416649/article/details/88018833

BasicAuth认证

BasicAuth是一种简单的基础http认证,用户名、密码写入http请求头中,用base64编码,防君子不防小人,安全性较低,因此很少使用。快速略过

启动apiserver时,使用–basic-auth-file参数指定csv文件,csv里面以逗号切割,存放用户名、密码、uid。

Authenticating Proxy (认证代理)----即RequestHeader认证

在这种方式 ,将 API Server 配置为从 HTTP Header (例如 X-Remote-User 字段 )对
用户进行识别。这需要与 Authenticating Proxy 程序一同工作, Authenticating Proxy 设置HTTP Header 的值。
简而言之,就是在apiserver之前有一个代理服务器,通过代理服务器的名义,可以将相关的认证信息在请求头透传给apiserver,以通过apiserver的认证。代理服务的相关信息需要预先配置。

要使用这种认证方式 ,就需要为 API Server 配置以下启动参数:

  • --requestheader-username-headers :必需字段,大小写不敏感。用来设置要获得用户身份所要检查的头部字段名称列表(有序)。第一个包含数值的字段会被用来提取用户名。
  • --requestheader-group-headers :可选字段,在 Kubernetes 1.6 版本以后支持,大小写不敏感。 建议设置为 “X-Remote-Group”。用来指定一组头部字段名称列表,以供检查用户所属的组名称。 所找到的全部头部字段的取值都会被用作用户组名。
  • --requestheader-extra-headers-prefix :可选字段,在 Kubernetes 1.6 版本以后支持,大小写不敏感。 建议设置为 “X-Remote-Extra-”。用来设置一个头部字段的前缀字符串,API 服务器会基于所给 前缀来查找与用户有关的一些额外信息。这些额外信息通常用于所配置的鉴权插件。 API 服务器会将与所给前缀匹配的头部字段过滤出来,去掉其前缀部分,将剩余部分 转换为小写字符串并在必要时执行百分号解码 后,构造新的附加信息字段键名。原来的头部字段值直接作为附加信息字段的值。

例如,使用下面的配置:

--requestheader-username-headers=X-Remote-User
--requestheader-group-headers=X-Remote-Group
--requestheader-extra-headers-prefix=X-Remote-Extra-

针对所收到的如下请求:

GET / HTTP/1.1
X-Remote-User: fido
X-Remote-Group: dogs
X-Remote-Group: dachshunds
X-Remote-Extra-Acme.com%2Fproject: some-project
X-Remote-Extra-Scopes: openid
X-Remote-Extra-Scopes: profile

会生成下面的用户信息:

name: fido
groups:
  - dogs
  - dachshunds
extra:
  acme.com/project:
    - some-project
  scopes:
    - openid
    - profile

为了防范头部信息侦听,在请求中的头部字段被检视之前, 身份认证代理需要向 API 服务器提供一份合法的客户端证书, 供后者使用所给的 CA 来执行验证。 警告:不要 在不同的上下文中复用 CA 证书,除非你清楚这样做的风险是什么以及 应如何保护 CA 用法的机制。

  • --requestheader-client-ca-file :必需字段,给出 PEM 编码的证书包。 在检查请求的头部字段以提取用户名信息之前,必须提供一个合法的客户端证书, 且该证书要能够被所给文件中的机构所验证。
  • --requestheader-allowed-names :可选字段,用来给出一组公共名称(CN)。 如果此标志被设置,则在检视请求中的头部以提取用户信息之前,必须提供 包含此列表中所给的 CN 名的、合法的客户端证书。

使用kubeadm默认部署的集群,就启用了requestheader的配置:

Anonymous认证

启用匿名请求支持之后,如果请求没有被已配置的其他身份认证方法拒绝,则被视作 匿名请求(Anonymous Requests)。这类请求获得用户名 system:anonymous 和 对应的用户组 system:unauthenticated。

例如,在一个配置了令牌身份认证且启用了匿名访问的服务器上,如果请求提供了非法的 持有者令牌,则会返回 401 Unauthorized 错误。 如果请求没有提供持有者令牌,则被视为匿名请求。

在 1.5.1-1.5.x 版本中,匿名访问默认情况下是被禁用的,可以通过为 API 服务器设定 --anonymous-auth=true 来启用。

在 1.6 及之后版本中,如果所使用的鉴权模式不是 AlwaysAllow,则匿名访问默认是被启用的。 从 1.6 版本开始,ABAC 和 RBAC 鉴权模块要求对 system:anonymous 用户或者 system:unauthenticated 用户组执行显式的权限判定,所以之前的为 * 用户或 * 用户组赋予访问权限的策略规则都不再包含匿名用户。

以上摘自官方文档 匿名请求

API Server 授权管理

当客户端发起API Server调用时,API Server内部要先进行用户认证,然后执行用户授权流程,即通过授权策略来决定一个API调用是否合法。对合法用户进行授权并且随后在用户访问时进行鉴权,是权限与安全系统的重要一环。

授权就是授予不同的用户不同的访问权限。

鉴权策略分类

目前支持6种鉴权策略,每种鉴权策略对应一个鉴权器,使用的鉴权策略需要在APIServer启动时以参数–authorization-mode的形式指定,多种策略同时指定时使用’,'号连接:

策略分类有:

  • --authorization-mode=ABAC 基于属性的访问控制(ABAC)模式允许你 使用本地文件配置策略。
  • --authorization-mode=RBAC 基于角色的访问控制(RBAC)模式允许你使用 Kubernetes API 创建和存储策略。
  • --authorization-mode=Webhook WebHook 是一种 HTTP 回调模式,允许你使用远程 REST 端点管理鉴权。
  • --authorization-mode=Node 节点鉴权是一种特殊用途的鉴权模式,专门对 kubelet 发出的 API 请求执行鉴权。
  • --authorization-mode=AlwaysDeny 该标志阻止所有请求。仅将此标志用于测试。
  • --authorization-mode=AlwaysAllow 此标志允许所有请求。仅在你不需要 API 请求 的鉴权时才使用此标志。

与上一篇的认证模块不同的是,当配置多个鉴权模块时,鉴权模块按顺序检查,靠前的模块具有更高的优先级来允许或拒绝请求

来看看现有的kubeadm部署集群启用的鉴权策略:

可以看到,默认启用了Node授权和RBAC授权模块。

鉴权结果
对于每一个请求的鉴权结果,有专门为其设计的健全结果描述结构体,如下:

vendor/k8s.io/apiserver/pkg/authorization/authorizer/interfaces.go:148

type Decision int

const (
	// 拒绝
	DecisionDeny Decision = iota
	// 允许,则鉴权流程视为成功,请求顺利进入
	DecisionAllow
	// 无操作,进入下一个鉴权模块,相当于pass
	DecisionNoOpinion
)

审查请求属性

Kubernetes 仅审查以下 API 请求属性:

  • 用户 - 身份验证期间提供的 user 字符串。
  • 组 - 经过身份验证的用户所属的组名列表。
    额外信息 - 由身份验证层提供的任意字符串键到字符串值的映射。
  • API - 指示请求是否针对 API 资源。
  • 请求路径 - 各种非资源端点的路径,如 /api 或 /healthz。
  • API 请求动词 - API 动词 get、list、create、update、patch、watch、 proxy、redirect、delete 和 deletecollection 用于资源请求。 要确定资源 API 端点的请求动词,请参阅 确定请求动词。
  • HTTP 请求动词 - HTTP 动词 get、post、put 和 delete 用于非资源请求。
  • Resource - 正在访问的资源的 ID 或名称(仅限资源请求)- 对于使用 get、update、patch 和 delete 动词的资源请求,你必须提供资源名称。
  • 子资源 - 正在访问的子资源(仅限资源请求)。
  • 命名空间 - 正在访问的对象的命名空间(仅适用于命名空间资源请求)。
  • API 组 - 正在访问的 API 组 (仅限资源请求)。空字符串表示核心 API 组

鉴权流程图

在这里插入图片描述

授权目标主体

ABAC 授权模式详解

基于属性的访问控制(Attribute-based access control - ABAC)定义了访问控制范例,其中通过使用将属性组合在一起的策略来向用户授予访问权限。

启用ABAC鉴权器需要额外增加一个--authorization-policy-file=SOME_FILENAME参数,指定一个json格式的授权策略文件,是一种静态的权限配置方式。

授权策略文件

在API Server启用ABAC模式时,需要指定授权策略文件的路径和名称(–authorization-policy-file=SOME_FILENAME),授权策略文件里的每一行都以一个Map类型的JSON对象进行设置,这被称为“访问策略对象”。通过设置访问策略对象中的apiVersion、kind、spec属性来确定具体的授权策略。

其中,apiVersion当前版本为abac.authorization.kubernetes.io/v1beta1;kind被设置为Policy;spec指详细的策略设置,包括主题属性、资源属性、非资源属性这三个字段

  • 主体属性:授权的目标主体可以是以下三者之一:
    • user(用户名):字符串类型,该字符串类型的用户名来源于Token文件(–token-auth-file参数设置的文件)或基本认证文件中用户名称段的值。由字符串进行标识,例如人名 (alice mail 地址 (bob@examp le.com 、用户ID (1001) 等,通常应该在客户端 CA 证书中进行设置。需要注意的是, Kubernetes内置了一组系统级别的用户/用户组,以 system :" 开头,用户自定义的名称不应该使用这个前缀
    • group(用户组):用户组与用户名类似,自定义的用户组由字符串进行标识,通常也应该在客户端 CA 证书中进行设置,并且要求不以 “system:" 为前缀。在被设置为“system:authenticated”时表示匹配所有已认证的请求,在被设置为“system:unauthenticated”时表示匹配所有未认证的请求
    • ServiceAccountKubernetes 系统中的用户名会被设置成以 “system:serviceaccount:"为前缀的名称,其所属的组名会被设置成以 “system:serviceaccounts:" 为前缀的名称
  • 资源属性
    • API Group(API组):字符串类型,表明匹配哪些API Group,例如extensions或*(表示匹配所有API Group)。
    • namespace(命名空间):字符串类型,表明该策略允许访问某个Namespace的资源,例如kube-system或*(表示匹配所有Namespace)。
    • resource(资源):字符串类型,API资源对象,例如pods或*(表示匹配所有资源对象)。
  • 非资源属性
    • nonResourcePath(非资源对象类路径):非资源对象类的URL路径,例如/version或/apis,*表示匹配所有非资源对象类的请求路径,也可以设置为子路径,/foo/*表示匹配所有/foo路径下的所有子路径。
      当使用ABAC授权模式时,下列特殊资源必须显式地通过nonResourcePath属性进行设置:
      • API版本协商过程中的/api、/api/、/apis、和/apis/
      • 使用kubectlversion命令从服务器获取版本时的/version。
      • create/update操作过程中的/swaggerapi/*。
    • readonly(只读标识):布尔类型,当它的值为true时,表明仅允许GET请求通过。

授权策略文件举例如下:

{
    "apiVersion":"abac.authorization.kubernetes.io/v1beta1",
    "kind":"Policy",
    "spec":{
        "user":"podManager",
        "namespace":"*",
        "resource":"pods",
        "readonly":true
    }
}

ABAC授权算法

API Server进行ABAC授权的算法为:在API Server收到请求之后,首先识别出请求携带的策略对象的属性,然后根据在策略文件中定义的策略对这些属性进行逐条匹配,以判定是否允许授权。如果有至少一条匹配成功,那么这个请求就通过了授权(不过还是可能在后续其他授权校验中失败)。
常见的策略配置如下:

  • 要允许所有已认证用户做某件事,可以写一个策略,将group属性设置为system:authenticated
  • 要允许所有未认证用户做某件事,可以把策略的group属性设置为system:unauthenticated
  • 要允许一个用户做任何事,将策略的API Group、namespace、resource和nonResourcePath属性设置为“*”即可。

常见的 ABAC 授权示例

在这里插入图片描述

对ServiceAccount进行授权

Service Account 成一个 ABAC 用户名 username ,用户名按照以下命名规则生成:
system:serviceaccount:<narnespace>:<serviceaccountname>

创建新的命名空间时,会产生一个如下名称的 Service Account:
system:serviceaccount:<namespace>:default

如果希望 kube-system 命名空间中的 Service Account “default” 具有全部权限,就需要在策略文件中加入如下内容:

{
	"apiVersion" : "abac.authorization.kubernetes.io/vlbetal",
	"kind" : "Policy",
	"spec": {
		"user" : "system:serviceaccount:kube-system:default",
		"namespace" : "*", 
		"resource": "*", 
		"apiGroup ": " *" 
	}
}

RBAC 授权模式详解

p397-p422

RBAC (Role-Based Access Control, 基于角色的访问模式控制 )从 Kubernetes 1.5版本开始引入,在 1.6 版本时升级为 Beta 版本,在 1.8 版本时升级为 GA 稳定版本。作为kubeadm 安装方式的默认选项,足见其重要性。
要使用 RBAC 授权模式,首先需要在 ku e-apiserver 服务的启动参数 --authorization-mode(授权模式)的列表中加上 RBAC, 例如 --authorization-rnode =…,RBAC

RBAC优势

在这里插入图片描述

RBAC API 资源对象说明

在RBAC 管理体系中, Kubernetes 引入了 资源对象 Role、ClusterRole、RoleBinding和ClusterRoleBinding。同其他 API 资源对象一样,用户可以使用 kubectl 或者 API 调用等方式操作这些资源对象。

ClusterRoleBinding, RoleBinding, ClusterRole, Role 四种对象之间的关系如下图:

角色(Role)和集群角色 (ClusterRole)

一个角色就是一组权限的集合,在 Role 中设置的权限都是许可 Permissive 形式的,不可以设置拒绝 (Deny) 形式的规则。

Role 设置的权限将会局限于命名空间 (namespace)范围内,如果需要在集群级别设置权限,就需要使用 ClusterRole了。
在这里插入图片描述
在这里插入图片描述

角色绑定 (RoleBinding)和 集群角色绑定 (ClusterRoleBinding)

角色绑定或集群角色绑定用来把一个角色绑定定到 一个目标主体 ,绑定目标可以是User (用户)、Group (组)或者 Service Account
RoleBinding 用于某个命名空间的授权,ClusterRoleBinding 用于集群范围 的授权

角色绑定 RoleBinding 示例

RoleBinding 可以与属于相同命名空间的Role 或者某个集群级别的 ClusterRole 绑定,完成对某个主体的授权
在这里插入图片描述
在这里插入图片描述
RoleBinding 也可以引用 ClusterRole ,对目标主体在其所在命名空间授予在 ClusterRole中定义的权限。一种常见的用法是集群管理员预先定义好一组 ClusterRole (权限设置),然后在多个命名空间中重复使用这些ClusterRole。
在这里插入图片描述
在这里插入图片描述

集群角色绑定 ClusterRoleBinding 示例

在这里插入图片描述

RBAC 对资源的引用方式

在这里插入图片描述
在这里插入图片描述

聚合ClusterRole

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

常见的授权规则示例

下面对常见的角色 (Role)和 角色绑定 (RoleBinding)内容进行示例说明,在本示例中仅展示关键 rules 配置的授权规则内容,省略资源对象本身的元数据内容。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

常见的角色绑定示例

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

kubernetes系统默认(内置)的授权规则 (ClusterRole和ClusterRoleBinding)

在这里插入图片描述
下面对系统提供的默认授权规则 (ClusterRole和ClusterRoleBinding) 进行说明。

API 发现 (API Discovery) 相关 ClusterRole

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

面向用户(User-facing)的ClusterRole

在这里插入图片描述
在这里插入图片描述

核心组件(Core Component) 的 ClusterRole

在这里插入图片描述
在这里插入图片描述

其它组件的 ClusterRole

在这里插入图片描述

系统内置控制器(Controller)的 ClusterRole

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

预防权限提升和授权初始化

防止一个具备一定权限的用户,创建超出其权限范围的Role(ClusterRole)或RoleBinding(ClusterRoleBinding)。

要允许该用户具备上述能力,可以为该用户设置创建 Role(ClusterRole)、和RoleBinding(或ClusterRoleBinding)的权限。
在这里插入图片描述

使用kubectl 命令行工具管理 RBAC

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

对ServiceAccount 的授权管理

默认的 RBAC 策略为控制平面组件、节点和控制器授予有限范围的权限,但是不会为命名空间 kube-system 之外的 ServiceAccount 授予任何权限(除了所有已认证用户都具有的Discovery 权限) 这使得管理员可以为特定的 ServiceAccount 授予所需的权限。细粒度的权限管理能够提供更高的安全性,但也会提高管理成本,粗放的授权方式可能会给ServiceAccount 提供不必要的权限,但更易于管理。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

从ABAC 更新为 RBAC 的建议

在这里插入图片描述
在这里插入图片描述
过渡到使用 RBAC 授权模式之后,管理员应该调整集群的访问控制策略,以确保它们满足信息安全的相关需求。

Webhook 授权模式详解

p394-p397

Node 授权模式详解

Node 授权模式针对的 Subject Node 不是 user 或者应用的 Service Account, 是专门对 kubelet 发起的 API 请求进行授权的管理模式。
在这里插入图片描述

准入控制器(Admission Control)

准入控制器概述

突破了之前所说的认证和鉴权两道关卡之后,客户端的调用诸求就能够得到 API Server 的真正响应了吗?答案是:不能 !这个请求还要通过 Admission Control (准入控制)所控制的一个准入控制链的层层考验,才能获得成功的响应。 Kubernetes 官方标准的“关卡”有 30 多个,还允许用户自定义扩展。
Admission Control 配备了一个准入控制器的插件列表,发送给 API Server 的任何请求都需要通过列表中每个准入控制器的检查,检查不通过, API Server 就会拒绝此调用请求。此外,准入控制器插件能够修改请求参数以完成一些自动化任务,比如 ServiceAccount这个控制器插件。

配置准入控制器

在这里插入图片描述
在这里插入图片描述

内置准入控制器列表

当前可配置的准入控制器插件如下。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Service Account

Service Account作用

在 Pod 中访问 Kubernetes API Server 服务时,是以 Service 方式访问名为 Kubernetes 的这个服务的,使用Service Account认证方式进行认证

default Service Account及secret

k8s默认为每一个命名空间都创建一个名为"default"的ServiceAccount,并为该ServiceAccount创建一个名为Tokens的Secret,这个 Secret 同时是 Mountable secrets,即可挂载的secret。
若Pod 在定义时没有指定 spec.serviceAccountName 属性,系统会自动将其赋值为 default,即大家都使用同一个命名空间中的default Service Account,并将default Service Account的secret会挂载到 该pod内各容器的指定目录下(默认是/run/secrets/kubernetes.io/serviceaccount/目录),用来协助完成 Pod中的进程访问 API Server 时的 身份鉴权。
在这里插入图片描述

在这里插入图片描述
从上面的输出信息中可以看到, default-token- 77oyg 包含三个数据项,分别是 token、ca.crt和namespace。

查看pod容器内的/run/secrets/kubernetes.io/serviceaccount/目录。
在这里插入图片描述
可以看到,k8s将secret对象的三个key(token、ca.crt、namespace)作为文件名,key的值(base64编码)进行base64解码后作为文件内容。

若pod想使用非 default Service Account, 则需要在定义时指定:
在这里插入图片描述
另外,一个 Service Account 可以包括多个 Secret 对象:
在这里插入图片描述
在这里插入图片描述

Service Account与Secret运行机制

Service Account 的正常工作离不开以下控制器: Service Account Controller、 Token Controller、 Admission Controller

  • Service Account Controller 的工作相对简单,它会监听 Service Account 和Namespace这两种资源对象的事件,如果在一个 Namespace 中没有默认的 Service Account, 那么它会为该
    Namespace 创建一个默认的 Service Account 对象,这就是在每个 Namespace 下都有一个名为 default的 Service Account 的原因。
  • Token Controller 监听以下事件:
    • 监听 Service Account 的事件,包括
      • 对Service Account创建事件,如果发现在新建的 Service Account 里没有对应的 Service Account Secret, 则会用 API Server 私钥 (–service-account-private-key-file 指定的文件)创建一个 Token, 并用该 Token、API Server 的CA 证书等三个信息产生一个新的 Secret 对象,然后放入刚才的 Service Account 中。
      • 对Service Account 删除事件,若监听到该事件,则自动删除与该 Service Account 相关的所有 Secret。
    • 监听 Secret 的创建和删除事件,确保与对应的 Service Account的关联关系正确。
  • Admission Controller 的重要作用:当我们在 API Server 的准入控制链中启用了 Service Account 类型的准入控制器时(这也是默认的设置),即在 kube-apiserver启动参数中包括下面的内容时:
    –admission_control=ServiceAccount 则针对 Pod 新增或修改的请求, Admission Controller 验证 Pod 里的Service Account 是否合法,并做出如下控制操作:
    • 如果 spec.serviceAccount 域没有被设置,则 Kubernetes 默认为其指定名称为 default 的Service Account
    • 如果 Pod spec.serviceAccount 域指定了不存在的 Service Account, 则该 Pod操作会被拒绝。
    • 如果在 Pod 中没有指定 ImagePullSecrets, 那么这个 spec .serviceAccount 域指定的Service Account的ImagePullSecrets 会被加入该 Pod中。
    • 给Pod 添加一个特殊的 volumeSource ,在该 Volume 中包含 Service Account Secret 中的 Token。
    • 给Pod 里的每个容器都增加对应的 VolumeSource, 将包含 Secret的Volume 挂载到Pod 中所有容器的指定目录下 (/var/run/secrets/kubemetes.io/serviceaccount)。

Kubernetes 1.6 版本以后,我们可以禁止自动创建 Service Account 对应的 Secret 了,在Service Account YAML 文件中增加automountServiceAccountToken: false 属性即可,同时可以在某个 Pod YAML 文件中增加此属性,以实现同样的效果。

Secret 私密凭据

Secret对象的作用

Secret 的主要作用是保管私密数据,比如密码、 OAuth Tokens、SSH Keys 等信息 。将这些私密信息放在 Secret 对象中比直接放在 Pod 或docker Image更安全,也更便于使用和分发。

Secret对象创建举例

下面的例子用于创建一个 Secret(secrets.yaml):

apiVersion : v1
kind: Secret 
metadata: 
  name: mysecret 
  type: Opaque
data : 
  password: dmFsdWUtMgOK 
  username: dmFsdWUtMQOK

# kubectl create -f secrets.yaml
在上面的例子中, data 域各子域的值必须为 BASE64 编码值,其中 password 域和usemame BA E64 编码前的值分别为 value-1和value-2。

Secret对象使用场景

1. 创建 Pod 时,通过为 Pod 指定 Service Account 来自动使用 Secret

主要用在 API Server 鉴权方面,前面提到过。

2. 通过挂载该 Secret Pod 来使用Secret

此场景将一个 Secret 通过挂载的方式添加到 Pod的Volume中。
在这里插入图片描述
在这里插入图片描述
在使用 Mount 方式挂载 Secret 时, Secret data 个域的 Key 值将被设置为目录中的文件名, Value 值被 BASE64 解码后存储在相应的文件中。

结论:我们可以通过 Sectet 保管其他系统的敏感信息(比如数据库的用户名和密码),并以 Mount 的方式将 Secret 载到 Container ,然后通过访问目录中文件的方式获取该敏感信息。

只有所有 Volume 都挂载成功, Pod 中的Container 才会被启动。 在kubelet 启动 Pod 中的 Container 后, Container 中与 Secret 相关的Volume 将不会被改变,即使 Secret 本身被修改。为了使用更新后的 Secret, 必须删除Pod, 并重新创建一个新 Pod。

当Secret 通过 Volume 方式被使用时 ,对 Secret 数据的任何修改都会引发 Volume 的同步更新 ,如果在一个业务系统中有大最 Secret 数据以Volume 方式被使用,则可能带来性能问题。另外, Secret 数据也可能被意外修改从而导致系统出现问题,为此, kubernetes 1.19版本默认开启了ImmutableEphemeralVolumes 新特性,我们可以通过设置 Secret的immutable 属性为 true 创建一个不可变的 Secret 对象

3. Docker 镜像下载时使用,通过指定 Pod spec.ImagePullSecrets 来使用Secret

应用流程如下:

在这里插入图片描述
在这里插入图片描述
每个单独的 Secret 大小都不能超过1 MB, Kubernetes 不鼓励创建大的 Secret, 因为如果使用大的 Secret ,则将大量占用 API Server和kubelet 的内存。当然,创建许多小的 Secret也能耗尽 API Server和kubelet 的内存。

Pod 安全策略

p419-p444

Pod安全策略的作用

  • 为了更精细地控制 Pod 启动或更新时安全管理, Kubernetes 1.5 版本开始引入PodSecurityPolicy 资源对象对 Pod 安全策略进行管理,到 1.18 版本时达到 Beta 阶段。
  • 通过对 PodSecurityPolicy 的设置,管理员可以控制 Pod 的运行条件,以及可以使用系统的哪些功能
  • PodSecurityPolicy 是集群范围内资源对象不属于命名空间范图

PodSecurityPolicy 工作机制

PodSecurityPolicy 配置详解

PodSecurityPolicy 策略示例

PodSecurityPolicy 的RBAC 授权

Pod 安全设置(Security Context)详解

Pod Security Context 定义

Kubernetes 可以为 Pod 置应用程序运行所需的权限或者访问控制等安全设置,涉及多种Linux Kernel 安全相关的系统参数,这些安全设置被称为 Security Context, 在Pod或Container 级别通过 securityContext 字段进行设置(如果在 Pod和Container 级别都设置了相同的安全字段,则容器将使用 Container 级别的设置)。
管理员设置的集群范围的 PodSecurityPlicy 策略会对 Pod的Security Context 安全设置进行校验,对于不满 PodSecurityPolicy 策略的 Pod, 系统将禁止创建。

Pod Security Context 可设置的安全策略内容

Pod Security Context 安全策略包括但不限于以下内容(将来可能会扩展):

  • 访问控制相关:基于Use ID和Group ID 进行控制,例如 runAsUser、runAsGroup、runAsNonRoot、Supplementary Group等。
  • seLinuxOptions : SELinux 相关设置。
  • 特权模式(privileged): 是否以特权模式运行。
  • Linux 能力(capabilities)相关:设置应用程序允许使用的 Linux 能力。
  • AppArmor: 设置对应用程序访问进行权限控制的 profile。
  • Seccomp: 设置允许容器使用的系统调用 (System Calls) 的profile。
  • allowPrivilegeEscalation: 是否允许提升权限。
  • readOnlyRootFilesystem:根文件系统是否为只读属性。

通过为 Pod 或容器进行应用程序运行所需的权限或者访问控制等安全设置,管理员就能够对容器应用进程的安全管理进行更加精细的控制,同时配合集群范围的PodSecurityPolicy 策略设置,使整个 Kubernetes 集群中的服务运行更加安全。

配置示例

Pod 级别的 Security Context 安全设置,作用于该 Pod 内的全郘容器

在这里插入图片描述
在这里插入图片描述

验证如下:
在这里插入图片描述

Pod Volume 权限修改策略

在这里插入图片描述
在这里插入图片描述

Container 级别的安全设置,作用于特定的容器

在这里插入图片描述

为Container 设置可用的 Linux 能力 (Capabilities)
  1. 我们先看一个没有添加这些能力的容器环境的默认能力设置:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    Linux 能力 关参数的命名以 Cap 开头,例如 Capinh、CapPrm、CapEff等。
    2.接下来为容器设置允许使用的 Lin 能力增加两个: CAP_NET _ADMIN
    和CAP_SYS_TIME, 通过 securityContext.capabilities 字段进行设置, YAML 文件的内容如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

为Pod或Container设置SELinux 标签

Security Context 还可以通过 seLinuxOptions 字段为 Pod或Container 设置 SELinux标签 level=“s0:c123,c456”, 例如:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值