This page describes how to configure an external NTP replay for Google Distributed Cloud (GDC) air-gapped appliance.
These steps are only required if you want to synchronize the appliance with external time after being disconnected.
Before you begin
To sync the appliance with external NTP, complete the following steps:
Before you begin, make sure that there is only one NTP relay. To verify, run the following command on the bootstrapper machine:
kubectl get ntprelay -A
The output looks like the following example:
NAMESPACE NAME AGE gpc-system bi-ntp-relay 4d21h
Configure the NTP relay
Connect the bootstrapper to the appliance device and determine the IP address of the connected interface:
ifconfig mgmt: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 198.18.0.30 netmask 255.255.255.224 broadcast 198.18.0.31 inet6 fe80::20c:29ff:fea8:fc35 prefixlen 64 scopeid 0x20<link> ...
Edit the
ntprelay
CR by including the bootstrapper mgmt IP as the upstream IP.kubectl edit ntprelay bi-ntp-relay -n gpc-system ntprelay.system.private.gdc.goog/bi-ntp-relay edited kubectl get ntprelay bi-ntp-relay -n gpc-system -oyaml
The output looks like the following example. In this example the IP address for
upstreamServers
is changed:apiVersion: system.private.gdc.goog/v1alpha1 kind: NTPRelay metadata: creationTimestamp: "2025-05-16T08:44:21Z" generation: 2 name: bi-ntp-relay namespace: gpc-system resourceVersion: "10871409" uid: 6cde8e65-791c-4bc6-9a8b-d5c9bf103f8b spec: upstreamServers: - 192.0.2.030
Verify the NTP synchronization:
kubectl get pods -l app.kubernetes.io/name=ntp -n ntp-system -o name | xargs -I {} kubectl exec {} -n ntp-system -- chronyc sources -v; echo
The output looks like the following:
.-- Source mode '^' = server, '=' = peer, '#' = local clock. / .- Source state '*' = current best, '+' = combined, '-' = not combined, | / 'x' = may be in error, '~' = too variable, '?' = unusable. || .- xxxx [ yyyy ] +/- zzzz || Reachability register (octal) -. | xxxx = adjusted offset, || Log2(Polling interval) --. | | yyyy = measured offset, || \ | | zzzz = estimated error. || | | \ MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* 192.0.2.026 1 6 17 43 +286ns[ +36us] +/- 1160us =? 192.0.2.029 0 6 0 - +0ns[ +0ns] +/- 0ns =? 192.0.2.051 0 6 0 - +0ns[ +0ns] +/- 0ns =? 192.0.2.059 0 6 0 - +0ns[ +0ns] +/- 0ns .-- Source mode '^' = server, '=' = peer, '#' = local clock. / .- Source state '*' = current best, '+' = combined, '-' = not combined, | / 'x' = may be in error, '~' = too variable, '?' = unusable. || .- xxxx [ yyyy ] +/- zzzz || Reachability register (octal) -. | xxxx = adjusted offset, || Log2(Polling interval) --. | | yyyy = measured offset, || \ | | zzzz = estimated error. || | | \ MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* 192.0.2.026 1 6 37 2 +2ns[ +90us] +/- 84us =? 192.0.2.029 2 6 1 8 +368us[ +449us] +/- 3761us =? 192.0.2.051 0 6 1 - +0ns[ +0ns] +/- 0ns =? 192.0.2.059 2 6 1 8 +663us[ +744us] +/- 11ms .-- Source mode '^' = server, '=' = peer, '#' = local clock. / .- Source state '*' = current best, '+' = combined, '-' = not combined, | / 'x' = may be in error, '~' = too variable, '?' = unusable. || .- xxxx [ yyyy ] +/- zzzz || Reachability register (octal) -. | xxxx = adjusted offset, || Log2(Polling interval) --. | | yyyy = measured offset, || \ | | zzzz = estimated error. || | | \ MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* 192.0.2.026 1 6 37 29 -6ns[ -759us] +/- 92us =? 192.0.2.029 2 6 1 36 +334us[ -346us] +/- 3775us =? 192.0.2.051 2 6 1 35 -125us[ -813us] +/- 5839us =? 192.0.2.059 0 6 1 - +0ns[ +0ns] +/- 0ns
Verify if the
chronyc
in the NTP pods refers to the newly added IP.kubectl exec -it -n ntp-system ntp2-84ddf7cd99-96vqn -- sh
The output looks like the following example:
Defaulted container "ntp-image" out of: ntp-image, ntp-node-exporter # chronyc tracking Reference ID : C612001E (198.18.0.30) Stratum : 2 Ref time (UTC) : Wed May 21 07:28:38 2025 System time : 0.000000005 seconds slow of NTP time Last offset : +0.000025645 seconds RMS offset : 0.000082131 seconds Frequency : 15.671 ppm slow Residual freq : +0.024 ppm Skew : 0.628 ppm Root delay : 0.000164273 seconds Root dispersion : 0.000180630 seconds Update interval : 64.8 seconds Leap status : Normal # exit