{"id":931,"date":"2017-04-25T14:04:37","date_gmt":"2017-04-25T18:04:37","guid":{"rendered":"http:\/\/jefflane.org\/v2\/?p=931"},"modified":"2017-04-25T14:04:37","modified_gmt":"2017-04-25T18:04:37","slug":"actually-useful-getting-started-guide-to-lxd-on-ubuntu","status":"publish","type":"post","link":"http:\/\/jefflane.org\/v2\/technology\/actually-useful-getting-started-guide-to-lxd-on-ubuntu\/","title":{"rendered":"Actually Useful Getting Started Guide to LXD on Ubuntu"},"content":{"rendered":"<p><a href=\"https:\/\/linuxcontainers.org\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium alignleft\" src=\"https:\/\/linuxcontainers.org\/static\/img\/containers.png\" width=\"318\" height=\"293\" \/><\/a>OK, this will still be kinda brief, but hopefully helps get you going with LXC containers (via LXD) quickly in a way that&#8217;s actually useful.<\/p>\n<p>I have typically used things like\u00a0<a href=\"https:\/\/www.digitalocean.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Digital Ocean<\/a>\u00a0and <a href=\"https:\/\/aws.amazon.com\/\">AWS<\/a>\u00a0to quickly launch a testbed, deploy some modified packages and, check the changes and then tear it all down quickly. \u00a0This works well for me but I&#8217;ve recently been trying to break my dependence on foreign services for this work. \u00a0So I&#8217;ve been using LXD more and more which is just as fast, and is local so I can do this sort of work without an internet connection if need be. \u00a0Below, I&#8217;ll outline a few very quick things to make using containers a bit more easy. \u00a0Note, all of the info below assumes you are using Ubuntu 16.04 LTS or later, with LXD installed (LXD is installed by default on 16.04 and newer). \u00a0Also, you should have at least some familiarity with lxc and lxd. \u00a0For more information on those, see\u00a0<a href=\"https:\/\/linuxcontainers.org\/lxc\/introduction\/\">https:\/\/linuxcontainers.org\/lxc\/introduction\/<\/a>.<\/p>\n<h2>Tip 1: \u00a0import images locally with useful aliases.<\/h2>\n<p>By default, when you launch a container, the image will be pulled from the internet if it does not already exist. \u00a0Also, if you want to use that container base again locally, you sometimes need to find an ugly fingerprint ID\u00a0to reference it with. \u00a0I&#8217;ve prefer to\u00a0locally import the images I want. \u00a0Not only does this let me create my own, easily remembered names for this, I can pull a variety of images from various sources and have my own local, off-line catalog of LXD images to create containers from.<\/p>\n<p>First, see what images are available. \u00a0Since I do all my work on ubuntu, I only need to check the default ubuntu remote. \u00a0This is done with the &#8216;image&#8217; command for lxc:<\/p>\n<p>&nbsp;<\/p>\n<pre>bladernr@galactica:~$ lxc image list ubuntu:\r\n+--------------------+--------------+--------+-------------------------------------------------+---------+----------+-------------------------------+\r\n| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE |\r\n+--------------------+--------------+--------+-------------------------------------------------+---------+----------+-------------------------------+\r\n| p (5 more) | 4c1e4092ead8 | yes | ubuntu 12.04 LTS amd64 (release) (20170417) | x86_64 | 156.78MB | Apr 17, 2017 at 12:00am (UTC) |\r\n+--------------------+--------------+--------+-------------------------------------------------+---------+----------+-------------------------------+\r\n| p\/armhf (2 more) | 68a83fae9fd3 | yes | ubuntu 12.04 LTS armhf (release) (20170417) | armv7l | 135.58MB | Apr 17, 2017 at 12:00am (UTC) |\r\n+--------------------+--------------+--------+-------------------------------------------------+---------+----------+-------------------------------+\r\n| p\/i386 (2 more) | 056784ac045d | yes | ubuntu 12.04 LTS i386 (release) (20170417) | i686 | 141.27MB | Apr 17, 2017 at 12:00am (UTC) |\r\n+--------------------+--------------+--------+-------------------------------------------------+---------+----------+-------------------------------+\r\n| t (5 more) | 536ea2799fc7 | yes | ubuntu 14.04 LTS amd64 (release) (20170405) | x86_64 | 119.89MB | Apr 5, 2017 at 12:00am (UTC) |\r\n+--------------------+--------------+--------+-------------------------------------------------+---------+----------+-------------------------------+\r\n| t\/arm64 (2 more) | 26b9b1fb1b15 | yes | ubuntu 14.04 LTS arm64 (release) (20170405) | aarch64 | 110.96MB | Apr 5, 2017 at 12:00am (UTC) |\r\n+--------------------+--------------+--------+-------------------------------------------------+---------+----------+-------------------------------+\r\n| t\/armhf (2 more) | 5e367a0ad31c | yes | ubuntu 14.04 LTS armhf (release) (20170405) | armv7l | 111.58MB | Apr 5, 2017 at 12:00am (UTC) |\r\n+--------------------+--------------+--------+-----------------------------lets--------------------+---------+----------+-------------------------------+\r\n| t\/i386 (2 more) | 38df07c91eac | yes | ubuntu 14.04 LTS i386 (release) (20170405) | i686 | 118.24MB | Apr 5, 2017 at 12:00am (UTC) |\r\n+--------------------+--------------+--------+-------------------------------------------------+---------+----------+-------------------------------+<\/pre>\n<p>There are a LOT of images available so I&#8217;ve trimmed the output significantly. \u00a0I&#8217;m mostly interested in Trusty for now, which has the alias &#8216;t&#8217;, so let&#8217;s import that image locally using the &#8216;copy&#8217; subcommand of the &#8216;image&#8217; lxc command:<\/p>\n<pre>bladernr@galactica:~$ lxc image copy ubuntu:t local: --alias=ubuntu-trusty\r\nImage copied successfully!\r\nbladernr@galactica:~$ lxc image list\r\n+---------------+--------------+--------+---------------------------------------------+--------+----------+-------------------------------+\r\n| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE |\r\n+---------------+--------------+--------+---------------------------------------------+--------+----------+-------------------------------+\r\n| ubuntu-trusty | 536ea2799fc7 | no | ubuntu 14.04 LTS amd64 (release) (20170405) | x86_64 | 119.89MB | Apr 24, 2017 at 10:58pm (UTC) |\r\n+---------------+--------------+--------+---------------------------------------------+--------+----------+-------------------------------+\r\n| ubuntu-xenial | f452cda3bccb | no | ubuntu 16.04 LTS amd64 (release) (20160627) | x86_64 | 310.30MB | Jul 15, 2016 at 5:55pm (UTC) |\r\n+---------------+--------------+--------+---------------------------------------------+--------+----------+-------------------------------+lets<\/pre>\n<p>What this does is download\u00a0a copy of the arch appropriate trusty container image hosted on the default Ubuntu image store and make it available locally on my desktop. \u00a0As you can see, I have both Trusty and Xenial images, with nice aliases that can be easily remembered later on when deploying containers.<\/p>\n<p>I have the release versions of the images, that&#8217;s all I need. \u00a0Because I&#8217;m just prototyping and testing locally, I don&#8217;t really worry too much about the latest package updates being installed on my containers.<\/p>\n<p>Ubuntu has two different remotes (streams) to get images from:<\/p>\n<pre>bladernr@galactica:~$ lxc image list ubuntu: |head -10\r\n+--------------------+--------------+--------+-------------------------------------------------+---------+----------+-------------------------------+\r\n| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE |\r\n+--------------------+--------------+--------+-------------------------------------------------+---------+----------+-------------------------------+\r\n| p (5 more) | 4c1e4092ead8 | yes | ubuntu 12.04 LTS amd64 (release) (20170417) | x86_64 | 156.78MB | Apr 17, 2017 at 12:00am (UTC) |\r\n+--------------------+--------------+--------+-------------------------------------------------+---------+----------+-------------------------------+\r\n| p\/armhf (2 more) | 68a83fae9fd3 | yes | ubuntu 12.04 LTS armhf (release) (20170417) | armv7l | 135.58MB | Apr 17, 2017 at 12:00am (UTC) |\r\n+--------------------+--------------+--------+-------------------------------------------------+---------+----------+-------------------------------+\r\n| p\/i386 (2 more) | 056784ac045d | yes | ubuntu 12.04 LTS i386 (release) (20170417) | i686 | 141.27MB | Apr 17, 2017 at 12:00am (UTC) |\r\n+--------------------+--------------+--------+-------------------------------------------------+---------+----------+-------------------------------+\r\n| t (5 more) | 9e0493502f9d | yes | ubuntu 14.04 LTS amd64 (release) (20170424) | x86_64 | 120.03MB | Apr 24, 2017 at 12:00am (UTC) |\r\n\r\n\r\nbladernr@galactica:~$ lxc image list ubuntu-daily: |head -10\r\n+--------------------+--------------+--------+-----------------------------------------------+---------+----------+-------------------------------+\r\n| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE |\r\n+--------------------+--------------+--------+-----------------------------------------------+---------+----------+-------------------------------+\r\n| p (5 more) | 12bb0982a94b | yes | ubuntu 12.04 LTS amd64 (daily) (20170424) | x86_64 | 155.64MB | Apr 24, 2017 at 12:00am (UTC) |\r\n+--------------------+--------------+--------+-----------------------------------------------+---------+----------+-------------------------------+\r\n| p\/armhf (2 more) | d95c2d1be3f8 | yes | ubuntu 12.04 LTS armhf (daily) (20170424) | armv7l | 136.64MB | Apr 24, 2017 at 12:00am (UTC) |\r\n+--------------------+--------------+--------+-----------------------------------------------+---------+----------+-------------------------------+\r\n| p\/i386 (2 more) | 4f516ec69c8f | yes | ubuntu 12.04 LTS i386 (daily) (20170424) | i686 | 139.71MB | Apr 24, 2017 at 12:00am (UTC) |\r\n+--------------------+--------------+--------+-----------------------------------------------+---------+----------+-------------------------------+\r\n| t (5 more) | 9e0493502f9d | yes | ubuntu 14.04 LTS amd64 (daily) (20170424) | x86_64 | 120.03MB | Apr 24, 2017 at 12:00am (UTC) |<\/pre>\n<p>The first of those contains only the &#8220;release&#8221; versions of the Ubuntu images. \u00a0That is, the versions that appear on each GA Release Day, or LTS Point Release Day. \u00a0The second, ubuntu-daily, provides images from the daily builds of Ubuntu, which are updated far more frequently. \u00a0This also gives you access to daily builds of the latest development \/ interim release such as the soon to be opened Ubuntu 17.10.<\/p>\n<h2>Tip 2: Configuring a user for easy login and actually getting work done.<\/h2>\n<p>The default Ubuntu images are missing two very important things, ssh keys and a default password for the &#8216;ubuntu&#8217; user. \u00a0There are a few different ways to tackle this. \u00a0If a root access is all you need, then this will suffice:<\/p>\n<pre>bladernr@galactica:~$ lxc exec subtle-marlin \/bin\/bash\r\nroot@subtle-marlin:~#<\/pre>\n<p>This will get you a root login, but I often need to have a non-privileged login. \u00a0So the first thing we need to configure the user. \u00a0This is accomplished using cloud-init and can be set using the profiles for lxc. \u00a0Specifically, I&#8217;m setting this in the default profile. \u00a0To access\/edit this profile, as of lxc version\u00a0<strong>2.0.7-0ubuntu1~16.04.2<\/strong>, you need to use the lxc profile command to edit the default profile and add a few things.<\/p>\n<p>To edit it use the command<em> lxd profile edit &lt;name&gt;\u00a0<\/em>(Note, this command may be different on other versions of lxc, such as <em>lxc edit profile &lt;name&gt;<\/em>.<\/p>\n<pre>bladernr@galactica:~$ lxc profile list\r\ndefault\r\ndocker\r\njuju-controller\r\njuju-default<\/pre>\n<p>Note that there are several profiles already created by default. \u00a0We&#8217;re only interested in the &#8216;<strong>default<\/strong>&#8216; profile, so let&#8217;s edit that:<\/p>\n<pre>### This is a yaml representation of the profile.\r\n### Any line starting with a '# will be ignored.\r\n###\r\n### A profile consists of a set of configuration items followed by a set of\r\n### devices.\r\n###\r\n### An example would look like:\r\n### name: onenic\r\n### config:\r\n### raw.lxc: lxc.aa_profile=unconfined\r\n### devices:\r\n### eth0:\r\n### nictype: bridged\r\n### parent: lxdbr0\r\n### type: nic\r\n###\r\n### Note that the name is shown but cannot be changed\r\n\r\nconfig:\r\n user.vendor-data: |\r\n  #cloud-config\r\n  users:\r\n  - name: ubuntu\r\n    ssh-import-id: bladernr\r\n    lock_passwd: false\r\n    sudo: ALL=(ALL) NOPASSWD:ALL\r\n    shell: \/bin\/bash\r\ndescription: \"\"\r\ndevices:\r\n eth0:\r\n  name: eth0\r\n  nictype: bridged\r\n  parent: lxdbr0\r\n  type: nic\r\nname: default\r\n\r\n<\/pre>\n<p>In that example, I have added modified the <em>user.vendor-data<\/em>\u00a0section to set a few items for the &#8220;ubuntu&#8221; user. \u00a0First, I used <em>ssh-import-id<\/em> to import my own ssh keys. \u00a0I believe this pulls from launchpad, but it may pull locally. \u00a0I&#8217;m honestly not sure which. \u00a0Next, I set <em>lock_passwd<\/em> to &#8216;false&#8217;. \u00a0letsIf you leave this unset, it defaults to &#8216;true&#8217; which will prevent password logins. \u00a0Of course, the ssh logins via key are MUCH more secure, but as I mentioned before, these are very short lived development instances, so security is of no concern to me, as proven in the next line.<\/p>\n<p>On this next line, I tell cloud-init to setup <em>sudo<\/em>\u00a0privileges for\u00a0the &#8216;ubuntu&#8217; user so that no password is required when performing ANY task via sudo. \u00a0That is about as close as you can get to using the root user instead. \u00a0It is VERY dangerous because anyone who gains access to &#8216;ubuntu&#8217; now has full, unfettered root access. \u00a0So don&#8217;t do this at home. \u00a0Again, for my use, these are short lived test and dev instances where security is not important. \u00a0I would NEVER do this on anthing that is even close to production level.<\/p>\n<p>In fact, on a production system you should probably consider leaving only the ssh-import-id set to only allow logins via ssh and key-based authentication. \u00a0You should definitely NOT set sudo as I have done here, also.<\/p>\n<p>Finally, I set the shell to <em>\/bin\/bash\u00a0<\/em>so when I ssh in, I&#8217;ll have a nice bash shell.<\/p>\n<p>There are other items you can set in here, such as password, ssh authorized_keys, group membership and so on. \u00a0You can find out more about cloud config in the <a href=\"http:\/\/cloudinit.readthedocs.io\/en\/latest\/topics\/examples.html\">cloudinit documentation<\/a>.<\/p>\n<h2>Conclusion<\/h2>\n<p>So there you go. \u00a0Those two tips should help setting up LXC\/LXD to be much easier and less hassle when launching instances for testing your code, prototyping and other needs. \u00a0Please do remember that I do some fairly ugly things (security wise) and you should make better choices there for production.<\/p>\n<p>Once you have those things configured, you should be able to quickly launch instances and connect to them via SSH and be able to perform whatever tasks you need.<\/p>\n<p>&nbsp;<\/p>\n<pre>\u00a0bladernr@galactica:~$ lxc list\r\n+---------------+---------+----------------------+------+------------+-----------+\r\n| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |\r\n+---------------+---------+----------------------+------+------------+-----------+\r\n| subtle-marlin | RUNNING | 10.148.80.232 (eth0) | | PERSISTENT | 0 |\r\n+---------------+---------+----------------------+------+------------+-----------+\r\nbladernr@galactica:~$ lxc launch ubuntu-trusty demo\r\nCreating demo\r\nStarting demo\r\nbladernr@galactica:~$ lxc list\r\n+---------------+---------+----------------------+------+------------+-----------+\r\n| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |\r\n+---------------+---------+----------------------+------+------------+-----------+\r\n| demo | RUNNING | 10.148.80.217 (eth0) | | PERSISTENT | 0 |\r\n+---------------+---------+----------------------+------+------------+-----------+\r\n| subtle-marlin | RUNNING | 10.148.80.232 (eth0) | | PERSISTENT | 0 |\r\n+---------------+---------+----------------------+------+------------+-----------+\r\nbladernr@galactica:~$ ssh ubuntu@10.148.80.217\r\nThe authenticity of host '10.148.80.217 (10.148.80.217)' can't be established.\r\nECDSA key fingerprint is SHA256:gyn682YAhs+LyZc7i0s9akfBoZCOnSYErMeds4MbaKI.\r\nAre you sure you want to continue connecting (yes\/no)? yes\r\nWarning: Permanently added '10.148.80.217' (ECDSA) to the list of known hosts.\r\nWelcome to Ubuntu 14.04.5 LTS (GNU\/Linux 4.4.0-70-generic x86_64)\r\n\r\n* Documentation: https:\/\/help.ubuntu.com\/\r\n\r\nSystem information as of Tue Apr 25 13:30:23 UTC 2017\r\n\r\nSystem load: 0.77 Memory usage: 0% Processes: 15\r\n Usage of \/home: unknown Swap usage: 47% Users logged in: 0\r\n\r\nGraph this data and manage this system at:\r\n https:\/\/landscape.canonical.com\/\r\n\r\nGet cloud support with Ubuntu Advantage Cloud Guest:\r\n http:\/\/www.ubuntu.com\/business\/services\/cloud\r\n\r\n0 packages can be updated.\r\n0 updates are security updates.\r\n\r\nThe programs included with the Ubuntu system are free software;\r\nthe exact distribution terms for each program are described in the\r\nindividual files in \/usr\/share\/doc\/*\/copyright.\r\n\r\nUbuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by\r\napplicable law.\r\n\r\nubuntu@demo:~$<\/pre>\n","protected":false},"excerpt":{"rendered":"<p><a href=\"https:\/\/linuxcontainers.org\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium alignleft\" src=\"https:\/\/linuxcontainers.org\/static\/img\/containers.png\" width=\"318\" height=\"293\" \/><\/a>OK, this will still be kinda brief, but hopefully helps get you going with LXC containers (via LXD) quickly in a way that&#8217;s actually useful.<\/p>\n<p>I have typically used things like\u00a0<a href=\"https:\/\/www.digitalocean.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Digital Ocean<\/a>\u00a0and <a href=\"https:\/\/aws.amazon.com\/\">AWS<\/a>\u00a0to quickly launch a testbed, deploy some modified packages and, check the changes and then tear it all down quickly. \u00a0This works well for me but I&#8217;ve recently been trying to break my dependence on foreign services for this work. \u00a0So I&#8217;ve been using LXD more and more which is just as fast, and  \u2026 <a class=\"continue-reading-link\" href=\"http:\/\/jefflane.org\/v2\/technology\/actually-useful-getting-started-guide-to-lxd-on-ubuntu\/\"> Continue reading<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[24,6,12],"tags":[25,27,26,28],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5mmXH-f1","jetpack-related-posts":[],"_links":{"self":[{"href":"http:\/\/jefflane.org\/v2\/wp-json\/wp\/v2\/posts\/931"}],"collection":[{"href":"http:\/\/jefflane.org\/v2\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/jefflane.org\/v2\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/jefflane.org\/v2\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/jefflane.org\/v2\/wp-json\/wp\/v2\/comments?post=931"}],"version-history":[{"count":1,"href":"http:\/\/jefflane.org\/v2\/wp-json\/wp\/v2\/posts\/931\/revisions"}],"predecessor-version":[{"id":933,"href":"http:\/\/jefflane.org\/v2\/wp-json\/wp\/v2\/posts\/931\/revisions\/933"}],"wp:attachment":[{"href":"http:\/\/jefflane.org\/v2\/wp-json\/wp\/v2\/media?parent=931"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/jefflane.org\/v2\/wp-json\/wp\/v2\/categories?post=931"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/jefflane.org\/v2\/wp-json\/wp\/v2\/tags?post=931"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}