推荐阅读
Helm3(K8S 资源对象管理工具)视频教程:https://edu.youkuaiyun.com/course/detail/32506
Helm3(K8S 资源对象管理工具)博客专栏:https://blog.youkuaiyun.com/xzk9381/category_10895812.html
本文原文链接:https://blog.youkuaiyun.com/xzk9381/article/details/116979754,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。
公司目前使用 sealos 搭建了三套 k8s 集群,为了方便管理,计划将三个集群的 kubeconfig 整合到一起,然后使用 kubectl 命令切换上下文来实现管理多个集群的目的。但是由于 sealos 搭建的集群中,kubeconfig 文件的上下文完全一样,所以需要自定义一个 kubeconfig 文件。
如果想要了解如何使用一个 kubeconfig 文件切换集群,可以参考我的另一篇文章:配置kubeconfig文件实现kubectl多集群切换
我首先说一下生成一个 kubeconfig 必要的步骤:
- 准备 CA 配置文件 ca-config.json。sealos 将 CA 的配置信息写到了代码中,所以我们需要自己再定义一个
- 准备 CA 证书文件和私钥,这个可以在 /etc/kubernetes/pki 目录下找到
- 准备用于给 kubectl 颁发证书的配置文件 admin-csr.json,这个也需要自行创建
- 使用 cfssl 工具根据 CA 配置文件、CA 证书文件和 admin-csr.json 文件生成 kubectl 证书文件 admin.pem 和 admin-key.pem
- kubectl 命令使用 kubeconfig 中的信息去连接 apiserver,所以首先需要使用 kubectl 命令将集群的信息(IP 地址和 CA 证书)写入到 kubeconfig 文件中
- 接下来需要使用 kubectl 写入客户端的证书信息和连接 apiserver 时所使用的用户名信息
- 最后设置用于区分每个集群的上下文信息,并且对每个集群都指定一个 cluster-name
接下来规划一下三个集群所需要使用到的信息(以下信息仅作示例,实际使用时按现场需求规划):
apiserver 地址 | 集群名称 | 上下文名称 | 用户名 |
---|---|---|---|
192.168.92.21 | k8s-cluster-a | k8s-cluster-a-context | k8s-cluster-a-admin |
192.168.92.22 | k8s-cluster-b | k8s-cluster-b-context | k8s-cluster-b-admin |
192.168.92.23 | k8s-cluster-c | k8s-cluster-c-context | k8s-cluster-c-admin |
一、生成 kubectl 使用的证书文件
我们使用 k8s-cluster-a 集群来进行示例,其他集群生成 kubeconfig 时只需要替换对应的值即可。
在 /opt 目录下创建一个 ssl 目录,在其中创建一个 CA 配置文件,名称为 ca-config.json,内容如下(注意,有效期指定 100 年):
{
"signing": {
"default": {
"expiry": "876000h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "876000h"
}
}
}
}
profiles 中指定一个 kubernetes 即可,也可换做其他名称。该名称在后面生成证书时使用。
再创建一个 admin-csr.json 文件,内容如下(CN 可修改为其他名称):
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:masters",
"OU": "ops"
}
]
}
使用 cfssl 工具生成用于给 kubectl 使用的证书和私钥:
cfssl gencert -ca=/etc/kubernetes/pki/ca.crt \
-ca-key=/etc/kubernetes/pki/ca.key \
-config=/opt/ssl/ca-config.json \
-profile=kubernetes admin-csr.json | cfssljson -bare admin
注意这里的 ca 证书和密钥,使用 sealos 已经生成的即可。profile 中指定的是配置文件中的 kubernetes。
执行改命令后会生成三个文件,admin.csr,admin.pem 和 admin-key.pem:
root@k8s-master:/opt/ssl# ll | grep admin
-rw-r--r-- 1 root root 1009 May 17 20:28 admin.csr
-rw-r--r-- 1 root root 228 May 17 20:03 admin-csr.json
-rw------- 1 root root 1675 May 17 20:28 admin-key.pem
-rw-r--r-- 1 root root 1249 May 17 20:28 admin.pem
二、生成 kubeconfig 文件
证书生成后,接下里就开始创建 kubeconfig 文件,首先使用 kubectl 配置 apiserver 的访问地址和认证信息:
kubectl config set-cluster k8s-cluster-a \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=https://192.168.92.21:6443 \
--kubeconfig=kubectl.kubeconfig
注意这里的
set-cluster k8s-cluster-a
,用于设置 kubeconfig 中的集群名称。每个集群都替换成已经规划好的名称即可。
然后设置客户端认证信息,包括客户端(也就是 kubectl)使用的证书和用户名:
kubectl config set-credentials k8s-cluster-a-admin \
--client-certificate=/opt/ssl/admin.pem \
--client-key=/opt/ssl/admin-key.pem \
--embed-certs=true \
--kubeconfig=kubectl.kubeconfig
注意这里的
set-credentials k8s-cluster-a-admin
,用于设置 kubeconfig 中访问集群的用户名称。每个集群都替换成已经规划好的名称即可。
最后是设置集群的上下文参数:
kubectl config set-context k8s-cluster-a-context \
--cluster=k8s-cluster-a \
--user=k8s-cluster-a-admin \
--kubeconfig=kubectl.kubeconfig
注意这里是生成一个上下文名称,然后将上下文与集群名称和用户名进行关联。
这样就会在当前目录下生成一个正确的 kubeconfig 文件,文件名称是 kubectl.kubeconfig。我们看一下内容(省略了部分证书和密钥数据信息):
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5akNDQWJLZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201b
......
......
NSS2gwcVpibmNyRWVudTZadWI0RUgrc2dsUUtTemljZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
server: https://192.168.92.21:6443
name: k8s-cluster-a
contexts:
- context:
cluster: k8s-cluster-a
user: k8s-cluster-a-admin
name: k8s-cluster-a-context
current-context: ""
kind: Config
preferences: {}
users:
- name: k8s-cluster-a-admin
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURiVENDQWxXZ0F3SUJBZ0lVRVRIT3JrWWw1TGhyWVgxYTE0TTF3Vm5jMjl3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd
......
......
Y3JmcGNWaHhWdThhdTl6VU0wN08wS1RXTWJUUjRtMmVGeTRECkdYdUlOdysvSDRPNGpyTTE1b01ET0pFPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBd25mWjc4c2xYbU9FRGFVL0xIRDYzU0c0cnNTelJMMHZ3OHZ2U2lhNWE2dDgwOXlLC
......
......
i0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
通过上面的内容可以看到包含了集群的证书、访问地址信息。在上下文参数中,包含了上下文名称和与其绑定的集群名称和用户名。
大家可以注意到,在 current-context: ""
中的内容为空,这里主要是用于多个 kubeconfig 文件整合到一起后,通过修改这个配置项来访问不同的 k8s 集群。我们可以先将这个配置项设置为当前的上下文内容:
kubectl config use-context k8s-cluster-a-context --kubeconfig=kubectl.kubeconfig
将这个文件拷贝到当前用户家目录下的 .kube
目录内,并重命名为 config,然后使用 kubectl 命令测试是否能连接 apiserver 即可。其他集群的 kubeconfig 文件也参照前面的步骤。
三、如何在 kubeconfig 跳过认证
在 sealos 搭建的集群中使用 kubeconfig 访问 apiserver 还有一个问题,sealos 初始化 apiserver 证书时,证书中允许的 hosts 只有如下几个:
localhost
kubernetes
kubernetes.default
kubernetes.default.svc
apiserver.cluster.local
kubernetes.default.svc.cluster.local
Master 主机名称
所以如果将 Master 的 IP 地址配置成其他的域名,然后将域名写到 kubeconfig 文件中时,执行 kubectl 命令就会报错。例如我们配置了一个域名 k8sdev.test.com ,域名解析到 Master 主机上。并且将 kubeconfig 文件中的 server 字段修改为域名地址。那么执行 kubectl 命令时会报如下错误:
Unable to connect to the server: x509: certificate is valid for localhost, kubernetes, kubernetes.default,
kubernetes.default.svc, apiserver.cluster.local, kubernetes.default.svc.cluster.local, k8s-master1-online-yz,
not k8sdev.test.com
解决这个问题的办法有两种,一个是重新申请证书,还有一个就是跳过认证。
重新申请证书过于麻烦,所以我们选择跳过认证。将 kubeconfig 中 cluster
对应的 certificate-authority-data
这一行内容删除,然后添加一行:insecure-skip-tls-verify: true
即可忽略认证:
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: https://k8sdev.test.com:6443
name: k8s-dev
......
......
但是忽略认证也会带来安全隐患,所以线上环境慎用,或者严格控制文件权限
本文原文链接:https://blog.youkuaiyun.com/xzk9381/article/details/116979754,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。