由于 kubelet 和 kube-proxy 用到的 kubeconfig 配置文件需要借助 kubectl 来生成,所以需要先安装一下 kubectl
kubernetes相关的证书
kubernetes-servers证书
创建 kubernetes证书签名请求
cat > /usr/local/kubernetes/crts/kubernetes-csr.json << EOF
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"192.168.16.235",
"api.kubernetes.master",
"10.254.0.1",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "ShangHai",
"L": "ShangHai",
"O": "k8s",
"OU": "System"
}
]
}
EOF
- 如果
hosts
字段不为空则需要指定授权使用该证书的 IP 或域名列表,由于该证书后续被 etcd 集群和 kubernetes master 集群使用,所以上面分别指定了 etcd 集群、kubernetes master 集群的主机 IP; - 还需要添加kube-apiserver注册的名为 kubernetes 服务的 IP(一般是 kue-apiserver 指定的 service-cluster-ip-range 网段的第一个IP,如 10.254.0.1)
生成 kubernetes 证书和私钥
cd /usr/local/kubernetes/crts/
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
-rw-------. 1 root root 1679 Jun 5 14:44 kubernetes-key.pem
-rw-r--r--. 1 root root 1602 Jun 5 14:44 kubernetes.pem
创建 Admin 证书
kubectl使用此证书,具有k8s集群内最高权限
创建 admin 证书签名请求
cat > /usr/local/kubernetes/crts/admin-csr.json << EOF
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "ShangHai",
"L": "ShangHai",
"O": "system:masters",
"OU": "System"
}
]
}
EOF
- 后续 kube-apiserver 使用 RBAC 对客户端(如 kubelet、kube-proxy、Pod)请求进行授权;
- kube-apiserver 预定义了一些 RBAC 使用的 RoleBindings,如 cluster-admin 将
Groupsystem:masters
与Role cluster-admin
绑定,该 Role 授予了调用kube-apiserver 的所有 API的权限; - OU 指定该证书的 Group 为
system:masters
,kubelet
使用该证书访问 kube-apiserver时 ,由于证书被 CA 签名,所以认证通过,同时由于证书用户组为经过预授权的system:masters
,所以被授予访问所有 API 的权限。
生成 admin 证书和私钥
cd /usr/local/kubernetes/crts/
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
-rw-------. 1 root root 1679 Jun 5 14:49 admin-key.pem
-rw-r--r--. 1 root root 1403 Jun 5 14:49 admin.pem
创建 Kube-Proxy 证书
创建 kube-proxy 证书签名请求
cat > /usr/local/kubernetes/crts/kube-proxy-csr.json << EOF
{
"CN": "system:kube-proxy",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "ShangHai",
"L": "ShangHai",
"O": "k8s",
"OU": "System"
}
]
}
EOF
- CN 指定该证书的 User 为
system:kube-proxy
; - kube-apiserver 预定义的
RoleBinding cluster-admin
将User system:kube-proxy
与Rolesystem:node-proxier
绑定,该 Role 授予了调用kube-apiserver Proxy
相关 API 的权限。
生成 kube-proxy 客户端证书和私钥
cd /usr/local/kubernetes/crts/
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
-rw-------. 1 root root 1675 Jun 5 14:51 kube-proxy-key.pem
-rw-r--r--. 1 root root 1407 Jun 5 14:51 kube-proxy.pem
校验证书
以校验kubernetes证书为例
使用openssl命令校验证书
openssl x509 -noout -text -in kubernetes.pem
- 确认
Issuer
字段的内容和ca-csr.json
一致; - 确认
Subject
字段的内容和kubernetes-csr.json
一致; - 确认
X509v3 Subject Alternative Name
字段的内容和kubernetes-csr.json
一致; - 确认
X509v3 Key Usage
、Extended Key Usage
字段的内容和ca-config.json
中kubernetes-profile
一致。
使用 Cfssl-Certinfo 命令校验
cfssl-certinfo -cert kubernetes.pem
分发证书
将生成的证书和秘钥文件(后缀名为.pem)拷贝到其他主机的 /etc/kubernetes/ssl 目录下备用
节点角色 | 证书密钥 |
master | ca,kubernetes |
node | ca,kube-proxy |
admin证书放在需要kubectl的节点上,如果node不使用kube-proxy则不需要kube-proxy证书
cp admin*.pem /etc/kubernetes/ssl/
cp kubernetes*.pem /etc/kubernetes/ssl/
ansible k8s-master -m copy -a 'src=/etc/kubernetes/ssl/ dest=/etc/kubernetes/ssl'
# kube-proxy证书
ansible k8s-node -m copy -a 'src=/etc/kubernetes/ssl/kube-proxy.pem dest=/etc/kubernetes/ssl/kube-proxy.pem'
ansible k8s-node -m copy -a 'src=/etc/kubernetes/ssl/kube-proxy-key.pem dest=/etc/kubernetes/ssl/kube-proxy-key.pem'
安装配置kubectl
获取软件包
wget https://dl.k8s.io/v1.10.3/kubernetes-server-linux-amd64.tar.gz # 包含了所有的binary程序
tar -xf kubernetes-server-linux-amd64.tar.gz -C /usr/local/src
cp /usr/local/src/kubernetes/server/bin/kubectl /usr/local/kubernetes/bin/
chmod +x /usr/local/kubernetes/bin/kubectl
echo 'export PATH=$PATH:/usr/local/kubernetes/bin' >> /etc/profile.d/kubernetes.sh # 分发到其他节点
source /etc/profile.d/kubernetes.sh
ansible k8s -m copy -a "src=/etc/profile.d/kubernetes.sh dest=/etc/profile.d/kubernetes.sh"
创建 kubectl kubeconfig 文件
- 由于kubectl直接使用kubeconfig格式的配置文件,不支持手动指定证书,需要将证书内容注入kubeconfig文件供kubectl使用
- 后续kube-controller-manager和kube-scheduler也使用该文件,此做法不符合权限最小化原则,但默认提供的controller-manager和scheduler角色绑定权限不足,无法直接使用,等待官方继续完善。
cd /etc/kubernetes/
# 设置集群参数
export KUBE_APISERVER="https://api.kubernetes.master" # 设置为master-api的域名,暂时可以将这个域名先绑定hosts解析 192.168.16.235 api.kubernetes.master
# 设置客户端认证参数
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER}
# 设置上下文参数
kubectl config set-credentials admin \
--client-certificate=/etc/kubernetes/ssl/admin.pem \
--embed-certs=true \
--client-key=/etc/kubernetes/ssl/admin-key.pem
# 设置默认上下文
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=admin
kubectl config use-context kubernetes
cat ~/.kube/config
# 将config文件复制供其他组件使用
cp ~/.kube/config /etc/kubernetes/ssl/admin.kubeconfig
创建 kubeconfig 文件
kubelet、kube-proxy 等 Node 机器上的进程与 Master 机器的 kube-apiserver 进程通信时需要认证和授权.
kubernetes 1.4 开始支持由 kube-apiserver 为客户端生成 TLS 证书的 TLS Bootstrapping 功能,这样就不需要为每个客户端生成证书了;该功能当前仅支持为 kubelet 生成证书。
创建 TLS Bootstrapping Token
Token auth file
Token可以是任意的包涵128 bit的字符串,可以使用安全的随机数发生器生成。
export BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ')
cat > /etc/kubernetes/token.csv <<EOF
${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
将token.csv发到所有机器(Master 和 Node)的 /etc/kubernetes/ 目录
ansible k8s -m copy -a 'src=/etc/kubernetes/token.csv dest=/etc/kubernetes/token.csv'
创建 kubelet bootstrapping kubeconfig 文件
cd /etc/kubernetes
# 设置集群参数
export KUBE_APISERVER="https://api.kubernetes.master"
# 设置客户端认证参数
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=bootstrap.kubeconfig
# 设置上下文参数
kubectl config set-credentials kubelet-bootstrap \
--token=${BOOTSTRAP_TOKEN} \
--kubeconfig=bootstrap.kubeconfig
# 设置默认上下文
kubectl config set-context default \
--cluster=kubernetes \
--user=kubelet-bootstrap \
--kubeconfig=bootstrap.kubeconfig
kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
- –embed-certs 为 true 时表示将 certificate-authority 证书写入到生成的 bootstrap.kubeconfig 文件中;
- 设置客户端认证参数时没有指定秘钥和证书,后续由 kube-apiserver 自动生成。
创建 kube-proxy kubeconfig 文件
# 设置集群参数
export KUBE_APISERVER="https://api.kubernetes.master"
# 设置客户端认证参数
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kube-proxy.kubeconfig
# 设置上下文参数
kubectl config set-credentials kube-proxy \
--client-certificate=/etc/kubernetes/ssl/kube-proxy.pem \
--client-key=/etc/kubernetes/ssl/kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=kube-proxy.kubeconfig
# 设置默认上下文
kubectl config set-context default \
--cluster=kubernetes \
--user=kube-proxy \
--kubeconfig=kube-proxy.kubeconfig
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
- 设置集群参数和客户端认证参数时 –embed-certs 都为 true,这会将 certificate-authority、client-certificate 和client-key 指向的证书文件内容写入到生成的 kube-proxy.kubeconfig 文件中;
- kube-proxy.pem 证书中 CN 为 system:kube-proxy,kube-apiserver 预定义的 RoleBinding cluster-admin 将Usersystem:kube-proxy 与 Role system:node-proxier 绑定,该 Role 授予了调用 kube-apiserver proxy 相关 API 的权限
分发 kubeconfig 文件
将两个 kubeconfig 文件分发到所有 Node 机器的 /etc/kubernetes/
目录
ansible k8s-node -m copy -a 'src=/etc/kubernetes/bootstrap.kubeconfig dest=/etc/kubernetes/bootstrap.kubeconfig'
ansible k8s-node -m copy -a 'src=/etc/kubernetes/kube-proxy.kubeconfig dest=/etc/kubernetes/kube-proxy.kubeconfig'