Ansible & LXC
-
I've been playing around some more with these and figured I'd write up what I did.
So I've been using LXC to test some different applications. Now it is possible to run lxc-clone and copy a container, but I wanted to use ansible to get a little more familiar with it.
I created a playbook that will create an LXC container, update it, add a few packages, create my user, and copy my ssh key. Here's the folder structure (all of this is in the deploy folder).
.
├── deploy
│ ├── create.yml
│ ├── hosts
│ ├── key
│ ├── known_hosts
│ └── vars.yml
├── hosts.yml
├── lxc.yml
└── update.ymlVars.yml contains some variables (it has system packages, but I've just hard coded them in the playbook for now).
--- container: test system_packages: - openssh - wget
Create.yml is where the magic happens.
--- - hosts: megatron vars_files: - vars.yml gather_facts: false sudo: true tasks: - name: Create container lxc_container: name: "{{ container }}" template: ubuntu state: started template_options: --release wily --arch amd64 container_command: | apt-get update apt-get upgrade apt-get install-y wget openssh-server useradd jhooks -s /bin/bash -m -U echo -e "tempass\ntempass" | passwd jhooks mkdir /home/jhooks/.ssh - name: Copy SSH key copy: src=key dest=/var/lib/lxc/{{ container }}/rootfs/home/jhooks/.ssh/authorized_keys mode=0600 - name: Change Permissions lxc_container: name: "{{ container }}" container_command: | chown -R jhooks:jhooks /home/jhooks
So this connects to the host megatron (my desktop) and uses variables from the vars.yml file. Gather facts is off because we don't really need them and we need sudo since these are privileged containers (it takes some more work to set up unprivileged ones). Then it runs a task called
Create container
. This creates a container with the name of the container variable in the vars.yml file (test in this case). It uses Ubuntu with release options of 15.10 and 64 bit and then starts it (state: started). Then it runs some commands inside the container, update, upgrade, install wget and ssh, add user jhooks, create temporary password, and then make the .ssh folder in my home folder. Then since we don't have access to the ssh server yet, it copies the key in the main folder through the host into the home folder of the container. Finally it logs back into the container and chown's the files inside /home/jhooks to make sure sudo didn't screw up permissions.The first time you create a container with ansible, it will take longer than you think it should, but after that it uses the cached template so this run took about 10-15 seconds.
Another couple things to note, eth0 is bridged on my desktop. Normally, the containers run with lxcbr0 as their bridge and are NAT'd behind your NIC with an address in 10.0.3.0/24. That interface comes up really quickly, but if you want normal network access you need a bridge. This comes up slower, at least on my systems (usually around 10-15 seconds). I just use
watch lxc-ls -f
and when it displays the IP of the container then you can log in without your password (using the key you copied) and then you can change your temporary password. -
So I realized some things went wrong. Since the interface doesn't come up right away, it wasn't installing the packages. I made a couple changes. This way it creates the container, stops it, adds the keys, creates an interface file under /etc/network/interfaces with an
ipaddr
variable from a jinja2 template, starts the container, pauses for 15 seconds, and then runs the updates and installation. On a normal system where the network interface would come up right away you wouldn't need to do this. Here's the changes:.
├── create.yml
├── hosts
├── key
├── known_hosts
├── templates
│ └── ip.j2
└── vars.ymlFolder structure for this specific playbook.
ip.j2 jinja template:
# This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/* # The loopback network interface auto lo iface lo inet loopback # The primary network interface auto eth0 iface eth0 inet static address {{ ipaddr }} netmask 255.255.255.0 broadcast 10.0.0.255 gateway 10.0.0.1 dns-nameservers 10.0.0.1
vars.yml
--- container: test ipaddr: 10.0.0.40
and the create.yml file
--- - hosts: megatron vars_files: - vars.yml gather_facts: false sudo: true tasks: - name: Create container lxc_container: name: "{{ container }}" template: ubuntu state: started template_options: --release wily --arch amd64 container_command: | useradd jhooks -s /bin/bash -m -U echo -e "tempass\ntempass" | passwd jhooks mkdir /home/jhooks/.ssh - name: Copy SSH key copy: src=key dest=/var/lib/lxc/{{ container }}/rootfs/home/jhooks/.ssh/authorized_keys mode=0600 - name: Add static IP template: src=templates/ip.j2 dest=/var/lib/lxc/{{ container }}/rootfs/etc/network/interfaces mode=0644 - name: Change Permissions lxc_container: name: "{{ container }}" state: started container_command: | chown -R jhooks:jhooks /home/jhooks chown root:root /etc/network/interfaces - name: Pause for 15 seconds pause: seconds=15 - name: Install wget and update lxc_container: name: "{{ container }}" container_command: | apt-get update apt-get upgrade -y apt-get install wget -y
-
I just checked the Ansible on CentOS 7, it too is not up to date contrary to the very clear documentation from Ansible that says that it is.
-
@scottalanmiller said:
I just checked the Ansible on CentOS 7, it too is not up to date contrary to the very clear documentation from Ansible that says that it is.
I haven't used it on CentOS 7 yet just Fedora and Ubuntu, thanks for the update. I wonder if installing from pip gives you the newest?
-
Does Fedora 23 have the latest?
-
no just 1.9.4. I think the clone_name is the only thing I've run into yet, but I haven't done that much.
-
@johnhooks said:
no just 1.9.4. I think the clone_name is the only thing I've run into yet, but I haven't done that much.
1.9.4-1 from the CentOS / RHEL 7 EPEL, too. Looks like the Ansible docs are wrong across the board. I wonder why they push a universally failing methodology specifically for getting the latest if there is no means of doing that from any platform.
-
@scottalanmiller said:
@johnhooks said:
no just 1.9.4. I think the clone_name is the only thing I've run into yet, but I haven't done that much.
1.9.4-1 from the CentOS / RHEL 7 EPEL, too. Looks like the Ansible docs are wrong across the board. I wonder why they push a universally failing methodology specifically for getting the latest if there is no means of doing that from any platform.
That's disappointing. I'm installing pip in a container and seeing if I can get a newer version that way.
-
Ah nevermind
Note
If you are intending to use Tower as the Control Machine, do not use a source install. Please use OS package manager (eg. apt/yum) or pip to install a stable version.I guess for the new features you need source, which isn't hard, you can just cd to the folder and run, but they should make that more known and not tell you to install from the package managers.
-
Yes, if the just didn't mention it, I would assume that I was going to be using GIT to keep it updated. It's only because they so strongly state otherwise that I looked at the repos.