I'm new to k8s/minikube (and to some extent, unix networking in general) so if I ask something that seems to make no sense, I'll be happy to clarify!
Goal
I want to configure a port-based TCP ingress, as described briefly in the nginx-ingress docs. In particular, I want to use the webpack-dev-server
from inside minikube
.
Error
When it's set up according to my best understanding, I still get Failed to load resource: net::ERR_CONNECTION_REFUSED
when requesting local.web:3001/client.js
. That is, navigating in my browser to 'local.web/' brings up the page, but without the bundle that webpack
is meant to be producing. The request for that fails.
Configuration
Moving from host machine to minikube pod, I have
/etc/hosts:
On my dev machine, I set local.web
to the minikube IP
$ echo "$(minikube ip) local.web" | sudo tee -a /etc/hosts
Ingress:
{
"kind": "Ingress",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "dev-web-ingress",
"namespace": "dev",
"selfLink": "/apis/extensions/v1beta1/namespaces/dev/ingresses/dev-web-ingress",
"uid": "64ebfc93-612e-11e9-8df7-0800270e7244",
"resourceVersion": "280750",
"generation": 3,
"creationTimestamp": "2019-04-17T16:32:30Z",
"labels": {
"platform": "advocate",
"tier": "frontend"
},
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"extensions/v1beta1\",\"kind\":\"Ingress\",\"metadata\":{\"annotations\":{\"kubernetes.io/ingress.class\":\"nginx\"},\"labels\":{\"platform\":\"advocate\",\"tier\":\"frontend\"},\"name\":\"dev-web-ingress\",\"namespace\":\"dev\"},\"spec\":{\"rules\":[{\"host\":\"local.web\",\"http\":{\"paths\":[{\"backend\":{\"serviceName\":\"dev-adv-web-service\",\"servicePort\":\"http\"},\"path\":\"/\"}]}}]}}\n",
"kubernetes.io/ingress.class": "nginx"
}
},
"spec": {
"rules": [
{
"host": "local.web",
"http": {
"paths": [
{
"path": "/",
"backend": {
"serviceName": "dev-adv-web-service",
"servicePort": "http"
}
}
]
}
}
]
},
"status": {
"loadBalancer": {
"ingress": [
{
"ip": "10.0.2.15"
}
]
}
}
}
TCP Services
{
"kind": "ConfigMap",
"apiVersion": "v1",
"metadata": {
"name": "tcp-services",
"namespace": "dev",
"selfLink": "/api/v1/namespaces/dev/configmaps/tcp-services",
"uid": "5e456f3e-622e-11e9-bcf8-0800270e7244",
"resourceVersion": "295220",
"creationTimestamp": "2019-04-18T23:04:50Z",
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"data\":{\"3001\":\"dev/dev-adv-web-service:3001\",\"9290\":\"dev/dev-echoserver:8080\"},\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{},\"name\":\"tcp-services\",\"namespace\":\"dev\"}}\n"
}
},
"data": {
"3001": "dev/dev-adv-web-service:3001",
}
}
Service:
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "dev-adv-web-service",
"namespace": "dev",
"selfLink": "/api/v1/namespaces/dev/services/dev-adv-web-service",
"uid": "64e3c65d-612e-11e9-8df7-0800270e7244",
"resourceVersion": "280675",
"creationTimestamp": "2019-04-17T16:32:30Z",
"labels": {
"app": "adv-web",
"tier": "frontend"
},
"annotations": [... edited for clarity]
},
"spec": {
"ports": [
{
"name": "http",
"protocol": "TCP",
"port": 80,
"targetPort": 3000,
"nodePort": 31246
},
{
"name": "http2",
"protocol": "TCP",
"port": 3001,
"targetPort": 3001,
"nodePort": 31392
}
],
"selector": {
"app": "frontend-container",
"tier": "frontend"
},
"clusterIP": "10.108.24.80",
"type": "LoadBalancer",
"sessionAffinity": "None",
"externalTrafficPolicy": "Cluster"
},
"status": {
"loadBalancer": {}
}
}
Pod
{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "dev-adv-web-768767454f-wxvnh",
"generateName": "dev-adv-web-768767454f-",
"namespace": "dev",
"selfLink": "/api/v1/namespaces/dev/pods/dev-adv-web-768767454f-wxvnh",
"uid": "65de844e-622c-11e9-bcf8-0800270e7244",
"resourceVersion": "294073",
"creationTimestamp": "2019-04-18T22:50:43Z",
"labels": {
"app": "frontend-container",
"pod-template-hash": "768767454f",
"tier": "frontend"
},
"ownerReferences": [
{
"apiVersion": "apps/v1",
"kind": "ReplicaSet",
"name": "dev-adv-web-768767454f",
"uid": "4babd3e7-613d-11e9-8df7-0800270e7244",
"controller": true,
"blockOwnerDeletion": true
}
]
},
"spec": {
"volumes": [
{
"name": "frontend-repo",
"hostPath": {
"path": "/Users/me/Projects/code/frontend",
"type": ""
}
},
{
"name": "default-token-7rfht",
"secret": {
"secretName": "default-token-7rfht",
"defaultMode": 420
}
}
],
"containers": [
{
"name": "adv-web-container",
"image": "localhost:5000/react:dev",
"command": [
"npm",
"run",
"dev"
],
"ports": [
{
"name": "http",
"containerPort": 3000,
"protocol": "TCP"
},
{
"name": "http2",
"containerPort": 3001,
"protocol": "TCP"
}
],
"env": [
{
"name": "HOSTNAME_PUBLISHED",
"valueFrom": {
"configMapKeyRef": {
"name": "dev-frontend-configmap",
"key": "HOSTNAME_PUBLISHED"
}
}
},
{
"name": "LOCAL_DOMAIN",
"valueFrom": {
"configMapKeyRef": {
"name": "dev-frontend-configmap",
"key": "LOCAL_DOMAIN"
}
}
},
{
"name": "HOST",
"valueFrom": {
"configMapKeyRef": {
"name": "dev-frontend-configmap",
"key": "HOST"
}
}
},
{
"name": "WEBPACK_PUBLISHED_PORT",
"valueFrom": {
"configMapKeyRef": {
"name": "dev-frontend-configmap",
"key": "WEBPACK_PUBLISHED_PORT"
}
}
},
{
"name": "WEBPACK_LISTEN_PORT",
"valueFrom": {
"configMapKeyRef": {
"name": "dev-frontend-configmap",
"key": "WEBPACK_LISTEN_PORT"
}
}
},
{
"name": "API_URL",
"valueFrom": {
"configMapKeyRef": {
"name": "dev-frontend-configmap",
"key": "API_URL"
}
}
},
{
"name": "LOGIN_CALLBACK_URL",
"valueFrom": {
"configMapKeyRef": {
"name": "dev-frontend-configmap",
"key": "LOGIN_CALLBACK_URL"
}
}
},
{
"name": "NPM_CONFIG_LOGLEVEL",
"valueFrom": {
"configMapKeyRef": {
"name": "dev-frontend-configmap",
"key": "NPM_CONFIG_LOGLEVEL"
}
}
}
],
"resources": {},
"volumeMounts": [
{
"name": "frontend-repo",
"mountPath": "/code"
},
{
"name": "default-token-7rfht",
"readOnly": true,
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
}
],
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"imagePullPolicy": "Always"
}
],
"restartPolicy": "Always",
"terminationGracePeriodSeconds": 30,
"dnsPolicy": "ClusterFirst",
"serviceAccountName": "default",
"serviceAccount": "default",
"nodeName": "minikube",
"securityContext": {},
"schedulerName": "default-scheduler",
"tolerations": [
{
"key": "node.kubernetes.io/not-ready",
"operator": "Exists",
"effect": "NoExecute",
"tolerationSeconds": 300
},
{
"key": "node.kubernetes.io/unreachable",
"operator": "Exists",
"effect": "NoExecute",
"tolerationSeconds": 300
}
],
"priority": 0,
"enableServiceLinks": true
},
"status": {
"phase": "Running",
"conditions": [
{
"type": "Initialized",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2019-04-18T22:50:43Z"
},
{
"type": "Ready",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2019-04-18T22:50:45Z"
},
{
"type": "ContainersReady",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2019-04-18T22:50:45Z"
},
{
"type": "PodScheduled",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2019-04-18T22:50:43Z"
}
],
"hostIP": "10.0.2.15",
"podIP": "172.17.0.13",
"startTime": "2019-04-18T22:50:43Z",
"containerStatuses": [
{
"name": "adv-web-container",
"state": {
"running": {
"startedAt": "2019-04-18T22:50:44Z"
}
},
"lastState": {},
"ready": true,
"restartCount": 0,
"image": "localhost:5000/react:dev",
"imageID": "docker-pullable://localhost:5000/react@sha256:2bfe61ed134044bff4b23f5c057af2f9c480c3c1a1927a485f09f3410528903d",
"containerID": "docker://57b9b6dafaf2aba8a21d5dd7db3543f4742c00331b49b48dc1561e3b5bd05315"
}
],
"qosClass": "BestEffort"
}
}
Hypotheses
One thought was that the namespace on the TCP services ConfigMap
was wrong. It's not clear to me from the docs where that's supposed to live. I have tried it in the namespace dev
, where the ingress, service, and deployment/pods live. I also tried adding the data
entry as above to the tcp-services
ConfigMap
in kube-system
.
The logs for the webpack pod show no errors, so I don't believe the problem is at the application level.
Since the GET local.web/
is returning data from the pod, I am convinced the service is at least partially correct.
I'm willing to perform any debugging you can suggest, and have no illusions that I know anything about what's going on--I'll be grateful for any help offered.