From df2ee71b0f54cb111e9cb12b246fd7681c7586da Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Thu, 30 Apr 2026 13:57:25 +0900 Subject: [PATCH] HBASE-30101 Move login() before RpcServer construction (#8122) The RpcServer constructor calls userProvider.getCurrentUserName() (HBASE-28321) which triggers UserGroupInformation.getCurrentUser(). If the server has not logged in yet, UGI bootstraps from the ticket cache and spawns a TGT renewer for whichever principal happens to be there, regardless of the principal the server is configured to use. Resolve the hostname up front via DNS.getHostname(...) and run the ZK client and server logins before createRpcServices(), so that UGI is already bound to the keytab principal by the time the RpcServer constructor runs. HRegionServer.getUseThisHostnameInstead() previously fell back to rpcServices.getSocketAddress().getHostName() when the reverse-DNS disable flag was set; that branch now uses DNS.getHostname directly so it no longer depends on rpcServices being constructed. Signed-off-by: Duo Zhang --- .../apache/hadoop/hbase/master/HMaster.java | 6 +++ .../hbase/regionserver/HRegionServer.java | 47 ++++++++++++------- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java index 96d29b20ac71..25ca935271f0 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java @@ -234,6 +234,7 @@ import org.apache.hadoop.hbase.util.Addressing; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.CoprocessorConfigurationUtil; +import org.apache.hadoop.hbase.util.DNS; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.apache.hadoop.hbase.util.FSTableDescriptors; import org.apache.hadoop.hbase.util.HBaseFsck; @@ -571,6 +572,11 @@ protected String getUseThisHostnameInstead(Configuration conf) { return conf.get(MASTER_HOSTNAME_KEY); } + @Override + protected DNS.ServerType getDNSServerType() { + return DNS.ServerType.MASTER; + } + private void registerConfigurationObservers() { configurationManager.registerObserver(this.rpcServices); configurationManager.registerObserver(this); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java index 4add5cadf766..aec436ebeda3 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java @@ -191,6 +191,7 @@ import org.apache.hadoop.hbase.util.CommonFSUtils; import org.apache.hadoop.hbase.util.CompressionTest; import org.apache.hadoop.hbase.util.CoprocessorConfigurationUtil; +import org.apache.hadoop.hbase.util.DNS; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.apache.hadoop.hbase.util.FSTableDescriptors; import org.apache.hadoop.hbase.util.FSUtils; @@ -667,28 +668,23 @@ public HRegionServer(final Configuration conf) throws IOException { this.stopped = false; this.namedQueueRecorder = NamedQueueRecorder.getInstance(this.conf); - rpcServices = createRpcServices(); useThisHostnameInstead = getUseThisHostnameInstead(conf); - - // if use-ip is enabled, we will use ip to expose Master/RS service for client, - // see HBASE-27304 for details. - boolean useIp = conf.getBoolean(HConstants.HBASE_SERVER_USEIP_ENABLED_KEY, - HConstants.HBASE_SERVER_USEIP_ENABLED_DEFAULT); - String isaHostName = - useIp ? rpcServices.isa.getAddress().getHostAddress() : rpcServices.isa.getHostName(); - String hostName = - StringUtils.isBlank(useThisHostnameInstead) ? isaHostName : useThisHostnameInstead; - serverName = ServerName.valueOf(hostName, this.rpcServices.isa.getPort(), this.startcode); - - rpcControllerFactory = RpcControllerFactory.instantiate(this.conf); - rpcRetryingCallerFactory = RpcRetryingCallerFactory.instantiate(this.conf, - clusterConnection == null ? null : clusterConnection.getConnectionMetrics()); - + // Resolve the hostname up-front and log in before creating the RpcServer. The RpcServer + // constructor reads UserGroupInformation.getCurrentUser() (HBASE-28321); if the server + // has not logged in yet, UGI bootstraps from the ticket cache and spawns a TGT renewer + // for whichever principal happens to be there. + String hostName = resolveHostName(conf, useThisHostnameInstead); // login the zookeeper client principal (if using security) ZKAuthentication.loginClient(this.conf, HConstants.ZK_CLIENT_KEYTAB_FILE, HConstants.ZK_CLIENT_KERBEROS_PRINCIPAL, hostName); // login the server principal (if using secure Hadoop) login(userProvider, hostName); + rpcServices = createRpcServices(); + serverName = ServerName.valueOf(hostName, this.rpcServices.isa.getPort(), this.startcode); + + rpcControllerFactory = RpcControllerFactory.instantiate(this.conf); + rpcRetryingCallerFactory = RpcRetryingCallerFactory.instantiate(this.conf, + clusterConnection == null ? null : clusterConnection.getConnectionMetrics()); // init superusers and add the server principal (if using security) // or process owner as default super user. Superusers.initialize(conf); @@ -772,7 +768,7 @@ protected String getUseThisHostnameInstead(Configuration conf) throws IOExceptio + UNSAFE_RS_HOSTNAME_KEY + " is used"; throw new IOException(msg); } else { - return rpcServices.isa.getHostName(); + return DNS.getHostname(conf, DNS.ServerType.REGIONSERVER); } } else { return hostname; @@ -827,6 +823,23 @@ private void initializeFileSystem() throws IOException { !canUpdateTableDescriptor(), cacheTableDescriptor()); } + protected DNS.ServerType getDNSServerType() { + return DNS.ServerType.REGIONSERVER; + } + + private String resolveHostName(Configuration conf, String useThisHostnameInstead) + throws IOException { + if (!StringUtils.isBlank(useThisHostnameInstead)) { + return useThisHostnameInstead; + } + // if use-ip is enabled, we will use ip to expose Master/RS service for client, + // see HBASE-27304 for details. + boolean useIp = conf.getBoolean(HConstants.HBASE_SERVER_USEIP_ENABLED_KEY, + HConstants.HBASE_SERVER_USEIP_ENABLED_DEFAULT); + InetAddress addr = InetAddress.getByName(DNS.getHostname(conf, getDNSServerType())); + return useIp ? addr.getHostAddress() : addr.getHostName(); + } + protected void login(UserProvider user, String host) throws IOException { user.login(SecurityConstants.REGIONSERVER_KRB_KEYTAB_FILE, SecurityConstants.REGIONSERVER_KRB_PRINCIPAL, host);