创建TLS证书和秘钥

创建TLS证书和秘钥

前言

执行下列步骤前建议你先阅读以下内容:

**注意:**这一步是在安装配置kubernetes的所有步骤中最容易出错也最难于排查问题的一步,而这却刚好是第一步,万事开头难,不要因为这点困难就望而却步。

如果您足够有信心在完全不了解自己在做什么的情况下能够成功地完成了这一步的配置,那么您可以尽管跳过上面的几篇文章直接进行下面的操作。

kubernetes 系统的各组件需要使用 TLS 证书对通信进行加密,本文档使用 CloudFlare 的 PKI 工具集 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-manager:使用 ca-key.pem、ca.pem

注意:以下操作都在 master 节点即 172.20.0.113 这台主机上执行,证书只需要创建一次即可,以后在向集群中添加新节点时只要将 /etc/kubernetes/ 目录下的证书拷贝到新节点上即可。

安装 CFSSL

方式一:直接使用二进制源码包安装

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
chmod +x cfssl_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl

wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
chmod +x cfssljson_linux-amd64
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson

wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl-certinfo_linux-amd64
mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfoexport PATH=/usr/local/bin:$PATH

方式二:使用go命令安装

我们的系统中安装了Go1.7.5,使用以下命令安装更快捷:

$ go get -u github.com/cloudflare/cfssl/cmd/...
$ echo $GOPATH/usr/local$ls /usr/local/bin/cfssl*cfssl cfssl-bundle cfssl-certinfo cfssljson cfssl-newkey cfssl-scan

$GOPATH/bin目录下得到以cfssl开头的几个命令。

注意:以下文章中出现的cat的文件名如果不存在需要手工创建。

创建 CA (Certificate Authority)

创建 CA 配置文件

mkdir /root/sslcd /root/ssl
cfssl print-defaults config > config.json
cfssl print-defaults csr > csr.json# 根据config.json文件的格式创建如下的ca-config.json文件# 过期时间设置成了 87600hcat > ca-config.json <<EOF{  "signing": {    "default": {      "expiry": "87600h"    },    "profiles": {      "kubernetes": {        "usages": [            "signing",            "key encipherment",            "server auth",            "client auth"        ],        "expiry": "87600h"      }    }  }}EOF

字段说明

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

创建 CA 证书签名请求

创建 ca-csr.json 文件,内容如下:

{  "CN": "kubernetes",  "key": {    "algo": "rsa",    "size": 2048
  },  "names": [
    {      "C": "CN",      "ST": "BeiJing",      "L": "BeiJing",      "O": "k8s",      "OU": "System"
    }
  ]
}
  • "CN":Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;
  • "O":Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group);

生成 CA 证书和私钥

$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
$ ls ca*ca-config.json  ca.csr  ca-csr.json  ca-key.pem  ca.pem

创建 kubernetes 证书

创建 kubernetes 证书签名请求文件 kubernetes-csr.json

{    "CN": "kubernetes",    "hosts": [      "127.0.0.1",      "172.20.0.112",      "172.20.0.113",      "172.20.0.114",      "172.20.0.115",      "10.254.0.1",      "kubernetes",      "kubernetes.default",      "kubernetes.default.svc",      "kubernetes.default.svc.cluster",      "kubernetes.default.svc.cluster.local"
    ],    "key": {        "algo": "rsa",        "size": 2048
    },    "names": [
        {            "C": "CN",            "ST": "BeiJing",            "L": "BeiJing",            "O": "k8s",            "OU": "System"
        }
    ]
}
  • 如果 hosts 字段不为空则需要指定授权使用该证书的 IP 或域名列表,由于该证书后续被 etcd 集群和 kubernetes master 集群使用,所以上面分别指定了 etcd 集群、kubernetes master 集群的主机 IP 和 kubernetes 服务的服务 IP(一般是 kube-apiserver 指定的 service-cluster-ip-range 网段的第一个IP,如 10.254.0.1。
  • hosts 中的内容可以为空,即使按照上面的配置,向集群中增加新节点后也不需要重新生成证书。

生成 kubernetes 证书和私钥

$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
$ ls kubernetes*kubernetes.csr  kubernetes-csr.json  kubernetes-key.pem  kubernetes.pem

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

echo ‘{"CN":"kubernetes","hosts":[""],"key":{"algo":"rsa","size":2048}}‘ | cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes -hostname="127.0.0.1,172.20.0.112,172.20.0.113,172.20.0.114,172.20.0.115,kubernetes,kubernetes.default" - | cfssljson -bare kubernetes

创建 admin 证书

创建 admin 证书签名请求文件 admin-csr.json

{  "CN": "admin",  "hosts": [],  "key": {    "algo": "rsa",    "size": 2048
  },  "names": [
    {      "C": "CN",      "ST": "BeiJing",      "L": "BeiJing",      "O": "system:masters",      "OU": "System"
    }
  ]
}
  • 后续 kube-apiserver 使用 RBAC 对客户端(如 kubeletkube-proxyPod)请求进行授权;
  • kube-apiserver 预定义了一些 RBAC 使用的 RoleBindings,如 cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予了调用kube-apiserver 的所有 API的权限;
  • OU 指定该证书的 Group 为 system:masterskubelet 使用该证书访问 kube-apiserver 时 ,由于证书被 CA 签名,所以认证通过,同时由于证书用户组为经过预授权的 system:masters,所以被授予访问所有 API 的权限;

生成 admin 证书和私钥

$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
$ ls admin*admin.csr  admin-csr.json  admin-key.pem  admin.pem

创建 kube-proxy 证书

创建 kube-proxy 证书签名请求文件 kube-proxy-csr.json

{  "CN": "system:kube-proxy",  "hosts": [],  "key": {    "algo": "rsa",    "size": 2048
  },  "names": [
    {      "C": "CN",      "ST": "BeiJing",      "L": "BeiJing",      "O": "k8s",      "OU": "System"
    }
  ]
}
  • 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 客户端证书和私钥

$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes  kube-proxy-csr.json | cfssljson -bare kube-proxy
$ ls kube-proxy*kube-proxy.csr  kube-proxy-csr.json  kube-proxy-key.pem  kube-proxy.pem

校验证书

以 kubernetes 证书为例

使用 opsnssl 命令

$ openssl x509  -noout -text -in  kubernetes.pem
...
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, ST=BeiJing, L=BeiJing, O=k8s, OU=System, CN=Kubernetes
        Validity
            Not Before: Apr  5 05:36:00 2017 GMT
            Not After : Apr  5 05:36:00 2018 GMT
        Subject: C=CN, ST=BeiJing, L=BeiJing, O=k8s, OU=System, CN=kubernetes
...
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                DD:52:04:43:10:13:A9:29:24:17:3A:0E:D7:14:DB:36:F8:6C:E0:E0
            X509v3 Authority Key Identifier:
                keyid:44:04:3B:60:BD:69:78:14:68:AF:A0:41:13:F6:17:07:13:63:58:CD

            X509v3 Subject Alternative Name:
                DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster, DNS:kubernetes.default.svc.cluster.local, IP Address:127.0.0.1, IP Address:172.20.0.112, IP Address:172.20.0.113, IP Address:172.20.0.114, IP Address:172.20.0.115, IP Address:10.254.0.1
...
  • 确认 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 命令

$ cfssl-certinfo -cert kubernetes.pem
...
{  "subject": {    "common_name": "kubernetes",    "country": "CN",    "organization": "k8s",    "organizational_unit": "System",    "locality": "BeiJing",    "province": "BeiJing",    "names": [      "CN",      "BeiJing",      "BeiJing",      "k8s",      "System",      "kubernetes"
    ]
  },  "issuer": {    "common_name": "Kubernetes",    "country": "CN",    "organization": "k8s",    "organizational_unit": "System",    "locality": "BeiJing",    "province": "BeiJing",    "names": [      "CN",      "BeiJing",      "BeiJing",      "k8s",      "System",      "Kubernetes"
    ]
  },  "serial_number": "174360492872423263473151971632292895707129022309",  "sans": [    "kubernetes",    "kubernetes.default",    "kubernetes.default.svc",    "kubernetes.default.svc.cluster",    "kubernetes.default.svc.cluster.local",    "127.0.0.1",    "10.64.3.7",    "10.254.0.1"
  ],  "not_before": "2017-04-05T05:36:00Z",  "not_after": "2018-04-05T05:36:00Z",  "sigalg": "SHA256WithRSA",
...

分发证书

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

mkdir -p /etc/kubernetes/ssl
cp *.pem /etc/kubernetes/ssl

参考

时间: 2024-10-12 00:24:30

创建TLS证书和秘钥的相关文章

部署k8s ssl集群实践2:cfssl配置根证书和秘钥

参考文档:https://github.com/opsnull/follow-me-install-kubernetes-cluster感谢作者的无私分享.集群环境已搭建成功跑起来.文章是部署过程中遇到的错误和详细操作步骤记录.如有需要对比参考,请按照顺序阅读和测试. 2.1##安装CFSSL使用CloudFlare 的 PKI 工具集 cfssl 来生成 Certificate Authority (CA) 证书和秘钥文件,CA 是自签名的证书,用来签名后续创建的其它 TLS 证书 [[ema

kubernetes部署之创建TLS证书(2)

研究过kubernetes的同事们都知道,kubernetes如果需要启用TLS认证,那么制作证书是必不可少的一步.然而,很多人在制作证书上遇到了很多的麻烦.今天主要记录一次我在部署kubernetes的过程中,是如何制作证书的.在整个过程中,将详细列出各组件的启动参数,给出配置文件,以及详解它们的含义和可能遇到的问题. 一.部署前准备 1.1 主机环境 环境参考ETCD集群部署,这里会增加一个VIP(192.168.15.200),用户实现kubernetes master高可用: 1.2 安

C#读取cer证书获取秘钥给字符串加密(RSA)

/// <summary> /// 使用私钥加密字符串 /// </summary> /// <param name="key">需加密的字符</param> /// <param name="keyPath">私钥证书文件地址</param> public string EncryptKey(string key,string keyPath) { X509Certificate2 c2 =

Win7 文件加密存储操作后,如何在事后备份证书、秘钥

这个密钥的特点是只有在此系统下用此账户才可以修改,即便是你用此账户设置加密后删除此账户再重新建一个同名的账户依然无法修改.而且此密钥无法破解.所以一旦加密后,重装系统或者更换账户就无法修改了.唯一的办法是在重装系统前备份密钥[1].加密文件操作如下,右键文件夹-->属性-->常规选项卡里选择“高级”-->勾选“加密内容以便保护数据”. 当你加密文件,或者文件夹后,第一次加密时会提示你备份证书,如果你当时没有备份,那么这篇文章可以帮助你在事后重新备份个人的证书. 方法是: 1. 以管理员方

yan证书与秘钥 匹配

Openssl: make sure your certificate matches the private key To make sure the files tally, display the modulus value of each file: openssl rsa -noout -modulus -in FILE.key openssl req -noout -modulus -in FILE.csr openssl x509 -noout -modulus -in FILE.

Git秘钥生成以及Gitlab配置(附以下问题解决方法:Key is invalid Fingerprint cannot be generated)

在进行Git密钥配置时,总是提示: “The form contains the following errors:Key is invalidFingerprint cannot be generated” 如下图: 查找了不少资料,大部分说粘贴的字符与实际生成的不一致,例如windows环境下,如果有换行习惯带"\r\n",去除即可.几次尝试都不可以. 最后发现是粘贴的内容有问题,只黏贴了密钥,没有前贴前面的“ssh-rsa” 和后面的邮箱. 谨记:要粘贴pub密钥里面的所有内容(

如何通过抓包查看客户端https连接中ssl/tls加密所采用的秘钥位数

在https传输的过程中,我们底层的加密传输协议是ssl/tls.这里所使用的加密算法的秘钥位数(也就是服务器所使用的https证书的位数)可能是1024/2048或者更高,目前1024位的证书已经被证实是不安全的,需要逐步替换掉. 那么如何通过抓包来查看当前连接所采用的实际加密位数呢(注意,这里是抓包查看,如果是网页我们用浏览器直接访问,点击那个小锁然后进行一系列的操作就可以查看到连接信息了,如果有兴趣查看以下链接内容:http://www.wosign.com/FAQ/how_to_chec

openvpn 证书秘钥结合用户密码双重认证(1)服务器端设置

Openvpn 环境: 拓扑图: 出差人员win7 client 115.16.1.8/30 | 郑州站点------------互联网-------上海站点 内网:192.168.20.0   |         内网:192.168.10.0.24 | eth0 :   1.1.1.1/30 北京Open VPN(iptables) eth1:  192.168.0.1/24 | eth0:  192.168.0.100/24 公司内网 web server 希望屏幕前的你,能看懂O(∩_∩

WSL、Git on Windows 、Putty等的创建的rsa秘钥与连接linux的使用。

1. 在windows 上面可以使用多种方式创建公钥和私钥 这里从一开始说: 1.1 windows subsystem linux 的方式最简单了 cmd 命令行 下 进入 WSL 输入命令 bash 然后 输入 ssh-keygen 创建私钥创建一个 证书存放位置. 然后就可以生成了 如上就是简单生成的 私钥 (这个秘钥对我来说没用.) 其实可以看一下 ssh-copy-id 的默认文件总是去找 /root/.ssh 目录下面的 其实 我这个证书秘钥文件 是当时我学习git 时 用git创建