本文目录导读:

在 Shell 脚本中配置容器的 DNS 策略,通常取决于你使用的容器运行时(如 Docker、Podman、containerd)以及编排工具(如 Kubernetes),以下是常见场景的配置方法:
Docker 容器
使用 --dns 选项(推荐)
#!/bin/bash docker run -d \ --name my-container \ --dns 8.8.8.8 \ --dns 8.8.4.4 \ --dns-search example.com \ --dns-opt timeout:5 \ nginx:latest
使用 --dns-opt 参数
#!/bin/bash docker run -d \ --dns 192.168.1.100 \ --dns-opt "attempts:3" \ --dns-opt "rotate" \ alpine ash -c "ping google.com"
使用 Docker Compose(通过 shell 生成配置)
#!/bin/bash
cat > docker-compose.yml << EOF
version: '3'
services:
web:
image: nginx
dns:
- 8.8.8.8
- 8.8.4.4
dns_search:
- example.com
dns_opt:
- timeout:5
- attempts:3
- rotate
EOF
docker-compose up -d
修改系统 DNS 配置(影响所有容器)
#!/bin/bash
# 配置 Docker 守护进程的 DNS(/etc/docker/daemon.json)
cat > /etc/docker/daemon.json << EOF
{
"dns": ["8.8.8.8", "8.8.4.4"],
"dns-opts": ["timeout:5", "attempts:3"],
"dns-search": ["example.com"]
}
EOF
systemctl restart docker
Podman 容器
Podman 支持与 Docker 类似的 --dns 选项:
#!/bin/bash podman run -d \ --name my-container \ --dns 1.1.1.1 \ --dns-search mycompany.local \ alpine sleep 3600
Kubernetes Pod
在 Kubernetes 中,DNS 策略通过 YAML 文件的 dnsPolicy 字段配置:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: nginx
image: nginx
dnsPolicy: "ClusterFirst" # 可选值:Default, ClusterFirst, ClusterFirstWithHostNet, None
dnsConfig: # 当 dnsPolicy 为 None 时必须指定
nameservers:
- 8.8.8.8
- 8.8.4.4
searches:
- ns1.svc.cluster.local
- my.dns.search.suffix
options:
- name: ndots
value: "2"
- name: edns0
Shell 脚本中动态生成并应用:
#!/bin/bash
kubectl apply -f - << EOF
apiVersion: v1
kind: Pod
metadata:
name: custom-dns-pod
spec:
containers:
- name: app
image: busybox
command: ["sleep", "3600"]
dnsPolicy: "None"
dnsConfig:
nameservers:
- 8.8.8.8
searches:
- default.svc.cluster.local
options:
- name: attempts
value: "3"
EOF
常见 DNS 策略对比
| 策略 | 描述 | 使用场景 |
|---|---|---|
Default |
继承节点 DNS 配置 | 需要访问外部服务且不想修改 |
ClusterFirst |
使用集群 DNS 优先 | 需要解析 Service 和 Pod 名称 |
ClusterFirstWithHostNet |
集群 DNS + 主机网络 | Pod 使用 hostNetwork 时 |
None |
完全自定义 DNS | 需要完全控制 DNS 配置时 |
调试与验证
配置完成后,在容器内验证:
#!/bin/bash # 进入容器检查 docker exec -it my-container cat /etc/resolv.conf # 测试 DNS 解析 docker exec my-container nslookup google.com docker exec my-container dig example.com # Kubernetes 中验证 kubectl exec -it dns-pod -- cat /etc/resolv.conf
最佳实践
- 避免硬编码:将 DNS 服务器地址定义为脚本变量
- 使用环境变量:通过
--env或 ConfigMap 传递 DNS 配置 - 处理不同环境:开发/测试/生产环境使用不同的 DNS 策略
- 日志记录:记录 DNS 配置变更以便审计
#!/bin/bash
# 更健壮的实现示例
DNS_SERVER=${DNS_SERVER:-"8.8.8.8"}
DNS_OPTS="timeout:${DNS_TIMEOUT:-5} attempts:${DNS_ATTEMPTS:-2}"
docker run -d \
--dns "$DNS_SERVER" \
--dns-opt "$DNS_OPTS" \
"$@"
根据你的具体使用场景(单一容器、集群编排、还是网络策略需求),选择最适合的方案即可。