10

Specifically, with the CLI tools- not openstack.

I'm looking at what a local dev setup with lxd might look like but am coming up empty handed when it comes to configuring new containers.

Are there any idiomatic (or otherwise) ways to configure lxd containers? Should I be looking at something more immutable like docker images?

Thanks. Any resources or pointers would be appreciated.

3 Answers 3

16

So there are multiple ways you can do so, either directly for a container:

lxc init ubuntu: CONTAINER
lxc config set CONTAINER user.user-data - < cloud-init-config.yml
lxc start CONTAINER

Or even shorter:

lxc launch ubuntu: CONTAINER --config=user.user-data="$(cat cloud-init-config.yml)"

Or through a profile:

lxc profile create dev
lxc profile set dev user.user-data - < cloud-init-config.yml
lxc launch ubuntu: CONTAINER -p default -p dev
2
  • How can .sh files be used instead of .yml? Is there a tutorial already available on this topic?
    – Greg
    Jun 12, 2017 at 23:13
  • The above is in reference to this question: stackoverflow.com/questions/44456522
    – Greg
    Jun 13, 2017 at 15:21
4

I had a slightly more specific question than the OP but it took me a while to work out what I was doing wrong. I thought I would post it here to help anyone else getting similarly stumped.

I wanted static networking settings for an LXC/LXD Ubuntu 16.04 container hosted on Ubuntu 16.04. I started by trying what Stéphane wrote but it wasn't working. All I ended up with was the default DHCP-attempting container with an IPv6 link local, as there is no DHCP being served in my configuration.

My initial YAML looked (something) like the following (taken from the cloud-init docs).

network:
  version: 1
  config:
    - type: physical
      name: eth0
      subnets:
        - type: static
          address: 192.168.23.14/27
          gateway: 192.168.23.1
          dns_nameservers:
            - 192.168.23.2
            - 8.8.8.8
          dns_search:
            - exemplary.maas

And I was loading this into user.user-data as described above.

lxc config set CONTAINER user.user-data - < CONTAINER.cloud-init-config.yml

It wasn't until I found Stéphane's documentation in the LXC/LXD source that I realised I needed to load that value into user.network-config.

So my final YAML looked (something) like this.

version: 1
config:
  - type: physical
    name: eth0
    subnets:
      - type: static
        address: 192.168.23.14/27
        gateway: 192.168.23.1
        dns_nameservers:
          - 192.168.23.2
          - 8.8.8.8
        dns_search:
          - exemplary.maas

Then I loaded this into user.network-config instead.

lxc config set CONTAINER user.network-config - < CONTAINER.network-config.yaml

It seems like I will need to keep two different files per container: one for network settings to load to user.network-config; and one for other config to load into user.user-data unless I can find a way of using a single file for everything.


Another problem I found which wasn't obvious to me at all was trying to configure non-network components automatically.

lxc config set CONTAINER user.user-data - < CONTAINER.user-data.yaml

The following YAML applied with the command above (despite looking correct using lxc config show CONTAINER) did not create anything inside my container.

write_files:
  - content: |
    # My new /etc/foo.bar file

    Foo
    Bar

    path: /etc/foo.bar

The clue buried away in User Data Input Formats, item 5: Cloud Config Data reads:

begins with "#cloud-config" or "Content-Type: text/cloud-config" This content is "cloud-config" data. See the examples for a commented example of supported config formats.

I don't believe this documentation is very clear. I could not get anything to work using the "Content-Type: text/cloud-config" form but I did find if you put #cloud-config on the first line, the YAML is parsed. I can only assume something isn't quite right, either my understanding, or someone's programming. It makes no sense to me that YAML you've explicitly loaded as the value of the key user.user-data should be used as anything other than cloud configuration data. Why else would anyone do that if it wasn't meant to be cloud configuration, and therefore why would a comment (which doesn't even use the normal shebang syntax) be required?

So, nonsense aside, the syntax which worked for user.user-data is:

#cloud-config

write_files:
  - content: |
      # My new /etc/foo.bar file

      Foo
      Bar

    path: /etc/foo.bar
3

One liner I went with today, this one sets it in the default profile for new containers:

echo -e "#cloud-config\nssh_authorized_keys:\n - $(cat ~/.ssh/id_rsa.pub)" | lxc profile set default user.user-data -

This one sets it in an existing container, but beware it will not work on containers that already booted as the SSH key stuff only gets done on first boot:

echo -e "#cloud-config\nssh_authorized_keys:\n - $(cat ~/.ssh/id_rsa.pub)" | lxc config set CONTAINER_NAME user.user-data -

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.