Creating nginx pod to work on port other than 80

Hi,
I am trying to create a nginx pod which should server on port 8081 and not the default port 80.

I used below command but thats not working, can someone please help.

controlplane ~ ➜ k run nginx --image=nginx --port=8081
pod/nginx created

controlplane ~ :heavy_multiplication_x: k run curler --image=curlimages/curl – sleep 4800
pod/curler created

controlplane ~ ➜ k exec curler – curl -s 10.244.1.2:8081
command terminated with exit code 7

############# But it works on port 80 ##############
controlplane ~ :heavy_multiplication_x: k exec curler – curl -s 10.244.1.2:80

Welcome to nginx! html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; }

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

controlplane ~ ➜

nginx gets its port setting from its config file. If you want to change that, you need to mount a modified config file into the container at /etc/nginx/conf.d/default.conf to override the default file:

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

I think the question is more subtle and @rob_kodekloud answers sum it all up but allow me to further clarify.

When you deploy a pod like nginx the listening port for the service is defined in the configuration file within the pod, in this case it’s TCP 80. The imperative run command allows to define a --port but that in itself doesn’t change anything within the pod, it’s only a preparation to bind a service to it.
In fact --port exposes the service only if expose is set to true

--port=-1: The port that this container exposes.  If --expose is true, this is also the port used by the service that is created.

If you run:

kubectl run nginx --image=nginx --port=8081 --expose=true

You’ll get:

service/nginx created
pod/nginx create

If you run:
kubectl run nginx --image=nginx --port=8081

You’ll only get:
pod/nginx create

As the default behaviour is not to expose the pod.

So specifying the --port implies to also create a separate service afterwards like:
kubectl expose pod nginx --port=8081 --target-port=8081

On a setup like this:
Pods

NAME     READY   STATUS    RESTARTS   AGE     IP          NODE             NOMINATED NODE   READINESS GATES
curler   1/1     Running   0          6h38m   10.1.1.71   docker-desktop   <none>           <none>
nginx    1/1     Running   0          2m54s   10.1.1.74   docker-desktop   <none>           <none>

Services

NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE    SELECTOR
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP    7d5h   <none>
nginx        ClusterIP   10.100.82.148   <none>        8081/TCP   27s    run=nginx

You can curl/wget from the curler to the nginx pod directly via the 10.1.1.74 only on port 80 (unless you perform the change Rob suggests). At this level the service definition is irrelevant and so is the --port from the the imperative command.
On the same node a pod can communicate with another pod without using services (unless network policies or other iptables tricks are done)

When using the service instead (either the one created with the expose command or with expose=true in the imperative run) you’ll use the cluster IP and then the port becomes relevant. Behind the scenes I suppose iptables creates some NAT rules for it.

I hope this clarifies as Kubernetes networking isn’t trivial at all and does my head in all the time.