Kubernetes 权威指南第二章校对(3)
春节宅在家伺候小祖宗,可惜老外们不休息,新东西一坨接着一坨,安装部分又超级没有技术含量,因此疯狂拖延。今天终于把二进制安装过程的 API Server 部分弄好。 这部分还只有一个 API Server,后续内容的推进过程中,还有很大的可能发生变化。 太讨厌了——第二章可能是个修身养性的章节。
首先是觉得在 service 里面引用环境变量的方式似乎没有什么特别的好处。因此丢弃了环境变量文件,直接把参数写入了 Service 文件。
其次,匿名访问、http 访问都是严重不建议的方式,现稿虽然后面加入了证书相关内容,难免造成误导,这里直接把证书内容加入到每个组件的安装过程之中,让读者在跳着读时候,也能够收到一个相对完整的效果。
更新后的 kube-apiserver.service
:
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=etcd.service
Wants=etcd.service
[Service]
ExecStart=/usr/bin/kube-apiserver \
--allow-privileged=true \
--authorization-mode=Node,RBAC \
--client-ca-file=/etc/kubernetes/pki/ca.crt \
--enable-admission-plugins=NodeRestriction \
--enable-bootstrap-token-auth=true \
--etcd-cafile=/etc/kubernetes/pki/ca.crt \
--etcd-certfile=/etc/kubernetes/pki/etcd-client.crt \
--etcd-keyfile=/etc/kubernetes/pki/etcd-client.key \
--etcd-servers=https://127.0.0.1:2379 \
--insecure-port=0 \
--kubelet-client-certificate=/etc/kubernetes/pki/kubelet-client.crt \
--kubelet-client-key=/etc/kubernetes/pki/kubelet-client.key \
--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname \
--secure-port=6443 \
--service-cluster-ip-range=10.96.0.0/12 \
--tls-cert-file=/etc/kubernetes/pki/apiserver.crt \
--tls-private-key-file=/etc/kubernetes/pki/apiserver.key
Restart=on-failure
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
kube-apiserver 需要一系列的数字证书才能启动。必要的证书参数包括:
--client-ca-file
:客户端(例如 kubectl)使用客户端证书作为凭据访问 apiserver 时,用于签发客户端证书的 ca 证书文件。--etcd-cafile
、--etcd-certfile
、--etcd-keyfile
:apiserver 作为客户端,使用 https 协议访问 etcd 时,所信任的 ca 证书文件,以及客户端证书文件和密钥。--kubelet-client-certificate
、--kubelet-client-key
:apiserver 访问 kubelet 时所使用的证书文件和密钥。--tls-cert-file
、--tls-private-key-file
:apiserver 提供 https 服务时所使用的证书文件和密钥。
etcd 一节中,我们已经了解了服务器证书的生成方法,这里为了简单起见,把所有用于签发证书的 ca 证书统一为前面生成过的 /etc/kubernetes/pki/ca.crt
。几个证书参数中,只有 --tls-cert-file
是和前面的 etcd-server.crt
一样的https 服务端证书,生成方法是一样的,差别在于 [alt_names]
字段,其中除了包括服务器的 IP 之外,还包含了几个 DNS 名称,代表的是缺省的 Kubernetes 服务,摘录如下:
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster.local
IP.1 = 10.211.55.33
IP.2 = 127.0.0.1
使用这个cnf文件生成apiserver的服务端密钥和证书文件:
# openssl genrsa -out apiserver.key 2048
# openssl req -new -key apiserver.key -subj "/CN=kubernetes" -config apiserver.cnf -out apiserver.csr
# openssl x509 -req -in apiserver.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out apiserver.crt -days 365 -extensions v3_req -extfile apiserver.cnf
这些命令执行成功后,生成 apiserver.key
和 apiserver.crt
两个文件,这两个证书将用于 apiserver 的--tls-private-key-file
、--tls-cert-file
两个参数。
生成 apiserver 的服务端证书后,还需要为 etcd 和 kubelet 生成客户端证书。客户端证书相对简单,主要关注的是 -subj
参数。
首先是 etcd 的客户端证书,设置 CN=apiserver,OU=kubernetes
:
# openssl genrsa -out etcd-client.key 2048
# openssl req -new -out etcd-client.csr -key etcd-client.key -subj "/CN=apiserver/OU=kubernetes"
# openssl x509 -req -in etcd-client.csr -out etcd-client.crt -signkey etcd-client.key -CA ca.crt -CAkey ca.key -CAcreateserial -days 365
类似地,生成 kubelet 客户端证书,和 etcd 客户端类似,不同是的 -subj
参数,命令如下:
# openssl genrsa -out kubelet-client.key 2048
# openssl req -new -out kubelet-client.csr -key kubelet-client.key -subj "/CN= kube-apiserver-kubelet-client /OU= system:masters"
# openssl x509 -req -in kubelet-client.csr -out kubelet-client.crt -signkey kubelet-client.key -CA ca.crt -CAkey ca.key -CAcreateserial -days 365
service文件和一系列的证书都生成完毕之后,用如下命令启动kube-apiserver服务:
# systemctl daemon-reload
# systemctl start kube-apiserver
服务启动之后,可以使用 curl 尝试访问 apiserver 的端口:
# curl https://127.0.0.1:6443
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",
"reason": "Forbidden",
"details": {
},
"code": 403
}
返回了鉴权失败的信息,证明 apiserver 在正常运行了。