配置文件设置 Kubelet 和kube-proxy参数

在后续集群安装kubelet时有些参数 ,建议通过配置文件的方式提供参数,因为这样可以简化节点部署和配置管理

 具体参考文档

https://kubernetes.io/zh/docs/tasks/administer-cluster/kubelet-config-file/

https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/

相应配置参数的字段类型都可以在这里面找到

https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/kubelet/config/v1beta1/types.go

https://blog.csdn.net/qq_38496902/article/details/106560163

KubeletConfiguration 结构体定义了可以通过文件配置的 Kubelet 配置子集、

提示一下:types.go出现的配置字段 ,如果要写入yaml文件参考后面json 格式配置文件必须是这个结构体中参数的 JSON 或 YAML 表现形式

https://github.com/ReSearchITEng/kubeadm-playbook/blob/master/group_vars/all/KubeletConfiguration.yml

 

 

最终的kubelet 相应的配置文件截图

 

相应的配置文件说明

https://kubernetes.io/docs/reference/config-api/kube-proxy-config.v1alpha1/

https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kubelet/

同理 kube-proxy也通过配置文件来启动,启动的时候有提示

https://github.com/kubernetes/kube-proxy/blob/master/config/v1alpha1/types.go

https://pkg.go.dev/k8s.io/kube-proxy/config/v1alpha1#KubeProxyConfiguration

配置文件格式

https://github.com/ReSearchITEng/kubeadm-playbook/blob/master/group_vars/all/KubeProxyConfiguration.yml

https://kubernetes.io/docs/reference/config-api/kube-proxy-config.v1alpha1/

 

启动脚本

相关的启动参数说明:

https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-proxy/

 

Kubelet 认证/鉴权

 

在通过kubectl访问pod信息,例如执行kubectl logs,常常会遇到类似如下错误:

 

Error from server (Forbidden): Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) ( pods/log tiller-deploy-6b5ffb6f-lg9jb)

 

-tools-reference/kubelet-authentication-authorization/

网上搜索可以通过启用anonymous访问,也就是使用--anonymous-auth=true

或者配置文件添加:

authentication:
    anonymous:
        enabled: true

但是设置之后错误依旧,为此我探究了一下kubelet的认证机制,终于将问题解决,其实很简单,答案后面揭晓。

官方文档介绍:

https://kubernetes.io/zh/docs/reference/command-line

我们知道kubectl只会和apiserver交互,对于kubectl logs kubectl exec等需要访问pod的这些命令,实际上是apiserver调用kubelet接口完成的,上述错误正是出在这个过程,而不是kubectl到apiserver的过程。

kubelet通过port指定的端口(默认10250)对外暴露服务,这个服务是需要TLS认证的,同时也可以通过 readOnlyPort 端口(默认10255,0表示关闭)对外暴露只读服务,这个服务是不需要认证的。

apiserver通过 --kubelet-https 参数指定调用哪个服务,true为前者,false为后者,此时只能执行只读操作。

认证过程

配置认证方式

有三种可配置认证方式:

  1. TLS认证,这也是默认的

    authentication:
        anonymous:
            enabled: false
        webhook:
        	enabled: false
        x509:
        	clientCAFile: xxxx
    
  2. 允许anonymous,这时可不配置客户端证书

    authentication:
        anonymous:
            enabled: true
    
  3. webhook,这时可不配置客户端证书

    authentication:
        webhook:
        	enabled: true

这时kubelet通过bearer tokens,找apiserver认证,如果存在对应的serviceaccount,则认证通过

如果2开启,则忽略x509和webhook认证;否则,如果1和3同时开启,则按1、3的顺序依次认证,任何一个认证通过则返回通过,否则认证不通过。

通过kubectl命令行访问kubelet时,无法传递bearer tokens,所以无法使用webhook认证,这时只能使用x509认证

默认情况下,到kubelet HTTPS endpoints且没有被其他配置的认证方法拒绝的请求被视为匿名请求。

对于匿名请求会给定system:anonymous的用户名和system:unauthenticated用户组

禁止匿名用户访问,对不可靠的请求返回401 Unauthorized:
启动kubelet的时候添加--anonymous-auth=false参数

开启X509客户端证书认证:
- 添加启动参数--client-ca-file, 并提供一个验证客户端证书的CA。
- 启动apiserver时需添加--kubelet-client-certificate 和 --kube-client-key 参数
- 详情参考 apiserver authentication documentation

 

 

 

kubelet对外暴露https服务,必须设置服务端证书,如果通过x509证书认证客户端,那么还需要配置客户端证书。

下面说明证书配置的三种方法:

手工指定证书
假设ca的证书和key:ca.pem,ca-key.pem

用上述ca生成kubelet服务端证书和key:kubelet-server.pem、kubelet-server-key.pem

用上述ca生成apiserver使用的客户端证书和key:kubelet-client.pem、kubelet-client-key.pem,证书CN为kubelet-client

修改kubelet的配置文件

tlsCertFile: kubelet-server.pem
tlsPrivateKeyFile: kubelet-server-key.pem
authentication:
x509:
clientCAFile: ca.pem
修改apiserver参数:

--kubelet-certificate-authority=ca.pem --kubelet-client-certificate=kubelet-client.pem --kubelet-client-key=kubelet-client-key.pem
授权kubelet-client用户:

kubectl create clusterrolebinding kubelet-admin --clusterrole=system:kubelet-api-admin --user=kubelet-client
经过上面5步,认证的过程实际已经OK了,第6步是为授权过程服务的,kubelet的授权是通过webhook委托给apiserver的。

自签名证书和key
实际上是上述过程的特化,不指定tlsCertFile和tlsPrivateKeyFile时,kubelet会自动生成服务端证书保存在--cert-dir指定目录中,文件名为kubelet.crt和kubelet.key,这个证书是自签名的,所以apiserver不需要指定--kubelet-certificate-authority,其他配置是一样的

通过TLS bootstrap机制
还可以通过TLS bootstrap机制分配kubelet服务证书。配置分配访问apiserver的客户端证书方法是一样的(参考官方文档)或者我前面写的文章

之后在相应kubelet的--cert-dir目录可以看到服务端证书已经生成。

配置客户端证书和前面的方法是一样的,上面3步只是生成服务端证书。

选择哪种方式
客户端证书配置是免不了的,区别是在服务端证书,显然自动生成更加方便,TLS bootstrap相对于自签名证书更加安全,集群统一使用信任的CA签名。

授权过程

配置授权方式

可配置两种授权方式:

  1. AlwaysAllow:从字面意思就可知道

    authorization:
    	mode: AlwaysAllow
    
  2. Webhook:这是默认模式

    authorization:
    	mode: Webhook
    

    这时授权过程是委托给apiserver的,使用apiserver一样的授权模式,也就是RBAC。

配置权限

如果通过Webhook授权,就需要通过RBAC为用户配置权限。

首先要弄清楚通过认证的用户是什么,通过x509证书认证的用户名是客户端证书中的CN字段,用户组为O字段;通过webhook认证的用户是token对应的serviceaccount;没有通过认证或使能anonymous,则用户为system:anonymous。

其次要弄清楚应该授权什么权限,系统已经存在一个system:kubelet-api-admin角色,这是最高的权限,可以根据需要创建低权限角色。

如果不创建权限会报相应的错误

 

 

 

确保传递给apiserver的--kubelet-client-certificate--kubelet-client-key标志所标识的用户具有以下属性的权限:

  • 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

kubectl create clusterrolebinding kubernetes   --clusterrole=system:kubelet-api-admin   --user=kubernetes 

这边吧kubelet-api-admin的权限用户给到证书里标识的用户

 

最终kubelet 的配置文件:

 

 

总结

如何配置kubelet的认证和授权,归结起来常用如下2种做法:

  1. 省事型,可用于开发环境

    authentication:
        anonymous:
            enabled: true
    authorization:
    	mode: AlwaysAllow        
    

    一开始出现的Forbidden问题就是没有配置AlwaysAllow,默认是Webhook。

  2. 安全型,生产环境使用

    authentication:
        anonymous:
            enabled: false
    authorization:
    	mode: Webhook
    

    服务端证书通过TLS bootstrap,客户端证书需要手工配置。

参考文档:

https://www.cnblogs.com/zhongpan/p/11964017.html

https://blog.csdn.net/mailjoin/article/details/79679882 

posted @ 2020-12-14 11:09  屌丝的IT  阅读(4872)  评论(0编辑  收藏  举报