mac笔记本当做服务器记录

持续更新中~

三更:放弃了mac,转战树莓派4b
二更:使用dp 创建虚拟机ubuntu,并设置网卡桥接,使用正常
已废弃:因为docker的权限问题各种坑


大致画了一下家庭布局图
在这里插入图片描述



基础环境准备1:mac设置不休眠

因为将mac当做服务器来使用需要7*24小时,要解决屏幕功耗(烧屏)及硬盘不会自动休眠,为todesk使用做准备。

1.设置MAC不休眠

解决 macbook m1 苹果笔记本电脑 关闭盖子 休眠

2.关闭键盘屏幕使用功能

平时我是合盖使用,所以需要降低损耗到最低,
合盖时屏幕设置亮度为最低,键盘屏幕设置禁用(长时间不用键盘灯自动熄灭)

3.关闭键盘副屏使用 灯光和误触

mac bookpro m1 笔记本关闭键盘屏幕 禁用键盘屏幕使用 键盘屏幕误触 Touch Bar禁用 禁用MacBook-Pro的触摸栏

基础环境准备2:关闭sip

Mac SIP系统完整性保护是OS X El Capitan及更高版本所采用的一项安全技术,这项技术能够帮助用户防止潜在的恶意软件修改Mac上受保护的文件和文件夹。SIP系统完整性保护可以限制root用户帐户,以及root用户能够在Mac系统的受保护部分完成的操作。
直接点就是说:对某些目录权限进行了限制,例如docker 的-v目录授权,例如在根目录创建文件夹

因为我的MAC是m1芯片的,传统的command+R的方式不能用,需要开机长按开机键才能进入系统
借鉴了:https://www.jianshu.com/p/6554ace478fb

基础环境准备2:关闭mac的自动更新

因为mac 准备就绪后会影响todesk 所以要关闭自动更新

在这里插入图片描述
请添加图片描述

第一步、todesk阶段

考虑了几个远程方案、例如向日葵、tv、vnc
测试了一下VNC发现速度不理想,最终使用了todesk

1. 安装ToDesk及权限配置

官网下载
在这里插入图片描述

2.测试连接正常

在这里插入图片描述

3.todesk 部分完成

有问题私信我,或者联系todesk官方客服支持群
在这里插入图片描述

解决ssh的问题

我想实现的要求:
1.在互联网上,直接ssh +ip地址+非常规端口号即可连接,或者增加生成的ssh密钥进行连接保证安全性
2.本地选择使用nginx 进行ssh代理到常规端口

1.mac 配置静态IP

因为之前是wifi dhcp连接的路由器为满足后续的端口开放、需要配置一个固定IP
在这里插入图片描述
在这里插入图片描述

2.mac配置固定dns 一般是网关也就是路由器的地址

设置DNS 不然不能上网
在这里插入图片描述

3.路由器配置

在路由器端进行固定IP的端口转发开放
在这里插入图片描述

4.MAC开放远程权限,并本地局域网测试

在这里插入图片描述

5.局域网测试

在这里插入图片描述

6.在光猫端,设置端口开放连接 外网访问

在这里插入图片描述

7.外网访问测试

在这里插入图片描述

8.ssh部分完成,已实现从外面通过ssh访问家里的电脑

Docker阶段

安装docker基础环境及设置开机自启

官网 https://www.docker.com/

1.下载安装

在这里插入图片描述

2.设置docker 开机自启

在这里插入图片描述

安装docker nginx

请看另一篇文章 http://t.csdn.cn/h1ojY

解决DDNS问题 动态公网IP

我是家庭宽带 只能申请到动态的公网ip,好处是不花钱,弊端是每次重启光猫,都会重新获取一个新的公网IP

为解决此办法,我尝试了很多个DDNS的方案。
包括但不限于。

1.云厂商DDNS(本教程使用)
2.购买一台云机nginx反代到本地,本地心跳检测域名,不通则立刻获取本地公网ip同步到云机nginx并重启。
3.路由器支持的DDNS功能
4. frp技术 花生壳、ngrok 等
5.软路由
6.ddns-go https://wp.gxnas.com/11459.html

下面我解释下为什么都排除了
2.成本高,还要保证一台转发云机。还要维持备案
3.路由器只支持部分的,例如花生壳的,看路由器兼容性
4. 研究了下花生壳,免费的只有2个,要么在花生壳买域名,要么push域名到贝锐(花生壳),要么每年40元解析费用,但都是需要实名认证的
5.软路由 ,需要设备,常开,具体功能我也没玩明白,以后研究明白了出教程
6. 是封装了各厂商的云API且是go语言编写,我未来打算自行封装,所以未采取该方案。

下面介绍一下通过腾讯云,云API调用,实现同步更新动态公网IP,解决痛点。

1.要用到的:

云API使用文档
借鉴了其他的文章

2.开始正文

首先要确定解析的域名
我的域名解析是这个
记录值是家宽公网ip
在这里插入图片描述

云api文档中

3.修改记录

这个接口是用来修改记录值的,也就是DNS解析到的IP地址,在这里进行修改DNS记录值
在这里插入图片描述

上图有4个参数需要填写,
分别是

  • Domain
    顶级域名 例如: baidu.com
  • RecordType
    记录类型

在这里插入图片描述

  • RecordLine
    记录线路,通过 API 记录线路获得,中文,比如:默认。
  • Value
    记录值,如 IP : 200.200.200.200, CNAME : cname.dnspod.com., MX : mail.dnspod.com.。
  • RecordId
    记录 ID 。注意下图如何获取
4.RecordId 获取

举例:
在这里插入图片描述

5.获取记录信息 得到RecordId

文档:https://console.cloud.tencent.com/api/explorer?Product=dnspod&Version=2021-03-23&Action=DescribeRecord&SignVersion=

这里发起一下请求,找到我解析的m的记录信息中 的RecordId
在这里插入图片描述

6.测试请求,部署代码

复制上图红框内容,回到上面请求,这里进行调试
在这里插入图片描述
在这里插入图片描述

请求成功了,下面生成代码,进行部署
在这里插入图片描述

7.生成密钥

可以看到,生成的代码中,有2个字段需要填写,

密钥
SecretId
SecretKey

链接地址:https://console.cloud.tencent.com/cam/capi
新建即可
在这里插入图片描述
填入密钥
在这里插入图片描述

8.代码完善一:获取公网ip

添加代码:
获取本地的公网ip地址的方法

   public static String getIpV4(){
        String ipV4 = "";
        try{
            String ipStr = HttpUtil.get("https://www.taobao.com/help/getip.php");
            ipV4 = ipStr.split("\"")[1];
        }catch(Exception e){
            e.printStackTrace();
            ipV4 = "127.0.0.1";
        }
        return ipV4;

    }

在这里插入图片描述

pom添加

<dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.1.2</version>
</dependency>

在这里插入图片描述
开始请求,启动main方法

在这里插入图片描述
在这里插入图片描述
成功啦!

9.代码完善二,解决心跳机制

下面解决心跳机制的问题。
想过几个方案

1.定时任务
2.定时ping 当ping不同的时候调用ddns方法
3.生成jar包,启动main方法,一直后台运行

我采用了方案2
操作如下
1.添加定时ping的任务
2.启动的jar包,开启后台守护程序
3.生成日志,重启记录发送邮箱
当请求超时时,说明ip不通了,需要更新一下,就调用一下方法

增加了如下代码
1.定时任务

    //动态定时任务
    public static void main(String[] args) {
        //每10秒执行一次
        CronUtil.schedule("*/10 * * * * *", new Task() {
            @Override
            public void execute() {

                Console.log("这里是动态添加定时任务!.");

            }
        });

        // 支持秒级别定时任务
        CronUtil.setMatchSecond(true);
        CronUtil.start();
    }

2.ping不同的时候调用ddns方法

    public static void main(String[] args) {
        System.out.println( ping("m.2048.top"));
    }

    /**
     * 检测IP地址是否能ping通
     *
     * @param ip IP地址
     * @return 返回是否ping通
     */
    public static boolean ping(String ip) {
        return ping(ip, 200);
    }

    /**
     * 检测IP地址是否能ping通
     *
     * @param ip      IP地址
     * @param timeout 检测超时(毫秒)
     * @return 是否ping通
     */
    public static boolean ping(String ip, int timeout) {
        try {
            return InetAddress.getByName(ip).isReachable(timeout); // 当返回值是true时,说明host是可用的,false则不可。
        } catch (Exception ex) {
            return false;
        }
    }

最后合起来的代码

package com.tencent;

import cn.hutool.core.lang.Console;
import cn.hutool.cron.CronUtil;
import cn.hutool.cron.task.Task;
import cn.hutool.http.HttpUtil;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.dnspod.v20210323.DnspodClient;
import com.tencentcloudapi.dnspod.v20210323.models.*;

import java.net.InetAddress;

public class ModifyRecord
{

    public static String ddns() {
        try{
            // 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
            // 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
            Credential cred = new Credential("密钥id", "密钥key");
            // 实例化一个http选项,可选的,没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("dnspod.tencentcloudapi.com");
            // 实例化一个client选项,可选的,没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            DnspodClient client = new DnspodClient(cred, "", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            ModifyRecordRequest req = new ModifyRecordRequest();
            req.setDomain("2048.top");
            req.setSubDomain("m");
            req.setRecordType("A");
            req.setRecordLine("默认");
            //获取本机的公网ipv4地址
            String ip=getIpV4();
            req.setValue(ip);
            Console.log("新的ip是:"+ip);
            req.setRecordId(纯数字);
            // 返回的resp是一个ModifyRecordResponse的实例,与请求对象对应
            ModifyRecordResponse resp = client.ModifyRecord(req);
            // 输出json格式的字符串回包
//            Console.log(ModifyRecordResponse.toJsonString(resp));
            return ModifyRecordResponse.toJsonString(resp);
        } catch (TencentCloudSDKException e) {
            Console.log(e.toString());
        }
        return null;
    }
    public static String getIpV4(){
        String ipV4 = "";
        try{
            String ipStr = HttpUtil.get("https://www.taobao.com/help/getip.php");
            ipV4 = ipStr.split("\"")[1];
        }catch(Exception e){
            e.printStackTrace();
            ipV4 = "127.0.0.1";
        }
        return ipV4;

    }

    /**
     * 检测IP地址是否能ping通
     *
     * @param ip IP地址
     * @return 返回是否ping通
     */
    public static boolean ping(String ip) {
        return ping(ip, 200);
    }

    /**
     * 检测IP地址是否能ping通
     *
     * @param ip      IP地址
     * @param timeout 检测超时(毫秒)
     * @return 是否ping通
     */
    public static boolean ping(String ip, int timeout) {
        try {
            return InetAddress.getByName(ip).isReachable(timeout); // 当返回值是true时,说明host是可用的,false则不可。
        } catch (Exception ex) {
            return false;
        }
    }


    public static void main(String[] args) {
        //动态定时任务
        //每10秒执行一次
        CronUtil.schedule("*/10 * * * * *", new Task() {
            @Override
            public void execute() {
//                Console.log("这里是动态添加定时任务!");
                //如果不通了  返回false
                if (!ping("m.2048.top")){
                    //就进行ddns方法
                    Console.log(ddns());
                }
            }
        });
        // 支持秒级别定时任务
        CronUtil.setMatchSecond(true);
        CronUtil.start();
    }

}

10.代码打包发布启动并测试

package打包成jar包
在这里插入图片描述
运行下面的这个jar包
启动命令 其实就是启动一个main方法

java -cp java-sdk-1.0-SNAPSHOT-jar-with-dependencies.jar com.tencent.ModifyRecord start
11.测试成功ddns完成在这里插入图片描述

运行正常
后期放到docker中使用

持续交付阶段

1.思路整理

后期部署的java、php等业务系统项目,打算每个业务应用都docker部署
目前想了2个方法,及搜索到的解决方案

1.jdea的docker集成,一键生成本地镜像,且部署线上docker 借鉴链接:https://blog.csdn.net/jackcheng1117/article/details/83080303
2.Jenkins 持续集成:https://blog.csdn.net/aiwangtingyun/article/details/123523669

考虑到一劳永逸,我选用jenkins

1.通过docker的方式安装jenkins
## 拉取 Jenkins 镜像
docker pull jenkins/jenkins
## 创建 Jenkins 挂载目录
mkdir -p /Users/work/jenkins
## 创建挂载目录的同时要给该目录配置权限 777,如果权限不足的话,到时进行目录挂载的时候会失败导致无法启动 Jenkins 容器。
chmod 777 /Users/work/jenkins
2.创建并启动容器
docker run -d \
    -p 9837:8080 \
    -p 50000:50000 \
    -v /Users/work/jenkins:/var/jenkins_home \
    -v /etc/localtime:/etc/localtime \
    --restart=always \
    --name=jenkins \
    jenkins/jenkins
  • -d:后台运行容器;
  • -p 8888:8080:将容器的 8080 端口映射到服务器的 8888 端口;
  • -p 50000:50000:将容器的 50000 端口映射到服务器的 50000 端口;
  • -v /Users/work/jenkins:/var/jenkins_home:将容器中 Jenkins 的工作目录挂载到服务器的 /Users/work/jenkins;
  • -v /etc/localtime:/etc/localtime:让容器使用和服务器同样的时间设置;
  • –restart=always:设置容器的重启策略为 Docker 重启时自动重启;
  • –name=jenkins:给容器起别名;

查看是否启动成功
在这里插入图片描述
上图是启动成功了,且端口映射正常

3.jenkins配置

下面在局域网访问一下,然后配置一下
在这里插入图片描述
根据创建docker时候的映射文件找到密码并填入
在这里插入图片描述
在这里插入图片描述

我的mac挂着魔法呢,所以我没换源,如果需要换源,百度搜下 jenkins换国内源。

我这里选择的新手推荐安装的插件
在这里插入图片描述

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

石宗昊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值