2053 kubelet
kubelet 运行在每个 worker 节点上,接收 kube-apiserver 发送的请求,管理 Pod 容器,执行交互式命令,如 exec、run、logs 等。
kubelet 启动时自动向 kube-apiserver 注册节点信息
为确保安全,部署时关闭了 kubelet 的非安全 http 端口,对请求进行认证和授权,拒绝未授权的访问(如 apiserver、heapster 的请求)。
部署策略:
动态创建 bootstrap token,而不是在 apiserver 中静态配置;
使用 TLS bootstrap 机制自动生成 client 和 server 证书,过期后自动轮转;
在 KubeletConfiguration 类型的 yaml 文件配置主要参数;
关闭只读端口,在安全端口 10250 接收 https 请求,对请求进行认证和授权,拒绝匿名访问和非授权访问;
使用 kubeconfig 访问 apiserver 的安全端口;
部署软件规划:
IP
部署软件包
10.40.61.116
kubelet
10.40.58.153
kubelet
10.40.58.154
kubelet
01.创建 Bootstrapping Token
Token可以是任意的包含128 bit的字符串,可以使用安全的随机数发生器生成。
export BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ')
cat > bootstrap-token.csv <<EOF
${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF注意:在进行后续操作前请检查 bootstrap-token.csv 文件,确认其中的 ${BOOTSTRAP_TOKEN} 环境变量已经被真实的值替换。
kube-apiserver启动时需要使用--token-auth-file=bootstrap-token.csv
如果后续重新生成了 BOOTSTRAP_TOKEN,则需要:
更新 bootstrap-token.csv 文件,分发到所有机器 (master 和 node)的 /etc/kubernetes/ 目录下,分发到node节点上非必需;
重新生成 bootstrap.kubeconfig 文件,分发到所有 node 机器的 /etc/kubernetes/ 目录下;
重启 kube-apiserver 和 kubelet 进程;
重新 approve kubelet 的 csr 请求;
02.创建 bootstrap kubeconfig 文件
执行下面的命令时需要先安装kubectl命令,请参考安装kubectl命令行工具。
--embed-certs为 true 时表示将 certificate-authority 证书写入到生成的 bootstrap.kubeconfig 文件中;设置客户端认证参数时没有指定秘钥和证书,后续由 kube-apiserver 自动生成;
设置集群参数
设置客户端认证参数
设置上下文参数
设置默认上下文
分发 kubeconfig 文件
将两个 kubeconfig 文件分发到所有 Node 机器的 /srv/kubernetes/kubeconfig 目录
03.维护配置文件
新版本的kubelet很多参数已经废弃只能通过创建单独的配置文件方式维护, 启动程序时使用--config
根据主机的实际情况替换address和healthzBindAddress
authentication.anonymous.enabled: 设置为 false,不允许匿名访问 10250 端口; authentication.x509.clientCAFile: 指定签名客户端证书的 CA 证书,开启 HTTPs 证书认证; authentication.webhook.enabled=true: 开启 HTTPs bearer token 认证。
04.使用systemd管理kubelet
根据实际情况替换--hostname-override, 并且kube-proxy配置的过程中也需要指定该参数
如果设置了 --hostname-override 选项,则 kube-proxy 也需要设置该选项,否则会出现找不到 Node 的情况;
--bootstrap-kubeconfig:指向 bootstrap kubeconfig 文件,kubelet 使用该文件中的用户名和 token 向 kube-apiserver 发送 TLS Bootstrapping 请求;
K8S approve kubelet 的 csr 请求后,在 --cert-dir 目录创建证书和私钥文件,然后写入 --kubeconfig 文件;
注意:kube-controller-manager 需要配置
--cluster-signing-cert-file和--cluster-signing-key-file参数,才会为 TLS Bootstrap 创建证书和私钥。
05.启动/停止 kubelet
kube-schedulercan be started and stopped as follows:
06.验证
0601.授权
kubelet 首次启动时向 kube-apiserver 发送证书签名请求,必须通过后 kubernetes 系统才会将该 Node 加入到集群。
启动时会查找--kubeletconfig参数对应的文件是否存在,如果不存在则使用 --bootstrap-kubeconfig 指定的 kubeconfig 文件向 kube-apiserver 发送证书签名请求 (CSR)。
kube-apiserver 收到 CSR 请求后,对其中的 Token 进行认证,认证通过后将请求的 user 设置为 kubelet-bootstrap:,user 设置为 user=kubelet-bootstrap,这一过程称为 Bootstrap Token Auth。
kubelet 创建 CSR 请求后,下一步需要创建被 approve,有两种方式:
kube-controller-manager 自动 aprrove;
手动使用命令 kubectl certificate approve;
CSR 被 approve 后,kubelet 向 kube-controller-manager 请求创建 client 证书,kube-controller-manager 中的 csr approving controller 使用 SubjectAccessReview API 来检查 kubelet 请求(对应的 User 是 kubelet-bootstrap)是否具有相应的权限。
默认情况下,这个 user 没有创建 CSR 的权限,因此 kubelet 会启动失败,可通过如下方式创建一个 clusterrolebinding,将 user kubelet-bootstrap 和 clusterrole system:node-bootstrapper 绑定。
注意: --user=kubelet-bootstrap 是在 创建 TLS Bootstrapping Token 章节中
bootstrap-token.csv文件中指定的用户名,bootstrap-token.csv同时也写入了 bootstrap.kubeconfig 文件
0602.查看kubelet服务
0603.查看端口
10248: healthz http 服务;
10250: https 服务,访问该端口时需要认证和授权(即使访问 /healthz 也需要);
未开启只读端口 10255;
07.允许approve CSR 请求,生成 kubelet client 证书
如果觉的手动允许approve麻烦可以直接配置自动approve
0701.手动允许approve CSR
查看未授权的 CSR 请求:
通过 CSR 请求:
自动生成了 kubelet kubeconfig 文件和公私钥:
0702.自动approve
创建三个 ClusterRoleBinding,分别用于自动 approve client、renew client 证书。
根据官方文档介绍 renew server证书基于安全的考虑要自己实现controller
Note: The CSR approving controllers implemented in core Kubernetes do not approve node serving certificates for security reasons. To use RotateKubeletServerCertificate operators need to run a custom approving controller, or manually approve the serving certificate requests.
auto-approve-csrs-for-group:自动 approve node 的第一次 CSR; 注意第一次 CSR 时,请求的 Group 为 system:kubelet-bootstrap;
auto-approve-renewals-for-nodes:自动 approve node 后续过期的 client 证书,自动生成的证书 Group 为 system:nodes;
创建资源:
08.授予 kube-apiserver 访问 kubelet API 的权限
因为kubelet启动时已经关闭了anonymous认证, 指定了authentication.x509.clientCAFile证书认证, 并且kube-apiserver中使用--kubelet-client-certificate和--kubelet-client-key标志启动apiserver, 所以需要进行对应的授权
kube-apiserver 的启动参数如下
apiserver.pem 中的CN为kubernetes,所以需要对该用户授权访问kubelet资源的授权
verb=*, resource=nodes, subresource=proxy
verb=*, resource=nodes, subresource=stats
verb=*, resource=nodes, subresource=log
verb=*, resource=nodes, subresource=spec
verb=*, resource=nodes, subresource=metrics
授权指令
如果不授权会报如下错误
09.控制证书轮转时间
由于kubelet的证书是kube-controller-manager负责签发的, 在kube-controller-manager启动参数中添加如下配置:
默认时间为8760h0m0s也就是1年
09.Q&A
Q: 遇到了一个大坑, 我查看了大量的bootstrap TLS 相关的文档, 文档上大部分的都是说使用bootstrap kubeconfig自动的签名node节点的证书,又根据文档查看说如果不指定--kubeconfig会自动使用bootstrap kubeconfig的APIserver地址, 但是一直报错
A: 启动的时候要指定
--bootstrap-kubeconfig, 也要指定--kubeconfig, 这里的--kubeconfig是指证书生成以后自动生成的kubelet.kubeconfig的目录
Q:
A: kubelet 启动时向 kube-apiserver 发送 TLS bootstrapping 请求,需要先将 bootstrap token 文件中的 kubelet-bootstrap 用户赋予 system:node-bootstrapper cluster 角色(role), 然后 kubelet 才能有权限创建认证请求(certificate signing requests):
Q: 因为我没有安装cni-plugin, 所以我没有指定cni相关的配置, worker几点一直是NotReady的状态, 但是查看官方文档说kubelet存在默认的docker网络插件, 我使用的就是docker, 那么问题出现在那里呢?
A: 经过万能的
--help查看, 他是这么说的
--network-plugin string <Warning: Alpha feature> The name of the network plugin to be invoked for various events in kubelet/pod lifecycle. This docker-specific flag only works when container-runtime is set to docker.但是又看--help人家说container-runtime默认就是docker, 情急之下删除了所有cni相关的配置, 发现居然起来了, 那看来就是这样了
Q: 查看kubelet日志报如下的错误
A: 报错的主要原因是
--hostname-override=py-modelo2o08cn-p005.pek3.wecash.net三个节点配置的相同, 需要清理rm -rf kubelet-*证书文件和rm -rf kubelet.kubeconfig文件
最后更新于
这有帮助吗?