How to change, edit, save /etc/hosts file from Azure Bash for Kubernetes? - linux

I uploaded a project to kubernetes and for its gateway to redirect the services, it requires the following:
127.0.0.1 app.my.project
127.0.0.1 event-manager.my.project
127.0.0.1 logger.my.project
and so on.
I can't run any sudo commands, so sudo nano /etc/hosts doesnt work. I tried vi /etc/hosts and it gives permission denied error. How can I edit /etc/hosts file or do some configuration on Azure to make it work like that?
Edit:
To give more information, I have uploaded a project to Kubernetes that has reverse-proxy settings.
So reaching the web-app of that project is not available via IP. Instead if I'm running the application locally, I have to edit the hosts file of the computer I'm using with
127.0.0.1 app.my.project
127.0.0.1 event-manager.my.project
127.0.0.1 logger.my.project
and so on. So whenever I type web-app.my.project its gateway redirects to web-app part and if I write app.my.project it redirects to app part, etc.
When I uploaded it to Azure Kubernetes Service it added default-http-backend on ingress-nginx namespace which created by itself. To expose these services, I opened the Http Routing option from Azure which gave me the loadbalancer at the left side of the image. So If I'm reading the situation correctly, (I'm most probably wrong though) it is something like the image below:
So, I added hostaliases to kube-system, ingress-nginx and default namespaces to make it like I edited a hosts file when I was running the project locally. But it still gives me that default backend - 404 ingress error
Edit 2:
I have nginx-ingress-controller which allows the redirection as far as I understand. So, when I add hostaliases to it as follows:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app: ingress-nginx
template:
metadata:
labels:
app: ingress-nginx
annotations:
prometheus.io/port: '10254'
prometheus.io/scrape: 'true'
spec:
hostAliases:
- ip: "127.0.0.1"
hostnames:
- "app.ota.local"
- "gateway.ota.local"
- "treehub.ota.local"
- "tuf-reposerver.ota.local"
- "web-events.ota.local"
hostNetwork: true
serviceAccountName: nginx-ingress-serviceaccount
containers:
- name: nginx-ingress-controller
image: {{ .ingress_controller_docker_image }}
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: tcp
containerPort: 8000
- name: http
containerPort: 80
- name: https
containerPort: 443
livenessProbe:
failureThreshold: 3
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
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
So when I edit yaml file as aforementioned, it gives the following error on Azure:
Failed to update the deployment
Failed to update the deployment 'nginx-ingress-controller'. Error: BadRequest (400) : Deployment in version "v1" cannot be handled as a Deployment: v1.Deployment.Spec: v1.DeploymentSpec.Template: v1.PodTemplateSpec.Spec: v1.PodSpec.HostAliases: []v1.HostAlias: readObjectStart: expect { or n, but found ", error found in #10 byte of ...|liases":["ip "127.0|..., bigger context ...|theus.io/scrape":"true"}},"spec":{"hostAliases":["ip "127.0.0.1""],"hostnames":["app.ota.local","g|...
If I edit the yaml file locally and try to run it from local kubectl which is connected to Azure, it gives the following error:
serviceaccount/weave-net configured
clusterrole.rbac.authorization.k8s.io/weave-net configured
clusterrolebinding.rbac.authorization.k8s.io/weave-net configured
role.rbac.authorization.k8s.io/weave-net configured
rolebinding.rbac.authorization.k8s.io/weave-net configured
daemonset.apps/weave-net configured Using cluster from kubectl
context: k8s_14
namespace/ingress-nginx unchanged deployment.apps/default-http-backend
unchanged service/default-http-backend unchanged
configmap/nginx-configuration unchanged configmap/tcp-services
unchanged configmap/udp-services unchanged
serviceaccount/nginx-ingress-serviceaccount unchanged
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole
unchanged role.rbac.authorization.k8s.io/nginx-ingress-role unchanged
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding
unchanged
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding
unchanged error: error validating
"/home/.../ota-community-edition/scripts/../generated/templates/ingress":
error validating data: ValidationError(Deployment.spec.template.spec):
unknown field "hostnames" in io.k8s.api.core.v1.PodSpec; if you choose
to ignore these errors, turn validation off with --validate=false
make: *** [Makefile:34: start_start-all] Error 1

Adding entries to a
Pod's /etc/hosts file provides Pod-level override of hostname
resolution when DNS and other options are not applicable. You can add
these custom entries with the HostAliases field in PodSpec.
Modification not using HostAliases is not suggested because the file
is managed by the kubelet and can be overwritten on during Pod
creation/restart.
I suggest that you use hostAliases instead
apiVersion: v1
kind: Pod
metadata:
name: hostaliases-pod
spec:
restartPolicy: Never
hostAliases:
- ip: "127.0.0.1"
hostnames:
- "app.my.project"
- "event-manager.my.project"
- "logger.my.project"
containers:
- name: cat-hosts
image: busybox
command:
- cat
args:
- "/etc/hosts"

Related

Azure AKS and Application Gateway returning 404

I have a AKS cluster deployed with an Application Gateway. These are all docker images running on the AKS cluster with a simple ingress. They all run on the same default namespace. One is a Vue frontend, the second is a Java spring backend, the last being a Fullstack Tomcat image. All three services ran completely fine without any issues; however, today all of the 3 services gave back a 404 error (without any changes to the cluster to my knowledge).
When testing for the health of these services, I was still able to kubectl to all the services. In addition, the Health Probe on Azure Application Gateway returned a healthy 200 status code for all three services.
I have tried removing the workloads and adding them back again. I have tried removing the services then adding them back again. I have done the same for the ingress as well.
I have also tried setting up the entire cluster from a fresh AKS cluster from scratch from a new AKS cluster, all three images perform without any issues.
The Yaml for a application on the AKS network looks like:
- apiVersion: apps/v1
kind: Deployment
metadata:
name: testvuefe
spec:
replicas: 2
selector:
matchLabels:
app: testvuefe
template:
metadata:
labels:
app: testvuefe
spec:
nodeSelector:
kubernetes.io/os: linux
containers:
- name: testvuefe
image: testdocker.azurecr.io/testvuefe:latest
ports:
- containerPort: 80
resources:
requests:
cpu: '0'
memory: '0'
limits:
cpu: '128'
memory: 512G
volumeMounts:
- mountPath: "/fileShare"
name: volume
volumes:
- name: volume
persistentVolumeClaim:
claimName: aks-azurefile
- apiVersion: v1
kind: Service
metadata:
name: testvuefe-service
spec:
type: ClusterIP
ports:
- targetPort: 80
name: port80
port: 80
protocol: TCP
selector:
app: testvuefe
- apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: testvuefe-ingress
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/health-probe-path: /user
appgw.ingress.kubernetes.io/cookie-based-affinity: "true"
spec:
rules:
- host: test.wbsoft.co.kr
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: testvuefe-service
port:
number: 80
As this issue as occurred once on a cluster, I need to understand what is causing these issues so that it does not happen during production. It would also be great if a solution can be found for the issue.

React App in Kubernetes is not connecting properly

I'm new to Kubernetes and I'm trying to deploy a React app to my cluster. Here's the basic info:
Docker Desktop, single-node Kubernetes cluster
React development frontend, exposing port 3000
Node.js/Express backend, exposing port 8080
NGINX Ingress Controller, serving my React frontend on "localhost:3000" and routing my Fetch API requests (fetch("localhost:3000/api/...", OPTIONS)) to the backend (which works)
I am having an issue when opening the React app. The Ingress Controller correctly routes to the app but the 3 bundles (bundle.js, main.chink.js, the third one which I don't remember) aren't loaded. I get the following error:
GET http://localhost/static/js/main.chunk.js net::ERR_ABORTED 404 (Not Found) ingress (one example)
I understand why this error happens. The Ingress Controller correctly routes the traffic but only loads the index.html file. In this file, there are calls to 3 scripts (referring to the bundles) which aren't loaded. I understand the error, the files don't get sent to the browser so the index.html file can't load them in, but do not know how to fix it.
Does anyone have any suggestions? de and then pulled from Docker Hub. Does anybody know what a possible solution could be? For example, does deploying the build/ folder (built React app using "npm run build") fix this? Do I have to use nginx inside my Dockerfile to build the container?
Ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: titanic-ingress
#labels:
#name: titanic-ingress
spec:
ingressClassName: nginx
rules:
- host: localhost
http:
paths:
- path: /
pathType: Exact
backend:
service:
name: titanicfrontendservice
port:
number: 3000
- path: /api
pathType: Exact
backend:
service:
name: titanicbackendservice
port:
number: 8080
Ingress controller deployment yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress
namespace: nginx-ingress
spec:
replicas: 1
selector:
matchLabels:
app: nginx-ingress
template:
metadata:
labels:
app: nginx-ingress
#annotations:
#prometheus.io/scrape: "true"
#prometheus.io/port: "9113"
spec:
serviceAccountName: nginx-ingress
containers:
- image: nginx/nginx-ingress:1.10.0
imagePullPolicy: IfNotPresent
name: nginx-ingress
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
- name: readiness-port
containerPort: 8081
#- name: prometheus
#containerPort: 9113
readinessProbe:
httpGet:
path: /nginx-ready
port: readiness-port
periodSeconds: 1
securityContext:
allowPrivilegeEscalation: true
runAsUser: 101 #nginx
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
args:
- -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
- -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret
#- -v=3 # Enables extensive logging. Useful for troubleshooting.
- -report-ingress-status
- -external-service=nginx-ingress
#- -enable-prometheus-metrics
#- -global-configuration=$(POD_NAMESPACE)/nginx-configuration
Ingress controller service yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress
namespace: nginx-ingress
spec:
externalTrafficPolicy: Local
type: LoadBalancer
ports:
- port: 3000
targetPort: 80
protocol: TCP
name: http
- port: 443
targetPort: 443
protocol: TCP
name: https
selector:
app: nginx-ingress
TL;DR
Switch your pathType in both /api and / path to Prefix.
I've included some explanation with fixed Ingress resource below.
For the reproduction purposes I used the titanic manifests that you provided in the another question:
Github.com: Strobosco: Titanicfullstack
The issue with your configuration is with: pathType.
Using your Ingress resource with pathType: Exact showed me blank page.
Modifying your Ingress resource with pathType: Prefix solved the issue.
Side note!
The message: "Would you have survived the sinking of the Titanic?" showed.
The exact Ingress configuration should be following:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: titanic-ingress
spec:
ingressClassName: nginx
rules:
- host: localhost
http:
paths:
- path: /
pathType: Prefix # <-- IMPORTANT
backend:
service:
name: titanicfrontendservice
port:
number: 3000
- path: /api
pathType: Prefix # <-- IMPORTANT
backend:
service:
name: titanicbackendservice
port:
number: 8080
Why I think it happened?
Citing the official documentation:
Path types
Each path in an Ingress is required to have a corresponding path type. Paths that do not include an explicit pathType will fail validation. There are three supported path types:
ImplementationSpecific: With this path type, matching is up to the IngressClass. Implementations can treat this as a separate pathType or treat it identically to Prefix or Exact path types.
Exact: Matches the URL path exactly and with case sensitivity.
Prefix: Matches based on a URL path prefix split by /. Matching is case sensitive and done on a path element by element basis. A path element refers to the list of labels in the path split by the / separator. A request is a match for path p if every p is an element-wise prefix of p of the request path.
-- Kubernetes.io: Docs: Concepts: Services networking: Ingress: Path types (there are some examples on how the path matching is handled)
Ingress controller is forced to match only the / path leaving rest of the dependencies (apart from the index.html) on other paths like /super.jpg and /folder/awesome.jpg to error with 404 code.
Side note!
You can test yourself this behavior by spawning an nginx Pod and placing example files in it. After applying the Ingress resource with / and pathType: Exact you won't be able to request it through the Ingress controller but you could access them within the cluster.
I encourage you to check the additional resources:
Kubernetes.io: Docs: Concepts: Services networking: Ingress
Kubernetes.github.io: Ingress nginx: User guide: Ingress path matching
The issue with your ingress.yaml is that the route for your ui should be /* and placed below the backend routing. Also, check your routing for APIs
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: titanic-ingress
#labels:
#name: titanic-ingress
spec:
ingressClassName: nginx
rules:
- host: localhost
http:
paths:
- path: /api/*
pathType: Exact
backend:
service:
name: titanicbackendservice
port:
number: 8080
- path: /*
pathType: Exact
backend:
service:
name: titanicfrontendservice
port:
number: 3000

Azure AKS External Load Balancer Not Connecting to POD

I am trying to create a multicontainer pod for a simple demo. I have an app that is build in docker containers. There are 3 containers
1 - redis server
1 - node/express microservice
2 - node/express/react front end
All 3 containers are deployed successfully and running.
I have created a public load balancer, which is running without any errors.
I cannot connect to the front end from the public ip.
I have also run tcpdump in the frontend container and there is no traffic getting in.
Here is my yaml file used to create the deployment and service
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydemoapp
spec:
replicas: 1
selector:
matchLabels:
app: mydemoapp
template:
metadata:
labels:
app: mydemoapp
spec:
nodeSelector:
"beta.kubernetes.io/os": linux
containers:
- name: microservices-web
image: mydemocr.azurecr.io/microservices_web:v1
ports:
- containerPort: 3001
- name: redislabs-rejson
image: mydemocr.azurecr.io/redislabs-rejson:v1
ports:
- containerPort: 6379
- name: mydemoappwebtest
image: mydemocr.azurecr.io/jsonformwebtest:v1
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: mydemoappservice
spec:
type: LoadBalancer
ports:
- protocol: TCP
port: 80
targetPort: 3000
selector:
app: mydemoapp
This is what a describe of my service looks like :
Name: mydemoappservice
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"mydemoappservice","namespace":"default"},"spec":{"ports":[{"p...
Selector: app=mydemoapp
Type: LoadBalancer
IP: 10.0.104.159
LoadBalancer Ingress: 20.49.172.10
Port: <unset> 80/TCP
TargetPort: 3000/TCP
NodePort: <unset> 31990/TCP
Endpoints: 10.244.0.17:3000
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal EnsuringLoadBalancer 24m service-controller Ensuring load balancer
Normal EnsuredLoadBalancer 24m service-controller Ensured load balancer
One more weirdness is that when I run the docker container from the front end I can get a shell and run curl localhost:3000 and get some output but when I do it in the az container I get the following response after some delay
curl: (52) Empty reply from server
As to why this container works on my machine and not in azure is another layer to the mystery.
Referring from docs here the container need to listen on 0.0.0.0 instead of 127.0.0.1 because
any port which is listening on the default 0.0.0.0 address inside a
container will be accessible from the network
.

k8s expose virtual service with istio

I’ve download the Prometheus helm chart
https://github.com/helm/charts/tree/master/stable/prometheus
and deploy it to our cluster as-is and I was able to access prom ui via port-forwarding.
As we are using istio I want to configure it to access with host (lik external IP ) and I configure the following but it doesn’t work for me.
I mean if I put the host I don’t get anything in the browser, any idea what could be missing here ?
I dont see any exteranal-ip when running kubectl get svc -n mon ,
just internal-ip which doesnt help to our needs.
gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: http-gateway
namespace: mon
spec:
selector:
istio: ingressgateway
servers:
- hosts: mo-gateway.web-system.svc.cluster.local
port:
name: https-monitoring
number: 443
protocol: HTTPS
tls:
mode: SIMPLE
privateKey: /etc/istio/sa-tls/tls.key
serverCertificate: /etc/istio/sa-tls/tls.crt
virtual_service.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: prom-virtualservice
namespace: mon
spec:
hosts:
- mo-gateway.web-system.svc.cluster.locall
gateways:
- http-gateway
http:
- match:
- uri:
prefix: /prometheus
route:
- destination:
host: prometheus-server
port:
number: 80
Any idea why it doesnt works ?
Btw, If I just change the type of Prometheus to use LoadBalancer it work, I was able to get external-ip and use it but not on istio
istio is up-and-running ...

Kubernetes nginx ingress-controller on Azure not reachable

I am very new to Azure, Kubernetes, even Docker itself, and playing with the system to learn and evaluate for a possible deployment later. I have so far dockerized my services and successfully deployed them and made the web frontend publicly visible using a service with type: LoadBalancer.
Now I would like to add TLS termination and have learned that for that I am supposed to configure an ingress controller with the most commonly mentioned one being nginx-ingress-controller.
Strictly monkeying examples and then afterwards trying to read up on the docs I have arrived at a setup that looks interesting but does not work. Maybe some kind soul can point out my mistakes and/or give me pointers on how to debug this and where to read more about it.
I have kubectl apply'd the following file:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: default-http-backend-deployment
namespace: kube-system
spec:
template:
metadata:
labels:
app: default-http-backend
spec:
terminationGracePeriodSeconds: 60
containers:
- name: default-http-backend
image: gcr.io/google_containers/defaultbackend:1.0
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: default-http-backend-service
namespace: kube-system
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
app: default-http-backend
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-ingress-controller-conf
namespace: kube-system
data:
# enable-vts-status: 'true'
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-ingress-controller-deployment
namespace: kube-system
spec:
replicas: 1
template:
metadata:
labels:
app: nginx-ingress-controller
spec:
terminationGracePeriodSeconds: 60
containers:
- image: gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.13
name: nginx-ingress-controller
ports:
- containerPort: 80
hostPort: 80
- containerPort: 443
hostPort: 443
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
- --configmap=$(POD_NAMESPACE)/nginx-ingress-controller-conf
---
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress-controller-service
namespace: kube-system
spec:
ports:
- name: https
port: 443
protocol: TCP
targetPort: 443
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx-ingress-controller
sessionAffinity: None
type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
namespace: kube-system
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host:
http:
paths:
- path: /
backend:
serviceName: default-http-backend-service
servicePort: 80
This gave me two pods:
c:\Projects\Release-Management\Azure>kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
<some lines removed>
kube-system default-http-backend-deployment-3108185104-68xnk 1/1 Running 0 39m
<some lines removed>
kube-system nginx-ingress-controller-deployment-4106313651-v7p03 1/1 Running 0 24s
Also two new services. Note that I have also configured the default-http-backend-service with type: LoadBalancer, this is for debugging only. I have included my web-frontend which is called webcms:
c:\Projects\Release-Management\Azure>kubectl get services --all-namespaces
NAMESPACE NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
<some lines removed>
default webcms 10.0.105.59 13.94.250.173 80:31400/TCP 23h
<some lines removed>
kube-system default-http-backend-service 10.0.106.233 13.80.68.38 80:31639/TCP 41m
kube-system nginx-ingress-controller-service 10.0.33.80 13.95.30.39 443:31444/TCP,80:31452/TCP 37m
And finally an ingress:
c:\Projects\Release-Management\Azure>kubectl get ingress --all-namespaces
NAMESPACE NAME HOSTS ADDRESS PORTS AGE
kube-system nginx-ingress * 10.240.0.5 80 39m
No errors that I can immediately detect. I then went to the Azure Dashboard and looked at the loadbalancer and its rules and that looks good to my (seriously untrained) eye. I did not touch these, the loadbalancer and the rules were created by the system. There is a screenshot here:
https://qvwx.de/tmp/azure-loadbalancer.png
But unfortunately it does not work. I can curl my webcms-service:
c:\Projects\Release-Management\Azure>curl -v http://13.94.250.173
* Rebuilt URL to: http://13.94.250.173/
* Trying 13.94.250.173...
* TCP_NODELAY set
* Connected to 13.94.250.173 (13.94.250.173) port 80 (#0)
<more lines removed, success>
But neither default-http-backend nor the ingress work:
c:\Projects\Release-Management\Azure>curl -v http://13.80.68.38
* Rebuilt URL to: http://13.80.68.38/
* Trying 13.80.68.38...
* TCP_NODELAY set
* connect to 13.80.68.38 port 80 failed: Timed out
* Failed to connect to 13.80.68.38 port 80: Timed out
* Closing connection 0
curl: (7) Failed to connect to 13.80.68.38 port 80: Timed out
(ingress gives the same with a different IP)
If you read this far: Thank you for your time and I would appreciate any hints.
Marian
Kind of a trivial thing, but it'll save you some $$$: the default-http-backend is not designed to be outside facing, and thus should not have type: LoadBalancer -- it is merely designed to 404 so the Ingress controller can universally /dev/null traffic for Pod-less Services.
Moving slightly up the triviality ladder, and for extreme clarity: I do not think what you have is wrong but I did want to offer you something to decide if you want to change. Typically the contract for a Pod's container is to give an ideally natural-language name to the port ("http", "https", "prometheus", whatever) that maps into the port of underlying image. And then, set targetPort: in the Service to that name and not the number which offers the container the ability to move the port number without breaking the Service-to-Pod contract. The nginx-ingress Deployment's container:ports: agrees with me on this one.
Now, let's get into the parts that may be contributing to your system not behaving as you wish.
I can't prove it right now, but the presence of containers:hostPort: is suspicious without hostNetwork: true. I'm genuinely surprised kubectl didn't whine, because those config combinations are a little weird.
I guess the troubleshooting step would be to get on the Node (that is, something within the cluster which is not a Pod -- you could do it with a separate VM within the same subnet as your Node, too, if you wish) and then curl to port 31452 of the Node upon which the nginx-ingress-controller Pod is running.
kubectl get nodes will list all available Nodes, and
kubectl get -o json pod nginx-ingress-controller-deployment-4106313651-v7p03 | jq -r '.items[0].status.hostIP' should produce the specific VM's IP address, if you don't already know it. Err, I just realized from your prompt you likely don't have jq -- but I don't know PowerShell well enough to know its JSON-querying syntax.
Then, from any Node: curl -v http://${that_host_IP_value}:31452 and see what materializes. It may be something, or it may be the same "wha?!" that the LoadBalancer is giving you.
As for the Ingress resource specifically, again default-http-backend is not supposed to have an Ingress resource -- I don't know if it hurts anything because I've never tried it, but I'd also bet $1 it is not helping your situation, either.
Since you already have a known working Service with default:webcms, I would recommend creating an Ingress resource in the default namespace with pretty much exactly what your current Ingress resource is, but pointed at webcms instead of default-http-backend. That way your Ingress controller will actually have something to target which isn't the default backend.
If you haven't already seen it, adding --v=2 will cause the Pod to emit the actual diff of its nginx config change, which can be unbelievably helpful in tracking down config misunderstandings
I'm so sorry that you're having to do battle with Azure, Ingress controllers, and rough-around-the-edges documentation for your first contact with Kubernetes. It really is amazing when you get all the things set up correctly, but it is a pretty complex piece of machinery, for sure.

Resources