可通过curl访问互联网的Kubernetes Pod出现java.net.SocketException: Network is unreachable错误排查
java.net.SocketException: Network is unreachable (connect failed) Problem Description
I've configured a simple CronJob in Kubernetes that creates a Pod to call the Slack API and pull conversation history. The app works perfectly when running locally or Dockerized, but after deploying to Kubernetes, I get the following error:
java.net.SocketException: Network is unreachable (connect failed)
java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
java.base/java.net.Socket.connect(Socket.java:609)
okhttp3.internal.platform.Platform.connectSocket(Platform.kt:120)
Here's my Kubernetes CronJob configuration:
apiVersion: batch/v1beta1 kind: CronJob metadata: name: my-app-job spec: schedule: "*/1 * * * *" jobTemplate: spec: template: spec: containers: - name: name image: myimage imagePullPolicy: Always ports: - containerPort: 443 protocol: TCP - containerPort: 80 protocol: TCP env: - name: http_proxy value: myproxy - name: https_proxy value: myproxy - name: no_proxy value: myproxy restartPolicy: OnFailure
During debugging, I found that the Pod can access public networks via curl (e.g., curl www.google.com returns HTTP/1.1 200 OK), but running ping gives ping: socket: Operation not permitted. I tried exposing ports via a NodePort Service but that didn't resolve the issue. I suspect I'm missing some configuration—how can I debug this further?
Troubleshooting Steps & Solutions
1. Fix the no_proxy Environment Variable Configuration
Your current no_proxy value is set to myproxy, which is incorrect. The no_proxy variable defines destination addresses that should bypass the proxy, not the proxy itself. This misconfiguration might be causing your Java app to incorrectly bypass the proxy when trying to reach Slack's API (or even loop back incorrectly).
Update the no_proxy value to include addresses that don't need proxy access, like cluster-internal services, localhost, and private IP ranges. For example:
env: - name: http_proxy value: myproxy - name: https_proxy value: myproxy - name: no_proxy value: "localhost,127.0.0.1,.cluster.local,10.0.0.0/8"
Adjust the values to match your cluster's internal network ranges.
2. Verify Java App Reads Proxy Environment Variables
Not all Java applications automatically pick up http_proxy/https_proxy environment variables. Some require explicit JVM arguments or code-level configuration:
- Add JVM proxy arguments to your container's command (if your app runs via
javacommand):
Replacecontainers: - name: name image: myimage command: ["java", "-Dhttp.proxyHost=myproxy_host", "-Dhttp.proxyPort=myproxy_port", "-Dhttps.proxyHost=myproxy_host", "-Dhttps.proxyPort=myproxy_port", "-jar", "your-app.jar"]myproxy_hostandmyproxy_portwith your actual proxy details (split from yourmyproxyvalue, which should be inhost:portformat). - Check your application code (especially if using OkHttp, which you are) to ensure it's configured to use system proxies. For OkHttp, you can enable proxy support with:
OkHttpClient client = new OkHttpClient.Builder() .proxy(ProxySelector.getDefault()) .build();
3. Check for NetworkPolicy Restrictions
If your cluster uses NetworkPolicies, ensure there's no policy blocking outbound traffic from your CronJob's Pod to Slack's API endpoints (typically https://slack.com on port 443). You can create a NetworkPolicy explicitly allowing this traffic:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-slack-access spec: podSelector: matchLabels: app: my-app-job # Match your CronJob's Pod labels (add labels to your CronJob template if missing) policyTypes: - Egress egress: - to: - ipBlock: cidr: 0.0.0.0/0 # Or restrict to Slack's IP ranges for tighter security ports: - protocol: TCP port: 443
4. Validate DNS Resolution in the Pod
Even if curl works, confirm that your Java app can resolve Slack's domain correctly. Exec into the running Pod and run:
nslookup slack.com
If DNS resolution fails, check your cluster's DNS configuration (e.g., CoreDNS status) or add explicit DNS settings to your Pod template:
spec: template: spec: dnsPolicy: "None" dnsConfig: nameservers: - 8.8.8.8 - 8.8.4.4
5. Ignore the ping Error (It's Expected)
The ping: socket: Operation not permitted error is normal in Kubernetes. By default, Pods run with a restricted security context that blocks ICMP traffic (which ping uses). This doesn't affect TCP-based connections like your Slack API calls, so you can safely ignore this issue.
内容的提问来源于stack exchange,提问作者Dimitrios

