.

Kubernetes中的证书工作机制

家用方法治疗白癜风 http://news.39.net/bjzkhbzy/190619/7230204.html

接触Kubernetes以来,我经常看到Kubernetes在不同的地方使用了证书(Certificate),在Kubernetes安装和组件启动参数中也需要配置大量证书相关的参数。但是Kubernetes的文档在解释这些证书的工作机制方面做得并不是太好。经过大量的相关阅读和分析工作后,我基本弄清楚了Kubernetes中证书的使用方式。在本文中,我将试图以一种比官方文档更容易理解的方式来说明Kubernetes证书相关的工作机制,如果你也存在这方面的疑惑,希望这篇文章对你有所帮助。

Kubernetes组件的认证方式

首先让我们来看一下Kubernetes中的组件:在Kubernetes中包含多个以独立进程形式运行的组件,这些组件之间通过HTTP/gRPC相互通信,以协同完成集群中应用的部署和管理工作。

从图中可以看到,Kubernetes控制平面中包含了etcd,kube-api-server,kube-scheduler,kube-controller-manager等组件,这些组件会相互进行远程调用,例如kube-api-server会调用etcd接口存储数据,kube-controller-manager会调用kube-api-server接口查询集群中的对象状态;同时,kube-api-server也会和在工作节点上的kubelet和kube-proxy进行通信,以在工作节点上部署和管理应用。

以上这些组件之间的相互调用都是通过网络进行的。在进行网络通信时,通信双方需要验证对方的身份,以避免恶意第三方伪造身份窃取信息或者对系统进行攻击。为了相互验证对方的身份,通信双方中的任何一方都需要做下面两件事情:

向对方提供标明自己身份的一个证书

验证对方提供的身份证书是否合法,是否伪造的?

在Kubernetes中使用了数字证书来提供身份证明,我们可以把数字证书简单理解为我们在日常生活中使用的“身份证”,上面标注了证书拥有者的身份信息,例如名称,所属组织机构等。为了保证证书的权威性,会采用一个通信双方都信任的CA(证书机构,CertificateAuthority)来颁发证书。这就类似于现实生活中颁发“身份证”的政府机构。数字证书中最重要的内容实际上是证书拥有者的公钥,该公钥代表了用户的身份。

在Kubernetes的组件之间进行通信时,数字证书的验证是在协议层面通过TLS完成的,除了需要在建立通信时提供相关的证书和密钥外,在应用层面并不需要进行特殊处理。采用TLS进行验证有两种方式:

服务器单向认证:只需要服务器端提供证书,客户端通过服务器端证书验证服务的身份,但服务器并不验证客户端的身份。这种情况一般适用于对Internet开放的服务,例如搜索引擎网站,任何客户端都可以连接到服务器上进行访问,但客户端需要验证服务器的身份,以避免连接到伪造的恶意服务器。

双向TLS认证:除了客户端需要验证服务器的证书,服务器也要通过客户端证书验证客户端的身份。这种情况下服务器提供的是敏感信息,只允许特定身份的客户端访问。

在Kubernetes中,各个组件提供的接口中包含了集群的内部信息。如果这些接口被非法访问,将影响集群的安全,因此组件之间的通信需要采用双向TLS认证。即客户端和服务器端都需要验证对方的身份信息。在两个组件进行双向认证时,会涉及到下面这些证书相关的文件:

服务器端证书:服务器用于证明自身身份的数字证书,里面主要包含了服务器端的公钥以及服务器的身份信息。

服务器端私钥:服务器端证书中包含的公钥所对应的私钥。公钥和私钥是成对使用的,在进行TLS验证时,服务器使用该私钥来向客户端证明自己是服务器端证书的拥有者。

客户端证书:客户端用于证明自身身份的数字证书,里面主要包含了客户端的公钥以及客户端的身份信息。

客户端私钥:客户端证书中包含的公钥所对应的私钥,同理,客户端使用该私钥来向服务器端证明自己是客户端证书的拥有者。

服务器端CA根证书:签发服务器端证书的CA根证书,客户端使用该CA根证书来验证服务器端证书的合法性。

客户端CA根证书:签发客户端证书的CA根证书,服务器端使用该CA根证书来验证客户端证书的合法性。

如果你需要了解更多关于TLS认证的原理,可以阅读一下medium上的原文。

Kubernetes中使用到的CA和证书

Kubernetes中使用了大量的证书,本文不会试图覆盖到所有可能使用到的证书,但会讨论到主要的证书。理解了这些证书的使用方法和原理后,也能很快理解其他可能遇到的证书文件。下图标识出了在kubernetes中主要使用到的证书和其使用的位置:

Kubernetes中使用到的主要证书

上图中使用序号对证书进行了标注。图中的箭头表明了组件的调用方向,箭头所指方向为服务提供方,另一头为服务调用方。为了实现TLS双向认证,服务提供方需要使用一个服务器证书,服务调用方则需要提供一个客户端证书,并且双方都需要使用一个CA证书来验证对方提供的证书。为了简明起见,上图中只标注了证书使用方提供的证书,并没有标注证书的验证方验证使用的CA证书。图中标注的这些证书的作用分别如下:

etcd集群中各个节点之间相互通信使用的证书。由于一个etcd节点既为其他节点提供服务,又需要作为客户端访问其他节点,因此该证书同时用作服务器证书和客户端证书。

etcd集群向外提供服务使用的证书。该证书是服务器证书。

kube-apiserver作为客户端访问etcd使用的证书。该证书是客户端证书。

kube-apiserver对外提供服务使用的证书。该证书是服务器证书。

kube-controller-manager作为客户端访问kube-apiserver使用的证书,该证书是客户端证书。

kube-scheduler作为客户端访问kube-apiserver使用的证书,该证书是客户端证书。

kube-proxy作为客户端访问kube-apiserver使用的证书,该证书是客户端证书。

kubelet作为客户端访问kube-apiserver使用的证书,该证书是客户端证书。

管理员用户通过kubectl访问kube-apiserver使用的证书,该证书是客户端证书。

kubelet对外提供服务使用的证书。该证书是服务器证书。

kube-apiserver作为客户端访问kubelet采用的证书。该证书是客户端证书。

kube-controller-manager用于生成和验证service-accounttoken的证书。该证书并不会像其他证书一样用于身份认证,而是将证书中的公钥/私钥对用于serviceaccounttoken的生成和验证。kube-controller-manager会用该证书的私钥来生成serviceaccounttoken,然后以secret的方式加载到pod中。pod中的应用可以使用该token来访问kube-apiserver,kube-apiserver会使用该证书中的公钥来验证请求中的token。我们将在文中稍后部分详细介绍该证书的使用方法。

通过这张图,对证书机制比较了解的读者可能已经看出,我们其实可以使用多个不同的CA来颁发这些证书。只要在通信的组件中正确配置用于验证对方证书的CA根证书,就可以使用不同的CA来颁发不同用途的证书。但我们一般建议采用统一的CA来颁发kubernetes集群中的所有证书,这是因为采用一个集群根CA的方式比采用多个CA的方式更容易管理,可以避免多个CA导致的复杂的证书配置、更新等问题,减少由于证书配置错误导致的集群故障。

Kubernetes中的证书配置

前面我们介绍了Kubernetes集群中主要使用到的证书。下面我们分别看一下如何将这些证书及其对应的私钥和CA根证书需要配置到Kubernetes中各个组件中,以供各个组件进行使用。这里假设使用一个集群根CA来颁发所有相关证书,因此涉及到CA的配置对应的证书文件名都是相同的。

etcd证书配置

需要在etcd的启动命令行中配置以下证书相关参数:

etcd对外提供服务的服务器证书及私钥。

etcd节点之间相互进行认证的peer证书、私钥以及验证peer的CA。

etcd验证访问其服务的客户端的CA。

/usr/local/bin/etcd\\--cert-file=/etc/etcd/kube-etcd.pem\\#对外提供服务的服务器证书--key-file=/etc/etcd/kube-etcd-key.pem\\#服务器证书对应的私钥--peer-cert-file=/etc/etcd/kube-etcd-peer.pem\\#peer证书,用于etcd节点之间的相互访问--peer-key-file=/etc/etcd/kube-etcd-peer-key.pem\\#peer证书对应的私钥--trusted-ca-file=/etc/etcd/cluster-root-ca.pem\\#用于验证访问etcd服务器的客户端证书的CA根证书--peer-trusted-ca-file=/etc/etcd/cluster-root-ca.pem\\#用于验证peer证书的CA根证书...

kube-apiserver证书配置

需要在kube-apiserver中配置以下证书相关参数:

kube-apiserver对外提供服务的服务器证书及私钥。

kube-apiserver访问etcd所需的客户端证书及私钥。

kube-apiserver访问kubelet所需的客户端证书及私钥。

验证访问其服务的客户端的CA。

验证etcd服务器证书的CA根证书。

验证serviceaccounttoken的公钥。

/usr/local/bin/kube-apiserver\\--tls-cert-file=/var/lib/kubernetes/kube-apiserver.pem\\#用于对外提供服务的服务器证书--tls-private-key-file=/var/lib/kubernetes/kube-apiserver-key.pem\\--etcd-certfile=/var/lib/kubernetes/kube-apiserver-etcd-client.pem\\#用于访问etcd的客户端证书--etcd-keyfile=/var/lib/kubernetes/kube-apiserver-etcd-client-key.pem\\#用于访问etcd的客户端证书的私钥--kubelet-client-certificate=/var/lib/kubernetes/kube-apiserver-kubelet-client.pem\\#用于访问kubelet的客户端证书--kubelet-client-key=/var/lib/kubernetes/kube-apiserver-kubelet-client-key.pem\\#用于访问kubelet的客户端证书的私钥--client-ca-file=/var/lib/kubernetes/cluster-root-ca.pem\\#用于验证访问kube-apiserver的客户端的证书的CA根证书--etcd-cafile=/var/lib/kubernetes/cluster-root-ca.pem\\#用于验证etcd服务器证书的CA根证书--kubelet-certificate-authority=/var/lib/kubernetes/cluster-root-ca.pem\\#用于验证kubelet服务器证书的CA根证书--service-account-key-file=/var/lib/kubernetes/service-account.pem\\#用于验证serviceaccounttoken的公钥...

采用kubeconfig访问kube-apiserver

Kubernetes中的各个组件,包括kube-controller-mananger、kube-scheduler、kube-proxy、kubelet等,采用一个kubeconfig文件中配置的信息来访问kube-apiserver。该文件中包含了kube-apiserver的地址,验证kube-apiserver服务器证书的CA证书,自己的客户端证书和私钥等访问信息。

在一个使用minikube安装的集群中,生成的kubeconfig配置文件如下所示,这四个文件分别为admin用户,kube-controller-mananger、kubelet和kube-scheduler的kubeconfig配置文件。

ls/etc/kubernetes/admin.confcontroller-manager.confkubelet.confscheduler.conf

我们打开controller-manager.conf来看一下,为了节约篇幅,这里没有写出证书和私钥的完整内容。

apiVersion:v1clusters:-cluster:#用于验证kube-apiserver服务器证书的CA根证书certificate-authority-data:LS0tLS1CRUdJTiBDRVJUSUZJQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0tLS0tCg==server:


转载请注明:http://www.abachildren.com/xgyy/3509.html