-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathansible-to-deploy-lxc-containers.html
287 lines (264 loc) · 15.4 KB
/
ansible-to-deploy-lxc-containers.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Creating and using LXC containers with Ansible in-memory inventory | gpocentek's webspace</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="keywords" content="" />
<meta name="author" content="Gauvain Pocentek" />
<meta name="kittycheck_rumble" content="true" />
<meta name="kittycheck_position" content="top=60,right=60" />
<!-- Le styles -->
<link rel="stylesheet" href="./theme/css/bootstrap.min.css" type="text/css" />
<style type="text/css">
body {
padding-top: 60px;
padding-bottom: 40px;
}
.sidebar-nav {
padding: 9px 0;
}
.tag-1 {
font-size: 13pt;
}
.tag-2 {
font-size: 10pt;
}
.tag-2 {
font-size: 8pt;
}
.tag-4 {
font-size: 6pt;
}
</style>
<link href="./theme/css/bootstrap-responsive.min.css" rel="stylesheet">
<link href="./theme/css/font-awesome.css" rel="stylesheet">
<link href="./theme/css/pygments.css" rel="stylesheet">
<link href="./theme/css/local.css" rel="stylesheet">
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!-- Le fav and touch icons -->
<link rel="shortcut icon" href="./theme/img/favicon.ico">
<link rel="apple-touch-icon" href="./theme/img/apple-touch-icon.png">
<link rel="apple-touch-icon" sizes="72x72" href="./theme/img/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="114x114" href="./theme/img/apple-touch-icon-114x114.png">
<link href="./" type="application/atom+xml" rel="alternate" title="gpocentek's webspace ATOM Feed" />
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container-fluid">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="./index.html"><strong>gpocentek's webspace</strong> – Random dev & ops notes</a>
<div class="nav-collapse">
<ul class="nav">
</ul>
<!--<p class="navbar-text pull-right">Logged in as <a href="#">username</a></p>-->
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="span8" id="content">
<div class="row">
<div class="span8">
<section id="content" class="well">
<article>
<header>
<h1>
<a href=""
rel="bookmark"
title="Permalink to Creating and using LXC containers with Ansible in-memory inventory">
Creating and using LXC containers with Ansible in-memory inventory
</a>
</h1>
<a href="./tag/ansible.html" class="label"><i class="icon-tag"></i> ansible</a>
<a href="./tag/lxc.html" class="label"><i class="icon-tag"></i> lxc</a>
<abbr class="published pull-right" title="2016-10-10T07:22:00+02:00">
<i class="icon-calendar"></i> mån 10 oktober 2016
</abbr>
</header>
<div class="entry-content">
<div class="section" id="what-we-want-to-do">
<h2>What we want to do</h2>
<p>Ansible provides an <a class="reference external" href="http://docs.ansible.com/ansible/lxc_container_module.html">lxc_container</a> module to manage LXC containers on a remote
host. It is very handy but once you've deployed a container you need to manage
applications deployed inside this container. Also with Ansible obviously!</p>
<p>A simple approach could be to write a playbook to deploy the LXC containers,
then generate a static inventory, and finally use this inventory with another
playbook to deploy your final application.</p>
<p>An other approach is to have a single playbook. The first play will deploy the
LXC containers and generate an in-memory inventory using the <a class="reference external" href="http://docs.ansible.com/ansible/add_host_module.html">add_host</a> module
for each container. The <tt class="docutils literal">lxc_container</tt> module returns the IP addresses for
the container (once it's started).</p>
<p>If your containers are connected to an internal bridge on the remote host, you
also need to configure your SSH client to help ansible access them.</p>
</div>
<div class="section" id="an-example-of-how-it-can-be-done">
<h2>An example of how it can be done</h2>
<p>The example uses the following setup:</p>
<ul>
<li><p class="first">the LXC hosts are listed in the <tt class="docutils literal">[lxc_hosts]</tt> group in the inventory</p>
</li>
<li><p class="first">for each host a list of containers to manage is defined in the <tt class="docutils literal">containers</tt>
variable in a <tt class="docutils literal"><span class="pre">host_vars/{{inventory_hostname}}</span></tt> file, with content similar
to this:</p>
<div class="highlight"><pre><span></span><span class="l l-Scalar l-Scalar-Plain">containers</span><span class="p p-Indicator">:</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">memcached-1</span>
<span class="l l-Scalar l-Scalar-Plain">service</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">memcache</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">mysql-1</span>
<span class="l l-Scalar l-Scalar-Plain">service</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">mysql</span>
</pre></div>
</li>
<li><p class="first">containers are connected to an <tt class="docutils literal">lxcbr0</tt> bridge, on a 10.0.100.0/24 network</p>
</li>
<li><p class="first">containers are deployed using a custom <tt class="docutils literal"><span class="pre">ubuntu-ansible</span></tt> template, based on
the original <tt class="docutils literal">ubuntu</tt> template. The template provides some extra
configuration steps to ease ansible integration:</p>
<ul class="simple">
<li>installation of python2.7</li>
<li>passwordless sudo configuration</li>
<li>injection of an SSH public key</li>
</ul>
<p>You can use the <tt class="docutils literal">container_command</tt> argument of the <tt class="docutils literal">lxc_container</tt>
module instead if using a custom template.</p>
</li>
</ul>
<div class="section" id="sample-playbook">
<h3>Sample playbook</h3>
<p>The first play creates the containers (if needed), and retrieves the dynamically
assigned IP addresses of all managed containers:</p>
<div class="highlight"><pre><span></span><span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">hosts</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">lxc_hosts</span>
<span class="l l-Scalar l-Scalar-Plain">become</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">tasks</span><span class="p p-Indicator">:</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Create the containers</span>
<span class="l l-Scalar l-Scalar-Plain">lxc_container</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">template</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">ubuntu-ansible</span>
<span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="s">"{{</span><span class="nv"> </span><span class="s">item.name</span><span class="nv"> </span><span class="s">}}"</span>
<span class="l l-Scalar l-Scalar-Plain">state</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">started</span>
<span class="l l-Scalar l-Scalar-Plain">with_items</span><span class="p p-Indicator">:</span> <span class="s">"{{</span><span class="nv"> </span><span class="s">containers</span><span class="nv"> </span><span class="s">}}"</span>
<span class="l l-Scalar l-Scalar-Plain">register</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">containers_info</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Wait for the network to be setup in the containers</span>
<span class="l l-Scalar l-Scalar-Plain">when</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">containers_info|changed</span>
<span class="l l-Scalar l-Scalar-Plain">pause</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">seconds=10</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Get containers info now that IPs are available</span>
<span class="l l-Scalar l-Scalar-Plain">lxc_container</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="s">"{{</span><span class="nv"> </span><span class="s">item.name</span><span class="nv"> </span><span class="s">}}"</span>
<span class="l l-Scalar l-Scalar-Plain">with_items</span><span class="p p-Indicator">:</span> <span class="s">"{{</span><span class="nv"> </span><span class="s">containers</span><span class="nv"> </span><span class="s">}}"</span>
<span class="l l-Scalar l-Scalar-Plain">register</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">containers_info</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Register the hosts in the inventory</span>
<span class="l l-Scalar l-Scalar-Plain">add_host</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="s">"{{</span><span class="nv"> </span><span class="s">item.lxc_container.ips.0</span><span class="nv"> </span><span class="s">}}"</span>
<span class="l l-Scalar l-Scalar-Plain">group</span><span class="p p-Indicator">:</span> <span class="s">"{{</span><span class="nv"> </span><span class="s">item.item.service</span><span class="nv"> </span><span class="s">}}"</span>
<span class="l l-Scalar l-Scalar-Plain">with_items</span><span class="p p-Indicator">:</span> <span class="s">"{{</span><span class="nv"> </span><span class="s">containers_info.results</span><span class="nv"> </span><span class="s">}}"</span>
</pre></div>
<p>The following plays use the newly added groups and hosts:</p>
<div class="highlight"><pre><span></span><span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">hosts</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">memcache</span>
<span class="l l-Scalar l-Scalar-Plain">become</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">tasks</span><span class="p p-Indicator">:</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">debug</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">msg="memcached deployment"</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">hosts</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">mysql</span>
<span class="l l-Scalar l-Scalar-Plain">become</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">tasks</span><span class="p p-Indicator">:</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">debug</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">msg="mysql deployment"</span>
</pre></div>
</div>
<div class="section" id="ssh-client-configuration">
<h3>SSH client configuration</h3>
<p>In the example setup Ansible can't reach the created containers because they
are connected on an isolated network. This can be dealt with an ssh
configuration in <tt class="docutils literal"><span class="pre">~/.ssh/config</span></tt>:</p>
<div class="highlight"><pre><span></span>Host lxc1
Hostname lxc1.domain.com
User localadmin
Host 10.0.100.*
User ubuntu
ForwardAgent yes
ProxyCommand ssh -q lxc1 nc %h %p
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
</pre></div>
</div>
</div>
<div class="section" id="final-word">
<h2>Final word</h2>
<p>Although this example deploys LXC containers, the same process can be used for
any type of VM/container deployment: EC2, OpenStack, GCE, Azure or any other
platform.</p>
</div>
</div><!-- /.entry-content -->
</article>
</section>
</div>
</div>
</div><!--/span-->
<div class="span3 well sidebar-nav" id="sidebar">
<ul class="nav nav-list">
<li class="nav-header"><h4><i class="icon-home icon-large"></i> social</h4></li>
<li><a href="https://www.linkedin.com/in/gauvainpocentek"><i class="icon-linkedin-sign icon-large"></i>linkedin</a></li>
<li><a href="https://github.com/gpocentek"><i class="icon-github-sign icon-large"></i>github</a></li>
<li class="nav-header"><h4><i class="icon-folder-close icon-large"></i>Categories</h4></li>
<li>
<a href="./category/ansible.html">
<i class="icon-folder-open icon-large"></i>ansible
</a>
</li>
<li>
<a href="./category/containers.html">
<i class="icon-folder-open icon-large"></i>containers
</a>
</li>
<li>
<a href="./category/lxc.html">
<i class="icon-folder-open icon-large"></i>lxc
</a>
</li>
<li>
<a href="./category/lxd.html">
<i class="icon-folder-open icon-large"></i>lxd
</a>
</li>
<li>
<a href="./category/medibuntu.html">
<i class="icon-folder-open icon-large"></i>medibuntu
</a>
</li>
<li>
<a href="./category/misc.html">
<i class="icon-folder-open icon-large"></i>misc
</a>
</li>
<li>
<a href="./category/openstack.html">
<i class="icon-folder-open icon-large"></i>openstack
</a>
</li>
<li>
<a href="./category/python-gitlab.html">
<i class="icon-folder-open icon-large"></i>python-gitlab
</a>
</li>
<li class="nav-header"><h4><i class="icon-th-list icon-large"></i>Archives</h4></li>
<li><a href="./archives.html"><i class="icon-edit icon-large"></i>articles</a></li>
<li class="nav-header"><h4><i class="icon-inbox icon-large"></i>Contact</h4></li>
<li><a href="mailto:[email protected]">
<i class="icon-envelope icon-large"></i>email</a></li>
</li>
<li></li>
</ul> </div><!--/.well -->
</div><!--/row-->
<hr>
</div><!--/.fluid-container-->
<!-- Le javascript -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./theme/js/jquery-1.7.2.min.js"></script>
<script src="./theme/js/bootstrap.min.js"></script>
</body>
</html>