/etc/rancher/node/password try enabling a unique node name with the --with-node-id flag

[root@localhost tls]# k3s -v
k3s version v1.22.5+k3s1 (405bf79d)
go version go1.16.10

我的k3s版本1.22.5+k3s1

在 K3s v1.20.2 之后

Rancher Docs: Architecture

代理节点注册的工作原理

代理节点注册到由k3s agent进程启动的 websocket 连接,连接由作为代理进程一部分运行的客户端负载均衡器维护。

代理将使用节点集群密码以及随机生成的节点密码向服务器注册,存储在/etc/rancher/node/password. 服务器会将各个节点的密码存储为 Kubernetes 机密,任何后续尝试都必须使用相同的密码。节点密码秘密存储在kube-system命名空间中,名称使用模板<host>.node-password.k3s

注意:在 K3s v1.20.2 之前,服务器将密码存储在磁盘上的/var/lib/rancher/k3s/server/cred/node-passwd.

如果/etc/rancher/node删除了代理的目录,则应为代理重新创建密码文件,或者从服务器中删除条目。

通过使用该--with-node-id标志启动 K3s 服务器或代理,可以将唯一节点 ID 附加到主机名。

 方法1:

[root@localhost tls]#  kubectl -n kube-system get secrets  | grep pass
172.16.10.5.node-password.k3s                        Opaque                                1      171m
172.16.10.15.node-password.k3s                       Opaque                                1      19m
[root@localhost tls]#  kubectl -n kube-system get secrets  172.16.10.15.node-password.k3s
NAME                             TYPE     DATA   AGE
172.16.10.15.node-password.k3s   Opaque   1      19m
[root@localhost tls]#  kubectl -n kube-system describe secrets  172.16.10.15.node-password.k3s
Name:         172.16.10.15.node-password.k3s
Namespace:    kube-system
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
hash:  113 bytes

[root@localhost tls]# kubectl -n kube-system delete secrets 172.16.10.15.node-password.k3s

 方法2: 也就是删除node节点通过kubectl delete nodes <node-id>

[root@localhost k3s-ansible-master]# kubectl get nodes


[root@localhost k3s-ansible-master]# kubectl delete nodes 172.16.10.15

 

 方法3: 默认用的是sqlite数据库,也可以用mysql、etcd【适合做集群时候用】等相关数据。

导出数据,然后分析,我没分析明白只是个思路。希望NB人物帮忙分析一下,主要是

SELECT value FROM kine WHERE deleted=0 AND name LIKE "/bootstrap/%" ORDER BY id DESC LIMIT 1

https://github.com/k3s-io/k3s/issues/4910

Rancher Docs: K3s Server Configuration Reference

https://github.com/k3s-io/k3s/issues/802

Solved: Failed to configure agent: Node password rejected, duplicate hostname or contents RKE2/K3S

表结构

PRAGMA TABLE_INFO (kine)

导出数据

[root@localhost k3s-ansible-master]# cd /var/lib/rancher/k3s/server/db;sqlite3 -header -csv state.db "select * from kine;" > data.csv

我猜测就是清理节点数据,类似之前用etcd的时候,通过etcdctl rm 清理节点数据。来解决问题

只不过这里使用delete from kine 来清理数据,我没有去做测试。我只是通过kubectl delete nodes <node-id> 来达到的清理数据目的,如果哪天kubectl delete nodes 清理不了的时候就要在数据库正面去清理数据了

自动部署的清单

位于目录路径的清单/var/lib/rancher/k3s/server/manifests在构建时被捆绑到 K3s 二进制文件中。这些将由rancher/helm-controller在运行时安装

[root@localhost tls]# ls /var/lib/rancher/k3s/server/manifests/
ccm.yaml  coredns.yaml  local-storage.yaml  metrics-server  rolebindings.yaml  traefik.yaml
[root@localhost tls]# ls /var/lib/rancher/k3s/server/manifests/metrics-server/
aggregated-metrics-reader.yaml  auth-delegator.yaml  auth-reader.yaml  metrics-apiservice.yaml  metrics-server-deployment.yaml  metrics-server-service.yaml  resource-reader.yaml
[root@localhost tls]#

在 K3s v1.20.2 之前:

基本原理

Agent注册的过程是十分复杂的,总的来说有两个目的:

  • 启动kubelet等服务,连接到server节点上的api-server服务,这是k8s集群必须的
  • 建立websocket tunnel,用于k3s的server和agent同步一些信息

我们在注册agent时只提供了server地址和node-token,agent是如何一步一步完成注册的?首先看node-token的格式:

在k3s的master端

[root@localhost tls]# cat /var/lib/rancher/k3s/server/node-token 
K107081ea35382d9c0c04f1930e6af4d71cc916ee4a9b70f5f3cbde02f3160e2204::server:2c011429c5dcc7a64e675d14863ebd89

在这里插入图片描述

这里的user和password会对应k3s api-server中basic auth的配置,k3s api-server启动时会设置一个特殊的authentication方式就是basic auth,对应文件在server节点的/var/lib/rancher/k3s/server/cred/passwd中:

[root@localhost tls]# cat /var/lib/rancher/k3s/server/cred/passwd 
2c011429c5dcc7a64e675d14863ebd89,server,server,k3s:server
2c011429c5dcc7a64e675d14863ebd89,node,node,k3s:agent

由此agent端通过解析node-token,可以获得一个和k3s api-server通信的授权,授权方式是basic auth。

了解node-token的作用,我们就可以解开agent注册过程的序幕,参考下图:在这里插入图片描述

以黄色文本框顺序为例,前三步是为了得到启动kubelet服务各种依赖信息,最后一步建立websocket通道。我们可以只关心前面三步,最重要的是api-server的地址,还有各种k8s组件通信的tls证书,由于那些证书是在server上签发,所以agent需要通过一些API请求获取,这些证书大致有:

[root@localhost tls]# ls
client-admin.crt       client-ca.key                    client-k3s-controller.crt  client-kube-proxy.crt  etcd                   service.key
client-admin.key       client-controller.crt            client-k3s-controller.key  client-kube-proxy.key  request-header-ca.crt  serving-kube-apiserver.crt
client-auth-proxy.crt  client-controller.key            client-kube-apiserver.crt  client-scheduler.crt   request-header-ca.key  serving-kube-apiserver.key
client-auth-proxy.key  client-k3s-cloud-controller.crt  client-kube-apiserver.key  client-scheduler.key   server-ca.crt          serving-kubelet.key
client-ca.crt          client-k3s-cloud-controller.key  client-kubelet.key         dynamic-cert.json      server-ca.key          temporary-cert

这些证书中kubelet两个证书最为特殊,由于kubelet在每个节点都运行,所以安全需要我们需要给每个kubelet node都单独签发证书(node-name作为签发依据)。涉及到单独签发就需要验证node信息是否合法,这时node-passwd就粉墨登场了。

这个过程大致是这样的,agent先生成一个随机passwd(/etc/rancher/node/password),并把node-name和node-passwd信息作为证书请求的request header发给k3s server,由于agent会向server申请两个kubelet证书,所以会收到两个带有此header的请求。如果agent首次注册,server收到第一个请求后,会把这个node-name和node-passwd解析出来存储到/var/lib/rancher/k3s/server/cred/node-passwd(注意K3s v1.20.2之前是这里)中,收到第二个请求后会读取node-passwd文件与header信息校验,信息不一致则会403拒绝请求。如果agent重复注册时,server会直接比对request header内容和本地信息,信息不一致也会403拒绝请求。

对比agent也就是node节点上的node-passwd(/etc/rancher/node/password)和server上的node-paswd:

agent
$ cat /etc/rancher/node/password
47211f28f469622cccf893071dbda698

server
$ hostname
cat /var/lib/rancher/k3s/server/cred/node-passwd
31567be88e5408a31cbd036fc9b37975,ip-172-31-13-54,ip-172-31-13-54,
cf3f4f37042c05c631e07b0c0abc528f,xxxxx,xxxxxx,

Agent node对应的passwd和server中存储的hostname对应的passwd不一致,按照我们前面说的基本原理,就会出现403的错误日志。

解决方案

为什么会出现passwd不一致呢?正常来说如果用k3s-agent-uninstall.sh来清理安装过的agent node,并不会删除password文件(/etc/rancher/node/password),那么问题很可能是VM重建或者手动操作删除的这个文件。因为agent上删除了password,agent再次注册时会重新生成password,就导致了新的password和server上原先存储的不一致。

解决办法可以有三种:

  • 手动在agent上创建password,内容和server中存储保持一致
  • 修改了server中的原始内容,让password和agent上新生成的保持一致
  • 可以试试agent注册时使用--with-node-id,这样server中认为这完全是新node,不会用原始信息比对

总 结

原则上不建议用户去触碰文中提到的这些文件,尽量把控制权交给k3s,即使我们清理agent节点,也尽量利用k3s内置的脚本。如果碰到此类问题,可以参考本文的原理介绍去分析,并通过已知的解决方案去修复它。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值