<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Mirantis - Medium]]></title>
        <description><![CDATA[Mirantis is the leading provider of open source, cloud native data center as-a-service, designed to help developers ship their most valuable code faster on any infrastructure. Headquartered in Silicon Valley, Mirantis powers innovation for Global 2k organizations - Medium]]></description>
        <link>https://medium.com/mirantis?source=rss----51179dc6acec---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Mirantis - Medium</title>
            <link>https://medium.com/mirantis?source=rss----51179dc6acec---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 30 May 2026 16:47:21 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/mirantis" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[The cloud native year-in-review]]></title>
            <link>https://medium.com/mirantis/the-cloud-native-year-in-review-d84716a14871?source=rss----51179dc6acec---4</link>
            <guid isPermaLink="false">https://medium.com/p/d84716a14871</guid>
            <category><![CDATA[security]]></category>
            <category><![CDATA[k0s]]></category>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[kubernetes]]></category>
            <dc:creator><![CDATA[Eric Gregory]]></dc:creator>
            <pubDate>Fri, 23 Dec 2022 15:53:19 GMT</pubDate>
            <atom:updated>2022-12-23T15:53:19.069Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*m8E22r61GA_62uaS.jpg" /></figure><p>Every Wednesday, Nick Chase and Eric Gregory from Mirantis go over the week’s cloud native and industry news on the <strong>Radio Cloud Native</strong> podcast.</p><p>This week, Eric and regular guest-host John Jainschigg discussed:</p><ul><li>New numbers on Kubernetes management challenges</li><li>Google releases open source OSV-Scanner</li><li>Major vulnerability in AWS Elastic Container Registry discovered and fixed</li><li>And more on the podcast, including a wide-ranging conversation about cloud native trends in 2022 and the year ahead</li></ul><p>You can watch the entire episode below or download the podcast from <a href="https://podcasts.apple.com/us/podcast/radio-cloud-native-with-eric-gregory-nick-chase/id1626524353">Apple Podcasts</a>, <a href="https://open.spotify.com/show/4cwNYluoRCvvFCgGHnOGqr?si=Sh0warzpR1i-G5Wewb7Cgg">Spotify</a>, or wherever you get your podcasts. If you’d like to tune into the next show live, <a href="https://www.linkedin.com/company/mirantis">follow Mirantis on LinkedIn</a> to receive our announcement of the next broadcast.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FIL-RAL4XKL0%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DIL-RAL4XKL0&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FIL-RAL4XKL0%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/cc0688db638221bd081aec846665f625/href">https://medium.com/media/cc0688db638221bd081aec846665f625/href</a></iframe><h3>New numbers on Kubernetes management challenges</h3><p><em>John</em>: Mike Vizard, <a href="https://containerjournal.com/features/datadog-report-surfaces-kubernetes-management-challenges/">writing</a> in <em>Container Journal</em> a few weeks back, did some analysis on the November update to DataDog’s several-years-running Container Report, pointing up some of the management challenges Kubernetes users are confronting. The report itself, though, is pretty upbeat: Kubernetes use among container-oriented organizations grew by 5%-ish between January and June of this year. Serverless is now used by 35% of these same orgs. Multi-cloud is also growing, and scaling — as you’d expect — with organization size: smaller orgs tend to have single clouds, but about 35% of orgs with 1000+ employees have more than one.</p><p>Ingress is now used by about 35% of orgs — DataDog itself points to Kubernetes Gateway API as the new frontier here: they’re waiting to see if Gateway displaces ingress or if the two functions will be used together. Service mesh is still way early — only 10% of orgs are using Istio and another roughly 2% are using LinkerD, with others seen more rarely.</p><p>The management challenges Vizard talks about in his piece are daunting, though. Most hosts are still running Kubernetes 1.21, which reached end of life earlier this year. A lot of hosts, moreover, are using an unsupported version of containerd to run containers, and about 30% of hosts are running version 1.4, which is also past EOL. The problem is that — for some orgs — staying with a Kubernetes version has become a necessity, at least in the short term, since existing apps will break because of changes in newer releases of the platform.</p><p>Organizations are doing a little better with access management this year — only 40%, down from 50% in 2019, are configuring Kubernetes with “overly permissive RBAC privileges.” But now the improvement seems to have flattened. We saw a few new projects at Kubecon, in October, that want to improve matters by making RBAC easier to use, and finer-grained. Hopefully they’ll have some success. We’d hope that widespread use of Open Policy Agent in DevSecOps frameworks will also start making this stat fall again.</p><p>Overall, the DataDog report is pretty illuminating. Vizard spoke with John Kendall, Senior Product Manager of Containers at Datadog, who said that the way forward was with managed Kubernetes services that provide organizations access to curated instances of the platform. Working with such services, Vizard pointed out, can both help solve the update challenge — for those who decide to update K8S — and make staying with a legacy version much less risky: the managed service provider taking responsibility for securing and continually optimizing. Managed services providers may also be able to help by updating existing cloud native applications to thrive on newer versions of Kubernetes, and by helping to build software supply chains that make it easier to create apps without Kubernetes version dependencies.</p><h3>Google releases open source OSV-Scanner</h3><p><em>Eric</em>: Google <a href="https://security.googleblog.com/2022/12/announcing-osv-scanner-vulnerability.html">announced</a> a new Go-based vulnerability scanner that utilizes the <a href="https://osv.dev/">OSV.dev</a> vulnerability database, fittingly titled <a href="https://github.com/google/osv-scanner">OSV-Scanner</a>.</p><p>Introduced in 2021, the OSV (or Open Source Vulnerabilities) project consists of…</p><ol><li>a standardized format for vulnerability data that is mapped to open source versioning schemes (and is basically just a standardized organizational pattern in JSON, so it’s human and machine readable)</li><li>a site and API that aggregates OSV-formatted data from distributed databases</li></ol><p>The new OSV-Scanner utility evaluates the whole open source dependency tree against its mega-database. The major advantage here is the breadth of package types covered, including not just Go but (deep breath) Linux kernel, Debian, Alpine, Android, npm, PyPI, crates.io, Maven, RubyGems, NuGet, Packagist, and OSS-Fuzz. Some estimates reckon OSV.dev as the largest existing vulnerability database, so it’s nice to have an automatable tool to leverage that.</p><p>According to Google’s announcement post, the next steps for the project should bring standalone CI actions and support for C/C++ vulnerabilities.</p><h3>Major vulnerability in AWS Elastic Container Registry discovered and fixed</h3><p><em>John</em>: Container registries are part of any container development setup, and are now critical to the broader ecosystem allowing for centralized storage and distribution of both private and public/commercial container images. And they’re not super-super complicated — there are lots of ways to improve container registry functionality, like encryption and image scanning and image signing and the ability to store artifact formats beyond container images. And there’s a vivid competitive market around such improvements. But basic registry stuff is typically imagined to be pretty solid.</p><p>Nah. AWS just fixed a severe vulnerability in their Elastic Container Registry that could have been bad news. Discovered by Gafnit Amiga, director of security research at Lightspin, the vuln would let bad people (and security researchers, okay) delete, update, and modify ECR public images, as well as fool with images stored in ECR belonging to private AWS accounts. ECR hosts many super-popular public images, including a “top six” that alone account for something like 13 billion cumulative pulls.</p><p>Amiga said that the vulnerability might allow an attacker to poison public images and then see these used widely, based on the trust created around public ECR’s commitment to verification. With essentially every detail of containers open to modification, potential attacks that could be launched via this supply chain vulnerability would be, she added: “limited only by the craftiness and goals of the adversary.”</p><p>Well, adversaries can sit back down, because the vulnerability was reported to AWS on November 12, and fixed by 24 hours later. AWS did a serious audit thereafter and are confident that the only activity associated with the issue was between accounts owned by the researcher. No other customer accounts were touched. Brava to Lightspin and this researcher. Side-note: women in cybersecurity are saving the world’s butt every day.</p><p><a href="https://podcasts.apple.com/us/podcast/radio-cloud-native-with-eric-gregory-nick-chase/id1626524353">Check out the podcast</a><em> for more of this week’s stories.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d84716a14871" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mirantis/the-cloud-native-year-in-review-d84716a14871">The cloud native year-in-review</a> was originally published in <a href="https://medium.com/mirantis">Mirantis</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Use Cluster API to Programmatically Configure and Deploy Kubernetes Clusters]]></title>
            <link>https://medium.com/mirantis/how-to-use-cluster-api-to-programmatically-configure-and-deploy-kubernetes-clusters-2efa80e7277f?source=rss----51179dc6acec---4</link>
            <guid isPermaLink="false">https://medium.com/p/2efa80e7277f</guid>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[lenses]]></category>
            <category><![CDATA[cluster-api]]></category>
            <dc:creator><![CDATA[Eric Gregory]]></dc:creator>
            <pubDate>Mon, 12 Dec 2022 14:52:46 GMT</pubDate>
            <atom:updated>2022-12-12T14:52:46.727Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*yGlA5ItqsDNTtwYw.jpg" /></figure><p>Kubernetes provides a portable, resilient, and resource-aware substrate for code that lives on the cloud. As Kubernetes has grown more popular, cloud infrastructure patterns have grown more complex: organizations may run hundreds or thousands of Kubernetes clusters at edge sites, and workloads may be orchestrated across multiple cloud providers or on-prem data centers.</p><p>That complexity calls for a unified interface through which clusters may be provisioned and managed, programmatically and at scale. The Kubernetes community created just such a tool in <strong>Cluster API</strong>.</p><p>In this tutorial, we will…</p><ul><li>Explain the fundamentals of Cluster API — what it is, how it works, and the core concepts that govern its design</li><li>Show you how to set up a local management cluster that will enable you to deploy new clusters to a cloud provider such as AWS</li><li>Walk you through the process of provisioning a workload cluster on AWS, and explain how to interact with that cluster via Lens</li></ul><p>This primer will serve as a foundation for further tutorials on Cluster API, in which we will show you how to control clusters across multiple environments and create a management interface that responds programmatically to your needs.</p><p>Ready? Let’s get started!</p><h3>What is the Cluster API?</h3><p>Cluster API is a tool for programmatically configuring and deploying Kubernetes clusters on a variety of different infrastructures. It is open source and maintained as a sub-project of Kubernetes; as of this writing it is in <a href="https://github.com/kubernetes-sigs/cluster-api/releases/tag/v1.2.4">version 1.2.4</a> and is regarded as production-ready.</p><p>For example, Cluster API is an upstream component of <a href="https://www.mirantis.com/software/mirantis-container-cloud/">Mirantis Container Cloud</a>, which uses the API to deliver a powerful infrastructure control plane managed through a single-pane GUI, while integrating management for components like Ceph storage.</p><h3>What is the purpose of Cluster API?</h3><p>Cluster API begins from a simple premise:</p><p>What if we could apply the “Kubernetes way of doing things” — that is, declarative configuration and deployment via API — to the <em>provisioning and management of clusters themselves</em>. What if spinning up a cluster to your specifications was functionally no different than deploying a Kubernetes resource like a Pod?</p><p>The answer to that “What if?” is that clusters would be <em>much</em> easier to configure and deploy programmatically and at scale — the same as any other Kubernetes resource. And that’s very useful for operators who want to manage lifecycles for hundreds or even thousands of clusters: whether those are edge clusters at retail locations, individual developer clusters, or clusters dedicated to sensitive, isolated workloads.</p><h3>How does Cluster API work?</h3><p>Cluster API not only gives us a way to <em>manage</em> Kubernetes clusters; it also <em>runs</em> on Kubernetes. Ultimately, Cluster API is simply a set of components that we install on a cluster and interact with in Kube-like style, through Kube-like tools.</p><p>This raises a sort of chicken-and-egg problem: as operators, we will need to provide a first cluster from which all of our other clusters will be initiated. This initial cluster may be temporary — a <strong>bootstrap cluster</strong> that will be discarded later — or it may serve an important and ongoing role as a <strong>management cluster</strong>.</p><p>In the conventions of Cluster API, the management cluster is one of two essential cluster types:</p><ul><li><strong>Management clusters</strong>: These clusters are responsible for the creation and oversight of other clusters through Cluster API. They are your agents for infrastructure management, and in that respect are a bit of an oddity — they’re probably not running application workloads like a normal Kubernetes cluster, but instead focusing entirely on provisioning, monitoring, and managing other clusters.</li><li><strong>Workload clusters</strong>: These are the clusters that will actually handle application workloads for your users — the business-as-usual clusters that do exactly what you would expect a Kubernetes cluster to do, running microservices and handling requests.</li></ul><p>This framework should sound familiar — it is, of course, reminiscent of the manager and worker <em>nodes</em> within a given Kubernetes cluster.</p><p>In any case, to get started with Cluster API, we need only furnish a few prerequisites:</p><ul><li><strong>An initial cluster</strong>: This is the starting cluster we will need to create the rest, and it can live in a lot of different places — on any number of clouds or on our local machine.</li><li><strong>kubectl</strong>: You’ll need the kubectl CLI installed on your workstation and all set to control your initial cluster.</li><li><strong>A provider</strong>: “Provider” is Cluster API’s abstraction for the infrastructure on which your newly created clusters will run. That might mean the big public cloud providers such as AWS, Azure, and Google Cloud, but it could also refer to more specialized providers such as Equinix Metal or DigitalOcean, or a host infrastructure such as OpenStack.</li></ul><p>With these pieces in place, we will be able to configure and create clusters at scale entirely programmatically.</p><p>Indeed, if you were so inclined, you could use the clusters you provision with Cluster API to run Cluster API components and provision yet another cluster. You can see, then, why the Cluster API logo is three turtles with Kubernetes logos on their shells: it’s Kubernetes <a href="https://en.wikipedia.org/wiki/Turtles_all_the_way_down">turtles all the way down</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/196/0*uXjGrO6sBwjnczQH" /></figure><h3>Deploying a cluster with Cluster API</h3><p>In this walkthrough, we will use a <strong>local development cluster</strong> as our <strong>management cluster</strong>, and we will deploy a <strong>workload cluster</strong> to <strong>AWS</strong>.</p><p>You can launch a local development cluster with Lens Desktop Kubernetes (a feature of Lens Pro), the Lens for Docker Desktop extension, Minikube, or another dev cluster implementation of your choice. Go ahead and start your local cluster now.</p><p>Next we’ll install the clusterctl command line tool. Download the binary from GitHub (making sure to grab the correct binary for your system):</p><pre>% curl -L https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.2.4/clusterctl-darwin-amd64 -o clusterctl</pre><p>From the same directory, use chmod to modify permissions so the binary is executable.</p><pre>% chmod +x ./clusterctl</pre><p>Put the clusterctl binary in your PATH.</p><pre>% sudo mv ./clusterctl /usr/local/bin/clusterctl</pre><p>The clusterctl CLI tool should be installed now. In a moment, we’re going to use it to initialize our local Kubernetes cluster as a management cluster. But before we do, we need to do some configuration for the provider to which we intend to deploy workload clusters — in this case, AWS.</p><h3>Initializing the management cluster for AWS</h3><p>We <em>could </em>configure for multiple providers, at this point, and clusterctl would enable us to manage all of them — enabling us to create and manage hybrid/multi-cloud architecture from a single interface. But for this primer, we’ll keep things simple and stick to a single provider.</p><p>Now, in order to do our AWS configuration, we’re going to download another CLI tool called clusterawsadm that will help us generate a CloudFormation stack with appropriate IAM resources. (CloudFormation is an AWS tool for infrastructure-as-code automation.) We’ll install this tool exactly the same way we did with clusterctl — again, verifying that you have the right binary for your system:</p><pre>% curl -L https://github.com/kubernetes-sigs/cluster-api-provider-aws/releases/download/v1.5.0/clusterawsadm-darwin-amd64 -o clusterawsadm<br>% chmod +x clusterawsadm<br>% sudo mv clusterawsadm /usr/local/bin</pre><p><strong>Note</strong>: The rest of this walkthrough uses AWS credentials and, once a workload cluster is deployed, will incur some costs if you follow along — proceed advisedly! Make sure to use the credentials for an IAM user with policies that make sense for you.</p><p>The clusterawsadm tool draws on a set of environment variables in order to run its configuration. Now we’ll use the export command to define those environment variables:</p><pre>% export AWS_REGION=us-east-1<br>% export AWS_ACCESS_KEY_ID=&lt;Your access key&gt;<br>% export AWS_SECRET_ACCESS_KEY=&lt;Your secret access key&gt;<br>% export AWS_SESSION_TOKEN=&lt;Session token&gt;</pre><p>Note: the session token is only necessary if you’re using multi-factor authentication.</p><p>With those environment variables defined, we can use clusterawsadm to generate our CloudFormation stack:</p><pre>% clusterawsadm bootstrap iam create-cloudformation-stack</pre><p>The system will return…</p><pre>Attempting to create AWS CloudFormation stack cluster-api-provider-aws-sigs-k8s-io</pre><p>…and it might take a moment. When it’s done, you’ll get a completion notification for various resources that looks like this:</p><pre>AWS::IAM::Role            |nodes.cluster-api-provider-aws.sigs.k8s.io                                            |CREATE_COMPLETE</pre><p>Now we’ll create another environment variable — this one with our newly-created credentials, base64-encoded.</p><pre>% export AWS_B64ENCODED_CREDENTIALS=$(clusterawsadm bootstrap credentials encode-as-profile)</pre><p>And finally, three last environment variables which will be required to specify details about our new workload clusters. <br>For the SSH key, you’ll need to actually <em>have</em> a key pair named default — alternatively, change the value here to an existing key pair. If you need to create an SSH key pair, you can do that on the <strong>Key pairs</strong> page found under <strong>Network &amp; Security</strong> in the EC2 menu.</p><pre>​​% export AWS_SSH_KEY_NAME=default<br>% export AWS_CONTROL_PLANE_MACHINE_TYPE=t3.large<br>% export AWS_NODE_MACHINE_TYPE=t3.large</pre><p>That’s it for our AWS-specific configuration. Now we’re ready to initialize our local cluster as a management cluster — with resources for deploying clusters to the provider AWS.</p><pre>% clusterctl init --infrastructure aws</pre><p>Your output should look something like this:</p><pre>Fetching providers<br>Installing cert-manager Version=&quot;v1.9.1&quot;<br>Waiting for cert-manager to be available...<br>Installing Provider=&quot;cluster-api&quot; Version=&quot;v1.2.4&quot; TargetNamespace=&quot;capi-system&quot;<br>Installing Provider=&quot;bootstrap-kubeadm&quot; Version=&quot;v1.2.4&quot; TargetNamespace=&quot;capi-kubeadm-bootstrap-system&quot;<br>Installing Provider=&quot;control-plane-kubeadm&quot; Version=&quot;v1.2.4&quot; TargetNamespace=&quot;capi-kubeadm-control-plane-system&quot;<br>Installing Provider=&quot;infrastructure-aws&quot; Version=&quot;v1.5.0&quot; TargetNamespace=&quot;capa-system&quot;<br> <br>Your management cluster has been initialized successfully!</pre><p>Before we move on, let’s take a moment to look at what we’ve done. If we take a look at our namespaces, we’ll see that we have several new namespaces in our management cluster dedicated to Cluster API tooling:</p><pre>% kubectl get ns<br>NAME                                STATUS   AGE<br>capd-system                         Active   43h<br>capi-kubeadm-bootstrap-system       Active   43h<br>capi-kubeadm-control-plane-system   Active   43h<br>capi-system                         Active   43h<br>cert-manager                        Active   43h</pre><p>We’ve also got quite a few new Custom Resource Definitions (CRDs). Here are a select handful:</p><pre>% kubectl get crds<br>NAME                                                             CREATED AT<br>clusterclasses.cluster.x-k8s.io                                  2022-10-17T19:19:36Z<br>clusterissuers.cert-manager.io                                   2022-10-17T19:18:31Z<br>clusterresourcesetbindings.addons.cluster.x-k8s.io               2022-10-17T19:19:36Z<br>clusterresourcesets.addons.cluster.x-k8s.io                      2022-10-17T19:19:36Z<br>clusters.cluster.x-k8s.io                                        2022-10-17T19:19:36Z<br>machinedeployments.cluster.x-k8s.io                              2022-10-17T19:19:37Z<br>machinehealthchecks.cluster.x-k8s.io                             2022-10-17T19:19:37Z<br>machinepools.cluster.x-k8s.io                                    2022-10-17T19:19:37Z<br>machines.cluster.x-k8s.io                                        2022-10-17T19:19:38Z<br>machinesets.cluster.x-k8s.io                                     2022-10-17T19:19:38Z<br>providers.clusterctl.cluster.x-k8s.io                            2022-10-17T19:18:17Z</pre><p>These CRDs are really the core mechanism of Cluster API, enabling the management cluster to handle, say, clusters and machines as Kubernetes resources.</p><h3>Creating and managing a workload cluster</h3><p>Now we’re ready to generate a workload cluster! We’ll use clusterctl’s generate cluster command to create a YAML manifest in our working directory — which we can use, in turn, to deploy our cluster.</p><pre>% clusterctl generate cluster test-cluster --infrastructure aws --kubernetes-version v1.25.0 --control-plane-machine-count=3 --worker-machine-count=3 &gt; test-cluster.yaml</pre><p>Note that we’re provisioning three worker machines for a reason: this is the requirement for minimum availability.</p><p>Let’s take a look at the YAML manifest we generated. Open the file with the code or text editor of your choice. You’ll see multiple manifests in this one file, defining several different kinds of resources:</p><ul><li>Cluster</li><li>AWSCluster</li><li>KubeadmControlPlane</li><li>AWSMachineTemplate</li><li>MachineDeployment</li><li>KubeadmConfigTemplate</li></ul><p>Here are several of those new Kubernetes resource types that we added through CRDs. Look through the manifests and observe how many of the details we’ve specified so far are rendered in the YAML. I’ll zoom in on just one of those manifests here:</p><pre>apiVersion: infrastructure.cluster.x-k8s.io/v1beta1<br>kind: AWSCluster<br>metadata:<br> name: test-cluster<br> namespace: default<br>spec:<br> region: us-east-1<br> sshKeyName: default</pre><p>Here we have an abstraction for an AWS-hosted cluster. It includes details like region and sshKeyName that we specified earlier through environment variables. And it’s linked to the resource instance of our more general Cluster object by name: test-cluster.</p><p>Let’s provision our workload cluster. From the directory where test-cluster.yaml is stored:</p><pre>% kubectl apply -f test-cluster.yaml</pre><p>Your output should look something like this:</p><pre>cluster.cluster.x-k8s.io/test-cluster created<br>awscluster.infrastructure.cluster.x-k8s.io/test-cluster created<br>kubeadmcontrolplane.controlplane.cluster.x-k8s.io/test-cluster-control-plane created<br>awsmachinetemplate.infrastructure.cluster.x-k8s.io/test-cluster-control-plane created<br>machinedeployment.cluster.x-k8s.io/test-cluster-md-0 created<br>awsmachinetemplate.infrastructure.cluster.x-k8s.io/test-cluster-md-0 created<br>kubeadmconfigtemplate.bootstrap.cluster.x-k8s.io/test-cluster-md-0 created</pre><p>Now we can use kubectl to manage those custom resource types. We can run…</p><pre>% kubectl get clusters<br>NAME           PHASE         AGE  <br>test-cluster   Provisioned   30s</pre><p>…and this gives us a view of all our clusters managed by Cluster API. We can get more granular and view all of our machines:</p><pre>% kubectl get machines<br>NAME                               CLUSTER          <br>test-cluster-control-plane-9cz2s   test-cluster</pre><p>Or perhaps we only wish to see our workload clusters on AWS:</p><pre>% kubectl get awsclusters<br>NAME           CLUSTER        READY<br>test-cluster   test-cluster   true</pre><p>The clusterctl CLI tool can help us gain even more insight. Run:</p><pre>% clusterctl describe cluster test-cluster</pre><p>The output should look like this:</p><pre>NAME                                                 READY  SEVERITY  REASON  SINCE                SINCE  MESSAGE                                                                               <br>Cluster/test-cluster                                 True                     28s                                                                                                               <br>├─ClusterInfrastructure                              True                     5m                                                                                                                <br>├─ControlPlane                                       True                     28s                                                                                           <br>│ └─3 Machines...                                    True                     2m                             <br>└─Workers                                                                                                                                                                                                       <br>  └─MachineDeployment/test-cluster-md-0              False  Warning           10m                             <br>    └─3 Machines...                                  True                     2m11s</pre><p>(I’ve omitted some detail for legibility here — the real output will give you names for all your nodes and more informative warnings for unready machines.)</p><p>Your results may not show the control plane as ready, but give it a couple of minutes and it should get there. The worker MachineDeployment will <strong>not</strong> become ready, however, because our new cluster is missing a final ingredient: a Container Network Interface (CNI) plugin to handle cluster networking.</p><p>Once a control plane node is ready, we can communicate with it — and our first order of business is to grab the <strong>kubeconfig for the worker cluster</strong>. The clusterctl CLI makes this easy:</p><pre>% clusterctl get kubeconfig test-cluster &gt; test-cluster.kubeconfig</pre><p>The command above will download a file called test-cluster.kubeconfig to our current working directory. Now we can <em>use </em>that kubeconfig to manage our new worker cluster, and the first thing we will do is add the open source <a href="https://www.tigera.io/project-calico/">Calico</a> CNI plugin, which provides network connectivity between workloads:</p><pre>% kubectl --kubeconfig=./test-cluster.kubeconfig \<br>  apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/calico.yaml</pre><p>Here, we’re telling kubectl to use the kubeconfig in our working directory and to apply to that cluster — our new workload cluster — the <a href="https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/calico.yaml">manifest</a> for Calico, which we’re grabbing from <a href="https://github.com/projectcalico/calico">GitHub</a>.</p><p>If you check out the Calico YAML, or simply skim the console output, you’ll see that we’re adding a pile of Custom Resource Definitions, a Controller, and several other resources:</p><pre>poddisruptionbudget.policy/calico-kube-controllers created<br>serviceaccount/calico-kube-controllers created<br>serviceaccount/calico-node created<br>configmap/calico-config created<br>customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created<br>customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created<br>clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created<br>clusterrole.rbac.authorization.k8s.io/calico-node created<br>clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created<br>clusterrolebinding.rbac.authorization.k8s.io/calico-node created<br>daemonset.apps/calico-node created<br>deployment.apps/calico-kube-controllers created</pre><p>Now that we’ve added Calico, the worker nodes in our workload cluster should quickly become ready:</p><pre>% clusterctl describe cluster test-cluster</pre><p>The output for a fully ready cluster:</p><pre>NAME                                                   READY  SEVERITY  REASON  SINCE                                                                                <br>Cluster/test-cluster                                   True                     4m48s                                                                                         <br>├─ClusterInfrastructure                                True                     9m20s                                                                                         <br>├─ControlPlane                                         True                     4m48s                                                                                         <br>│ └─3 Machines...                                      True                     6m20s       <br>└─Workers                                                                                                                                                                                  <br>  └─MachineDeployment/test-cluster-md-0                True                     78s                                                                                           <br>    └─3 Machines...                                    True                     6m31s</pre><p>At this point, we’re fully operational, and we can use the workload cluster’s kubeconfig to do whatever we need to do on the cluster.</p><p>For ongoing interaction with the cluster, we could continue to specify the kubeconfig with kubectl, or merge it with our local kubeconfig and switch contexts, but one of the easier ways to hop between cluster contexts is using <strong>Lens</strong>.</p><p>After <a href="https://www.mirantis.com/blog/getting-started-with-lens/">downloading and starting Lens</a>, simply click on the <strong>plus sign</strong> in the lower-right corner and select <strong>Sync kubeconfig</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/522/0*g5dhPnLO_tYGqSec" /></figure><p>Now you can easily switch between clusters and manage your workload clusters, <a href="https://www.mirantis.com/blog/getting-started-with-lens/">install charts with a few clicks via Lens’ Helm interface</a>, or just as easily <a href="https://www.mirantis.com/blog/5-things-you-didn-t-know-you-could-do-with-lens/">set up a Prometheus monitoring stack</a>.</p><p>Here we can see all of our nodes organized for easy monitoring and management:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*WYn7DtZbZbB6rvfd" /></figure><p>When we’re done with the workload cluster, the clean-up is mercifully easy:</p><pre>% kubectl delete cluster test-cluster<br>cluster.cluster.x-k8s.io &quot;test-cluster&quot; deleted</pre><p>That brings us to the end of this introductory primer, but it’s by no means the end of what you can do with Cluster API. In future walkthroughs, we’ll show you how to programmatically control clusters in other environments, and how to create a hybrid environment that is programmatically responsive to your needs.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2efa80e7277f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mirantis/how-to-use-cluster-api-to-programmatically-configure-and-deploy-kubernetes-clusters-2efa80e7277f">How to Use Cluster API to Programmatically Configure and Deploy Kubernetes Clusters</a> was originally published in <a href="https://medium.com/mirantis">Mirantis</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Technical Learning Curves: Not All Have Equal Value]]></title>
            <link>https://medium.com/mirantis/technical-learning-curves-not-all-have-equal-value-852f38106e96?source=rss----51179dc6acec---4</link>
            <guid isPermaLink="false">https://medium.com/p/852f38106e96</guid>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[learning]]></category>
            <dc:creator><![CDATA[John Jainschigg]]></dc:creator>
            <pubDate>Tue, 09 Aug 2022 20:15:56 GMT</pubDate>
            <atom:updated>2022-08-09T20:15:56.552Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jseh3jiOW3u3GAzbVkvH6Q.png" /></figure><p>Tech folks love to learn. This is a good thing. Climbing up steep learning curves is an absolute requirement for success in IT, DevOps, software development, and allied fields.</p><p>Of course, that’s true in other parts of the organization, as well. Business, Sales, and Marketing leaders don’t reach the C-suite unless they’re constantly learning. Once there, their impact strongly reflects their willingness to keep on digging deep.</p><p>But there are differences between Tech and Managerial approaches to learning.</p><p>In my experience, managerial learning tends to focus on business relevant issues. Leaders study how to communicate differentiating benefits better; how to build category dominance. They read about how to quantify business progress and improve business processes. The best surround themselves with smart and trusted counselors inside and outside the orgs they serve, and depend on these coaches to keep them focused, challenging them with new ideas and directions for learning.</p><p>Even when executives dip into theory, they tend to concentrate on what’s business-relevant: that is, unpacking business culture, or understanding macro-scale phenomena that influence business growth and survival. lt was a CEO, for example, who first pointed me in the direction of <a href="https://en.wikipedia.org/wiki/Nassim_Nicholas_Taleb">Nicholas Taleb’s </a>explorations of disruption and resilience (“Black Swan,” “Antifragile,” and so on), and <a href="https://en.wikipedia.org/wiki/Daniel_Kahneman">Daniel Kahneman’s</a> work on modes of thinking (notably “Thinking Fast and Slow”) — all material I’ve used, over the past decade, to build better clouds and applications.</p><p>Technical learning should be results-focused, too. And sometimes it is. In fact, what’s arguably the most powerful mechanism for results-focus, category creation, business growth, and wealth creation of the late 20th/early 21st centuries emerged from tech: “commoditize your complements.” That’s shorthand for two things:</p><ul><li>“Focus on what’s truly business-relevant and open up to let others do everything else.”</li><li>“Help make the things that you don’t do, and upon which you depend, as cheap as possible.”</li></ul><p>The actual technique is much older; as old as the idea of standardized parts and supply chains (which dates back to the dawn of mechanized manufacturing). More recent poster children for “commoditize your complements” were IBM and Microsoft, whose open hardware architecture and non-exclusive OS licenses ushered in modern computing, with its vast ecosystem of competing software and hardware makers.</p><p><a href="https://www.joelonsoftware.com/2002/06/12/strategy-letter-v/">Software engineer and StackOverflow co-founder Joel Spolsky’s famous 2002 blog</a> popularized the phrase, and Spolsky also used it to explain phenomena like “Why is IBM paying people to contribute to open source projects?” <em>Answer: Because IBM was, at the time, repositioning as an IT consultancy, so their complements were software components. Ergo, they invested in helping other folks build and provide this software at low- or no cost.</em></p><p>These days, you see “commoditize your complements” at work everywhere in tech — not least in the flood of “rent, don’t own” SaaS solutions and cloud technologies we all use every day.</p><h3>But failure modes remain</h3><p>And yet … tech orgs often still fall into failure modes like “not manufactured here disease,” where engineers feel they can’t trust “outsiders” to deliver parts of a product or service.</p><p>This can lead to misallocation of time, effort, headspace, and headcount — as engineers study and train, and orgs hire and tool up to design, build, and manage parts of a solution stack (like OpenStack and/or Kubernetes) that are <em>technically required</em> for many use-cases, but (in all their details) <em>not business-essential</em>.</p><p>Especially with respect to complex cloud platforms, the line between “technically required” and “business essential” can seem blurry, even (maybe especially) to sophisticated experts.</p><p><a href="https://www.mirantis.com/blog/technical-learning-curves-not-all-have-equal-value?utm_source=organic%20social&amp;utm_medium=medium%20blog&amp;utm_campaign=global-medium-blog">Read the rest of this article on the Mirantis blog</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=852f38106e96" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mirantis/technical-learning-curves-not-all-have-equal-value-852f38106e96">Technical Learning Curves: Not All Have Equal Value</a> was originally published in <a href="https://medium.com/mirantis">Mirantis</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[No more moats: Hardening cloud native security]]></title>
            <link>https://medium.com/mirantis/no-more-moats-hardening-cloud-native-security-3fab25ed04b9?source=rss----51179dc6acec---4</link>
            <guid isPermaLink="false">https://medium.com/p/3fab25ed04b9</guid>
            <category><![CDATA[zero-trust]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[kubernetes-security]]></category>
            <dc:creator><![CDATA[Eric Gregory]]></dc:creator>
            <pubDate>Wed, 13 Jul 2022 20:32:25 GMT</pubDate>
            <atom:updated>2022-07-13T20:32:25.261Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*j9BHHwC4byvn0q6F.jpg" /></figure><p>A recent <a href="https://www.cncf.io/blog/2021/12/20/new-slashdata-report-5-6-million-developers-use-kubernetes-an-increase-of-67-over-one-year/">SlashData report</a> with the Cloud Native Computing Foundation found a 67% year-over-year increase in Kubernetes adoption–but it’s clear that security practices aren’t keeping pace. For example, organizations such as Tesla have experienced <a href="https://redlock.io/blog/cryptojacking-tesla">cryptojacking attacks</a> on their Kubernetes clusters because of misconfigured components. In June 2022, <a href="https://www.infosecurity-magazine.com/news/misconfigured-kubernetes-exposed/">security analysts estimated</a> that more than 900,000 Kubernetes clusters are improperly exposed to the open Internet, creating an unnecessary attack vector and opportunity for data leakage.Kubernetes enables organizations to achieve High Availability and resilience, but at the cost of complexity that can lead to serious vulnerabilities if a team doesn’t have experience standing up a cluster.</p><p>Beyond the inherent complexity, cloud native computing requires a dramatic change in thinking about security. A cloud native environment is fundamentally different from traditional data centers, in that it is usually distributed and designed to run many containerized workloads. The <strong>castle-and-moat</strong> thinking that predominated in classical data center security — treating the network perimeter as a moat and the network as a secure stronghold — simply doesn’t cut it anymore (if it ever did).</p><p>In fact, operating with those metaphors is apt to put your systems at risk, even in a traditional data center. Fortunately, cloud native security means we must act as if there <em>is</em> no perimeter, proceeding with a presumption of “<strong>zero trust</strong>.” That means monitoring and validating <em>everything</em> within your system–not only users and devices, but software components, including the dependencies of dependencies within every containerized microservice. A minimum viable cloud native security strategy means creating a <strong>secure software supply chain</strong>.</p><p>That may sound daunting, but there is good news. Kubernetes is a highly resource-aware and extensible system, and the Kubernetes ecosystem includes a range of components to support a secure software supply chain and other security measures. This can help you incorporate four key elements of Kubernetes security:</p><ol><li>Private container registries (and scanning)</li><li>RBAC and secure CI/CD</li><li>Software Bill of Materials (SBOM)</li><li>Disaster recovery measures</li></ol><h3>Private container registries (and scanning)</h3><p>In Kubernetes, workloads are based on container images. Additionally, software is often built on the foundations of existing container images for common components like programming languages or web frameworks.</p><p>In other words, container images are essential building blocks. But like any other element in your system, they can’t be trusted. Original container images should be signed and verified. Existing container images should never be drawn from public registries like Docker Hub, which are vulnerable to tampering and malware–one discovery firm found over 4 million Docker Hub images with vulnerabilities open to exploitation.</p><p>Instead, organizations should rely on private <a href="https://www.mirantis.com/cloud-native-concepts/understanding-containers/what-is-a-container-registry/">container registries</a> with robust image signing and registry scanning capabilities. A private registry enables you to use Role-Based Access Control (RBAC) to determine who can use and update container images. It helps you to validate the software that flows out of the registry–and if you have a good registry scanner, you can run regular scans against a CVE database to ensure that there are no known vulnerabilities lurking in your images.</p><p>There are a number of options for private registries available. <a href="https://goharbor.io/">Harbor</a> is an open source private registry option in the CNCF ecosystem, while <a href="https://www.mirantis.com/blog/how-mirantis-secure-registry-protects-your-deployments-across-the-software-lifecycle">Mirantis Secure Registry</a> provides a supported option for enterprises, with RBAC and registry scanning.</p><h3>RBAC and secure CI/CD</h3><p><strong>Role-based Access Control (RBAC)</strong> applies to more than your private container registry. It should be enforced across a Kubernetes cluster. Fortunately, Kubernetes makes that relatively easy, enabling you to define specific roles using the principle of least privilege — meaning any user should have only as much system privilege as they require for their function. Kubernetes namespaces give you a way to enforce separation based on team or other variables, while still permitting controlled access to shared resources.</p><p>Of course, workflows are a bigger issue than individual users and the resources to which they have access. It is a good idea to implement policy-as-code to enforce security policies as part of a security-conscious CI/CD process. There are a number of powerful tools to help you manage workflows with Kubernetes, but it’s important that you evaluate them for security concerns. For example, <a href="https://argoproj.github.io/">Argo</a> is a popular suite of open source tools in the CNCF ecosystem that help to automate, observe, and manage deployment, but it poses <a href="https://argo-cd.readthedocs.io/en/stable/security_considerations/">serious security considerations</a> that users need to evaluate carefully, implementing mitigations or workarounds as appropriate.</p><p>A thoughtful approach to CI/CD can both avoid vulnerabilities and help to harden security. Tools such as Mirantis Secure Registry can support workflow automation with features such as automatic image promotion based on security validation, reducing the opportunity for human error.</p><p><em>Read the rest of this article </em><a href="https://www.mirantis.com/blog/no-more-moats-hardening-cloud-native-security"><em>at the Mirantis blog</em></a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3fab25ed04b9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mirantis/no-more-moats-hardening-cloud-native-security-3fab25ed04b9">No more moats: Hardening cloud native security</a> was originally published in <a href="https://medium.com/mirantis">Mirantis</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing Pods (and other Kubernetes objects)]]></title>
            <link>https://medium.com/mirantis/introducing-pods-and-other-kubernetes-objects-96ab8739ed3f?source=rss----51179dc6acec---4</link>
            <guid isPermaLink="false">https://medium.com/p/96ab8739ed3f</guid>
            <category><![CDATA[kubernetes-pods]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[kubernetes-object]]></category>
            <dc:creator><![CDATA[Eric Gregory]]></dc:creator>
            <pubDate>Fri, 17 Jun 2022 18:40:31 GMT</pubDate>
            <atom:updated>2022-06-17T18:40:30.973Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZO4duXZ6g8ZJCZrnYouc3w.png" /></figure><p><em>One of the biggest challenges for implementing cloud native technologies is learning the fundamentals — especially when you need to fit your learning into a busy schedule. In this series, we’ll break down core cloud native concepts, challenges, and best practices into short, manageable exercises and explainers, so you can learn five minutes at a time.</em></p><p>In the <a href="https://www.mirantis.com/blog/the-architecture-of-a-kubernetes-cluster">last lesson</a>, we investigated the architecture of a Kubernetes cluster, including the major components of the control plane and worker nodes, as well as common architectural patterns for a cluster. Today, we’ll start to break down the core abstractions that organize activity on the cluster — starting with Pods.</p><p><strong>Table of Contents</strong></p><ol><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-what-is-kubernetes?utm_source=organic+social&amp;utm_medium=medium+blog&amp;utm_campaign=global-medium-blog">What is Kubernetes?</a></li><li><a href="https://www.mirantis.com/blog/setting-up-a-kubernetes-learning-environment?utm_source=organic+social&amp;utm_medium=medium+blog&amp;utm_campaign=global-medium-blog">Setting Up a Kubernetes Learning Environment</a></li><li><a href="https://www.mirantis.com/blog/the-architecture-of-a-kubernetes-cluster?utm_source=organic+social&amp;utm_medium=medium+blog&amp;utm_campaign=global-medium-blog">The Architecture of a Kubernetes Cluster</a></li><li>Introducing Pods (and other Kubernetes objects) <strong>← You are here</strong></li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/288/0*6fLQftCIiqnQWaFg.png" /></figure><blockquote>These lessons assume a basic understanding of containers. If you need to get up to speed on Docker and containerization, download our free ebook, <a href="https://info.mirantis.com/mirantis-container-5-minute?utm_source=organic+social&amp;utm_medium=medium+blog&amp;utm_campaign=global-medium-blog"><strong>Learn Containers 5 Minutes at a Time</strong></a>. This concise, hands-on primer explains:</blockquote><blockquote>- The key concepts underlying containers — and how to use core tools like image registries</blockquote><blockquote>- Fundamentals of container networking that are essential for understanding container orchestrators like Kubernetes</blockquote><blockquote>- How to deploy containerized apps in single-container and multi-container configurations</blockquote><h4>What are Kubernetes objects?</h4><p>Kubernetes defines entities on the cluster as <strong>objects</strong>. The term functions the same way here as in most computer science contexts: Kubernetes objects are instances of a class with certain attributes, and they give us a model for abstraction. In Kubernetes, we’re using objects to define entities in our cluster — and more specifically, the desired state and status of those entities. Kubernetes is all about <em>intent</em>, and objects are the model we use to express our intent.</p><p>So far we’ve been a little vague — what kind of “entities” are we talking about here, and what might we intend for them? Well, let’s have a look. We can use kubectl to retrieve a complete list of abstractions that are manageable through the Kubernetes API. Start Minikube and then enter:</p><pre>% kubectl api-resources</pre><p>You should see a list something like this:</p><pre>NAME                             SHORTNAMES   APIVERSION<br>bindings                                       v1<br>componentstatuses                 cs           v1<br>configmaps                        cm           v1<br>endpoints                         ep           v1<br>events                            ev           v1<br>limitranges                       limits       v1<br>namespaces                        ns           v1<br>nodes                             no           v1<br>persistentvolumeclaims            pvc          v1<br>persistentvolumes                 pv           v1<br>pods                              po           v1<br>podtemplates                                   v1<br>replicationcontrollers            rc           v1<br>resourcequotas                    quota        v1<br>secrets                                        v1<br>serviceaccounts                   sa           v1<br>services                          svc          v1<br>mutatingwebhookconfigurations                  admissionregistration.k8s.io/v1<br>validatingwebhookconfigurations                admissionregistration.k8s.io/v1<br>customresourcedefinitions         crd,crds     apiextensions.k8s.io/v1<br>apiservices                                    apiregistration.k8s.io/v1<br>controllerrevisions                            apps/v1<br>daemonsets                        ds           apps/v1<br>deployments                       deploy       apps/v1<br>replicasets                       rs           apps/v1<br>statefulsets                      sts          apps/v1<br>tokenreviews                                   authentication.k8s.io/v1<br>localsubjectaccessreviews                      authorization.k8s.io/v1<br>selfsubjectaccessreviews                       authorization.k8s.io/v1<br>selfsubjectrulesreviews                        authorization.k8s.io/v1<br>subjectaccessreviews                           authorization.k8s.io/v1<br>horizontalpodautoscalers          hpa          autoscaling/v2<br>cronjobs                          cj           batch/v1<br>jobs                                           batch/v1<br>certificatesigningrequests        csr          certificates.k8s.io/v1<br>leases                                         coordination.k8s.io/v1<br>endpointslices                                 discovery.k8s.io/v1<br>events                            ev           events.k8s.io/v1<br>flowschemas                                    flowcontrol.apiserver.k8s.io/v1beta2<br>prioritylevelconfigurations                    flowcontrol.apiserver.k8s.io/v1beta2<br>nodes                                          metrics.k8s.io/v1beta1<br>pods                                           metrics.k8s.io/v1beta1<br>ingressclasses                                 networking.k8s.io/v1<br>ingresses                         ing          networking.k8s.io/v1<br>networkpolicies                   netpol       networking.k8s.io/v1<br>runtimeclasses                                 node.k8s.io/v1<br>poddisruptionbudgets              pdb          policy/v1<br>podsecuritypolicies               psp          policy/v1beta1<br>clusterrolebindings                            rbac.authorization.k8s.io/v1<br>clusterroles                                   rbac.authorization.k8s.io/v1<br>rolebindings                                   rbac.authorization.k8s.io/v1<br>roles                                          rbac.authorization.k8s.io/v1<br>priorityclasses                   pc           scheduling.k8s.io/v1<br>csidrivers                                     storage.k8s.io/v1<br>csinodes                                       storage.k8s.io/v1<br>csistoragecapacities                           storage.k8s.io/v1beta1<br>storageclasses                    sc           storage.k8s.io/v1<br>volumeattachments                              storage.k8s.io/v1</pre><p>Read through the complete list; some concepts like “nodes’’ should be familiar already. (We’ve removed the NAMESPACED and KIND columns for readability, but those are informative — review them, too!)</p><p>Kubernetes uses these abstractions to record our intent for system<strong> resources</strong> in a way that the API server can use in communicating with other components. A resource might have to do with workloads, services, policies, or another area of the system. These are essentially the classes that Kubernetes objects instantiate, and objects give us a common model for all of these resources.</p><p>In this series, we’ll focus on the most essential Kubernetes objects for developers. Let’s start with the elementary particle of Kubernetes: the Pod.</p><h4>What is a Pod?</h4><p>We can ask Kubernetes itself. In the terminal, enter:</p><pre>% kubectl explain pod</pre><p>You should get the following answer:</p><pre>KIND:     Pod<br>VERSION:  v1<br>DESCRIPTION:<br>Pod is a collection of containers that can run on a host. This resource is created by clients and scheduled onto hosts.<br>…</pre><p>So what does this mean? What is a Pod? A <strong>Pod</strong> is a unit of one or more containers that share a network namespace and storage volumes while running on a Kubernetes node. It is also Kubernetes’ most granular unit of scheduling for a containerized workload.</p><p>Up until now, we’ve used the general term “workload” to refer to the containerized processes that Kubernetes is orchestrating. As we’ve seen previously, the system assigns these workloads to worker nodes, the physical or virtual machines that are part of the cluster. These are the “hosts” in the definition above. But Kubernetes adds a conceptual layer <em>separating</em> the node from the container, and that’s the Pod.</p><p>Each Pod is assigned a unique IP address, so containers <em>within</em> the Pod can communicate with one another over localhost, and Pods can communicate with one another at fixed addresses.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*_txdWnHZuZ6O52qc" /></figure><p>These two ideas — the abstraction of the Pod, and each Pod having its own IP address — are fundamental, defining concepts for Kubernetes. They extend all the way back to the Borg project at Google, and they distinguish Kubernetes from other container orchestrators like Swarm. It is difficult to overstate the importance of the Pod; it contributes to the high scalability of Kubernetes, and it informs many of the networking patterns we will encounter going forward.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*saQZ7fZr_J1Jj8sR" /></figure><p>We’ve said that a Pod consists of “one or more containers.” The conventional wisdom on containers-per-Pod is that <strong>a given Pod should include only one container if possible</strong>, and multiple containers only when they are tightly coupled. Sometimes, your Kubernetes configuration may necessitate a multi-container Pod — when using an Istio service mesh, for example, each Pod will include a “sidecar” container in addition to the primary container. But we wouldn’t expect to see more than two or three containers in most Pods. (We’ll talk more about service meshes later, but if you’re ready to dive into the deep end now, you can check out <a href="https://info.mirantis.com/l/530892/2021-09-23/syxbh6">Service Mesh for Mere Mortals</a>.)</p><blockquote><strong>Testing the limits</strong><br> <br>“Sure,” I hear you say, “I understand that we <em>should</em> run no more than a handful of containers per Pod. But I’m a maverick! I want to test the limits. How many containers <em>can</em> we run in a Pod?”<br> <br>Short answer: There’s no defined limit. As of version 1.23, the <a href="https://kubernetes.io/docs/setup/best-practices/cluster-large/">Kubernetes docs</a> note that Kubernetes is designed for a maximum of 300,000 total containers. <em>Technically</em>, you could cram all of them into one Pod (assuming you could satisfy the underlying compute and storage requirements). But the docs also tell us that the system is designed for no more than 150,000 Pods, and that ratio is instructive. Operating at the extremities of scale, we would have two containers per Pod.</blockquote><p>By separating out the functionality of your containerized services into minimal viable units, you can scale those units — those services or microservices — independently. Say, for example, that you have a Pod representing the core functionality of the auth service on your web app, and you suddenly experience a barrage of sign-ups. The cluster can scale up your auth service as needed without needlessly duplicating other, unrelated elements of the app.</p><p><a href="https://www.mirantis.com/blog/introducing-pods-and-other-kubernetes-objects?utm_source=organic+social&amp;utm_medium=medium+blog&amp;utm_campaign=global-medium-blog"><em>Read the rest of this tutorial on the Mirantis blog</em></a><em>.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=96ab8739ed3f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mirantis/introducing-pods-and-other-kubernetes-objects-96ab8739ed3f">Introducing Pods (and other Kubernetes objects)</a> was originally published in <a href="https://medium.com/mirantis">Mirantis</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Architecture of a Kubernetes Cluster]]></title>
            <link>https://medium.com/mirantis/the-architecture-of-a-kubernetes-cluster-55a7748b1424?source=rss----51179dc6acec---4</link>
            <guid isPermaLink="false">https://medium.com/p/55a7748b1424</guid>
            <category><![CDATA[kubernetes]]></category>
            <dc:creator><![CDATA[Eric Gregory]]></dc:creator>
            <pubDate>Mon, 13 Jun 2022 13:41:38 GMT</pubDate>
            <atom:updated>2022-06-13T13:41:38.280Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Qt7v1Rwny4Xw-eQvZ90qjw.png" /></figure><p><em>One of the biggest challenges for implementing cloud native technologies is learning the fundamentals — especially when you need to fit your learning into a busy schedule.</em></p><p><em>In this series, we’ll break down core cloud native concepts, challenges, and best practices into short, manageable exercises and explainers, so you can learn five minutes at a time. These lessons assume a basic familiarity with the Linux command line and a Unix-like operating system — beyond that, you don’t need any special preparation to get started.</em></p><p>Last time, we set up a local Kubernetes environment and learned three different ways to interact with a cluster: the kubectl command line tool, the Kubernetes Web Dashboard, and the Lens IDE. In this lesson, we’ll explore the architecture of a Kubernetes cluster: its core components, how they interact with one another, and how we interact with them.</p><p><strong>Table of Contents</strong></p><ol><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-what-is-a-container/">What is a Container?</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-creating-observing-and-deleting-containers/">Creating, Observing, and Deleting Containers</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-build-image-from-dockerfile/">Build Image from Dockerfile</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-using-an-image-registry/">Using an Image Registry</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-volumes-and-persistent-storage/">Volumes and Persistent Storage</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-container-networking-and-opening-container-ports/">Container Networking and Opening Container Ports</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-running-a-containerized-app/">Running a Containerized App</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-multi-container-apps-on-user-defined-networks/">Multi-Container Apps on User-Defined Networks</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-docker-compose-and-next-steps">Docker Compose and Next Steps</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-what-is-kubernetes">What is Kubernetes?</a></li><li><a href="https://www.mirantis.com/blog/setting-up-a-kubernetes-learning-environment">Setting Up a Kubernetes Learning Environment</a></li><li>The Architecture of a Kubernetes Cluster <strong>←You are here</strong></li></ol><h4>Universal node components</h4><p>A Kubernetes cluster is made up of <strong>nodes</strong>. A node is simply a compute resource: it can be either a virtual or physical computer. Last time, we noted that our Minikube cluster is a single-node cluster, meaning that it consists of only one machine–typically a containerized or virtual machine running on our laptop or desktop.</p><p>Any node might need to step up and run workloads at any time, so the components required to make that happen are found on every node. Those components include:</p><ul><li><strong>A container runtime</strong>: This is the component that actually runs containers on a node. Today, Kubernetes supports a variety of runtimes, including containerd, CRI-O, Mirantis Container Runtime, and others.</li><li><strong>kubelet</strong>: A kubelet runs on every node and mediates between the control plane and the node in question, passing instructions to the container runtime — ”Start this workload!” — and then monitoring the status of the job. In order to facilitate the use of different runtimes, the kubelet communicates with the container runtime through a standardized Container Runtime Interface (or CRI).</li><li><strong>kube-proxy</strong>: Containerized workloads will need to be able to communicate with one another and the world outside the cluster. In other words, we’re going to have a lot of complicated networking going on! The kube-proxy component is a given node’s on-site network expert, managing network rules and connections on the node.</li></ul><p>We can visualize the fundamental components of a node like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*yBI_NHJFvlkkI25H" /></figure><h4>The Kubernetes control plane</h4><p>Nodes in Kubernetes clusters are assigned roles. Start your Minikube cluster and then run the following command:</p><pre>% kubectl get nodes</pre><p>You should see one node, named minikube, because this is a single-node cluster.</p><pre>NAME      STATUS   ROLES                  AGE     VERSION<br>minikube  Ready    control-plane,master   99s     v1.23.1</pre><p>Note the roles listed here. The minikube node is fulfilling the roles of control-plane and master. What does this mean?</p><p>The <strong>control plane</strong> coordinates the assignment of workloads — meaning containerized applications and services — to other nodes. If there are no other nodes in the cluster, as in our case, then the control plane node has to roll up its sleeves and get its hands dirty.</p><p>In a real-world, production-grade Kubernetes deployment, you will almost certainly have many nodes dedicated to running workloads — these are sometimes called <strong>worker nodes</strong>. Additionally, you will likely have multiple nodes in the control plane. (We’ll discuss this and other architectural patterns shortly.)</p><p>In such a scenario, the control plane is dedicated to ensuring that the current state of the cluster matches a pre-defined <strong>specification </strong>(or<strong> spec</strong>) — the <em>desired</em> state of the cluster. If our specification says that an instance of NGINX should be running, and the control plane learns that this isn’t the case, it sets out to assign the job and resolve the discrepancy.</p><blockquote><strong>A note on terminology.</strong><br> <br>So what about the master role? At the time of writing (as of release 1.24), it is interchangeable with control-plane. “Master” was the original term and is currently retained to maintain integrations between components that use the label, but the Kubernetes project plans to phase out the use of the word in this context. Eventually, the get nodes command above will only return control-plane for the node role.<br> <br>This change reflects an ongoing conversation about the suitability of the term “master” in the tech industry and broader culture; many technologies are moving away from the use of “master” terminology just as they moved away from the use of “slave” metaphors several years ago. GitHub, for example, now encourages defining a “main” branch rather than a “master” branch.<br> <br>The important thing to know when learning Kubernetes is that many third-party resources will discuss master nodes, though the term is no longer used in the Kubernetes documentation. These older resources are referring to nodes with the control-plane role, which we can think of as members of a cluster’s leadership committee. From here on out, we’ll use “control plane” to refer to this role.</blockquote><p>Ultimately, the control plane is a group of components that work together to make the actual state of the cluster match its spec. It responds to unexpected events out there in the real world (like a service going down), and it takes onboard any changes to the spec and assigns resources accordingly.</p><p>So what are these control plane components?</p><ul><li><strong>kube-apiserver</strong>: Last lesson, we said that every interaction with the cluster from tools like kubectl or Lens is mediated by the Kubernetes API. The <strong>API server</strong> exposes that API. The API server is the hub at the center of activity on the cluster, and the only control plane component that communicates directly with nodes running workloads. It also mediates communications between the various elements of the control plane.</li><li><strong>kube-scheduler</strong>: Put simply, the scheduler assigns work. When we tell the API server that we want to run a workload, the API server passes that request to the scheduler. The scheduler, in turn, consults with the API server to check the cluster status and then matches the new job to a node that meets the relevant resource requirements — whether that means hardware specifications or policy constraints.</li><li><strong>etcd</strong>: By default, the Kubernetes cluster runs on an assumption of ephemerality: any node and any workload may be spun up or stopped at any moment and replaced with an identical instance. The processes in the cluster are meant to match a specification, but they’re not expected to persist. This is a philosophy of <strong>statelessness</strong>, and it resembles the operational assumptions of containers themselves. But even if you’re running entirely stateless apps on your cluster, you will need to save and persist configuration and state data for the cluster, and etcd is the default means of doing so. It’s a key-value store that may be located inside the cluster <em>or</em> externally. Only the API server communicates directly with etcd. Note that etcd may be used outside the context of Kubernetes as well; it’s ultimately designed to serve as a distributed data store for relatively small amounts of data.</li><li><strong>kube-controller-manager </strong>and <strong>cloud-controller-manager</strong> are the watchdogs: they constantly monitor the state of the cluster, compare it to the spec, and initiate changes if the state and spec don’t match. The <strong>kube-controller-manager</strong> focuses on the upkeep of workloads and resources within the cluster, while the <strong>cloud-controller-manager</strong> is essentially a translator who speaks the language of your cloud provider–dedicated to coordinating resources from your cloud infrastructure. The cloud-controller-manager is an optional component designed for clusters deployed on the cloud.</li></ul><p>It’s tempting to think of the control plane as one or more “boss” nodes — that’s <em>essentially</em> true, but it’s a bit of a simplification that obscures important details. For example, etcd may be integrated into a control plane node <em>or</em> hosted externally. And as we’ve seen, a control plane node includes all of the components of a worker node. Typically, components of the control plane are initially installed on a single machine that doesn’t run container workloads…but that’s not a necessary or optimal configuration for every situation.</p><p>We can visualize a control plane node like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*j4-rNN-_TwXVzTJu" /></figure><p>Kubernetes is a distributed system designed in large part for resiliency. But as you can imagine, the control plane <em>could</em> become a single point of failure, especially if it is consolidated on one machine. For this reason, the system offers a “High Availability” configuration, which is the recommended approach for production environments. A High Availability (or HA) cluster will include multiple replicas of the control plane node.</p><p>While one of the control plane nodes is the primary cluster manager, the replicas work constantly to remain in sync — and a load balancer can apportion traffic between the various replicas of the API server as needed. Similarly, if duplicates of etcd are sitting on multiple control plane nodes (or an external host), they form a collective that runs its own consensus mechanism to ensure uniformity between the members. These measures ensure that if a control plane node goes down, there are replicas available to pick up the slack.</p><h4>Kubernetes architectural patterns</h4><p>Before we move on, let’s pause and take stock:</p><ul><li>A cluster is made up of one or more nodes.</li><li>Any node can run container workloads.</li><li>At least one node also has the components and role to act as the control plane and manage the cluster.</li><li>A cluster configured for High Availability (that is, production-grade resilience) includes replicas of all control plane components.</li></ul><p>Now, with all of these takeaways in place, let’s look at the big picture. What are the major architectural patterns for a Kubernetes cluster?</p><ul><li><strong>Single node</strong>: This pattern is what we have running right now via Minikube — a single cluster that fulfills the role of the control plane and runs any workloads we wish to run. This node walks and chews bubblegum at the same time: great for learning and development, but not suited for most production uses.</li><li><strong>Multiple nodes with a single node control plane</strong>: If we were to connect another node to our cluster as a dedicated worker node, then we would have a cluster with clear separation of responsibilities…but also a single point of failure in the control plane node.</li><li><strong>Multiple nodes with High Availability</strong>: When control plane components are replicated across multiple nodes, a cluster can achieve high levels of resiliency through strategic redundancy.</li></ul><p>For each of the models above, there are two major sub-variants: you might include the etcd data store on the control plane node(s) — a model called “stacked etcd” — or you might host etcd externally. High Availability configurations are possible with both of these approaches to the data store.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*rSThWKO-PAL40CEl" /></figure><p>As we’ve established, we’re currently working with a single-node cluster. Let’s get a little more information about that node and see how it correlates with what we’ve learned about Kubernetes architecture:</p><pre>% kubectl describe node minikube</pre><p>This command will give us a good deal of information on our node. Read through the output and look for references to the components we’ve discussed. A few sections to note:</p><pre>…<br>System Info:<br>  Machine ID:                 8de776e053e140d6a14c2d2def3d6bb8<br>  System UUID:                45bc9478-1425-44bd-a441-bfe282c0ce3e<br>  Boot ID:                    fbdac8bf-80eb-4939-86f1-fcf792c9468f<br>  Kernel Version:             5.10.76-linuxkit<br>  OS Image:                   Ubuntu 20.04.2 LTS<br>  Operating System:           linux<br>  Architecture:               amd64<br>  Container Runtime Version:  docker://20.10.12<br>  Kubelet Version:            v1.23.1<br>  Kube-Proxy Version:         v1.23.1<br>…</pre><p>My Minikube cluster is running on a container, so the information on my system refers to those details. Here we also find version numbers for our universal node components like the container runtime, kubelet, and kube-proxy.</p><p>Further down, we can find information on node resource usage. Note some of the entries in the “Non-terminated Pods” list:</p><pre>Namespace      Name                               CPU Requests  CPU Limits  Memory Requests<br> ---------      ----                               ------------  ----------  ---------------<br>  …      <br>  kube-system    etcd-minikube                      100m (2%)     0 (0%)      100Mi (1%)<br>  kube-system    kube-apiserver-minikube            250m (6%)     0 (0%)      0 (0%)<br>  kube-system    kube-controller-manager-minikube   200m (5%)     0 (0%)      0 (0%)<br>  kube-system    kube-proxy-9rjzk                   0 (0%)        0 (0%)      0 (0%)<br>  kube-system    kube-scheduler-minikube            100m (2%)     0 (0%)      0 (0%)<br>  …</pre><p>Here we find a number of familiar faces: our instances of the API server, etcd, the scheduler, and the controller manager — the whole control plane team — as well as kube-proxy.</p><p>But wait — what’s a pod? That’s a question for our next lesson. Now that we understand the architecture of a Kubernetes cluster, next time we’ll take a look at the core abstractions that govern activity on the cluster: Kubernetes Objects.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=55a7748b1424" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mirantis/the-architecture-of-a-kubernetes-cluster-55a7748b1424">The Architecture of a Kubernetes Cluster</a> was originally published in <a href="https://medium.com/mirantis">Mirantis</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Setting Up a Kubernetes Learning Environment]]></title>
            <link>https://medium.com/mirantis/setting-up-a-kubernetes-learning-environment-797d66f9491a?source=rss----51179dc6acec---4</link>
            <guid isPermaLink="false">https://medium.com/p/797d66f9491a</guid>
            <category><![CDATA[cloud-native]]></category>
            <category><![CDATA[kubernetes]]></category>
            <dc:creator><![CDATA[Eric Gregory]]></dc:creator>
            <pubDate>Tue, 07 Jun 2022 20:16:48 GMT</pubDate>
            <atom:updated>2022-06-07T20:16:48.760Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7bVN1Riyrq89lWVlJ-XawA.png" /></figure><p><em>One of the biggest challenges for implementing cloud native technologies is learning the fundamentals — especially when you need to fit your learning into a busy schedule.</em></p><p><em>In this series, we’ll break down core cloud native concepts, challenges, and best practices into short, manageable exercises and explainers, so you can learn five minutes at a time. These lessons assume a basic familiarity with the Linux command line and a Unix-like operating system — beyond that, you don’t need any special preparation to get started.</em></p><p>In the last lesson, we learned how Kubernetes orchestrates containers, who runs Kubernetes, and why. Today, we’ll set up a cluster on our local machine so we can get some hands-on experience.</p><h4>Table of Contents</h4><ol><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-what-is-a-container/">What is a Container?</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-creating-observing-and-deleting-containers/">Creating, Observing, and Deleting Containers</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-build-image-from-dockerfile/">Build Image from Dockerfile</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-using-an-image-registry/">Using an Image Registry</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-volumes-and-persistent-storage/">Volumes and Persistent Storage</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-container-networking-and-opening-container-ports/">Container Networking and Opening Container Ports</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-container-networking-and-opening-container-ports/">Container Networking and Opening Container Ports</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-running-a-containerized-app/">Running a Containerized App</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-multi-container-apps-on-user-defined-networks/">Multi-Container Apps on User-Defined Networks</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-docker-compose-and-next-steps">Docker Compose and Next Steps</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-what-is-kubernetes">What is Kubernetes?</a></li><li><strong>Setting Up a Kubernetes Learning Environment</strong> ←You are here</li></ol><h4>Choices when Accessing Clusters</h4><p>As we’ll see in the next few lessons, a Kubernetes cluster can run in a wide variety of configurations according to its use case. For learning purposes, we’re going to start with a<strong> single-node cluster</strong> on our local machine.</p><p>In the “real world,” clusters will typically spread across multiple nodes (or machines), each of which will have dedicated roles like managing the cluster or running workloads. In <em>this</em> case, everything will happen on a single node. That will give us a relatively straightforward development environment in which we can figure out the fundamentals, before progressing to more complex configurations.</p><p>The first decision we need to make is which version of Kubernetes to install. Because Kubernetes is an open source system, it has given rise to a variety of alternative <strong>distributions</strong> with their own particular use-cases, just as the Linux kernel is the foundation of numerous Linux distributions. The <strong>k0s</strong> (pronounced “kay-zeros”) project, for example, is a distribution designed for maximum resource efficiency, so it might run (and scale) anywhere from Raspberry Pis to powerful servers in public or private clouds. The creators of Kubernetes distributions usually try to maintain full compatibility with “upstream” Kubernetes — the original, baseline project — so that users can utilize the full suite of open source tooling developed by the community.</p><p>To get started, we’re going to use a distribution called <strong>Minikube</strong>, which is designed specifically for learning Kubernetes.</p><h4>Installing Minikube</h4><p>Minikube requires about 2GB of RAM to run, and it wants 20GB of disk space, which is the amount it assigns for cluster usage by default. (You can configure it to use as little as 2GB if you’re short on space.) It works on macOS, Linux, or Windows, and depending on its configuration, it runs on a container, a virtual machine, a combination of the two, or bare metal. Most people will be running it through VMs, containers, or both. If you have Docker Desktop or Docker Engine installed (as in our previous unit), then you’re ready to get started.</p><p>On an x86–64 machine running macOS with the Homebrew Package Manager, installation is a simple terminal command:</p><pre>% brew install minikube</pre><p>Users with other CPU architectures and operating systems will want to consult the <a href="https://minikube.sigs.k8s.io/docs/start/">official installation instructions</a> to download the version that is right for them.</p><p>Once Minikube is installed, make sure Docker is running, and then run the following command in the terminal:</p><pre>% minikube start</pre><p>You should see some friendly, emoji-illustrated status updates confirming that the system is running:</p><pre>👍  Starting control plane node minikube in cluster minikube<br>🚜  Pulling base image ...<br>🔄  Restarting existing docker container for &quot;minikube&quot; ...<br>🐳  Preparing Kubernetes v1.23.1 on Docker 20.10.12 ...<br>    ▪ kubelet.housekeeping-interval=5m<br>    ▪ Generating certificates and keys ...<br>    ▪ Booting up control plane ...<br>    ▪ Configuring RBAC rules ... <br>    ▪ Verifying Kubernetes components...<br>    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5<br>    ▪ Using image kubernetesui/dashboard:v2.3.1<br>    ▪ Using image k8s.gcr.io/metrics-server/metrics-server:v0.4.2<br>    ▪ Using image kubernetesui/metrics-scraper:v1.0.7<br>🌟  Enabled addons: storage-provisioner, metrics-server, default-storageclass, dashboard<br>🏄  Done! kubectl is now configured to use &quot;minikube&quot; cluster and &quot;default&quot; namespace by default</pre><p>We can confirm that Kubernetes is running with another command:</p><pre>% minikube kubectl get nodes</pre><p>This will list the nodes associated with our Kubernetes cluster. We should get a result that looks something like this:</p><pre>NAME      STATUS   ROLES                  AGE     VERSION<br>minikube   Ready    control-plane,master   5m26s   v1.23.1</pre><p>All right — we have one node, and that makes sense, because we said that this would be a single-node cluster. But what’s kubectl, and why am I using it?</p><p>For the answer, we need to break down an important element of Kubernetes development: <strong>cluster access</strong>.</p><p><a href="https://www.mirantis.com/blog/setting-up-a-kubernetes-learning-environment"><em>Read the rest of this tutorial on the Mirantis blog.</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=797d66f9491a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mirantis/setting-up-a-kubernetes-learning-environment-797d66f9491a">Setting Up a Kubernetes Learning Environment</a> was originally published in <a href="https://medium.com/mirantis">Mirantis</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[3 key elements to protect a Kubernetes cluster]]></title>
            <link>https://medium.com/mirantis/3-key-elements-to-protect-a-kubernetes-cluster-d9dc614cf952?source=rss----51179dc6acec---4</link>
            <guid isPermaLink="false">https://medium.com/p/d9dc614cf952</guid>
            <category><![CDATA[open-policy-agent]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[kubernetes-security]]></category>
            <category><![CDATA[mirantis]]></category>
            <dc:creator><![CDATA[Avinash Desireddy]]></dc:creator>
            <pubDate>Wed, 01 Jun 2022 03:08:25 GMT</pubDate>
            <atom:updated>2022-06-01T03:08:25.232Z</atom:updated>
            <content:encoded><![CDATA[<p><a href="https://www.helpnetsecurity.com/2022/04/26/kubernetes-security-principles/">Kubernetes</a> changed how we structure, deploy, and run our applications and became a de-facto standard for running infrastructure at scale. With the rapid adoption of container-based technologies, organizations are increasingly concerned about the security of their Kubernetes clusters. And they should be! While cloud and enterprise distributions provide solid security capabilities, they require tuning according to match organizational security needs.</p><p><em>Note: This blog post was originally published by HelpNetSecutiry. You can view the original post </em><a href="https://www.helpnetsecurity.com/2022/05/23/protect-kubernetes-cluster/"><em>here</em></a><em>.</em></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FcKZ3Di6tgFA%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DcKZ3Di6tgFA&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FcKZ3Di6tgFA%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/191417a7460061ecfbccbb555fd3aaf2/href">https://medium.com/media/191417a7460061ecfbccbb555fd3aaf2/href</a></iframe><p>In this article, I’ll go over three fundamental areas you need to consider to protect a Kubernetes cluster:</p><ul><li>Role-based access control (RBAC)</li><li>Open Policy Agent (OPA)</li><li>Network policies</li></ul><p>Let’s dive in!</p><h3>Role-based access control</h3><p>Let’s consider an organization with three application teams (Blue, Green, and Red). Because these teams are working on different products, they should be given different access to the Kubernetes cluster. For example, the Green and Red teams should not be able to see, access, or delete what the Blue team deployed.</p><p>RBAC is a way to control what Kubernetes resources users can access. While RBAC is enabled by default, you must configure it to use it.</p><p>There are 5 key elements to RBAC:</p><ul><li>Subjects — Users and processes</li><li>Resources — Objects to which access should be restricted</li><li>Verbs — Sets of operations that can be executed, often referred to as actions</li><li>Roles — An object that connects API Resources with Verbs</li><li>RoleBinding — An object that connects Roles with Subjects</li></ul><p>Let’s go back to our organization example and define a policy where only the Blue team can <em>create</em>, <em>delete</em> and <em>list</em> Pods, Deployments, and Services.</p><p>First, we create a Role object named <em>`role-blue`</em>, where we define the actions that can be performed on specific Kubernetes resources. In this specific case, the Role enables the actions <em>`create`</em>,<em> `delete`</em>, and <em>`list`</em> to be performed on the resources; <em>`pods`</em>,<em> `deployments`</em>, and <em>`services`</em>.</p><pre>apiVersion: rbac.authorization.k8s.io/v1<br>kind: Role<br>metadata:<br>  name: blue-role<br>  namespace: blue<br>rules:<br>- apiGroups: [&quot;&quot;, &quot;apps&quot;]<br>  resources: [&quot;pods&quot;, &quot;deployments&quot;, &quot;services&quot;]<br>  verbs: [&quot;create&quot;, &quot;delete&quot;, &quot;list&quot;]</pre><p>Next, we create a RoleBinding named <em>`blue-rb`</em>. This RoleBinding belongs to <em>`blue-ns`</em>, which links the above-created role <em>`role-blue`</em> with the blue team, named <em>`blue`</em>.</p><pre>apiVersion: rbac.authorization.k8s.io/v1<br>kind: RoleBinding<br>metadata:<br>  name: blue-rb<br>  namespace: blue-ns<br>subjects:<br>- apiGroup: rbac.authorization.k8s.io<br>  kind: User<br>  name: blue<br>roleRef:<br>  kind: Role<br>  name: blue-role<br>  apiGroup: rbac.authorization.k8s.io</pre><p>Once these resources are applied to the cluster, the users from the <em>`blue`</em> team will have the ability to perform the operations defined in <em>`role-blue`</em>.</p><h3>Open Policy Agent</h3><p>Open Policy Agent (OPA) is a general-purpose policy engine that unifies policy enforcement across the stack. Its high-level declarative language provides flexibility to specify policy as code. You can use OPA to enforce policies in Kubernetes, CI/CD pipelines, API gateways, and more. Let’s dive into how to use and implement it in Kubernetes.</p><p>The Kubernetes implementation of OPA is called <a href="https://github.com/open-policy-agent/gatekeeper">Gatekeeper</a>. It is designed and deployed as an AdmissionController that intercepts requests, processes them, and responds back with a permit or deny response.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*bqygoTcqlm4084sq.jpeg" /></figure><p>When permitted, the object gets deployed on the cluster; otherwise, the request will be rejected and feedback provided to the user. Administrators can define policies that instruct Kubernetes to limit the resources such as memory or CPU that containers or namespaces can consume, approve only containers based on images from specific registries, restrict NodePort service creation, or enforce standard naming.</p><p>For example, here is a sample template and constraint policy that allows creation of Pods only when ResourceQuota is configured in a namespace.</p><p><em>constraint.yaml</em></p><pre>apiVersion: constraints.gatekeeper.sh/v1beta1<br>kind: K8sRequiredResourceQuota<br>metadata:<br>  name: namespace-must-have-resourcequota<br>spec:<br>  match:<br>    kinds:<br>      - apiGroups: [&quot;&quot;, &quot;apps&quot;]<br>        kinds: [&quot;Pod&quot;]<br>    excludedNamespaces:<br>      - gatekeeper-system</pre><p><em>template.yaml</em></p><pre>apiVersion: templates.gatekeeper.sh/v1beta1<br>kind: ConstraintTemplate<br>metadata:<br>  name: k8srequiredresourcequota<br>  annotations:<br>  description: Requires Pods to launch in Namespaces with ResourceQuotas.<br>spec:<br>  crd:<br>    spec:<br>      names:<br>        kind: K8sRequiredResourceQuota<br>  targets:<br>    - target: admission.k8s.gatekeeper.sh<br>      rego: |<br>        package k8srequiredresourcequota<br>        violation[{&quot;msg&quot;: msg}] {<br>          input.review.object.kind = [&quot;Pod&quot;]<br>          requestns := input.review.object.metadata.namespace<br>          not data.inventory.namespace[requestns][&quot;v1&quot;][&quot;ResourceQuota&quot;]<br>          msg := sprintf(&quot;container &lt;%v&gt; could not be created because the &lt;%v&gt; namespace does not have ResourceQuotas defined&quot;, [input.review.object.metadata.name,input.review.object.metadata.namespace])<br>        }</pre><h3>Network policy</h3><p>Network policies are very similar to a regular firewall but differ in the sense that they are application-centric. When you define a network policy for an application, Kubernetes automatically applies those rules to the associated containers due to the highly dynamic environment in which containers are constantly created and terminated. Network policies control the flow of traffic to or from these containers.</p><p>By default, network traffic to and from Pods is not restricted. A good starting point is to set a deny-all traffic rule, and then only allow necessary traffic.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*4ujRHYY0aw-2x8lR.jpg" /></figure><p>By default, Kubernetes uses a flat network structure allowing any Pod to communicate with other Pods or Services in the cluster. In a cluster with multiple applications or multi-level applications, defense-in-depth plays a key role in securing the communication layer. Network policies allow us to achieve that.</p><p>Here is an <em>`app1-network-policy`</em> that applies the following rules in the <em>`blue`</em> namespace for the Pods with label <em>“role=db”</em>:</p><ul><li><em>[Ingress]</em> Allows connections from the ipBlock 172.17.0.0/24 on port 6379</li><li><em>[Ingress]</em> Allows connections from other pods if they are labeled as <em>“role=frontend”</em> and if they belong to the namespace with labels <em>“project=myproject”</em> on port 6379</li><li><em>[Egress]</em> The pod can communicate with other pods with IP range 10.0.0.0/24 on port 5978.</li></ul><pre>apiVersion: networking.k8s.io/v1<br>kind: NetworkPolicy<br>metadata:<br>  name: app1-network-policy<br>  namespace: blue<br>spec:<br>  podSelector:<br>    matchLabels:<br>      role: db<br>  policyTypes:<br>  - Ingress<br>  - Egress<br>  ingress:<br>  - from:<br>    - ipBlock:<br>        cidr: 172.17.0.0/24<br>    - namespaceSelector:<br>        matchLabels:<br>          project: myproject<br>    - podSelector:<br>        matchLabels:<br>          role: frontend<br>    ports:<br>    - protocol: TCP<br>      port: 6379<br>  egress:<br>  - to:<br>    - ipBlock:<br>        cidr: 10.0.0.0/24<br>    ports:<br>    - protocol: TCP<br>      port: 5978</pre><h3>Conclusion</h3><p>With RBAC, OPA, and network policies in place, you can protect your Kubernetes cluster by assuring that contributors have the proper access, that security policies are enforced, and that the network is tightly secured.</p><h3>About Mirantis</h3><p>Mirantis helps organizations ship code faster on public and private clouds. The company provides a public cloud experience on any infrastructure from the data center to the edge. With Lens and the Mirantis Cloud-Native Platform, Mirantis empowers a new breed of Kubernetes developers by removing infrastructure and operations complexity and providing one cohesive cloud experience for complete app and DevOps portability, a single pane of glass, and automated full-stack lifecycle management with continuous updates.</p><p>For more details, visit <a href="https://mirantis.com">https://mirantis.com</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d9dc614cf952" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mirantis/3-key-elements-to-protect-a-kubernetes-cluster-d9dc614cf952">3 key elements to protect a Kubernetes cluster</a> was originally published in <a href="https://medium.com/mirantis">Mirantis</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Multi-Container Apps on User-Defined Networks]]></title>
            <link>https://medium.com/mirantis/multi-container-apps-on-user-defined-networks-a799aae6e7cd?source=rss----51179dc6acec---4</link>
            <guid isPermaLink="false">https://medium.com/p/a799aae6e7cd</guid>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[containers]]></category>
            <dc:creator><![CDATA[Eric Gregory]]></dc:creator>
            <pubDate>Fri, 06 May 2022 13:59:03 GMT</pubDate>
            <atom:updated>2022-05-06T13:59:02.981Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*a0fdikG_S1WbXdAZ_T5aCA.png" /></figure><p><em>One of the biggest challenges for implementing cloud native technologies is learning the fundamentals — especially when you need to fit your learning into a busy schedule.</em></p><p><em>In this series, we’ll break down core cloud native concepts, challenges, and best practices into short, manageable exercises and explainers, so you can learn five minutes at a time. These lessons assume a basic familiarity with the Linux command line and a Unix-like operating system — beyond that, you don’t need any special preparation to get started.</em></p><p>Last time, we ran a web app–the open source wiki platform Mediawiki–from a container in a single-container configuration, with a persistent volume and a container port published to the host machine. That gave us a functional development environment, from which we could modify and build on the application.</p><p>But cloud native deployments often consist of applications spread across multiple containers. How can we connect the constituent parts of a single application once they’ve been containerized? In this tutorial, we’ll learn how to let containers talk to one another by deploying Mediawiki in a multi-container configuration on a user-defined network.</p><h3>Table of Contents</h3><ol><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-what-is-a-container/">What is a Container?</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-creating-observing-and-deleting-containers/">Creating, Observing, and Deleting Containers</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-build-image-from-dockerfile/">Build Image from Dockerfile</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-using-an-image-registry/">Using an Image Registry</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-volumes-and-persistent-storage/">Volumes and Persistent Storage</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-container-networking-and-opening-container-ports/">Container Networking and Opening Container Ports</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-running-a-containerized-app/">Running a Containerized App</a></li><li>Multi-Container Apps on User-Defined Networks←You are here</li></ol><h3>User-defined networks</h3><p>When containers reside on the default bridge network together, they should in theory be able to communicate with each other by name via Domain Name System (DNS)–but they can’t. Instead, those containerized apps need to know one another’s specific IP addresses to transmit data back and forth.</p><p>This is a deliberate restriction on the default bridge network. But why? Well, simply by virtue of being default, the docker0 bridge is apt to be a busy place, full of Docker containers without any necessary relationship to one another — without any need to communicate. That could be a security risk in a system predicated on isolation. So on the default bridge, Docker makes containers jump through a few extra hoops to communicate effectively.</p><p>When we have a group of containers that need to communicate, instead of using the default bridge we can place them in their own user-defined network. While this isn’t the only way to let containers communicate, it is the Docker-preferred way of doing things, since this creates a precisely scoped layer of isolation. We can create a user-defined network with the command:</p><pre>docker network create &lt;network name&gt;</pre><p>The -d (or --driver) argument for this command specifies a model for the new network: bridge, overlay, or a custom driver option added by the user.</p><ul><li><strong>Bridge networks</strong> allow containers within the network — all of which must be on the same Docker daemon host — to communicate with one another while isolating them from other networks.</li><li><strong>Overlay networks</strong> allow containers within the network — which may be spread across multiple Docker daemon hosts–to communicate with one another while isolating them from other networks. This driver is used by the container orchestrator Docker Swarm.</li><li><strong>Custom drivers</strong> allow for custom network rules.</li></ul><p>The bridge driver is the default, so if you don’t specify a driver, Docker will create a bridge network. The bridge driver is what we’ll be using in this lesson.</p><blockquote><strong>What about linking?</strong></blockquote><blockquote>Another way to name-based communication between containers on the default bridge is container linking, which involves creating manual links between containers using the --link argument. This was once the standard technique for connecting containers, and you’ll still see it used in the docs for many images. But Docker considers this a legacy option, which means that it is not recommended and may be disabled in the future; linking has been superseded by user-defined networks.</blockquote><h3>Exercise: A multi-container wiki using container networking</h3><p><strong>You can follow along in this video tutorial:</strong></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FtRqEJta6S10%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DtRqEJta6S10&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FtRqEJta6S10%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/cf12916289513d00d51c55acf924b7c7/href">https://medium.com/media/cf12916289513d00d51c55acf924b7c7/href</a></iframe><p><em>To follow the rest of the tutorial, </em><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-multi-container-apps-on-user-defined-networks/"><em>read the rest at the Mirantis blog</em></a><em>.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a799aae6e7cd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mirantis/multi-container-apps-on-user-defined-networks-a799aae6e7cd">Multi-Container Apps on User-Defined Networks</a> was originally published in <a href="https://medium.com/mirantis">Mirantis</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Run a Containerized App with Docker]]></title>
            <link>https://medium.com/mirantis/how-to-run-a-containerized-app-with-docker-e8f6518f3c86?source=rss----51179dc6acec---4</link>
            <guid isPermaLink="false">https://medium.com/p/e8f6518f3c86</guid>
            <category><![CDATA[docker]]></category>
            <dc:creator><![CDATA[Eric Gregory]]></dc:creator>
            <pubDate>Tue, 29 Mar 2022 20:12:43 GMT</pubDate>
            <atom:updated>2022-03-29T20:12:43.220Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/768/1*DTkVyG-YfkxE5aDyoBaIEg.png" /></figure><p><em>One of the biggest challenges for implementing cloud native technologies is learning the fundamentals — especially when you need to fit your learning into a busy schedule.</em></p><p><em>In this series, we’ll break down core cloud native concepts, challenges, and best practices into short, manageable exercises and explainers, so you can learn five minutes at a time. These lessons assume a basic familiarity with the Linux command line and a Unix-like operating system — beyond that, you don’t need any special preparation to get started.</em></p><p>In our last lesson, we defined some core concepts in container networking and learned how to publish container ports, opening a container’s services to traffic from the outside world. This time, we’re going to bring together most of what we’ve learned so far to run a containerized web app with persistent volumes and published ports: in this case, a knowledge-sharing <strong>wiki</strong> platform.</p><h3>Table of Contents</h3><ol><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-what-is-a-container/">What is a Container?</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-creating-observing-and-deleting-containers/">Creating, Observing, and Deleting Containers</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-build-image-from-dockerfile/">Build Image from Dockerfile</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-using-an-image-registry/">Using an Image Registry</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-volumes-and-persistent-storage/">Volumes and Persistent Storage</a></li><li><a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-container-networking-and-opening-container-ports/">Container Networking and Opening Container Ports</a></li><li>Running a Containerized App ←You are here</li></ol><h3>Bringing the pieces together</h3><p>Wikipedia is built on an open source platform called Mediawiki, and an official Docker image for the application is maintained on Docker Hub. That means it should be easy to get our own wiki running quickly — in less than five minutes, even!</p><p>The default architecture for this deployment is very straightforward: a single container for the application, which can either write data to a volume all on its own — the default configuration — or work in tandem with a second container running a production-grade database — the option you would want to use if you were taking this wiki to production, pushing it live for real-world use.</p><p>In this lesson, we’re going to start with a single-container configuration — but we won’t stop there. Next time, we’ll also explore how to link containers for a more production-ready configuration.</p><p>But we’re getting ahead of ourselves. For now, let’s focus on getting our wiki up and running!</p><h3>Exercise: A Wiki as a Containerized App</h3><p>Let’s start by <a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-volumes-and-persistent-storage/">creating a new volume</a> that will store the persistent data for our wiki:</p><pre>docker volume create wiki-data</pre><p>Now we’re going to run a Docker container based on the official Mediawiki image. We’ll call our new container solo-wiki since it’s going to run in a single-container configuration. We’ll also <a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-container-networking-and-opening-container-ports/">publish a port</a> so we can access the application on our host machine, and add our volume for persistent storage.</p><pre>docker run --name solo-wiki -v wiki-data:/wiki-data -p 8000:80 -d mediawiki</pre><p>Now when we visit localhost:8000 in our web browser, we should see a starting page for our wiki. But the app still needs to be set up. On the starting page, click “<strong>Complete the installation</strong>.”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*2IskZbn5SSA8NSId.png" /></figure><p>To follow the rest of the tutorial, <a href="https://www.mirantis.com/blog/cloud-native-5-minutes-at-a-time-running-a-containerized-app/">read the full post at the Mirantis blog</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e8f6518f3c86" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mirantis/how-to-run-a-containerized-app-with-docker-e8f6518f3c86">How to Run a Containerized App with Docker</a> was originally published in <a href="https://medium.com/mirantis">Mirantis</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>