blog

나코스 듀얼 버전 업그레이드 실무 매뉴얼

인증 및 SSL 경험 공유에 대한 Nacos 서버 + 클라이언트 1.1.4에서 2.2.4로 업그레이드, 도움이 되길 바랍니다!...

Oct 21, 2025 · 8 min. read
シェア

컨텍스트

원래 버전의 Nacos에서 보안 취약점이 발견되어 이를 수정하기 위해 업그레이드가 필요했습니다. 문의 끝에 2.2.4 버전으로 업그레이드하기로 결정했습니다.

Nacos 서비스에는 세 가지가 있습니다:

단계

  1. 서버 측 업그레이드
  2. 클라이언트 업그레이드
  3. 서버 측에서 인증 사용

참고: 서버를 버전 2.2.4로 업그레이드하는 경우, 구성 센터는 Nacos 1.0 이상의 모든 버전의 클라이언트를 지원하고 서비스 검색은 Nacos 1.2 이상의 모든 버전의 클라이언트와 호환되므로 포렌식을 활성화할 필요가 없는 경우 클라이언트는 업그레이드하지 않고 그대로 둘 수 있습니다.

::

I. 서버 측 업그레이드

Nginx 프록시 구성 수정하기

참고: 1.1.4 버전에서는 Nacos 서버의 프로토콜이 업그레이드되어 8848 포트에서 8849 포트로 Nginx를 통해 프록시 포워딩하는 방식이 추가되었습니다. Nacos 2.2.4 버전에서는 새로운 gRPC 통신 방식에 새로운 포트가 필요하므로 nginx.conf에 새로운 포트 포워딩 구성을 추가해야 합니다.

::

# 정확한 경로는 실제 경로를 기준으로 합니다.
# 구성 파일의 위치를 모르는 경우, 히스토리를 사용하거나./ -name "nginx.conf" 2> /dev/null 찾을 명령
# 백업 구성 파일
cp /home/appuser/nginx/conf/nginx.conf /home/appuser/nginx/conf/nginx.conf_20240114_bak
# 구성 파일 수정
vim /home/appuser/nginx/conf/nginx.conf
# http{} 같은 레벨에서 다음을 추가합니다.
stream {
 upstream nacos-tcp {
 	# IP 호스트 서버에 해당합니다.
 server 192.0:9849;
 }
 server {
 listen 9848;
 proxy_pass nacos-tcp;
 }
}
# 구성 변경이 올바른지 확인
/home/appuser/nginx/sbin/nginx -t
# 구성 파일 다시 로드
/home/appuser/nginx/sbin/nginx -s reload

SQL 실행

나코스 2.x 버전은 나코스 1.x 버전과 비교하여 데이터 구조가 변경되었는데, 해당 SQL 스크립트는 다음과 같습니다:

참고: 새 버전이 시작되기 전에 SQL 스크립트를 실행해야 하며, 그렇지 않으면 오류와 함께 시작됩니다.

ALTER TABLE nacos_config.config_info ADD encrypted_data_key TEXT NOT NULL COMMENT ' ;
ALTER TABLE nacos_config.config_info_beta ADD encrypted_data_key TEXT NOT NULL COMMENT ' ;
ALTER TABLE nacos_config.his_config_info ADD encrypted_data_key TEXT NOT NULL COMMENT ' ;
CREATE TABLE nacos_config.`permissions` (
 `role` varchar(50) NOT NULL,
 `resource` varchar(255) NOT NULL,
 `action` varchar(8) NOT NULL,
 UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);

구성 파일 수정

문제를 수정하기 위해 구성 파일의 불일치를 피하려면 로컬에서 직접 해당 구성 파일을 수정한 다음 압축하여 서버에 업로드하는 것이 좋습니다!

  • application.properties
    ### 서버 포트 번호
    server.port=8849
    ### 데이터베이스 유형 사용
    spring.datasource.platform=mysql
    db.num=1
    db.url.0=jdbc:mysql://192.3:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
    db.user.0=root
    db.password.0=root
    ### 인증 활성화 또는 비활성화
    nacos.core.auth.enabled=false
    ### 이전 버전의 서비스에서 인증 방법을 활성화하고 업그레이드가 완료된 후에는 비활성화합니다.
    nacos.core.auth.enable.userAgentAuthWhite=true
    ### 다른 nacos 서버의 요청을 식별하기 위한 화이트리스트 권한 부여.
    nacos.core.auth.server.identity.key=identityRegexp
    nacos.core.auth.server.identity.value=identityRegexp
    ### 액세스 토큰을 생성하는 데 사용되는 키입니다.
    # 공식적으로 구성 항목을 Base64로 인코딩된 문자열로 설정할 것을 권장하며, 원래 키 길이는 32자 이상이어야 합니다.
    nacos.core.auth.plugin.nacos.token.secret.key=aWRlbnRpdHlpZGVudGl0eWlkZW50aXR5aWRlbnRpdHlpZGVudGl0eQ==
    
  • cluster.conf
    192.0:8848
    192.1:8848
    192.2:8848
    

서버 업그레이드

## 설치 패키지 업로드
rz
##  
unzip nacos-2.2.4.zip -d /home/appuser
## 기존 서비스 중지
NY /home/appuser/nacos-1.1.4/bin/shutdown.sh
## 새 서비스 시작
NY /home/appuser/nacos-2.2.4/bin/startup.sh
## 시작 로그 보기
tail -f /home/appuser/nacos-2.2.4/logs/start.out -n 10
## mybatis-plus 아이콘이 표시되고 오류가 보고되지 않으면 시작에 성공한 것입니다.
## nacos 페이지에 로그인하여 작동하는지 확인합니다.

II. 클라이언트 업그레이드

제가 알기로는 클라이언트를 업그레이드하는 방법에는 두 가지가 있습니다:

  • 둘째: Nacos 클라이언트 버전 업그레이드하기

프로젝트의 규모가 크고 시간 제약이 있기 때문에 첫 번째 업그레이드 방법은 더 위험하므로 두 번째 방법을 선택합니다.

종속성 추가

<dependency>
 <groupId>com.alibaba.cloud</groupId>
 <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
 <exclusions>
 <exclusion>
 <groupId>com.alibaba.nacos</groupId>
 <artifactId>nacos-client</artifactId>
 </exclusion>
 </exclusions>
</dependency>
<dependency>
 <groupId>com.alibaba.cloud</groupId>
 <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
 <exclusions>
 <exclusion>
 <groupId>com.alibaba.nacos</groupId>
 <artifactId>nacos-client</artifactId>
 </exclusion>
 </exclusions>
</dependency>
<dependency>
 <groupId>com.alibaba.nacos</groupId>
 <artifactId>nacos-client</artifactId>
 <version>2.2.4</version>
</dependency>
<dependency>
 <groupId>com.alibaba.nacos</groupId>
 <artifactId>nacos-common</artifactId>
 <version>2.2.4</version>
</dependency>

구성 추가

bootstrap.yml

spring:
 cloud:
 nacos:
 discovery:
 username: nacos
 password: nacos
 config:
 username: nacos
 password: nacos
 contextPath: /nacos

Nacos 클라이언트 소스 코드 다시 작성하기

재작성 방법: 프로젝트의 java 디렉터리에서 클래스를 재작성해야 하는 새 패키지 경로를 만든 다음 해당 경로에 소스 코드를 복사하여 수정합니다(예: NacosDiscoveryProperties 클래스가 com.alibaba.cloud.nacos의 패키지 경로에 있는 경우 java 디렉터리 아래에 새 패키지를 만든 다음 소스 코드를 복사합니다).

다음 코드는 주요 수정 코드이며 전체 파일이 아니라는 점에 유의하세요!

  • NacosDiscoveryProperties.java

    public class NacosDiscoveryProperties {
     private String username;
     private String password;
     public String getUsername() {
     return username;
     }
     public void setUsername(String username) {
     this.username = username;
     }
     public String getPassword() {
     return password;
     }
     public void setPassword(String password) {
     this.password = password;
     }
     public Properties getNacosProperties() {
     properties.put(USERNAME, Objects.toString(username, ""));
     properties.put(PASSWORD, Objects.toString(password, ""));
     }
    }
    
  • NacosConfigProperties.java

    public class NacosConfigProperties {
     private String username;
     private String password;
     public String getUsername() {
     return username;
     }
     public void setUsername(String username) {
     this.username = username;
     }
     public String getPassword() {
     return password;
     }
     public void setPassword(String password) {
     this.password = password;
     }
     public Properties getConfigServiceProperties() {
     properties.put(USERNAME, Objects.toString(username, ""));
     properties.put(PASSWORD, Objects.toString(password, ""));
     }
    }
    
  • ServerHttpAgent.java

    public class ServerHttpAgent implements HttpAgent {
     public static final String HTTP = "http://";
     public static final String HTTPS = "https://";
     private static final boolean isSSL = ObjectUtils.isEmpty(System.getProperty("nacos.ssl.enable"))
     || Boolean.parseBoolean(System.getProperty("nacos.ssl.enable"));
     static {
     if (isSSL) {
     try {
     TrustManager[] managers = new TrustManager[1];
     managers[0] = new TrustAllManager();
     SSLContext sc = SSLContext.getInstance("SSL");
     sc.init(null, managers, null);
     HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
     HttpsURLConnection.setDefaultHostnameVerifier((urlHostName, session) -> true);
     } catch (Exception e) {
     LOGGER.error("trust all https certificates fail", e);
     }
     }
     }
     public static class TrustAllManager implements X509TrustManager {
     @Override
     public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
     }
     @Override
     public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
     }
     @Override
     public X509Certificate[] getAcceptedIssuers() {
     return null;
     }
     }
     private String getUrl(String serverAddr, String relativePath, boolean isSSL) {
     String contextPath = serverListMgr.getContentPath().startsWith("/") ?
     serverListMgr.getContentPath() : "/" + serverListMgr.getContentPath();
     String url = StringUtils.removeEnd(serverAddr, "/") + "/" + StringUtils.removeStart(contextPath, "/") + relativePath;
     if (isSSL && url.startsWith(HTTP)) {
     return HTTPS + StringUtils.removeStart(url, HTTP);
     } else {
     return url;
     }
     }
    }
    
  • NacosRestTemplate.java

    public class NacosRestTemplate extends AbstractNacosRestTemplate {
     private static final Logger LOGGER = LogUtils.logger(NacosRestTemplate.class);
     private static final boolean isSSL = ObjectUtils.isEmpty(System.getProperty("nacos.ssl.enable"))
     || Boolean.parseBoolean(System.getProperty("nacos.ssl.enable"));
     static {
     if (isSSL) {
     try {
     TrustManager[] managers = new TrustManager[1];
     managers[0] = new ServerHttpAgent.TrustAllManager();
     SSLContext sc = SSLContext.getInstance("SSL");
     sc.init(null, managers, null);
     HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
     HttpsURLConnection.setDefaultHostnameVerifier((urlHostName, session) -> true);
     } catch (Exception e) {
     LOGGER.error("trust all https certificates fail", e);
     }
     }
     }
     public static class TrustAllManager implements X509TrustManager {
     @Override
     public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
     }
     @Override
     public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
     }
     @Override
     public X509Certificate[] getAcceptedIssuers() {
     return null;
     }
     }
    }
    

셋째, 서버 측에서 인증을 열어야 합니다.

# 구성 파일 편집
vim /home/appuser/nacos-2.2.4/conf/application.conf
# 다음 줄을 찾아 false를 true로 변경하면 재부팅할 필요가 없습니다.
nacos.core.auth.enabled=false

전원을 켠 후 서비스 로그와 Nacos 로그를 관찰하여 정상인지 확인하세요.

nacos 로그는 /home/appuser/nacos-2.2.4/logs/nacos.log 디렉토리에 있습니다.

Read next

헤더 콘텐츠의 잘못된 문자셋인 http 400을 기억하세요.

프로젝트 릴리스 후 온라인 시간 제한 작업이 400이어야 한다는 것을 발견했습니다! 그 당시에는 혼란스러웠고 변경 사항이 http 클라이언트와 관련이 없다는 것을 막연하게 기억하고 첫 번째 반응은 디버깅하는 것이었지만 처음에 문제 해결 방향을 잘못 생각한 것이 당황스러웠습니다.

Oct 20, 2025 · 2 min read