• DevOps
  • 流水线选择Github代码仓库时报错 x509: certificate is valid for ... 以及排查过程中发现容器内 DNS 错误解析的现象

创建部署问题时,请参考下面模板,你提供的信息越多,越容易及时获得解答。
发帖前请点击 发表主题 右边的 预览(👀) 按钮,确保帖子格式正确。
你只花一分钟创建的问题,不能指望别人花上半个小时给你解答。

操作系统信息
虚拟机,Ubuntu server 20.04,4C/16G,新装系统,NAT 网络

Kubernetes版本信息
v1.24.7,多节点。

容器运行时
ctr github.com/containerd/containerd v1.6.4

KubeSphere版本信息
v3.3.2,在线安装。全套安装。

问题是什么
使用 DevOps 添加流水线 选择 Github 仓库时,提示:
Get “https://api.github.com/user”: x509: certificate is valid for *.mytrafficmanagement.com, mytrafficmanagement.com, not api.github.com
以及在排查过程中,发现 Pod 内 DNS 错误解析不存在的域名到 Linode 的问题(看起来和 Kubesphere 没有直接关联)。

排查过程

因为不懂证书方面的知识,原本想在本地搭建一个 GitLab 将就一下先,结果运行流水线的时候才发现下载 Maven 依赖也需要联网。于是先按能不能在容器内部访问到外部 https 网站的方向摸索解决问题。

一、devops-jenkins

初始状态

通过 kubesphere 提供的终端,在 Jenkins 内执行 curlapt-get update。默认情况下,访问 http 和 https 网站都有问题,但是 apt-get update 可以,只是速度有点慢。

# curl http://api.github.com/users
<html><head><title>api.github.com</title></head><body><h1>api.github.com</h1><p>Coming soon.</p></body></html>

# curl http://www.baidu.com
<html><head><title>www.baidu.com</title></head><body><h1>www.baidu.com</h1><p>Coming soon.</p></body></html>

# curl https://api.github.com/users
curl: (7) Failed to connect to api.github.com port 443: Connection refused

# curl https://www.baidu.com
curl: (60) SSL: no alternative certificate subject name matches target host name 'www.baidu.com'
More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

# apt-get update
Get:1 http://deb.debian.org/debian bullseye InRelease [116 kB]
......
设置代理后

为终端设置代理,代理为宿主机的 Clash,测试网络通畅。

# export http_proxy=http://192.168.46.1:7890
# export https_proxy=http://192.168.46.1:7890
# export no_proxy=localhost,127.0.0.1/24,192.168.46.1/24
# curl http://api.github.com/users
# 什么都没返回
# curl https://api.github.com/users
[
  {
    "id": 1,
    "gravatar_id": "",
    "type": "User",
    "site_admin": false
  },
......

原本计划像给 普通 Docker 容器内部设置代理一样,让 Jenkins 能访问外部网络和下载资源先凑合学习。但是没找到合适的方法,Containerd 不熟悉,同时也担心代理设置不当会影响集群内部的通信,引起更多问题,决定继续测试。

apt-get install iputils-ping
# ping api.github.com
PING api.github.com.localdomain (72.14.185.43) 56(84) bytes of data.
64 bytes from li51-43.members.linode.com (72.14.185.43): icmp_seq=1 ttl=127 time=223 ms
......

DNS 的问题

注意到解析返回的结果很奇怪,物理机(Window10)和虚拟机(Ubuntu 20.04)是一致且正确的,担心 DNS 有问题,也想着如果解决了 DNS 是不是证书的问题也迎刃而解。

# apt-get install dnsutils
# dig api.github.com

; <<>> DiG 9.16.42-Debian <<>> api.github.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8208
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;api.github.com.                        IN      A

;; ANSWER SECTION:
api.github.com.         5       IN      A       20.205.243.168

;; Query time: 7 msec
;; SERVER: 169.254.25.10#53(169.254.25.10)
;; WHEN: Sat Jul 01 15:52:21 UTC 2023
;; MSG SIZE  rcvd: 73

# nslookup api.github.com
Server:         169.254.25.10
Address:        169.254.25.10#53

Name:   api.github.com.localdomain
Address: 45.33.20.235
** server can't find api.github.com.localdomain: NXDOMAIN

发现只有 dig 返回的 IP 是正确的,/etc/hosts 里没有发现明显干扰项。

# cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.233.76.111   devops-jenkins-55f5f458fb-jc6z9
错误的域名

排查了很久,后来才注意到 ping 和 nslookup 最终查询的域名不对,被拼接上了 localdomain。以下为 /etc/resolv.conf 的内容,dns 查询会依次先拼接上 search 给定的后缀进行查询。

# cat /etc/resolv.conf
search kubesphere-devops-system.svc.cluster.local svc.cluster.local cluster.local localdomain
nameserver 169.254.25.10
options ndots:5

在添加了 localdomain 后缀后,一个不存在的域名 api.github.com.localdomain 竟然通过查询得到 linode 的 IP,经过测试,别的域名加上该后缀后也会解析到 linode 的 IP 上。
Linode 是 VPS 厂家,IP 是 Akamai 的 IP,也看到过两者一起的广告。

错误可以往上验证到虚拟机 Ubuntu

经过测试,宿主机上 api.github.com.localdomain 是无法正常解析的,虚拟机 Ubuntu 上可以被解析,但是虚拟机 Ubuntu 上的 /etc/resolve.conf 的 search 在 nameserver 之后,不会出现容器内部类似的情况。

验证修复 DNS 是否可修复容器的网络问题

虚拟机 Ubuntu 验证

虚拟机 Ubuntu 在替换掉 DNS 服务器后,api.github.com.localdomain 确实不能被解析。

$ cat /etc/netplan/00-installer-config.yaml 
# This is the network config written by 'subiquity'
network:
  ethernets:
    ens33:
      dhcp4: true
      nameservers:
        addresses: [8.8.8.8,114.114.114.114]
  version: 2
$ sudo netplan apply 
$ ping api.github.com.localdomain
ping: api.github.com.localdomain: Name or service not known

Jenkins 容器验证

删除掉 /etc/resolv.conf 中的 localdomain 或者 nameserver 替换成 8.8.8.8,ping api.github.com 都能正常被解析,其中后者也能让 api.github.com.localdomain 不被解析,在没有代理的情况下 curl https://api.github.com/users 也可以正常访问,只是速度略慢。

# ping api.github.com
PING api.github.com (20.205.243.168) 56(84) bytes of data.
64 bytes from 20.205.243.168 (20.205.243.168): icmp_seq=1 ttl=127 time=102 ms

# ping api.github.com.localdomain
ping: api.github.com.localdomain: Name or service not known

从结果上看,应该是 Ubuntu 自带的 nameserver 127.0.0.1:53 和容器自带的集群 nameserver 169.254.25.10:53 会让 xxxxxx.localdomain 的域名被解析到 Linode 的 IP 上。
但是,修改 Jenkins 的 nameserver 后,选择 Github 仓库时的证书报错仍然存在,不知道该报错对应的请求是不是出自 Jenkins Pod
(总结到这里,才意识到可能选错了容器,去翻了一下日志,发现是 devops-apiserver 的报错,亏得直接连接不上该容器,要不然大半夜会被纠结住要不要继续测试验证)

两个主要的疑问

一、流水线中选择代码仓库以及下载 Maven 依赖时的证书错误是什么原因,会是我的集群搭建过程有问题或者配置不正确吗?
二、DNS 问题是什么原因呢,大家有遇到过吗?虽然改 DNS 服务器能解决,总觉得不得劲,不知道根本问题在哪里,而且于集群内容器的网络问题无益。

附上 coredns 的 configmaps,也不知道有没有用。

$ kubectl get configmaps -n=kube-system coredns -o yaml
apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
           lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf {
           max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2023-06-21T10:58:03Z"
  name: coredns
  namespace: kube-system
  resourceVersion: "244"
  uid: edaf9a11-ecac-4b16-920b-8505f53096d2

最后,先谢谢大家了,请大家帮帮忙。

1 个月 后