Jason Pan

NUC10 搭建本地开发环境

黄杰 / 2020-07-19


本文从硬件购置、系统安装、网络设计与配置、系统环境设置、博客搭建、开发环境搭建、NFSD搭建等方面,说明支持多个博客服务、远程开发编译的Linux主机搭建方法。

引子

相比于云主机,自己买实体机搭建有更高的性价比,也能让自己能对系统、网络等有清晰的理解。

我个人需要一台服务器,实现以下服务:

如果你也有同样的需求,可以先自己折腾一下。仔细琢磨,很多不能都会变成

本文有以下亮点和问题解决方法:

  1. NUC10 安装 CentOS 8
  2. 消除一根网线通客厅的限制
  3. 自动修改常变的IP解析
  4. 解决单机上搭多个Hugo博客网站
  5. 解决Nginx不刷新或慢刷新下游域名解析的问题

本文中用到的相关脚本详见GitHub仓库

剧透一下实现细节:

nuc-dev-env-framework

购置列表

选购一台自己的服务器,这里选用NUC10,性能强、功耗低、空间占用小。

购置项目 备注 价格(元)
寒霜峡谷NUC10i7FNH 6核12线程 3499
金士顿 DDR4 2666 16GB 2666是频率 459
西数 500GB M.2接口 NVMe蓝盘 2400MBps 479
panzhongxian.cn域名 博客地址 29
.xyz域名 用于自动更新NUC IP 6
云主机 1核 1G 40GB硬盘 1Mbps 作为HTTP代理 79

NUC10 安装 CentOS 8

更新BIOS

参考: 英特尔® NUC 的 BIOS 更新和恢复说明

可以先将U盘格式化成FAT32格式,然后将更新的文件放进优盘,F7方式更新即可。

不支持Boot from SD card

没有U盘,直接使用SD卡写进去一个ISO,插进去后仍提示没有找到启动程序的设备。

Intel官方文档有说明,NUC10不支持SD卡启动。

UEFI

这里有介绍UEFI和Legacy启动的区别。NUC10默认使用UEFI,而且我进入BIOS发现不能勾选掉UEFI启动。

直接使用UltraISO写入镜像会报:

[sdb] No Caching mode page found
[sdb] Assuming drive cache:write through

可以参考How to Install CentOS 8 Server 文章中使用 Rufus 创建可以启动的U盘

安装CentOS

安装过程主要参考How to Install CentOS 8 Server这篇文章。

新硬盘提示空间不足。可以勾选I would like to make additional space availible. 点击Done之后,可以delete掉大块空间,然后reclaim space。

网络设计

如果要从外部访问家中的服务器,则需要有公网的IP和端口

物理网络拓扑

电信员接法

network-01

实际情况

很多家庭中的结构可能都跟我家这种类似:

我的接法

网上各种的教程,一根网线拆两根的、以超级管理员修改光猫配置的,其实通通不需要

network-02

但是需要配置一下路由器:

让外网能够访问到你

申请公网IP

深圳地区,可以直接电话电信客服,要求分配给自己公网IP,而不是NAT的私有地址(10. 开头的网址)。

电信会创建工单处理,几小时内会回电话结单,之后重启光猫即可。

固定MAC与IP映射

因为路由开启了DHCP,需要将NUC的MAC分配固定的局域网(LAN)IP,这就是我们在设置DHCP时预留IP的用处。

登录路由器管理页面->应用管理->IP与MAC映射表,可以固定映射关系。

LAN端口映射到公网端口

如果要通过公网访问局域网某端口的服务,需要设置内部端口公网端口固定映射。

登录路由器管理页面->应用管理->虚拟服务器,可以添加映射关系,指定外部端口、协议、内部地址和端口。

TODO 放一张图。

自动更新域名

电信分配的公网IP是会变的,只有通过提供域名才能从外部方便地访问到我们服务。

可以调用域名所在云平台的API,通过定时任务来及时更新域名解析的IP。

我在阿里云上购买的域名,API可以参考这里UpdateDomainRecord,详细的代码参考这里

系统环境与服务设置

SSHD

安装SSHD

yum install openssh-server

修改 sshd_config

/etc/ssh/sshd_config 中的下边设置sshd的端口。

我这里是设置了一个大端口 56022 ,也可以注释掉直接使用 22 端口:

# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
Port 56022

允许root用户sshd:

PermitRootLogin yes

设置使用密码登录:

# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication yes

启动sshd

加入到开机启动的列表中:

systemctl enable sshd.service      # 开机时就启动
systemctl is-enabled sshd.service  # 查看是否加入到了开机启动

开机之后的启动、停、重启、状态:

systemctl start sshd.service
systemctl stop sshd.service 
systemctl restart sshd.service
systemctl status sshd.service

防火墙端口放通

TODO: 如果不设置的错误内容

firewall-cmd --list-ports # 查看当前放通的端口
firewall-cmd --zone=public --add-port=56022/tcp --permanent # 放通端口
firewall-cmd --reload # 重启防火墙后生效

关闭GUI

因为只是作为服务器使用,也暂时没有远程连接桌面的需求,图形界面可以关闭掉。

处理方法类似于上边 sshd 服务,这里的服务名是 gdm.service (GNOME Display Manager)

service gdm status  # 查看是否打开
service gdb stop    # 关掉gdm服务
systemctl disable gdm.service  # 关闭开机启动

创建用户

普通用户

useradd -m -d /PATH/TO/FOLDER USERNAME
passwd USERNAME
# TODO: add into sudoer list

特殊用户

gpasswd -a hugo docker

博客搭建

使用Hugo作为博客引擎,开源框架,当前社区也比较活跃。

背景中也提到了,我需要搭建多个博客网站。

NUC 上 HUGO Docker

因为我这边搭了两个hugo的博客网站,直接使用docker起两个容器,然后将1313端口映射出两个端口来。

在dockerhub上有klakegg/hugo镜像。

# 博客网站A 的目录,使用13130端口
cd ${BLOG_A_DIR} && docker run --rm -v $(pwd):/src -p 13130:1313 klakegg/hugo "server --bind=0.0.0.0" &> /dev/null &
# 博客网站B 的目录,使用13131端口
cd ${BLOG_B_DIR} && docker run --rm -v $(pwd):/src -p 13131:1313 klakegg/hugo "server --bind=0.0.0.0" &> /dev/null &

京东云 Nginx 转发

电信将个人用户的80、8080、443端口都给封掉了,如果要对外提供服务,必须得搞一个云服务器。

我这里购买了一个腾讯云的服务器,通过配置nginx转发至NUC上。

server {
    listen              443 ssl;
    server_name         domain_name_1;

    ssl_certificate     /etc/ssl/domain_name_1/full_chain.pem;
    ssl_certificate_key /etc/ssl/domain_name_1/private.key;
    location / {
        proxy_pass http://panzhongxian123.xyz:13130;
    }
}

用 Envoy 替换 Nginx

因为我这个域名会很频繁的修改解析记录,上述 Nginx 配置不能刷新域名的新解析记录。以为最近恰好在用 Envoy,知道其有多重方式发现下游能解决这个问题,所以直接使用 Envoy 替换 Nginx。

创建配置文件

配置文件完整版请点击链接envoy.yaml,其中,自动刷新DNS的下游集群的配置如下:

  clusters:
  - name: service_pan
    connect_timeout: 0.25s
    type: LOGICAL_DNS
    # Comment out the following line to test on v6 networks
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: service_google
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: panzhongxian123.xyz
                port_value: 13130

使用Envoy的Docker

不需要自己编译Envoy也可以使用最新的Envoy,创建 Dockerfile,内容如下:

FROM envoyproxy/envoy:v1.14-latest
COPY envoy.yaml /etc/envoy/envoy.yaml

构建镜像:

docker build -t envoy:v1 .

定时拉Github内容

每分钟重新拉取一次github上的最新内容,因为可能有git push -f,所以每次会reset --hard以避免直接pull产生冲突。

*/1 * * * * cd ${BLOG_A_DIR} ;  git fetch --all && git reset --hard origin/master
*/1 * * * * cd ${BLOG_B_DIR} ;  git fetch --all && git reset --hard origin/master

开发环境搭建

一次性安装开发者工具

https://blog.csdn.net/sanbingyutuoniao123/article/details/80498090

Vim工具搭建

./git/new-machine-start.md

Install Vim and Plugins

git clone https://github.com/vim/vim.git
cd vim/src
make

Vundle

VIM 插件管理工具

https://github.com/VundleVim/Vundle.vim

vim-codefmt

自动格式化代码 FROM Google

https://github.com/google/vim-codefmt

bazel format

https://github.com/bazelbuild/vim-ft-bzl

Plugin 'bazelbuild/vim-ft-bzl'

配色方案

syntax enable
set t_Co=16
let g:solarized_termcolors=256
set background=dark

localvimrc

为了避免某些项目中不需要自动对齐等功能,可以设置使用local vimrc。

https://github.com/embear/vim-localvimrc

保持上次位置

vimrc

if has("autocmd")
  au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif

Docker

LLVM

Bazel

远程开发