<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<title>Technocoder - aarch64</title>
	<link href="https://blog.techno.fish/tags/aarch64/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="https://blog.techno.fish"/>
	<generator uri="https://www.getzola.org/">Zola</generator>
	<updated>2021-12-07T00:00:00+00:00</updated>
	<id>https://blog.techno.fish/tags/aarch64/atom.xml</id>
	<entry xml:lang="en">
		<title>Running x86-64 Docker Images on ARM</title>
		<published>2021-12-07T00:00:00+00:00</published>
		<updated>2021-12-07T00:00:00+00:00</updated>
		<link href="https://blog.techno.fish/running-x86-64-docker-images-on-arm/" type="text/html"/>
		<id>https://blog.techno.fish/running-x86-64-docker-images-on-arm/</id>
		<content type="html">&lt;p&gt;Need to run Intel-based Docker images on a Linux ARM machine? Run this command:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;&quot;&gt;
&lt;code&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt; run&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt; --rm --privileged&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt; aptman&#x2F;qus&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt; -s&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt; --&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt; -p x86_64
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s it! Try running your Docker image. Keep reading to learn how it works and what you need to be aware of.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-it-works&quot;&gt;How it works&lt;&#x2F;h2&gt;
&lt;p&gt;When you run any executable, it gets sent to the kernel so that it can check its architecture. You might have seen this error message before:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;&quot;&gt;
&lt;code&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;exec user process caused &amp;quot;exec format error&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This means the architecture didn&#x27;t match up with what&#x27;s supported for your system. The Linux kernel has a feature called &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Binfmt_misc&quot;&gt;&lt;code&gt;binfmt_misc&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; which allows us to define our own handlers for arbitrary executable formats. We use this feature to load &lt;code&gt;x86-64&lt;&#x2F;code&gt; executables using QEMU.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.qemu.org&quot;&gt;QEMU&lt;&#x2F;a&gt; is a suite of machine emulators for a huge variety of system architectures. In this case, we don&#x27;t actually emulate a system with a kernel but instead, we use QEMU&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;www.qemu.org&#x2F;docs&#x2F;master&#x2F;user&#x2F;main.html&quot;&gt;user space emulator&lt;&#x2F;a&gt;. This means it has much less overhead than emulating a complete system. Privileged actions like writing to files or sending network requests are delegated directly to the Linux kernel.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dbhi&#x2F;qus&quot;&gt;qus&lt;&#x2F;a&gt; Docker image packages this whole setup so that all you need to do is run it as a container. It contains the required QEMU binaries and also automatically registers them into &lt;code&gt;binfmt_misc&lt;&#x2F;code&gt;. As it requires direct access to the Linux kernel, we use the &lt;code&gt;--privileged&lt;&#x2F;code&gt; Docker flag. You can learn more about it on its project page.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;caveats&quot;&gt;Caveats&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;performance&quot;&gt;Performance&lt;&#x2F;h3&gt;
&lt;p&gt;As we&#x27;re emulating (not virtualizing!) the &lt;code&gt;x86-64&lt;&#x2F;code&gt; architecture, the performance penalty is going to be significant. That is, it could be up to an order of magnitude slower for some workloads. I&#x27;ve found that it works fine for a small web server.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reboots&quot;&gt;Reboots&lt;&#x2F;h3&gt;
&lt;p&gt;The Linux kernel resets any registered &lt;code&gt;binfmt_misc&lt;&#x2F;code&gt; handlers on system reboots. To persist these handlers across reboots, you can use &lt;code&gt;crontab&lt;&#x2F;code&gt; to run a script containing the Docker command at startup:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;&quot;&gt;
&lt;code&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt; crontab&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt; -e
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre style=&quot;background-color:#2b303b;&quot;&gt;
&lt;code&gt;&lt;span style=&quot;font-style:italic;color:#5f697a;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;@reboot&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt; sh $&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;HOME&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&#x2F;script.sh
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;further-resources&quot;&gt;Further resources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;qus&lt;&#x2F;code&gt; homepage: &lt;a href=&quot;https:&#x2F;&#x2F;dbhi.github.io&#x2F;qus&#x2F;&quot;&gt;https:&#x2F;&#x2F;dbhi.github.io&#x2F;qus&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;multiarch&#x2F;qemu-user-static&lt;&#x2F;code&gt; - a similar tool for &lt;code&gt;x86-64&lt;&#x2F;code&gt; hosts: &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;multiarch&#x2F;qemu-user-static&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;multiarch&#x2F;qemu-user-static&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
	</entry>
</feed>
