树莓派4B“重启计划”Ⅳ——ARM64架构编译部署nacos-2.0.3

给树莓派安装了docker之后,可以使用docker编译和部署nacos服务。Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台,整体基于java语言开发,原生支持spring应用,通常用作微服务的注册中心。

本章的目标是要在树莓派4B上运行nacos服务,但是可惜的是官方发布的预编译版安装包中从nacos1.1.3版之后不再支持arm64架构,所以如果你想在树莓派上运行nacos最新的2.0.3版服务的话,需要自己动手从源码编译。

以下是我踩坑了两周之后的避坑记录:

一、准备环境

为了避免污染实际的树莓派系统环境,整体的nacos编译操作需要在容器中进行,首先需要启动一个基于ubuntu系统的基础镜像容器。

docker run --name temp -d ubuntu:focal /bin/sh -c "while true;do sleep 1; done"  # 启动容器
docker exec -it temp bash  # 进入容器

# 以下命令皆在容器中执行,安装系统依赖
apt-get update && apt-get install -y gcc g++ make libc6-dev wget vim unzip
复制代码

按照官方文档下载符合最低版本要求的java8maven3.2.5,将java8解压到/root/tools/jdk8,将maven解压到/root/tools/maven,配置环境变量。

export JAVA_HOME=/root/tools/jdk8
export MAVEN_HOME=/root/tools/maven
export PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH
复制代码

配置完成后执行mvn --version命令查看输出。

image.png

注意避免使用最高版本的java17和maven3.8.4,否则编译nacos时将出现各种奇葩报错。

二、安装protobuf

ProtoBuf 是结构数据序列化方法,可简单类比于 XML,安装protobuf主要是为了其中包含的各种头文件,编译nacos时会存在依赖。

wget https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protobuf-all-3.17.3.tar.gz -O protobuf-all-3.17.3.tar.gz
tar xf protobuf-all-3.17.3.tar.gz
cd protobuf-3.17.3
./configure --disable-shared
make -j4
make install
复制代码

完成后ProtoBuf的库文件被安装到/usr/local/lib路径下。

三、安装grpc-java

编译nacos-consistency组件依赖protoc-gen-grpc-java工具,指定版本必须是1.24,但是官网上1.24版grpc-java的预编译包只能运行在X86架构的CPU上,所以此处必须手动编译,编译方法如下:

wget https://github.com/grpc/grpc-java/archive/refs/tags/v1.24.2.zip -O grpc-java-v1.24.2.zip
unzip grpc-java-v1.24.2.zip
cd grpc-java-v1.24.2/compiler
../gradlew java_pluginExecutable
复制代码

编译完成后生成的可执行文件位于./compiler/build/exe/java_plugin/protoc-gen-grpc-java,需要将文件安装到本地maven库,编译nacos-consistency组件时将会使用此包,安装命令如下:

cp /root/downloads/grpc-java-1.24.2/compiler/build/exe/java_plugin/protoc-gen-grpc-java /root/downloads/protoc-gen-grpc-java-1.24.0-linux-aarch_64.exe  # 复制编译好的可执行文件
mvn install:install-file -DgroupId=io.grpc -DartifactId=protoc-gen-grpc-java -Dversion=1.24.0 -Dclassifier=linux-aarch_64 -Dpackaging=exe -Dfile=/root/downloads/protoc-gen-grpc-java-1.24.0-linux-aarch_64.exe  # 安装文件到本地maven库
复制代码

执行完成后将在本地maven库路径下生成/root/.m2/repository/io/grpc/protoc-gen-grpc-java/1.24.0/protoc-gen-grpc-java-1.24.0-linux-aarch_64.exe文件。此文件虽然以exe结尾但确实可以运行在arm64架构的linux系统上。

参考博文:

  www.cnblogs.com/ghj1976/p/5…

  blog.csdn.net/u013985522/…

查询maven包:

  search.maven.org/artifact/io…

四、编译nacos2.0.3

终于到了最关键的一步,正式开始编译nacos2.0.3,使用wget从源码的下载地址下载源码包,然后解压压缩包。

wget https://github.com/alibaba/nacos/archive/refs/tags/2.0.3.tar.gz -O nacos-2.0.3.tar.gz
tar xf nacos-2.0.3.tar.gz
cd nacos-2.0.3/
复制代码

修改./console/pom.xml文件,在第114行附近<artifactId>spring-boot-maven-plugin</artifactId>下添加版本信息<version>2.3.12.RELEASE</version>,否则编译nacos-console组件时将报错找不到spring-boot-maven-plugin插件。

image.png

配置maven国内源,否则可能有些依赖会导致下载超时,maven的配置文件在maven工具的安装路径下的conf目录中,即/root/tools/maven/conf/settings.xml文件,在该文件中的<mirrors>节点中添加阿里的公共maven库:

<mirror>
    <id>aliyunmaven</id>
    <mirrorOf>*</mirrorOf>
    <name>aliyunmaven</name>
    <url>https://maven.aliyun.com/repository/public</url>
</mirror>
复制代码

image.png

保存文件,然后在nacos源码目录执行编译命令:

mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
复制代码

等待一会儿(时间不长,但以上从头到此这波操作竟然卡了我两周!!!!!)截图留念:

编译完成

编译完成后nacos的可执行文件位于./distribution/target/,注意保存nacos-server-2.0.3.tar.gz文件。

image.png

找不到插件的解决方案:

  stackoverflow  官网wiki

传包超时解决方案:

  apache官方配置说明  阿里云公共库说明

五、测试nacos

将编译好的nacos部署包解压到/root/tools,启动服务

tar xf ./distribution/target/nacos-server-2.0.3.tar.gz -C /root/tools/
cd /root/tools/nacos/bin/
bash startup.sh -m standalone
复制代码

根据提示查看/root/tools/nacos/logs/start.out日志输出,直到服务正常启动无报错,日志内容大概如下:

/root/tools/jdk8/bin/java -Djava.ext.dirs=/root/tools/jdk8/jre/lib/ext:/root/tools/jdk8/lib/ext  -Xms512m -Xmx512m -Xmn256m -Dnacos.standalone=true -Dnacos.member.list= -Xloggc:/root/tools/nacos/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -Dloader.path=/root/tools/nacos/plugins/health,/root/tools/nacos/plugins/cmdb -Dnacos.home=/root/tools/nacos -jar /root/tools/nacos/target/nacos-server.jar  --spring.config.additional-location=file:/root/tools/nacos/conf/ --logging.config=/root/tools/nacos/conf/nacos-logback.xml --server.max-http-header-size=524288

         ,--.
       ,--.'|
   ,--,:  : |                                           Nacos 2.0.3
,`--.'`|  ' :                       ,---.               Running in stand alone mode, All function modules
|   :  :  | |                      '   ,'\   .--.--.    Port: 8848
:   |   \ | :  ,--.--.     ,---.  /   /   | /  /    '   Pid: 467815
|   : '  '; | /       \   /     \.   ; ,. :|  :  /`./   Console: http://172.17.0.5:8848/nacos/index.html
'   ' ;.    ;.--.  .-. | /    / ''   | |: :|  :  ;_
|   | | \   | \__\/: . ..    ' / '   | .; : \  \    `.      https://nacos.io
'   : |  ; .' ," .--.; |'   ; :__|   :    |  `----.   \
|   | '`--'  /  /  ,.  |'   | '.'|\   \  /  /  /`--'  /
'   : |     ;  :   .'   \   :    : `----'  '--'.     /
;   |.'     |  ,     .-./\   \  /            `--'---'
'---'        `--`---'     `----'

2021-12-08 15:32:42,094 INFO Bean 'org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler@1ea9f009' of type [org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2021-12-08 15:32:42,127 INFO Bean 'methodSecurityMetadataSource' of type [org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2021-12-08 15:32:44,036 INFO Tomcat initialized with port(s): 8848 (http)
2021-12-08 15:32:48,664 INFO Root WebApplicationContext: initialization completed in 37406 ms
2021-12-08 15:33:13,997 INFO Initializing ExecutorService 'applicationTaskExecutor'
2021-12-08 15:33:14,832 INFO Adding welcome page: class path resource [static/index.html]
2021-12-08 15:33:17,352 INFO Creating filter chain: Ant [pattern='/**'], []
2021-12-08 15:33:17,570 INFO Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@6a937336, org.springframework.security.web.context.SecurityContextPersistenceFilter@35f639fa, org.springframework.security.web.header.HeaderWriterFilter@6b69761b, org.springframework.security.web.csrf.CsrfFilter@5c448433, org.springframework.security.web.authentication.logout.LogoutFilter@5d425813, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@6c6333cd, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@8deb645, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@278667fd, org.springframework.security.web.session.SessionManagementFilter@26221bad, org.springframework.security.web.access.ExceptionTranslationFilter@1b5c3e5f]
2021-12-08 15:33:18,283 INFO Initializing ExecutorService 'taskScheduler'
2021-12-08 15:33:18,408 INFO Exposing 16 endpoint(s) beneath base path '/actuator'
2021-12-08 15:33:19,047 INFO Tomcat started on port(s): 8848 (http) with context path '/nacos'
2021-12-08 15:33:19,070 INFO Nacos started successfully in stand alone mode. use embedded storage
复制代码

六、构建镜像

以上的全部操作只是为了得到arm64架构可用的nacos-server-2.0.3.tar.gz文件作为nacos服务的部署包,使用此编译好的部署包构建docker镜像将不再需要重新从源码编译nacos,所以也就不需要再重新安装和配置mavenprotobufgrpc-java等依赖,只需要具备基本的java环境即可。

所以,构建nacos:2.0.3镜像需要的资源大致如下。

# tree nacos-docker-v2.0.3
nacos-docker-v2.0.3
├── Dockerfile                          # 构建镜像所需的指令和说明
├── files
│   ├── entrypoint_raw.sh               # 容器启动之前做一些初始化配置
│   ├── installenv_raw.sh               # 安装和配置各项依赖
│   ├── jdk-8u271-linux-aarch64.tar.gz  # java环境
│   ├── nacos-server-2.0.3.tar.gz       # nacos服务
│   └── start_services_raw.sh           # 运行容器时启动nacos服务
├── nacos-mysql.sql                     # nacos数据库的表结构
└── README.md                           # 帮助文档

1 directory, 8 files
复制代码

其中,Dockerfile文件是用来构建nacos:2.0.3镜像的文本文件,包含了一条条构建镜像所需的指令和说明,此处主要是传输文件和执行脚本;installenv_raw.sh文件用于安装系统依赖、配置java和nacos;entrypoint_raw.sh用于在启动容器时根据参数渲染配置文件,如数据库的IP、端口、帐号、密码等;start_services_raw.sh用于在启动容器后自动拉起nacos服务。

以下是各主要文件的代码。

1. 文件Dockerfile
FROM ubuntu:focal
MAINTAINER [email protected]

ADD files/ /tmp/

# 清除^M
RUN cat /tmp/start_services_raw.sh | tr -d "\r" >> /tmp/start_services.sh
RUN chmod +x /tmp/start_services.sh
RUN cat /tmp/entrypoint_raw.sh | tr -d "\r" >> /tmp/entrypoint.sh
RUN chmod +x /tmp/entrypoint.sh

# 清除^M并执行安装脚本
RUN cat /tmp/installenv_raw.sh | tr -d "\r" >> /tmp/installenv.sh
RUN chmod +x /tmp/installenv.sh && /bin/bash /tmp/installenv.sh

EXPOSE 22/tcp
EXPOSE 8848/tcp

# 修改配置,启动服务,CMD 在docker run 时运行
CMD ["/tmp/start_services.sh"]
ENTRYPOINT ["/tmp/entrypoint.sh"]
复制代码
2. 安装脚本files/installenv_raw.sh
#!/bin/sh

echo "==========================================="
echo -e "`date '+%Y-%m-%d %H:%M:%S'`: 安装软件包\n"
apt-get update && apt-get upgrade -y && apt-get -y install locales tzdata vim openssh-sftp-server
apt-get clean

echo "==========================================="
echo -e "`date '+%Y-%m-%d %H:%M:%S'`: 配置时区和字符集\n"
# 此处使用非交互模式配置时区和字符集
export DEBIAN_FRONTEND=noninteractive  # 通过环境变量设置使用非交互模式
ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && dpkg-reconfigure -f noninteractive tzdata
localedef -c -i zh_CN -f UTF-8 zh_CN.UTF-8

echo "==========================================="
echo -e "`date '+%Y-%m-%d %H:%M:%S'`: 解压工程文件\n"
mkdir -p /root/tools/
tar xf /tmp/nacos-server-2.0.3.tar.gz -C /root/tools/
tar xf /tmp/jdk-8u271-linux-aarch64.tar.gz -C /root/tools/
mv /root/tools/jdk1.8.0_271 /root/tools/jdk8

rm -rf /tmp/nacos-server-2.0.3.tar.gz /tmp/jdk-8u271-linux-aarch64.tar.gz

echo "==========================================="
echo -e "`date '+%Y-%m-%d %H:%M:%S'`: 安装结束\n"
复制代码
3. 配置文件和环境变量相关的脚本files/entrypoint_raw.sh
#!/bin/sh

# 此DB_CONF变量供sed命令使用,注意转义/:&等字符
DB_CONF="characterEncoding=utf8\&connectTimeout=1000\&socketTimeout=3000\&autoReconnect=true\&useUnicode=true\&useSSL=false\&serverTimezone=UTC"

# 容器接受DB_HOST、DB_PORT、DB_NAME、DB_USER、DB_PASSWORD作为容器启动的参数,
# 如果参数全都存在,将根据给定的参数值更新nacos服务的配置文件。
if [ "$DB_HOST" -a "$DB_PORT" -a "$DB_NAME" -a "$DB_USER" -a "$DB_PASSWORD" ];then
    # 此DB_STR变量供sed命令使用,注意转义/:&等字符
    DB_STR="jdbc\:mysql\:\/\/${DB_HOST}\:${DB_PORT}\/${DB_NAME}?${DB_CONF}"
    sed -i 's/^# \(spring.datasource.platform=\)/\1/' /root/tools/nacos/conf/application.properties
    sed -i "s/spring.datasource.platform=.*/spring.datasource.platform=mysql/g" /root/tools/nacos/conf/application.properties
    sed -i 's/^# \(db.num=\)/\1/' /root/tools/nacos/conf/application.properties
    sed -i "s/db.num=.*/db.num=1/g" /root/tools/nacos/conf/application.properties
    sed -i 's/^# \(db.url.0=\)/\1/' /root/tools/nacos/conf/application.properties
    sed -i "s/db.url.0=.*/db.url.0=${DB_STR}/g" /root/tools/nacos/conf/application.properties
    sed -i 's/^# \(db.user.0=\)/\1/' /root/tools/nacos/conf/application.properties
    sed -i "s/db.user.0=.*/db.user.0=${DB_USER}/g" /root/tools/nacos/conf/application.properties
    sed -i 's/^# \(db.password.0=\)/\1/' /root/tools/nacos/conf/application.properties
    sed -i "s/db.password.0=.*/db.password.0=${DB_PASSWORD}/g" /root/tools/nacos/conf/application.properties
fi

exec "$@"
复制代码
4. 服务启动的脚本files/start_services_raw.sh
#!/bin/sh

export JAVA_HOME=/root/tools/jdk8
export PATH=$JAVA_HOME/bin:$PATH
cd /root/tools/nacos/bin/
bash shutdown.sh  # 停服务的命令
bash startup.sh -m standalone  # 以standalone模式启动服务

tail -500f /root/tools/nacos/logs/start.out  # 阻塞命令,作为docker log命令的输出
复制代码
5. nacos-mysql.sql文件

  此文件是nacos官方提供的sql表结构,位于编译包中的conf目录下,现已提取出来备用。

以上资源文件都准备好之后可以在Dockerfile所在目录下执行构建命令,对于此类耗时较长的命令建议使用nohup将命令挂起到后台并将命令的输出重定向到日志文件:nohup docker build -t nacos:2.0.3 . &> build.log &,命令执行过程中可以使用tail -f build.log查看进度。

image.png

构建完成后建议使用docker save命令保存镜像,结合xz压缩镜像包便于传输和保存。

docker save -o nacos_arm64_v2.0.3.tar nacos:2.0.3  # 打包保存镜像
xz nacos_arm64_v2.0.3.tar  # 压缩镜像文件
复制代码

image.png

压缩后的镜像文件大小约416MB,可以复制到其他arm64架构的linux系统上,只需执行导入docker镜像的命令docker load -i nacos_arm64_v2.0.3.tar.xz即可正常使用此镜像。

七、启动nacos服务

启动nacos需要先准备好数据库服务,创建数据库和帐号,此前已经使用docker部署过mariadb,ip地址192.168.3.14,端口3306,这时只需要创建帐号和新数据库。

CREATE DATABASE `nacosdata` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';  /*创建数据库nacosdata,默认编码utf8mb4*/
CREATE USER 'nacos'@'192.168.%' IDENTIFIED BY '***********';  /*创建用户*/
GRANT USAGE ON *.* TO 'nacos'@'192.168.%';
GRANT ALL PRIVILEGES ON `nacosdata`.* TO 'nacos'@'192.168.%' WITH GRANT OPTION;  /*给用户nacos分配nacosdata库的全部权限*/
--grant all privileges on nacosdata.* to nacos@'%' identified by '*********';--  /*这条语句似乎顶上面三条*/
FLUSH PRIVILEGES;  /*刷新权限设置*/
复制代码

使用新创建的nacos账户登录数据库,确认帐号可用后导入nacos官方提供的sql文件nacos-mysql.sql,其中包含nacos所需的表结构。

image.png

数据库和数据表准备完成后即可创建并启动nacos容器,将以上数据库信息作为容器参数传入。

docker run -d --name work_nacos --restart=always \
    -e "DB_HOST=192.168.3.14" -e "DB_PORT=3306" \
    -e "DB_NAME=nacosdata" -e "DB_USER=nacos" \
    -e "DB_PASSWORD=********" -p 2288:8848 nacos:2.0.3
复制代码

此命令执行需要花费一段时间,可以使用docker logs work_nacos命令查看日志。

image.png

确认服务正常启动后可以使用浏览器访问http://192.168.3.14:2288/nacos查看nacos页面,默认帐号和密码都是nacos,登录后可以看到服务版本为2.0.3。

image.png

附:伸手党福利

本文内容所需的全部资源都已上传到百度网盘,提取码:8frx,敬请自取。

捕获.PNG

Guess you like

Origin juejin.im/post/7039730488751161374