<h2>We want to archieve the following:</h2>

<ul>
<li>Magento Shop running on Google Kubernetes</li>
<li>Deployment via config file (eg. stage.yaml, live.yaml) etc.</li>
<li>PHP 7.2</li>
<li>MySQL 5.6 / MariaDB</li>
<li>Redis</li>
<li>nginx:alpine</li>
<li>https</li>
<li>Persistent volume claims for Magento and MySQL</li>
</ul>

<p>I am learning kubernetes for a few weeks now but I am struggling with some design concepts and some basic questions came up.</p>

<p>I first tried docker-compose, than building docker images via Dockerfiles, stumbled over helm and kubectl. And now I came across building pods and building deployments. Now I know many different things but a real life example or some best practice knowledge would be appreciated. Google is great.. but it seems there is not just one way.</p>

<h3>1. Regarding Pods</h3>

<p>I understand, that pods should be able to be easily replaced / destroyed /recreated ... </p>

<p>Is it better to have a POD configuration like
- nginx container
- php container
- mysql container
- redis container
edit: as I just read, pods share an IP-Adress so it would make no sense to inlcude mysql or redis here, right?</p>

<p>or better one pod with a
- mysql container
and one pod with containers for
- nginx
- php</p>

<p>and another with a 
- redis container</p>

<h3>2. Mounting a persistent volume claim or a remote webroot like /var/www/html locally to work on.</h3>

<p>The content of the local webroot comes from a git repo.</p>

<h3>3. Handling of type: pod vs. type:deployment</h3>

<p>I can create a yaml file for defining the containers inside my pod (type:pod). But I also can define a deployment.yaml (type:deployment).</p>

<p>Do I have to reference my pod.yaml inside my deployment.yaml or does the deployment includes all pod configuration and replaces the pod.yaml?</p>

<blockquote>
  <p>Deployment via config file (eg. stage.yaml, live.yaml) etc.</p>
</blockquote>

<p>I've found <a href="https://helm.sh" rel="nofollow noreferrer">Helm</a> to work well for this.  A Helm "chart" can be deployed with a corresponding set of "values" in a YAML file, and these can be used to configure various parts of the overall deployment.</p>

<p>One useful part of Helm is that there is <a href="https://github.com/helm/charts" rel="nofollow noreferrer">a standard library of charts</a>.  Where you say you need MySQL, you can <code>helm install stable/mysql</code> and get a pre-packaged installation without worrying about the specific details of stateful sets, persistent volumes, <em>etc.</em></p>

<p>You'd package everything you suggest here into a single chart, which would have multiple (templated) YAML files for the different Kubernetes parts.</p>

<blockquote>
  <p>Handling of type: pod vs. type:deployment</p>
</blockquote>

<p>A deployment will create some (configurable) number of identical copies of a pod.  The pod spec inside the deployment spec contains all of the details it needs.  The 
deployment YAML replaces an existing pod YAML.</p>

<p>You generally don't directly create pods.  The upgrade lifecycle in particular can be a little tricky to do by hand, and deployments do all the hard work for you.</p>

<blockquote>
  <p>Is it better to have a POD configuration like...</p>
</blockquote>

<p>Remember that the general operation of things is that a deployment will create some number of copies of a pod.  When you have an updated version of the software, you'd push it to a Docker image repository and change the image tag in the deployment spec.  Kubernetes will launch additional copies of the pod with the new pod spec, then destroy the old ones.</p>

<p>The two fundamental rules here:</p>

<ol>
<li><p>If the components' lifecycles are different, they need to be in different deployments.  For example, you don't want to destroy the database when you update code, so these need to be in separate deployments.</p></li>
<li><p>If the number of replicas are different, they need to be in different deployments.  Your main service might need 3 or 5 replicas, depending on load; nginx just routes HTTP messages around and might only need 1 or 3; the databases can't be replicated and can only use 1.</p></li>
</ol>

<p>In the setup you show, I'd have four separate deployments, one each for MySQL, Redis, the nginx proxy, and the main application.</p>

<blockquote>
  <p>The content of the webroot comes from a git repo.</p>
</blockquote>

<p>The easiest way is to build it into an image, probably the nginx image.</p>

<p>If it's "large" (gigabytes in size) you might find it more useful to just host this static content somewhere outside Kubernetes entirely.  Anything that has static file hosting will work fine.</p>

<p>There's not to my knowledge a straightforward way to copy arbitrary content into a persistent volume without writing a container to do it.</p>

<hr>

<p>Your question doesn't mention Kubernetes services at all.  These are core, and you should read up on them.  In particular where your application talks to the two data stores, it would refer to the service and not the MySQL pod directly.</p>

<p>Depending on your environment, also consider the possibility of hosting the databases outside of Kubernetes.  Their lifecycle is <em>very</em> different from your application containers: you never want to stop the database and you really don't want the database's managed stored to be accidentally deleted.  You may find it easier and safer to use a bare-metal database setup, or to use a hosted database setup.  (My personal experience is mostly with AWS, and you could use RDS for a MySQL instance, Elasticache for Redis, and S3 for the static file hosting discussed above.)</p>
