--logtostderr # 是否把日志打印到标准错误输出
--log-dir # 日志目录
--etcd-servers # etcd
--etcd-cafile # 用来认证etcd的ca证书
--etcd-certfile # 用来连接etcd的证书。
--etcd-keyfile
--bind-address # 监听的有安全连接(https)的ip地址。
--advertise-address # 要广播给集群成员的ip地址, 必须要能够访问, 如果为空,就是--bind-address的地址,如果都没有,则为机器默认地址。
--secure-port # https安全连接的端口
--tls-cert-file # apiserver https的证书。
--tls-private-key-file
--service-cluster-ip-range # service ip 范围, 不能与pod ip范围冲突。
--service-node-port-range # service nodePort 范围
--allow-privileged # 是否允许特权容器。
--kubelet-https # 使用https连接kubelet, 执行kubectl log, exec之类的操作,apiserver需要连接kubelet。 默认就是true
--master-service-namespace # kubernetes service放到哪个namespace, 默认default。
# 准入控制
--admission-control # 使用enable-admission-plugins 或 disable-admission-plugins代替, 未来版本会删除这个参数。
--enable-admission-plugins # 启用的准入控制插件。
--disable-admission-plugins # 关闭的准入插件。
# 认证方式,不是authorization-mode授权那个。是第一层的认证。
--anonymous-auth # 匿名访问,默认就是true。在没有被这层的其他认证方式拒绝的情况下就是匿名访问,比如在请求中证书或者是token都没有提供。 匿名访问拥有用户`system:anonymous`和组`system:unauthenticated`,给匿名访问授权就通过这俩。
--authentication-token-webhook-config-file # 通过远程服务器认证
--authentication-token-webhook-cache-ttl # 对身份认证决定的缓存时间,默认2分钟。
--client-ca-file # 用来认证客户端的ca证书。
--requestheader-client-ca-file # 用来认证客户端的ca证书, 认证通过以后,还要查看客户端的common name 是否包含在requestheader-allowed-names指定的列表里。
--requestheader-allowed-names # 与requestheader-client-ca-file一起提供认证。
--service-account-key-file # 解密验证service account token 的,可以使用证书,最好生成一个秘钥对,这里指定公钥。 controller-manager那里指定私钥。
--enable-bootstrap-token-auth # 使用bootstrap-token认证需要启用这个,注意:这个bootstrap-token认证只是一种认证方式,不是启用bootstrap方式获取证书。他是只用于获取证书过程中的一种认证方式,但是获取证书的认证不是只有这一种,比如下面的--token-auth-file认证也可以。
--token-auth-file # 可以使用token文件认证。
# 上面的认证方式是'或'的关系, 只要有一种认证通过就行。
# (--requestheader-client-ca-file AND --requestheader-allowed-names) OR --client-ca-file OR --service-account-key-file OR --token-auth-file
# 授权相关。
--authorization-mode # 授权认证模式, 一般是: RBAC, Node
--authorization-webhook-config-file # 通过远程服务器确认授权。
# 扩展api相关
--proxy-client-cert-file # apiserver连接别人的证书,用于连接扩展API。
--proxy-client-key-file
# 身份认证代理
--requestheader-extra-headers-prefix=X-Remote-Extra- # 指定额外信息使用的HTTP头部名称。
--requestheader-group-headers=X-Remote-Group # 指定存放用户组的http头部
--requestheader-username-headers=X-Remote-User # 指定存放用户名的http头部。
生成一对密钥:
私钥:
openssl genrsa -out sa.key 2048
公钥:
openssl rsa -in sa.key -pubout -out sa.pub
requestheader-client-ca-file, client-ca-file
--requestheader-client-ca-file 与 --client-ca-file的不同就是前者还要通过--requestheader-allowed-names。
一般情况下, --requestheader-client-ca-file与--requestheader-allowed-names用来认证扩展的api服务,
就是创建kind: APIService的服务,如 metrics-server就是这样的。
--client-ca-file 是认证一般用户的。
--requestheader-client-ca-file 与 --client-ca-file 需要使用不同的CA,因为他们的认证方式是这个样子的:
(--requestheader-client-ca-file and --requestheader-allowed-names) or --client-ca-file
如果使用相同的ca, 会导致--requestheader-client-ca-file认证通过, 然后就会去判断--requestheader-allowed-names。
apiserver访问kubelet相关的参数
在执行kubectl logs, kubectl exec之类的命令时,apiserver需要访问kubelet。 这时就不是apiserver来认证kubelet了, 而是kubelet来认证apiserver。
1、--kubelet-https
:
apiserver是否访问kubelet的https端口。 kubelet有两个端口, 一个是https端口,需要认证。 一个是http端口,不需要认证,是只读端口。
https端口虽然需要认证,但是因为kubelet默认开启了匿名访问,并且鉴权部分是允许所有,所以apiserver也是可以请求kubelet的。
2、--kubelet-certificate-authority
:
指定CA证书, 在apiserver连接kubelet时,用来验证kubelet的https端口证书。 默认情况下kubelet的https证书是自签证书,没有ca,这个参数也就用不了了。 只有在kubelet指定了证书,或者是自动签署的服务证书,拥有CA证书的情况下,才会考虑是否用这个来验证。验证我访问的kubelet确实是我要访问的。
这个参数与下面这俩参数没关系。
3、--kubelet-client-certificate、--kubelet-client-key
:
apiserver请求kubelet时提供的证书。 在kubelet关闭匿名访问,并且打开了客户端证书认证的时候。 apiserver必须指定这俩参数,不然kubectl logs, kubectl exec 这类需要访问kubelet的请求就会失败。
具体的kubelet认证可以看这里:
https://www.yxingxing.net/archives/kubelet-20201216-authentication
enable-bootstrap-token-auth
--enable-bootstrap-token-auth: 启用bootstrap-token认证。 允许kubelet在引导时使用bootstrap-token认证。 专门用于kubelet引导启动时认证的。
是一种用于验证kubelet的更简单且更易于管理的方法,并且在启动kube-apiserver时不需要任何其他标志。需要创建secret资源。
kubelet自动从apiserver获取签署的TLS证书,kubelet需要--bootstreap-kubeconfig配置文件设置令牌,其中的user部分就可以使用bootstrap-token, 也可以使用--token-auth-file里的token认证。证书可能也可以, 没有试过。
因为bootstrap-token是专用于kubelet引导启动时认证的,而且还有过期时间,所以安全性也高。
启用以后,可以在kube-system命名空间创建bootstrap.kubernetes.io/token类型的secret来创建token。
还需要在kube-controller-manager里面注意--controllers参数(启用的控制器), 需要启用bootstrapsigner, 默认是启用所有的, 一般不用管。
TLS引导以及相关配置: https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/
bootstrap令牌验证: https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/
从上面的网址中抄出来的权限设置方式:
bootstrap的token没有明显的user和group, 使用的是k8s内置的system:bootstrappers组和system:nodes组,所以给这两个组授权就可以了。
1、 授权kubelet创建CSR证书请求文件, 需要给system:bootstrappers组绑定k8s内置的system:node-bootstrapper 角色。
2、 设置CSR是可以签署的, 需要给system:bootstrappers组绑定k8s内置的system:certificates.k8s.io:certificatesigningrequests:nodeclient 角色。
3、 授权kubelet能够自动续订证书, 需要给system:nodes组绑定k8s内置的system:certificates.k8s.io:certificatesigningrequests:selfnodeclient角色.
这种自动获取证书的方式,也不仅仅只有bootstrap令牌, 也可以用其他的验证方式,如serviceaccount token, 如统一的证书, 只要权限设置正确,kubelete的bootstrp-kubeconfig设置好就可以用了。
匿名访问
anonymous-auth
这个参数默认是启用的,--anonymous-auth=false
可以关闭。
在其它的认证方式都没有拒绝的情况下,就是匿名访问。
给匿名访问授权通过用户system:anonymous
和组system:unauthenticated
.
如:
我这里开启的认证只有证书, 不提供证书,也就不会被拒绝。就是匿名访问了。
只不过没有对services
资源的访问权限。
[root@k8smaster1 bin]# curl --cacert /opt/kubernetes/cert/k8s/k8s_ca.pem https://192.168.1.221:6443/api/v1/services
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "services is forbidden: User \"system:anonymous\" cannot list resource \"services\" in API group \"\" at the cluster scope",
"reason": "Forbidden",
"details": {
"kind": "services"
},
"code": 403
}[root@k8smaster1 bin]#
给匿名组或者用户添加权限就可以, 我这里给组添加了内置的view
角色,有获取一些资源的权限。
[root@k8smaster1 bin]# kubectl create clusterrolebinding anonymous-view --clusterrole=view --group=system:unauthenticated
clusterrolebinding.rbac.authorization.k8s.io/anonymous-view created
再执行curl就有东西了, 列出的是刚建立集群就存在的service
: kubernetes
。
[root@k8smaster1 bin]# curl --cacert /opt/kubernetes/cert/k8s/k8s_ca.pem https://192.168.1.221:6443/api/v1/services
{
"kind": "ServiceList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/services",
"resourceVersion": "70562"
},
"items": [
{
"metadata": {
"name": "kubernetes",
"namespace": "default",
"selfLink": "/api/v1/namespaces/default/services/kubernetes",
"uid": "1d0edcb5-80d1-433d-9f0f-4f2b5faae6b5",
"resourceVersion": "162",
"creationTimestamp": "2020-12-13T11:21:12Z",
"labels": {
"component": "apiserver",
"provider": "kubernetes"
},
"managedFields": [
{
"manager": "kube-apiserver",
"operation": "Update",
"apiVersion": "v1",
"time": "2020-12-13T11:21:12Z",
"fieldsType": "FieldsV1",
"fieldsV1": {"f:metadata":{"f:labels":{".":{},"f:component":{},"f:provider":{}}},"f:spec":{"f:clusterIP":{},"f:ports":{".":{},"k:{\"port\":443,\"protocol\":\"TCP\"}":{".":{},"f:name":{},"f:port":{},"f:protocol":{},"f:targetPort":{}}},"f:sessionAffinity":{},"f:type":{}}}
}
]
},
"spec": {
"ports": [
{
"name": "https",
"protocol": "TCP",
"port": 443,
"targetPort": 6443
}
],
"clusterIP": "10.0.0.1",
"type": "ClusterIP",
"sessionAffinity": "None"
},
"status": {
"loadBalancer": {
}
}
}
]
}[root@k8smaster1 bin]#
关闭匿名访问以后:
[root@k8smaster1 controller]# curl --cacert /opt/kubernetes/cert/k8s/k8s_ca.pem https://192.168.1.221:6443/api/v1/services
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "Unauthorized",
"reason": "Unauthorized",
"code": 401
}[root@k8smaster1 controller]#
参数配置
测试环境:
[Unit]
Description=kubernetes api server
After=network-online.target
[Service]
ExecStart=/opt/kubernetes/bin/kube-apiserver \
--log-dir=/opt/kubernetes/log/apiserver \
--logtostderr=false \
--v=4 \
--etcd-cafile=/opt/kubernetes/cert/etcd/etcd-ca.pem \
--etcd-certfile=/opt/kubernetes/cert/etcd/kube-apiserver-etcd-client.crt \
--etcd-keyfile=/opt/kubernetes/cert/etcd/kube-apiserver-etcd-client.key \
--etcd-servers=https://172.100.101.171:2379,https://172.100.101.172:2379,https://172.100.101.173:2379 \
--tls-cert-file=/opt/kubernetes/cert/k8s/kube-apiserver.crt \
--tls-private-key-file=/opt/kubernetes/cert/k8s/kube-apiserver.key \
--proxy-client-cert-file=/opt/kubernetes/cert/front-proxy/front-proxy-client.crt \
--proxy-client-key-file=/opt/kubernetes/cert/front-proxy/front-proxy-client.key \
--requestheader-client-ca-file=/opt/kubernetes/cert/front-proxy/front-proxy-ca.pem \
--requestheader-allowed-names=front-proxy-client \
--requestheader-extra-headers-prefix=X-Remote-Extra- \
--requestheader-group-headers=X-Remote-Group \
--requestheader-username-headers=X-Remote-User \
--enable-bootstrap-token-auth \
--authorization-mode=RBAC,Node \
--client-ca-file=/opt/kubernetes/cert/k8s/kubernetes-ca.pem \
--service-account-key-file=/opt/kubernetes/cert/k8s/sa.pub \
--allow-privileged \
--service-cluster-ip-range=10.0.0.0/16 \
--kubelet-client-certificate=/opt/kubernetes/cert/k8s/kube-apiserver-kubelet-client.crt \
--kubelet-client-key=/opt/kubernetes/cert/k8s/kube-apiserver-kubelet-client.key \
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction,AlwaysPullImages \
--service-node-port-range=20000-50000
Restart=on-failure
[Install]
WantedBy=multi-user.target