<p>I am learning Kubernetes, and have great trouble understanding the use of names/labels/selectors, and whether pod names and container names should be aligned.</p>

<p>I have a setup with a .NET Core MVC App, a PostgreSQL database and an Nginx reverse proxy.</p>

<p>It is working great with this docker-compose.yml:</p>

<pre><code>version: "3.7"

services:

  reverseproxy:
    build:
      context: ./Nginx
      dockerfile: ../Nginx.dockerfile
    ports:
      - "80:80"
      - "443:443"
    restart: always

  db:
    image: postgres:12.1-alpine
    environment:
      POSTGRES_PASSWORD: "mvcdbsecretpassword"

  mvc:
    depends_on:
      - reverseproxy
      - db
    build:
      context: .
      dockerfile: ./MyMvc.dockerfile
    environment:
      ConnectionStrings.MyMvc: "Host=db;Port=5432;Database=MyMvcDb;Username=postgres;Password=mvcdbsecretpassword"
    expose:
      - "5000"
    restart: always
</code></pre>

<p>The MVC app container is built and tagged and pushed to my Docker hub registry.
At startup it logs the connection string and it accepts the settings from the docker-compose file (obviously - it is working after all).</p>

<p>I have converted this into six kubernetes yaml files:</p>

<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
  labels:
    name: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:12.1-alpine
        env:
        - name: POSTGRES_PASSWORD
          value: mvcdbsecretpassword
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: postgres
  labels:
    app: postgres
spec:
  ports:
  - name: "postgres"
    port: 5432
    targetPort: 5432
  selector:
    app: postgres
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mvc
  labels:
    name: mymvc
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mymvc
  template:
    metadata:
      labels:
        app: mymvc
    spec:
      containers:
      - name: mvc
        image: mymvc:v2
        env:
          - name: ConnectionStrings.MyMvc
            value: "Host=postgres;Port=5432;Database=MyMvcDb;Username=postgres;Password=mvcdbsecretpassword"
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: mvc
  labels:
    app: mymvc
spec:
  ports:
  - name: "mvc"
    port: 5000
    targetPort: 5000
  selector:
    app: mymvc
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: reverseproxy-deployment
  labels:
    app: mymvc
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mymvc
  template:
    metadata:
      labels:
        app: mymvc
    spec:
      containers:
      - name: reverseproxy
        image: reverseproxy:v2
        ports:
        - containerPort: 80
        - containerPort: 443
---
apiVersion: v1
kind: Service
metadata:
  name: reverseproxy-service
  labels:
    app: mymvc
spec:
  ports:
  - name: "http"
    port: 80
    targetPort: 80
  - name: "https"
    port: 443
    targetPort: 443
  selector:
    app: mymvc
  type: LoadBalancer
</code></pre>

<p>As stated earlier I am very confused about when to use names and when to use labels.</p>

<p>A little guidance will be greatly appreciated.</p>

<p>EDIT: David Maze helped me understand the relationship between names, labels, and selectors. YAML files are updated accordingly.</p>

<p>I also added a service for the mvc app exposing port 5000.</p>

<p>Now the pods are no longer crashing, but I still have no access to the MVC app.</p>

<p>I guess, I should mention that I'm trying to make this run on Docker Desktop on a Windows 10 box.</p>

<p>The reverse proxy made sense in the Compose stack, but I am no longer sure, that it also makes sense in a Kubernetes Cluster, or if I should rather setup some kind of Ingress controller.</p>

<p>Could someone tell me, if it is even possible to test this setup on Docker Desktop?</p>

<p>Running <code>kubectl get nodes -o wide</code> reveals that there is no external IP, but I'm also not sure if the cluster is mirrored to localhost.</p>

TheRoadrunner
<p>There are three things that actually matter in this setup:</p>

<ol>
<li>When your "mvc" pod tries to connect to a host named <code>postgres</code> via the database connection string, that matches the <em>name</em> of a service.</li>
<li>In your two services, the <code>matchLabels:</code> need to be a subset of the <em>labels</em> of a pod; that is, the <code>spec</code>, <code>template</code>, <code>metadata</code>, <code>labels</code> of a deployment.</li>
<li>In the deployments, the <code>matchLabels</code> need to match the <em>labels</em> of the corresponding pod (right next to them in the YAML file).</li>
</ol>

<p>The other parts (the names of the deployments, the labels of the services and the top-level deployment objects) don't actually matter, but they can be useful for looking things up later.</p>

<p>In the example you show the service labels don't actually match.  You need to say <em>e.g.</em></p>

<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Service
spec:
  selector:
    matchLabels:
      app: reverseproxy # &lt;-- include "app:" key
</code></pre>

<p>If you look at output like <code>kubectl describe service reverseproxy-service</code> (using the object <em>name</em> at the command prompt) you should see a line like <code>Endpoints: &lt;none&gt;</code>; that indicates that the service isn't correctly binding to the matching pods, and a label mismatch like this is a frequent cause.</p>
