随着 Linux 的不断发展壮大,涌现出了各种各样的 DNS 自动管理程序,它们都想要直接获得 /etc/resolv.conf
的控制权,有些人欣然接受,有些人则无法接受。如果你是无法接受的那一方,那么请继续往下看,我会教你如何识别出是哪些程序在控制你的 /etc/resolv.conf
文件,以及如何夺回控制权。
目前能够控制 /etc/resolv.conf
文件的工具大概有这么几个:netconfig, NetworkManager, resolvconf, rdnssd 和 systemd-resolved
。如果你的 /etc/resolv.conf
文件正在被它们控制,那么你对该文件的任何修改都会在几分钟后被覆盖,或者重启后被恢复成原来的值。
要想重新夺回对 /etc/resolv.conf
的控制权,首先就要识别出是谁在控制这个文件
1. 找出是谁在控制 /etc/resolv.conf
先尝试读取 /etc/resolv.conf
开头的注释,注释里一般会标明是谁在操控该文件:
sh
$ head /etc/resolv.conf
有些工具不会在 /etc/resolv.conf
文件中添加注释,从文件内容里找不到任何蛛丝马迹。这时我们需要换种方法,直接查看该文件是否是一个软链接:
sh
$ ls -l /etc/resolv.conf
如果还是找不到任何线索,那就只能查看系统运行的进程中是否有上面提到的工具。如果还是找不到,那么恭喜你,resolv.conf
已经完全掌控在你的手里,你想怎么改就直接改吧。
接下来将会教你如何禁用自动管理 resolv.conf
的各种程序。
2. NetworkManager
NetworkManager
是最常见的自动配置网络和 DNS 的工具。比如在 Debian 和 Fedora 中它负责配置 /etc/resolv.conf
。 NetworkManager
可以和其他工具共存,即使禁用了所有其他管理 resolv.conf
的程序,NetworkManager
也会跳出来接管 resolv.conf。
可以将 NetworkManager
的主配置部分的选项 dns
设置为 none
来禁用其对 DNS
的管理功能:
sh
$ echo -e "[main]\ndns=none" > /etc/NetworkManager/conf.d/no-dns.conf
$ systemctl restart NetworkManager.service
$ rm /etc/resolv.conf
如果配置完了以后没有生效,那么可能存在配置冲突(通常是由 dnsmasq
引起的),需要找到冲突的配置:
sh
$ grep -ir "\[main\]" /etc/NetworkManager/
3. netconfig
如果是 openSUSE
,SUSE 或其他衍生发行版,一般都是由 netconfig
来控制 resolv.conf
。可以通过禁用 /etc/sysconfig/network/config
中的 NETCONFIG_DNS_POLICY
选项来禁用其对 resolv.conf
的控制:
sh
NETCONFIG_DNS_POLICY=""
还要删除 netconfig
生成的 resolv.conf
文件,并重启系统:
sh
$ rm /etc/resolv.conf
$ reboot
现在就可以手动创建 /etc/resolv.conf
文件随意修改了。
4. resolvconf 和 rdnssd
如果是 Debian 8.0 或 Ubuntu 15.04,并且启用了 IPv6,那么你可能会遇到 resolvconf 和 rdnssd 互相争夺 resolv.conf 控制器的情况。两个服务都想控制这个文件,每隔几毫秒就会覆盖对方的配置,从而导致间歇性的 DNS 解析中断。可以直接禁用并立即停止这两个服务:
sh
$ systemctl disable --now resolvconf.service rdnssd.service
$ rm /etc/resolv.conf
最后手动创建 /etc/resolv.conf
文件。
5. systemd-resolved
如果是 Ubuntu 16.10 或更新的版本,则由 systemd-resolved
服务来管理 DNS,可以使用下面的命令来禁用并立即停止该服务:
sh
$ systemctl disable --now systemd-resolved.service
$ rm /etc/resolv.conf
然后手动创建 /etc/resolv.conf
文件。
6. 创建 /etc/resolv.conf
最后的最后,就是手动创建 /etc/resolv.conf
文件了,建议权限设置为 644。配置示例:
sh
nameserver 114.114.114.114
nameserver 223.5.5.5
当然,除了 nameserver
外,还有其他的参数可以配置,感兴趣可以 man
一下:
sh
$ man 5 resolv.conf
k8s 相关
在某些 Kubernetes 安装过程中,特别是当涉及到网络插件(如 Flannel、Weave、Calico 等)时,systemd-resolved
可能会引起 DNS 配置和解析的问题。因此,禁用 systemd-resolved
并手动配置 DNS 解析器是一个常见的做法。
以下是禁用 systemd-resolved
并手动配置 DNS 解析的步骤:
1. 禁用 systemd-resolved
禁用并停止 systemd-resolved 服务:
bash
sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
2. 删除 /etc/resolv.conf
的符号链接
默认情况下,/etc/resolv.conf
是一个符号链接,指向 systemd-resolved
的配置文件。你需要删除这个符号链接并创建一个新的静态配置文件。
首先,删除符号链接:
bash
sudo rm /etc/resolv.conf
3. 创建新的 /etc/resolv.conf
创建一个新的 /etc/resolv.conf
文件,并手动配置 DNS 解析器。例如,使用 Google 的公共 DNS 服务器:
bash
sudo bash -c 'cat << EOF > /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
EOF'
4. 确认 DNS 解析配置
验证新的 DNS 配置是否生效:
bash
cat /etc/resolv.conf
确保输出显示的是你配置的 DNS 服务器地址。
5. 重启网络服务
为了确保所有网络设置生效,你可以重启网络服务:
bash
复制代码
sudo systemctl restart networking
更改kubelet配置
另发现kubeadm(v1.21.3)安装的kubelet
默认会使用 /run/systemd/resolve/resolv.conf
,也可以手工更改,配置( /var/lib/kubelet/config.yaml
)
sh
cat /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
resolvConf: /run/systemd/resolve/resolv.conf
resolvConf修改为你更改的: /etc/resolv.conf
参考资料:
https://icloudnative.io/posts/resolvconf-tutorial/
https://dyrnq.com/ubuntu-update-etc-resolve-conf/