Ingress problems are specific to your implementation, so let me just speak to a bare-metal, LAN implementation with no load-balancer.
The key validation point of an ingress resource is that it gets an address (after all, what am I supposed to hit, if the ingress doesn't have an address associated with it?) So if you do
kubectl get ingress some-ingress
Over and over (give it 30 seconds or so) and it never shows an address - what now?
On bare-metal LAN there are a few trouble spots. First, ensure that your Ingress resource can find your Ingress controller - so (setting aside the controller spec for now) your resource needs to be able to find your controller with something like:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-api-ingress
annotations:
kubernetes.io/ingress.class: nginx
Where your controller has entries like:
Labels: app.kubernetes.io/component=controller
app.kubernetes.io/instance=ingress-nginx
app.kubernetes.io/managed-by=Helm
app.kubernetes.io/name=ingress-nginx
app.kubernetes.io/version=1.0.4
helm.sh/chart=ingress-nginx-4.0.6
But now let's go back a step - your controller - is it setup appropriately for your (in my case) bare-metal LAN implementation? (this is all made super-easy by the cloud providers, so I'm providing this answer for my friends in the private cloud community)
There the issue is that you need this essential hostNetwork setting to be true, in your Ingress controller deployment. So for that, instead of using the basic yamil (https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.4/deploy/static/provider/baremetal/deploy.yaml) - wget it, and modify it to set the spec of the template of the spec of the Deployment, so that hostNetwork: true - something like (scroll down to the end):
# Source: ingress-nginx/templates/controller-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
helm.sh/chart: ingress-nginx-4.0.6
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.0.4
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
revisionHistoryLimit: 10
minReadySeconds: 0
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
spec:
dnsPolicy: ClusterFirst
containers:
- name: controller
image: k8s.gcr.io/ingress-nginx/controller:v1.0.4@sha256:545cff00370f28363dad31e3b59a94ba377854d3a11f18988f5f9e56841ef9ef
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
args:
- /nginx-ingress-controller
- --election-id=ingress-controller-leader
- --controller-class=k8s.io/ingress-nginx
- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
runAsUser: 101
allowPrivilegeEscalation: true
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: LD_PRELOAD
value: /usr/local/lib/libmimalloc.so
livenessProbe:
failureThreshold: 5
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
- name: webhook
containerPort: 8443
protocol: TCP
volumeMounts:
- name: webhook-cert
mountPath: /usr/local/certificates/
readOnly: true
resources:
requests:
cpu: 100m
memory: 90Mi
nodeSelector:
kubernetes.io/os: linux
serviceAccountName: ingress-nginx
terminationGracePeriodSeconds: 300
hostNetwork: true
volumes:
- name: webhook-cert
secret:
secretName: ingress-nginx-admission
Deploy that, then setup your ingress resource, as indicated above.
Your key tests are:
- Does my ingress have a dedicated node in my bare-metal implementation?
- if I hit port 80 on the ingress node, do I get the same thing as hitting the NodePort? (let's say NodePort is 31207 - do I get the same thing hitting port 80 on the ingress node as hitting port 31207 on any node?)
Final note: Ingress has changed a lot over the past few years, and tutorials are often providing examples that don't pass validation - please feel free to comment on this answer if it has become out of date