ca在k8s中作为第一层认证,很重要, 这个ca是k8s环境私有的,最好不要用于外部服务。
k8s通常需要的CA:
https://kubernetes.io/zh/docs/setup/best-practices/certificates/
一、生成证书
使用工具生成就行,一般也是封装的openssl。
我这里使用自己的脚本openssl.tar
可以修改脚本里面的组织信息。里面就是执行的openssl命令。
export CA_DIR="$(pwd)/CA" # CA目录
export KEY_COUNTRY="CN" # 国家
export KEY_PROVINCE="BJ" # 省市
export KEY_CITY="BJ" # 城市
export KEY_ORG="atest.pub" # 组织
export KEY_OUNAME="op" # 部门名称
export KEY_EMAIL="op@atest.pub" # 邮件
export KEY_COMMONNAME="ca.atest.pub" # 主机名, 在下面还会指定
openssl.sh init # 生成ca
解压以后:
[root@k8s-ca backup]# ls
conf openssl.sh
[root@k8s-ca backup]# ./openssl.sh init
Generating RSA private key, 4096 bit long modulus
...............................................................................................................................++
....................................++
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CN]:
State or Province Name (full name) [BJ]:
Locality Name (eg, city) [BJ]:
Organization Name (eg, company) [atest.pub]:
Organizational Unit Name (eg, section) [op]:
Common Name (eg, your name or your server's hostname) [ca.atest.pub]:
Email Address [op@atest.pub]:
Using configuration from conf/openssl.cnf
create ca cert is successful
生成证书:
openssl.sh build <username> [san] # 附加的san名称,需要修改conf/openssl.sh里的alt_name, 添加对应信息。
san (Subject Alternative Name) 是 SSL 标准 x509 中定义的一个扩展, 用来支持单证书多域名的情况。
使用san扩展,需要修改conf/openssl.cnf配置文件,写上其他的域名或IP,也可以写邮件之类的信息。 如:
[ alt_names ]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
IP.1 = 172.100.102.80
IP.2 = 172.100.102.90
IP.3 = 10.0.0.1
[root@k8s-ca backup]# ./openssl.sh build kube-apiserver san
Generating RSA private key, 2048 bit long modulus
.............................................+++
.............+++
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CN]:
State or Province Name (full name) [BJ]:
Locality Name (eg, city) [BJ]:
Organization Name (eg, company) [atest.pub]:
Organizational Unit Name (eg, section) [op]:
Common Name (eg, your name or your server's hostname) [kube-apiserver]:
Email Address [op@atest.pub]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from conf/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 1 (0x1)
Validity
Not Before: Oct 25 09:55:09 2019 GMT
Not After : Oct 22 09:55:09 2029 GMT
Subject:
countryName = CN
stateOrProvinceName = BJ
organizationName = atest.pub
organizationalUnitName = op
commonName = kube-apiserver
emailAddress = op@atest.pub
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Subject Alternative Name:
DNS:kubernetes, IP Address:172.100.102.80, IP Address:172.100.102.90, IP Address:10.0.0.1
Certificate is to be certified until Oct 22 09:55:09 2029 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
create kube-apiserver cert is successful
/data/backup/CA/certs/kube-apiserver/kube-apiserver.crt: OK
wget http://172.100.102.77/k8s/kube-apiserver.tar
[root@k8s-ca backup]#
注意证书中的这个:
二、openssl.cnf
这个配置文件里有几个关键参数要注意一下。
有兴趣可以man一下看看详细的信息:
man x509v3_config
man ca
man openssl.cnf
man openssl
man req
1、[v3_req]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
IP.1 = 172.100.102.80
IP.2 = 172.100.102.90
IP.3 = 10.0.0.1
是申请证书时一些配置,重点是 subjectAltName, 这个就是san扩展的配置。
有两种配置方式:
第一种就是加上@alt_names, 创建出来alt_names字段, 里面写san的配置。这个alt_names 名称无所谓,只要对应上就行。
第二种是 可以写在一行,以逗号分开, 如:
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
#subjectAltName = @alt_names
subjectAltName = DNS.1:kubernetes, DNS.2:kubernetes.default, IP.1:172.100.102.80, IP.2:172.100.102.90
最后san里面还可以写其他信息,如:
subjectAltName只能写一行,上面只是举例, 写多行的话下面的会覆盖上面的。
2、[ policy_match ]。
[ policy_match ]
countryName = match
stateOrProvinceName = match
#organizationName = match
organizationName = supplied
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
重点关注 organizationName 组织名称, 这个默认情况下是match, 表示需要与CA的一致。
但是在k8s中RBAC授权部分, 证书里的organizationName表示Group,给Group授权就是给这个字段的名称授权。 所以要改掉。另外,commonName表示User。
比如这里的Organization Name, 设置为system:masters, 就是k8s里的system:masters组。
3、[ CA_default ]
CA的默认配置, 包含证书的有效期, 不过这个在命令行制定就行, 也没什么需要注意的。
三、节点信任CA
CA所生成的证书以后会让docker 的镜像仓库使用,或者是其他原因节点需要访问这个证书的节点,一般都是https请求。 所以最好在前期让节点信任私有CA。
centos7为例
把CA/cacert.pem文件,只要是ca的证书文件就行, 放到对应节点的/etc/pki/ca-trust/source/anchors/目录下, 执行 update-ca-trust, 就完成节点的信任了。
如果docker已经启动了,需要重启docker才能让docker重读信任的证书列表。
简单来说就两步:
1、ca证书放到 /etc/pki/ca-trust/source/anchors/
2、执行命令: update-ca-trust
3、重启docker(自己把握是否可以重启): systemctl restart docker