Jenkins集成K8S防踩坑(部分内容摘自GPT)
在连接k8s时,需要一个k8s service account(即sa),同时需要该服务账号具有cluster-admin权限,对该sa获取token加入Jenkins凭证,配合k8s服务证书,即可完成Jenkins集成k8s。
一、操作流程
在连接k8s时,需要一个k8s service account(即sa),同时需要该服务账号具有cluster-admin权限,对该sa获取token加入Jenkins凭证,配合k8s服务证书,即可完成Jenkins集成k8s。
1. 创建sa账户并授予权限
kubectl create sa jenkins
2. 为其分配cluster-admin权限
kubectl create clusterrolebinding jenkins --clusterrole cluster-admin --serviceaccount=default:jenkins
3. 查看该账号的详细信息
kubectl describe sa jenkins
输出信息中包含与该账户关联的secrets,其中包含用于身份验证的令牌,例如jenkins-token-9ztfs
4. 获取令牌
kubectl describe secrets jenkins-token-9ztfs
将输出的token添加入Jenkins,类别为Secret text。
5. 获取k8s服务证书
- 首先查看apiserver的地址
kubectl cluster-info
- 使用
find -type d -name ".kube"
查找.kube的路径,并在.kube文件夹下的config文件中查看集群的连接信息,存放在clusters
字段下的certificate-authority-data
中 - 将该内容下的证书经过base64加密
echo "<context>" | base64 -d
添加入jenkins的云配置中,注意需要提前下载kubernetes插件。
6. 测试是否连接成功
二、可能遇到的问题
1. 需要打通的端口?
-
连接外部的Jenkins服务器到Kubernetes集群时,需要打通以下端口:
-
Kubernetes API服务器端口:Jenkins服务器需要与Kubernetes集群的API服务器通信。Kubernetes API服务器的默认端口是 6443。确保Jenkins服务器可以访问集群中的API服务器的这个端口。
-
节点SSH端口(可选):如果您的Jenkins服务器需要通过SSH连接到Kubernetes节点以执行某些任务,那么您需要打通节点的SSH端口。SSH默认端口是 22。这通常是可选的,取决于您的工作负载和部署需求。
-
Kubelet端口:Kubelet是运行在Kubernetes节点上的组件,它负责与控制平面通信,用于管理Pod的生命周期。Kubelet的默认端口是 10250。如果您需要Jenkins服务器通过Kubelet执行一些操作,需要确保Jenkins服务器可以访问Kubelet的这个端口。
-
Kube-proxy端口(可选):Kube-proxy是Kubernetes网络代理,负责处理集群内的网络流量。它通常使用一组端口来处理服务负载均衡和代理流量。这些端口是动态分配的,通常位于范围 30000-32767。如果您使用Kube-proxy来代理服务的流量,需要确保Jenkins服务器可以与这些端口通信。
请注意,确保网络规则和防火墙策略允许Jenkins服务器与Kubernetes集群上的这些端口通信,以便正常执行CI/CD任务。确保考虑到安全性和网络设置来配置这些连接。
2. 能否ping通集群的master节点决定了外部服务器能否连接到集群吗?
-
外部的 Jenkins 服务器连接到 Kubernetes 集群不一定需要能够 ping 通 Kubernetes 的 master 节点。Ping 是一种用于测试主机之间是否能够通信的网络工具,但它不一定代表能够建立有效的 HTTP 或 HTTPS 连接到 Kubernetes 的 API 服务器。
-
对于连接到 Kubernetes 集群的 Jenkins 服务器,最重要的是确保以下条件满足:
-
网络可达性: Jenkins 服务器必须能够在网络层上与 Kubernetes 集群的 API 服务器通信。这通常涉及到确保网络路由和防火墙规则允许从 Jenkins 服务器到 API 服务器的请求流量。这不仅包括 ping,还包括 HTTP 或 HTTPS 请求。
-
Kubernetes 配置: 在 Jenkins 服务器上,需要正确配置 Kubernetes 客户端,通常使用 kubeconfig 文件或相关配置来指定集群、用户和上下文。这些配置信息将 Jenkins 服务器连接到 Kubernetes 集群。
-
Kubernetes API 服务器配置: Kubernetes API 服务器需要正确配置以接受来自 Jenkins 服务器的请求。这通常涉及到配置 API 服务器的 TLS 证书、认证和授权方式。
-
RBAC 权限: Jenkins 服务器需要具有足够的权限来执行所需的操作。这涉及到在 Kubernetes 中设置适当的 RBAC 角色和角色绑定。
-
Ping 是一种用于测试网络可达性的工具,但它不涉及 TLS 握手或身份验证等方面,而这些在与 Kubernetes 集群的 API 服务器进行通信时更为关键。因此,如果 Jenkins 服务器无法 ping 通 Kubernetes 的 master 节点,但上述条件都得到满足,仍然可以建立有效的连接。
确保网络配置和 Kubernetes 配置正确,并根据需要进行适当的调试和故障排除,以确保 Jenkins 服务器能够与 Kubernetes 集群正常通信。
3. 如何判断apiserver是否可达?
-
要判断 Kubernetes 集群外的 API 服务器是否可达,您可以使用一些命令行工具或脚本来进行测试。以下是一个示例使用
curl
命令的方法,您可以使用它来检查 API 服务器是否可达:curl --insecure --head --max-time 5 https://your-api-server-url
在这个命令中,您需要替换
your-api-server-url
为实际的 API 服务器地址。这个命令执行以下操作:-
--insecure
:忽略 TLS 证书验证,这在测试集群外的 API 服务器时通常是必需的,因为通常情况下 TLS 证书是自签名的或由内部颁发机构签发的。 -
--head
:发送 HTTP HEAD 请求,这只会检查 API 服务器是否响应,但不会下载页面内容。 -
--max-time 5
:设置最大超时时间为 5 秒。如果在 5 秒内无法建立连接,将返回失败。
-
-
如果 API 服务器可达,您将看到一个类似以下的响应头:
HTTP/1.1 200 OK Date: ... ...
如果 API 服务器不可达,您可能会收到连接超时或拒绝连接的错误消息。
请注意,上述示例中的 curl
命令假设您的 API 服务器是通过 HTTPS 访问的,并且使用了自签名证书或无效证书。如果您的 API 服务器配置了其他类型的证书验证,您可能需要根据需要调整 curl
命令。
此外,您可以使用其他命令行工具,例如 wget
或 nc
(netcat),来执行类似的测试。测试 API 服务器可达性是故障排除和监控集群的一部分,可以帮助您在出现问题时快速发现问题。
4. Failure executing: GET at: http://47.93.21.10:6443/api/v1/namespaces/jenkins/pods. Message: Bad Request.
“Bad Request” 错误通常表示发出的HTTP请求存在问题,可能是由于请求的格式或内容不正确而导致的。在您提供的错误消息中,您正在尝试使用HTTP GET 请求访问Kubernetes集群的API服务器,但遇到了"Bad Request"错误。
以下是一些可能导致"Bad Request"错误的常见原因和解决方法:
-
URL 错误: 确保您的请求URL(http://47.93.21.10:6443/api/v1/namespaces/jenkins/pods)是正确的,包括正确的端口号和路径。检查拼写错误和URL格式。
-
认证问题: 如果请求需要身份验证,确保您提供了有效的凭证(如令牌或证书)来进行身份验证。
-
API服务器问题: 检查Kubernetes API服务器是否正在运行,并且监听在指定的端口上(6443)。还要确保API服务器配置正确,没有不一致性或错误。
-
请求格式问题: 确保HTTP请求的格式正确,包括正确的HTTP方法(如GET)、请求标头和有效负载。
-
RBAC权限问题: 如果您正在使用Kubernetes的RBAC(基于角色的访问控制),请确保您的用户具有足够的权限来执行此请求。检查角色和角色绑定配置。
-
网络问题: 确保Jenkins服务器可以访问Kubernetes集群的API服务器。检查防火墙规则、网络策略和DNS设置,确保网络通信正常。
-
Kubernetes集群状态: 如果Kubernetes集群的状态异常,可能会导致"Bad Request"错误。确保集群运行正常。
检查上述问题可能会帮助您找到导致"Bad Request"错误的根本原因。如果问题仍然存在,请提供更多详细信息,以便我能够提供更精确的帮助。
5. Error testing connection 47.93.21.10:6443: io.fabric8.kubernetes.client.KubernetesClientException
“io.fabric8.kubernetes.client.KubernetesClientException” 错误通常是由 Kubernetes 客户端库遇到问题时引发的异常。在这种情况下,您在测试与 Kubernetes 集群的连接时遇到了异常。
以下是一些可能导致此异常的常见原因和解决方法:
-
连接问题: 这个异常可能是因为无法与 Kubernetes 集群建立连接而引发的。检查您的网络连接,确保能够访问指定的 Kubernetes API 服务器地址(在您的情况下是 47.93.21.10)和端口(在您的情况下是 6443)。确保网络畅通。
-
API 服务器问题: 如果 Kubernetes API 服务器出现故障或配置问题,也可能导致此异常。检查 API 服务器的状态,确保它正在运行,并且配置正确。
-
身份验证和授权问题: 如果测试连接需要身份验证,但提供的凭据无效或缺失必需的权限,那么这也可能引发异常。确保您的身份验证凭据有效,具有足够的权限来执行操作。
-
Kubernetes 客户端库问题: 您使用的 Kubernetes 客户端库可能不是最新版本,或者可能存在一些问题。尝试升级或修复库,以确保它与您的 Kubernetes 版本兼容。
-
Kubernetes 集群配置问题: 检查您的 Kubernetes 集群的配置文件(kubeconfig),以确保它包含正确的集群、用户和上下文配置。确保它位于正确的位置,并且权限正确。
-
Kubernetes RBAC 权限问题: 如果您正在使用 Kubernetes 的 RBAC,确保您的用户或服务帐户具有执行所需操作的权限。检查角色和角色绑定配置。
-
TLS 证书问题: 如果使用 TLS 进行连接,确保证书和密钥正确配置,并且证书是否由受信任的证书颁发机构签发。
-
日志和调试: 查看 Kubernetes 客户端库的日志,以获取有关问题的更多信息。调试信息可能有助于确定问题的根本原因。
您可以根据上述建议逐一检查和排除可能的问题,以确定引发异常的确切原因。如果问题仍然存在,提供更多详细信息和错误上下文可能有助于进一步诊断问题。
6. curl --insecure --head --max-time 5 https://47.93.21.10:6443 返回403 如何解决?
如果您在使用 curl 访问 Kubernetes API 服务器时收到 403 错误,即使使用了 --insecure 选项来忽略证书验证,那么问题可能是由于 API 服务器的访问控制策略导致的。以下是一些可能的解决方法:
-
检查 RBAC 权限:403 错误通常表示身份验证成功,但请求被服务器拒绝。检查与您使用的凭证(令牌、用户名/密码等)相关的 RBAC(基于角色的访问控制)配置。确保您的凭证被授权执行所需的操作。您可以检查角色、角色绑定和集群角色绑定来确定是否存在权限问题。
-
查看 API 服务器的日志:尝试查看 Kubernetes API 服务器的日志以获取更多详细信息。日志通常包含与请求拒绝相关的详细信息,例如哪个角色或资源受到了限制。您可以查看 API 服务器的日志文件以帮助确定问题的具体原因。
-
检查请求标头:确保您的请求标头包含正确的信息。特别是,确保 Authorization 标头包含有效的令牌或凭证。请检查标头是否正确,以确保它们与 Kubernetes API 服务器的预期标头匹配。
-
审查网络策略:检查是否存在 Kubernetes 网络策略,它可能会限制从集群外部到 API 服务器的访问。网络策略可以限制来自特定 IP 地址范围的访问,因此确保您的 IP 地址被允许。
-
证书问题:如果使用 HTTPS 访问 API 服务器,确保证书链完整并且证书是有效的。检查您使用的证书是否被信任。使用 --insecure 选项来禁用证书验证可能不是永久的解决方法,而是一个用于测试的工具。
-
尝试其他身份验证方式:如果您在使用令牌进行身份验证,尝试使用不同的令牌(如果有多个令牌可用)。或者尝试使用用户名/密码等其他身份验证方式来验证身份。
-
检查 IP 地址和端口:确保您的 curl 请求中的 IP 地址和端口号与实际的 Kubernetes API 服务器配置匹配。
如果上述方法无法解决问题,建议联系集群管理员或 Kubernetes 安全团队以获取进一步的支持和诊断。继续调查可能需要深入了解集群的特定配置和安全策略。
7. 如何查看apiserver的日志?
要查看 Kubernetes API 服务器的日志,通常需要访问主节点上的 Kubernetes API 服务器容器的日志。以下是一种方法,可以通过 kubectl
命令查看 API 服务器容器的日志:
-
首先,使用
kubectl
连接到您的 Kubernetes 集群。如果尚未配置kubectl
,您可以使用以下命令进行配置:kubectl config set-cluster my-cluster-name --server=https://your-api-server-url kubectl config set-credentials my-credentials --token=your-auth-token kubectl config set-context my-context --cluster=my-cluster-name --user=my-credentials kubectl config use-context my-context
在上述命令中,替换以下内容:
my-cluster-name
:集群名称。https://your-api-server-url
:您的 Kubernetes API 服务器的 URL。my-credentials
:凭证名称。your-auth-token
:用于身份验证的令牌。
-
一旦连接到集群,您可以使用以下命令查看 API 服务器容器的日志:
kubectl logs -n kube-system kube-apiserver-master -c kube-apiserver
在上述命令中,
-n kube-system
指定了要查看的命名空间(通常 API 服务器在 kube-system 命名空间中),kube-apiserver-master
是 API 服务器的 Pod 名称,kube-apiserver
是容器名称。请确保 Pod 名称和容器名称与您的集群配置匹配。 -
运行上述命令后,将会显示 API 服务器的日志内容。您可以查看日志以查找与 403 错误相关的详细信息,例如权限拒绝的原因、请求信息等。
请注意,上述命令是示例命令,实际的命名空间、Pod 名称和容器名称可能因集群配置而异。您需要根据您的集群配置来查找正确的命名空间和 Pod 名称。
如果您没有权限查看日志,可能需要联系集群管理员或具有足够权限的用户以获取日志访问权限。确保在查看日志时遵循集群的安全策略和最佳实践。
8. 400和403有什么区别?
HTTP 状态码中的 400 和 403 都表示客户端发出的请求遇到了问题,但它们有不同的含义和用途:
-
400 Bad Request (错误请求):
- 状态码 400 表示客户端发送的请求无效,服务器无法理解或处理请求。
- 这可能是由于请求中的语法错误、缺少必需的参数或请求无效而导致的。
- 400 错误通常表示请求的问题是客户端导致的,而不是服务器的问题。
- 例子:如果客户端发送一个无效的 JSON 请求体,服务器可能会返回 400 Bad Request。
-
403 Forbidden (禁止访问):
- 状态码 403 表示客户端的请求是有效的,但服务器拒绝执行该请求,因为客户端没有足够的权限来执行请求的操作。
- 这表示服务器已经理解了请求,但拒绝执行它,因为请求者的身份认证成功,但没有足够的权限来执行所需的操作。
- 403 错误通常用于访问控制和身份验证问题,表明客户端需要提供更高级别的授权或凭证才能执行请求。
- 例子:如果客户端尝试删除一个只允许管理员访问的资源,服务器可能会返回 403 Forbidden。
总的来说,400 表示请求无效,而 403 表示请求是有效的,但由于权限不足或其他访问控制问题而被服务器拒绝。根据这两个状态码,客户端可以更好地理解问题的性质,以采取适当的行动。
9. 如何查看apiserver响应外部请求的日志?
要查看 Kubernetes API Server(kube-apiserver)响应外部请求的日志,您通常需要访问运行 kube-apiserver 的主节点的日志文件。具体步骤如下:
-
SSH 登录到主节点:首先,您需要 SSH 登录到运行 kube-apiserver 的 Kubernetes 主节点。您需要具有足够的权限才能访问主节点的日志文件。
-
查找 kube-apiserver 日志文件:通常,kube-apiserver 的日志文件位于
/var/log
目录下。您可以使用以下命令查找 kube-apiserver 日志文件:sudo ls /var/log | grep kube-apiserver
这将列出 kube-apiserver 相关的日志文件,通常以
.log
扩展名结尾。 -
查看日志文件:一旦找到 kube-apiserver 的日志文件,您可以使用
cat
、less
或tail
等命令来查看日志内容。例如,要使用less
查看日志文件,可以运行:sudo less /var/log/kube-apiserver.log
使用箭头键和 Page Up/Page Down 键来浏览日志内容。
-
过滤日志:kube-apiserver 的日志通常包含大量信息,您可能希望根据需要使用
grep
命令来筛选特定的日志条目。例如,要查看来自特定 IP 地址的请求,您可以运行:sudo cat /var/log/kube-apiserver.log | grep "source IP"
或使用其他相关的关键词。
请注意,上述步骤中的命令需要在主节点上以管理员权限运行。确保您具有足够的权限以访问日志文件。此外,kube-apiserver 的日志可能包含敏感信息,因此在查看和共享日志时要格外小心。
在生产环境中,通常会使用专门的日志聚合工具(例如 Elasticsearch、Fluentd、Kibana 或 Loki)来集中存储和分析 kube-apiserver 的日志,以便更轻松地进行故障排除和监控。这些工具提供了更高级的日志分析和查询功能。
10. Error testing connection https://47.93.21.10:6443: java.io.IOException: Hostname 47.93.21.10 not verified:
certificate: sha256/hpSGlp/5fSOd3YM95C+RC4ZPVe5XCjvkEXzVHSSX51I=
DN: CN=kube-apiserver
subjectAltNames: [10.96.0.1, 172.19.191.192, aliyunk8s.com, k8smaster, kubernetes, kubernetes.default, kubernetes.default.svc, kubernetes.default.svc.cluster.local]
如何解释上述错误?
上述错误消息表明,在尝试连接到 HTTPS 主机 https://47.93.21.10:6443 时,出现了证书验证问题。证书验证失败的原因是主机名 (Hostname) “47.93.21.10” 未通过验证,这与证书中包含的主题备用名称 (Subject Alternative Names) 不匹配。该证书的主题备用名称列出了允许的有效主机名或 IP 地址,但主机名 “47.93.21.10” 并未包含在其中。
要解决这个问题,有几种方法可以考虑:
-
使用证书中的有效主题备用名称或主机名:首选方法是在客户端请求中使用与证书中的主题备用名称匹配的有效主机名或 IP 地址。如果您可以确保请求的主机名或 IP 地址在证书的主题备用名称列表中,那么您应该能够顺利连接。
-
更新证书:如果您有控制证书的能力,可以更新证书,将您计划使用的主机名或 IP 地址添加到证书的主题备用名称列表中。然后,将使用新证书重新配置服务器。
-
禁用主机名验证:不建议,但在某些情况下,您可以选择禁用主机名验证。这会使连接不再验证主机名,但会降低安全性,因为它将容许连接到不受信任或未知的主机。
具体的解决方法取决于您的使用情况和环境。最佳实践是确保您的证书与实际使用的主机名或 IP 地址匹配,以提高安全性。如果您无法更改证书,您可能需要考虑使用与证书中列出的主题备用名称匹配的主机名或 IP 地址。如果这不可行,您可以探索其他选项,如证书更新或禁用主机名验证,但要谨慎行事,以确保不会降低通信的安全性。
更多推荐
所有评论(0)