应用说明:
PHP: php-fpm7.4 、 php-fpm7.4.13
Traefik(用于Kubernetes的ACME和ingress-route)
Helm v3进行服务自动化部署
用于测试的代码
$domain = 'www.mywebsite.com';
echo 'gethostbynamel(): '; var_dump(gethostbynamel($domain)); #false
echo 'checkdnsrr(): '; var_dump(checkdnsrr($domain, 'A')); #false
echo 'dns_get_record(): '; var_dump(dns_get_record($domain)); #empty
问题描述:
因为发现代码中需要上传到OSS的地方出现了 “Cannot resolve host”报错(来源于curl()函数)。
此问题仅出现在Kubernetes(1.18,使用的是腾讯TKE服务进行集群管理) 由Helm(v3)部署Dockerfile镜像后出现。
这份Dockerfile在本地(我的电脑)通过 docker build & docker run以及某一台独立的服务器上通过docker-compose 基于该Dockerfile进行 build .
都是没有问题的。
Dockerfile大致样貌,使用supervisor(以root运行)管理容器内的Nginx、php-fpm启动。 这份Dockerfile是正常且持续工作了1年的。。。
FROM php:7.4-fpm-alpine
ENV TZ=Asia/Shanghai
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
# Install dev dependencies
RUN apk add ... #此处省略一堆安装依赖的部分
COPY src /var/www
WORKDIR /var/www
RUN chown -R www-data:www-data /var/www/
&& chmod +x /usr/local/bin/start
RUN chmod -R 777 storage && chmod -R 755 public
RUN composer install --optimize-autoloader --no-dev
ADD src/.env.example .env
RUN php artisan jwt:secret && php artisan storage:link && php artisan key:generate
CMD ["/usr/local/bin/start"]
先决排查:
kube-dns pods、endpoints、开启日志无异常...正常
使用bosybox:1.28.3(讲究)进行DNS解析测试...正常
程序pod中/etc/resolv.conf 的nameserver和搜索域可用,FQDN服务解析正常(nslookup) .... 正常
程序pod下shell执行 curl 到 api.weixin.qq.com和www.baidu.com ...正常
程序pod下使用php -a和 php artisan tinker执行curl 到 api.weixin.qq.com ...正常
程序pod下kill php-fpm,然后启动php-fpm ... 无效
将程序代码中使用CURL的部分增加关闭DNS缓存 curl_setopt($ch,CURLOPT_DNS_USE_GLOBAL_CACHE,false)... 无效
修改/etc/resolv.conf为644..无效
程序pod中/etc/resolv.conf增加其他DNS(阿里云内网DNS、114和8那种,每次只加2条,不超3条nameserver),然后重启php-fpm ... 无效
总结:
- php-cli一切正常,可以解析,仅php-fpm无法解析域名, IP可以。感觉php-fpm对/etc/resolv.conf没感觉。。。
- kube-dns正常,kube-proxy正常。
- 在/etc/hosts中增加所要用的OSS服务的解析(比如 公网IP bucket-name.oss.aliyun.com),php-fpm才可以工作。
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…