Kubernetes中coredns无法正常域名解析问题

  下载了比较新的版本,查看下安装后的版本

Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.0", GitCommit:"9e991415386e4cf155a24b1da15becaa390438d8", GitTreeState:"clean", BuildDate:"2020-03-25T14:58:59Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.0", GitCommit:"9e991415386e4cf155a24b1da15becaa390438d8", GitTreeState:"clean", BuildDate:"2020-03-25T14:50:46Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"}

按官方文档安装 kubeadm kubelet, kubectl后,如果不安装相关的网络 addon, 默认安装的coredns会是pending状态,而master会是"not ready"状态。

Kubernetes中coredns无法正常域名解析问题_第1张图片

去官方

https://docs.projectcalico.org/getting-started/kubernetes/flannel/flannel

 

curl https://docs.projectcalico.org/manifests/canal-etcd.yaml -O

apply -f 后直接都正常了。

集群内的IP及访问也很正常。

  后来到pod的容器内,却不能访问service 的name. 这明显是dns出了问题。

  而pod里的容器内ping 集群内各IP都可以,却连baidu这样的域名 都ping不通。

  为什么很多教程里在验证dns都需要下载busybox,dig类的docker,因为一般的docker容器里可能连ping都没有。

https://blog.csdn.net/networken/article/details/105604173

这个教程是极棒的问题排查方式 ,可以通过更改各POD容器里的/etc/resolv.confj里的nameserver,开始它都默认指向kube-dns的集群地址,这个时候集群dns有问题,所以啥域名也拼不通,直接将它换成阿里云的域名解析服务器223.5.5.5,发现解析www.baidu.com没有问题了。 

    这个时候将nameserver更改成kube-dns 服务下的一个pod比如说coredns-546565776c-v7465 的集群内的本地地址,这个时候dns也是正常的,可以解析集群内的service name 及外部的域名,比如百度,说明 什么?,说明了是这个kube-dns的service出了问题。 而service是通过proxy来分发的。

   这个时候我们去kubectl -n kube-system logs -f  kube-proxy-c4fws ,发现了

] Failed to list IPVS destinations, error: parseIP Error ip=[253 0 0 16 2 69 0 0 221 232 251 54 204 98 3 124

很多类似这样的打印,所以这样就可以在百度找到

   https://blog.csdn.net/networken/article/details/105604173根据它的指引,我们可以找到根据原因 

https://github.com/kubernetes/kubernetes/issues/89520

下面作部分的引用 :

After some study, I find that this issue most likely is caused by the low linux kernel version.
I have reproduced this problem on Linux CentOS 3.10.0-693.el7.x86_64.

Accroding to the code, netlink will try to get d.AddressFamily attribute, but I find the kernel just does not support it :(

This is the Destination Attributes defined in /usr/include/linux/ip_vs.h (kernel 3.10)

/*
 * Attributes used to describe a destination (real server)
 *
 * Used inside nested attribute IPVS_CMD_ATTR_DEST
 */
enum {
	IPVS_DEST_ATTR_UNSPEC = 0,
	IPVS_DEST_ATTR_ADDR,		/* real server address */
	IPVS_DEST_ATTR_PORT,		/* real server port */

	IPVS_DEST_ATTR_FWD_METHOD,	/* forwarding method */
	IPVS_DEST_ATTR_WEIGHT,		/* destination weight */

	IPVS_DEST_ATTR_U_THRESH,	/* upper threshold */
	IPVS_DEST_ATTR_L_THRESH,	/* lower threshold */

	IPVS_DEST_ATTR_ACTIVE_CONNS,	/* active connections */
	IPVS_DEST_ATTR_INACT_CONNS,	/* inactive connections */
	IPVS_DEST_ATTR_PERSIST_CONNS,	/* persistent connections */

	IPVS_DEST_ATTR_STATS,		/* nested attribute for dest stats */
	__IPVS_DEST_ATTR_MAX,
};

No IPVS_DEST_ATTR_ADDR_FAMILY attribute is defined!

But in new kernel version, the Destination Attributes is defined like this:

/*
 * Attributes used to describe a destination (real server)
 *
 * Used inside nested attribute IPVS_CMD_ATTR_DEST
 */
enum {
	IPVS_DEST_ATTR_UNSPEC = 0,
	IPVS_DEST_ATTR_ADDR,		/* real server address */
	IPVS_DEST_ATTR_PORT,		/* real server port */

	IPVS_DEST_ATTR_FWD_METHOD,	/* forwarding method */
	IPVS_DEST_ATTR_WEIGHT,		/* destination weight */

	IPVS_DEST_ATTR_U_THRESH,	/* upper threshold */
	IPVS_DEST_ATTR_L_THRESH,	/* lower threshold */

	IPVS_DEST_ATTR_ACTIVE_CONNS,	/* active connections */
	IPVS_DEST_ATTR_INACT_CONNS,	/* inactive connections */
	IPVS_DEST_ATTR_PERSIST_CONNS,	/* persistent connections */

	IPVS_DEST_ATTR_STATS,		/* nested attribute for dest stats */

	IPVS_DEST_ATTR_ADDR_FAMILY,	/* Address family of address */

	IPVS_DEST_ATTR_STATS64,		/* nested attribute for dest stats */

	IPVS_DEST_ATTR_TUN_TYPE,	/* tunnel type */

	IPVS_DEST_ATTR_TUN_PORT,	/* tunnel port */

	IPVS_DEST_ATTR_TUN_FLAGS,	/* tunnel flags */

	__IPVS_DEST_ATTR_MAX,
};

Obviously, the kernel has added some attributes (IPVS_DEST_ATTR_ADDR_FAMILY, IPVS_DEST_ATTR_STATS64...).

That is why kube-proxy works well on systems with a higher version of the kernel.

So we can address this issue by upgrading our linux kernel.
Not sure which kernel version is the minimum requirement, maybe we should document something about this.

 

最后,通过将linux内核更新到4.x.x

## 载入公钥
$ rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org

## 安装 ELRepo 最新版本
$ yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm

## 列出可以使用的 kernel 包版本
$ yum list available --disablerepo=* --enablerepo=elrepo-kernel

## 安装指定的 kernel 版本:
$ yum install -y kernel-lt-4.4.218-1.el7.elrepo --enablerepo=elrepo-kernel

## 查看系统可用内核
$ cat /boot/grub2/grub.cfg | grep menuentry

menuentry 'CentOS Linux (3.10.0-1062.el7.x86_64) 7 (Core)' --class centos (略)
menuentry 'CentOS Linux (4.4.218-1.el7.elrepo.x86_64) 7 (Core)' --class centos ...(略)

## 设置开机从新内核启动
$ grub2-set-default "CentOS Linux (4.4.218-1.el7.elrepo.x86_64) 7 (Core)"

## 查看内核启动项
$ grub2-editenv list
saved_entry=CentOS Linux (4.4.218-1.el7.elrepo.x86_64) 7 (Core)
重启系统使内核生效:

$ reboot
启动完成查看内核版本是否更新:

$ uname -r

4.4.218-1.el7.elrepo.x86_64
 

最后重启后,一切正常。

注:可以看是否不通过ipvs的方式,这样是否就不用升级内核了,毕竟 这样重的操作,不方便实现一键安装,中间需要通过重启服务器等操作。

你可能感兴趣的:(LINUX,服务容器,DOCK)