Kubernetes 集群安全机制说明和认证

机制说明


Kubernetes 作为一个分布式集群的管理工具,保证集群的安全性是其一个重要的任务。API Server 是集群内部各个组件通信的中介,也是外部控制的入口。所以 Kubernetes 的安全机制基本就是围绕保护 API Server 来设计的。Kubernetes 使用了认证(Authentication)、鉴权(Authorization)、准入控制(AdmissionControl)三步来保证API Server的安全。

当用户或者pod访问apiserver的时候来镜像身份的识别,这就是认证。 

Authentication 认证


HTTP Token 认证:通过一个 Token 来识别合法用户(或者理解为通过一个字符串识别合法用户)

HTTP Token 的认证是用一个很长的特殊编码方式的并且难以被模仿的字符串 - Token 来表达客户的一种方式。Token 是一个很长的很复杂的字符串,每一个 Token 对应一个用户名存储在 API Server 能访问的文件中(这种存储方式不是存储在etcd上面,而是一个文件当中,安全性可想而知)。当客户端发起 API 调用请求时,需要在 HTTP Header 里放入 Token。

HTTP  Base 认证:通过用户名+密码的方式认证

用户名+:+密码用 BASE64 算法进行编码后的字符串放在 HTTP Request 中的 Heather Authorization 域里发送给服务端,服务端收到后进行解码,获取用户名及密码。这样服务器就知道用户名密码,然后进行判定。

上面两种都不太安全,都是服务器去验证客户端的机会,但是客户端没有认证服务器。也就是服务器可以认证客户端是否是一个合理的合法的。但是客户端不知道这个服务是不是真的,万一是一个假的也不是不可能。上面的一种放在文件当中不安全,第二种用户名密码方式太费劲。

最严格的 HTTPS 证书认证:基于 CA 根证书签名的客户端身份认证方式

在整个K8s域当中签署一个CA根证书,所有节点的证书都是以这个根证书签发出来的子证书,并且实现的是https的双向认证。

[root@k8s-master ~]# ls /etc/kubernetes/pki/ | grep ca
ca.crt
ca.key

I、HTTPS 证书认证:

II、需要认证的节点

对于认证来说白了就是用户或者pod访问apiserver的时候来进行身份的识别,集群的组件etcd  controller manager等需要访问apiserver。那么也需要有双向认证的证书存在

 两种类型

  1. Kubenetes 组件对 API Server 的访问:kubectl、Controller Manager、Scheduler、kubelet、kube-proxy(CA证书认证)
  2. Kubernetes 管理的 Pod 容器对API Server的访问:Pod(dashboard 也是以 Pod 形式运行,SA Service Account认证)

安全性说明

  • Controller Manager、Scheduler与API Server在同一台机器,所以直接使用APIServer的非安全端口访问,-insecure-bind-address=127.0.0.1  (加密的交互是一个消耗资源的过程,由于API Server和Controller Manager、Scheduler在同一台机器,所以访问本地的回环接口就可以访问API Server,没有一个双向的https证书的加密,这里没有必要使用https加密)
  • kubectl、kubelet、kube-proxy 访问 API Server 就都需要证书进行 HTTPS 双向认证(是远程访问的过程,这个就要https的双向认证了)

证书颁发

  1. 手动签发:通过 k8s 集群的跟 ca 进行签发 HTTPS 证书
  2. 自动签发:kubelet 首次访问 API Server 时,使用 token 做认证,通过后,Controller Manager 会为kubelet 生成一个证书,以后的访问都是用证书做认证了

III、kubeconfig

kubeconfig文件包含集群参数(CA证书、API Server地址),客户端参数(上面生成的证书和私钥),集群context信息(集群名称、用户名)。Kubenetes 组件通过启动时指定不同的kubeconfig文件可以切换到不同的集群

IV、ServiceAccount

Pod中的容器访问API Server。因为Pod的创建、销毁是动态的,所以要为它手动生成证书就不可行了。Kubenetes使用了Service Account解决Pod 访问API Server的认证问题

(为什么不使用组件之间的双向认证呢,如果使用双向认证就会几百个证书,因为有几百个pod,并且pod会销毁,所以证书就相当于没用了,同时创建证书对集群会造成压力)

V、Secret 与 SA 的关系

Kubernetes 设计了一种资源对象叫做 Secret,分为两类,一种是用于 ServiceAccount 的 service-account-token,另一种是用于保存用户自定义保密信息的 Opaque。ServiceAccount 中用到包含三个部分:Token、ca.crt、namespace

  • token是使用 API Server 私钥签名的 JWT。用于访问API Server时,Server端认证
  • ca.crt,根证书。用于Client端验证API Server发送的证书
  • namespace, 标识这个service-account-token的作用域名空间
root@nginx-6799fc88d8-drb2s:/run/secrets/kubernetes.io/serviceaccount# pwd
/run/secrets/kubernetes.io/serviceaccount
root@nginx-6799fc88d8-drb2s:/run/secrets/kubernetes.io/serviceaccount# ls
ca.crt	namespace  token

Json web token(JWT),是为了在网络应用环境间传递声明而执行的一种基于 Json 的开放标准((Rrc 7519】)该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(sso)场景。jwt的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声面明德患,该 token 也可直接被用于认证,也可被加密

默认情况下,每个 namespace 都会有一个 ServiceAccount,如果 Pod 在创建时没有指定 ServiceAccount,就会使用 Pod 所属的 namespace 的 ServiceAccount,默认挂载目录/run/secrets/kubernetes.io/serviceaccount

这个serviceaccount会生成一个token保存在secret里面,serviceaccount和secret是有关联的,用sercert保存token的 (Kubernetes 自身也有一些内置的 Secret,主要用来保存访问 APIServer 的 service account token)

[root@k8s-master ~]# kubectl get serviceaccount
NAME      SECRETS   AGE
default   1         65d

[root@k8s-master ~]# kubectl describe sa default
Name:                default
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   default-token-j9294
Tokens:              default-token-j9294
Events:              <none>

[root@k8s-master ~]#  kubectl  get secret default-token-j9294
NAME                  TYPE                                  DATA   AGE
default-token-j9294   kubernetes.io/service-account-token   3      65d

#这里保存的是token信息
[root@k8s-master ~]#  kubectl  describe secret default-token-j9294
Name:         default-token-j9294
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: default
              kubernetes.io/service-account.uid: 3b6f6ac8-fb89-42e0-9a45-d14680ee6157

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1066 bytes
namespace:  7 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6InR0cTRHNDNQUGFMeUZ5Rnp1azZnSUEyRVU0WEY1dWdEMEYwd056ZnNkWWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tajkyOTQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjNiNmY2YWM4LWZiODktNDJlMC05YTQ1LWQxNDY4MGVlNjE1NyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.cbHTMxahgVgImt2ll-cN4pJIbtN_gMks9Wg-Aqc3hvntktpmPFN0TRk9eT362HoYFpf6RB5pJvH4Xg-eACoZ9IfOcIqDK8ky14jk1z5TolgXrLv1OqacxI8PlRJBDvmjIEX8iLIxcFE63gJQpBoDscCOHMMs-i1cuygdRr2vEq47XX_ykxPg49pw1hRaG4DSLjfCTA7kAG3R-9NnhGCpexruryDd4ftqaKKf12BTmT8xgydcvNWzzkgnYMnoF-o8cfaLqd9c_-TOr3h1VGyoop925CCrTXqHxBU6VPEnSRozegIfDbLwbyhp4Wq3CTDyBAc4YSm8WbqRPyikNRa-ow


[root@k8s-master ~]# kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6799fc88d8-wp9kx   1/1     Running   0          50m


#指定了sa,也就是k8s在创建pod的时候会将创建的sa会注入到pod当中,里面程序带着
[root@k8s-master ~]# kubectl exec -it nginx-6799fc88d8-wp9kx sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# cd /run/secrets/kubernetes.io/
# ls
serviceaccount
# cd serviceaccount
# ls
ca.crt	namespace  token
# cat token
eyJhbGciOiJSUzI1NiIsImtpZCI6InR0cTRHNDNQUGFMeUZ5Rnp1azZnSUEyRVU0WEY1dWdEMEYwd056ZnNkWWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tajkyOTQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjNiNmY2YWM4LWZiODktNDJlMC05YTQ1LWQxNDY4MGVlNjE1NyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.cbHTMxahgVgImt2ll-cN4pJIbtN_gMks9Wg-Aqc3hvntktpmPFN0TRk9eT362HoYFpf6RB5pJvH4Xg-eACoZ9IfOcIqDK8ky14jk1z5TolgXrLv1OqacxI8PlRJBDvmjIEX8iLIxcFE63gJQpBoDscCOHMMs-i1cuygdRr2vEq47XX_ykxPg49pw1hRaG4DSLjfCTA7kAG3R-9NnhGCpexruryDd4ftqaKKf12BTmT8xgydcvNWzzkgnYMnoF-o8cfaLqd9c_-TOr3h1VGyoop925CCrTXqHxBU6VPEnSRozegIfDbLwbyhp4Wq3CTDyBAc4YSm8WbqRPyikNRa-ow

总结


对于整个k8s集群来说使用的是https认证,是一个双向认证的方式,如果是系统的组件想要访问k8s apiserver分为两种

  • 一种是在一台机器上,访问非安全端口
  • 另外一种是远程访问需要https认证

如果是pod想要访问就要使用sa

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值