6

How can I get the IP address of an LXC container in a format I can use in scripting?

Right now, the command lxc info <container> report that information, but in a human readable format, with a lot of information.

I would like to ONLY to GET the IP address given a container name.

Note: I HAVE to duplicate this question because Linux Containers have changed a lot.

Installing lxd and using unprivileged containers is the default way to go this days (2017) and I think the solutions posted on the original question are do not resolve the issue in this case.

In any case, I installed the package lxc1 to get access to the command lxc-info, but that command doesn't recognize any of my unprivileged containers.

jgomo3
  • 716

8 Answers8

5

A native solution (which isn't any prettier than @siloko's answer) would be

lxc list "<name>" -c 4 | awk '!/IPV4/{ if ( $2 != "" ) print $2}'

There are alternatives to awk, but that's tangential to the question.

Jonathan Y.
  • 1,054
4

So far this is the easiest way:

lxc list -c4 --format csv <container> | cut -d' ' -f1

But maybe it will be possible without cut.

EDIT: Uncut bash:

a=( $(lxc list -c4 --format csv u1) ) ip4=$a[1] echo $ip4

Hint from @monstermunchkin from the above issue.

2
lxc list | grep nameofthecontainer | egrep -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"

This is what I am using, I pass the container name in as a variable.

muru
  • 207,228
Neil
  • 21
2

pylxd is the official python API client interface developed, supported, and endorsed by the LXD project.

Installation instructions here

$ python3
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
>>> from pylxd import Client
>>> client = Client()
>>> for p in client.containers.all(): print(p.name, p.state().network['eth0']['addresses'][0]['address'])
... 
stretch-cc 10.76.67.242
0

These use a single grep.

For IPv4:

lxc info container-name |grep -Po '\seth\d:\sinet\s+\K[0-9\.]+'

For IPv6 (will probably list multiple IPs):

lxc info container-name |grep -Po '\seth\d:\sinet6\s+\K[0-9a-f:]+'
bitinerant
  • 1,157
0

Install jq:

sudo apt-get install jq

The function get_lxc_container_ip has 4 arguments:

  • arg1: container name
  • arg2(optional): family, inet(default) or inet6
  • arg3(optional): interface, default values are both eth0 and enp5s0
  • arg4(optional): scope, global(default), link or local

Exit status:

  • 0: success
  • 4: no valid result
  • 1 (not likely): jq last output value was either false or null
  • 2 (not likely): jq usage problem or system error
  • 3 (not likely): jq program compile error
get_lxc_container_ip() {
    local container=$1
    local family=${2:-inet}
    local interface=\"${3:-'eth0", "enp5s0'}\"
    local scope=${4:-global}
    lxc list --format json |
        jq -re 'try .[] | select (.name == "'"$container"'") 
            | .state.network | to_entries[]
            | select(.key == ('"$interface"')).value.addresses[]
            | select((.family == "'"$family"'") and (.scope == "'"$scope"'"))
            | .address'
}

Since a container can create many interfaces (e.g. run docker/lxd inside the container with security.nesting=true), other ways based on text filtering may get inaccurate result. jq does not have this problem.

Be aware that some interfaces may have multiple IP addresses (e.g. family=inet6 and scope=global), you may need to pipe it to head -1 to get the first result.

0

Probably a bit ugly but:

lxc-info -n my-container | grep IP: | tr -d ' ' | cut -f2 -d:

will get you just the IP address

slowko
  • 932
-1
lxc-info --name container --ips --no-humanize

prints the container IP addresses.

The returned value is a list because a container can have more than one address.