Go언어

[Golang] go binary 실행시 /lib64/libc.so.6: version `GLIBC_2.XX' not found 에러 해결 방법

아무일도없었다 2024. 5. 30. 22:14

[환경]

  • golang:1.xx 이미지를 통해 container에서 golang 빌드
  • golang binary를 rocky 또는 기타 linux에서 실행

 

[개요]

 

 

예전 버전의 Golang 이미지를 사용해서 빌드할 때는 문제가 없었는데, 1.19였나 1.20 버전 이상부터 빌드된 binary를 실행하면 아래의 에러가 발생하였다. (이 글을 쓰고 있는 현재는 1.22 버전을 사용 중이다.)

 

/lib64/libc.so.6: version `GLIBC_2.XX' not found

 

당시에는 원인도 모르고 급하게 해결하였으나, 최근 급하게 해결한 방법이 먹히질 않는 상황이 발생하였고 다시 한번 이런저런 삽질을 하다가 해결했는데 이를 기록해놓으려고 한다.

 


[원인]

 

golang을 빌드할 때 기본으로 들어가는 옵션값들이 상당히 많은데 그중 특정 golang 이상 버전부터 cgo 내부 glibc 의존성에서 문제가 발생하였다. (ldd 명령어로 확인가능)

 

ubuntu 또는 golang 이미지를 사용한 container 환경에서 (여기도 ubuntu로 알고 있다.) golang을 빌드한다면 상당히 높은 버전의 glibc를 사용하여 컴파일되는데, 이렇게 만들어진 binary를 rocky 또는 cent 같은 linux 환경에서 실행한다면 glibc의 버전차이로 인해 호환이 안되고 있는 문제로 보인다.

 


[해결 방안]

 

1. go build 앞에 CGO_ENABLED=0 추가

CGO_ENABLED=0 go build -o my_application

 

이 해결방법은 단순하게 golang에서 CGO를 비활성화시켜 버리는 것이다.

 

그렇다면 자연스럽게 cgo가 컴파일 과정에서 호환성 문제를 안고 사라지게 된다.

 

그리고 대부분은 이 방법을 사용하여 해결이 가능할 것으로 예상된다.

 

하지만 cgo를 사용하는 go application에서는 위의 방법을 사용할 수가 없다는 단점이 있다.

 

 

2. go build 시 아래 옵션 추가

go build -o myapplication -ldflags "-linkmode external -extldflags -static"

 

1번의 해결방안은 cgo를 사용하지 않는 프로그램에만 해당하는 방법이다.

 

cgo를 사용하는 프로그램에서는 1번의 방법을 사용할 수가 없기 때문에 2번의 방법을 사용해야 한다.

 

위의  옵션을 사용하여 컴파일을 한다면 runtime에 필요한 library를 applicaion에 모두 포함시켜서 정적으로 빌드를 할 수 있다.

 

이 방식으로 컴파일을 하면 runtime시 glibc에 대한 의존성이 사라지고 모두 binary에 포함되기 때문에 문제는 해결할 수 있지만 binary 사이즈가 꽤나 넉넉해졌을 것이다.

 

 

3. 호환성 있는 glibc 버전 설치하기

 

이 방법은 사실 시도를 안 해봤다. (필자는 2번에서 해결됨)

 

어디까지나 이론상 가능한 부분이다.

 

따라서 1번과 2번 모두 실패한 누군가가 3번의 방법을 통해 시도하지 않을까.. 추측해 본다.

반응형