目录
kube-apiserver
kube-apiserver既然为kubernetes中master的核心组件,并且是cluster中所有请求的终点,那么kubernetes是如何接收请求,又是如何将结果返回至客户端?
部署策略:
- 3个节点高可用, 使用负载均衡或者haproxy/nginx 等4层透明代理实现高可用;
- 关闭非安全端口 8080 和匿名访问;
- 在安全端口 6443 接收 https 请求;
- 严格的认证和授权策略 (x509、token、RBAC);
- 开启 bootstrap token 认证,支持 kubelet TLS bootstrapping;
- 使用 https 访问 kubelet、etcd,加密通信;
部署软件规划
IP | 部署软件包 |
---|---|
10.40.61.116 | kube-apiserver |
10.40.58.153 | kube-apiserver |
10.40.58.154 | kube-apiserver |
01.创建 kubernetes-master 证书和私钥
API Server证书主要用于客户端程序连接apiserver时进行加密和验证。Kubernetes API Server 凭证中必需包含 master 的静态 IP 地址。
创建 Kubernetes API Server 凭证签发请求文件:
cat > kube-apiserver-csr.json <<EOF
{
"CN": "kubernetes",
"hosts": [
"10.40.61.116",
"10.40.58.153",
"10.40.58.154",
"127.0.0.1",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local",
"apiserver-p001.svc.gxd88.cn"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "China",
"L": "Beijing",
"O": "Kubernetes",
"OU": "Kubernetes",
"ST": "Beijing"
}
]
}
EOF
hosts 字段指定授权使用该证书的 IP 和域名列表,这里列出了 master 节点 IP、kubernetes 服务的 IP 和域名;
kubernetes 服务 IP 是 apiserver 自动创建的,一般是 --service-cluster-ip-range 参数指定的网段的第一个IP
创建 Kubernetes API Server 凭证与私钥:
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
kube-apiserver-csr.json | cfssljson -bare kube-apiserver
结果产生以下两个文件:
kube-apiserver-key.pem
kube-apiserver.pem
02.Service Account 证书
Service Account证书用于生成各个Namespace默认的token,以及进行token验证。在集群内部服务访问API Server时会使用这个token进行身份认证,
其中kube-apiserver使用公钥, kube-controller-manager使用私钥
cat > service-account-csr.json <<EOF
{
"CN": "service-accounts",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "China",
"L": "Beijing",
"O": "Kubernetes",
"OU": "Kubernetes",
"ST": "Beijing"
}
]
}
EOF
创建 Kubernetes service-account 凭证与私钥:
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
service-account-csr.json | cfssljson -bare service-account
结果将生成以下两个文件
service-account-key.pem
service-account.pem
03.使用systemd管理kube-apiserver
tee > /etc/systemd/system/kube-apiserver.service <<EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
ExecStart=/srv/kubernetes/bin/kube-apiserver \\
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota,NodeRestriction \\
--bind-address=0.0.0.0 \\
--authorization-mode=Node,RBAC \\
--enable-bootstrap-token-auth \\
--token-auth-file=/srv/kubernetes/pki/bootstrap-token.csv \\
--runtime-config=rbac.authorization.k8s.io/v1 \\
--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname \\
--kubelet-https=true \\
--kubelet-client-certificate=/srv/kubernetes/pki/kube-apiserver.pem \\
--kubelet-client-key=/srv/kubernetes/pki/kube-apiserver-key.pem \\
--anonymous-auth=false \\
--requestheader-client-ca-file=/srv/kubernetes/pki/ca.pem \\
--requestheader-allowed-names= \\
--requestheader-extra-headers-prefix=X-Remote-Extra- \\
--requestheader-group-headers=X-Remote-Group \\
--requestheader-username-headers=X-Remote-User \\
--proxy-client-cert-file=/srv/kubernetes/pki/admin.pem \\
--proxy-client-key-file=/srv/kubernetes/pki/admin-key.pem \\
--service-cluster-ip-range=10.244.0.0/16 \\
--service-node-port-range=20000-45000 \\
--tls-cert-file=/srv/kubernetes/pki/kube-apiserver.pem \\
--tls-private-key-file=/srv/kubernetes/pki/kube-apiserver-key.pem \\
--client-ca-file=/srv/kubernetes/pki/ca.pem \\
--enable-aggregator-routing=true \\
--service-account-key-file=/srv/kubernetes/pki/service-account.pem \\
--etcd-cafile=/srv/kubernetes/pki/ca.pem \\
--etcd-certfile=/srv/kubernetes/pki/etcd.pem \\
--etcd-keyfile=/srv/kubernetes/pki/etcd-key.pem \\
--etcd-servers=https://10.40.61.116:2379,https://10.40.58.153:2379,https://10.40.58.154:2379 \\
--allow-privileged=true \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/srv/kubernetes/log/api-audit.log \\
--event-ttl=1h \\
--v=2 \\
--logtostderr=false \\
--log-dir=/srv/kubernetes/log
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
04.启动/停止 kube-apiserver
To configure kube-apiserver to start automatically when the system boots up, run the following commands:
sudo /bin/systemctl daemon-reload
sudo /bin/systemctl enable kube-apiserver.service
kube-apiserver can be started and stopped as follows:
sudo systemctl start kube-apiserver.service
sudo systemctl stop kube-apiserver.service
05.验证
检查kube-apiserver服务:
$ systemctl status kube-apiserver |grep Active
Active: active (running) since 四 2020-04-16 13:44:33 CST; 2 days ago
查看kube-apiserver写入etcd的数据:
/srv/kubernetes/bin/etcdctl \
--endpoints=https://10.40.58.153:2379,https://10.40.58.154:2379,https://10.40.61.116:2379 \
--cacert=/srv/kubernetes/pki/ca.pem \
--cert=/srv/kubernetes/pki/etcd.pem \
--key=/srv/kubernetes/pki/etcd-key.pem get / --prefix --keys-only
检查集群信息
$ kubectl cluster-info
$ kubectl get all --all-namespaces
$ kubectl get componentstatuses
06.参数详解
kube-apiserver的参数,主要包括:
- 准入插件
- 扩展apiserver
- 认证方式
- 审计
- 日志
- etcd配置
- 各种证书
- 外部认证
- ......
必须参数
/srv/kubernetes/bin/kube-apiserver \
--service-cluster-ip-range=10.223.0.0/16 \
--etcd-servers=https://etcd-1:2379,https://etcd-2:2379,https://etcd-3:2379
--service-cluster-ip-range
: CIDR 表示的 IP 范围,服务的 cluster ip
将从中分配。 一定不要和分配给 nodes 和 pods 的 IP 范围产生重叠。
--etcd-servers
: 连接的 etcd
服务器列表 , 形式为(scheme://ip:port),使用逗号分隔。
准入插件
比如开启PodPreset
/srv/kubernetes/bin/kube-apiserver \
--enable-admission-plugins
apiserver租约
apiserver使用租约上网方式进行注册,能够感知上下线
/srv/kubernetes/bin/kube-apiserver \
--endpoint-reconciler-type=lease
认证方式
节点使用Node,其他使用RBAC,某些组件可能会用到Webhook
/srv/kubernetes/bin/kube-apiserver \
--authorization-mode=Node,RBAC
证书相关
/srv/kubernetes/bin/kube-apiserver \
--tls-cert-file=/srv/kubernetes/pki/apiserver.pem \
--tls-private-key-file=/srv/kubernetes/pki/apiserver-key.pem \
--client-ca-file=/srv/kubernetes/pki/ca.pem \
--service-account-key-file=/srv/kubernetes/pki/service-account.pem
--tls-cert-file
: 包含用于 HTTPS 的默认 x509 证书的文件。(如果有 CA 证书,则附加于 server 证书之后)。如果启用了 HTTPS 服务,并且没有提供 --tls-cert-file 和 --tls-private-key-file,则将为公共地址生成一个自签名的证书和密钥并保存于 /var/run/kubernetes 目录。
--tls-private-key-file
: 包含匹配 --tls-cert-file 的 x509 证书私钥的文件。
--client-ca-file
: 如果设置此标志,对于任何请求,如果存包含 client-ca-file 中的 authorities 签名的客户端证书,将会使用客户端证书中的 CommonName 对应的身份进行认证。 所有的客户端证书由该CA进行签发
--service-account-key-file
: 包含 PEM 加密的 x509 RSA 或 ECDSA 私钥或公钥的文件,用于验证 ServiceAccount 令牌。如果设置该值,--tls-private-key-file 将会被使用。指定的文件可以包含多个密钥,并且这个标志可以和不同的文件一起多次使用。
kubelet 接入配置
/srv/kubernetes/bin/kube-apiserver \
--kubelet-https=true \
--kubelet-client-certificate=/srv/kubernetes/pki/apiserver.pem \
--kubelet-client-key=/srv/kubernetes/pki/apiserver-key.pem
--kubelet-client-certificate
: 用于 TLS 的客户端证书文件路径。
--kubelet-client-key
: 用于 TLS 的客户端证书密钥文件路径 .
--kubelet-https
:为 kubelet 启用 https。 (默认值 true)
这个里面配置的证书是kube-apiserver访问kubelet时使用
设置API访问审计日志
开启k8s的审计功能,必须配置--audit-policy-file
才会生效。
/srv/kubernetes/bin/kube-apiserver \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/srv/kubernetes/log/api-audit.log \
--audit-policy-file=/srv/kubernetes/conf/audit-policy-minimal.yml
--audit-log-path
: 如果设置该值,所有到apiserver
的请求都将会被记录到这个文件。'-' 表示记录到标准输出。
--audit-log-maxage
: 基于文件名中的时间戳,旧审计日志文件的最长保留天数
--audit-log-maxbackup
: 旧审计日志文件的最大保留个数
--audit-log-maxsize
: 审计日志被轮转前的最大兆字节数。
--audit-policy-file
: 定义审计策略配置的文件的路径。需要打开 AdvancedAuditing'
特性开关。AdvancedAuditing
需要一个配置来启用审计功能。
程序运行日志
/srv/kubernetes/bin/kube-apiserver \
--v=2 \
--logtostderr=false \
--log-dir=/srv/kubernetes/log
设置ETCD证书信息
/srv/kubernetes/bin/kube-apiserver \
--etcd-cafile=/srv/kubernetes/pki/ca.pem \
--etcd-certfile=/srv/kubernetes/pki/apiserver.pem \
--etcd-keyfile=/srv/kubernetes/pki/apiserver-key.pem \
--etcd-servers=https://etcd-1:2379,https://etcd-2:2379,https://etcd-3:2379
--etcd-cafile
: 用于保护 etcd 通信的 SSL CA 文件。
--etcd-certfile
: 用于保护 etcd 通信的的 SSL 证书文件。
--etcd-keyfile
: 用于保护 etcd 通信的 SSL 密钥文件。
--etcd-servers
: 连接的 etcd 服务器列表 , 形式为(scheme://ip:port),使用逗号分隔。
开启扩展apiserver
开启扩展apiserver,比如metrics-server,再比如prometheus-adapter
/srv/kubernetes/bin/kube-apiserver \
--requestheader-client-ca-file=/srv/kubernetes/pki/ca.pem
--requestheader-allowed-names=
--requestheader-extra-headers-prefix=X-Remote-Extra-
--requestheader-group-headers=X-Remote-Group
--requestheader-username-headers=X-Remote-User
--proxy-client-cert-file=/srv/kubernetes/pki/admin.pem
--proxy-client-key-file=/srv/kubernetes/pki/admin-key.pem
--requestheader-allowed-names
: 使用 --requestheader-username-headers 指定的,允许在头部提供用户名的客户端证书通用名称列表。如果为空,任何通过 --requestheader-client-ca-file 中 authorities 验证的客户端证书都是被允许的。
--requestheader-client-ca-file
: 在信任请求头中以 --requestheader-username-headers 指示的用户名之前,用于验证接入请求中客户端证书的根证书捆绑。
--requestheader-extra-headers-prefix
: 用于检查的请求头的前缀列表。建议使用 X-Remote-Extra-。
--requestheader-group-headers
: 用于检查群组的请求头列表。建议使用 X-Remote-Group.
--requestheader-username-headers
: 用于检查用户名的请求头列表。建议使用 X-Remote-User。
--proxy-client-cert-file
: 当必须调用外部程序时,用于证明 aggregator 或者 kube-apiserver 的身份的客户端证书。包括代理到用户 api-server 的请求和调用 webhook 准入控制插件的请求。它期望这个证书包含一个来自于 CA 中的 --requestheader-client-ca-file 标记的签名。该 CA 在 kube-system 命名空间的 'extension-apiserver-authentication' configmap 中发布。从 Kube-aggregator 收到调用的组件应该使用该 CA 进行他们部分的双向 TLS 验证。
--proxy-client-key-file
: 当必须调用外部程序时,用于证明 aggregator 或者 kube-apiserver 的身份的客户端证书密钥。包括代理到用户 api-server 的请求和调用 webhook 准入控制插件的请求。
支持节点以bootstrap-token加入集群
/srv/kubernetes/bin/kube-apiserver \
--enable-bootstrap-token-auth
--token-auth-file=/srv/kubernetes/pki/bootstrap-token.csv
--enable-bootstrap-token-auth
: 启用此选项以允许 kube-system
命名空间中的bootstrap.kubernetes.io/token'
类型密钥可以被用于 TLS 的启动认证
--token-auth-file
: 如果设置该值,这个文件将被用于通过令牌认证来保护 API 服务的安全端口。
开放某些api组支持
/srv/kubernetes/bin/kube-apiserver \
--runtime-config=rbac.authorization.k8s.io/v1=true
--runtime-config=rbac.authorization.k8s.io/v1beta1=true
--runtime-config=settings.k8s.io/v1alpha1=true
比如podpreset需要--runtime-config=settings.k8s.io/v1alpha1=true
,再比如custom metrics需要--runtime-config=rbac.authorization.k8s.io/v1beta1=true
service的虚拟IP,也就是ClusterIP网段
/srv/kubernetes/bin/kube-apiserver \
--service-cluster-ip-range=10.223.0.0/16
NodePort的端口范围
/srv/kubernetes/bin/kube-apiserver \
--service-node-port-range=20000-45000
网友评论