summaryrefslogtreecommitdiff
path: root/doc/rtd/topics/faq.rst
blob: 2815f4928f82d2f891a4e409bcc85e97eeb6a4cc (plain)
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
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
.. _faq:

FAQ
***

How do I get help?
==================

Having trouble? We would like to help!

- First go through this page with answers to common questions
- Use the search bar at the upper left to search these docs
- Ask a question in the ``#cloud-init`` IRC channel on Libera
- Join and ask questions on the `cloud-init mailing list <https://launchpad.net/~cloud-init>`_
- Find a bug? Check out the :ref:`reporting_bugs` topic for
  how to report one

Where are the logs?
===================

Cloud-init uses two files to log to:

- `/var/log/cloud-init-output.log`: captures the output from each stage of
  cloud-init when it runs
- `/var/log/cloud-init.log`: very detailed log with debugging output,
  detailing each action taken
- `/run/cloud-init`: contains logs about how cloud-init decided to enable or
  disable itself, as well as what platforms/datasources were detected. These
  logs are most useful when trying to determine what cloud-init ran or did not
  run.

Be aware that each time a system boots, new logs are appended to the files in
`/var/log`. Therefore, the files may have more than one boot worth of
information present.

When reviewing these logs look for any errors or Python tracebacks to check
for any errors.

Where are the configuration files?
==================================

Cloud-init config is provided in two places:

- `/etc/cloud/cloud.cfg`
- `/etc/cloud/cloud.cfg.d/*.cfg`

These files can define the modules that run during instance initialization,
the datasources to evaluate on boot, and other settings.

Where are the data files?
=========================

Inside the `/var/lib/cloud/` directory there are two important subdirectories:

instance
--------

The `/var/lib/cloud/instance` directory is a symbolic link that points
to the most recently used instance-id directory. This folder contains the
information cloud-init received from datasources, including vendor and user
data. This can be helpful to review to ensure the correct data was passed.

It also contains the `datasource` file that contains the full information
about what datasource was identified and used to setup the system.

Finally, the `boot-finished` file is the last thing that cloud-init does.

data
----

The `/var/lib/cloud/data` directory contain information related to the
previous boot:

* `instance-id`: id of the instance as discovered by cloud-init. Changing
  this file has no effect.
* `result.json`: json file will show both the datasource used to setup
  the instance, and if any errors occurred
* `status.json`: json file shows the datasource used and a break down
  of all four modules if any errors occurred and the start and stop times.

What datasource am I using?
===========================

To correctly setup an instance, cloud-init must correctly identify the
cloud that it is on. Therefore knowing what datasource is used on an
instance launch can help aid in debugging.

To find what datasource is getting used run the `cloud-id` command:

.. code-block:: shell-session

    $ cloud-id
    nocloud

If the cloud-id is not what is expected, then running the `ds-identify`
script in debug mode and providing that in a bug can help aid in resolving
any issues:

.. code-block:: shell-session

    $ sudo DEBUG_LEVEL=2 DI_LOG=stderr /usr/lib/cloud-init/ds-identify --force

The force parameter allows the command to be run again since the instance has
already launched. The other options increase the verbosity of logging and
put the logs to STDERR.

How can I re-run datasource detection and cloud-init?
=====================================================

If a user is developing a new datasource or working on debugging an issue it
may be useful to re-run datasource detection and the initial setup of
cloud-init.

To do this, force ds-identify to re-run, clean up any logs, and re-run
cloud-init:

.. code-block:: shell-session

  $ sudo DI_LOG=stderr /usr/lib/cloud-init/ds-identify --force
  $ sudo cloud-init clean --logs
  $ sudo cloud-init init --local
  $ sudo cloud-init init

.. warning::

    These commands will re-run cloud-init as if this were first boot of a
    system: this will, at the very least, cycle SSH host keys and may do
    substantially more.  Do not run these commands on production systems.

How can I debug my user data?
=============================

Two of the most common issues with user data, that also happens to be
cloud-config is:

1. Incorrectly formatted YAML
2. First line does not contain `#cloud-config`

To verify your YAML, we do have a short script called `validate-yaml.py`_
that can validate your user data offline.

.. _validate-yaml.py: https://github.com/canonical/cloud-init/blob/main/tools/validate-yaml.py

Another option is to run the following on an instance to debug userdata
provided to the system:

.. code-block:: shell-session

    $ cloud-init schema --system --annotate

As launching instances in the cloud can cost money and take a bit longer,
sometimes it is easier to launch instances locally using Multipass or LXD:

Why did cloud-init never complete?
==================================

To check if cloud-init is running still, run:

.. code-block:: shell-session

        $ cloud-init status

To wait for clous-init to complete, run:

.. code-block:: shell-session

        $ cloud-init status --wait

There are a number of reasons that cloud-init might never complete. This list
is not exhaustive, but attempts to enumerate potential causes:

External reasons:
-----------------
- failed dependant services in the boot
- bugs in the kernel or drivers
- bugs in external userspace tools that are called by cloud-init

Internal reasons:
-----------------
- a command in ``bootcmd`` or ``runcmd`` that never completes (ex: running
  `cloud-init status --wait` will wait forever on itself and never complete)
- nonstandard configurations that disable timeouts or set extremely high
  values ("never" is used in a loose sense here)

How can I make a module run on every boot?
==========================================
Modules have a default frequency that can be overridden. This is done
by modifying the module list in ``/etc/cloud/cloud.cfg``.

1. Change the module from a string (default) to a list.
2. Set the first list item to the module name and the second item to the
   frequency.

Example
-------
The following example demonstrates how to log boot times to a file every boot.

Update ``/etc/cloud/cloud.cfg``:

.. code-block:: yaml
   :name: /etc/cloud/cloud.cfg
   :emphasize-lines: 3

        cloud_final_modules:
        # list shortened for brevity
         - [phone-home, always]
         - final-message
         - power-state-change



Then your userdata could then be:

.. code-block:: yaml

        #cloud-config
        phone_home:
            url: http://example.com/$INSTANCE_ID/
            post: all



How can I test cloud-init locally before deploying to the cloud?
================================================================

Several different virtual machine and containerization tools can be used for
testing locally. Multipass, LXD, and qemu are described in this section.


Multipass
---------

`Multipass`_ is a cross-platform tool to launch Ubuntu VMs across Linux,
Windows, and macOS.

When a user launches a Multipass VM, user data can be passed by adding the
`--cloud-init` flag and the appropriate YAML file containing user data:

.. code-block:: shell-session

    $ multipass launch bionic --name test-vm --cloud-init userdata.yaml

Multipass will validate the YAML syntax of the cloud-config file before
attempting to start the VM! A nice addition to help save time when
experimenting with launching instances with various cloud-configs.

Multipass only supports passing user-data and only as YAML cloud-config
files. Passing a script, a MIME archive, or any of the other user-data
formats cloud-init supports will result in an error from the YAML syntax
validator.

.. _Multipass: https://multipass.run/

LXD
---

`LXD`_ offers a streamlined user experience for using linux system
containers. With LXD, a user can pass:

* user data
* vendor data
* metadata
* network configuration

The following initializes a container with user data:

.. code-block:: shell-session

    $ lxc init ubuntu-daily:bionic test-container
    $ lxc config set test-container user.user-data - < userdata.yaml
    $ lxc start test-container

To avoid the extra commands this can also be done at launch:

.. code-block:: shell-session

    $ lxc launch ubuntu-daily:bionic test-container --config=user.user-data="$(cat userdata.yaml)"

Finally, a profile can be setup with the specific data if a user needs to
launch this multiple times:

.. code-block:: shell-session

    $ lxc profile create dev-user-data
    $ lxc profile set dev-user-data user.user-data - < cloud-init-config.yaml
    $ lxc launch ubuntu-daily:bionic test-container -p default -p dev-user-data

The above examples all show how to pass user data. To pass other types of
configuration data use the config option specified below:

+----------------+---------------------------+
| Data           | Config Option             |
+================+===========================+
| user data      | cloud-init.user-data      |
+----------------+---------------------------+
| vendor data    | cloud-init.vendor-data    |
+----------------+---------------------------+
| network config | cloud-init.network-config |
+----------------+---------------------------+

See the LXD `Instance Configuration`_ docs for more info about configuration
values or the LXD `Custom Network Configuration`_ document for more about
custom network config.

.. _LXD: https://linuxcontainers.org/
.. _Instance Configuration: https://linuxcontainers.org/lxd/docs/master/instances
.. _Custom Network Configuration: https://linuxcontainers.org/lxd/docs/master/cloud-init

QEMU
----

The `cloud-localds` command from the `cloud-utils`_ package generates a disk
with user supplied data. The NoCloud datasouce allows users to provide their
own user data, metadata, or network configuration directly to an instance
without running a network service. This is helpful for launching local cloud
images with QEMU for example.

The following is an example of creating the local disk using the cloud-localds
command:

.. code-block:: shell-session

    $ cat >user-data <<EOF
    #cloud-config
    password: password
    chpasswd:
      expire: False
    ssh_pwauth: True
    ssh_authorized_keys:
      - ssh-rsa AAAA...UlIsqdaO+w==
    EOF
    $ cloud-localds seed.img user-data

The resulting seed.img can then get passed along to a cloud image containing
cloud-init. Below is an example of passing the seed.img with QEMU:

.. code-block:: shell-session

    $ qemu-system-x86_64 -m 1024 -net nic -net user \
        -hda ubuntu-20.04-server-cloudimg-amd64.img \
        -hdb seed.img

The now booted image will allow for login using the password provided above.

For additional configuration, users can provide much more detailed
configuration, including network configuration and metadata:

.. code-block:: shell-session

    $ cloud-localds --network-config=network-config-v2.yaml \
      seed.img userdata.yaml metadata.yaml

See the :ref:`network_config_v2` page for details on the format and config of
network configuration. To learn more about the possible values for metadata,
check out the :ref:`datasource_nocloud` page.

.. _cloud-utils: https://github.com/canonical/cloud-utils/

Where can I learn more?
=======================

Below are some videos, blog posts, and white papers about cloud-init from a
variety of sources.

Videos:

- `cloud-init - The Good Parts`_
- `Perfect Proxmox Template with Cloud Image and Cloud Init [proxmox, cloud-init, template]`_
- `cloud-init - Building clouds one Linux box at a time (Video)`_
- `Metadata and cloud-init`_
- `Introduction to cloud-init`_

Blog Posts:

- `cloud-init - The cross-cloud Magic Sauce (PDF)`_
- `cloud-init - Building clouds one Linux box at a time (PDF)`_
- `The beauty of cloud-init`_
- `Cloud-init Getting Started [fedora, libvirt, cloud-init]`_
- `Build Azure Devops Agents With Linux cloud-init for Dotnet Development [terraform, azure, devops, docker, dotnet, cloud-init]`_
- `Cloud-init Getting Started [fedora, libvirt, cloud-init]`_
- `Setup Neovim cloud-init Completion [neovim, yaml, Language Server Protocol, jsonschema, cloud-init]`_

Events:

- `cloud-init Summit 2019`_
- `cloud-init Summit 2018`_
- `cloud-init Summit 2017`_


Whitepapers:

- `Utilising cloud-init on Microsoft Azure (Whitepaper)`_
- `Cloud Instance Initialization with cloud-init (Whitepaper)`_

.. _cloud-init - The Good Parts: https://www.youtube.com/watch?v=2_m6EUo6VOI
.. _Utilising cloud-init on Microsoft Azure (Whitepaper): https://ubuntu.com/engage/azure-cloud-init-whitepaper
.. _Cloud Instance Initialization with cloud-init (Whitepaper): https://ubuntu.com/blog/cloud-instance-initialisation-with-cloud-init

.. _cloud-init - The cross-cloud Magic Sauce (PDF): https://events.linuxfoundation.org/wp-content/uploads/2017/12/cloud-init-The-cross-cloud-Magic-Sauce-Scott-Moser-Chad-Smith-Canonical.pdf
.. _cloud-init - Building clouds one Linux box at a time (Video): https://www.youtube.com/watch?v=1joQfUZQcPg
.. _cloud-init - Building clouds one Linux box at a time (PDF): https://web.archive.org/web/20181111020605/https://annex.debconf.org/debconf-share/debconf17/slides/164-cloud-init_Building_clouds_one_Linux_box_at_a_time.pdf
.. _Metadata and cloud-init: https://www.youtube.com/watch?v=RHVhIWifVqU
.. _The beauty of cloud-init: https://web.archive.org/web/20180830161317/http://brandon.fuller.name/archives/2011/05/02/06.40.57/
.. _Introduction to cloud-init: http://www.youtube.com/watch?v=-zL3BdbKyGY
.. _Build Azure Devops Agents With Linux cloud-init for Dotnet Development [terraform, azure, devops, docker, dotnet, cloud-init]: https://codingsoul.org/2022/04/25/build-azure-devops-agents-with-linux-cloud-init-for-dotnet-development/
.. _Perfect Proxmox Template with Cloud Image and Cloud Init [proxmox, cloud-init, template]: https://www.youtube.com/watch?v=shiIi38cJe4
.. _Cloud-init Getting Started [fedora, libvirt, cloud-init]: https://blog.while-true-do.io/cloud-init-getting-started/
.. _Setup Neovim cloud-init Completion [neovim, yaml, Language Server Protocol, jsonschema, cloud-init]: https://phoenix-labs.xyz/blog/setup-neovim-cloud-init-completion/

.. _cloud-init Summit 2019: https://powersj.io/post/cloud-init-summit19/
.. _cloud-init Summit 2018: https://powersj.io/post/cloud-init-summit18/
.. _cloud-init Summit 2017: https://powersj.io/post/cloud-init-summit17/