K8S 学习笔记 | Kubernetes 集群安装之证书、TLS 认证与 etcd 安装
技术
作者:宋净超
译者:
2017-10-23 06:28

 

宋净超(Jimmy Song),TalkingData 容器技术负责人,微服务和云原生应用布道者。2017 年初开始研究 Kubernetes,至目前已发表近 40 篇 Kubernetes 学习笔记。同时,他也是「K8sMeetup 中国社区」的活跃者,见证了「K8sMeetup 中国社区」的一路成长。
经 Jimmy Song 本人授权, K8sMeetup 中国将持续转载他的 Kubernetes 学习笔记,由浅入深地分享他在学习过程中的收获。本文参考自《和我一步步部署 Kubernetes 集群》(https://github.com/opsnull/follow-me-install-kubernetes-cluster)

创建 TLS 证书和秘钥
Kubernetes 系统的各组件需要使用 TLS 证书对通信进行加密,本文档使用 CloudFlare 的 PKI 工具集 cfsslhttps://github.com/cloudflare/cfssl)来生成 Certificate Authority (CA) 和其它证书;
生成的 CA 证书和秘钥文件如下:

  • ca-key.pem
  • ca.pem
  • kubernetes-key.pem
  • kubernetes.pem
  • kube-proxy.pem
  • kube-proxy-key.pem
  • admin.pem
  • admin-key.pem

使用证书的组件如下:

  • etcd:使用 ca.pem、kubernetes-key.pem、kubernetes.pem;
  • kube-apiserver:使用 ca.pem、kubernetes-key.pem、kubernetes.pem;
  • kubelet:使用 ca.pem;
  • kube-proxy:使用 ca.pem、kube-proxy-key.pem、kube-proxy.pem;
  • kubectl:使用 ca.pem、admin-key.pem、admin.pem;

kube-controller、kube-scheduler 当前需要和 kube-apiserver 部署在同一台机器上且使用非安全端口通信,故不需要证书。
安装 CFSSL
方式一:直接使用二进制源码包安装


方式二:使用 go 命令安装


我们的系统中安装了 Go1.7.5,使用以下命令安装更快捷:
在 $GOPATH/bin 目录下得到以 cfssl 开头的几个命令。
注意:以下文章中出现的 cat 的文件名如果不存在需要手工创建。
创建 CA (Certificate Authority)
创建 CA 配置


文件字段说明:

  • ca-config.json:可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile;
  • signing:表示该证书可用于签名其它证书;生成的 ca.pem 证书中 CA=TRUE;
  • server auth:表示client可以用该 CA 对server提供的证书进行验证;
  • client auth:表示server可以用该CA对client提供的证书进行验证;

创建 CA 证书签名请求


  • "CN":Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;
  • "O":Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group);

生成 CA 证书和私钥


创建 Kubernetes 证书
创建 Kubernetes 证书签名请求


  • 如果 hosts 字段不为空则需要指定授权使用该证书的 IP 或域名列表,由于该证书后续被 etcd 集群和 Kubernetes master 集群使用,所以上面分别指定了 etcd 集群、Kubernetes master 集群的主机 IP 和 Kubernetes 服务的服务 IP(一般是 kue-apiserver 指定的 service-cluster-ip-range 网段的第一个IP,如 10.254.0.1。

生成 Kubernetes 证书和私钥


或者直接在命令行上指定相关参数:


创建 admin 证书
创建 admin 证书签名请求

  • 后续 kube-apiserver 使用 RBAC 对客户端(如 kubelet、kube-proxy、Pod)请求进行授权;
  • kube-apiserver 预定义了一些 RBAC 使用的 RoleBindings,如 cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予了调用 kube-apiserver 的所有 API的权限;
  • OU 指定该证书的 Group 为 system:masters,kubelet 使用该证书访问 kube-apiserver 时 ,由于证书被 CA 签名,所以认证通过,同时由于证书用户组为经过预授权的 system:masters,所以被授予访问所有 API 的权限;

生成 admin 证书和私钥


创建 kube-proxy 证书
创建 kube-proxy 证书签名请求

  • CN 指定该证书的 User 为 system:kube-proxy;
  • kube-apiserver 预定义的 RoleBinding cluster-admin 将User system:kube-proxy 与 Role system:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限;

生成 kube-proxy 客户端证书和私钥


校验证书
以 Kubernetes 证书为例。

使用 opsnssl 命令



  • 确认 Issuer 字段的内容和 ca-csr.json 一致;
  • 确认 Subject 字段的内容和 kubernetes-csr.json 一致;
  • 确认 X509v3 Subject Alternative Name 字段的内容和 kubernetes-csr.json 一致;
  • 确认 X509v3 Key Usage、Extended Key Usage 字段的内容和 ca-config.json 中 kubernetes profile 一致;

使用 cfssl-certinfo 命令



分发证书
将生成的证书和秘钥文件(后缀名为 .pem)拷贝到所有机器的 /etc/kubernetes/ssl 目录下备用;


创建 kubeconfig 文件
kubelet、kube-proxy 等 Node 机器上的进程与 Master 机器的 kube-apiserver 进程通信时需要认证和授权;Kubernetes 1.4 开始支持由 kube-apiserver 为客户端生成 TLS 证书的 TLS Bootstrapping (https://kubernetes.io/docs/admin/kubelet-tls-bootstrapping/) 功能,这样就不需要为每个客户端生成证书了;该功能当前仅支持为 kubelet 生成证书;
创建 TLS Bootstrapping Token
Token auth file
Token可以是任意的包涵 128 bit的字符串,可以使用安全的随机数发生器生成。

后三行是一句,直接复制上面的脚本运行即可

将 token.csv 发到所有机器(Master 和 Node)的 /etc/kubernetes/ 目录。


创建 kubelet bootstrapping kubeconfig 文件

  • --embed-certs 为 true 时表示将 certificate-authority 证书写入到生成的 bootstrap.kubeconfig 文件中;
  • 设置客户端认证参数时没有指定秘钥和证书,后续由 kube-apiserver 自动生成;

创建 kube-proxy kubeconfig 文件

  • 设置集群参数和客户端认证参数时 --embed-certs 都为 true,这会将 certificate-authority、client-certificate 和 client-key 指向的证书文件内容写入到生成的 kube-proxy.kubeconfig 文件中;
  • kube-proxy.pem 证书中 CN 为 system:kube-proxy,kube-apiserver 预定义的 RoleBinding cluster-admin 将User system:kube-proxy 与 Role system:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限;

分发 kubeconfig 文件
将两个 kubeconfig 文件分发到所有 Node 机器的 /etc/kubernetes/ 目录。


创建高可用 etcd 集群
Kubernetes 系统使用 etcd 存储所有数据,本文档介绍部署一个三节点高可用 etcd 集群的步骤,这三个节点复用 Kubernetes master 机器,分别命名为sz-pg-oam-docker-test-001.tendcloud.com、sz-pg-oam-docker-test-002.tendcloud.com、sz-pg-oam-docker-test-003.tendcloud.com:

  • sz-pg-oam-docker-test-001.tendcloud.com:172.20.0.113
  • sz-pg-oam-docker-test-002.tendcloud.com:172.20.0.114
  • sz-pg-oam-docker-test-003.tendcloud.com:172.20.0.115

TLS 认证文件
需要为 etcd 集群创建加密通信的 TLS 证书,这里复用以前创建的 Kubernetes 证书


  • Kubernetes 证书的 hosts 字段列表中包含上面三台机器的 IP,否则后续证书校验会失败;

下载二进制文件
到 https://github.com/coreos/etcd/releases 页面下载最新版本的二进制文件



创建 etcd 的 systemd unit 文件
注意替换 IP 地址为你自己的 etcd 集群的主机 IP。


  • 指定 etcd 的工作目录为 /var/lib/etcd,数据目录为 /var/lib/etcd,需在启动服务前创建这两个目录;
  • 为了保证通信安全,需要指定 etcd 的公私钥 (cert-file 和 key-file)、Peers 通信的公私钥和 CA 证书(peer-cert-file、peer-key-file、peer-trusted-ca-file)、客户端的 CA 证书(trusted-ca-file);
  • 创建 kubernetes.pem 证书时使用的 kubernetes-csr.json 文件的 hosts 字段包含所有 etcd 节点的 IP,否则证书校验会出错;
  • --initial-cluster-state 值为 new 时,--name 的参数值必须位于 --initial-cluster 列表中;

完整 unit 文件见:etcd.service(https://github.com/rootsongjc/follow-me-install-kubernetes-cluster/blob/master/systemd/etcd.service
环境变量配置文件 /etc/etcd/etcd.conf。


这是 172.20.0.113 节点的配置,其他两个 etcd节点只要将上面的 IP 地址改成相应节点的 IP 地址即可


启动 etcd 服务



在所有的 Kubernetes master 节点重复上面的步骤,直到所有机器的 etcd 服务都已启动


验证服务
在任一 Kubernetes master 机器上执行如下命令:



结果最后一行为 cluster is healthy 时表示集群服务正常
 

1416 comCount 0