Skip to content

Commit 3837fc1

Browse files
committed
fix(gpu): Stabilize NodeManager startup and enhance script robustness
This commit incorporates several fixes to address NodeManager startup issues, particularly on Rocky Linux, and improves the overall robustness and idempotency of the GPU initialization script. Key changes: 1. **Corrected Systemd Service Order:** - The `dataproc-gpu-config.service` is now configured to run *Before* `hadoop-yarn-nodemanager.service` and `hadoop-yarn-resourcemanager.service`. - YARN services are now restarted using `ExecStartPost` directives within the `dataproc-gpu-config.service` unit, ensuring configurations are applied prior to service startup. - The internal restart loop in the generated `apply-dataproc-gpu-config.sh` is no longer needed and has been removed. 2. **Rocky Linux NodeManager Fix:** - Added `export HADOOP_NICENESS=0` to `/etc/hadoop/conf/hadoop-env.sh` on Rocky Linux systems to prevent NodeManager startup failures due to `renice` permission issues. 3. **Improved Idempotency:** - `configure_gpu_isolation` now checks for existing lines in `container-executor.cfg` and `yarn-env.sh` before adding configurations, preventing duplicates. 4. **Hardened MIG Script Fetching:** - The script will now exit with an error if MIG is enabled but the required MIG scripts cannot be fetched. 5. **Deferred Script Logging:** - The generated `apply-dataproc-gpu-config.sh` script now defines `install_log` to ensure `execute_with_retries` can log properly. 6. **Debugging:** - Added more verbose output around the `systemctl daemon-reload` call in the generated script to help diagnose any potential issues. - Redirected stderr to stdout when executing the generated script in the main script for better log capture.
1 parent db0297d commit 3837fc1

1 file changed

Lines changed: 66 additions & 34 deletions

File tree

gpu/install_gpu_driver.sh

Lines changed: 66 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,15 +1708,38 @@ function configure_gpu_isolation() {
17081708
echo "Hadoop conf dir ${HADOOP_CONF_DIR} not found. Skipping GPU isolation config."
17091709
return
17101710
fi
1711+
17111712
# enable GPU isolation
17121713
sed -i "s/yarn\.nodemanager\.linux\-container\-executor\.group\=.*$/yarn\.nodemanager\.linux\-container\-executor\.group\=yarn/g" "${HADOOP_CONF_DIR}/container-executor.cfg"
1714+
1715+
local cfg_file="${HADOOP_CONF_DIR}/container-executor.cfg"
1716+
# Ensure [gpu] section exists and module.enabled=true
1717+
if ! grep -q "^\[gpu\]" "${cfg_file}"; then
1718+
printf '\n[gpu]\nmodule.enabled=true\n' >> "${cfg_file}"
1719+
elif ! grep -q "^module.enabled=true" "${cfg_file}"; then
1720+
# Assuming [gpu] exists, add module.enabled if missing
1721+
sed -i "/\[gpu\]/a module.enabled=true" "${cfg_file}"
1722+
fi
1723+
17131724
if [[ $IS_MIG_ENABLED -ne 0 ]]; then
1714-
# configure the container-executor.cfg to have major caps
1715-
printf '\n[gpu]\nmodule.enabled=true\ngpu.major-device-number=%s\n\n[cgroups]\nroot=/sys/fs/cgroup\nyarn-hierarchy=yarn\n' $MIG_MAJOR_CAPS >> "${HADOOP_CONF_DIR}/container-executor.cfg"
1716-
printf 'export MIG_AS_GPU_ENABLED=1\n' >> "${HADOOP_CONF_DIR}/yarn-env.sh"
1717-
printf 'export ENABLE_MIG_GPUS_FOR_CGROUPS=1\n' >> "${HADOOP_CONF_DIR}/yarn-env.sh"
1718-
else
1719-
printf '\n[gpu]\nmodule.enabled=true\n[cgroups]\nroot=/sys/fs/cgroup\nyarn-hierarchy=yarn\n' >> "${HADOOP_CONF_DIR}/container-executor.cfg"
1725+
if ! grep -q "^gpu.major-device-number=" "${cfg_file}"; then
1726+
sed -i "/\[gpu\]/a gpu.major-device-number=${MIG_MAJOR_CAPS}" "${cfg_file}"
1727+
fi
1728+
fi
1729+
1730+
# Ensure [cgroups] section and its contents
1731+
if ! grep -q "^\[cgroups\]" "${cfg_file}"; then
1732+
printf '\n[cgroups]\nroot=/sys/fs/cgroup\nyarn-hierarchy=yarn\n' >> "${cfg_file}"
1733+
fi
1734+
1735+
local yarn_env_file="${HADOOP_CONF_DIR}/yarn-env.sh"
1736+
if [[ $IS_MIG_ENABLED -ne 0 ]]; then
1737+
if ! grep -q "^export MIG_AS_GPU_ENABLED=" "${yarn_env_file}"; then
1738+
printf 'export MIG_AS_GPU_ENABLED=1\n' >> "${yarn_env_file}"
1739+
fi
1740+
if ! grep -q "^export ENABLE_MIG_GPUS_FOR_CGROUPS=" "${yarn_env_file}"; then
1741+
printf 'export ENABLE_MIG_GPUS_FOR_CGROUPS=1\n' >> "${yarn_env_file}"
1742+
fi
17201743
fi
17211744

17221745
# Configure a systemd unit to ensure that permissions are set on restart
@@ -1974,14 +1997,30 @@ function run_hadoop_spark_config() {
19741997
NUM_MIG_GPUS="$(echo ${migquery_result} | uniq | wc -l)"
19751998
if [[ "${NUM_MIG_GPUS}" -eq "1" ]] && (echo "${migquery_result}" | grep -q Enabled); then
19761999
IS_MIG_ENABLED=1
2000+
if [[ ! -d "/usr/local/yarn-mig-scripts" ]]; then
2001+
if ! fetch_mig_scripts; then
2002+
echo "ERROR: Failed to fetch MIG scripts, which are required because MIG is enabled." >&2
2003+
return 1
2004+
fi
2005+
fi
19772006
NVIDIA_SMI_PATH='/usr/local/yarn-mig-scripts/' # Set MIG path
19782007
MIG_MAJOR_CAPS=$(grep nvidia-caps /proc/devices | cut -d ' ' -f 1 || echo 0)
1979-
if [[ ! -d "/usr/local/yarn-mig-scripts" ]]; then fetch_mig_scripts || echo "WARN: Failed to fetch MIG scripts." >&2; fi
19802008
fi
19812009
fi
19822010
fi
19832011

2012+
# Prevent renice errors on systems like Rocky Linux
2013+
if is_rocky; then
2014+
if [[ -f "${HADOOP_CONF_DIR}/hadoop-env.sh" ]]; then
2015+
if ! grep -q "^export HADOOP_NICENESS=" "${HADOOP_CONF_DIR}/hadoop-env.sh"; then
2016+
echo "export HADOOP_NICENESS=0" >> "${HADOOP_CONF_DIR}/hadoop-env.sh"
2017+
echo "Added HADOOP_NICENESS=0 to hadoop-env.sh"
2018+
fi
2019+
fi
2020+
fi
2021+
19842022
# Ensure config directories exist
2023+
19852024
if [[ ! -d "${HADOOP_CONF_DIR}" || ! -d "${SPARK_CONF_DIR}" ]]; then
19862025
echo "ERROR: Config directories (${HADOOP_CONF_DIR}, ${SPARK_CONF_DIR}) not found. Cannot apply configuration."
19872026
return 1 # Use return instead of exit in a function
@@ -2025,6 +2064,9 @@ function create_deferred_config_files() {
20252064
# Deferred configuration script generated by install_gpu_driver.sh
20262065
set -xeuo pipefail
20272066
2067+
# Define install_log for execute_with_retries
2068+
readonly install_log="/tmp/apply-dataproc-gpu-config.log"
2069+
20282070
# --- Minimal necessary functions and variables ---
20292071
# Define constants
20302072
readonly HADOOP_CONF_DIR='/etc/hadoop/conf'
@@ -2157,25 +2199,13 @@ curl_retry_args="-fsSL --retry-connrefused --retry 10 --retry-max-time 30"
21572199
$(declare -f run_hadoop_spark_config)
21582200
21592201
# --- Execute the config logic ---
2160-
if run_hadoop_spark_config; then
2161-
# Configuration successful, disable the service
2162-
systemctl disable ${service_name}.service
2163-
rm -f "${config_script_path}" "${service_file}"
2164-
systemctl daemon-reload
2165-
else
2166-
echo "ERROR: Deferred configuration script (${config_script_path}) failed." >&2
2167-
# Keep the service enabled to allow for manual inspection/retry
2168-
exit 1
2169-
fi
2170-
2171-
# Restart services after applying config
2172-
for svc in resourcemanager nodemanager; do
2173-
if (systemctl is-active --quiet hadoop-yarn-\${svc}.service); then
2174-
systemctl stop hadoop-yarn-\${svc}.service || echo "WARN: Failed to stop \${svc}"
2175-
systemctl start hadoop-yarn-\${svc}.service || echo "WARN: Failed to start \${svc}"
2176-
fi
2177-
done
2178-
2202+
run_hadoop_spark_config
2203+
# Configuration successful, disable the service
2204+
systemctl disable dataproc-gpu-config.service
2205+
rm -f "${config_script_path}" "${service_file}"
2206+
echo "Reloading systemd manager configuration..."
2207+
systemctl daemon-reload
2208+
echo "systemd daemon-reload complete."
21792209
exit 0
21802210
EOF
21812211

@@ -2184,13 +2214,15 @@ EOF
21842214
cat <<EOF > "${service_file}"
21852215
[Unit]
21862216
Description=Apply Dataproc GPU configuration on first boot
2187-
# Ensure it runs after Dataproc agent and YARN services are likely up
2188-
After=google-dataproc-agent.service network-online.target hadoop-yarn-resourcemanager.service hadoop-yarn-nodemanager.service
2217+
After=network-online.target google-dataproc-agent.service
21892218
Wants=network-online.target google-dataproc-agent.service
2219+
Before=hadoop-yarn-resourcemanager.service hadoop-yarn-nodemanager.service
21902220
21912221
[Service]
21922222
Type=oneshot
21932223
ExecStart=${config_script_path} # Execute the generated config script
2224+
ExecStartPost=/bin/systemctl try-restart hadoop-yarn-resourcemanager.service
2225+
ExecStartPost=/bin/systemctl try-restart hadoop-yarn-nodemanager.service
21942226
RemainAfterExit=no # Service is done after exec
21952227
StandardOutput=journal+console
21962228
StandardError=journal+console
@@ -2301,7 +2333,7 @@ function main() {
23012333
# Running as a standard init action: execute the generated script immediately
23022334
local -r config_script_path="/usr/local/sbin/apply-dataproc-gpu-config.sh"
23032335
if [[ -x "${config_script_path}" ]]; then
2304-
bash -x "${config_script_path}"
2336+
bash -x "${config_script_path}" 2>&1
23052337
else
23062338
echo "ERROR: Generated config script ${config_script_path} not found or not executable."
23072339
exit 1
@@ -2550,8 +2582,8 @@ function set_proxy(){
25502582
storage datafusion dataproc certificatemanager networksecurity
25512583
dataflow privateca logging )
25522584

2553-
for svc in "${services[@]}"; do
2554-
no_proxy_list+=("${svc}.googleapis.com")
2585+
for gcpsvc in "${services[@]}"; do
2586+
no_proxy_list+=("${gcpsvc}.googleapis.com")
25552587
done
25562588

25572589
no_proxy="$( IFS=',' ; echo "${no_proxy_list[*]}" )"
@@ -2749,9 +2781,9 @@ function harden_sshd_config() {
27492781
# TODO: test whether sshd will reload with this change before mv
27502782
mv -f /tmp/sshd_config_new /etc/ssh/sshd_config
27512783
done
2752-
local svc=ssh
2753-
if is_rocky ; then svc="sshd" ; fi
2754-
systemctl reload "${svc}"
2784+
local sshsvc=ssh
2785+
if is_rocky ; then sshsvc="sshd" ; fi
2786+
systemctl reload "${sshsvc}"
27552787
}
27562788

27572789
function prepare_to_install(){

0 commit comments

Comments
 (0)