<p>I'm new to K8s, I'll try minikube with 2 container running in a pod with this command:</p>

<pre><code>kubectl apply -f deployment.yaml
</code></pre>

<p>and this deployment.yml:</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code>apiVersion: v1
kind: Pod
metadata:
  name: site-home
spec:

  restartPolicy: Never

  volumes:
  - name: v-site-home
    emptyDir: {}

  containers:


  - name: site-web
    image: site-home:1.0.0
    ports:
    - containerPort: 80
    volumeMounts:
    - name: v-site-home
      mountPath: /usr/share/nginx/html/assets/quotaLago
  
  - name: site-cron
    image: site-home-cron:1.0.0
    volumeMounts:
    - name: v-site-home
      mountPath: /app/quotaLago</code></pre>
</div>
</div>
</p>

<p>I've a shared volume so if I understand I cannot use deployment but only pods (maybe stateful set?)</p>

<p>In any case I want to expose the port 80 from the container site-web in the pod site-home. 
In the official docs I see this for deployments:</p>

<pre><code>kubectl expose deployment hello-node --type=LoadBalancer --port=8080
</code></pre>

<p>but I cannot use for example:</p>

<pre><code>kubectl expose pod site-web --type=LoadBalancer --port=8080
</code></pre>

<p>any idea?</p>

<blockquote>
  <p>but I cannot use for example:</p>

<pre><code>kubectl expose pod site-web --type=LoadBalancer --port=8080
</code></pre>
</blockquote>

<p>Of course you can, however exposing a single <code>Pod</code> via <code>LoadBalancer</code> <code>Service</code> doesn't make much sense. If you have a <code>Deployment</code> which typically manages a set of <code>Pods</code> between which the real load can be balanced, <code>LoadBalancer</code> does its job. However you can still use it just for exposing a single <code>Pod</code>.</p>

<p>Note that your container exposes port <code>80</code>, not <code>8080</code> (<code>containerPort: 80</code> in your <code>container</code> specification) so you need to specify it as <code>target-port</code> in your <code>Service</code>. Your <code>kubectl expose</code> command may look like this:</p>

<pre><code>kubectl expose pod site-web --type=LoadBalancer --port=8080 --target-port=80
</code></pre>

<p>If you provide only <code>--port=8080</code> flag to your <code>kubectl expose</code> command it assumes that the <code>target-port</code>'s value is the same as value of <code>--port</code>. You can easily check it by yourself looking at the service you've just created:</p>

<pre><code>kubectl get svc site-web -o yaml
</code></pre>

<p>and you'll see something like this in <code>spec.ports</code> section:</p>

<pre><code>- nodePort: 32576
    port: 8080
    protocol: TCP
    targetPort: 8080
</code></pre>

<p>After exposing your <code>Pod</code> (or <code>Deployment</code>) properly i.e. using:</p>

<pre><code>kubectl expose pod site-web --type=LoadBalancer --port=8080 --target-port=80
</code></pre>

<p>you'll see something similar:</p>

<pre><code>  - nodePort: 31181
    port: 8080
    protocol: TCP
    targetPort: 80
</code></pre>

<p>After issuing <code>kubectl get services</code> you should see similar output:</p>

<pre><code>NAME                            TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)          AGE
site-web                              ClusterIP      &lt;Cluster IP&gt;   &lt;External IP&gt;           8080:31188/TCP         4m42s
</code></pre>

<p>If then you go to <code>http://&lt;External IP&gt;:8080</code> in your browser or run <code>curl http://&lt;External IP&gt;:8080</code> you should see your website's frontend.</p>

<p>Keep in mind that this solution makes sense and will be fully functional in cloud environment which is able to provide you with a real load balancer. Note that if you declare such <code>Service</code> type in <strong>Minikukbe</strong> in fact it creates <a href="https://kubernetes.io/docs/concepts/services-networking/service/#nodeport" rel="noreferrer">NodePort</a> service as it is unable to provide you with a real load balancer. So your application will be available on your Node's ( your Minikube VM's ) IP address on randomly selected port in range <code>30000-32767</code> (in my example it's port <code>31181</code>).</p>

<p>As to your question about the volume:</p>

<blockquote>
  <p>I've a shared volume so if I understand I cannot use deployment but
  only pods (maybe stateful set?)</p>
</blockquote>

<p>yes, if you want to use specifically <a href="https://kubernetes.io/docs/concepts/storage/volumes/#emptydir" rel="noreferrer">EmptyDir</a> volume, it cannot be shared between different <code>Pods</code> (even if they were scheduled on the same node), it is shared only between containers within the same <code>Pod</code>. If you want to use <code>Deployment</code> you'll need to think about another storage solution such as <a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/" rel="noreferrer">PersistenetVolume</a>.</p>

<hr>

<p>EDIT:</p>

<p>In the first moment I didn't notice the error in your command:</p>

<pre><code>kubectl expose pod site-web --type=LoadBalancer --port=8080
</code></pre>

<p>You're trying to expose non-existing <code>Pod</code> as your <code>Pod</code>'s name is <code>site-home</code>, not <code>site-web</code>. <code>site-web</code> is a name of one of your containers (within your <code>site-home</code> <code>Pod</code>). Remember: we're exposing <code>Pod</code>, not <code>containers</code> via <code>Service</code>.</p>

<blockquote>
  <p>I change 80->8080 but I always come to <code>error:kubectl expose pod
  site-home --type=LoadBalancer --port=8080 return:error: couldn't
  retrieve selectors via --selector flag or introspection: the pod has
  no labels and cannot be exposed</code> See <code>'kubectl expose -h'</code> for help
  and examples.</p>
</blockquote>

<p>The key point here is: <code>the pod has no labels and cannot be exposed</code></p>

<p>It looks like your <code>Pod</code> doesn't have any <code>labels</code> defined which are required so that the <code>Service</code> can select this particular <code>Pod</code> (or set of similar <code>Pods</code> which have the same label) from among other <code>Pods</code> in your cluster. You need at least one label in your <code>Pod</code> definition. Adding simple label <code>name: site-web</code> under <code>Pod</code>'s <code>metadata</code> section should help. It may look like this in your <code>Pod</code> definition:</p>

<pre><code>apiVersion: v1
kind: Pod
metadata:
  name: site-home
  labels:
    name: site-web
spec:
...
</code></pre>

<p>Now you may even provide this label as selector in your service however it should be handled automatically if you omit <code>--selector</code> flag:</p>

<pre><code>kubectl expose pod site-home --type=LoadBalancer --port=8080 --target-port=80 --selector=name=site-web
</code></pre>

<p><strong>Remember:</strong> in <strong>Minikube</strong> real load balancer cannot be created and instead of <code>LoadBalancer</code> <code>NodePort</code> type will be created. Command <code>kubectl get svc</code> will tell you on which port (in range <code>30000-32767</code>) your application will be available.</p>

<blockquote>
  <p>and `kubectl expose pod site-web --type=LoadBalancer
  --port=8080 return: Error from server (NotFound): pods "site-web" not found. Site-home is the pod, site-web is the container with the port
  exposed, what's the issue?</p>
</blockquote>

<p>if you don't have a <code>Pod</code> with name <code>"site-web"</code> you can expect such message. Here you are simply trying to expose non-existing <code>Pod</code>.</p>

<blockquote>
  <p>If I exposed a port from a container the port is automatically exposed
  also for the pod ?</p>
</blockquote>

<p>Yes, you have the port defined in Container definition. Your <code>Pods</code> automatically expose all ports that are exposed by the <code>Containers</code> within them.</p>
