解决 “Function not implemented“, 为 arm64 架构宿主机重新构建 Nacos 镜像

时间:2025-03-08 09:14:55

文章目录

  • 前言
  • 重新构建镜像的步骤
  • 附录
    • FAQ: "cannot install the best candidate for the job" & "conflicting requests"
    • Dockerfile 文件

前言

官方的 Nacos 镜像在 arm64 架构的系统上运行容器会出现 “Function not implemented” 的相关异常日志以致于容器内 Nacos 无法正常启动.
原因是官方镜像基于的 CentOS 的基础镜像版本并不支持 arm64 架构的系统.

其实 版本是有 arm64 支持的, 只是官方镜像并没有采用那个 platform (docker pull --platform=<plartform> <image-name>:<tag>)

于是下载官方 Dockerfile 尝试将基础镜像版本改为 CentOS , 但是, 由于 CentOS 已经 EOL 了, 镜像构建过程中出现各种 “Failed to download metadata for repo ‘xxx’: Cannot prepare internal mirrorlist: No URLs in mirrorlist” 的问题.
进而, 将基础镜像改为 “rockylinux:8”, 关于 rockylinux 的介绍, 可以参考:

重新构建镜像的步骤

首先, 去到 Nacos 官方 Github 地址找到你想要的版本 (这里以 v2.1.0 为例, nacos/nacos-server:v2.1.0 的 Dockerfile (/nacos-group/nacos-docker/tree/v2.1.0/build)), 简单阅读一下 Dockerfile, 注意几个关键点:

FROM centos:7.9.2009
...



ADD bin/ bin/
ADD conf/ conf/

...

首先将 “From centos:7.9.2009” 修改为 “FROM rockylinux:8”, 然后将 bin 目录和 conf 目录都下载到本地和 Dockerfile 同一目录. 结构如下:

$ tree ./
./
├── Dockerfile
├── bin
│   └── 
└── conf
    └── 

重新构建镜像:

docker build -t caplike/nacos-server:v2.1.0 .

先尝试启动一次容器:

docker run --name nacos -d caplike/nacos-server:v2.1.0

停止容器, cp 相关目录 (为了 bind mounts):

docker cp nacos:/home/nacos/conf .docker-mounts/nacos-server2.1.0
docker cp nacos:/home/nacos/logs .docker-mounts/nacos-server2.1.0
docker cp nacos:/home/nacos/data .docker-mounts/nacos-server2.1.0
docker cp nacos:/home/nacos/bin  .docker-mounts/nacos-server2.1.0

然后再启动:
值得一提的是, 由于 Nacos 额外暴露了两个 RPC 端口用于通信, 分别是按照偏移量 1000 和 1001 计算的, 所以端口映射改了的话, 相应的剩下两个 RPC 的端口也要加上对应的偏移量, 如:

docker run -d -p 20003:8848 -p 21003:9848 -p 21004:9849 \
 --name nacos-server2.1.0 \
 -v .docker-mounts/nacos-server2.1.0/conf:/home/nacos/conf \
 -v .docker-mounts/nacos-server2.1.0/data:/home/nacos/data \
 -v .docker-mounts/nacos-server2.1.0/logs:/home/nacos/logs \
 -e MODE=standalone \
 --restart=always \
 caplike/nacos-server:v2.1.0

最后, 附上我自己构建的支持 arm64 架构的 nacos-server:v2.1.0 镜像, 欢迎直接使用, HUB 地址: /repository/docker/caplike/nacos-server/general

附录

FAQ: “cannot install the best candidate for the job” & “conflicting requests”

yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel wget iputils nc vim libcurl 后追加 "–nobest --allowerasing”

Dockerfile 文件

FROM rockylinux:8
MAINTAINER like "@"

# set environment
ENV MODE="cluster" \
    PREFER_HOST_MODE="ip"\
    BASE_DIR="/home/nacos" \
    CLASSPATH=".:/home/nacos/conf:$CLASSPATH" \
    CLUSTER_CONF="/home/nacos/conf/" \
    FUNCTION_MODE="all" \
    JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk" \
    NACOS_USER="nacos" \
    JAVA="/usr/lib/jvm/java-1.8.0-openjdk/bin/java" \
    JVM_XMS="1g" \
    JVM_XMX="1g" \
    JVM_XMN="512m" \
    JVM_MS="128m" \
    JVM_MMS="320m" \
    NACOS_DEBUG="n" \
    TOMCAT_ACCESSLOG_ENABLED="false" \
    TIME_ZONE="Asia/Shanghai"

ARG NACOS_VERSION=2.1.0
ARG HOT_FIX_FLAG=""

WORKDIR $BASE_DIR

RUN set -x \
    && yum update -y \
    && yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel wget iputils nc  vim libcurl --nobest --allowerasing
RUN wget  /alibaba/nacos/releases/download/${NACOS_VERSION}${HOT_FIX_FLAG}/nacos-server-${NACOS_VERSION}. -P /home
RUN tar -xzvf /home/nacos-server-${NACOS_VERSION}. -C /home \
    && rm -rf /home/nacos-server-${NACOS_VERSION}. /home/nacos/bin/* /home/nacos/conf/*.properties /home/nacos/conf/*.example /home/nacos/conf/
RUN yum autoremove -y wget \
    && ln -snf /usr/share/zoneinfo/$TIME_ZONE /etc/localtime && echo $TIME_ZONE > /etc/timezone \
    && yum clean all




ADD bin/ bin/
ADD conf/ conf/


# set startup log dir
RUN mkdir -p logs \
	&& cd logs \
	&& touch  \
	&& ln -sf /dev/stdout  \
	&& ln -sf /dev/stderr 
RUN chmod +x bin/

EXPOSE 8848
ENTRYPOINT ["bin/"]