v1.16、v1.19.5
注意
关闭 swap
不关在启动 kubelet 与 kube-proxy 的时候会提示,不支持 swap 环境启动。
firewalld, selinux 也关闭。
系统时区
一、介绍
kubelet 是主要的工作节点程序,功能如下:
-
注册节点。
-
从 apiserver 监测已分配给节点的 pod 信息, 或者是从本地配置中获取 pod 信息, 启动 pod。
-
执行容器健康检查。探针。
-
挂载 pod 需要挂载的卷。
-
下载 pod 需要的 secret, configmap, 并挂载。
-
监控容器和节点资源。
-
发送节点状态和 pod 状态给 apiserver。
-
提供/metrics/cAdvisor 监控接口。
二、参数
还是单独出来了,随着学习越写越多,太占篇幅了。
https://www.yxingxing.net/archives/kubelet-20201217-parameter
三、文件
也就是目录结构还有执行文件。conf 目录下的文件一会 er 生成。
[root@k8s-node1 k8s]# tree
.
├── bin
│ ├── kubelet
│ └── kube-proxy
├── conf
├── logs
└── ssl
4 directories, 2 files
四、Unit
[Unit]
Description=kubelet
Requires=docker.service
[Service]
ExecStart=/usr/local/k8s/bin/kubelet\
--address=172.100.102.71 \
--bootstrap-kubeconfig=/usr/local/k8s/conf/bootstrp-kubeconfig \
--cert-dir=/usr/local/k8s/ssl \
--cgroup-driver=systemd \
--cluster-dns=10.0.0.2 \
--cluster-domain=cluster.local \
--kubeconfig=/usr/local/k8s/conf/kubeconfig \
--log-dir=/usr/local/k8s/logs \
--logtostderr=false \
--rotate-certificates \
--v=4 \
--root-dir=/usr/local/kubelet-data \
--pod-infra-container-image=registry.cn-beijing.aliyuncs.com/yangxingxing/pause:3.1
Restart=on-failure
[Install]
WantedBy=multi-user.target
这里的 pause 镜像是从 google 云下载并上传到阿里的,可以使用。
五、配置自动获取证书
如果不需要自动获取证书就不需要这一步
详细流程:
这个页面不要选择语言为中文, 发现页面不一样,看起来是非常老的信息,而且也是英文的。
https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/
证书轮换:
https://kubernetes.io/zh/docs/tasks/tls/certificate-rotation/
初始化流程截出来了,页面翻译的:
引导程序初始化
在引导程序初始化过程中,会发生以下情况:
kubelet开始
kubelet认为,它并没有有一个kubeconfig文件
kubelet搜索并找到bootstrap-kubeconfig文件
kubelet读取其引导程序文件,检索API服务器的URL和有限用法的“令牌”
kubelet连接到API服务器,使用令牌进行身份验证
kubelet现在具有有限的凭据来创建和检索证书签名请求(CSR)
kubelet为自己创建一个CSR,并将signerName设置为 kubernetes.io/kube-apiserver-client-kubelet
通过以下两种方式之一批准CSR:
如果已配置,则kube-controller-manager会自动批准CSR
如果进行了配置,则外部流程(可能是一个人)会使用Kubernetes API或通过以下方式批准CSR kubectl
为kubelet创建了证书
证书已颁发给kubelet
kubelet检索证书
kubeletkubeconfig使用密钥和签名证书创建一个正确的名称
kubelet开始正常运行
可选:如果已配置,则kubelet在证书即将到期时会自动请求更新证书
根据配置,自动或手动批准和颁发续签的证书。
bootstrap令牌验证:
https://kubernetes.io/zh/docs/reference/access-authn-authz/bootstrap-tokens/
这里的bootstrap是一种认证方式。非必须,也可以使用其他认证方式。
kubelect参数的bootstrip-kubeconfig是引导获取证书的意思
而bootstrap认证是一种认证方式,专门用于kubelet引导启动时认证的。
1、kube-apiserver需要做的
https://www.yxingxing.net/articles/2019/10/30/1572423121991.html
(1)需要启用enable-bootstrap-token-auth参数。只有使用bootstrap令牌验证的方式需要。如果不使用bootstrap令牌验证,就不需要enable-bootstrap-token-auth参数。
--enable-bootstrap-token-auth
如果使用token的方式就是:
--token-auth-file=FILENAME
如果使用token的方式, 官方网站显示组名是固定的system:bootstrappers。
如:
令牌, 用户名, 用户id, 组名。
02b50b05283e98dd0fd71db496ef01e8,kubelet-bootstrap,10001,"system:bootstrappers"
无论是引导令牌认证,还是token认证,授权都一样。
(2)授权kubelet创建CSR证书签名请求。
直接把创建clusterrolebinding的内容直接复制下来并应用就可以。
[root@k8s-master init]# cat kubelet-csr.yaml
# enable bootstrapping nodes to create CSR
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: create-csrs-for-bootstrapping
subjects:
- kind: Group
name: system:bootstrappers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: system:node-bootstrapper
apiGroup: rbac.authorization.k8s.io
[root@k8s-master init]# kubectl apply -f kubelet-csr.yaml
clusterrolebinding.rbac.authorization.k8s.io/create-csrs-for-bootstrapping created
[root@k8s-master init]#
(3)授权可以签发证书。
其中又有两种方式:
1、节点还没有证书,只能使用bootstrip令牌认证,这就需要跟上面一样给system:bootstrappers组授权。
页面翻译的,能理解就行。创建一个clusterrolebinding。
[root@k8s-master init]# cat kubelet-new-crt.yaml
# Approve all CSRs for the group "system:bootstrappers"
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: auto-approve-csrs-for-group
subjects:
- kind: Group
name: system:bootstrappers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
apiGroup: rbac.authorization.k8s.io
[root@k8s-master init]# kubectl apply -f kubelet-new-crt.yaml
clusterrolebinding.rbac.authorization.k8s.io/auto-approve-csrs-for-group created
[root@k8s-master init]#
2、节点有证书,需要续订证书,就给system:nodes
组,赋予可以续订证书的权限。
因为自动签署的证书里的组就是system:nodes
, 可以通过一条命令查看:
[root@k8snode1 cert]# openssl x509 -in kubelet-client-2020-12-16-09-08-23.pem -noout -subject
subject= /O=system:nodes/CN=system:node:k8snode1
[root@k8snode1 cert]#
给system:nodes
组续订证书的权限。
[root@k8s-master init]# cat kubelet-renew-crt.yaml
# Approve renewal CSRs for the group "system:nodes"
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: auto-approve-renewals-for-nodes
subjects:
- kind: Group
name: system:nodes
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
apiGroup: rbac.authorization.k8s.io
[root@k8s-master init]# kubectl apply -f kubelet-renew-crt.yaml
clusterrolebinding.rbac.authorization.k8s.io/auto-approve-renewals-for-nodes created
[root@k8s-master init]#
权限创建完了。
2、controller-manager需要做的
其实就是启动的时候加上三个参数以及开启bootstrap控制器。
--cluster-signing-cert-file=
--cluster-signing-cert-file
--experimental-cluster-signing-duration
controller-manager 需要启动bootstrapsigner控制器。默认是启动的。
--experimental-cluster-signing-duration
这个参数在v1.19.5变成了--cluster-signing-duration
。
3、kubelet
- 存储生成的密钥和证书的路径(可选,可以使用默认值)
kubeconfig
尚不存在的文件的路径;它将引导文件放在这里bootstrap-kubeconfig
文件的路径,用于提供服务器和引导程序凭据的URL,例如引导程序令牌。- 续订证书的配置,一个参数:
--rotate-certificates
。 官方网站说明还有一个功能标记RotateKubeletClientCertificate
,默认就是启用的,而且我也没找到。
在上面的启动参数里都已经加上了。
现在就剩创建bootstrap-kubeconfig文件了。
4、配置bootstrap-kubeconfig文件
这个文件与一般的kubeconfig文件格式一样, 只是 user 部分使用 bootstrap-token。 所以主要是创建bootstrap-token。
说明bootstrap-token格式
https://kubernetes.io/zh/docs/reference/access-authn-authz/bootstrap-tokens/
就是这个格式,如果能打开上面的网址, 里面都有介绍。 要求大致如下:
-
token必须类似 abcdef.0123456789abcdef 这种格式,必须匹配正则表达式
[a-z0-9]{6}\.[a-z0-9]{16}
,令牌的第一部分是“token-id”,后面部分是tokne-secret。 -
type 必须为
bootstrap.kubernetes.io/token
, -
name 必须为
bootstrap-token-<token id>
, -
必须在
kube-system
namespace 中。
其他说明:
-
expiration
字段控制令牌的到期时间。过期的令牌在用于身份验证时将被拒绝,并在ConfigMap签名期间被忽略。到期值使用RFC3339编码为绝对UTC时间。 -
controller-manager启用
tokencleaner
控制器 能够自动删除过期的令牌。 -
usage-bootstrap-*
表示这是用于什么。必须将值设置为true
启用。有下面两个。 -
usage-bootstrap-authentication
表示令牌可以用作承载令牌向API服务器进行身份验证。 -
usage-bootstrap-signing
指示令牌可用于签署cluster-info
ConfigMap。 -
auth-extra-groups
: 令牌默认的组是system:bootstrappers
, 如果需要设置额外的组,就在这里添加,组名必须以 "system:bootstrappers:" 开头。
创建bootstrip-token
生成一些随机值:
[root@k8s-master init]# openssl rand -base64 20
yiCm94HtA5vm1Y6Nt1oWcN3wfRE=
摘出来几个做token-id, 和 token-secret, 大写变成小写就可以。
[root@k8s-master init]# cat bootstrip-token.yaml
apiVersion: v1
kind: Secret
metadata:
# Name MUST be of form "bootstrap-token-<token id>"
name: bootstrap-token-yicm94
namespace: kube-system
# Type MUST be 'bootstrap.kubernetes.io/token'
type: bootstrap.kubernetes.io/token
stringData:
# Token ID and secret. Required.
token-id: yicm94
token-secret: hta5vm1y6nt1owcn
# Expiration. Optional.
expiration: 2019-11-28T03:22:11Z
# Allowed usages.
usage-bootstrap-authentication: "true"
usage-bootstrap-signing: "true"
[root@k8s-master init]# kubectl apply -f bootstrip-token.yaml
secret/bootstrap-token-yicm94 created
[root@k8s-master init]#
注意过期时间。
接下来直接把kubectl使用的config文件或者自己新创建一个文件, 放到kubelect启动参数bootstrap-kubeconfig所指定的文件。
删除原来文件user部分的证书认证,把token放进去。
成了这个样子就可以了。接下来就可以启动kubelet了。
另外: 上面的server 我这里没有连接vip, 因为还要安装hasproxy 或 nginx做负载均衡代理到后面的apiserver。 这里只是说明kubelet, 就不折腾了。
五、启动kubelet。
[root@k8s-node1 k8s]# tree
.
├── bin
│ ├── kubelet
│ └── kube-proxy
├── conf
│ └── bootstrp-kubeconfig
├── logs
└── ssl
4 directories, 3 files
[root@k8s-node1 conf]# systemctl start kubelet
[root@k8s-node1 k8s]# tree
.
├── bin
│ ├── kubelet
│ └── kube-proxy
├── conf
│ ├── bootstrp-kubeconfig
│ └── kubeconfig
├── logs
│ ├── kubelet.ERROR -> kubelet.k8s-node1.root.log.ERROR.20191124-020405.7817
│ ├── kubelet.INFO -> kubelet.k8s-node1.root.log.INFO.20191124-020344.7817
│ ├── kubelet.k8s-node1.root.log.ERROR.20191124-020405.7817
│ ├── kubelet.k8s-node1.root.log.INFO.20191124-020344.7817
│ ├── kubelet.k8s-node1.root.log.WARNING.20191124-020345.7817
│ └── kubelet.WARNING -> kubelet.k8s-node1.root.log.WARNING.20191124-020345.7817
└── ssl
├── kubelet-client-2019-11-24-02-03-44.pem
├── kubelet-client-current.pem -> /usr/local/k8s/ssl/kubelet-client-2019-11-24-02-03-44.pem
├── kubelet.crt
└── kubelet.key
4 directories, 14 files
在master节点查看一下:
[root@k8s-master logs]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-node1 Ready <none> 52s v1.16.2
另外: 上面是通过bootstrap-token的方式认证的,不清楚其他的认证方式,如:
证书的方式, 是不是需要固定组为system:bootstrappers, 然后也是按上面的方式给这个组授权。
六、一些额外的东西
1、证书的组与用户
因为要给kubelet
使用Node鉴权模式,需要system:ndoes
组以及system:node:<nodeName>
用户,所以就算不使用自动颁发的证书,自己手动给kubelet创建证书的时候。也需要指定组名system:ndoes
和用户名system:node:<nodeName>
。 如果不使用Node鉴权,比如要使用RBAC,那就无所谓了。
Node鉴权:
https://kubernetes.io/zh/docs/reference/access-authn-authz/node/
2、续订证书时的用户
测试发现在bootstrip-token可以使用的情况下,续订证书中的csr请求用户是bootstrap-token, 而在token过期或者删除的情况下就是node了。
[root@k8smaster1 bootstrip]# kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
csr-6hzp8 45m kubernetes.io/kube-apiserver-client-kubelet system:node:k8snode1 Approved,Issued
csr-d5jwf 25s kubernetes.io/kube-apiserver-client-kubelet system:node:k8snode1 Approved,Issued
csr-lj4nz 89m kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:h9qwkh Approved,Issued
可能会有疑问,之前授权的是system:nodes
组,这里显示的请求是system:node:k8snode1
用户。
csr请求里面是有组的,只是没有显示出来而已,详细信息就可以看到了。