k8s 二进制部署 二 (私有ca)

大番茄 2019年10月25日 443次浏览

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]#

注意证书中的这个:
image.png

二、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 名称无所谓,只要对应上就行。

image.png

第二种是 可以写在一行,以逗号分开, 如:

image.png

[ 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里面还可以写其他信息,如:

image.png
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组。
image.png

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