summaryrefslogtreecommitdiff
path: root/man/nm-cloud-setup.xml
blob: 16c695a97fbf71ffc6f445ecbccaf2960cff073b (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
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY % entities SYSTEM "common.ent" >
%entities;
]>

<!--
  nm-cloud-setup(8) manual page

  Copyright 2020 Red Hat, Inc.

  Permission is granted to copy, distribute and/or modify this document
  under the terms of the GNU Free Documentation License, Version 1.1
  or any later version published by the Free Software Foundation;
  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
  Texts. You may obtain a copy of the GNU Free Documentation License
  from the Free Software Foundation by visiting their Web site or by
  writing to:

  Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-->

<refentry id="nm-cloud-setup">
  <refentryinfo>
    <title>nm-cloud-setup</title>
    <author>Automatic Network Configuration in Cloud with NetworkManager</author>
  </refentryinfo>

  <refmeta>
    <refentrytitle>nm-cloud-setup</refentrytitle>
    <manvolnum>8</manvolnum>
    <refmiscinfo class="source">NetworkManager</refmiscinfo>
    <refmiscinfo class="manual">Automatic Network Configuration in Cloud with NetworkManager</refmiscinfo>
    <refmiscinfo class="version">&NM_VERSION;</refmiscinfo>
  </refmeta>

  <refnamediv>
    <refname>nm-cloud-setup</refname>
    <refpurpose>Overview of Automatic Network Configuration in Cloud</refpurpose>
  </refnamediv>

  <refsect1>
    <title>Overview</title>

    <para>When running a virtual machine in a public cloud environment, it is
    desirable to automatically configure the network of that VM.
    In simple setups, the VM only has one network interface and the public
    cloud supports automatic configuration via DHCP, DHCP6 or IPv6 autoconf.
    However, on the virtual machine might have multiple network
    interfaces, or multiple IP addresses and IP subnets
    on one interface. Also, the administrator can reconfigure those settings
    while the machine is running. NetworkManager's nm-cloud-setup is a tool
    that automatically picks up such configuration and updates the network
    configuration of the host.</para>

    <para>Multiple cloud providers are supported. See <xref linkend="providers"/>.</para>
  </refsect1>

  <refsect1>
    <title>Use</title>

    <para>The goal of nm-cloud-setup is to be configuration-less and work automatically.
    All you need is to opt-in to the desired cloud providers (see <xref linkend="env"/>)
    and run <command>/usr/libexec/nm-cloud-setup</command>.</para>

    <para>Usually this is done by enabling the nm-cloud-setup.service systemd service
    and let it run periodically. For that there is both a nm-cloud-setup.timer systemd timer
    and a NetworkManager dispatcher script.</para>
  </refsect1>

  <refsect1>
    <title>Details</title>

    <para>
    nm-cloud-setup configures the network by fetching the configuration from
    the well-known meta data server of the cloud provider. That means, it already
    needs the network configured to the point where it can reach the meta data
    server. Commonly that means, that a simple connection profile is activated
    that possibly uses DHCP to get the primary IP address. NetworkManager will
    create such a profile for ethernet devices automatically if it is not configured
    otherwise via <literal>"no-auto-default"</literal> setting in NetworkManager.conf.
    One possible alternative may be to create such an initial profile with
    <command>nmcli device connect "$DEVICE"</command> or
    <command>nmcli connection add type ethernet ...</command>.
    </para>

    <para>nm-cloud-setup modifies the run time configuration akin to <command>nmcli device modify</command>.
    With this approach, the configuration is not persisted
    and only preserved until the device disconnects.</para>

    <refsect2>
      <title>/usr/libexec/nm-cloud-setup</title>

      <para>The binary <command>/usr/libexec/nm-cloud-setup</command> does most of the
      work. It supports no command line arguments but can be configured via environment
      variables.
      See <xref linkend="env"/> for the supported environment variables.</para>

      <para>By default, all cloud providers are disabled unless you opt-in by enabling one
      or several providers. If cloud providers are enabled, the program
      tries to fetch the host's configuration from a meta data server of the cloud via HTTP.
      If configuration could be not fetched, no cloud provider are detected and the
      program quits.
      If host configuration is obtained, the corresponding cloud provider is
      successfully detected. Then the network of the host will be configured.</para>

      <para>It is intended to re-run nm-cloud-setup every time when the configuration
      (maybe) changes. The tool is idempotent, so it should be OK to also run it
      more often than necessary. You could run <command>/usr/libexec/nm-cloud-setup</command>
      directly. However it may be preferable to restart the nm-cloud-setup systemd
      service instead or use the timer or dispatcher script to run it periodically (see below).</para>
    </refsect2>

    <refsect2>
      <title>nm-cloud-setup.service systemd unit</title>
      <para>Usually <command>/usr/libexec/nm-cloud-setup</command> is not run directly,
      but only by <command>systemctl restart nm-cloud-setup.service</command>. This
      ensures that the tool only runs once at any time. It also allows to integrate
      use the nm-cloud-setup systemd timer,
      and to enable/disable the service via systemd.</para>

      <para>As you need to set environment variable to configure nm-cloud-setup binary,
      you can do so via systemd override files. Try <command>systemctl edit nm-cloud-setup.service</command>.</para>
    </refsect2>

    <refsect2>
      <title>nm-cloud-setup.timer systemd timer</title>
      <para><command>/usr/libexec/nm-cloud-setup</command> is intended to run
      whenever an update is necessary. For example, during boot when when
      changing the network configuration of the virtual machine via the cloud
      provider.</para>

      <para>One way to do this, is by enabling the nm-cloud-setup.timer systemd timer
      with <command>systemctl enable --now nm-cloud-setup.timer</command>.</para>
    </refsect2>

    <refsect2>
      <title>/usr/lib/NetworkManager/dispatcher.d/90-nm-cloud-setup.sh</title>

      <para>There is also a NetworkManager dispatcher script that will
      run for example when an interface is activated by NetworkManager.
      Together with the nm-cloud-setup.timer systemd timer this
      script is to automatically pick up changes to the network.</para>

      <para>The dispatcher script will do nothing, unless the systemd service is
      enabled. To use the dispatcher script you should therefor run
      <command>systemctl enable nm-cloud-setup.service</command> once.</para>
    </refsect2>

  </refsect1>

  <refsect1 id="env">
    <title>Environment Variables</title>

    <para>The environment variables are used to configure <command>/usr/libexec/nm-cloud-setup</command>.
    You may want to configure them in the systemd service with <command>systemctl edit nm-cloud-setup.service</command>.</para>

    <itemizedlist>
      <listitem>
        <para><literal>NM_CLOUD_SETUP_LOG</literal>: control the logging verbosity. Set it
          one of <literal>TRACE</literal>, <literal>DEBUG</literal>, <literal>INFO</literal>,
          <literal>WARN</literal>, <literal>ERR</literal> or <literal>OFF</literal>. The program
          will print message on stdout and the default level is <literal>WARN</literal>.</para>
      </listitem>
      <listitem>
        <para><literal>NM_CLOUD_SETUP_AZURE</literal>: boolean, whether Microsoft Azure support is enabled. Defaults
          to <literal>no</literal>.</para>
      </listitem>
      <listitem>
        <para><literal>NM_CLOUD_SETUP_EC2</literal>: boolean, whether Amazon EC2 (AWS) support is enabled. Defaults
          to <literal>no</literal>.</para>
      </listitem>
      <listitem>
        <para><literal>NM_CLOUD_SETUP_GCP</literal>: boolean, whether Google GCP support is enabled. Defaults
          to <literal>no</literal>.</para>
      </listitem>
    </itemizedlist>

  </refsect1>

  <refsect1 id="providers">
    <title>Supported Cloud Providers</title>

    <refsect2>
      <title>Amazon EC2 (AWS)</title>

      <para>The tools tries to fetch configuration from <literal>http://169.254.169.254/</literal>. Currently, it only
      configures IPv4 and does nothing about IPv6. It will do the following.</para>

      <itemizedlist>
        <listitem>
          <para>First fetch <literal>http://169.254.169.254/latest/meta-data/</literal> to determine whether the
          expected API is present. This determines whether EC2 environment is detected and whether to proceed
          to configure the host using EC2 meta data.</para>
        </listitem>
        <listitem>
          <para>Fetch <literal>http://169.254.169.254/2018-09-24/meta-data/network/interfaces/macs/</literal> to get the list
          of available interface. Interfaces are identified by their MAC address.</para>
        </listitem>
        <listitem>
          <para>Then for each interface fetch <literal>http://169.254.169.254/2018-09-24/meta-data/network/interfaces/macs/$MAC/subnet-ipv4-cidr-block</literal>
          and <literal>http://169.254.169.254/2018-09-24/meta-data/network/interfaces/macs/$MAC/local-ipv4s</literal>.
          Thereby we get a list of local IPv4 addresses and one CIDR subnet block.</para>
        </listitem>
        <listitem>
          <para>Then nm-cloud-setup iterates over all interfaces for which it could fetch IP configuration.
          If no ethernet device for the respective MAC address is found, it is skipped.
          Also, if the device is currently not activated in NetworkManager or if the currently
          activated profile has a user-data <literal>org.freedesktop.nm-cloud-setup.skip=yes</literal>,
          it is skipped.</para>
          <para>Then, the tool will change the runtime configuration of the device.
            <itemizedlist>
              <listitem>
                <para>Add static IPv4 addresses for all the configured addresses from <literal>local-ipv4s</literal> with
                prefix length according to <literal>subnet-ipv4-cidr-block</literal>. For example,
                we might have here 2 IP addresses like <literal>"172.16.5.3/24,172.16.5.4/24"</literal>.</para>
              </listitem>
              <listitem>
                  <para>Choose a route table 30400 + the index of the interface and
                  add a default route <literal>0.0.0.0/0</literal>. The gateway
                  is the first IP address in the CIDR subnet block. For
                  example, we might get a route <literal>"0.0.0.0/0 172.16.5.1 10 table=30401"</literal>.</para>
              </listitem>
              <listitem>
                  <para>Finally, add a policy routing rule for each address. For example
                  <literal>"priority 30401 from 172.16.5.3/32 table 30401, priority 30401 from 172.16.5.4/32 table 30401"</literal>.</para>
              </listitem>
            </itemizedlist>
            With above example, this roughly corresponds for interface <literal>eth0</literal> to
            <command>nmcli device modify "eth0" ipv4.addresses "172.16.5.3/24,172.16.5.4/24" ipv4.routes "0.0.0.0/0 172.16.5.1 10 table=30401" ipv4.routing-rules "priority 30401 from 172.16.5.3/32 table 30401, priority 30401 from 172.16.5.4/32 table 30401"</command>.
            Note that this replaces the previous addresses, routes and rules with the new information.
            But also note that this only changes the run time configuration of the device. The
            connection profile is not affected by that.
          </para>
        </listitem>
      </itemizedlist>
   </refsect2>

    <refsect2>
      <title>Google Cloud Platform (GCP)</title>

      <para>The tools tries to fetch configuration from <literal>http://metadata.google.internal/</literal>.</para>
    </refsect2>

    <refsect2>
      <title>Microsoft Azure</title>

      <para>The tools tries to fetch configuration from <literal>http://169.254.169.254/</literal>.</para>
    </refsect2>

  </refsect1>

  <refsect1>
    <title>See Also</title>
    <para>
      <link linkend='NetworkManager'><citerefentry><refentrytitle>NetworkManager</refentrytitle><manvolnum>8</manvolnum></citerefentry></link>
      <link linkend='nmcli'><citerefentry><refentrytitle>nmcli</refentrytitle><manvolnum>1</manvolnum></citerefentry></link>
    </para>
  </refsect1>
</refentry>