@zhangsiming65965
2020-09-22T02:36:43.000000Z
字数 12434
阅读 164
Kubernetes
=============================
message --> (公钥加密) --> || 传输 || --> (私钥解密) --> message
注意:
1.这里与数字证书认证相反,是公钥加密私钥解密
2.公钥私钥需要是一个秘钥对
message --> H(message) --> Hash message
处理加入一个随机数,然后得出结果(加盐); 可以有效缓解在输入值是一个有效的集合,哈希值也是固定长度被别人‘试’出来的几率
message --> H(R|message) --> Hash message
数字签名;把数据根据私钥/哈希进行加密,然后必须要对应的公钥来进行解密认证才能确保数据安全。前半句的加密过程就叫做 '数字签名'
Alice想要通过证书加密让Bob安全读到自己的信息流程如下:
公钥
和姓名,机构、地址等身份信息。使用内置根证书确认身份并获取Alice证书
)使用刚刚获取的Alice证书(公钥)解析Alice发送的内容
)注意:
1.自签发证书:证书签发商和证书持有者是同一个人,缺点是没有人能告诉你"这个人就是这个人(我就是我)"; 所以需要上面的信任证书机构的介入,多一环进行认证证明
2.证书链:但是信任的证书机构的根证书是很机密的,一旦被盗取可能会导致很多人都无法证明"我就是我", 所以一般会引入一些中间证书商,多一层上面的解析循环;这样也保证了万一中间商证书泄露,不至于全部使用证书机构的人都陷于危险之中
3.证书签发一般都是有一定时期的, 过期了就如同废纸
参考链接:https://zhaohuabing.com/post/2020-03-19-pki/
参考链接:https://medium.com/sitewards/the-magic-of-tls-x509-and-mutual-authentication-explained-b2162dec4401
用该证书的私钥来生成 service account token,然后以 secret 的方式加载到 pod 中
。pod 中的应用可以使用该 token 来访问 kube-apiserver, kube-apiserver 会使用该证书中的公钥来验证请求中的 token
注意:
1. 只有当你运行 kube-proxy 并要支持 扩展 API 服务器 时,才需要 front-proxy 证书
$ ssh 10.20.11.120
$ sudo systemctl status etcd
● etcd.service - etcd docker wrapper
Loaded: loaded (/etc/systemd/system/etcd.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-08-03 15:42:36 CST; 1 months 18 days ago
$ cat /etc/etcd.env | tail -13
# TLS settings
ETCD_TRUSTED_CA_FILE=/etc/ssl/etcd/ssl/ca.pem # etcd验证访问 etcd 服务器的客户端证书的 CA 根证书, 服务端签名证书和服务端私钥
ETCD_CERT_FILE=/etc/ssl/etcd/ssl/member-ip-10-20-11-120.pem
ETCD_KEY_FILE=/etc/ssl/etcd/ssl/member-ip-10-20-11-120-key.pem
ETCD_CLIENT_CERT_AUTH=true
ETCD_PEER_TRUSTED_CA_FILE=/etc/ssl/etcd/ssl/ca.pem # etcd peer之间验证访问 etcd 服务器的客户端证书的 CA 根证书, 服务端签名证书和服务端私钥
ETCD_PEER_CERT_FILE=/etc/ssl/etcd/ssl/member-ip-10-20-11-120.pem
ETCD_PEER_KEY_FILE=/etc/ssl/etcd/ssl/member-ip-10-20-11-120-key.pem
ETCD_PEER_CLIENT_CERT_AUTH=True
# 验证etcd证书过期时间
$ sudo openssl x509 -in /etc/ssl/etcd/ssl/ca.pem -noout -dates
notBefore=Aug 6 05:07:43 2019 GMT
notAfter=Jul 13 05:07:43 2119 GMT
$ ssh 10.20.11.120
$ cd /etc/kubernetes
$ cat manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
- kube-apiserver
- --advertise-address=10.20.11.120
- --etcd-cafile=/etc/ssl/etcd/ssl/ca.pem # 用于验证 etcd 客户端证书的 CA 根证书, 用于访问 etcd 的客户端证书和私钥
- --etcd-certfile=/etc/ssl/etcd/ssl/node-ip-10-20-11-120.pem
- --etcd-keyfile=/etc/ssl/etcd/ssl/node-ip-10-20-11-120-key.pem
- --kubelet-client-certificate=/etc/kubernetes/ssl/apiserver-kubelet-client.crt # 用于访问 kubelet 的客户端证书和私钥
- --kubelet-client-key=/etc/kubernetes/ssl/apiserver-kubelet-client.key
- --proxy-client-cert-file=/etc/kubernetes/ssl/front-proxy-client.crt # 只有当你运行 kube-proxy 并要支持 扩展 API 服务器 时,才需要 front-proxy 证书
- --proxy-client-key-file=/etc/kubernetes/ssl/front-proxy-client.key
- --client-ca-file=/etc/kubernetes/ssl/ca.crt # 用于验证访问 kube-apiserver 的客户端的证书的 CA 根证书
- --service-account-key-file=/etc/kubernetes/ssl/sa.pub # 用于验证 service account token 的公钥
- --tls-cert-file=/etc/kubernetes/ssl/apiserver.crt # 用于对外提供服务的服务器证书和私钥
- --tls-private-key-file=/etc/kubernetes/ssl/apiserver.key
...
上面三个apiserver的客户端组件的证书都写在了对应的KUBECONFIG中,名为controller-manager.conf, kubelet.conf, scheduler.conf, 就不一一展示, 随便列举一个如下:
# 包含验证apiserver证书的ca证书, 还有请求时候的看客户端证书和私钥
root@ip-10-20-11-120:/etc/kubernetes# cat scheduler.conf
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRFNU1EZ3dOakExTURrek1Gb1hEVEk1TURnd016QTFNRGt6TUZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTWg2Ck5JOEJBUzVGUUlORUlwalNIQjN6V2lPdGNpUDU5NDNEMTU4Q0hIMmNhVitYalQxS2RsQ1pNRys0bVNRd3dmSE8KNEtINjdnWGF0RDBoRVBlYjVlZm4zYUQvTkRxME1FWWRBRUNEWDAvdmxUWUtjS1l4bHcwTXorbUlhK00vWE5aUgozaE5aejBwbEVDS2F4c2ZXSVVaSUNJb1VFOFA5ZHBqemdOck5WdTV6WHR3T3crOVhFUVp1aHlwVzlvTWFneEN1ClpWcUJJUURzZHFrejdoZEVVOWh5TGJLVXQrbnZlTGNETHJHV2dVSFBJTjBycmE1NXRQYTR1RTN3MXpvZWRGa0QKeFF6ZzZFSTZJRmNCMFM0d2ttU2cxNkV2N0JUajZpUzNTNHd2d0pwd3RCVWY5bVc1Sm1zYnZkckFlL1pOMldNKwo3aUZkTFFpMzRlKzg1eUFJOHM4Q0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFFVFBLNDZHV0dMMVpmSHFWT3pzengzL0lab04KRnErOUxXejJIdTRHaWlmUmdJakJUODVOc1J1VDJUQlNCSVRXZzlNUUM1ZFRpSTVzWnh0MENsV29XaFRML2E1MwprbzBXa1VWVVY5SjhmZDZ0RHdZNXNMTmdZeHliM2VZblEzTXU4QVMrZ2NSZWVtVjFCMFc0T0JkSW52eTFkdVhICndVMmM3WmhwYzFpdkNUVmowcXBkVFhRTmw2bGlNUWpQWXY4eTdyblFCMTZ0K0VTRXZPRzFCeHRWVUFJdXFET0oKeHNaY2MvdmJCZjBjbDBiMk9iQmIwSG4rbEVxb25TcnJlZnlncXZtYTNwbVNaMDIzTG5aMXkzdjFSMEkzVjlVZApoOTJRb2t6K2x0QUNQU3UzTHVJSXBpR3VxbVZNeTNtL21YamU2L0d0eDJYbWtxTUtITmNuNlBTSWU4UT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
server: https://10.20.11.120:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: system:kube-scheduler
name: system:kube-scheduler@kubernetes
current-context: system:kube-scheduler@kubernetes
kind: Config
preferences: {}
users:
- name: system:kube-scheduler
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMzakNDQWNhZ0F3SUJBZ0lJSEdKbkpVMUtvcE13RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4T1RBNE1EWXdOVEE1TXpCYUZ3MHlNVEE0TURNd056TTRNalphTUNBeApIakFjQmdOVkJBTVRGWE41YzNSbGJUcHJkV0psTFhOamFHVmtkV3hsY2pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCCkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU1VOEFPY245OFdtZlVJOEc4VEdsN0Vaa09oeFY3eVpETXo5cDNIbWIyWnEKOVljTFRDdDd4OUswVG9yZW1CMG4vdG5qTmkrbFo3eXJsdGFHaXpjeVZ5Q0ZQWmQyUit0ZjlVNWcwNU5yTUxJcApZOHJjL3pOS0FMQSs3dk5FL0RxRDQya1pBMnpKUXMxU0RNUkFKZ3FaWmVXLzJIQmRPVS9xc0xrRkVVbGVZYmQ3CnhlczRHeWFLMUVrYXVvU2ptdlM2ODR1cnpaU1o5TzFLQnFVN2dicDVzandBZzl2WVVCVU5vSGw0alNQYU1sQ2EKYWVEZG1CRmtNVm5rWk9vR3haeUZ2WHVjcTVzdnJ4b1JsUElXOUVwS1hORFpaOVAyaTJNZitZWlRocDEzTFFKTwp0Q2dWd0lFVXo3S1ZBMDROTjA3L2J6RkcxeWxLUHVlMVluTWNjc2t4dkw4Q0F3RUFBYU1uTUNVd0RnWURWUjBQCkFRSC9CQVFEQWdXZ01CTUdBMVVkSlFRTU1Bb0dDQ3NHQVFVRkJ3TUNNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUIKQVFDYmx2RzlUTno0eThTNFFoNU5WZUhudjhPeG96VkRHa09IOHIvRzVEU2ZUazVCTFhmQjgvRU9mbzNnLytnZwpRNDZtMTVIdnFTYVhtYU5iKys1Mlg4N3BtLzFWZmgycVduUW9XVmdmQkdGL0FuMWN1TW1Ra0hWTlB4bEVoeHZuCjhEb1k2SEMwdy9LUW1OTGRuOEI5bys3UEJGRlhmaE9KY2RkMkc1SWNpS0Y2ZEk3UkJHVFBIZGE1TzJJb0Y4OEsKLzY3MnN5UGFIYXJENFFQWkZEYUVLRGNwa0w0UEpQYlM4QTlweTM3dVJuZVQ1dkp3MjFnVXY4RlFveWtnWkQwZAo0QkozL05Ld0dEZUQ5aFE2amhXM01SYjNGTkVjU00vNGc2NXh4VmpiNlRJM0tlenpkdFRZTnQwUm5IVkdXNk0zCmNPVjI5MzgzR1FWUkZWT3NVK2JQQ2JycgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBeFR3QTV5ZjN4YVo5UWp3YnhNYVhzUm1RNkhGWHZKa016UDJuY2VadlptcjFod3RNCkszdkgwclJPaXQ2WUhTZisyZU0yTDZWbnZLdVcxb2FMTnpKWElJVTlsM1pINjEvMVRtRFRrMnN3c2lsanl0ei8KTTBvQXNEN3U4MFQ4T29QamFSa0RiTWxDelZJTXhFQW1DcGxsNWIvWWNGMDVUK3F3dVFVUlNWNWh0M3ZGNnpnYgpKb3JVU1JxNmhLT2E5THJ6aTZ2TmxKbjA3VW9HcFR1QnVubXlQQUNEMjloUUZRMmdlWGlOSTlveVVKcHA0TjJZCkVXUXhXZVJrNmdiRm5JVzllNXlybXkrdkdoR1U4aGIwU2twYzBObG4wL2FMWXgvNWhsT0duWGN0QWs2MEtCWEEKZ1JUUHNwVURUZzAzVHY5dk1VYlhLVW8rNTdWaWN4eHl5VEc4dndJREFRQUJBb0lCQUd6KzJOemxhSGFRcUI0SApTNjAxdGpTSGxWM3U3UFpyZWZoNm9LTkFIZ1h5UzljaU5paTlrZEx1RTQySXIzVkZXZ0FkSVIrNWY1ZHpGN3RiCnhPbHU1MWt3YUxZZ0JtU2J0ZHRuaE9TdDBzNVNNelN6WmxCNHIrSzJGS1RaVmE0Y25uckErUFNRVUZ0WTRYYysKb0FjeGVHODcwcWRkelVOTnhmV3BTRUZNYUNIVnlYeW1RQ1lRNXdBVDR0am1tNHZGNm9LbktHeldIRWZSWEQ4OAo3YUYrVmcyMzlVNHhzQWpRUHFsMFc1M3FyUFB1R0pjMXhJWUJ5RzVuQ2pRa0tPVlEzRUt1NVNPTUdlSFhsRmpvCnUraStkN3NDaDBvWStlUTRyREJXNFYwdGFCczAxM2VjTDUrNHRDRjhuQW1mZzBoQ0RVSkY4QnJpM1ZCeWoyTWUKNmhCelhMa0NnWUVBeHdCbWRIRlVZVTNEMU9sRGFnd2sxN1p5TUtjbG1DWmlxSWwvOHdaZ3ZMb0puaVlCUS9QUApZVFdObXNpMnd3bWpMcFhaT2lLcDVnRldheWxMYnRKekVXRnpnbEtPYnM4WnB4eEtEMTAvdlhmK0ZFRXJnMkd0Cmd2UEw1YjBtdERWNTB5aGt4TDE4U2MyNWJGd3NRSTVISzdtaisyM1k4WEFpeGxQcno2Snl6QzBDZ1lFQS9ib0cKNUlGcjRTYlJrSEoxeEozS2orVEswRXRldGZRbTNRKytRLzVXbGQ3VWtvNHI4RUZWQ2lscEpiTWVOa1AwUjhZYQovcjRaNzJYREpjMXdPcFVvNjN0TGlXSkxQdUVwOGNhalNsSDc4QlNHRUdXaGEwZ0pTYnJPUHEvdW16OW53ZlV5CmN0SExTa0Z6THlLWkd5dmViZ2dVWTlTVjRYVklqQmU4MXZ0cmhCc0NnWUVBbzQzQnB2d3AxSnNjVTFXdjBXM1AKcmZiR0hSU1RBbHl5QTBDWEJ6NzdyTURkL0x2Um1HNit4MjlEUmE2bS90OWgzWHpNLzBuVUJ6U2NPUkRFYlgzTAprc0pjTkFUMENVQnZIZmhUS2hPQ3VvN3ZKT2gzQWRENjBVRGNHS0tBTitZbmpST0sxbVBCemNxbUZkZ2ZpcU1rCi9WdmkyVmRyME90UHVWN3AxVW4zUGJVQ2dZRUFtUlpDem1CZ0xNcjFLb2hGRWtwNlMzT3FBeDlXbDhZbUpMODQKOTJGZjhMRXY1UFV2QVprSnJFWHNFVGtQZzRKZ3cyVitLREdmQ0ZpSDlDa09DK3F2YzlWQ2NEUUVYbjRRaHJacApFNUIveUEwNkRtNmpoRTFFZlYzZXp1ZnJ1WFA2TUlhMjE1eEpZaFkzWHpzcTBjQVlScDlOWGlhSUFDNTVoVDFWClRRa0poLzBDZ1lFQXJKdnZiSWxIdWV5VU5ScitqM3FQejFIS3RtQmhZc0dEN3QrU2FEeDJlaVBSdzNsL1g0MEQKVFFFYVBNY291dXgrZkN3SmtzTnFqcGZ6Sjk5M1RacHYxL0owR01rUXhKZVdvOGN0bGdEVVBIMjlsOW9FUVlWegpralJ4ZCt6Q0tiUnhyTDVkaDRpMmlDeUNSSkdYNSt2Rm83QjlYaEdCVDRiZkNFYk1iSWRyam9FPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
Service account 主要被 pod 用于访问 kube-apiserver。 在为一个 pod 指定了 service account 后,kubernetes 会为该 service account 生成一个 JWT token,并使用 secret 将该 service account token 挂载到 pod 上。pod 中的应用可以使用 service account token 来访问 api server。service account 证书被用于生成和验证 service account token
注意:
1. Service account加密过程是文章开头说的"非对称加密", 也就是说只是controller-manager私钥加密数据, 然后kube-apiserver的公钥进行解密而已
2. 由于是非对称加密, 也就是说没有"双向 tls 认证"
3. istio的做法就是为每个 service account 生成一个证书, 之后就可以"双向 tls 认证"
$ cat manifests/kube-controller-manager.yaml | grep service-account
- --service-account-private-key-file=/etc/kubernetes/ssl/sa.key
- --use-service-account-credentials=true
$ cat manifests/kube-apiserver.yaml | grep service-account
- --service-account-key-file=/etc/kubernetes/ssl/sa.pub
- Kubernetes 提供了一个 certificates.k8s.io API,可以使用配置的 CA 根证书来签发用户证书
- Kubernetes 提供了 TLS bootstrapping 的方式来简化 Kubelet 证书的生成过程, 过程如下:(需要apiserver启用--enable-bootstrap-token-auth)
1) 调用 kube-apiserver 生成一个 bootstrap token
2) 将该 bootstrap token 写入到一个 kubeconfig 文件中,作为 kubelet 调用 kube-apiserver 的客户端验证方式
3) 通过 --bootstrap-kubeconfig 启动参数将 bootstrap token 传递给 kubelet 进程
4) Kubelet 采用bootstrap token 调用 kube-apiserver API,生成自己所需的服务器和客户端证书
5) 证书生成后,Kubelet 采用生成的证书和 kube-apiserver 进行通信,并删除本地的 kubeconfig 文件,以避免 bootstrap token 泄漏风险
参考链接:
https://zhaohuabing.com/post/2020-05-19-k8s-certificate/
https://kubernetes.io/zh/docs/tasks/tls/managing-tls-in-a-cluster/
我们都知道 serviceaccount 的 token 是依赖于 sa.key 和 sa.pub 的,也就是说如果这俩秘钥更换了,所有的 serviceaccout 就都失效了,会重新创建(kube-system命名空间的会自动轮换,其他ns的需要手动); 但是如果只是更换证书的话,其实是不需要更换sa秘钥对的,因为sa秘钥对采用的是"非对称加密", 也就是说永不过期,除非删除秘钥对;事实上我们只要手动更换其他证书即可:
$ cp -R /etc/kubernetes/ssl /etc/kubernetes/ssl.backup
$ cp /etc/kubernetes/admin.conf /etc/kubernetes/admin.conf.backup
$ cp /etc/kubernetes/controller-manager.conf /etc/kubernetes/controller-manager.conf.backup
$ cp /etc/kubernetes/kubelet.conf /etc/kubernetes/kubelet.conf.backup
$ cp /etc/kubernetes/scheduler.conf /etc/kubernetes/scheduler.conf.backup
$ kubeadm alpha certs renew apiserver-kubelet-client
$ kubeadm alpha certs renew apiserver
$ kubeadm alpha certs renew front-proxy-client
$ kubeadm alpha kubeconfig user --client-name system:kube-controller-manager > /etc/kubernetes/controller-manager.conf
$ kubeadm alpha kubeconfig user --client-name system:kube-scheduler > /etc/kubernetes/scheduler.conf
$ kubeadm alpha kubeconfig user --client-name system:node:{nodename} --org system:nodes > /etc/kubernetes/kubelet.conf
$ kubeadm alpha kubeconfig user --client-name kubernetes-admin --org system:masters > /etc/kubernetes/admin.conf
$ cp /etc/kubernetes/admin.conf ~/.kube/config
最后重启基础组件即可(嫌麻烦可以直接master节点关机重启)
参考链接:https://github.com/kubernetes-sigs/kubespray/issues/5464