<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Adventures in a Cloud Native Landscape</title>
    <link>https://windsock.io/</link>
    <description>Recent content on Adventures in a Cloud Native Landscape</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Fri, 14 Mar 2025 14:04:56 +0000</lastBuildDate><atom:link href="https://windsock.io/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Web User Interfaces for Managing Flux GitOps Environments</title>
      <link>https://windsock.io/web-uis-for-managing-flux-gitops-environments/</link>
      <pubDate>Fri, 14 Mar 2025 14:04:56 +0000</pubDate>
      
      <guid>https://windsock.io/web-uis-for-managing-flux-gitops-environments/</guid>
      <description>&lt;p&gt;Whenever I hear a debate about the pros and cons of &lt;a href=&#34;https://argo-cd.readthedocs.io/en/stable/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Argo CD&lt;/a&gt; and &lt;a href=&#34;https://fluxcd.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Flux&lt;/a&gt; as preferred &lt;a href=&#34;https://opengitops.dev/#principles&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitOps&lt;/a&gt; solutions, invariably it&amp;rsquo;s Argo CD that &lt;a href=&#34;https://www.reddit.com/r/kubernetes/comments/1937tty/argo_cd_or_flux_cd_what_is_the_most_used_cicd_tool&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;wins out&lt;/a&gt;. Often, but not always, it&amp;rsquo;s Argo CD&amp;rsquo;s web user interface that is &lt;a href=&#34;https://www.reddit.com/r/devops/comments/1c7xvmc/comment/l0eebf7&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;cited&lt;/a&gt; as the big differentiator between the two tools. Now, I could (but shouldn&amp;rsquo;t) wax lyrical about the &lt;a href=&#34;https://phoenixnap.com/glossary/clickops&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;clickops&lt;/a&gt; approach being a potential anti-pattern to the GitOps way of doing things. GitOps tools use abstractions represented as Kubernetes config to model the environment;  an &lt;a href=&#34;https://argo-cd.readthedocs.io/en/stable/user-guide/application-specification/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Application&lt;/a&gt; or &lt;a href=&#34;https://argo-cd.readthedocs.io/en/stable/user-guide/application-set/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;ApplicationSet&lt;/a&gt;, a &lt;a href=&#34;https://fluxcd.io/flux/components/source/gitrepositories/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitRepository&lt;/a&gt;, a &lt;a href=&#34;https://fluxcd.io/flux/components/source/helmcharts/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;HelmChart&lt;/a&gt;, a &lt;a href=&#34;https://fluxcd.io/flux/components/kustomize/kustomizations/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Kustomization&lt;/a&gt;, and so on. Just like the Kubernetes config that represents the application that is to be managed using GitOps, the Gitops abstractions need to be expressed &lt;a href=&#34;https://github.com/open-gitops/documents/blob/v1.0.0/GLOSSARY.md#declarative-description&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;declaratively&lt;/a&gt; in &lt;a href=&#34;https://github.com/open-gitops/documents/blob/v1.0.0/GLOSSARY.md#state-store&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;immutable, versioned storage&lt;/a&gt; (such as a version control system, like Git), too. Otherwise, they will suffer the ambiguity and lack of reliability associated with &lt;a href=&#34;https://www.solarwinds.com/resources/it-glossary/configuration-drift&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;configuration drift&lt;/a&gt;. Clickops is fine if these abstractions are managed using GitOps principles, but not OK if they&amp;rsquo;re created in the cluster, in an imperative fashion through a web UI. Enough!&lt;/p&gt;
&lt;p&gt;There is an obvious attraction to a web UI for would be adopters set free in an unfamiliar environment. For developers, whose only want is to get their application deployed, having to get your head around the complexities of Kubernetes and the machinations of a GitOps tool, is an unnecessary distraction. A web UI that enables you to operate these environments, and to gain appropriate, timely feedback on deployments from, is all too valuable. This is the great upside to the web UI that Argo CD provides out-of-the-box. But, what about Flux?&lt;/p&gt;
&lt;p&gt;Flux, perhaps because of the clickops anti-pattern, doesn&amp;rsquo;t come bundled with a web UI like Argo CD&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. However, it has a feature-rich &lt;a href=&#34;https://fluxcd.io/flux/cmd/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;command line interface&lt;/a&gt; instead (as does &lt;a href=&#34;https://argo-cd.readthedocs.io/en/stable/user-guide/commands/argocd/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Argo CD&lt;/a&gt;, by the way), which enables the creation of the configuration for its abstractions, amongst other useful things. A comprehensive CLI is right up my Straße, but clearly it&amp;rsquo;s not for everyone, so what can you do to minimise your exposure to it, and still get an optimal experience with Flux? Well, all is not lost, because there are a few community-provided web UI solutions for Flux to try out!&lt;/p&gt;
&lt;h2 id=&#34;flux-plugin-for-headlamp&#34;&gt;
  Flux Plugin for Headlamp
  &lt;a class=&#34;heading-link&#34; href=&#34;#flux-plugin-for-headlamp&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://headlamp.dev/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Headlmap&lt;/a&gt; is a general, open-source web UI for Kubernetes, and is a &lt;a href=&#34;https://www.cncf.io/projects/headlamp/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;sandbox project&lt;/a&gt; of the Cloud Native Computing Foundation. It enables the management of Kubernetes clusters and the workloads deployed therein, and even has a map view (beta) of the objects and their relationships, much the same as can be found in Argo CD&amp;rsquo;s web UI. Headlamp is designed to be extensible through a plugin architecture, with individual plugins created as Javascript bundles. Currently, Headlamp has plugins for &lt;a href=&#34;https://prometheus.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Prometheus&lt;/a&gt;, &lt;a href=&#34;https://backstage.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Backstage&lt;/a&gt;, &lt;a href=&#34;https://cert-manager.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;cert-manager&lt;/a&gt;, &lt;a href=&#34;https://opencost.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;OpenCost&lt;/a&gt;, and Flux, amongst others. It&amp;rsquo;s a growing list.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://windsock.io/images/headlamp.png&#34; alt=&#34;headlamp&#34;&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://artifacthub.io/packages/headlamp/headlamp-plugins/headlamp_flux&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;plugin for Flux&lt;/a&gt; adds a sidebar entry for managing the objects that relate to Flux abstractions; things like a HelmRelease, a Kustomization, or an ImagePolicy. In tabular form, it provides the summary details of each object and its status, with the ability to drill down further to retrieve more granular information when needed. This allows for determining the state of the system without having to use the command line to interrogate the cluster directly.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s also possible to suspend reconciliation, or force an asynchronous sync with the &amp;lsquo;source&amp;rsquo; if required. Headlamp&amp;rsquo;s UI adapts to the permissions available to the authenticated user, according to the privileges afforded to the user via RBAC. Hence, users get to see and do only what their role permits them to see and do.&lt;/p&gt;
&lt;h2 id=&#34;weave-gitops&#34;&gt;
  Weave GitOps
  &lt;a class=&#34;heading-link&#34; href=&#34;#weave-gitops&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Flux originated from a company called Weaveworks, which sadly closed down in 2024. Amongst the numerous open-source tools initiated by Weaveworks, was Weave GitOps, which included a graphical  &amp;lsquo;management overlay&amp;rsquo; for Flux-based GitOps environments. After the demise of Weaveworks, the Weave GitOps open-source project lay abandoned for almost a year, before it was uncoupled from the defunct organisation and donated to a &lt;a href=&#34;https://github.com/weaveworks/weave-gitops&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;community-driven entity&lt;/a&gt; of the same name. The first &lt;a href=&#34;https://github.com/weaveworks/weave-gitops/commit/e6c63d9c6ec45e8f8fd2fea5521884cb51a26d9d&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;commit&lt;/a&gt; in the resurrection was made in November 2024. After a couple of months of work, a &lt;a href=&#34;https://github.com/weaveworks/weave-gitops/releases/tag/0.39.0-rc.1&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;0.39.0 Release Candidate (RC.1)&lt;/a&gt; surfaced on GitHub.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://windsock.io/images/weave-gitops.png&#34; alt=&#34;weave-gitops&#34;&gt;&lt;/p&gt;
&lt;p&gt;Weave GitOps is very similar in look, feel and function to the Flux Plugin for Headlamp, with some minor differences. It won&amp;rsquo;t be a surprise to learn that the Headlamp plugin was inspired to some degree by Weave GitOps, as evidenced by &lt;a href=&#34;https://github.com/headlamp-k8s/plugins/pull/75#issuecomment-2304247595&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;this comment&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Whilst the web UI provided by Weave GitOps is functioning again as a viable front end to Flux, at present it feels as if there is still a fair bit of work to be done to get it to a stable and viable proposition. It will be interesting to see how these two similar user interfaces progress, and whether they start to diverge at some point.&lt;/p&gt;
&lt;h2 id=&#34;capacitor&#34;&gt;
  Capacitor
  &lt;a class=&#34;heading-link&#34; href=&#34;#capacitor&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Another option for graphically viewing Flux environments, is &lt;a href=&#34;https://github.com/gimlet-io/capacitor&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Capacitor&lt;/a&gt;, an open-source web UI that originated from a company called Gimlet. It has a similar goal to the other user interfaces; to provide simple, graphical feedback on the state of the applications running in a cluster, being managed by Flux. And, to see the state of Flux itself, too.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://windsock.io/images/capacitor.png&#34; alt=&#34;capacitor&#34;&gt;&lt;/p&gt;
&lt;p&gt;Capacitor arrived in a &lt;a href=&#34;https://fluxcd.io/blog/2024/02/introducing-capacitor/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;fanfare&lt;/a&gt; in early 2024, before the Headlamp plugin was released, and before work commenced on the resurrection of Weave GitOps. For a while it was the only web UI available for Flux. In recent times, however, there appears to have been a hiatus in its maintenance, with the last commit to Capacitor&amp;rsquo;s GitHub repo having been made in October 2024. It&amp;rsquo;s unclear what the long term future holds for Capacitor.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;
  Conclusion
  &lt;a class=&#34;heading-link&#34; href=&#34;#conclusion&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;All of these user interfaces for Flux are designed in a similar vein; to provide a simple, utilitarian view on the state of deployed applications, and the Flux runtime environment that manages them. In the main, the interfaces are read-only, which removes the temptation to revert to clickops-style management. Unlike the web UI provided by Argo CD, none of them have the means to create any abstractions for managing applications.&lt;/p&gt;
&lt;p&gt;Without the ability to create the abstractions, Flux adopters are left to craft YAML definitions for these abstractions by hand. Or, the Flux CLI can be used to create them according to the arguments that are provided to the sub-command in question (e.g. &lt;code&gt;flux create source oci&lt;/code&gt;). Just be sure to export the definitions rather than have them created imperatively in the cluster, and then commit them to the source that the Flux runtime is watching.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a little too early to know how this landscape will shift over time, but for those with a preference for a web UI over a CLI, Headlamp seems the best bet at present. It has a wider focus than just Flux, it&amp;rsquo;s well maintained, and is a registered sandbox project of the CNCF.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;It&amp;rsquo;s worth mentioning &lt;a href=&#34;https://github.com/flux-subsystem-argo/flamingo&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Flamingo&lt;/a&gt;, a Flux Subsystem for Argo, which integrates Flux and Argo CD, and thereby provides the Argo CD web UI to Flux users. Unfortunately, the project is currently stalled as it seeks sponsorship for its continuation.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Using Frp to Publicly Expose Services in a Local Kubernetes Cluster</title>
      <link>https://windsock.io/using-frp-to-publicly-expose-services-in-a-local-kubernetes-cluster/</link>
      <pubDate>Thu, 27 Jun 2024 09:04:15 +0000</pubDate>
      
      <guid>https://windsock.io/using-frp-to-publicly-expose-services-in-a-local-kubernetes-cluster/</guid>
      <description>&lt;p&gt;I recently had cause to test out &lt;a href=&#34;https://cert-manager.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;cert-manager&lt;/a&gt; using the Kubernetes &lt;a href=&#34;https://gateway-api.sigs.k8s.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Gateway API&lt;/a&gt;, but wanted to do this using a local cluster on my laptop, based on &lt;a href=&#34;https://kind.sigs.k8s.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;kind&lt;/a&gt;. I wanted cert-manager to automatically acquire an X.509 certificate on behalf of an application service running in the cluster, using the &lt;a href=&#34;https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;ACME protocol&lt;/a&gt;. This isn&amp;rsquo;t straightforward to achieve, as:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The cluster, hosting cert-manager as an ACME client, runs on a laptop on a private network behind a router, using NAT.&lt;/li&gt;
&lt;li&gt;The certificate authority (CA) issuing the X.509 certificate, which provides the ACME server component, needs to present a domain validation challenge to cert-manager, from the internet.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Essentially, the problem is that the cluster is on a private network, but needs to be addressable via a registered domain name, from the internet. How best to achieve this?&lt;/p&gt;
&lt;h2 id=&#34;options&#34;&gt;
  Options
  &lt;a class=&#34;heading-link&#34; href=&#34;#options&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;There are probably a million and one ways to achieve this, all with varying degrees of complexity. We could use &lt;a href=&#34;https://www.howtogeek.com/428413/what-is-reverse-ssh-tunneling-and-how-to-use-it/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;SSH reverse tunnelling&lt;/a&gt;, or a commercial offering like &lt;a href=&#34;https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Cloudflare Tunnel&lt;/a&gt;, or one of the myriad of &lt;a href=&#34;https://github.com/anderspitman/awesome-tunneling?tab=readme-ov-file#open-source-at-least-with-a-reasonably-permissive-license&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;open source tunnelling solutions&lt;/a&gt; available. I chose to use &lt;a href=&#34;https://github.com/fatedier/frp&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;frp&lt;/a&gt;, &amp;ldquo;a fast reverse proxy that allows you to expose a local server located behind a NAT or firewall to the internet&amp;rdquo;. With 82,000 GitHub stars, it seems popular!&lt;/p&gt;
&lt;h2 id=&#34;frp&#34;&gt;
  Frp
  &lt;a class=&#34;heading-link&#34; href=&#34;#frp&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;https://windsock.io/images/frp-client-server.png&#34; alt=&#34;frp-client-server&#34;&gt;&lt;/p&gt;
&lt;p&gt;Frp uses a client/server model to establish a connection at either end of a tunnel; the server component at the end that is publicly exposed to the internet, and the client on the private network behind the router. Client traffic arriving at the frp server end is routed to the frp client through the tunnel, according to the configuration provided for the client and server components.&lt;/p&gt;
&lt;h3 id=&#34;frp-server-configuration&#34;&gt;
  Frp Server Configuration
  &lt;a class=&#34;heading-link&#34; href=&#34;#frp-server-configuration&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;For my scenario, I chose to host the frp server on a DigitalOcean &lt;a href=&#34;https://www.digitalocean.com/products/droplets&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;droplet&lt;/a&gt;, with a domain name set to resolve to the droplet&amp;rsquo;s public IP address. This is the domain name that will appear in the certificate&amp;rsquo;s &lt;a href=&#34;https://en.wikipedia.org/wiki/Subject_Alternative_Name&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Subject Alternative Name&lt;/a&gt; (SAN). The configuration file for the server looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;# Server configuration file -&amp;gt; /home/frps/frps.toml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;# Bind address and port for frp server and client communication&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bindAddr &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;0.0.0.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bindPort &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;7000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;# Token for authenticating with client&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;auth&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;token &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;CH6JuHAJFDNoieah&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;# Configuration for frp server dashboard (optional)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;webServer&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;addr &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;0.0.0.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;webServer&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;port &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;7500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;webServer&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;user &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;webServer&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;password &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;NGe1EFQ7w0q0smJm&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;# Ports for virtual hosts (applications running in Kubernetes)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vhostHTTPPort &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vhostHTTPSPort &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;443&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this simple scenario, the configuration provides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the interfaces and port number through which the frp client interacts with the server&lt;/li&gt;
&lt;li&gt;a token used by the client and the server for authenticating with each other&lt;/li&gt;
&lt;li&gt;access details for the server dashboard that shows active connections&lt;/li&gt;
&lt;li&gt;the ports the server will listen on for virtual host traffic (&lt;code&gt;80&lt;/code&gt; for HTTP and &lt;code&gt;443&lt;/code&gt; for HTTPS)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because this setup is temporary, and to make things relatively easy, the frp server can be run using a container rather than installing the binary to the host:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker run -d --restart always --name frps \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -p 7000:7000 \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -p 7500:7500 \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -p 80:80 \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -p 443:443 \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -v /home/frps/frps.toml:/etc/frps.toml \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ghcr.io/fatedier/frps:v0.58.1 -c /etc/frps.toml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A container image for the frp server is provided by the maintainer of frp, as a &lt;a href=&#34;https://github.com/users/fatedier/packages/container/package/frps&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub package&lt;/a&gt;. The Dockerfile from which the image is built, can also be &lt;a href=&#34;https://raw.githubusercontent.com/fatedier/frp/dev/dockerfiles/Dockerfile-for-frps&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;found in the repo&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;kind-cluster&#34;&gt;
  Kind Cluster
  &lt;a class=&#34;heading-link&#34; href=&#34;#kind-cluster&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Before discussing the client setup, let&amp;rsquo;s just describe how the cluster is configured on the private network.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ docker network inspect -f &amp;#34;{{json .IPAM.Config}}&amp;#34; kind | jq &amp;#39;.[0]&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Subnet&amp;#34;: &amp;#34;172.18.0.0/16&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Gateway&amp;#34;: &amp;#34;172.18.0.1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Kind uses containers as Kubernetes nodes, which communicate using a (virtual) Docker network provisioned for the purpose, called &amp;lsquo;kind&amp;rsquo;. In this scenario, it uses the local subnet &lt;code&gt;172.18.0.0/16&lt;/code&gt;. Let&amp;rsquo;s keep this in the forefront of our minds for a moment, but turn to what&amp;rsquo;s running in the cluster.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ kubectl -n envoy-gateway-system get pods,deployments,services
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME                                            READY   STATUS    RESTARTS   AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pod/envoy-default-gw-3d45476e-b5474cb59-cdjps   2/2     Running   0          73m
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pod/envoy-gateway-7f58b69497-xxjw5              1/1     Running   0          16h
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;deployment.apps/envoy-default-gw-3d45476e   1/1     1            1           73m
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;deployment.apps/envoy-gateway               1/1     1            1           16h
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME                                    TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)               AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service/envoy-default-gw-3d45476e       LoadBalancer   10.96.160.26   172.18.0.6    80:30610/TCP          73m
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service/envoy-gateway                   ClusterIP      10.96.19.152   &amp;lt;none&amp;gt;        18000/TCP,18001/TCP   16h
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service/envoy-gateway-metrics-service   ClusterIP      10.96.89.244   &amp;lt;none&amp;gt;        19001/TCP             16h
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The target application is running in the default namespace in the cluster, and is exposed using the &lt;a href=&#34;https://gateway.envoyproxy.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Envoy Gateway&lt;/a&gt;, acting as a &lt;a href=&#34;https://gateway-api.sigs.k8s.io/concepts/glossary/#gateway-controller&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;gateway controller&lt;/a&gt; for &lt;a href=&#34;https://gateway-api.sigs.k8s.io/concepts/api-overview/#resource-model&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Gateway API objects&lt;/a&gt;. The Kubernetes Gateway API supersedes the Ingress API. The Envoy Gateway provisions a deployment of &lt;a href=&#34;https://www.envoyproxy.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Envoy&lt;/a&gt;, which proxies HTTP/S requests for the application, using a Service of type LoadbLanacer. The &lt;a href=&#34;https://github.com/kubernetes-sigs/cloud-provider-kind&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Cloud Provider for Kind&lt;/a&gt; is also used to emulate the provisioning of a &amp;lsquo;cloud&amp;rsquo; load balancer, which exposes the application beyond the cluster boundary with an IP address. The IP address is &lt;code&gt;172.18.0.6&lt;/code&gt;, and is on the subnet associated with the &amp;lsquo;kind&amp;rsquo; network. Remember, this IP address is still inaccessible from the internet, because it&amp;rsquo;s on the private network, behind the router.&lt;/p&gt;
&lt;p&gt;If the frp client can route traffic received from the frp server, for the domain name, to this IP address on the &amp;lsquo;kind&amp;rsquo; network, it should be possible to use cert-manager to request an X.509 certificate using the ACME protocol. Further, it&amp;rsquo;ll enable anonymous, internet-facing clients  to consume applications running in the cluster on the private network, too.&lt;/p&gt;
&lt;h3 id=&#34;frp-client-configuration&#34;&gt;
  Frp Client Configuration
  &lt;a class=&#34;heading-link&#34; href=&#34;#frp-client-configuration&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Just as the frp server running on the droplet needs a configuration file, so does the frp client running on the laptop.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;# Client configuration file -&amp;gt; /home/frpc/frpc.toml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;# Address of the frp server (taken from the environment),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;# along with its port&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;serverAddr &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;{{ .Envs.FRP_SERVER_ADDR }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;serverPort &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;7000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;# Token for authenticating with server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;auth&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;token &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;CH6JuHAJFDNoieah&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;# Proxy definition for &amp;#39;https&amp;#39; traffic, with the destination&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;# IP address taken from the environment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;[[&lt;/span&gt;proxies&lt;span style=&#34;color:#eceff4&#34;&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;name &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;type &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;localIP &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;{{ .Envs.FRP_PROXY_LOCAL_IP }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;localPort &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;443&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;customDomains &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;myhost.xyz&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;# Proxy definition for &amp;#39;http&amp;#39; traffic, with the destination&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;# IP address taken from the environment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;[[&lt;/span&gt;proxies&lt;span style=&#34;color:#eceff4&#34;&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;name &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;http&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;type &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;http&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;localIP &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;{{ .Envs.FRP_PROXY_LOCAL_IP }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;localPort &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;customDomains &lt;span style=&#34;color:#eceff4&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;myhost.xyz&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The configuration file content is reasonably self-explanatory, but there are a couple of things to point out:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;For flexibility, the IP address of the frp server is configured using an environment variable rather than being hard-coded.&lt;/li&gt;
&lt;li&gt;The file contains proxy definitions for both, HTTP and HTTPS traffic, for the domain &lt;code&gt;myhost.xyz&lt;/code&gt;. The destination IP address for this proxied traffic is also taken from the environment (which evaluates to &lt;code&gt;172.18.0.6&lt;/code&gt; in this particular scenario).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As the frp client is getting some of its configuration from the environment, the relevant environment variables need to be set. In this case, the frp server is running on a DigitalOcean droplet, which requires &lt;code&gt;doctl&lt;/code&gt; in order to interact with the DigitalOcean API:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;export&lt;/span&gt; FRP_SERVER_ADDR&lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;$(doctl compute droplet list --tag-name kind-lab --format PublicIPv4 --no-header)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We know the local target IP address already, but this may be different in subsequent test scenarios, so it&amp;rsquo;s best to query the cluster to retrieve the IP address and set the variable accordingly:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;export&lt;/span&gt; FRP_PROXY_LOCAL_IP&lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;$(kubectl get gtw gw -o yaml | yq &amp;#39;.status.addresses.[] | select(.type == &amp;#34;&lt;/span&gt;IPAddress&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;) | .value&amp;#39;)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Just as the frp server was deployed as a container, so too can the frp client (Docker image for the client is &lt;a href=&#34;https://github.com/users/fatedier/packages/container/package/frpc&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;here&lt;/a&gt;, and the Dockerfile &lt;a href=&#34;https://raw.githubusercontent.com/fatedier/frp/dev/dockerfiles/Dockerfile-for-frpc&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;here&lt;/a&gt;):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker run -d --restart always --name frpc \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --network kind \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -p 7000:7000 \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -v /home/frpc/frpc.toml:/etc/frpc.toml \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -e FRP_SERVER_ADDR \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -e FRP_PROXY_LOCAL_IP \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ghcr.io/fatedier/frpc:v0.58.1 -c /etc/frpc.toml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The frpc client container is attached to the &amp;lsquo;kind&amp;rsquo; network, so that the traffic that it proxies can be routed to the IP address defined in the &lt;code&gt;FRP_PROXY_LOCAL_IP&lt;/code&gt; variable; &lt;code&gt;172.18.0.6&lt;/code&gt;. Once deployed, the frp server and client establish a tunnel that proxies HTTP/S requests to the exposed Service in the cluster.&lt;/p&gt;
&lt;p&gt;This enables cert-manager to initiate certificate requests for &lt;a href=&#34;https://cert-manager.io/docs/usage/gateway/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;suitably configured&lt;/a&gt; Gateway API objects using the ACME protocol. But, it also allows a CA (for example, &lt;a href=&#34;https://letsencrypt.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Let&amp;rsquo;s Encrypt&lt;/a&gt;), to challenge cert-manager with an &lt;a href=&#34;https://letsencrypt.org/docs/challenge-types/#http-01-challenge&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;HTTP-01&lt;/a&gt; or &lt;a href=&#34;https://letsencrypt.org/docs/challenge-types/#dns-01-challenge&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;DNS-01&lt;/a&gt; challenge for proof of domain control. In turn, cert-manager is able to respond to the challenge, and then establish a Kubernetes secret with the TLS artifacts (X.509 certificate and private key). The secret can then be used to establish secure TLS-encrypted communication between clients and the target application in the cluster on the private network.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;
  Conclusion
  &lt;a class=&#34;heading-link&#34; href=&#34;#conclusion&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Not everyone wants to spin up a cloud-provided Kubernetes cluster for testing purposes; it can get expensive. Local development cluster tools, such as kind, are designed for just such requirements. But, you&amp;rsquo;ll always need to satisfy that one scenario where you need to access the local cluster from the internet, and sometimes with an addressable domain name. Frp is just one solution available, but it&amp;rsquo;s a comprehensive solution with a lot more features that haven&amp;rsquo;t been discussed here. Just to be clear, you should read up on &lt;a href=&#34;https://github.com/fatedier/frp?tab=readme-ov-file#tls&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;securing the connection&lt;/a&gt; between the client and server, to ensure no eavesdropping on the traffic flow.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>JSON Pointer Syntax in JSON Patches with Kustomize</title>
      <link>https://windsock.io/json-pointer-syntax-in-json-patches-with-kustomize/</link>
      <pubDate>Tue, 21 May 2024 15:28:54 +0000</pubDate>
      
      <guid>https://windsock.io/json-pointer-syntax-in-json-patches-with-kustomize/</guid>
      <description>&lt;p&gt;I was recently struggling to add a single annotation to a Kubernetes object definition, using a &lt;a href=&#34;https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/#patch-using-inline-json6902&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;JSON Patch&lt;/a&gt; with Kustomize, when I stumbled on the &lt;a href=&#34;https://datatracker.ietf.org/doc/html/rfc6901&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;JSON Pointer&lt;/a&gt; syntax. It&amp;rsquo;s fleetingly referenced in the Kustomize documentation, and can be useful in some circumstances. So, here’s a summary of what it is, and what it does.&lt;/p&gt;
&lt;h2 id=&#34;the-problem&#34;&gt;
  The Problem
  &lt;a class=&#34;heading-link&#34; href=&#34;#the-problem&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;My challenge was to add an annotation to a single Kubernetes object with Kustomize. The &lt;code&gt;commonAnnotations&lt;/code&gt; &lt;a href=&#34;https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/commonannotations/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;field&lt;/a&gt; adds annotations to all rendered objects, so that’s no good for the job at hand, and the builtin &lt;a href=&#34;https://kubectl.docs.kubernetes.io/references/kustomize/builtins/#_annotationtransformer_&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Annotations Transformer&lt;/a&gt; doesn’t cut it either. We could use a &lt;a href=&#34;https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/#patch-using-inline-strategic-merge&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Strategic Merge&lt;/a&gt; patch instead, but where would the fun be in that?! A JSON Patch, targeting the specific object definition, seems the best way to go. Let&amp;rsquo;s suppose we have an object definition in the Kustomize base that contains the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; gateway.networking.k8s.io
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Gateway
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#81a1c1&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; https-gw
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#81a1c1&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;foo&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; bar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;snip&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A JSON Patch can be defined to add the annotation &lt;code&gt;cert-manager.io/issuer: letsencrypt-issuer&lt;/code&gt; at the path (target location) in the JSON document that represents the object. We could then perform a &lt;a href=&#34;https://kubectl.docs.kubernetes.io/references/kustomize/cmd/build/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Kustomize build&lt;/a&gt;, and apply the JSON Patch defined in a Kustomization:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; kustomize.config.k8s.io/v1beta1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Kustomization
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;patches&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#81a1c1&#34;&gt;patch&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;|-&lt;/span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;      - op: add
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;        path: /metadata/annotations
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;        value:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;          cert-manager.io/issuer: letsencrypt-issuer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;target&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; gateway.networking.k8s.io
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Gateway
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; https-gw
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We’d hope that this renders the following from the build:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; gateway.networking.k8s.io
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Gateway
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#81a1c1&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; https-gw
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#81a1c1&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;foo&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; bar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;cert-manager.io/issuer&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; letsencrypt-issuer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;snip&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Alas, not so. Instead, we get the following, with the original &lt;code&gt;foo: bar&lt;/code&gt; annotation &lt;em&gt;&lt;strong&gt;replaced&lt;/strong&gt;&lt;/em&gt; with the annotation defined in the patch:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; gateway.networking.k8s.io
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Gateway
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#81a1c1&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; https-gw
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#81a1c1&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;cert-manager.io/issuer&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; letsencrypt-issuer
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The reason for this is explained in the JSON Patch &lt;a href=&#34;https://datatracker.ietf.org/doc/html/rfc6902#section-4.1&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;IETF RFC6902&lt;/a&gt; standard for the &amp;lsquo;add&amp;rsquo; operation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If the target location specifies an object member that does exist, that member&amp;rsquo;s value is replaced.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Because the target location specified by the patch&amp;rsquo;s path (&lt;code&gt;/metadata/annotations&lt;/code&gt;) already has a value in the Kustomize base definition (&lt;code&gt;foo: bar&lt;/code&gt;), it gets clobbered with the value defined in the patch. That&amp;rsquo;s not what we want.&lt;/p&gt;
&lt;h2 id=&#34;potential-solution&#34;&gt;
  Potential Solution
  &lt;a class=&#34;heading-link&#34; href=&#34;#potential-solution&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;In the search for a solution, we could draw on another one of the IETF RFC6902 functions for the &amp;lsquo;add&amp;rsquo; operation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If the target location specifies an object member that does not already exist, a new member is added to the object.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The patch could be amended to include the annotation&amp;rsquo;s key in the path, which should get added to the object with the value specified:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; kustomize.config.k8s.io/v1beta1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Kustomization
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;patches&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#81a1c1&#34;&gt;patch&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;|-&lt;/span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;      - op: add
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;        path: /metadata/annotations/cert-manager.io/issuer
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;        value: letsencrypt-issuer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;target&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; gateway.networking.k8s.io
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Gateway
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; https-gw
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But, this time, there is an error:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Error: add operation does not apply: doc is missing path: &amp;#34;/metadata/annotations/cert-manager.io/issuer&amp;#34;: missing value
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The proposed key for the annotation, &lt;code&gt;cert-manager.io/issuer&lt;/code&gt;, has been interpreted as two different components of the path to the target location in the JSON document. In effect, we&amp;rsquo;re trying to add the &amp;lsquo;object member&amp;rsquo; &lt;code&gt;issuer&lt;/code&gt; to a target location that doesn&amp;rsquo;t exist.&lt;/p&gt;
&lt;h2 id=&#34;the-solution&#34;&gt;
  The Solution
  &lt;a class=&#34;heading-link&#34; href=&#34;#the-solution&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The JSON Patch specification requires the value of the path to be a string containing a &lt;a href=&#34;https://datatracker.ietf.org/doc/html/rfc6901&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;JSON Pointer&lt;/a&gt;; a sequence of zero or more reference tokens, each prefixed by a &lt;code&gt;/&lt;/code&gt;. The characters &lt;code&gt;/&lt;/code&gt; and &lt;code&gt;~&lt;/code&gt; both have speical meanings in JSON Pointer. So, if one of the reference tokens contains a &lt;code&gt;/&lt;/code&gt;, as in our annotation example, it needs to be escaped so that it can be interpreted literally. The sequence &lt;code&gt;~1&lt;/code&gt; is used in place of &lt;code&gt;/&lt;/code&gt; where it is to be interpreted literally. The JSON Patch needs to be re-defined, thus:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; kustomize.config.k8s.io/v1beta1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Kustomization
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;patches&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#81a1c1&#34;&gt;patch&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;|-&lt;/span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;      - op: add
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;        path: /metadata/annotations/cert-manager.io~1issuer
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;        value: letsencrypt-issuer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;target&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; gateway.networking.k8s.io
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Gateway
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; https-gw
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we&amp;rsquo;re adding the object member &lt;code&gt;cert-manager.io/issuer&lt;/code&gt; to the object. Rendering this Kustomization with a Kustomize build, gives us just what we need:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; gateway.networking.k8s.io
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Gateway
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#81a1c1&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; https-gw
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#81a1c1&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;foo&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; bar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;cert-manager.io/issuer&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; letsencrypt-issuer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;snip&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;conclusion&#34;&gt;
  Conclusion
  &lt;a class=&#34;heading-link&#34; href=&#34;#conclusion&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve always viewed the JSON Patch mechanism in Kustomize as a bit of a black art. Sometimes it pays to go and read up on what you&amp;rsquo;re actually trying to do! RFCs may not be everyone&amp;rsquo;s cup of tea, so &lt;a href=&#34;https://jsonpatch.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://jsonpatch.com/&lt;/a&gt; is a little easier on the eye.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Installing ESO with a Custom Namespace Using Kustomize</title>
      <link>https://windsock.io/installing-eso-with-a-custom-namespace-using-kustomize/</link>
      <pubDate>Sun, 03 Dec 2023 14:35:54 +0000</pubDate>
      
      <guid>https://windsock.io/installing-eso-with-a-custom-namespace-using-kustomize/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m putting this here in case anyone runs into the same problem as I did (and, seemingly, &lt;a href=&#34;https://github.com/external-secrets/external-secrets/issues/2273&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;others&lt;/a&gt;).&lt;/p&gt;
&lt;h5 id=&#34;tldr&#34;&gt;
  TLDR
  &lt;a class=&#34;heading-link&#34; href=&#34;#tldr&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;If you want to install the &lt;a href=&#34;https://external-secrets.io/latest/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;External Secrets Operator&lt;/a&gt; (ESO);&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;using Kustomize instead of Helm,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;intend to use the &lt;code&gt;external-secrets.yaml&lt;/code&gt; file from the assets on the GitHub &lt;a href=&#34;https://github.com/external-secrets/external-secrets/releases&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;release page&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;want to deploy to a custom namespace (instead of &amp;lsquo;default&amp;rsquo;)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;some patching is required to get the pods running.&lt;/p&gt;
&lt;h2 id=&#34;the-problem&#34;&gt;
  The Problem
  &lt;a class=&#34;heading-link&#34; href=&#34;#the-problem&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The External Secrets Operator is generally deployed using Helm, with a chart provided and maintained by the project community. For those who don&amp;rsquo;t use Helm, and would prefer to work with YAML instead, an &lt;code&gt;external-secrets.yaml&lt;/code&gt; file is provided in the assets on the project&amp;rsquo;s GitHub release page. It contains the CRDs as well as the various manifests for getting ESO deployed. The different manifests have been rendered with the assumption that ESO is being deployed to the &amp;lsquo;default&amp;rsquo; namespace on Kubernetes.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;d prefer to deploy ESO to a different, custom namespace, you might use Kustomize to patch the YAML before using &lt;code&gt;kubectl&lt;/code&gt; to apply it to the cluster. A Kustomization could be created to define the namespace, and to have it applied to all object definitions:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; kustomize.config.k8s.io/v1beta1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Kustomization
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;resources&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - namespace.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - https://github.com/external-secrets/external-secrets/releases/download/v0.9.9/external-secrets.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; eso
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, this will result in the failure of the &lt;a href=&#34;https://external-secrets.io/latest/api/components/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;TLS bootstrapping mechanism&lt;/a&gt; for the validating webhook, which, in turn, will inhibit the ability to create any SecretStore or ExternalSecret objects:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ kubectl -n eso get po
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME                                               READY   STATUS             RESTARTS     AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;external-secrets-9f6b87d4b-f44vx                   1/1     Running            0            21m
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;external-secrets-cert-controller-8d89c6584-ncbz2   0/1     Running            0            21m
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;external-secrets-webhook-5857bd5fff-rndcf          0/1     CrashLoopBackOff   6 (2m ago)   21m
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you switch back to deploying in the &amp;lsquo;default&amp;rsquo; namespace, all is rosy again. Perusing the documentation, it&amp;rsquo;s not entirely clear what configuration change is required to prevent this problem occurring, but the logs from the pods suggest that a Kubernetes secret with the TLS credentials for the webhook is missing.&lt;/p&gt;
&lt;h2 id=&#34;the-solution&#34;&gt;
  The Solution
  &lt;a class=&#34;heading-link&#34; href=&#34;#the-solution&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;It turns out the fix requires some additional options provided for the cert-controller and webhook containers, that relate to the custom namespace. With these added, the secret with the TLS credentials appears in the custom namespace, and all is well:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ kubectl -n eso get secrets external-secrets-webhook
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME                       TYPE     DATA   AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;external-secrets-webhook   Opaque   4      15s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A patch can be defined in the Kustomization to effect this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; kustomize.config.k8s.io/v1beta1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Kustomization
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;snip&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;patches&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#81a1c1&#34;&gt;patch&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;|-&lt;/span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;      - op: replace
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;        path: /spec/template/spec/containers/0/args/3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;        value: &amp;#34;--service-namespace=eso&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;      - op: replace
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;        path: /spec/template/spec/containers/0/args/5
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;        value: &amp;#34;--secret-namespace=eso&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;target&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; external-secrets-cert-controller
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#81a1c1&#34;&gt;patch&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;|-&lt;/span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;      - op: replace
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;        path: /spec/template/spec/containers/0/args/2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87&#34;&gt;        value: &amp;#34;--dns-name=external-secrets-webhook.eso.svc&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;target&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; external-secrets-webhook
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I hope this helps someone out there!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Bootstrapping Argo CD</title>
      <link>https://windsock.io/bootstrapping-argocd/</link>
      <pubDate>Mon, 19 Dec 2022 15:18:55 +0000</pubDate>
      
      <guid>https://windsock.io/bootstrapping-argocd/</guid>
      <description>&lt;p&gt;This article follows on from an &lt;a href=&#34;https://windsock.io/bootstrapping-gitops-agents/&#34; &gt;introductory article&lt;/a&gt; that discussed the chicken or the egg paradox when it comes to bootstrapping GitOps agents into Kubernetes clusters. The article discusses how this relates to one of the popular GitOps solutions commonly used to automate application deployments to Kubernetes, &lt;a href=&#34;https://argo-cd.readthedocs.io/en/stable/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Argo CD&lt;/a&gt;. Argo CD is one of the prominent GitOps solutions that pioneers this evolving approach to application delivery, and is part of a family of tools that co-exist under the Argo umbrella. Collectively, the Argo toolset is a recently &lt;a href=&#34;https://www.cncf.io/announcements/2022/12/06/the-cloud-native-computing-foundation-announces-argo-has-graduated/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;graduated project&lt;/a&gt; of the Cloud Native Computing Foundation (CNCF).&lt;/p&gt;
&lt;h2 id=&#34;installing-argo-cd&#34;&gt;
  Installing Argo CD
  &lt;a class=&#34;heading-link&#34; href=&#34;#installing-argo-cd&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;When it comes to bootstrapping Argo CD into a cluster to act as a GitOps agent, there are detailed &lt;a href=&#34;https://argo-cd.readthedocs.io/en/stable/operator-manual/installation/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;instructions for installation&lt;/a&gt; according to the preferred setup (i.e. multi-tenant, high availability and so on). Kubernetes configuration files (including its custom resource definitions) are maintained at Argo CD&amp;rsquo;s &lt;a href=&#34;https://github.com/argoproj/argo-cd/tree/master/manifests&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub repo&lt;/a&gt;, and these can be applied directly with &lt;code&gt;kubectl&lt;/code&gt;, or through a &lt;a href=&#34;https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Kustomization&lt;/a&gt; definition. There&amp;rsquo;s a &lt;a href=&#34;https://github.com/argoproj/argo-helm/tree/main/charts/argo-cd&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Helm chart&lt;/a&gt;, too, for anyone who prefers to use the chart packaging metaphor for applications. Using one of these techniques gets Argo CD running in a target cluster.&lt;/p&gt;
&lt;p&gt;So, we know how to install Argo CD, but, what&amp;rsquo;s less clear is how or if Argo CD can manage itself according to &lt;a href=&#34;https://opengitops.dev/#principles&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitOps principles&lt;/a&gt;. The project&amp;rsquo;s documentation is a little opaque in this regard. But, if you look hard enough, you&amp;rsquo;ll find a &lt;a href=&#34;https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#manage-argo-cd-using-argo-cd&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;reference&lt;/a&gt; to managing Argo CD with Argo CD. It suggests using a Kustomization to define how Argo CD is configured to run in a Kubernetes cluster, with the config stored in a Git repo, which is monitored by the installed instance of Argo CD. There&amp;rsquo;s even a &lt;a href=&#34;https://cd.apps.argoproj.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;live online example&lt;/a&gt; of Argo CD managing itself, alongside a bunch of other applications.&lt;/p&gt;
&lt;p&gt;A deployed agent, with its configuration held in versioned storage, configured to fetch and reconcile that same configuration, fulfils the GitOps principles. What&amp;rsquo;s missing from this tantalising glimpse of self-management, however, is how this works in practice. Let&amp;rsquo;s see if we can unpick this.&lt;/p&gt;
&lt;h2 id=&#34;applications-in-argo-cd&#34;&gt;
  Applications in Argo CD
  &lt;a class=&#34;heading-link&#34; href=&#34;#applications-in-argo-cd&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;GitOps agents work with instances of their own &lt;a href=&#34;https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;custom resources&lt;/a&gt;, that enable them to manage applications according to the GitOps principles. For Argo CD, the main custom resource it extends the Kubernetes API with, is the &amp;lsquo;Application&amp;rsquo;. In defining an Application object, and having it applied to the cluster, we provide Argo CD with the information it needs to manage that application. Some of the information defined in the object is mandatory, and some is optional. For example, the source location of the application&amp;rsquo;s remote Git or Helm repository that contains its configuration, and the coordinates of the target cluster where the application is to be deployed, are mandatory. Here&amp;rsquo;s an example Application definition that could be used by Argo CD for managing itself;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; argoproj.io/v1alpha1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Application
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#81a1c1&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; argocd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#81a1c1&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; argocd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#81a1c1&#34;&gt;destination&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; argocd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;server&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; https://kubernetes.default.svc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#81a1c1&#34;&gt;project&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#81a1c1&#34;&gt;source&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;path&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; argocd-bootstrap/argocd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;repoURL&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; https://github.com/nbrownuk/gitops-bootstrap.git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;targetRevision&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; HEAD
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#81a1c1&#34;&gt;syncPolicy&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;automated&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;allowEmpty&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;prune&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#81a1c1&#34;&gt;selfHeal&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This object definition would need to be applied to a cluster running Argo CD, which would then be enacted upon by Argo CD&amp;rsquo;s application controller, resulting in periodic fetches of the configuration from the source repo. Any changes made to Argo CD&amp;rsquo;s configuration in the repo (for example, a change in app version), would then be applied to the cluster, which would result in a rolling update of Argo CD. Hence, Argo CD is managing itself.&lt;/p&gt;
&lt;p&gt;But, let&amp;rsquo;s stop to think for a moment; isn&amp;rsquo;t the definition of the Application part of the overall configuration? We&amp;rsquo;ve manually applied the Application object definition to the cluster, but it&amp;rsquo;s not stored in our &amp;lsquo;source of truth&amp;rsquo; in the Git repo. If we had to re-create the cluster, would we remember the Git reference to use for the targetRevision; was it the HEAD, a branch, a specific commit? What was the sync policy for &lt;a href=&#34;https://assets.digitalocean.com/articles/comics/imperative-declarative-k8s.jpg&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;imperative changes&lt;/a&gt; made inside the cluster? This is one of the typical scenarios that inspired the GitOps philosophy - to take away the ambiguity of configuration, by using declarative configuration residing in versioned storage. This includes the configuration that drives the actions of the GitOps agent itself.&lt;/p&gt;
&lt;h2 id=&#34;app-of-apps-pattern&#34;&gt;
  App of Apps Pattern
  &lt;a class=&#34;heading-link&#34; href=&#34;#app-of-apps-pattern&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Using a pattern called &amp;lsquo;&lt;a href=&#34;https://argo-cd.readthedocs.io/en/stable/operator-manual/cluster-bootstrapping/#app-of-apps-pattern&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;app of apps&lt;/a&gt;&amp;rsquo;, Argo CD enables Argo CD to manage itself declaratively. The pattern is more general purpose in utility, in that a single &amp;lsquo;root&amp;rsquo; Application definition serves as a pointer to a Git directory path containing one or more further Application definitions. Applying the &amp;lsquo;root&amp;rsquo; definition results in the creation of all the subordinate Application objects in the cluster, which are then acted upon by Argo CD&amp;rsquo;s application controller. One of the subordinate Application objects might be one that defines Argo CD itself.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── managedapps
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  ├── argocd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  │  ├── kustomization.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  │  └── namespace.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  └── podinfo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│     └── kustomization.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── rootapp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  ├── kustomization.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  └── rootapp.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── subapps
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├── argocd.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├── kustomization.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   └── podinfo.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here, the &amp;lsquo;rootapp&amp;rsquo; Application definition (contained in rootapp.yaml) references the path, &amp;lsquo;subapps&amp;rsquo;, and each of the Application definitions at this location (argocd.yaml, podinfo.yaml) reference the corresponding sub-directories under &amp;lsquo;managedapps&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;If there are just a few applications, this pattern works well. But, if there are a multitude of applications, then maintenance of the plethora of Application definitions can become burdensome. As an enhancement to this pattern, the Argo CD project introduced the &lt;a href=&#34;https://argocd-applicationset.readthedocs.io/en/stable/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;ApplicationSet&lt;/a&gt; custom resource and controller. An ApplicationSet object defines one or more &amp;lsquo;&lt;a href=&#34;https://argocd-applicationset.readthedocs.io/en/stable/Generators/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;generators&lt;/a&gt;&amp;rsquo;, which generate key/value pairs called parameters. The definition will also contain a &amp;lsquo;&lt;a href=&#34;https://argocd-applicationset.readthedocs.io/en/stable/Template/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;template&lt;/a&gt;&amp;rsquo;, which the ApplicationSet controller will render with the corresponding parameters. In this way, a single ApplicationSet object can automatically spawn numerous Application resources, saving on the administrative overhead of maintaining lots of Application definitions by hand.&lt;/p&gt;
&lt;p&gt;An ApplicationSet definition can work equally as well as the app of apps pattern for managing Argo CD itself. Maybe you&amp;rsquo;d want to lean towards the ApplicationSet solution, as it&amp;rsquo;s seen as an evolution of the app of apps pattern.&lt;/p&gt;
&lt;h2 id=&#34;argo-cd-autopilot&#34;&gt;
  Argo CD Autopilot
  &lt;a class=&#34;heading-link&#34; href=&#34;#argo-cd-autopilot&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;One of the problems with setting up the &amp;lsquo;app of apps&amp;rsquo; or ApplicationSet configuration for Argo CD self-management, is that there are a number of manual steps involved:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Establish Git repo with app configuration&lt;/li&gt;
&lt;li&gt;Install Argo CD&lt;/li&gt;
&lt;li&gt;Create secret for trusted access to Git repo&lt;/li&gt;
&lt;li&gt;Apply &amp;lsquo;root&amp;rsquo; Application or ApplicationSet object definition&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of these steps are particularly onerous, but where there are manual steps there is always the opportunity to introduce error and ambiguity. The more automated everything is, the better chance of a successful outcome. This is where &lt;a href=&#34;https://argocd-autopilot.readthedocs.io/en/stable/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Argo CD Autopilot&lt;/a&gt; adds some value.&lt;/p&gt;
&lt;p&gt;Argo CD Autopilot is a command line tool for bootstrapping Argo CD and managed applications into Kubernetes clusters. It &lt;a href=&#34;https://codefresh.io/blog/launching-argo-cd-autopilot-opinionated-way-manage-applications-across-environments-using-gitops-scale/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;originated&lt;/a&gt; from engineers at Codefresh as an ancillary project to Argo CD. And, it seeks to take away some of the complexity of bootstrapping an Argo CD GitOps implementation, as well as to provide a sane repo structure for the configuration of the managed applications. It still uses ApplicationSet and Application objects under the covers, but hides the complexity behind its CLI. The price you pay for this simplified user experience, is an opinionated approach to the repo structure, and the way you might approach your deployment workflows.&lt;/p&gt;
&lt;p&gt;In terms of bootstrapping Argo CD itself, however, it&amp;rsquo;s as simple as issuing a command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ argocd-autopilot repo bootstrap \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --repo https://github.com/nbrownuk/argocd-bootstrap \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --git-token &amp;#34;$(&amp;lt; ./github-token)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The net result is the creation of a Git repo (hence, the need to supply a &lt;a href=&#34;https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#about-personal-access-tokens&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;personal access token&lt;/a&gt; with &amp;lsquo;repo&amp;rsquo; privileges) containing a prescribed directory structure, with all of the necessary configuration elements to enable self-management of Argo CD. It also results in the deployment of Argo CD to the cluster addressed by your current context. From here you can use the CLI to create projects and applications for management by Argo CD, with the necessary configuration automatically created in the Git repo.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── apps
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  ├── podinfo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  │  ├── base
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  │  │  └── kustomization.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  │  └── overlays
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  │     └── prod
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  │        ├── config.json
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  │        └── kustomization.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  └── README.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── bootstrap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  ├── argo-cd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  │  └── kustomization.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  ├── argo-cd.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  ├── cluster-resources
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  │  ├── in-cluster
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  │  │  ├── argocd-ns.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  │  │  └── README.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  │  └── in-cluster.json
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  ├── cluster-resources.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  └── root.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── projects
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├── prod.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   └── README.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The directory structure above is an example of a configured Git repo when using Argo CD Autopilot.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s early days for the Argo CD Autopilot project, with some features still missing. For example, its CLI doesn&amp;rsquo;t yet support the use of Helm charts as the embodiment of application configuration, although it&amp;rsquo;s possible to &lt;a href=&#34;https://github.com/argoproj-labs/argocd-autopilot/issues/38#issuecomment-1117961569&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;work around&lt;/a&gt; this using the limited support provided by Kustomize. Argo CD Autopilot isn&amp;rsquo;t necessarily for everybody, especially given its opinionated approach. But, if you&amp;rsquo;re looking for a convenient method for bootstrapping Argo CD, it does the job perfectly. It even allows you to recover from the loss of a cluster using the CLI, by bootstrapping with reference to the original Git repo as the source of truth.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Bootstrapping Flux</title>
      <link>https://windsock.io/bootstrapping-flux/</link>
      <pubDate>Mon, 12 Dec 2022 12:13:28 +0000</pubDate>
      
      <guid>https://windsock.io/bootstrapping-flux/</guid>
      <description>&lt;p&gt;Following on from an &lt;a href=&#34;https://windsock.io/bootstrapping-gitops-agents/&#34; &gt;introductory article&lt;/a&gt; on the merits of bootstrapping GitOps agents into Kubernetes clusters, this article looks into how this can be achieved with &lt;a href=&#34;https://fluxcd.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Flux&lt;/a&gt;. Flux is a collective name to describe several discrete Kubernetes controllers (also known as the GitOps Toolkit), that each perform a separate, specific GitOps-oriented function. Flux is a &lt;a href=&#34;https://www.cncf.io/announcements/2022/11/30/flux-graduates-from-cncf-incubator/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;graduated&lt;/a&gt; Cloud Native Computing Foundation (CNCF) project.&lt;/p&gt;
&lt;h2 id=&#34;installing-flux&#34;&gt;
  Installing Flux
  &lt;a class=&#34;heading-link&#34; href=&#34;#installing-flux&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Bootstrapping involves installation, and Flux can be installed into a Kubernetes cluster in a variety of ways. A set of YAML manifests are maintained in the project&amp;rsquo;s &lt;a href=&#34;https://github.com/fluxcd/flux2/tree/main/manifests&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub repo&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ kustomize build https://github.com/fluxcd/flux2/manifests/install?ref=v0.37.0 | \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    kubectl apply -f -
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But, if Helm is your thing, then there&amp;rsquo;s a &lt;a href=&#34;https://artifacthub.io/packages/helm/fluxcd-community/flux2&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;packaged Helm chart&lt;/a&gt; maintained for installing Flux, too. There&amp;rsquo;s even a command line tool, unsurprisingly called &lt;a href=&#34;https://fluxcd.io/flux/cmd/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Flux&lt;/a&gt;, that can also be used to get Flux up and running in a cluster:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ flux install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Performing any of these actions would provide us with a working Flux deployment in a cluster, consisting of the set of controllers that govern its GitOps actions.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ kubectl -n flux-system get po
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME                                          READY   STATUS    RESTARTS   AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;helm-controller-7b85c84687-dzdbr              1/1     Running   0          81s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;image-automation-controller-f45c4b86b-sqqlf   1/1     Running   0          81s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;image-reflector-controller-59c894c647-lzb76   1/1     Running   0          80s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kustomize-controller-d88d76876-dqw2m          1/1     Running   0          80s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;notification-controller-55df97fbb9-jbrqb      1/1     Running   0          80s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;source-controller-5bb5c7b9bd-dsd6w            1/1     Running   0          80s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But, it doesn&amp;rsquo;t provide us with a self-managed setup, using immutable, declarative configuration stored under version control.&lt;/p&gt;
&lt;p&gt;It turns out that the Flux project considers that bootstrapping, self-management and recovery, are primary concerns of GitOps deployments based on Flux. And, as such, it provides an installation mechanism that speaks to each of these concerns, which is &lt;a href=&#34;https://fluxcd.io/flux/installation/#bootstrap&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;described prominently&lt;/a&gt; in the documentation. So, how does Flux go about bootstrapping?&lt;/p&gt;
&lt;h2 id=&#34;bootstrapping-with-the-flux-cli&#34;&gt;
  Bootstrapping with the Flux CLI
  &lt;a class=&#34;heading-link&#34; href=&#34;#bootstrapping-with-the-flux-cli&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The Flux CLI is a like a Swiss army knife, in that it provides a large number of useful, utilitarian features. As well as using it to install Flux&amp;rsquo;s controllers into a cluster, you can use it to create the manifests for the custom resource objects that the controllers use to perform GitOps actions, for example. And a whole lot more, besides.&lt;/p&gt;
&lt;p&gt;Perhaps one of its most important functions, however, is its ability to perform a bootstrap of a GitOps environment, using a single command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ flux bootstrap github \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --repository flux-bootstrap \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --owner nbrownuk \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --personal true
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a fairly vanilla example of the use of the &lt;code&gt;flux bootstrap&lt;/code&gt; command, but there are a ton of other flags available to nuance the outcome. The command performs a lot of work behind the scenes; it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;creates a remote Git repo (GitHub, GitLab, AWS CodeCommit etc.)&lt;/li&gt;
&lt;li&gt;clones the repo&lt;/li&gt;
&lt;li&gt;generates the manifests for each of Flux&amp;rsquo;s controllers&lt;/li&gt;
&lt;li&gt;commits the manifests and pushes them to the remote repo&lt;/li&gt;
&lt;li&gt;installs the controllers into the cluster using the generated manifests&lt;/li&gt;
&lt;li&gt;creates an ssh key pair for trusted communication between Flux&amp;rsquo;s source controller and the remote repo (if you don&amp;rsquo;t bring your own)&lt;/li&gt;
&lt;li&gt;creates a secret embodying the private key, and adds the public key to the remote Git repo as a &amp;lsquo;deploy key&amp;rsquo;&lt;/li&gt;
&lt;li&gt;generates manifests (based on Flux&amp;rsquo;s custom resources) for the purposes of syncing desired state from the remote repo to the cluster&lt;/li&gt;
&lt;li&gt;commits sync manifests and pushes them to the remote repo&lt;/li&gt;
&lt;li&gt;applies the sync manifests to cluster, and waits for reconciliation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&amp;rsquo;s a lot of heavy lifting done on our behalf, and results in a repo structure that contains all that&amp;rsquo;s needed for Flux to manage itself:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── flux-system
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├── gotk-components.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├── gotk-sync.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   └── kustomization.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &amp;lsquo;gotk-components.yaml&amp;rsquo; manifest contains the custom resource definitions, and the Kubernetes object definitions for each of the controllers. And, the &amp;lsquo;gotk-sync.yaml&amp;rsquo; manifest contains custom resource object definitions, providing Flux with the location of the repo, and the path within the repo that contains the configuration that is to be applied to the cluster. That&amp;rsquo;s all Flux needs to manage itself. And, should you be unfortunate enough to lose you cluster, the bootstrap command can be run again to provision Flux to a new cluster, using the configuration in the repo.&lt;/p&gt;
&lt;h2 id=&#34;updating-flux&#34;&gt;
  Updating Flux
  &lt;a class=&#34;heading-link&#34; href=&#34;#updating-flux&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;As I write, even though Flux has gained graduate status with the CNCF, and has acquired &lt;a href=&#34;https://fluxcd.io/adopters/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;a sizeable community of adopters&lt;/a&gt;, the project is still &lt;a href=&#34;https://fluxcd.io/roadmap/#flux-gitops-ga-q1-2023&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;working towards&lt;/a&gt; General Availability. This means that Flux gets updated on a regular basis, which begs the question, how does Flux get updated after bootstrap?&lt;/p&gt;
&lt;p&gt;Firstly, with each release, a new version of the Flux CLI is provided&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. And so, to achieve an update to Flux after an initial bootstrap, all that&amp;rsquo;s required is a re-run of the bootstrap command with the updated version of the CLI. Execution of the command results in an update to the controller definitions in the &amp;lsquo;gotk-components.yaml&amp;rsquo; file in the remote Git repo, which is subsequently fetched and applied to the cluster by Flux. And this results in a rolling update of each controller running in the cluster.&lt;/p&gt;
&lt;p&gt;It may be more preferable to gate this change in the source Git repo using a pull request. The revised manifest for the new controller versions could be generated in advance using the following command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;$&lt;/span&gt; flux install &lt;span style=&#34;color:#81a1c1&#34;&gt;--&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;./&lt;/span&gt;gotk&lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;components&lt;span style=&#34;color:#81a1c1&#34;&gt;.&lt;/span&gt;yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you&amp;rsquo;re using GitHub as the Git host provider, this could also be &lt;a href=&#34;https://github.com/fluxcd/flux2/tree/main/action#automate-flux-updates&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;automated&lt;/a&gt; using &lt;a href=&#34;https://docs.github.com/en/actions&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Actions&lt;/a&gt;, which could easily be adapted for use in other CI/CD systems.&lt;/p&gt;
&lt;p&gt;Bootstrapping and updating in this manner is all well and good, if we&amp;rsquo;re happy to use a command line interface to achieve this. Sometimes, DevOps teams prefer to bundle the installation of core services into the infrastructure layer. How do we manage this for Flux?&lt;/p&gt;
&lt;h2 id=&#34;bootstrapping-with-terraform&#34;&gt;
  Bootstrapping with Terraform
  &lt;a class=&#34;heading-link&#34; href=&#34;#bootstrapping-with-terraform&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;When provisioning an entire environment for running cloud-native applications, an interesting question arises. What delineates infrastructure from applications? This line can get quite blurred, and different people will have different answers as to where to draw the line. But, the question is an important one, because different tools are generally used for managing the different layers. &lt;a href=&#34;https://www.terraform.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Terraform&lt;/a&gt; is pretty ubiquitous when it comes to managing infrastructure, and as we know, Flux is used to manage application deployments to Kubernetes.&lt;/p&gt;
&lt;p&gt;Flux sits on the boundary; you can&amp;rsquo;t manage applications with Flux until it&amp;rsquo;s provisioned, and you can&amp;rsquo;t provision Flux until the Kubernetes cluster is provisioned. Many will choose to drop Flux into the infrastructure layer, and have Terraform handle its bootstrapping, after which, Flux is able to manage itself. Anticipating the need, and recognising the importance of catering for this scenario, the Flux project has provided a &lt;a href=&#34;https://registry.terraform.io/providers/fluxcd/flux/latest&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Flux Terraform provider&lt;/a&gt; for provisioning Flux.&lt;/p&gt;
&lt;p&gt;Up to at least v0.21.0, the Flux provider consisted of two data sources; one for generating the YAML for the &lt;a href=&#34;https://registry.terraform.io/providers/fluxcd/flux/0.21.0/docs/data-sources/install&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;CRDs and deployment configuration&lt;/a&gt;, and one for generating the YAML for the &lt;a href=&#34;https://registry.terraform.io/providers/fluxcd/flux/0.21.0/docs/data-sources/sync&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;sync activity&lt;/a&gt;. The code used to achieve this is the same code used in the CLI for bootstrapping Flux. But, generation of the Kubernetes configuration doesn&amp;rsquo;t get Flux bootstrapped, and the user is required to make use of other Terraform providers to store the configuration in a Git source, and then to get it applied to a cluster.&lt;/p&gt;
&lt;p&gt;The official Terraform &lt;a href=&#34;https://registry.terraform.io/providers/hashicorp/kubernetes/latest&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Kubernetes provider&lt;/a&gt;, which is needed to apply the generated configuration to the cluster, comes with some &lt;a href=&#34;https://www.reddit.com/r/Terraform/comments/zam12h/kubernetes_provider_resources_v1_vs_nonv1_is_it/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;drawbacks&lt;/a&gt;. And, further, the notion that the Flux provider doesn&amp;rsquo;t itself handle the bootstrapping, might be considered a sub-optimal user experience. This has prompted the Flux project to &lt;a href=&#34;https://github.com/fluxcd/terraform-provider-flux/issues/301&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;overhaul the Flux provider&lt;/a&gt;, so that it performs the bootstrap process in its entirety. At the time of writing, a new &lt;a href=&#34;https://github.com/fluxcd/terraform-provider-flux/pull/332&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;bootstrap resource&lt;/a&gt; is in development for the Flux provider. With this important revision, the initial &lt;code&gt;terraform apply&lt;/code&gt; will:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;generate the necessary configuration,&lt;/li&gt;
&lt;li&gt;push the configuration to the Git repo,&lt;/li&gt;
&lt;li&gt;apply the configuration to the cluster, and wait for reconciliation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Subsequently, Terraform is responsible for managing the configuration in the repo, and Flux is responible for fetching and applying the configuration from the repo. This provides a clear delineation of responsibility, and a much improved user experience.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;For the sake of clarity, the version of the CLI reflects the Flux release version, whereas the individual controllers have different, independent release versions. For example, in Flux v0.37.0, the source controller version is v0.32.1, whilst the helm controller is v0.27.0.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Bootstrapping GitOps Agents</title>
      <link>https://windsock.io/bootstrapping-gitops-agents/</link>
      <pubDate>Sun, 04 Dec 2022 11:47:54 +0000</pubDate>
      
      <guid>https://windsock.io/bootstrapping-gitops-agents/</guid>
      <description>&lt;p&gt;Since the term was &lt;a href=&#34;https://www.weave.works/blog/gitops-operations-by-pull-request&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;originally coined&lt;/a&gt; back in 2017 by Alexis Richardson (CEO of Weaveworks), the GitOps philosophy has struggled to find a coherent, consensual definition. This fostered some ambiguity, and occasionally some contradiction. For example, &lt;a href=&#34;https://www.gitops.tech/#push-based-vs-pull-based-deployments&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;push-based deployments&lt;/a&gt; were once categorised as a valid approach to GitOps deployments, &lt;a href=&#34;https://www.linkedin.com/feed/update/urn:li:activity:6988163333044527104?utm_source=share&amp;amp;utm_medium=member_desktop&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;but now they&amp;rsquo;re not&lt;/a&gt;. There was going to be a common &lt;a href=&#34;https://github.com/argoproj/gitops-engine/blob/master/specs/design.md&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitOps engine&lt;/a&gt; for the good of the community, and &lt;a href=&#34;https://fluxcd.io/flux/migration/faq-migration/#is-the-gitops-toolkit-related-to-the-gitops-engine&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;then there wasn&amp;rsquo;t&lt;/a&gt;. Flux was in the vanguard of software tools that exemplified GitOps, and then it needed to be &lt;a href=&#34;https://fluxcd.io/flux/migration/faq-migration/#why-did-you-rewrite-flux&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;rewritten from the ground up&lt;/a&gt;. And, so on.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s encouraging, then, that the last 12 months or so have seen a gradual maturing of the concept, with a &lt;a href=&#34;https://opengitops.dev/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;common understanding&lt;/a&gt; of what we mean by the term &amp;lsquo;GitOps&amp;rsquo;. And the community has started working together across competing technologies, all under the umbrella of the Cloud Native Computing Foundation (CNCF). Some of the tooling has even acquired &amp;lsquo;&lt;a href=&#34;https://www.cncf.io/projects/#maturity-levels&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;graduated&lt;/a&gt;&amp;rsquo; project status with the CNCF. All is good in GitOps land.&lt;/p&gt;
&lt;p&gt;As the work to define standards has unfolded, and the development of software tools to meet those standards has ensued, one aspect of GitOps has consistently bugged me. It&amp;rsquo;s an implementation detail that doesn&amp;rsquo;t seem to get a lot of attention.&lt;/p&gt;
&lt;h2 id=&#34;gitops-agents&#34;&gt;
  GitOps Agents
  &lt;a class=&#34;heading-link&#34; href=&#34;#gitops-agents&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;First, let&amp;rsquo;s briefly outline what a GitOps agent is in the context of a Kubernetes cluster. A GitOps agent is a software application that (at least in part) implements the Kubernetes &lt;a href=&#34;https://kubernetes.io/docs/concepts/architecture/controller/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;controller pattern&lt;/a&gt;, and is responsible for reconciling the declared &amp;lsquo;desired state&amp;rsquo; with the actual cluster state. That is, the Kubernetes configuration for an application stored in a version control system (VCS), is periodically fetched and applied to the cluster, resulting in automated deployments. Change is initiated through the VCS, and explicitly not through direct, imperative change in the cluster. This allows application deployments to be managed using the inherent control features of the hosting VCS (i.e. pull or merge requests).&lt;/p&gt;
&lt;h2 id=&#34;chicken-or-the-egg&#34;&gt;
  Chicken or the Egg
  &lt;a class=&#34;heading-link&#34; href=&#34;#chicken-or-the-egg&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;So, GitOps agents allow us to automate application installs and updates in a Kubernetes cluster, according to the &lt;a href=&#34;https://opengitops.dev/#principles&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitOps principles&lt;/a&gt;. But, aren&amp;rsquo;t the agents themselves, software applications? They might be controllers, but they&amp;rsquo;re still just software applications, requiring; installation, update, reconfiguration, recovery, and so on. This begs the question, how do GitOps agents get deployed to a cluster? Can they be deployed to a cluster according to GitOps principles, like the apps they manage? Can they be used to manage themselves? Seemingly, this is an example of the classic &lt;a href=&#34;https://en.wikipedia.org/wiki/Chicken_or_the_egg&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;chicken or the egg&lt;/a&gt; paradox!&lt;/p&gt;
&lt;p&gt;If we have to manually install or update a GitOps agent, then it&amp;rsquo;s deployment is open to all of the issues that the GitOps principles seek to resolve; ambiguous state, configuration drift, unsolicited change, and much more. This effectively makes the state of the whole system as frail as if there were no GitOps agent at all. To that end, it&amp;rsquo;s crucial that GitOps solutions address this problem head on, and provide a means for bootstrapping their agents, whilst allowing for their ongoing management, in line with the GitOps principles that underpin the whole approach.&lt;/p&gt;
&lt;p&gt;This is the first article in a brief series looking into the different approaches taken to the bootstrapping conundrum.&lt;/p&gt;
&lt;h2 id=&#34;up-next&#34;&gt;
  Up Next
  &lt;a class=&#34;heading-link&#34; href=&#34;#up-next&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The two leading projects in the GitOps domain (arguably), Flux and ArgoCD, go about bootstrapping in different ways. First, we&amp;rsquo;ll discuss how the Flux project &lt;a href=&#34;https://windsock.io/bootstrapping-flux/&#34; &gt;goes about bootstrapping&lt;/a&gt; its numerous controllers, and then we&amp;rsquo;ll lift the lid on ArgoCD, to see &lt;a href=&#34;https://windsock.io/bootstrapping-argocd/&#34; &gt;how it gets things done&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Customising Docker CLI Output</title>
      <link>https://windsock.io/customising-docker-cli-output/</link>
      <pubDate>Thu, 03 Aug 2017 12:52:09 +0000</pubDate>
      
      <guid>https://windsock.io/customising-docker-cli-output/</guid>
      <description>&lt;p&gt;Docker provides a comprehensive API and CLI to its platform. This article is concerned with customising the output returned by Docker CLI commands.&lt;/p&gt;
&lt;p&gt;There are a large number of Docker client CLI commands, which provide information relating to various Docker objects on a given Docker host or Swarm cluster. Generally, this output is provided in a tabular format. An example, which all Docker users will have come across, is the &lt;code&gt;docker container ls&lt;/code&gt; command, which provides a list of running containers:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ docker container ls
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;43195e559b42        wordpress           &amp;#34;docker-entrypoint...&amp;#34;   47 seconds ago      Up 46 seconds       0.0.0.0:8080-&amp;gt;80/tcp   wp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;f7926468281f        mariadb             &amp;#34;docker-entrypoint...&amp;#34;   2 minutes ago       Up 2 minutes        3306/tcp               mysql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;customising-command-output&#34;&gt;
  Customising Command Output
  &lt;a class=&#34;heading-link&#34; href=&#34;#customising-command-output&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Sometimes, all of this information is too much, and you may find yourself wanting to format the output just how you&amp;rsquo;d like it. You might want to do this to de-clutter the output, for aesthetic purposes, or for formatting output as input to scripts. This is quite straightforward to do, as a large number of CLI commands have a config option, &lt;code&gt;--format&lt;/code&gt;, just for this purpose. The format of the output needs to be specified using a &lt;a href=&#34;https://golang.org/pkg/text/template/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Golang template&lt;/a&gt;, which translates a JSON object into the desired format. For example, if we&amp;rsquo;re only interested in the container ID, image, status, exposed ports and name, we could get this with the following (the &lt;code&gt;\t&lt;/code&gt; specifies a tab):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ docker container ls --format &amp;#39;{{.ID}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;43195e559b42    wordpress    Up 41 minutes    0.0.0.0:8080-&amp;gt;80/tcp    wp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;f7926468281f    mariadb    Up 43 minutes    3306/tcp    mysql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This provides us with the reduced amount of information we specified, but it looks a bit shoddy. We can add the table directive to improve the look:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ docker container ls --format &amp;#39;table {{.ID}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CONTAINER ID        IMAGE               STATUS              PORTS                  NAMES
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;43195e559b42        wordpress           Up About an hour    0.0.0.0:8080-&amp;gt;80/tcp   wp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;f7926468281f        mariadb             Up About an hour    3306/tcp               mysql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Docker actually uses a template applied to a JSON object, to generate the default output you see when no user-defined formatting is applied. The default table format for listing all of the container objects is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.RunningFor}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These are not the complete set of fields available in the output, however. We can find all of the fields associated with the container object, with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ docker container ls --format &amp;#39;{{json .}}&amp;#39; | jq &amp;#39;.&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Command&amp;#34;: &amp;#34;\&amp;#34;docker-entrypoint...\&amp;#34;&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;CreatedAt&amp;#34;: &amp;#34;2017-07-24 16:23:25 +0100 BST&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;ID&amp;#34;: &amp;#34;43195e559b42&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Image&amp;#34;: &amp;#34;wordpress&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Labels&amp;#34;: &amp;#34;&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;LocalVolumes&amp;#34;: &amp;#34;1&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Mounts&amp;#34;: &amp;#34;c71e998f250e...&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Names&amp;#34;: &amp;#34;wp&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Networks&amp;#34;: &amp;#34;wp&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Ports&amp;#34;: &amp;#34;0.0.0.0:8080-&amp;gt;80/tcp&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;RunningFor&amp;#34;: &amp;#34;About an hour ago&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Size&amp;#34;: &amp;#34;0B&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Status&amp;#34;: &amp;#34;Up About an hour&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Command&amp;#34;: &amp;#34;\&amp;#34;docker-entrypoint...\&amp;#34;&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;CreatedAt&amp;#34;: &amp;#34;2017-07-24 16:21:33 +0100 BST&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;ID&amp;#34;: &amp;#34;f7926468281f&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Image&amp;#34;: &amp;#34;mariadb&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Labels&amp;#34;: &amp;#34;&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;LocalVolumes&amp;#34;: &amp;#34;1&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Mounts&amp;#34;: &amp;#34;acaa1732009a...&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Names&amp;#34;: &amp;#34;mysql&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Networks&amp;#34;: &amp;#34;wp&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Ports&amp;#34;: &amp;#34;3306/tcp&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;RunningFor&amp;#34;: &amp;#34;About an hour ago&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Size&amp;#34;: &amp;#34;0B&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Status&amp;#34;: &amp;#34;Up About an hour&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice that there are some keys in each of the objects, missing from the default output; Labels, LocalVolumes, Mounts and Networks, to name a few. Hence, we could customise our output further, by replacing the Status field with the Networks field:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ docker container ls --format &amp;#39;table {{.ID}}\t{{.Image}}\t{{.Networks}}\t{{.Ports}}\t{{.Names}}&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CONTAINER ID        IMAGE               NETWORKS            PORTS                  NAMES
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;43195e559b42        wordpress           bridgey,wp          0.0.0.0:8080-&amp;gt;80/tcp   wp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;f7926468281f        mariadb             wp                  3306/tcp               mysql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;making-a-customisation-permanent&#34;&gt;
  Making a Customisation Permanent
  &lt;a class=&#34;heading-link&#34; href=&#34;#making-a-customisation-permanent&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;--format&lt;/code&gt;config option is great if you want to customise the output in a specific way for a particular use case. It would be a significant PITA, however, if you had to remember this syntax each time you issued a command, if you wanted to perpetually have customised output. You would of course, create an alias, or a script. Docker, however, allows you to make this customisation more permanent, with the use of a configuration file.  When a user on a Docker host logs in to the Docker Hub for the very first time, using the &lt;code&gt;docker login&lt;/code&gt; command, a file called &lt;code&gt;config.json&lt;/code&gt; is created in a directory called &lt;code&gt;.docker&lt;/code&gt; in the user&amp;rsquo;s home directory. This file is used by Docker to hold JSON encoded properties, including a user&amp;rsquo;s credentials. It can also be used to hold the format template for the &lt;code&gt;docker container ls&lt;/code&gt; command, using the &lt;code&gt;psFormat&lt;/code&gt; property. The property is called &lt;code&gt;psFormat&lt;/code&gt;, after the old version of the command name, &lt;code&gt;docker ps&lt;/code&gt;. A &lt;code&gt;config.json&lt;/code&gt; file might look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cat config.json
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;#34;auths&amp;#34;: {},
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;#34;psFormat&amp;#34;: &amp;#34;table {{.ID}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}\t{{.Networks}}&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;psFormat&lt;/code&gt; property is the JSON key, whilst the value is the required template for configuring the command output.&lt;/p&gt;
&lt;p&gt;With the &lt;code&gt;psFormat&lt;/code&gt; property defined, every time you use the &lt;code&gt;docker container ls&lt;/code&gt; command, you&amp;rsquo;ll get the customised output you desire. It&amp;rsquo;s possible to override the customisation on a case by case basis, simply by using the &lt;code&gt;--format&lt;/code&gt; config option, which takes precedence. Take care when editing the config file; incorrect syntax could render all properties invalid.&lt;/p&gt;
&lt;h2 id=&#34;valid-command-customisation-properties&#34;&gt;
  Valid Command Customisation Properties
  &lt;a class=&#34;heading-link&#34; href=&#34;#valid-command-customisation-properties&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Whilst the output for a large number of commands can be formatted using the &lt;code&gt;--format&lt;/code&gt; config option, permanent customisation via a property defined in the &lt;code&gt;config.json&lt;/code&gt; file, is mainly reserved for commands listing particular objects. A complete list of the commands, their relevant config property, and default template, are provided in the table below:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Command&lt;/th&gt;
          &lt;th&gt;Property&lt;/th&gt;
          &lt;th&gt;Default Template&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;docker container ls&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;psFormat&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.RunningFor}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;docker image ls&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;imagesFormat&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedSince}}\t{{.Size}}&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;docker network ls&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;networksFormat&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;table {{.ID}}\t{{.Name}}\t{{.Driver}}\t{{.Scope}}&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;docker plugin ls&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;pluginsFormat&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;table {{.ID}}\t{{.Name}}\t{{.Description}}\t{{.Enabled}}&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;docker volume ls&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;volumesFormat&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;table {{.Driver}}\t{{.Name}}&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This table omits a number of templates for Docker CLI commands that relate to &amp;lsquo;&lt;a href=&#34;https://docs.docker.com/engine/swarm/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;swarm mode&lt;/a&gt;&amp;rsquo;. Finally, the output of the &lt;code&gt;docker stats&lt;/code&gt; command can be defined in the &lt;code&gt;config.json&lt;/code&gt; file, too. This command provides rudimentary, real-time resource consumption for running containers, and the &lt;code&gt;statsFormat&lt;/code&gt; property allows for customising which metrics are displayed:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Command&lt;/th&gt;
          &lt;th&gt;Property&lt;/th&gt;
          &lt;th&gt;Default Template&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;docker stats&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;statsFormat&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDs}}&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
</description>
    </item>
    
    <item>
      <title>Explaining Docker Image IDs</title>
      <link>https://windsock.io/explaining-docker-image-ids/</link>
      <pubDate>Wed, 08 Jun 2016 12:18:47 +0000</pubDate>
      
      <guid>https://windsock.io/explaining-docker-image-ids/</guid>
      <description>&lt;p&gt;When Docker v1.10 came along, there was a fairly seismic change with the way the Docker Engine handles images. Whilst this was &lt;a href=&#34;https://blog.docker.com/2016/01/docker-1-10-rc/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;publicised well&lt;/a&gt;, and there was little impact on the general usage of Docker (image migration, aside), there were some UI changes which sparked some &lt;a href=&#34;https://github.com/docker/docker/issues/20131&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;confusion&lt;/a&gt;. So, what was the change, and why does the &lt;code&gt;docker history&lt;/code&gt; command show some IDs as &lt;code&gt;&amp;lt;missing&amp;gt;&lt;/code&gt;?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ docker history debian
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1742affe03b5        10 days ago         /bin/sh -c #(nop) CMD [&amp;#34;/bin/bash&amp;#34;]             0 B                 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;missing&amp;gt;           10 days ago         /bin/sh -c #(nop) ADD file:5d8521419ad6cfb695   125.1 MB
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;preamble&#34;&gt;
  Preamble
  &lt;a class=&#34;heading-link&#34; href=&#34;#preamble&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;First, some background. A docker image is a read-only template for creating containers, and provides a filesystem based on an ordered union of multiple layers of files and directories, which can be shared with other images and containers. Sharing of image layers is a fundamental component of the Docker platform, and is possible through the implementation of a &lt;a href=&#34;https://en.wikipedia.org/wiki/Copy-on-write&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;copy-on-write&lt;/a&gt; (COW) mechanism. During its lifetime, if a container needs to change a file from the read-only image that provides its filesystem, it copies the file up to its own private read-write layer before making the change.&lt;/p&gt;
&lt;p&gt;A layer or &amp;lsquo;diff&amp;rsquo; is created during the Docker image build process, and results when commands are run in a container, which produce new or modified files and directories. These new or modified files and directories are &amp;lsquo;committed&amp;rsquo; as a new layer. The output of the &lt;code&gt;docker history&lt;/code&gt; command above shows that the &lt;code&gt;debian&lt;/code&gt; image has two layers.&lt;/p&gt;
&lt;h2 id=&#34;historical-perspective&#34;&gt;
  Historical Perspective
  &lt;a class=&#34;heading-link&#34; href=&#34;#historical-perspective&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Historically (pre Docker v1.10), each time a new layer was created as a result of a commit action, Docker also created a corresponding image, which was identified by a randomly generated 256-bit &lt;a href=&#34;https://en.wikipedia.org/wiki/Universally_unique_identifier&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;UUID&lt;/a&gt;, usually referred to as an image ID (presented in the UI as either a short 12-digit hex string, or a long 64-digit hex string). Docker stored the layer contents in a directory with a name synonymous with the image ID. Internally, the image consisted of a configuration object, which held the characteristics of the image, including its ID, and the ID of the image&amp;rsquo;s parent image. In this way, Docker was able to construct a filesystem for a container, with each image in turn referencing its parent and the corresponding layer content, until the base image was reached which had no parent. Optionally, each image could also be tagged with a meaningful name (e.g. &lt;code&gt;my_image:1.0&lt;/code&gt;), but this was usually reserved for the leaf image. This is depicted in the diagram below:&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;&lt;img src=&#34;https://windsock.io/images/Historical_Image.png&#34;
    alt=&#34;Historical Image&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;Using the &lt;code&gt;docker inspect&lt;/code&gt; command would yield:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ docker inspect my_image:1.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;#34;Id&amp;#34;: &amp;#34;ca1f5f48ef431c0818d5e8797dfe707557bdc728fe7c3027c75de18f934a3b76&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;#34;Parent&amp;#34;: &amp;#34;91bac885982d2d564c0e1869e8b8827c435eead714c06d4c670aaae616c1542c&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This method served Docker well for a sustained period, but over time was perceived to be sub-optimal for a variety of reasons. One of the big drivers for change, came from the lack of a means of detecting whether an image&amp;rsquo;s contents had been tampered with during a push to or pull from a registry, such as the &lt;a href=&#34;https://hub.docker.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Docker Hub&lt;/a&gt;. This led to robust &lt;a href=&#34;https://github.com/docker/docker/issues/9719&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;criticism&lt;/a&gt; from the community at large, and led to a series of changes, culminating in content addressable IDs.&lt;/p&gt;
&lt;h2 id=&#34;content-addressable-ids&#34;&gt;
  Content Addressable IDs
  &lt;a class=&#34;heading-link&#34; href=&#34;#content-addressable-ids&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Since Docker v1.10, generally, images and layers are no longer synonymous. Instead, an image directly references one or more layers that eventually contribute to a derived container&amp;rsquo;s filesystem.&lt;/p&gt;
&lt;p&gt;Layers are now identified by a digest, which takes the form &lt;code&gt;algorithm:hex&lt;/code&gt;; for example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sha256:fc92eec5cac70b0c324cec2933cd7db1c0eae7c9e2649e42d02e77eb6da0d15f
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The hex element is calculated by applying the algorithm (&lt;a href=&#34;https://en.wikipedia.org/wiki/Secure_Hash_Algorithm&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;SHA256&lt;/a&gt;) to a layer&amp;rsquo;s content. If the content changes, then the computed digest will also change, meaning that Docker can check the retrieved contents of a layer with its published digest in order to verify its content. Layers have no notion of an image or of belonging to an image, they are merely collections of files and directories.&lt;/p&gt;
&lt;p&gt;A Docker image now consists of a configuration object, which (amongst other things) contains an ordered list of layer digests, which enables the Docker Engine to assemble a container&amp;rsquo;s filesystem with reference to layer digests rather than parent images. The image ID is also a digest, and is a computed SHA256 hash of the image configuration object, which contains the digests of the layers that contribute to the image&amp;rsquo;s filesystem definition. The following diagram depicts the relationship between image and layers post Docker v1.10:&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;&lt;img src=&#34;https://windsock.io/images/Content_Addressable_Image.png&#34;
    alt=&#34;Content ddressable mage&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;The digests for the image and layers have been shortened for readability.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;diff&lt;/code&gt; directory for storing the layer content, is now named after a randomly generated &amp;lsquo;cache ID&amp;rsquo;, and the Docker Engine maintains the link between the layer and its cache ID, so that it knows where to locate the layer&amp;rsquo;s content on disk.&lt;/p&gt;
&lt;p&gt;So, when a Docker image is pulled from a registry, and the &lt;code&gt;docker history&lt;/code&gt; command is used to reveal its contents, the output provides something similar to:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ docker history swarm
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;c54bba046158        9 days ago          /bin/sh -c #(nop) CMD [&amp;#34;--help&amp;#34;]                0 B                 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;missing&amp;gt;           9 days ago          /bin/sh -c #(nop) ENTRYPOINT &amp;amp;{[&amp;#34;/swarm&amp;#34;]}      0 B                 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;missing&amp;gt;           9 days ago          /bin/sh -c #(nop) VOLUME [/.swarm]              0 B                 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;missing&amp;gt;           9 days ago          /bin/sh -c #(nop) EXPOSE 2375/tcp               0 B                 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;missing&amp;gt;           9 days ago          /bin/sh -c #(nop) ENV SWARM_HOST=:2375          0 B                 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;missing&amp;gt;           9 days ago          /bin/sh -c #(nop) COPY dir:b76b2255a3b423981a   0 B                 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;missing&amp;gt;           9 days ago          /bin/sh -c #(nop) COPY file:5acf949e76228329d   277.2 kB            
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;missing&amp;gt;           9 days ago          /bin/sh -c #(nop) COPY file:a2157cec2320f541a   19.06 MB
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The command provides detail about the image and the layers it is composed of. The &lt;code&gt;&amp;lt;missing&amp;gt;&lt;/code&gt; value in the &lt;code&gt;IMAGE&lt;/code&gt; field for all but one of the layers of the image, is misleading and a little unfortunate. It conveys the suggestion of an error, but there is no error as layers are no longer synonymous with a corresponding image and ID. I think it would have been more appropriate to have left the field blank. Also, the image ID appears to be associated with the uppermost layer, but in fact, the image ID doesn&amp;rsquo;t &amp;lsquo;belong&amp;rsquo; to any of the layers. Rather, the layers collectively belong to the image, and provide its filesystem definition.&lt;/p&gt;
&lt;h2 id=&#34;locally-built-images&#34;&gt;
  Locally Built Images
  &lt;a class=&#34;heading-link&#34; href=&#34;#locally-built-images&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Whilst this narrative for content addressable images holds true for all Docker images post Docker v1.10, locally built images on a Docker host are treated slightly differently. The generic content of an image built locally remains the same - it is a configuration object containing configuration items, including an ordered list of layer digests.&lt;/p&gt;
&lt;p&gt;However, when a layer is committed during an image build on a local Docker host, an &amp;lsquo;intermediate&amp;rsquo; image is created at the same time. Just like all other images, it has a configuration item which is a list of the layer digests that are to be incorporated as part of the image, and its ID or digest contains a hash of the configuration object. Intermediate images aren&amp;rsquo;t tagged with a name, but, they do have a &amp;lsquo;Parent&amp;rsquo; key, which contains the ID of the parent image.&lt;/p&gt;
&lt;p&gt;The purpose of the intermediate images and the reference to parent images, is to facilitate the use of Docker&amp;rsquo;s &lt;a href=&#34;http://thenewstack.io/understanding-the-docker-cache-for-faster-builds/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;build cache&lt;/a&gt;. The build cache is another important feature of the Docker platform, and is used to help the Docker Engine make use of pre-existing layer content, rather than regenerating the content needlessly for an identical build command. It makes the build process more efficient. When an image is built locally, the &lt;code&gt;docker history&lt;/code&gt; command might provide output similar to the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ docker history jbloggs/my_image:latest 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;26cca5b0c787        52 seconds ago      /bin/sh -c #(nop) CMD [&amp;#34;/bin/sh&amp;#34; &amp;#34;-c&amp;#34; &amp;#34;/bin/b   0 B                 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;97e47fb9e0a6        52 seconds ago      /bin/sh -c apt-get update &amp;amp;&amp;amp;     apt-get inst   16.98 MB            
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1742affe03b5        13 days ago         /bin/sh -c #(nop) CMD [&amp;#34;/bin/bash&amp;#34;]             0 B                 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;missing&amp;gt;           13 days ago         /bin/sh -c #(nop) ADD file:5d8521419ad6cfb695   125.1 MB
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this example, the top two layers are created during the local image build, whilst the bottom layers came from the base image for the build (e.g. &lt;a href=&#34;https://docs.docker.com/engine/reference/builder/#from&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Dockerfile instruction&lt;/a&gt; &lt;code&gt;FROM debian&lt;/code&gt;). We can use the &lt;code&gt;docker inspect&lt;/code&gt; command to review the layer digests associated with the image:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ docker inspect jboggs/my_image:latest 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;#34;RootFS&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;#34;Type&amp;#34;: &amp;#34;layers&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;#34;Layers&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;#34;sha256:4dcab49015d47e8f300ec33400a02cebc7b54cadd09c37e49eccbc655279da90&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;#34;sha256:f22bfbc1df820c465d94215e45bf9b1f0ae0fe3435a90dc5296a4b55712f46e7&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;docker history&lt;/code&gt; command shows the image as having four layers, but &lt;code&gt;docker inspect&lt;/code&gt; suggests just two layers. This is because the two &lt;code&gt;CMD&lt;/code&gt; instructions produce metadata for the image, don&amp;rsquo;t add any content, and therefore the &amp;lsquo;diff&amp;rsquo; is empty.&lt;/p&gt;
&lt;p&gt;When a locally built image is pushed to a registry, it is only the leaf image that is uploaded along with its constituent layers, and a subsequent pull by another Docker host will not yield any intermediate parent images. This is because once the image is made available to other potential users on different Docker hosts via a registry, it effectively becomes read-only, and the components that support the build cache are no longer required. Instead of the image ID, &lt;code&gt;&amp;lt;missing&amp;gt;&lt;/code&gt; is inserted into the history output in its place.&lt;/p&gt;
&lt;p&gt;Pushing the image to a registry might yield:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ docker push jbloggs/my_image:latest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;The push refers to a repository [docker.io/jbloggs/my_image]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;f22bfbc1df82: Pushed 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;5f70bf18a086: Layer already exists 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4dcab49015d4: Layer already exists 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;latest: digest: sha256:7f63e3661b1377e2658e458ac1ff6d5e0079f0cfd9ff2830786d1b45ae1bb820 size: 3147
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this example, only one layer has been pushed, as two of the layers already exist in the registry, referenced by one or more other images which use the same content.&lt;/p&gt;
&lt;h2 id=&#34;a-final-twist&#34;&gt;
  A Final Twist
  &lt;a class=&#34;heading-link&#34; href=&#34;#a-final-twist&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The digests that Docker uses for layer &amp;lsquo;diffs&amp;rsquo; on a Docker host, contain the sha256 hash of the tar archived content of the diff. Before the layer is uploaded to a registry as part of a push, it is compressed for bandwidth efficiency. A manifest is also created to describe the contents of the image, and it contains the digests of the &lt;strong&gt;compressed&lt;/strong&gt; layer content. Consequently, the digests for the layers in the manifest are different to those generated in their uncompressed state. The manifest is also pushed to the registry.&lt;/p&gt;
&lt;p&gt;The digest of a compressed layer diff can be referred to as a &amp;lsquo;distribution digest&amp;rsquo;, whilst the digest for the uncompressed layer diff can be referred to as a &amp;lsquo;content digest&amp;rsquo;. Hence, when we pull our example image on a different Docker host, the &lt;code&gt;docker pull&lt;/code&gt; command gives the following output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;$&lt;/span&gt; docker pull jbloggs&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;my_image
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Using default tag&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; latest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;latest&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Pulling from jbloggs&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;my_image
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;51&lt;/span&gt;f5c6a04d83&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Pull complete 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;a3ed95caeb02&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Pull complete 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;9&lt;/span&gt;a246d793396&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Pull complete 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Digest&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; sha256&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;7&lt;/span&gt;f63e3661b1377e2658e458ac1ff6d5e0079f0cfd9ff2830786d1b45ae1bb820
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Status&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; Downloaded newer image &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;for&lt;/span&gt; jbloggs&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;my_image&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The distribution digests in the output of the &lt;code&gt;docker pull&lt;/code&gt; command, are very different to the digests reported by the &lt;code&gt;docker push&lt;/code&gt; command. But, the pull will decompress the layers, and the output of a &lt;code&gt;docker inspect&lt;/code&gt; command will provide the familiar content digests that we saw after the image build.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;
  Summary
  &lt;a class=&#34;heading-link&#34; href=&#34;#summary&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Following the changes to image and layer handling in Docker v1.10:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A Docker image provides a filesystem for a derived container based on the references it stores to layer diffs&lt;/li&gt;
&lt;li&gt;Layer diffs are referenced using a digest, which contains an SHA256 hash of an archive of the diff&amp;rsquo;s contents&lt;/li&gt;
&lt;li&gt;A Docker image&amp;rsquo;s ID is a digest, which contains an SHA256 hash of the image&amp;rsquo;s JSON configuration object&lt;/li&gt;
&lt;li&gt;Docker creates intermediate images during a local image build, for the purposes of maintaining a build cache&lt;/li&gt;
&lt;li&gt;An image manifest is created and pushed to a Docker registry when an image is pushed&lt;/li&gt;
&lt;li&gt;An image manifest contains digests of the image&amp;rsquo;s layers, which contain the SHA256 hashes of the compressed, archived diff contents&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Referencing Docker Images</title>
      <link>https://windsock.io/referencing-docker-images/</link>
      <pubDate>Mon, 27 Apr 2015 16:39:42 +0000</pubDate>
      
      <guid>https://windsock.io/referencing-docker-images/</guid>
      <description>&lt;p&gt;Docker images are the templates that derive the nature and behaviour of a container, and Docker stores these images in repositories on hosted registries. An official registry, called the &lt;a href=&#34;https://registry.hub.docker.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Docker Hub Registry&lt;/a&gt;, is hosted by &lt;a href=&#34;https://www.docker.com&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Docker Inc.&lt;/a&gt;, which contains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A set of official, certified  Docker repositories, which are curated by the Docker community&lt;/li&gt;
&lt;li&gt;Publicly accessible repositories, provided by any individual or organisation with a Docker Hub account&lt;/li&gt;
&lt;li&gt;Private repositories for individuals and organisations who purchase one of the &lt;a href=&#34;https://www.docker.com/pricing/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;available plans&lt;/a&gt; provided by Docker Inc&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Docker Hub Registry is an incredibly valuable resource, with over 7 million publicly available repositories of Docker images. But what if you&amp;rsquo;re a security conscious corporation, that wants to keep your intellectual property proprietary, behind a corporate firewall? Or you&amp;rsquo;re a third-party wanting to provide a value add service to your customers? You have a choice; you can either purchase a commercial product like &lt;a href=&#34;https://www.openshift.com/products/quay&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Red Hat Quay&lt;/a&gt;, or you can deploy an open-source solution such as &lt;a href=&#34;https://goharbor.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Harbor&lt;/a&gt; inside your corporate firewall.&lt;/p&gt;
&lt;p&gt;All of these options, however, pose a serious question - how do I address the correct image that I need for my container? For example, how do I make sure that the MySQL image I use for my application is the one that has been carefully crafted by the Database Administrators inside my organisation, rather than the official MySQL image on the public Docker Hub Registry, or even some other random MySQL image provided by an unknown entity on the Docker Hub Registry? This all comes down to specifying the correct image name when you retrieve an image or invoke a container using the Docker CLI or API, and there is a format that needs to be adhered to. A fully qualified image name (FQIN) consists of three main components; a registry location (with an optional port specification), a username, and a repository name (with an optional tag specification):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hostname[:port]/username/reponame[:tag]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The hostname and optional port specify the location of the registry, and if these are omitted then Docker defaults to the Docker Hub Registry at &lt;code&gt;index.docker.io&lt;/code&gt;. The next element in the image name is a username, and once again, if this is omitted, it corresponds to a special username called &lt;code&gt;library&lt;/code&gt;. In the Docker Hub Registry, the &lt;code&gt;library&lt;/code&gt; username is for the officially, curated Docker images. Finally, a repository name needs to be specified, and optionally an image tag to identify the specific image from its related images in the repository (if the tag is omitted, Docker assumes the tag &lt;code&gt;latest&lt;/code&gt;).&lt;/p&gt;
&lt;h5 id=&#34;library-images&#34;&gt;
  Library Images
  &lt;a class=&#34;heading-link&#34; href=&#34;#library-images&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;In order to &amp;lsquo;pull&amp;rsquo; the latest official Ubuntu image, the following Docker CLI command can be invoked:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker pull ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this format, the registry location, username and tag have been omitted. The shortened image name directs the Docker engine to pull the latest library image from the &lt;code&gt;ubuntu&lt;/code&gt; repository on the Docker Hub Registry. This could also have been achieved using the longhand format:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker pull index.docker.io/library/ubuntu:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h5 id=&#34;user-images&#34;&gt;
  User Images
  &lt;a class=&#34;heading-link&#34; href=&#34;#user-images&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;In order to pull the latest version of an image called &lt;code&gt;pxe&lt;/code&gt; that belongs to the user &lt;code&gt;jpetazzo&lt;/code&gt; on the Docker Hub Registry, the following command can be used:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker pull jpetazzo/pxe
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this example, the registry location has been omitted, and so the default Docker Hub Registry is the target for the Docker engine.&lt;/p&gt;
&lt;h5 id=&#34;images-on-third-party-registries&#34;&gt;
  Images on Third-Party Registries
  &lt;a class=&#34;heading-link&#34; href=&#34;#images-on-third-party-registries&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;Some third-party organisations host their own Docker registries independent of Docker Inc, which they make available to their customers. In order to pull an image that resides on a third party registry (such as &lt;a href=&#34;https://r.j3ss.co/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;r.j3ss.co&lt;/a&gt;), the registry location needs to be supplied along with the username and repository, e.g.:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker pull r.j3ss.co/tor-browser:stable
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this case, a tag has been specified as part of the image name in order to differentiate it from other versions of the image.&lt;/p&gt;
&lt;h5 id=&#34;images-on-self-hosted-registries&#34;&gt;
  Images on Self-Hosted Registries
  &lt;a class=&#34;heading-link&#34; href=&#34;#images-on-self-hosted-registries&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;Finally, we can reference an image that resides on a locally configured, self-hosted registry by specifying the registry location and the repository required:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker pull internal.mycorp.com:5000/revealjs:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>The docker-proxy</title>
      <link>https://windsock.io/the-docker-proxy/</link>
      <pubDate>Wed, 15 Apr 2015 12:11:31 +0000</pubDate>
      
      <guid>https://windsock.io/the-docker-proxy/</guid>
      <description>&lt;p&gt;Containers created and managed by the &lt;a href=&#34;https://www.docker.com&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Docker engine&lt;/a&gt; are able to provide the service that is running inside the container, not only to other co-located containers, but also to remote hosts. Docker achieves this with port forwarding.&lt;/p&gt;
&lt;p&gt;When a container starts with its port mapped to the Docker host on which it runs, in addition to the new process that runs inside the container, you may have noticed an additional process on the Docker host called &lt;code&gt;docker-proxy&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  PID TTY      STAT   TIME COMMAND
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 8006 ?        Sl     0:00 docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8000 -container-ip 172.17.0.2 -container-port 8000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The purpose of this process is to enable a service consumer to communicate with the service providing container &amp;hellip;. but it&amp;rsquo;s only used in particular circumstances. The &lt;code&gt;docker-proxy&lt;/code&gt; operates in &lt;a href=&#34;http://www.catb.org/jargon/html/U/userland.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;userland&lt;/a&gt;, and simply receives any packets arriving at the host&amp;rsquo;s specified port, that the kernel hasn&amp;rsquo;t &amp;lsquo;dropped&amp;rsquo; or forwarded, and redirects them to the container&amp;rsquo;s port.&lt;/p&gt;
&lt;p&gt;In order to understand why this process exists, we first need to understand a little about Docker&amp;rsquo;s networking configuration. The default modus operandi for a Docker host is to create a virtual ethernet bridge (called &lt;code&gt;docker0&lt;/code&gt;), attach each container&amp;rsquo;s network interface to the bridge, and to use network address translation (NAT) when containers need to make themselves visible to the Docker host and beyond:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://windsock.io/content/images/2018/03/Basic_Container_Networking.png&#34; alt=&#34;Docker Bridge&#34;&gt;&lt;/p&gt;
&lt;p&gt;Controlling access to a container&amp;rsquo;s service is controlled with rules associated with the host&amp;rsquo;s &lt;a href=&#34;http://www.netfilter.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;netfilter framework&lt;/a&gt;, in both the NAT and filter tables. The general processing flow of packets by netfilter is depicted in &lt;a href=&#34;http://inai.de/images/nf-packet-flow.png&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;this diagram&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If a container&amp;rsquo;s port &lt;code&gt;172.17.0.2:8000&lt;/code&gt; is to be mapped to the host as port &lt;code&gt;8000&lt;/code&gt;, then Docker adds some rules to netfilter&amp;rsquo;s NAT table, enabling the container to &amp;lsquo;masquerade&amp;rsquo; as the host using NAT:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Chain PREROUTING (policy ACCEPT 49 packets, 9985 bytes)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;num   pkts bytes target     prot opt in     out       source               destination         
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1       80  4152 DOCKER     all  --  *      *         0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Chain OUTPUT (policy ACCEPT 1436 packets, 151K bytes)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;num   pkts bytes target     prot opt in     out       source               destination         
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1      274 56172 DOCKER     all  --  *      *         0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Chain POSTROUTING (policy ACCEPT 1369 packets, 137K bytes)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;num   pkts bytes target     prot opt in     out       source               destination         
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1      274 56172 MASQUERADE all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0                   
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2        0     0 MASQUERADE tcp  --  *      *         172.17.0.2           172.17.0.2           tcp dpt:8000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Chain DOCKER (2 references)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;num   pkts bytes target     prot opt in       out     source               destination         
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1        0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8000 to:172.17.0.2:8000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Netfilter is stateful, which means that it can track connections that have already been established, and in such circumstances it bypasses the NAT table rules. But in order for a connection to be established in the first place, packets are subjected to the scrutiny of the rules in the NAT and filter tables.&lt;/p&gt;
&lt;p&gt;Packets destined for the host&amp;rsquo;s socket (the container&amp;rsquo;s mapped port) are processed by netfilter and tested against the rules in the &lt;code&gt;PREROUTING&lt;/code&gt; chain of the NAT table, and provided the destination address of a packet is local to the Docker host (which it is), netfilter jumps to the DOCKER chain for further processing. As long as the packet didn&amp;rsquo;t arrive from the ethernet bridge (i.e. from a container), and provided the packet is addressed to TCP port &lt;code&gt;8000&lt;/code&gt; on the Docker host, then its destination is changed to &lt;code&gt;172.17.0.2:8000&lt;/code&gt; by the DNAT target - which is the container socket. As the packet needs to be routed to the container, the rules in the &lt;code&gt;FORWARD&lt;/code&gt; chain of the filter table are assessed:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;num   pkts bytes target     prot opt in       out      source              destination         
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1       63 10326 DOCKER     all  --  *        docker0  0.0.0.0/0           0.0.0.0/0           
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2       50  9618 ACCEPT     all  --  *        docker0  0.0.0.0/0           0.0.0.0/0            ctstate RELATED,ESTABLISHED
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3       61  5675 ACCEPT     all  --  docker0 !docker0  0.0.0.0/0           0.0.0.0/0           
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4        0     0 ACCEPT     all  --  docker0  docker0  0.0.0.0/0           0.0.0.0/0           
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Chain DOCKER (1 references)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;num   pkts bytes target     prot opt in       out      source              destination         
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1        0     0 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0           172.17.0.2           tcp dpt:8000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The first rule applies, which forces a jump to the &lt;code&gt;DOCKER&lt;/code&gt; chain, and the single rule in the chain matches the characteristics of the packet, and &amp;lsquo;accepts&amp;rsquo; the packet for forwarding on to the container&amp;rsquo;s socket. Hence, a remote service consuming process thinks it is communicating with the Docker host, but is being serviced by the container instead.&lt;/p&gt;
&lt;p&gt;Similarly, when a container initiates a dialogue with a remote service provider, netfilter&amp;rsquo;s NAT &lt;code&gt;POSTROUTING&lt;/code&gt; chain changes the source IP address of packets from the container&amp;rsquo;s IP address, to the address of the host&amp;rsquo;s network interface that is responsible for routing the packets to their required destination. This is achieved with netfilter&amp;rsquo;s MASQUERADE target.&lt;/p&gt;
&lt;p&gt;A Docker host makes significant use of netfilter rules to aid NAT, and to control access to the containers it hosts, and the &lt;code&gt;docker-proxy&lt;/code&gt; mechanism isn&amp;rsquo;t always required. However, there are certain circumstances where this method of control is not available, which is why Docker also creates an instance of the &lt;code&gt;docker-proxy&lt;/code&gt; whenever a container&amp;rsquo;s port is forwarded to the Docker host.&lt;/p&gt;
&lt;p&gt;Firstly, in order for a remote host to consume a container&amp;rsquo;s service, the Docker host must act like a router, forwarding traffic to the network associated with the ethernet bridge. A Linux host is not normally configured to be a router, so the kernel parameter &lt;code&gt;net.ipv4.ip_forward&lt;/code&gt; needs to be set to &lt;code&gt;1&lt;/code&gt; (&lt;code&gt;net.ipv6.conf.default.forwarding&lt;/code&gt; and &lt;code&gt;net.ipv6.conf.all.forwarding&lt;/code&gt; for IPv6). Docker takes care of this if its daemon is started with default settings. If, however, the daemon is started with the &lt;code&gt;--ip-forward&lt;/code&gt; and/or &lt;code&gt;--iptables&lt;/code&gt; command line options set to &lt;code&gt;false&lt;/code&gt;, then Docker can&amp;rsquo;t make use of netfilter rules and has to fall back on the &lt;code&gt;docker-proxy&lt;/code&gt;. This scenario is probably quite rare, but it is conceivable that some corporate security policies may impose this constraint.&lt;/p&gt;
&lt;p&gt;Secondly, even when Docker is able to forward packets using netfilter rules, there is one circumstance where it is not possible to apply netfilter rules. Unless told otherwise, when a container&amp;rsquo;s port is forwarded to the Docker host, it will be forwarded to all of the host&amp;rsquo;s interfaces, including its loopback interface. But the Linux kernel does not allow the routing of loopback traffic, and therefore it&amp;rsquo;s not possible to apply netfilter NAT rules to packets originating from 127.0.0.0/8. Instead, netfilter sends packets through the filter table&amp;rsquo;s INPUT chain to a local process listening on the designated port - the &lt;code&gt;docker-proxy&lt;/code&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;docker-proxy&lt;/code&gt;, then, is a &amp;lsquo;catch all&amp;rsquo; method for allowing container port forwarding to the Docker host. However, it&amp;rsquo;s generally considered that the &lt;code&gt;docker-proxy&lt;/code&gt; is an inelegant solution to the problems highlighted above, and when a large range of container ports are exposed, it &lt;a href=&#34;https://github.com/docker/docker/issues/11185&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;consumes considerable memory&lt;/a&gt;. An attempt was previously made to remove the dependency for the &lt;code&gt;docker-proxy&lt;/code&gt;, but this fell foul of the &lt;a href=&#34;https://github.com/docker/docker/issues/9134&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;limitations&lt;/a&gt; of the aged kernel in RHEL 6.x and CentOS 6.x, which the Docker project feels duty bound to support. Hence, the &lt;code&gt;docker-proxy&lt;/code&gt; remains a major constituent part of the Docker experience in all Docker versions up to the current version 1.5. As I write, version 1.6 is due for imminent release, and there have been moves to remove the automatic requirement for the &lt;code&gt;docker-proxy&lt;/code&gt;, which I&amp;rsquo;ll cover in another article.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Update - &lt;a href=&#34;https://docs.docker.com/v17.09/engine/userguide/networking/default_network/binding/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Hairpin NAT Support&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>A Basic Container</title>
      <link>https://windsock.io/a-basic-container/</link>
      <pubDate>Wed, 25 Mar 2015 10:59:59 +0000</pubDate>
      
      <guid>https://windsock.io/a-basic-container/</guid>
      <description>&lt;p&gt;We&amp;rsquo;ve looked at five of the six available namespaces provided by the Linux kernel in a series of &lt;a href=&#34;https://windsock.io/introducing-namespaces&#34; &gt;previous articles&lt;/a&gt;, and we&amp;rsquo;ll take a look at the final namespace, the USER namespace, in a future article. This article looks at how we can combine a number of the namespaces with a specially prepared directory, in which we&amp;rsquo;ll &amp;lsquo;jail&amp;rsquo; our process using the &lt;code&gt;chroot&lt;/code&gt; system call. Although our implementation will be missing a few key features that normally accompany container implementations (e.g. cgroups), the resulting environment in which our process will run, can be considered a very rudimentary container of sorts. It isolates the process from several different system resources, and contains the process within a limited filesystem.&lt;/p&gt;
&lt;p&gt;The first thing we need to do is to prepare a directory on the host which will become the root filesystem for the container, which will be located at &lt;code&gt;/var/local/jail&lt;/code&gt;. We&amp;rsquo;re going to provide just a few binaries for the container to use; &lt;code&gt;env&lt;/code&gt;, &lt;code&gt;bash&lt;/code&gt;, &lt;code&gt;ps&lt;/code&gt;, &lt;code&gt;ls&lt;/code&gt; and &lt;code&gt;top&lt;/code&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s not just a simple matter of copying the binaries to &lt;code&gt;/var/local/jail&lt;/code&gt;, each binary relies on shared libraries, and we also need to ensure they are available in the appropriate directory in the container&amp;rsquo;s filesystem. To do this, we can make use of the &lt;code&gt;ldd&lt;/code&gt; command, whose purpose is to provide information regarding the shared libraries used by a particular binary. I&amp;rsquo;ve created a script called &lt;code&gt;binlibdepcp.sh&lt;/code&gt;, which takes care of determining the library dependencies for a binary, and then copying them along with the relevant libraries to the correct locations in the container&amp;rsquo;s filesystem. It also copies the &lt;code&gt;ld.so.cache&lt;/code&gt; file, which is the list of directories that is searched for libraries, in the event that a required library does not reside in &lt;code&gt;/lib&lt;/code&gt; or &lt;code&gt;/usr/lib&lt;/code&gt;. The script is available on &lt;a href=&#34;https://github.com/nbrownuk/Namespaces&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s demonstrate this for the &lt;code&gt;env&lt;/code&gt; binary, which is located at &lt;code&gt;/usr/bin/env&lt;/code&gt;. Having previously created the &lt;code&gt;/var/local/jail&lt;/code&gt; directory, the &lt;code&gt;env&lt;/code&gt; binary and libraries are copied to the correct location under &lt;code&gt;/var/local/jail&lt;/code&gt; with the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;$&lt;/span&gt; sudo &lt;span style=&#34;color:#81a1c1&#34;&gt;./&lt;/span&gt;binlibdepcp&lt;span style=&#34;color:#81a1c1&#34;&gt;.&lt;/span&gt;sh &lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;usr&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;bin&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;env &lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;var&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;local&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;jail
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;sudo&lt;span style=&#34;color:#eceff4&#34;&gt;]&lt;/span&gt; password &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;for&lt;/span&gt; wolf&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Copying &lt;span style=&#34;color:#81a1c1&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      env &lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;OK&lt;span style=&#34;color:#eceff4&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                libc&lt;span style=&#34;color:#81a1c1&#34;&gt;.&lt;/span&gt;so&lt;span style=&#34;color:#81a1c1&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;6&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;OK&lt;span style=&#34;color:#eceff4&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     ld&lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;linux&lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;x86&lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;64.&lt;/span&gt;so&lt;span style=&#34;color:#81a1c1&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;OK&lt;span style=&#34;color:#eceff4&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              ld&lt;span style=&#34;color:#81a1c1&#34;&gt;.&lt;/span&gt;so&lt;span style=&#34;color:#81a1c1&#34;&gt;.&lt;/span&gt;cache &lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;OK&lt;span style=&#34;color:#eceff4&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;......&lt;/span&gt; Done
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can repeat this exercise for the other binaries we intend to use within the container, which, more likely than not, are located in either &lt;code&gt;/usr/bin&lt;/code&gt; or &lt;code&gt;/bin&lt;/code&gt;. Additionally, so that our commands will display nicely when we run them inside the container, we need to provide the relevant portion of the terminfo database. Assuming we have an &lt;code&gt;xterm&lt;/code&gt;, we can copy this into the jail (the location of the &lt;code&gt;terminfo&lt;/code&gt; database varies from Linux distro to distro, so make sure to copy the files to the correct directory under &lt;code&gt;/var/local/jail&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;$&lt;/span&gt; sudo mkdir &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;p &lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;var&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;local&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;jail&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;lib&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;terminfo&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;x
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;sudo&lt;span style=&#34;color:#eceff4&#34;&gt;]&lt;/span&gt; password &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;for&lt;/span&gt; wolf&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;$&lt;/span&gt; sudo cp &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;p &lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;lib&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;terminfo&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;x&lt;span style=&#34;color:#81a1c1&#34;&gt;/*&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;var&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;local&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;jail&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;lib&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;terminfo&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;x
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s the container&amp;rsquo;s filesystem prepared. Now we need to amend the program we have slowly been developing whilst we&amp;rsquo;ve been looking at the properties of containers. The changes are available in the &lt;code&gt;invoke_ns6.c&lt;/code&gt; source file, which can be found &lt;a href=&#34;https://github.com/nbrownuk/Namespaces&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The first change is to add a new command line option, &lt;code&gt;-c&lt;/code&gt; which must be accompanied with a directory path, which will be the root of the jail:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Parse command line options and construct arguments
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// to be passed to childFunction
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;((&lt;/span&gt;option &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;getopt&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argc&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; argv&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;+hvpmu:ni:c:&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;))&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;switch&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;option&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;jail &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;path &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;malloc&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;sizeof&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;strlen&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;optarg&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;strcpy&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;path&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; optarg&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;i&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;strcmp&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;no&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; optarg&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;strcmp&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;yes&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; optarg&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#88c0d0&#34;&gt;fprintf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;stderr&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;%s: option requires valid argument -- &amp;#39;i&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#88c0d0&#34;&gt;usage&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;strcmp&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;yes&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; optarg&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWIPC&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;ipc &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;n&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWNET&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;u&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWUTS&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;hostname &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;malloc&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;sizeof&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;strlen&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;optarg&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;strcpy&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;hostname&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; optarg&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;m&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWNS&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;p&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWPID&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;v&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;verbose &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;h&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;usage&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_SUCCESS&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;default&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;usage&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The other main change is to add some code to ensure that if the &lt;code&gt;-c&lt;/code&gt; option is supplied, the cloned child process is jailed inside the directory with the &lt;code&gt;chroot&lt;/code&gt; system call. The &lt;code&gt;chroot&lt;/code&gt; system call changes the root directory of the child process, and we change the current working directory to that root directory, and then create a &lt;code&gt;/proc&lt;/code&gt; directory within it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// If specified, place process in chroot jail
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;jail&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;verbose&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;printf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: creating chroot jail&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;chroot&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;path&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: childFunction: chroot&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;verbose&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;printf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: changing directory into chroot jail&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;chdir&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: childFunction: chdir&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;access&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;/proc&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; F_OK&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;mkdir&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;/proc&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0555&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: childFunction: mkdir&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can now invoke our container (with a customised command prompt) with the following command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;$&lt;/span&gt; sudo &lt;span style=&#34;color:#81a1c1&#34;&gt;./&lt;/span&gt;invoke_ns &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;vpmu calculus &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;c &lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;var&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;local&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;jail env PS1&lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;\h [\W] &amp;#34;&lt;/span&gt; TERM&lt;span style=&#34;color:#81a1c1&#34;&gt;=$&lt;/span&gt;TERM bash &lt;span style=&#34;color:#81a1c1&#34;&gt;--&lt;/span&gt;norc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;sudo&lt;span style=&#34;color:#eceff4&#34;&gt;]&lt;/span&gt; password &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;for&lt;/span&gt; wolf&lt;span style=&#34;color:#eceff4&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;calculus &lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now that we have an interactive &lt;code&gt;bash&lt;/code&gt; command shell running inside the container, we can use the &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;ps&lt;/code&gt; and &lt;code&gt;top&lt;/code&gt; commands to verify we have a very minimal operating environment, if not a very useful one! It doesn&amp;rsquo;t take much imagination, however, to see the possibilities for containing independent workloads in minimal, lightweight containers.&lt;/p&gt;
&lt;p&gt;In reality, a process inside a container needs a few more things than we have provided in our rudimentary version. Thankfully, the excellent work that has been conducted in the open source community with projects like &lt;a href=&#34;https://www.docker.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Docker&lt;/a&gt; and &lt;a href=&#34;https://linuxcontainers.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;LXC&lt;/a&gt;, have taken the hard work out of creating and manipulating workloads within containers.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;You could also use the content of a root filesystem obtained from a suitable distro, e.g. &lt;a href=&#34;https://partner-images.canonical.com/core/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Ubuntu&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>IPC Namespace</title>
      <link>https://windsock.io/ipc-namespace/</link>
      <pubDate>Mon, 16 Feb 2015 16:02:00 +0000</pubDate>
      
      <guid>https://windsock.io/ipc-namespace/</guid>
      <description>&lt;p&gt;The IPC namespace is used for isolating System V IPC objects, and POSIX message queues. The clone flag used to achieve this is &lt;code&gt;CLONE_NEWIPC&lt;/code&gt;. We&amp;rsquo;ve adapted our program from &lt;a href=&#34;https://windsock.io/introducing-namespaces&#34; &gt;previous articles&lt;/a&gt;, to create a POSIX message queue, which will be used to pass a message between a process and its cloned child process.&lt;/p&gt;
&lt;p&gt;To demonstrate how the IPC namespace establishes isolation of a POSIX message queue, we&amp;rsquo;ll create a message queue in the parent process, and attempt to open it from within the child process, in order to send a message from the child to the parent process. We&amp;rsquo;ll do this once when the cloned child process remains in the global IPC namespace, and then when it is created within a new IPC namespace.&lt;/p&gt;
&lt;p&gt;So, first off, we need to embellish the program, which is available &lt;a href=&#34;https://github.com/nbrownuk/Namespaces&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;here&lt;/a&gt; (&lt;code&gt;invoke_ns5.c&lt;/code&gt;), with a new command line option, &lt;code&gt;-i&lt;/code&gt;. The &lt;code&gt;-i&lt;/code&gt; option must be accompanied with a string of either &amp;lsquo;&lt;code&gt;yes&lt;/code&gt;&amp;rsquo; or &amp;lsquo;&lt;code&gt;no&lt;/code&gt;&amp;rsquo;. If &amp;lsquo;&lt;code&gt;yes&lt;/code&gt;&amp;rsquo; is specified, the child process will be cloned in a new IPC namespace, and if &amp;lsquo;&lt;code&gt;no&lt;/code&gt;&amp;rsquo; is specified, it remains in the global IPC namespace.&lt;/p&gt;
&lt;p&gt;The command line parsing now looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Parse command line options and construct arguments
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// to be passed to childFunction
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;((&lt;/span&gt;option &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;getopt&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argc&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; argv&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;+hvpmu:ni:&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;))&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;switch&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;option&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;i&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;strcmp&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;no&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; optarg&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;strcmp&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;yes&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; optarg&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#88c0d0&#34;&gt;fprintf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;stderr&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;%s: option requires valid argument -- &amp;#39;i&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#88c0d0&#34;&gt;usage&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;strcmp&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;yes&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; optarg&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWIPC&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;ipc &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;n&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWNET&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;u&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWUTS&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;hostname &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;malloc&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;sizeof&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;char&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;strlen&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;optarg&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;strcpy&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;hostname&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; optarg&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;m&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWNS&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;p&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWPID&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;v&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;verbose &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;h&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;usage&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_SUCCESS&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;default&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;usage&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We also need to define the message queue name:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Define message queue name
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;*&lt;/span&gt;mq_name &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;/ipc_namespace&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If the &lt;code&gt;-i&lt;/code&gt; command line option has been specified, before making the call to &lt;code&gt;clone&lt;/code&gt;, the parent calls the &lt;code&gt;prepareMQ&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Prepare message queue
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;ipc&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    mq &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;prepareMQ&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;amp;&lt;/span&gt;args&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;mq &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;prepareMQ&lt;/code&gt; function creates a message queue (in the global IPC namespace), and opens it for reading and writing, with a maximum message size of 81 bytes (an extra byte for termination):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Prepare message queue
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;mqd_t&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;prepareMQ&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;*&lt;/span&gt;child_args&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;struct&lt;/span&gt; arguments &lt;span style=&#34;color:#81a1c1&#34;&gt;*&lt;/span&gt;args &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; child_args&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;mqd_t&lt;/span&gt;            mq&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1&#34;&gt;int&lt;/span&gt;              oflags &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; O_CREAT &lt;span style=&#34;color:#81a1c1&#34;&gt;|&lt;/span&gt; O_RDWR&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;struct&lt;/span&gt; mq_attr   attr&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    attr&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;mq_flags   &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    attr&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;mq_maxmsg  &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;10&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    attr&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;mq_msgsize &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;81&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    attr&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;mq_curmsgs &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    mq &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;mq_open&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;mq_name&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; oflags&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0644&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;amp;&lt;/span&gt;attr&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;mq &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;verbose&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;printf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;Parent: opening message queue %s&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; mq_name&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;Parent: prepareMQ: mq_open&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;return&lt;/span&gt; mq&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the message queue has been established, the child process is created with the &lt;code&gt;clone&lt;/code&gt; system call, and then the parent waits 60 seconds for a message from the child process, before timing out. If a message is received from the child process, the parent process echoes this to &lt;code&gt;stdout&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Read message from child on message queue
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;ipc&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;clock_gettime&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;CLOCK_REALTIME&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;amp;&lt;/span&gt;timeout&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        timeout&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;tv_sec &lt;span style=&#34;color:#81a1c1&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;60&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;mq_getattr&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;mq&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;amp;&lt;/span&gt;attr&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            msg &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;malloc&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;attr&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;mq_msgsize&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;mq_timedreceive&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;mq&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; msg&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; attr&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;mq_msgsize&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;NULL&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;amp;&lt;/span&gt;timeout&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;verbose&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#88c0d0&#34;&gt;printf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;Parent: received message from child&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#88c0d0&#34;&gt;printf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;    Parent: the following message was received from the child&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;     &amp;gt;&amp;gt; %s&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; msg&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;Parent: main: mq_timedreceive&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;free&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;msg&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;Parent: main: mq_getattr&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;Parent: main: clock_gettime&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the child process has terminated, the parent closes and removes the message queue:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Remove message queue
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;ipc&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;verbose&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;printf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;Parent: closing message queue %s&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; mq_name&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;mq_close&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;mq&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;Parent: main: mq_close&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;verbose&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;printf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;Parent: removing message queue %s&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; mq_name&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;mq_unlink&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;mq_name&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;Parent: main: mq_unlink&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With regard to the cloned child, we have added some additional code to the &lt;code&gt;childFunction&lt;/code&gt;, which gets executed when the child process is created. If the &lt;code&gt;-i&lt;/code&gt; command line option has been specified, the child attempts to open the message queue created by the parent, and prompts the user to enter a message, which is then sent to the message queue. If the child has got this far, it closes the message queue and continues to process the other namespace requirements:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Send message to parent if -i option provided
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;ipc&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;verbose&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;printf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: opening message queue %s&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; mq_name&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    mq &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;mq_open&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;mq_name&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; oflags&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;mq &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;mq_getattr&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;mq&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;amp;&lt;/span&gt;attr&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            msg &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;malloc&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;attr&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;mq_msgsize&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;printf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;     Child: enter a message to send to the parent process (MAX 80 chars)&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;     &amp;gt;&amp;gt; &amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;fgets&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;msg&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; attr&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;mq_msgsize&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; stdin&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;NULL&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                msg&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;strcspn&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;msg&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)]&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;\0&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#88c0d0&#34;&gt;printf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;verbose&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#88c0d0&#34;&gt;printf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: sending message to parent&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;mq_send&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;mq&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; msg&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; attr&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;mq_msgsize&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: childFunction: mq_send&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: childFunction: fgets&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;verbose&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#88c0d0&#34;&gt;printf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: closing message queue %s&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; mq_name&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;mq_close&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;mq&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: childFunction: mq_close&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;free&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;msg&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: childFunction: mq_getattr&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: childFunction: mq_open&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now let&amp;rsquo;s see what happens when we execute the program. First, we need to compile it, remembering to specify &lt;code&gt;-lrt&lt;/code&gt; in order to link the POSIX real-time library into the executable, which contains the message queue API. In the first instance we&amp;rsquo;ll specify &lt;code&gt;-i no&lt;/code&gt;, which means the cloned child process remains in the same IPC namespace as its parent, the global IPC namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo ./invoke_ns -vi no
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[sudo] password for wolf:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: PID of parent is 11944
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: opening message queue /ipc_namespace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: PID of child is 11945
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: PID of child is 11945
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: opening message queue /ipc_namespace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     Child: enter a message to send to the parent process (MAX 80 chars)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &amp;gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At this point, we need to type a message of up to 80 characters, perhaps &amp;hellip;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;I will return to haunt you with peculiar piano riffs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After hitting return, the message is sent to the message queue, which the parent reads, and echoes to &lt;code&gt;stdout&lt;/code&gt;. In this instance, because we have only specified the &lt;code&gt;-i no&lt;/code&gt; option, the child process exits, which triggers the parent to close and remove the message queue, before it exits:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     Child: enter a message to send to the parent process (MAX 80 chars)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &amp;gt;&amp;gt; I will return to haunt you with peculiar piano riffs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: sending message to parent
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: closing message queue /ipc_namespace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: received message from child
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Parent: the following message was received from the child
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &amp;gt;&amp;gt; I will return to haunt you with peculiar piano riffs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: closing message queue /ipc_namespace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: Removing message queue /ipc_namespace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: ./invoke_ns - Finishing up
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If we now run the program again, but this time specify &lt;code&gt;-i yes&lt;/code&gt; as the command line option, the child process will be created in a new IPC namespace and will not be able to open the message queue, because it can&amp;rsquo;t see it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo ./invoke_ns -vi yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[sudo] password for wolf:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: PID of parent is 12508
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: opening message queue /ipc_namespace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: PID of child is 12509
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: PID of child is 12509
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: opening message queue /ipc_namespace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: mq_open: No such file or directory
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After 60 seconds, the parent&amp;rsquo;s wait for reading the message queue times out:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: mq_timedreceive: Connection timed out
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: closing message queue /ipc_namespace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: Removing message queue /ipc_namespace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: ./invoke_ns - Finishing up
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each IPC namespace has its own message queue filesystem, which is only visible to processes residing in the same IPC namespace.&lt;/p&gt;
&lt;p&gt;In the &lt;a href=&#34;https://windsock.io/a-basic-container&#34; &gt;next article&lt;/a&gt;, we&amp;rsquo;ll look at cloning a process into several namespaces, along with a minimal chroot filesystem, in order to create a &amp;lsquo;rustic&amp;rsquo; container.
&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Network Namespace</title>
      <link>https://windsock.io/network-namespace/</link>
      <pubDate>Wed, 14 Jan 2015 20:04:00 +0000</pubDate>
      
      <guid>https://windsock.io/network-namespace/</guid>
      <description>&lt;p&gt;So far in this series, we&amp;rsquo;ve looked at isolating processes in &lt;a href=&#34;https://windsock.io/pid-namespace&#34; &gt;PID&lt;/a&gt;, &lt;a href=&#34;https://windsock.io/mnt-namespace&#34; &gt;mount&lt;/a&gt; and &lt;a href=&#34;https://windsock.io/uts-namespace&#34; &gt;UTS&lt;/a&gt; namespaces. The next namespace in this sequence is the network namespace, which allows you to isolate a process in terms of its network stack. That is, a process that is cast into a new network namespace using one of the system calls &lt;code&gt;clone&lt;/code&gt; or &lt;code&gt;unshare&lt;/code&gt;, or an existing network namespace with &lt;code&gt;setns&lt;/code&gt;, are isolated from the host&amp;rsquo;s network stack, but enjoy their own private network stack associated with the namespace. The resources that are isolated include routes, firewall rules, network devices, and ports.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve been developing a program to demonstrate how each of the namespaces work, and the changes that incorporate the network namespace can be found in &lt;code&gt;invoke_ns4.c&lt;/code&gt;, which is available &lt;a href=&#34;https://github.com/nbrownuk/Namespaces&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;here&lt;/a&gt;. The changes that have been made from the last iteration are trivial; we&amp;rsquo;ve added a new command line option, &lt;code&gt;-n&lt;/code&gt;, which specifies that the cloned process is to be created in a new network namespace, and the addition of the &lt;code&gt;CLONE_NEWNET&lt;/code&gt; constant to the clone flags when parsing the command line options:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Parse command line options and construct arguments
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// to be passed to childFunction
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;((&lt;/span&gt;option &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;getopt&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argc&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; argv&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;+hvpmu:n&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;))&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;switch&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;option&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;n&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWNET&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;u&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWUTS&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;hostname &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;malloc&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;sizeof&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;char&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;strlen&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;optarg&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;strcpy&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;hostname&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; optarg&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;m&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWNS&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;p&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWPID&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;v&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;verbose &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;h&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;usage&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_SUCCESS&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;default&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;usage&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the new version of the program has been compiled, we can invoke it with the following command line options and arguments:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo ./invoke_ns -vpmnu calculus env PS1=&amp;#34;\h\[\] [\[\]\w\[\]] &amp;#34; PATH=$PATH bash --norc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[sudo] password for wolf:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: PID of parent is 6142
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: PID of child is 6143
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: PID of child is 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: Executing command bash ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;calculus [/home/wolf]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The cloned process is created in a number of namespaces, including a new network namespace. Just as we&amp;rsquo;ve done in the previous examples, we can confirm that the process resides in its own network namespace, distinct from the global network namespace of all the other processes running on the system:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo ls -l /proc/6142/ns &amp;amp;&amp;amp; sudo ls -l /proc/6143/ns
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[sudo] password for wolf:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;total 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar 12 12:21 ipc -&amp;gt; ipc:[4026531839]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar 12 12:21 mnt -&amp;gt; mnt:[4026531840]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar 12 12:21 net -&amp;gt; net:[4026531956]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar 12 12:21 pid -&amp;gt; pid:[4026531836]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar 12 12:21 user -&amp;gt; user:[4026531837]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar 12 12:21 uts -&amp;gt; uts:[4026531838]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;total 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar 12 12:21 ipc -&amp;gt; ipc:[4026531839]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar 12 12:21 mnt -&amp;gt; mnt:[4026532430]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar 12 12:21 net -&amp;gt; net:[4026532434]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar 12 12:21 pid -&amp;gt; pid:[4026532432]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar 12 12:21 user -&amp;gt; user:[4026531837]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar 12 12:21 uts -&amp;gt; uts:[4026532431]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At the &lt;code&gt;bash&lt;/code&gt; command prompt of the cloned process, we can see what the new network namespace provides the process:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;calculus [/home/wolf] ip link show
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1: lo: &amp;lt;LOOPBACK&amp;gt; mtu 65536 qdisc noop state DOWN mode DEFAULT qlen 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The kernel has simply provided a loopback interface, which we can bring up with &lt;code&gt;ip link set lo up&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is very spartan, and it is up to the initiator to configure a meaningful network stack for the namespace. Assuming that we want any processes running in the new network namespace to be able to communicate beyond the boundaries of the namespace, then we need to establish a &amp;rsquo;tunnel&amp;rsquo; between the global network namespace and our newly created network namespace.&lt;/p&gt;
&lt;p&gt;To do this, we can create a pair of virtual ethernet interfaces (veth pair), one which will reside in the new network namespace, and one that will reside in the global network namespace. The pair of interfaces are linked to one another like a pipe, and whatever appears at one end, finds its way to the other end.&lt;/p&gt;
&lt;p&gt;The veth pair is created in the global network namespace, and then we need to move one of the interfaces into our new network namespace. We&amp;rsquo;ll call the interface that will reside in the global network namespace, &amp;lsquo;&lt;code&gt;host&lt;/code&gt;&amp;rsquo;, whilst the interface that is to be moved to the new network namespace will be called &amp;lsquo;&lt;code&gt;guest&lt;/code&gt;&amp;rsquo;. In a &lt;code&gt;bash&lt;/code&gt; command shell which resides in the global network namespace, we use the following to create the veth pair:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo ip link add host type veth peer name guest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When this is done, we can see the newly created veth pair by listing the interfaces available in the global network namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ip link show
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2: enp0s3: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    link/ether 08:00:27:fd:d7:6a brd ff:ff:ff:ff:ff:ff
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3: guest@host: &amp;lt;BROADCAST,MULTICAST,M-DOWN&amp;gt; mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    link/ether 4a:47:28:07:d4:d6 brd ff:ff:ff:ff:ff:ff
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4: host@guest: &amp;lt;BROADCAST,MULTICAST,M-DOWN&amp;gt; mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    link/ether de:7b:af:36:05:e3 brd ff:ff:ff:ff:ff:ff
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In order to move the &amp;lsquo;&lt;code&gt;guest&lt;/code&gt;&amp;rsquo; interface into the new network namespace, we need to use the PID of the cloned child process, as it is in the global network namespace, that is &lt;code&gt;6143&lt;/code&gt;. The command simply moves the interface called &amp;lsquo;&lt;code&gt;guest&lt;/code&gt;&amp;rsquo; into the network namespace which PID &lt;code&gt;6143&lt;/code&gt; resides in:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo ip link set guest netns 6143
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can check that this has been accomplished by issuing the &lt;code&gt;ip link show&lt;/code&gt; command in both network namespaces. In the global network namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ip link show
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2: enp0s3: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    link/ether 08:00:27:fd:d7:6a brd ff:ff:ff:ff:ff:ff
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4: host@if3: &amp;lt;BROADCAST,MULTICAST&amp;gt; mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    link/ether de:7b:af:36:05:e3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And in the new network namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;calculus [/home/wolf] ip link show
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3: guest@if4: &amp;lt;BROADCAST,MULTICAST&amp;gt; mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    link/ether 4a:47:28:07:d4:d6 brd ff:ff:ff:ff:ff:ff link-netnsid 0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can assign an IP address to each of the interfaces in the veth pair. In the new network namespace, we can execute the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;calculus [/home/wolf] ip addr add 10.0.0.2/24 dev guest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;calculus [/home/wolf] ip link set guest up
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;calculus [/home/wolf] ip addr show guest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3: guest@if4: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 1500 qdisc noqueue state LOWERLAYERDOWN qlen 1000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    link/ether 4a:47:28:07:d4:d6 brd ff:ff:ff:ff:ff:ff link-netnsid 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    inet 10.0.0.2/24 scope global guest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       valid_lft forever preferred_lft forever
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And in the global network namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo ip addr add 10.0.0.1/24 dev host
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[wolf@centos ~]$ sudo ip link set host up
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[wolf@centos ~]$ ip addr show host
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4: host@if3: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP qlen 1000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    link/ether de:7b:af:36:05:e3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    inet 10.0.0.1/24 scope global host
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       valid_lft forever preferred_lft forever
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    inet6 fe80::dc7b:afff:fe36:5e3/64 scope link 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       valid_lft forever preferred_lft forever
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, we can check that each interface is reachable from the other by pinging from each end.&lt;/p&gt;
&lt;p&gt;In order to make a network namespace more useful, additional work would need to be carried out to establish a suitable network configuration for a specific purpose, e.g. creating a bridge on the host for bridging to a physical network interface.&lt;/p&gt;
&lt;p&gt;In the &lt;a href=&#34;https://windsock.io/ipc-namespace&#34; &gt;next article&lt;/a&gt;, we&amp;rsquo;ll take a look at the IPC namespace.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Additional notes on network namespaces&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Physical network interfaces can only exist in one network namespace at a time, and are returned to the global network namespace as and when the network namespace they reside in, terminates.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>UTS Namespace</title>
      <link>https://windsock.io/uts-namespace/</link>
      <pubDate>Tue, 30 Dec 2014 17:11:00 +0000</pubDate>
      
      <guid>https://windsock.io/uts-namespace/</guid>
      <description>&lt;p&gt;The UTS namespace is used to isolate two specific elements of the system that relate to the &lt;code&gt;uname&lt;/code&gt; system call. UTS is an abbreviation of &lt;a href=&#34;https://people.eecs.berkeley.edu/~brewer/cs262/unix.pdf&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;UNIX Time Sharing&lt;/a&gt;, a term that dates back to the fledgling days of UNIX, when multi-user, multi-tasking operating systems were a novelty.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;&lt;img src=&#34;https://windsock.io/images/KThompsonDRitchie.jpg&#34;
    alt=&#34;Ken Thompson &amp;amp; Dennis Ritchie&#34;&gt;&lt;figcaption&gt;
      &lt;p&gt;Ken Thompson &amp;amp; Dennis Ritchie&lt;/p&gt;
    &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The UTS namespace is named after the data structure used to store information returned by the &lt;code&gt;uname&lt;/code&gt; system call. Specifically, the UTS namespace isolates the hostname and the NIS domain name. &lt;a href=&#34;https://en.wikipedia.org/wiki/Network_Information_Service&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;NIS&lt;/a&gt;, an abbreviation of Network Information Service, is an outdated directory service created by &lt;a href=&#34;https://en.wikipedia.org/wiki/Sun_Microsystems&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Sun Microsystems&lt;/a&gt; for the Solaris operating system, which was discontinued by Oracle after its acquisition of Sun Microsystems. In short, the UTS namespace is about isolating hostnames.&lt;/p&gt;
&lt;p&gt;To demonstrate its use, the program we used in the &lt;a href=&#34;https://windsock.io/mnt-namespace&#34; &gt;last article&lt;/a&gt; about the mount namespace, has been further adapted as &lt;code&gt;invoke_ns3.c&lt;/code&gt;, and is available &lt;a href=&#34;https://github.com/nbrownuk/Namespaces&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;here&lt;/a&gt;. Unsurprisingly, we&amp;rsquo;ve added a new command line option to our program, &lt;code&gt;-u&lt;/code&gt;, which must be accompanied with a string that will be used to set the hostname in our newly created UTS namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ./invoke_ns -h
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Usage: ./invoke_ns [options] [cmd [arg...]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Options can be:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -h           display this help message
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -v           display verbose messages
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -p           new PID namespace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -m           new MNT namespace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -u hostname  new UTS namespace with associated hostname
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ve added some code to parse the command line when &lt;code&gt;-u&lt;/code&gt; is specified, which adds the &lt;code&gt;CLONE_NEWUTS&lt;/code&gt; constant to the clone flags, and stores the hostname in some dynamically allocated memory. The pointer to the memory is passed as part of the &lt;code&gt;args&lt;/code&gt; structure to the &lt;code&gt;clone&lt;/code&gt; system call, which provides the arguments to &lt;code&gt;childFunction&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Parse command line options and construct arguments
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// to be passed to childFunction
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;((&lt;/span&gt;option &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;getopt&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argc&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; argv&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;+hvpmu:&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;))&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;switch&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;option&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;u&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWUTS&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;hostname &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;malloc&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;sizeof&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;char&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;strlen&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;optarg&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;strcpy&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;hostname&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; optarg&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;m&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWNS&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;p&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWPID&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;v&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;verbose &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;h&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;usage&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_SUCCESS&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;default&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;usage&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In order to set the hostname inside the new UTS namespace, we need to add some code to &lt;code&gt;childFunction&lt;/code&gt; using the &lt;code&gt;sethostname&lt;/code&gt; system call:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Set new hostname in UTS namespace if applicable
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;flags &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;amp;&lt;/span&gt; CLONE_NEWUTS&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;sethostname&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;hostname&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;strlen&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;hostname&lt;span style=&#34;color:#eceff4&#34;&gt;))&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: childFunction: sethostname&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Having compiled &lt;code&gt;invoke_ns3.c&lt;/code&gt;, we can run the program with &lt;code&gt;sudo ./invoke_ns -vpmu calculus env PS1=&#39;\h\[\] [\[\]\w\[\]] &#39; bash&lt;/code&gt;, which will set the hostname inside the new UTS namespace as &amp;lsquo;calculus&amp;rsquo;. As part of the command that&amp;rsquo;s specified for the cloned process to run, we&amp;rsquo;ve set the &lt;code&gt;bash&lt;/code&gt; shell prompt (using the environment variable &lt;code&gt;PS1&lt;/code&gt;) to include the hostname, which is, of course, &amp;lsquo;calculus&amp;rsquo;. We can also use the &lt;code&gt;hostname&lt;/code&gt; command to echo the hostname set for the UTS namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo ./invoke_ns -vpmu calculus env PS1=&amp;#39;\h\[\] [\[\]\w\[\]] &amp;#39; bash --norc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: PID of parent is 16375
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: PID of child is 16376
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: PID of child is 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: executing command env ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;calculus [/home/wolf] hostname
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;calculus 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Hence, it&amp;rsquo;s possible to provide processes running on a given host system, an entirely different identity in terms of hostname, provided they exist in their own unique UTS namespace.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://windsock.io/net-namespace&#34; &gt;next article&lt;/a&gt; will cover the NET namespace.
&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Mount Namespace</title>
      <link>https://windsock.io/mount-namespace/</link>
      <pubDate>Fri, 19 Dec 2014 11:49:00 +0000</pubDate>
      
      <guid>https://windsock.io/mount-namespace/</guid>
      <description>&lt;p&gt;In the &lt;a href=&#34;https://windsock.io/pid-namespace&#34; &gt;last article&lt;/a&gt; about namespaces, we looked at the PID namespace. This time, we&amp;rsquo;ll take a look at the mount namespace.&lt;/p&gt;
&lt;p&gt;Mount namespaces isolate a set of mount points for a process or processes in a given namespace, providing the opportunity for different processes on a system to have different views of the host&amp;rsquo;s filesystem. When a new mount namespace is created with either of the system calls &lt;code&gt;clone&lt;/code&gt; or &lt;code&gt;unshare&lt;/code&gt;, it is done so with a copy of the set of mounts that exist in the mount namespace where the calling process resides. Any subsequent changes to the set of mounts in the &amp;lsquo;parent&amp;rsquo; or &amp;lsquo;child&amp;rsquo; mount namespaces, are not reflected in the other &amp;hellip;. unless the mount is a &lt;a href=&#34;https://lwn.net/Articles/689856/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;shared mount&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the article where we discussed PID namespaces, we discovered that the process we cloned into a new PID namespace, appeared as if it resided in the PID namespace of its parent. This is because the parent and child processes share the same mount namespace and view of the filesystem, and when we listed the contents of &lt;code&gt;/proc/$$/ns&lt;/code&gt; for the process in the new PID namespace (which has PID 1), we actually listed the namespaces for the &amp;lsquo;init&amp;rsquo; process in the global PID namespace! That&amp;rsquo;s very confusing.&lt;/p&gt;
&lt;p&gt;To get around this problem, as well as cloning our process into a new PID namespace, we&amp;rsquo;ll also create a new mount namespace for it at the same time, and mount a new &lt;a href=&#34;https://man7.org/linux/man-pages/man5/procfs.5.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;procfs&lt;/code&gt;&lt;/a&gt;. The program we started with in the previous article, has been adapted as &lt;code&gt;invoke_ns2.c&lt;/code&gt;, and can be downloaded &lt;a href=&#34;https://github.com/nbrownuk/Namespaces&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are a couple of trivial changes; the first is the addition of the &lt;code&gt;-m&lt;/code&gt; command line option to specify creation of a new mount namespace, and the second is the parsing of that option, which adds the &lt;code&gt;CLONE_NEWNS&lt;/code&gt; constant to the clone flags:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Parse command line options and construct arguments
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// to be passed to childFunction
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;((&lt;/span&gt;option &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;getopt&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argc&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; argv&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;+hvpm&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;))&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;switch&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;option&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;m&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWNS&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;p&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWPID&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;v&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;verbose &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;h&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;usage&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_SUCCESS&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;default&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;usage&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice that the clone flag constant for the mount namespace does not follow the convention associated with the constants for the other namespace types, i.e. &lt;code&gt;CLONE_NEWTYPE&lt;/code&gt;. Instead of &lt;code&gt;CLONE_NEWMNT&lt;/code&gt;, it is &lt;code&gt;CLONE_NEWNS&lt;/code&gt;, and that&amp;rsquo;s because it was the first to appear in the kernel, and points to the notion that there may not have been other namespaces planned at that point in time.&lt;/p&gt;
&lt;p&gt;The bigger change to the program, is the following addition to the &lt;code&gt;childFunction&lt;/code&gt;, which gets called by the child process:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Mount new proc instance in new mount namespace if and only if
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// the child exists in both a new PID and mount namespace
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;((&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;flags &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;amp;&lt;/span&gt; CLONE_NEWPID&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;flags &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;amp;&lt;/span&gt; CLONE_NEWNS&lt;span style=&#34;color:#eceff4&#34;&gt;))&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;mount&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;/proc&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; MS_REC&lt;span style=&#34;color:#81a1c1&#34;&gt;|&lt;/span&gt;MS_PRIVATE&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;NULL&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: childFunction: mount&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;mount&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;proc&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;/proc&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;proc&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;NULL&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: childFunction: mount&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This code makes the mount private to the new namespace (systemd makes all mounts &amp;lsquo;shared&amp;rsquo; by default), and mounts a new &lt;code&gt;procfs&lt;/code&gt; at &lt;code&gt;/proc&lt;/code&gt; within the newly created mount namespace. Having compiled the modified code contained in &lt;code&gt;invoke_ns2.c&lt;/code&gt;, we can run the program with the additional argument:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo ./invoke_ns -vpm env PS1=&amp;#34;ns # &amp;#34; bash --norc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[sudo] password for wolf: 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: PID of parent is 16179
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: PID of child is 16180
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: PID of child is 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: executing command env ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ns #
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On the face of it, nothing is any different to the version we ran when we were looking at PID namespaces. Listing the namespace directories for the parent and child in the global namespace yields:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo ls -l /proc/16179/ns &amp;amp;&amp;amp; sudo ls -l /proc/16180/ns
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[sudo] password for wolf: 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;total 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:07 ipc -&amp;gt; ipc:[4026531839]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:07 mnt -&amp;gt; mnt:[4026531840]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:07 net -&amp;gt; net:[4026531956]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:07 pid -&amp;gt; pid:[4026531836]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:07 user -&amp;gt; user:[4026531837]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:07 uts -&amp;gt; uts:[4026531838]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;total 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:07 ipc -&amp;gt; ipc:[4026531839]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:07 mnt -&amp;gt; mnt:[4026532118]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:07 net -&amp;gt; net:[4026531956]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:07 pid -&amp;gt; pid:[4026532173]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:07 user -&amp;gt; user:[4026531837]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:07 uts -&amp;gt; uts:[4026531838]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As expected, the parent and child processes reside in different PID and mount namespaces. When listing the namespaces from the &lt;code&gt;bash&lt;/code&gt; command shell prompt of the child process within the new namespaces, however, we get what we expect this time:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ns # ls -l /proc/$$/ns
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;total 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:09 ipc -&amp;gt; ipc:[4026531839]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:09 mnt -&amp;gt; mnt:[4026532118]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:09 net -&amp;gt; net:[4026531956]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:09 pid -&amp;gt; pid:[4026532173]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:09 user -&amp;gt; user:[4026531837]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 13:09 uts -&amp;gt; uts:[4026531838]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;PID &lt;code&gt;1&lt;/code&gt; within the new PID and mount namespaces, reports exactly the same as PID &lt;code&gt;16180&lt;/code&gt; in the global namespaces; they are a representation of the same process. Additionally, if we do a process listing inside the new namespaces, we get just two processes, the &lt;code&gt;bash&lt;/code&gt; command shell and &lt;code&gt;ps&lt;/code&gt; itself:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ns # ps
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  PID TTY          TIME CMD
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    1 pts/0    00:00:00 bash
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    3 pts/0    00:00:00 ps
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the &lt;a href=&#34;https://windsock.io/uts-namespace&#34; &gt;next article&lt;/a&gt;, we&amp;rsquo;ll take a look at the UTS namespace.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>PID Namespace</title>
      <link>https://windsock.io/pid-namespace/</link>
      <pubDate>Sun, 14 Dec 2014 14:26:00 +0000</pubDate>
      
      <guid>https://windsock.io/pid-namespace/</guid>
      <description>&lt;p&gt;A PID namespace isolates process ID (PID) numbers, thereby allowing different processes running on the same Linux system to have the same PID. Processes with the same PID, don&amp;rsquo;t clash however, because they are isolated from each other by virtue of existing in different PID namespaces.&lt;/p&gt;
&lt;p&gt;To demonstrate how they work, we&amp;rsquo;ll use a C program using the &lt;a href=&#34;https://man7.org/linux/man-pages/man2/clone.2.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;clone&lt;/code&gt;&lt;/a&gt; system call, which can be downloaded from &lt;a href=&#34;https://github.com/nbrownuk/Namespaces&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub&lt;/a&gt;. We&amp;rsquo;ll develop the program in future articles to demonstrate the other namespaces. Let&amp;rsquo;s take a look at the key parts of the first iteration of the program, &lt;code&gt;invoke_ns1.c&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Firstly, having compiled it &lt;code&gt;gcc -o invoke_ns ./invoke_ns1.c&lt;/code&gt;, use of the program can be established by executing &lt;code&gt;./invoke_ns -h&lt;/code&gt;. This provides:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Usage: ./invoke_ns [options] [cmd [arg...]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Options can be:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -h           display this help message
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -v           display verbose messages
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -p           new PID namespace
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As well as the &lt;code&gt;-h&lt;/code&gt; option, the program also takes a &lt;code&gt;-p&lt;/code&gt; option to specify the creation of a new PID namespace for the new cloned process, and a &lt;code&gt;-v&lt;/code&gt; option to specify verbosity, which is useful for understanding what is happening as the program executes. The program also takes an optional command and associated arguments to execute in the cloned process within the new namespace.&lt;/p&gt;
&lt;p&gt;If the &lt;code&gt;-p&lt;/code&gt; command line option is used, a flag is set with the &lt;code&gt;CLONE_NEWPID&lt;/code&gt; constant, which will ultimately get passed to the &lt;code&gt;clone&lt;/code&gt; system call:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Parse command line options and construct arguments
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// to be passed to childFunction
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;((&lt;/span&gt;option &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;getopt&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argc&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; argv&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;+hvp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;))&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;switch&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;option&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;p&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|=&lt;/span&gt; CLONE_NEWPID&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;v&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;verbose &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;break&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#39;h&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;usage&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_SUCCESS&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;default&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;usage&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the command line options have been processed, if a command and associated arguments have been provided to the program at the command line, these are copied into some memory allocated for the purpose. The pointer to the memory block, &lt;code&gt;args.command&lt;/code&gt;, along with some other information, will be another argument to the &lt;code&gt;clone&lt;/code&gt; system call:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Assemble command to be executed in namespace
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;optind &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; argc&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;command &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;malloc&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;sizeof&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argc &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt; optind &lt;span style=&#34;color:#81a1c1&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;i &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; optind&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt; i &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;lt;&lt;/span&gt; argc&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt; i&lt;span style=&#34;color:#81a1c1&#34;&gt;++&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;command&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;i &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt; optind&lt;span style=&#34;color:#eceff4&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;malloc&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;strlen&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;i&lt;span style=&#34;color:#eceff4&#34;&gt;])&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;strcpy&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;command&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;i &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt; optind&lt;span style=&#34;color:#eceff4&#34;&gt;],&lt;/span&gt; argv&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;i&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    args&lt;span style=&#34;color:#eceff4&#34;&gt;.&lt;/span&gt;command&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;argc &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt; optind&lt;span style=&#34;color:#eceff4&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;NULL&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Just before the call to &lt;code&gt;clone&lt;/code&gt;, we need to allocate a unique memory block to act as the stack for the child process that will get created, so that it doesn&amp;rsquo;t interfere with the stack associated with the parent:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Allocate heap for child&amp;#39;s stack
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;child_stack &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;malloc&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;STACK_SIZE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;child_stack &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;NULL&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;Parent: main: malloc&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, we get to execute the &lt;code&gt;clone&lt;/code&gt; system call:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Clone child process
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;child &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;clone&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;childFunction&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; child_stack &lt;span style=&#34;color:#81a1c1&#34;&gt;+&lt;/span&gt; STACK_SIZE&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; flags &lt;span style=&#34;color:#81a1c1&#34;&gt;|&lt;/span&gt; SIGCHLD&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;amp;&lt;/span&gt;args&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;childFunction&lt;/code&gt; argument is a function that gets executed by the child process after it has been created. We&amp;rsquo;ll discuss this further in a moment. The other arguments include a pointer to the child&amp;rsquo;s stack, the &amp;lsquo;clone flags&amp;rsquo;, and our command and arguments and ancillary information, which will be passed to the &lt;code&gt;childFunction&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Staying with the parent process for the moment, if the &lt;code&gt;clone&lt;/code&gt; system call is successful, it waits for the child process to terminate, before the program exits:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Wait for child to finish
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;waitpid&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;child&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;NULL&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;Parent: main: waitpid&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the meantime, the &lt;code&gt;clone&lt;/code&gt; system call has created a new, child process within a new PID namespace, which calls the function &lt;code&gt;childFunction&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Function passed to the clone system call
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;childFunction&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#81a1c1&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;*&lt;/span&gt;child_args&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;struct&lt;/span&gt; arguments &lt;span style=&#34;color:#81a1c1&#34;&gt;*&lt;/span&gt;args &lt;span style=&#34;color:#81a1c1&#34;&gt;=&lt;/span&gt; child_args&lt;span style=&#34;color:#eceff4&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;verbose&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;printf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: PID of child is %d&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#88c0d0&#34;&gt;getpid&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;// Execute command if given
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#616e87;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;command &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;NULL&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#88c0d0&#34;&gt;clearenv&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;fprintf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;stderr&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: childFunction: couldn&amp;#39;t clear environment&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;verbose&lt;span style=&#34;color:#eceff4&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#88c0d0&#34;&gt;printf&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: executing command %s ...&lt;/span&gt;&lt;span style=&#34;color:#ebcb8b&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;,&lt;/span&gt; args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;command&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;execvp&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;command&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;],&lt;/span&gt; &lt;span style=&#34;color:#81a1c1&#34;&gt;&amp;amp;&lt;/span&gt;args&lt;span style=&#34;color:#81a1c1&#34;&gt;-&amp;gt;&lt;/span&gt;command&lt;span style=&#34;color:#eceff4&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b48ead&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#81a1c1;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_SUCCESS&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#88c0d0&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a3be8c&#34;&gt;&amp;#34; Child: childFunction: execvp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#88c0d0&#34;&gt;exit&lt;/span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;(&lt;/span&gt;EXIT_FAILURE&lt;span style=&#34;color:#eceff4&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#eceff4&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Its purpose is to simply execute the command and its arguments, if one has been provided at the command line. It does this using the &lt;a href=&#34;https://man7.org/linux/man-pages/man3/execvp.3.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;execvp&lt;/code&gt;&lt;/a&gt; system call, which replaces the process image with a new one based on the command provided. That&amp;rsquo;s it! Let&amp;rsquo;s see how it works in practice.&lt;/p&gt;
&lt;p&gt;First, some information regarding how to determine which namespace a process is running in. Each namespace for a given process is represented by a file in the &lt;code&gt;procfs&lt;/code&gt; directory &lt;code&gt;/proc/$$/ns&lt;/code&gt; where &lt;code&gt;$$&lt;/code&gt; is the PID of the process in question. For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ls -l /proc/$$/ns
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;total 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 wolf wolf 0 Mar  9 15:29 ipc -&amp;gt; ipc:[4026531839]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 wolf wolf 0 Mar  9 15:29 mnt -&amp;gt; mnt:[4026531840]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 wolf wolf 0 Mar  9 15:29 net -&amp;gt; net:[4026531956]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 wolf wolf 0 Mar  9 15:29 pid -&amp;gt; pid:[4026531836]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 wolf wolf 0 Mar  9 15:29 user -&amp;gt; user:[4026531837]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 wolf wolf 0 Mar  9 15:29 uts -&amp;gt; uts:[4026531838]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The files are special symlinks bearing the namespace type (e.g. &lt;code&gt;mnt&lt;/code&gt;), which point to inodes which represent unique namespaces, which the kernel reports as a conjugation of the namespace type and the inode number. Hence, if two different processes exist in the same namespace, their symlinks will point to the same inodes.&lt;/p&gt;
&lt;p&gt;Every process exists in one namespace of each type, whether it is the global namespace (sometimes called the default or root namespace), or one that has been subsequently created using &lt;code&gt;clone&lt;/code&gt; or &lt;code&gt;unshare&lt;/code&gt;. You can test this out by starting two separate command shells and issuing the command &lt;code&gt;ls -l /proc/$$/ns&lt;/code&gt; in each, and comparing the results - the output from each should be identical, as both processes belong in the global PID namespace.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s create a new PID namespace for a cloned process using &lt;code&gt;invoke_ns&lt;/code&gt;, and let&amp;rsquo;s ascertain whether the child process exists in a new PID namespace. We can create the new PID namespace specifying that the child process execute an interactive &lt;code&gt;bash&lt;/code&gt; command shell:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo ./invoke_ns -vp env PS1=&amp;#34;ns # &amp;#34; bash --norc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[sudo] password for wolf: 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: PID of parent is 16034
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parent: PID of child is 16035
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: PID of child is 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Child: executing command env ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ns # 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that we have to be a privileged user to create the PID namespace, the &lt;code&gt;CAP_SYS_ADMIN&lt;/code&gt; capability is required. We&amp;rsquo;ve created the new PID namespace and specified that an interactive &lt;code&gt;bash&lt;/code&gt; command shell be executed using the command prompt &amp;lsquo;&lt;code&gt;ns #&lt;/code&gt;&amp;rsquo;. The parent process reports that it has a PID of &lt;code&gt;16034&lt;/code&gt;, and that the cloned child process has a PID of &lt;code&gt;16035&lt;/code&gt;. The child, however, reports that it has a PID of &lt;code&gt;1&lt;/code&gt;, and is executing the command &amp;lsquo;&lt;code&gt;env ...&lt;/code&gt;&amp;rsquo;. Although the child process exists in the newly created namespace, it also has a PID in the namespace from which it was created, in this case the global PID namespace.&lt;/p&gt;
&lt;p&gt;In a &lt;code&gt;bash&lt;/code&gt; command shell in the global PID namespace (i.e. not at the prompt &amp;lsquo;&lt;code&gt;ns #&lt;/code&gt;&amp;rsquo;), we can list the namespaces for the parent (&lt;code&gt;16034&lt;/code&gt;) and child (&lt;code&gt;16035&lt;/code&gt;) processes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo ls -l /proc/16034/ns &amp;amp;&amp;amp; sudo ls -l /proc/16035/ns
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[sudo] password for wolf: 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;total 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 10:52 ipc -&amp;gt; ipc:[4026531839]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 10:52 mnt -&amp;gt; mnt:[4026531840]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 10:52 net -&amp;gt; net:[4026531956]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 10:52 pid -&amp;gt; pid:[4026531836]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 10:52 user -&amp;gt; user:[4026531837]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 10:52 uts -&amp;gt; uts:[4026531838]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;total 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 10:52 ipc -&amp;gt; ipc:[4026531839]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 10:52 mnt -&amp;gt; mnt:[4026531840]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 10:52 net -&amp;gt; net:[4026531956]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 10:52 pid -&amp;gt; pid:[4026532118]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 10:52 user -&amp;gt; user:[4026531837]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx. 1 root root 0 Sep  7 10:52 uts -&amp;gt; uts:[4026531838]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;All of the namespaces are identical, apart from the PID namespaces, which indicates that the the parent and child processes are in different PID namespaces. A strange thing happens, however, if we list the namespaces for a process from within our &lt;code&gt;bash&lt;/code&gt; command shell in the new PID namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ns # ls -l /proc/$$/ns
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;total 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar  9 17:03 ipc -&amp;gt; ipc:[4026531839]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar  9 17:03 mnt -&amp;gt; mnt:[4026531840]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar  9 17:03 net -&amp;gt; net:[4026531956]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar  9 17:03 pid -&amp;gt; pid:[4026531836]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar  9 17:03 user -&amp;gt; user:[4026531837]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 Mar  9 17:03 uts -&amp;gt; uts:[4026531838]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From within the new PID namespace, listing the namespaces suggests that the child process still exists in the global PID namespace (4026531836). Clearly this is a contradiction, and we&amp;rsquo;ll explain why this is in the &lt;a href=&#34;https://windsock.io/mnt-namespace&#34; &gt;next article&lt;/a&gt;, which discusses the Mount namespace.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Additional notes on PID namespaces&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When a new PID namespace is created, the first process that is created in the namespace is &amp;lsquo;init-like&amp;rsquo; in nature, and is given the PID 1. It is &amp;lsquo;init-like&amp;rsquo; in behaviour, because it assumes parenthood of any orphaned processes in the namespace, and when it terminates, all other processes which belong in the same namespace are terminated with the SIGKILL signal, and the namespace is subsequently removed.&lt;/p&gt;
&lt;p&gt;PID namespaces can be nested up to a &lt;a href=&#34;https://github.com/torvalds/linux/blob/f804b3159482eedbb4250b1e9248c308fb63b805/include/linux/pid_namespace.h#L16&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;depth of 32&lt;/a&gt;, and any given process in a descendent namespace, will have as many different PIDs as it has ancestors + a PID for the namespace in which it resides. A PID in a descendent namespace can be &amp;lsquo;seen&amp;rsquo; or operated on (subject to permissions) by processes in ancestor namespaces, and those in its own namespace, but not processes in sibling namespaces or descendent namespaces.
&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Introducing Namespaces</title>
      <link>https://windsock.io/introducing-the-namespaces/</link>
      <pubDate>Mon, 08 Dec 2014 16:09:00 +0000</pubDate>
      
      <guid>https://windsock.io/introducing-the-namespaces/</guid>
      <description>&lt;p&gt;The container abstraction has made a big entry into the world of software development, offering a method for streamlined feature delivery. You don&amp;rsquo;t necessarily need to know about the inner workings of containers in order to use them, but it can help when it comes to getting the best from them.&lt;/p&gt;
&lt;p&gt;In a series of articles I&amp;rsquo;ll be exploring one of the Linux kernel features that make containers possible; namespaces. &lt;a href=&#34;http://man7.org/linux/man-pages/man7/namespaces.7.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Linux namespaces&lt;/a&gt; provide the isolation features that are so important to the container abstraction. The series uncovers the different namespaces in turn, but starts with a general intro:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Introducing Namespaces (this article)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://windsock.io/pid-namespace&#34; &gt;PID Namespace&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://windsock.io/mount-namespace&#34; &gt;Mount Namespace&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://windsock.io/uts-namespace&#34; &gt;UTS Namespace&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://windsock.io/network-namespace&#34; &gt;Network Namespace&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://windsock.io/ipc-namespace&#34; &gt;IPC Namespace&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://windsock.io/a-basic-container&#34; &gt;A Basic Container&lt;/a&gt; (putting it all together)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;A namespace is effectively a means of isolating a set of names or identifiers, and is very familiar to software developers, as the concept is widely used, either &lt;a href=&#34;http://www.cplusplus.com/doc/tutorial/namespaces/#namespace&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;explicitly&lt;/a&gt; or &lt;a href=&#34;http://docstore.mik.ua/orelly/java-ent/jnut/ch02_11.htm&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;implicitly&lt;/a&gt;, in many different programming languages. Linux namespaces isolate processes, so that different processes have a different view of various system resources, according to the namespaces they belong to.&lt;/p&gt;
&lt;p&gt;Since the first namespace arrived in the Linux kernel in version 2.4.19 in 2002, as many as &lt;a href=&#34;https://www.kernel.org/doc/ols/2006/ols2006v1-pages-101-112.pdf&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;ten different namespaces&lt;/a&gt; have been proposed, but to date just six&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; have made it into the mainstream kernel. The namespaces that have been implemented are the Mount namespace, the UTS namespace, the PID namespace, the Network namespace, the IPC namespace, and the User namespace. Those missing from the original list are the security namespace, the security keys namespace, the device namespace, and the time namespace.&lt;/p&gt;
&lt;p&gt;The following table shows when each namespace arrived in the mainstream Linux kernel:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;strong&gt;Namespace&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Clone Flag&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Kernel&lt;/strong&gt;&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;&lt;strong&gt;Year&lt;/strong&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Mount&lt;/td&gt;
          &lt;td&gt;CLONE_NEWNS&lt;/td&gt;
          &lt;td&gt;2.4.19&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;2002&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;UTS&lt;/td&gt;
          &lt;td&gt;CLONE_NEWUTS&lt;/td&gt;
          &lt;td&gt;2.6.19&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;2006&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;PID&lt;/td&gt;
          &lt;td&gt;CLONE_NEWPID&lt;/td&gt;
          &lt;td&gt;2.6.24&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;2008&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Network&lt;/td&gt;
          &lt;td&gt;CLONE_NEWNET&lt;/td&gt;
          &lt;td&gt;2.6.29&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;2009&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;IPC&lt;/td&gt;
          &lt;td&gt;CLONE_NEWIPC&lt;/td&gt;
          &lt;td&gt;2.6.30&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;2009&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;User&lt;/td&gt;
          &lt;td&gt;CLONE_NEWUSER&lt;/td&gt;
          &lt;td&gt;3.8&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;2013&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;So, how do you place processes into namespaces? This is achieved with three different Linux system calls: &lt;code&gt;clone&lt;/code&gt;, &lt;code&gt;unshare&lt;/code&gt; and &lt;code&gt;setns&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;clone&lt;/code&gt; system call is a general purpose function for creating a new process (&amp;lsquo;child&amp;rsquo;) based on the calling process&amp;rsquo; (&amp;lsquo;parent&amp;rsquo;) context, which can be modified based on the flags passed, and can be used to specify a new namespace(s) in which the child is to exist.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;unshare&lt;/code&gt; system call is also a general purpose function, which can be used by a calling process to disassociate its shared context from other processes, and for our interest, place itself in a new namespace(s). In essence, the &lt;code&gt;clone&lt;/code&gt; system call creates a new process, whereas the &lt;code&gt;unshare&lt;/code&gt; system call doesn&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;Finally, the &lt;code&gt;setns&lt;/code&gt; system call allows a calling process to join a different, existing namespace, by specifying a file descriptor that relates to the namespace in question.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://windsock.io/pid-namespace&#34; &gt;next article&lt;/a&gt; looks at the PID namespace in more detail, and how the &lt;code&gt;clone&lt;/code&gt; system call is used to create a new PID namespace.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Update 2020-10-21; the Linux kernel now carries a &lt;a href=&#34;https://man7.org/linux/man-pages/man7/cgroup_namespaces.7.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Cgroup&lt;/a&gt; and &lt;a href=&#34;https://man7.org/linux/man-pages/man7/time_namespaces.7.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Time&lt;/a&gt; namespace.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title></title>
      <link>https://windsock.io/about/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://windsock.io/about/</guid>
      <description>&lt;h1 id=&#34;about&#34;&gt;
  About
  &lt;a class=&#34;heading-link&#34; href=&#34;#about&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h1&gt;
&lt;figure&gt;&lt;img src=&#34;https://windsock.io/images/nigel-circular.png&#34; width=&#34;25%&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;Thanks for dropping by! I&amp;rsquo;m &lt;strong&gt;Nigel Brown&lt;/strong&gt;, and I&amp;rsquo;m an independent trainer, author and consultant, with a particular interest in cloud native computing. I love technology and working out how things work, and my main aim here is to provide some technical insight and opinion into popular open source software projects.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m also for hire, and here are some of things I work on with cloud-native companies who I partner with.&lt;/p&gt;
&lt;h2 id=&#34;technical-writing&#34;&gt;
  Technical Writing
  &lt;a class=&#34;heading-link&#34; href=&#34;#technical-writing&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I do a lot of technical writing in the form of blog articles, tutorials and technical guides. This usually involves picking apart a tool or an approach, and then describing how it works, and the benefits it provides (or otherwise). Sometimes I do this in my own name, and other times I ghostwrite the content on behalf of someone else.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We brought on Nigel as a 3rd party writer to assist with articles, checklists, and guides for our website blog that specializes in up-to-date Cloud-Native technologies. Nigel delivers 3-4 articles monthly covering very niche topics in the Cloud-Native ecosystem that we are able to use for education of our audience as well as capture leads from downloadable gated content. Nigel is very knowledgeable in our space and delivers work quickly and accurately. Our Developers never have changes to make to the content he produces, which is astounding. Highly recommended!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Tommy Hobin, Inbound Marketing Manager, &lt;a href=&#34;https://www.giantswarm.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Giant Swarm&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;course-authoring&#34;&gt;
  Course Authoring
  &lt;a class=&#34;heading-link&#34; href=&#34;#course-authoring&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve written numerous technical training courses, both for &lt;a href=&#34;https://windsock.io/courses/&#34; &gt;myself&lt;/a&gt; and for partners. The material I create tends to relate to cloud-native technologies, and covers a number of different formats; slide creation, lab exercises, workshops, and video content.&lt;/p&gt;
&lt;h2 id=&#34;training-delivery&#34;&gt;
  Training Delivery
  &lt;a class=&#34;heading-link&#34; href=&#34;#training-delivery&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;As well as authoring course material, I also deliver technical training courses directly to my customers, as well as through the partners I work with. Training is delivered in classroom format, both on-site as well as in a virtual setting.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I really enjoy working with Nigel. Over the last few years he has contributed greatly to training delivery at CS with workshop facilitation and content creation. He is a really reliable, attentive and thoughtful collaborator, and we have built some truly great things together.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Ben Fakalogotoa, Training Delivery Manager, &lt;a href=&#34;https://www.container-solutions.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Container Solutions&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;If you&amp;rsquo;re short on bandwidth and need some reliable help with creating technical content, then I&amp;rsquo;d love to help! You can get in touch at nigel at windsock.io.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title></title>
      <link>https://windsock.io/courses/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://windsock.io/courses/</guid>
      <description>&lt;p&gt;Here are the video-based training courses that I&amp;rsquo;ve created; they&amp;rsquo;re hosted on &lt;a href=&#34;https://www.pluralsight.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Pluralsight&amp;rsquo;s technology learning platform&lt;/a&gt;. It requires a subscription, but you can try it out with a &lt;a href=&#34;https://www.pluralsight.com/pricing/free-trial&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;free 10-day trial&lt;/a&gt;.&lt;/p&gt;





&lt;div class=&#34;tabs tabs-left&#34;&gt;
  
  



&lt;style&gt;
  .tabs input#tab-0-0:checked ~ .tab-content-0-0 {
    display: block;
  }
&lt;/style&gt;

&lt;input type=&#34;radio&#34; class=&#34;tab-input&#34; name=&#34;tab-select-0&#34; id=&#34;tab-0-0&#34; checked/&gt;
&lt;label for=&#34;tab-0-0&#34; class=&#34;tab-label&#34;&gt;Cloud Native Training&lt;/label&gt;
&lt;div class=&#34;tab-content tab-content-0-0&#34;&gt;
  &lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.pluralsight.com/library/courses/kubernetes-gateway-api-role-based-ingress-configuration&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Kubernetes Gateway API: Role-based Configuration of Ingress&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This course is for anyone who needs to delegate the configuration of ingress between different teams using the Gateway API.&lt;/p&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.pluralsight.com/library/courses/kubernetes-gateway-api-getting-started&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Kubernetes Gateway API: Getting Started&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This course is for anyone who is involved in configuring external client access to applications running in Kubernetes clusters.&lt;/p&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.pluralsight.com/library/courses/kustomize-getting-started&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Getting Started with Kustomize&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This course is for anyone who needs to deploy applications to Kubernetes clusters, but prefers patching YAML definitions to create variants, rather than writing complex templates to achieve the same.&lt;/p&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.pluralsight.com/courses/gitops-kubernetes-flux-2-automate-deployments-using&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Using GitOps to Automate Kubernetes Deployments with Flux 2&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This course is for DevOps teams responsible for managing the deployments of cloud-native applications to Kubernetes clusters.&lt;/p&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.pluralsight.com/courses/docker-apps-developing-core-principles-2023&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Developing Docker Apps: Core Principles&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This course is for software developers who are looking to build on their basic understanding of application containers, to start to use Docker in earnest to build cloud native application services.&lt;/p&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.pluralsight.com/courses/automating-kubernetes-deployments-gitops-workflow&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Automating Kubernetes Deployments Using a GitOps Workflow&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This course is for DevOps teams responsible for managing the deployments of cloud-native applications to Kubernetes clusters.&lt;/p&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.pluralsight.com/courses/managing-ingress-traffic-patterns-kubernetes-services&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Managing Ingress Traffic Patterns for Kubernetes Services&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This course is for DevOps teams responsible for configuring Kubernetes clusters to expose workloads beyond the cluster.&lt;/p&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.pluralsight.com/courses/securing-docker-platform&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Securing the Docker Platform&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This course is for DevOps and IT Ops teams who are responsible for providing a secure platform for container operations.&lt;/p&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.pluralsight.com/courses/securing-docker-container-workloads&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Securing Docker Container Workloads&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This course is for DevOps and IT Ops teams who have a responsibility for securing the software applications they deploy into production environments.&lt;/p&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.pluralsight.com/courses/containerizing-software-application-docker&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Containerizing a Software Application with Docker&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This course is for software developers seeking to adopt the microservices architecture pattern, using the Docker platform as the packaging and distribution mechanism.&lt;/p&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;




&lt;/div&gt;



</description>
    </item>
    
  </channel>
</rss>
