Linux System Administration Questions
Operating and maintaining Linux and Unix systems: filesystems and permissions, process and service management, package management and updates, shell and scripting, storage, and network configuration on the host. Covers day-to-day administration, troubleshooting, monitoring and tuning host resource usage (CPU, memory, swap, and I/O), and hardening of Linux servers that underpin most infrastructure. The Linux operator's core skill set.
You're responsible for optimizing NFS performance for a build farm that has many small file reads. What kernel-level and mount-option settings would you consider changing on the client and server to improve throughput and reduce latency? Explain trade-offs.
Sample Answer
Direct answer
For a build farm's small-file-read pattern, the dominant cost is METADATA round-trips (an open, a stat, a
close, for every tiny file) rather than raw data throughput, so the highest-leverage changes are lengthening
the client's attribute cache and, on NFS (Network File System, the standard protocol for sharing filesystems
over a network) version 4.1 or newer, using delegations so a client can serve repeated opens and reads from
its own local cache with zero server round-trips. Recommend NFSv4.1+ with delegations as the default for
this workload over tuning NFSv3 options alone, and that recommendation flips for a workload dominated by many
clients concurrently WRITING to the same files, where delegations mostly can't be granted and their benefit
disappears.
Structured elaboration, client and server, with trade-offs
Client-side mount options:
rsize/wsize(the read/write buffer size per RPC, remote procedure call, request): raised toward the
maximum the server and network support (commonly up to 1MiB on a modern NFSv4 setup over a fast LAN)
reduces the NUMBER of round-trips per file read. Trade-off: larger buffers cost more memory per
outstanding request, though for genuinely tiny files this knob matters far less than the metadata-focused
ones below.actimeo(attribute cache timeout, how long the client trusts its cached copy of a file's size,
modification time, and permissions before re-validating with the server): raised from the historical
few-second default to somewhere in the 60 to 600 second range for a read-mostly, rarely-changing source
tree, cutting the exact "stat every file" round-trip pattern build tools are notorious for. Trade-off: a
longeractimeomeans a change made on one client or the server takes longer to become visible elsewhere,
fine for source checked out once per build, dangerous for files multiple agents actively read and write
concurrently.nconnect(multiple TCP, Transmission Control Protocol, connections per mount, supported on modern Linux
NFS clients) spreads many small, latency-bound requests across several connections instead of serializing
them behind one connection's round-trip time, directly attacking the "many tiny requests, each paying full
round-trip latency" cost profile. Trade-off: more open connections and threads on both client and server,
a real resource cost across many build clients at once.- NFSv4.1+ delegations: the server grants a client exclusive or read-only authority over a file, letting
the client serve subsequent opens, reads, and closes from local cache with zero server round-trip until
the delegation is recalled, the single biggest win for a build farm's repeatedly-opened header and source
files. Trade-off: delegations are recalled the moment any other client wants conflicting access, so heavy
cross-client writes to the same files get little benefit and pay some delegation-management overhead for
nothing. noatimeon the client mount to stop every read from also generating a metadata-updating write (access
time) back to the server, a nearly free win with no real use case in a build farm.
Server-side and kernel-level:
nfsdthread count: a small-file-heavy workload generates a high RATE of quick operations, benefiting
from more concurrent server threads than a large-sequential-file workload needs, but too many relative to
the server's actual disk and CPU capacity just adds contention, tune against observed server saturation,
not blindly.- Backing storage latency matters far more here than for large sequential workloads: small-file metadata
operations are latency-bound (each pays a full seek or lookup cost), not throughput-bound, so an SSD
(solid-state drive) backed export changes the picture dramatically compared to spinning disk, where
no client-side tuning fixes a genuinely slow backing store. asyncversussyncexport options trade write-acknowledgment speed against durability (a crash under
asynccan silently lose acknowledged writes); this workload, described as read-heavy small-file reads,
benefits far less from this knob than the read-side changes above, since the win is specifically on the
write path.
Worked example
A build farm of 200 continuous integration (CI) agents each checks out roughly 500,000 files, typically
under 4KiB each, from one NFS server before every build. On a baseline NFSv3 mount with default 8KiB
rsize/wsize and a 3-second actimeo, every checkout re-validates metadata for essentially every file
against the server: even at a conservative 1ms per round-trip, 500,000 metadata round-trips alone is over
eight minutes of pure wait per agent before any file content transfers at all (this is a direct arithmetic
consequence of the stated file count and an assumed round-trip time, not a benchmark claim, the real number
on any given network will differ, but the SHAPE, metadata round-trip count scaling linearly with file
count, is the reproducible point). Moving to NFSv4.1 with delegations means the second and later agents to
touch an unchanged tree serve most of those lookups from a granted delegation with zero server round-trips,
and raising actimeo to 300 seconds for agents that don't hold a delegation cuts their re-validation rate
by roughly two orders of magnitude relative to the 3-second default, both changes attacking the same
bottleneck the baseline arithmetic identifies: round-trip COUNT, not raw data throughput.
Trade-offs and pitfalls
The most common wrong turn on this exact workload is tuning rsize/wsize upward and stopping there, that
only helps DATA throughput for large reads, while a build farm's actual bottleneck, as the arithmetic above
shows, is metadata round-trip count for many tiny files, which actimeo, delegations, and nconnect
address directly and rsize/wsize barely touch. Also, applying an aggressive actimeo to a tree that IS
actively modified by other build steps (generated artifacts, not just checked-out source) reintroduces real
staleness bugs, agents silently working from stale metadata about files other agents just wrote, so long
cache lifetimes belong specifically on the read-only, checked-out-once source tree, with shorter caching (or
a separate mount) kept for any shared, actively-written build-output directory.
Describe how to set up a persistent ip route and a static IP on a modern Linux distribution (systemd-based). Provide the files or commands you would use, and how to verify the configuration.
Sample Answer
Direct answer
On a modern systemd-based Linux distribution the network stack itself is normally managed by one
of two systemd-adjacent tools: Netplan (Ubuntu, rendering to systemd-networkd or
NetworkManager) or NetworkManager directly via nmcli (RHEL/Fedora/most other current
distributions). Both persist a static IP and a route as a declarative config file that survives
reboot; neither uses the legacy ifconfig/route add commands, which do not persist at all.
Structured elaboration
Ubuntu: Netplan
Write a YAML file under /etc/netplan/ (mode 600, root-only, since it can contain credentials
for other network types):
# /etc/netplan/01-static.yaml
network:
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: false
addresses:
- 192.168.1.50/24
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses: [1.1.1.1, 8.8.8.8]
Apply with sudo netplan apply (or netplan try, which auto-rolls-back if you do not confirm
within a timeout, the safer choice over a remote SSH session where a bad config could lock you
out). Netplan is a generator: it translates this YAML into the actual backend config (a
systemd-networkd .network file, or NetworkManager keyfiles, depending on renderer:) and
that generated config, not the YAML directly, is what persists the setting across reboots.
RHEL 8+/current: NetworkManager via nmcli
nmcli connection add type ethernet con-name static-eth0 ifname eth0 \
ipv4.method manual ipv4.addresses 192.168.1.50/24 \
ipv4.gateway 192.168.1.1 ipv4.dns "1.1.1.1 8.8.8.8"
nmcli connection up static-eth0
This writes a persistent connection profile (a keyfile under
/etc/NetworkManager/system-connections/) that NetworkManager reactivates automatically on every
boot; there is no separate "make it permanent" step, creating the connection profile is the
persistence mechanism.
Verification, either path
ip addr show <iface>confirms the address is actually bound.ip route showconfirms the route table, in particular the default route via the gateway you
set.resolvectl status(networkd) ornmcli device show <iface>(NetworkManager) confirms DNS
servers took effect.journalctl -u systemd-networkdorjournalctl -u NetworkManagerfor anything that failed to
apply.- Reboot (or at minimum,
systemctl restartthe relevant service) once and re-check the same
three commands, since a config that "looks right" in the file but was never actually re-applied
is a common false confidence trap.
Worked example
Both were verified for real. The Netplan YAML above was fed to netplan generate (the step
netplan apply runs internally before touching the live interface), which produced the exact
systemd-networkd unit it is documented to produce:
$ netplan generate && cat /run/systemd/network/10-netplan-eth0.network
[Match]
Name=eth0
[Network]
LinkLocalAddressing=ipv6
Address=192.168.1.50/24
DNS=1.1.1.1
DNS=8.8.8.8
[Route]
Destination=0.0.0.0/0
Gateway=192.168.1.1
The nmcli command above was run against a live NetworkManager instance and produced the
persisted keyfile exactly as documented:
$ cat /etc/NetworkManager/system-connections/static-eth0.nmconnection
[connection]
id=static-eth0
type=ethernet
interface-name=eth0
[ipv4]
address1=192.168.1.50/24
dns=1.1.1.1;8.8.8.8;
gateway=192.168.1.1
method=manual
One caveat worth calling out: this specific container's interface came up as plain eth0
(confirmed with ip -o link show), because Docker's bridge networking assigns veth interfaces
eth0 by convention and there is no PCI bus path for udev's predictable-naming rules to key off
inside a container network namespace. That does not generalize to real hardware or a VM: there,
with systemd-udev predictable network interface naming active (the default on virtually every
current distribution), the interface is almost never called eth0, it is something like
enp1s0, ens192, or enp0s3 depending on the bus and slot. Never hardcode eth0 in either
config on a real host; always confirm the actual name with ip -o link show first, since a
config written against a name the interface does not have will silently fail to apply to
anything.
Trade-offs and pitfalls
- Applying a bad static config over SSH can cut your own access;
netplan try(auto-rollback on
timeout) or bringing the change up on a console/out-of-band path first are the safe patterns,
applying blind over the connection you are about to change is not. - Mixing tools is a real footgun: if
NetworkManageris active and you also hand-edit
/etc/network/interfaces(the old Debian ifupdown format) or vice versa, the two can fight over
the same interface. Check which manager actually owns the interface (nmcli device status,
ornetworkctl statusfor networkd) before adding a second config source. - A route added with the old
ip route add ...command (no persistence file behind it) vanishes
on reboot; this is the single most common "it worked, then broke after a routine reboot"
incident on freshly built hosts, always encode the route in the same persistent config as the
address, never as an ad hocip route add. - DNS set via
nameservers:/ipv4.dnsonly takes effect if nothing else (like a DHCP client on
a different interface, or a stale/etc/resolv.confnot managed byresolvectl) is overriding
it;resolvectl statusshowing the expected servers is the actual proof, not just the config
file content.
Describe how to view and bring up or down a network interface on a modern Linux system. Include concrete commands using both ip and ifconfig, explain the differences between iproute2 and legacy tools, and describe how to make the interface state persistent across reboots using systemd-networkd, Netplan, or /etc/network/interfaces.
Sample Answer
Direct answer
To inspect and control interface state right now, ip (from the iproute2 package) is the modern, actively maintained tool, and ifconfig (from the older net-tools package) is a legacy tool that still works on many distributions but has been effectively unmaintained for years and cannot represent things modern Linux networking supports, like multiple IPv6 addresses cleanly or network namespaces (isolated network stacks, each with its own interfaces and routing table, that containers rely on to keep their networking separate from the host's). Neither ip nor ifconfig changes survive a reboot on their own; making an interface's state persistent needs the distribution's actual network configuration layer: Netplan (Ubuntu), systemd-networkd, or the classic /etc/network/interfaces file with ifupdown.
Viewing and toggling with each tool
With iproute2 (ip):
ip addr show eth0 # view addresses on eth0
ip link set eth0 up # bring the interface up
ip link set eth0 down # bring it down
ip addr add 192.168.1.50/24 dev eth0 # add an address
With legacy net-tools (ifconfig):
ifconfig eth0 # view (older, more limited output format)
ifconfig eth0 up
ifconfig eth0 down
ifconfig eth0 192.168.1.50 netmask 255.255.255.0
Why iproute2 replaced ifconfig
ifconfigshows only one IPv4 and, awkwardly, has limited support for displaying multiple IPv6 addresses on the same interface;ip addr showhandles an arbitrary number of addresses of either family naturally.ipunderstands network namespaces (ip netns), which containers and network isolation features depend on;ifconfigpredates that concept entirely and has no equivalent.ipexposes routing, links, addresses, rules, and tunnels all through one consistent tool (ip route,ip link,ip addr,ip rule,ip tunnel);net-toolssplits the same functionality across several separate, inconsistently designed commands (route,ifconfig,arp).- Most current distributions still ship
ifconfigfor familiarity and backward compatibility with old scripts, but treat it as read-only muscle memory rather than the tool to write new automation against.
Making interface state persistent, by distribution family
- Ubuntu (17.10 and later): Netplan. A YAML file under
/etc/netplan/, for example:applied withyamlnetwork: version: 2 ethernets: eth0: dhcp4: truenetplan apply. Netplan is a configuration front-end; it renders into eithersystemd-networkdor NetworkManager underneath, depending on which renderer the distribution defaults to. systemd-networkddirectly (common on minimal servers and container base images): a.networkfile under/etc/systemd/network/, for example/etc/systemd/network/10-eth0.network:applied withini[Match] Name=eth0 [Network] DHCP=yessystemctl restart systemd-networkd./etc/network/interfaces(classic Debian-familyifupdown, still found on older Debian installs and some embedded distributions):applied by bringing the interface down and back up, orauto eth0 iface eth0 inet dhcpsystemctl restart networkingon systems that still ship theifupdownservice.
Trade-offs and pitfalls
- The single most common mistake is testing a network change with a live
ip addr/ip linkcommand over an SSH session on that same interface, without having a persistent config ready, then losing the connection on the next reboot (or worse, on the nextNetworkManager/systemd-networkdrestart, which can reapply the old, unpersisted configuration and undo your live change immediately). - Mixing
ifconfig-based scripts with a host actually managed by NetworkManager orsystemd-networkdis fragile: the higher-level manager can reassert its own configuration over whatever a rawifconfig/ipcommand just changed, on its own schedule, making a manual fix look like it "didn't stick." - Know which configuration layer actually owns the interface on a given host before editing anything: running Netplan config and a hand-edited
/etc/network/interfacesfile at the same time on the same interface produces confusing, sometimes conflicting behavior, since only one is meant to be authoritative.
Explain the purpose and typical contents of /etc/resolv.conf on Linux. Describe how the name resolution flow can involve glibc NSS, systemd-resolved, NetworkManager, and local caches like dnsmasq. How do you change DNS temporarily and persistently?
Sample Answer
Direct answer
/etc/resolv.conf tells the system's name resolution machinery which DNS servers to query and in what order, via nameserver lines, plus optional search domains to try appending to unqualified hostnames. On a modern Linux host that file is rarely hand-maintained directly: it is usually generated and kept in sync by whichever layer is actually managing DNS underneath, most commonly systemd-resolved (the DNS-resolving component of systemd, the init system and service manager most modern Linux distributions use; it runs its own local stub resolver, typically listening on 127.0.0.53, and often makes /etc/resolv.conf a symlink pointing at a file it generates) or NetworkManager, sometimes with dnsmasq in front as a small local caching layer.
The resolution flow, layer by layer
- An application calls a resolution function from glibc (the standard C library most Linux programs are built against), which consults NSS, Name Service Switch: a configurable dispatch mechanism (
/etc/nsswitch.conf) that decides, for a given lookup type, which sources to check and in what order. Thehosts:line in that file, something likehosts: files dns, is what makes/etc/hostsget checked before DNS at all, for every application on the system, without each program needing its own logic for that. - If DNS is reached, glibc's resolver reads
/etc/resolv.conffor which server(s) to query. - On a host running
systemd-resolved,/etc/resolv.confcommonly just points at127.0.0.53,systemd-resolved's own stub listener, rather than at the real upstream DNS servers directly.systemd-resolveditself holds the actual upstream server list (learned from DHCP, static configuration, or per-interface settings) and does its own caching, so the file glibc reads and the servers actually queried over the network are two different things on such a host. - NetworkManager, when it manages DNS, can either write
/etc/resolv.confdirectly with the servers it learned from DHCP or static configuration, or hand the job off tosystemd-resolved(a mode controlled by NetworkManager's owndns=setting), depending on how the distribution configured it. dnsmasq, where present, is a small lightweight resolver and DHCP server often used as an additional local caching layer in front of upstream DNS, either standalone or as NetworkManager's local caching backend on some distributions.
Changing DNS, temporarily versus persistently
- Temporary (until the next reconnect, reboot, or manager restart):
resolvectl dns eth0 1.1.1.1on asystemd-resolvedhost (the modern command;systemd-resolveis the older, now-deprecated name for essentially the same functionality).- Editing
/etc/resolv.confdirectly works immediately for any new resolution, but only until whatever manages that file (systemd-resolved, NetworkManager) next regenerates it and overwrites your edit, which can happen at any reconnect or restart with no warning.
- Persistent:
- Netplan (Ubuntu): add a
nameservers:block under the relevant interface in the YAML config, thennetplan apply. - NetworkManager:
nmcli con mod <connection-name> ipv4.dns "1.1.1.1 8.8.8.8"followed bynmcli con up <connection-name>to apply it. systemd-networkd: add aDNS=line under[Network]in the relevant.networkfile, thensystemctl restart systemd-networkd.
- Netplan (Ubuntu): add a
Trade-offs and pitfalls
- The most common confusion is editing
/etc/resolv.confby hand on a host runningsystemd-resolvedor NetworkManager, seeing it work, and then being surprised it reverts on its own later; check whether the file is a symlink (ls -l /etc/resolv.conf) before assuming a manual edit is safe or durable. resolvectl statusshows you the actual per-interface DNS configurationsystemd-resolvedis using, which can differ from what a barecat /etc/resolv.confshows when the stub resolver is in play; when DNS behavior looks wrong, checkresolvectl status, not just the file, or you can chase a mismatch that does not actually explain the resolver's real behavior.searchdomains inresolv.confcan cause surprising, hard-to-debug behavior where an unqualified hostname silently resolves against the wrong domain (or leaks an internal hostname query to an external DNS server it should never have reached), which is a real concern worth checking for on hosts that handle sensitive internal name lookups.
Explain how to view and manipulate the kernel routing table on Linux. Include examples using ip route show, how to add a default gateway, delete a route, and explain route metrics and preference when multiple routes match a destination.
Sample Answer
Direct answer
ip route show prints the kernel's main routing table: which network each route covers, which interface (dev) traffic for it goes out on, and an optional gateway (via) for anything not directly reachable on the local network segment. Add a default gateway (the route used when no more specific route matches) with ip route add default via <gateway-ip> dev <iface>, remove a route with ip route del <destination>, and when more than one route could match the same destination, the kernel prefers the most specific match first (longest prefix), and only falls back to comparing route metrics (an administrator-assigned preference number, lower wins) when two routes have the exact same prefix length.
Reading and changing the table
ip route show on a typical host looks like:
default via 192.168.1.1 dev eth0
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.50
- The first line is the default route: anything not matched by a more specific line goes to
192.168.1.1outeth0. - The second line is a directly connected network (
scope linkmeans "no gateway needed, it is on this local segment"), automatically added by the kernel when the interface got its address (proto kernel), withsrcshowing which local address the kernel picks as the source for packets sent out on that route.
Adding a default gateway:
ip route add default via 192.168.1.1 dev eth0
Deleting a route:
ip route del 203.0.113.0/24
(you can also target a specific gateway or device if more than one route matches the same destination, with ip route del 203.0.113.0/24 via 192.168.1.1).
Adding a route with an explicit metric, to prefer one path over another when both could apply:
ip route add 10.0.0.0/8 via 192.168.1.1 dev eth0 metric 50
ip route add 10.0.0.0/8 via 192.168.2.1 dev eth1 metric 100
How the kernel actually picks among matching routes
Two separate mechanisms, applied in this order:
- Longest prefix match, always first. A route to
10.1.2.0/24is preferred over a route to10.0.0.0/8for a destination of10.1.2.5, no matter what metric either has, because/24is a more specific (longer) prefix than/8. This is not configurable; it is how IP routing fundamentally works. - Lowest metric, only among routes with an identical prefix length. If two routes both cover exactly
10.0.0.0/8(for example, one via each of two uplinks), the one with the lowermetricvalue is preferred. If both prefix length and metric are identical, the kernel can install both as equal-cost routes and load-balance across them (multipath), depending on kernel configuration.
Worked example
On a host with an added policy route in a separate table:
$ ip route add 203.0.113.0/24 dev lo table 100
$ ip route show table 100
203.0.113.0/24 dev lo scope link
This route only exists in table 100, not the main table, so ip route show (which defaults to showing the main table) will not display it at all; ip route get <address> is the fastest way to check which route the kernel would actually pick for a specific destination end to end, since it accounts for all applicable tables and rules, not just what a plain ip route show happens to print.
Trade-offs and pitfalls
- A very common mistake is deleting or adding a route and expecting it to survive a reboot:
ip routechanges made this way are runtime-only. Persistence needs the distribution's own network configuration mechanism (Netplan,systemd-networkd, NetworkManager, or/etc/network/interfaces, whichever the host uses). - Remember that
ip route showalone will not reveal routes that live in a non-main table, or a policy rule (ip rule) that sends certain traffic to a different table entirely; always check withip route show table allorip route get <destination>when a route you expect does not seem to be taking effect and the main table looks correct. - Setting an aggressively low metric on a route you intend as a backup path, without also making sure its prefix is not accidentally more specific than the primary path's, can cause it to silently win over the route you actually wanted preferred, since prefix length always overrides metric.
Unlock Full Question Bank
Get access to all 14 Linux System Administration interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.