<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>docker on CodeGoalie</title><link>https://codegoalie.com/categories/docker/</link><description>Recent content in docker on CodeGoalie</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 30 Dec 2019 16:13:36 -0500</lastBuildDate><atom:link href="https://codegoalie.com/categories/docker/index.xml" rel="self" type="application/rss+xml"/><item><title>Cleaning Up Docker Images</title><link>https://codegoalie.com/posts/cleaning-up-docker-images/</link><pubDate>Mon, 30 Dec 2019 16:13:36 -0500</pubDate><guid>https://codegoalie.com/posts/cleaning-up-docker-images/</guid><description>&lt;p>After a while of using docker locally for development, you may notice that you
have a lot of images and containers laying around on your disk that you no
longer use. This post shows you an effective way to clean up 50 of GB or more
of disk space.&lt;/p>
&lt;p>The first, best thing to do is clean up dangling images. These are docker images
that are not referenced by a container. These can be orphaned when containers are
removed or intermediate steps that don&amp;rsquo;t get cleaned up. One quick command can
remove them:&lt;/p>
&lt;pre>&lt;code>$ docker image prune
&lt;/code>&lt;/pre>&lt;p>Typically, if you&amp;rsquo;ve been using docker for a while, this will clear up quite a bit
of space. But, there&amp;rsquo;s more we can do.&lt;/p>
&lt;p>The next step you might think to do is remove other images that you know you don&amp;rsquo;t use.
We can list them with the &lt;code>docker images&lt;/code> command. However, you won&amp;rsquo;t be able
to delete them directly because they are being referenced by containers (otherwise
they would have been removed by the prune command). So, let&amp;rsquo;s look at containers:&lt;/p>
&lt;pre>&lt;code>$ docker ps -a
&lt;/code>&lt;/pre>&lt;blockquote>
&lt;p>Note: the &lt;code>a&lt;/code> flag shows all containers not just those running. You probably
don&amp;rsquo;t want to remove a container that&amp;rsquo;s currently running anyway.&lt;/p>
&lt;/blockquote>
&lt;p>Wow. That&amp;rsquo;s a long list. Way down at the bottom I noticed some old and temporary
projects and experiments. Here&amp;rsquo;s an example of some less notables from my list:&lt;/p>
&lt;pre>&lt;code>68585b76a752 46d00b64e6cb &amp;quot;/bin/sh -c yarn&amp;quot; 13 months ago Exited (1) 13 months ago upbeat_tesla
3cb298f62318 3bc06921fcd0 &amp;quot;/bin/sh -c yarn&amp;quot; 14 months ago Exited (1) 14 months ago charming_benz
31e91aaa9111 3bc06921fcd0 &amp;quot;/bin/sh -c yarn&amp;quot; 14 months ago Exited (1) 14 months ago upbeat_lovelace
79428b687b22 6533ab88e0ff &amp;quot;basj&amp;quot; 16 months ago Created welcomely_web_run_75
&lt;/code>&lt;/pre>&lt;p>Ok, so now copy and paste the container ID (first column) for each one you&amp;hellip; J/K.&lt;/p>
&lt;p>I also noticed that this output has the created time in the fourth column. This
is helpful, but not particularly useful. I do have some long running projects
and would prefer not to simply remove containers that I&amp;rsquo;ve created long ago.&lt;/p>
&lt;p>However, the very next column shows the last time the container was executed. I
would like to remove containers that I haven&amp;rsquo;t run in a while. We can grep for
rows of the output which exited many months ago:&lt;/p>
&lt;pre>&lt;code> $ docker ps -a | grep -E &amp;quot;Exited \([0-9]{1,3}\) 2[0-3] months ago&amp;quot;
&lt;/code>&lt;/pre>&lt;p>This looks scary. But, I promise I actually wrote this by hand and it&amp;rsquo;s pretty
simple. If I&amp;rsquo;m being honest, it&amp;rsquo;s probably too simple, but it worked for my case.&lt;/p>
&lt;p>First, we use the &lt;code>E&lt;/code> flag to enable the regex engine. Then we want to match rows
with the string like &amp;ldquo;Existed (&lt;!-- raw HTML omitted -->) &amp;lt;some number more than 20&amp;gt; months
ago&amp;rdquo;. Most of that is plain strings. Really just for the numbers we want to use
the regex. The first is the exit code in the parenthesis. Most containers had
&lt;code>0&lt;/code> or &lt;code>1&lt;/code> exit codes. But, a few had &lt;code>137&lt;/code>. So I just matched on any up to 3
digit number within the parenthesis: &lt;code>[0-9]{1,3}&lt;/code>.&lt;/p>
&lt;p>Second, we match a plain 2 then any units digit of months between 0 and 3,
inclusively: &lt;code>2[0-3]&lt;/code>. My results had the oldest container stopping 23 months
ago. You mileage may vary and I&amp;rsquo;ll leave it up to you to modify and re-run to
suit your situation.&lt;/p>
&lt;p>Now that we&amp;rsquo;ve got a good list of containers to delete, let&amp;rsquo;s use some
command-line fu to save a ton of copy/pasting. Let&amp;rsquo;s pipe this filtered list
into &lt;code>awk&lt;/code> to get rid of the rest of the text save for the first hash (field).&lt;/p>
&lt;pre>&lt;code>awk '{print $1}'
&lt;/code>&lt;/pre>&lt;p>Then, pass each row (which now only contains the ID hash of the container) into
&lt;code>docker rm&lt;/code>. To do this, we can use &lt;code>xargs&lt;/code>:&lt;/p>
&lt;pre>&lt;code>xargs -i@ docker rm @
&lt;/code>&lt;/pre>&lt;p>Putting it all together:&lt;/p>
&lt;pre>&lt;code>$ docker ps -a | grep -E &amp;quot;Exited \([0-9]{1,3}\) 2[0-3] months ago&amp;quot; | awk '{print $1}' | xargs -i@ docker rm @
&lt;/code>&lt;/pre>&lt;p>Then, go back to the top and remove dangiling images:&lt;/p>
&lt;pre>&lt;code>$ docker image prune
&lt;/code>&lt;/pre>&lt;p>There you have it. I removed containers I hadn&amp;rsquo;t run for more than 8 months or so and freed up almost 50GB.
I hope you have similar or better results! Let me know how you fare: &lt;a href="mailto:chris@codegoalie.com">chris@codegoalie.com&lt;/a>&lt;/p>
&lt;p>Happy &lt;code>docker rm&lt;/code>-ing!&lt;/p></description></item><item><title>Working with Containers: beyond the tutorial</title><link>https://codegoalie.com/posts/working-with-containers/</link><pubDate>Thu, 04 Feb 2016 15:11:50 -0500</pubDate><guid>https://codegoalie.com/posts/working-with-containers/</guid><description>&lt;p>Over the past few months, I&amp;rsquo;ve been getting my hands dirty with containers,
Docker, and Kubernetes in an effort to get some hands on experience working
toward microservices. I&amp;rsquo;ve been building up a small application to generate and
serve Sudoku puzzles. My original goal was to see how many puzzles with unique
solution I could actually find, but that&amp;rsquo;s another post entirely. There are
already
&lt;a href="https://docs.docker.com/engine/userguide/basics/">many&lt;/a>
&lt;a href="http://kubernetes.io/v1.1/examples/guestbook-go/README.html">great&lt;/a>
&lt;a href="https://cloud.google.com/container-engine/docs/tutorials/guestbook">tutorials&lt;/a>
about
&lt;a href="https://docs.docker.com/">Docker&lt;/a>
and
&lt;a href="http://kubernetes.io/v1.1/docs/whatisk8s.html">Kubernetes&lt;/a>
on &lt;a href="https://cloud.google.com/container-engine/docs/">Google Container Engine&lt;/a>,
so I won&amp;rsquo;t go into getting started details here. This post is meant to explain
some of the stickier points that I had to pickup the hard way. I hope to save
you one or two headaches.&lt;/p>
&lt;!-- raw HTML omitted -->
&lt;h2 id="turn-key-kubernetes">Turn Key Kubernetes&lt;/h2>
&lt;p>Typically, I&amp;rsquo;ve used AWS for my infrastructure needs, but Google Container
Engine runs kubernetes for you and can spin up a new cluster with one command.
Again, there are many tutorials about the specifics but here are a few things I
didn&amp;rsquo;t know going in which would have been helpful.&lt;/p>
&lt;h3 id="keeping-costs-down">Keeping costs down&lt;/h3>
&lt;p>By default your cluster is composed of 3 &lt;code>n1-standard-1&lt;/code> instances. When just
getting started this is probably more than you need in both resources and cost.
Since I was more interested in playing with containers than messing with
compute engine instances (that&amp;rsquo;s the whole point of containers), I didn&amp;rsquo;t pay
any attention to them, but you should. It&amp;rsquo;s super easy and quick to change both
the number of instances and the instance types in your cluster.&lt;/p>
&lt;p>Google Container Engine clusters are built on the idea of &lt;a href="https://cloud.google.com/compute/docs/instance-groups/">instance
groups&lt;/a>, which
are just one or more instance defined by the same &lt;a href="https://cloud.google.com/compute/docs/instance-templates">instance
template&lt;/a>. The
template described the instances you want in your group with attributes like
machine type and base image, etc. In the Google Cloud Console, you can design
a new template right in the interface (pick a new machine type from a drop down)
and use smaller or larger instances.&lt;/p>
&lt;p>Scaling the number of instances in your cluster is even easier. Edit the
Instance Group and change the &amp;ldquo;Number of Instances&amp;rdquo; textbox value. You can even
enter 0 to stop getting billed for the instance time. This works great when you
don&amp;rsquo;t need the instances to be up 24/7 while just playing around.&lt;/p>
&lt;h3 id="persistent-storage">Persistent Storage&lt;/h3>
&lt;p>When a pod is restarted or rescheduled, it gets recreated from scratch. Anything
that was stored on disk is gone. This can cause unexpected issues. For example,
I was using redis for storing Sudoku puzzles and if the redis-master pod
restarted, I lost all contents of the database. This can be unexpected because
when running redis locally, the disk snapshots always remain even when
restarting the redis-server process. With containers, this is not the case. If
you need to store anything to disk that you care about, you&amp;rsquo;ll need to store
that in a volume backed by a Google Persistent Disk. Once again, there are many
tutorials on the specifics.&lt;/p>
&lt;h3 id="stuck-in-creatingcontainer">Stuck in CreatingContainer&lt;/h3>
&lt;p>When using a Google persistent disks, I was running into pods getting
rescheduled onto new nodes (instance), but the disk remained attached to the
previous node. Since Google Cloud persistent disks can only be attached to one
node at a time, this caused the pod to hang during creation and never start.
The quick fix to this is just detach the disk from it&amp;rsquo;s current node.
Kubernetes will attach it to the correct node for you.&lt;/p>
&lt;pre>&lt;code>gcloud compute instances detach-disk &amp;lt;instance-name&amp;gt; --disk &amp;lt;disk-name&amp;gt;
&lt;/code>&lt;/pre>&lt;p>There&amp;rsquo;s currently an effort to redesign the volumne mount/dismount system in
Kubernetes to address this issue. I also think that as redis was maxing out the
memory on the nodes and crashing, it was causing unnecessary havok on my
cluster.&lt;/p>
&lt;h2 id="restarting-a-pod">&amp;ldquo;Restarting&amp;rdquo; a pod&lt;/h2>
&lt;p>Early on my Sudoku generator was very naive and had exponention performance, so
it would get &amp;ldquo;stuck&amp;rdquo; trying to come up with new puzzles. Locally, I was just
restarting the process. But when I got it into the cluster, it wasn&amp;rsquo;t always
clear if it was broken, or just getting held up (I did fix this and went from
a puzzle every few minutes to a few puzzles a second). The great feature of
using replication controllers is that it will keep the specified number of pods
running. So to &amp;ldquo;restart&amp;rdquo; a pod that&amp;rsquo;s being managed by a replication controller,
just delete it. The replication controller will bring up a new one. If you
aren&amp;rsquo;t using a replication controller to manage your pods, do so.&lt;/p>
&lt;p>Hopefully these tips will make your container journey a little smoother.&lt;/p></description></item></channel></rss>