20230407kubekey搭建k8s

视频版

https://www.bilibili.com/video/BV1gL411Y75L

 

背景

20230204尝试搭建k8s青春版

上次尝试了k3s,本来计划是尝试原版k8s,但看了下文档感觉略麻烦,我决定放弃。。。。

按上次eric的建议这次尝试玩下kubekey

安装准备

环境要求

Ubuntu 16.04,18.04,20.04CPU:2 核,内存:4 G,硬盘:40 G

机器节点2c4g * 3

  • 所有节点必须都能通过 SSH 访问。
  • 所有节点时间同步。
  • 所有节点都应使用 sudo/curl/openssl/tar
域名分配
k8s1.k8s.local
k8s2.k8s.local
k8s3.k8s.local
kubesphere.k8s.local

生成config

修改config

每个节点上安装依赖项

任务机上执行这个安装集群

安装过程

这时候可以进到命令行查看安装过程,ks-installer-86ddb55c5b-gwlhh就是安装的pod

可以进入pod容器查看目录

也可以直接用logs查看日志

观察到这两个pod一直起不来

都是源于configmap kubesphere-config不存在

多等了一会发现第二个pod ks-controller-manager-8569fb495c-b9qwv自己成功了,可能有降级?(来自20230701的更新:只是单纯的慢,实际是monitor还没装完,所以不动它也能自己好)

尝试手动修改kubesphere-config 里的jwtToken

kubectl get cm kubesphere-config -n kubesphere-system -o yaml

删除pod ks-apiserver后不再报错

参考

https://kubesphere.io/zh/docs/v3.3/installing-on-linux/introduction/multioverview/

https://github.com/kubesphere/kubesphere/issues/4729

http://www.minio.org.cn/docs/minio/kubernetes/upstream/

https://docs.ceph.com/en/quincy/cephfs/index.html

 

20230311neo4j测试

0.背景

因json文件、mysql、mongo存储都不能方便的满足我的要求,计划后续使用图数据库来存储复杂的的图状关系

1.安装

看了一眼dockerhub有现成的镜像,直接选了最新的

7474是web端浏览器的端口,7687是数据库本身的端口。启动后默认用户名密码都是neo4j,记得修改密码。这里测试,因此用弱密码12345678

2.使用

2.1.基本语法

node节点

relationship关系

properties属性

好了,你已经学会基本的语法了,是时候设计一个复杂的项目了(

3.集成到java中

尝试 spring-boot 3 + neo4j ORM

3.1.修改pom.xml

3.2.entity类

3.3 repo类

注意:关系字段中,如果实体不存在则会自动创建Node,但如果修改实体导致数据减少,OGM不会删除关联的实体,只会删除关系

 

参考

https://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#preface

https://neo4j.com/docs/getting-started/current/get-started-with-neo4j/

https://neo4j.com/docs/browser-manual/current/

https://www.w3cschool.cn/neo4j/neo4j_cql_introduction.html

20230203IDEA插件开发-Action的实现

背景

开发的插件点击后UI卡住,怀疑是阻塞了UI线程。。。。仔细看下文档

文档翻译-Action的实现

自定义的action类是派生自抽象类 AnAction的子类。当用户操作菜单项或工具栏按钮时,IDEA会调用action的方法

基于 AnAction 的类不能包含任何属性,因为 AnAction 的实例会存在 application整个生命周期。如果 AnAction 类使用了属性存储了短声明周期的数据但没有合理的清除,会造成内存泄漏。例如如果你把Project对象存到了这里,当用户关闭了这个Project之后就会发生内存泄漏

方法Override覆盖原则

每个action可以覆盖 AnAction.update(),必须覆盖AnAction.actionPerformed().

AnAction.update() 用来被IDEA调用更新action的状态,action是否可用/是否可见取决于action在当前UI上是否可用.AnActionEvent 对象会传递给这个方法并且包含当前action上下文的信息。可以通过修改和事件上下文关联的Presentation对象状态来改变action是否可用。像Overriding the AnAction.update() Method说的一样, update() 方法的执行速度非常重要

2022.3+版本后AnAction.getActionUpdateThread() 返回 ActionUpdateThread 线程决定了 update() 方法是否在 background thread (BGT) or the event-dispatching thread (EDT)上被调用。首选的方式是在BGT上执行update方法, 这样可以保证application侧读取 PSIthe virtual file system (VFS), 或 project models的有利条件。在BGT上运行update的Actions不应该直接访问Swing 组件的结构。 反之EDT上运行的update的Action必须禁止访问PSI, VFS, 或 project的数据,但可以访问Swing组件和其他UI模型。所有由DataContext 提供的可访问数据在这里有说明 Determining the Action Context. 当必须从BGT切换回EDT时,需要使用 AnActionEvent.getUpdateSession()方法获得 UpdateSession 并调用 UpdateSession.compute() 在EDT上运行方法。从2022.3开始,插件的DevKit将会有检查 Plugin DevKit | Code | ActionUpdateThread 是否丢失,来提醒插件作者实现这个方法

AnAction.actionPerformed() 将会在可用之后当用户选择action时被IDEA调用。这个方法是实现action最麻烦的任务,它包含了当action被调用时要执行的代码。 actionPerformed()方法也接收一个 AnActionEvent作为参数,它用来访问任何上下文相关的信息例如 projects, files, selection。。。参考Overriding the AnAction.actionPerformed() Method 获取更多信息

这里还有其他的方法可以在 AnAction 类中被覆盖,例如改变action默认的 Presentation。还有一个使用场景可以通过覆盖构造器来达成,当动态注册到分组的时候demo可以在这里看到Grouping Actions

AnAction.update 

IDEA会周期性的调用AnAction.update() 方法来响应用户的操作。 update() 方法用于动态判断action在当前上下文是否应该禁用或启用。方法的实现必须确保可用性状态和可见性状态 ,否则指定的action将会”卡住”。(译者注:这里的意思应该是从用户看来是卡住的现象,实际就是没响应任何动作)

AnAction.update()方法可能在UI线程上频繁的调用。所以这个方法必须非常快的执行,没有必须执行的实际动作。例如检查选中的对象是否可用,但不做任何文件系统相关的动作。如果新的状态无法被快速的确定是否可用,判定过程应该在AnAction.actionPerformed()中执行,并通知notify用户这个动作在当前上下文不能被执行

线程

//TODO

参考

https://plugins.jetbrains.com/docs/intellij/basic-action-system.html

https://plugins.jetbrains.com/docs/intellij/general-threading-rules.html#modality-and-invokelater

20230224dev-assistant idea plugin开发

既然ChatGPT能理解自然语言,为什么不让它来帮我写代码完成这个开发任务呢?

基于这个猜想,我尝试让它编写IDEA插件逻辑,以一个LOGGER插入为例。

我给的命令是

利用IntelliJ Platform Plugin SDK获取当前光标所在类的成员变量,检测是否存在LOGGER,如果不存在,在类声明的第一行插入LOGGER的声明,并import对应的slf4j依赖。用java实现

它给出的代码如下

对不起,是我高估了AI的实力,它部分代码在胡写。。。。得自己验证是否可行,它的代码看着没毛病,但实际很多地方都有问题= =

还是自己动手写吧,参考 https://www.bilibili.com/video/BV15D4y137Sp/

20230218长期计划:dev-assistant

背景

最近试用ChatGPT给我带来了新的想法,如果你觉得我后面写的比较离谱,那确实有可能是我错误的高估了现有AI的能力,就当我是在做梦吧hhhh。总的来说这种对话的方式极大的降低了人机交互的门槛。相比于传统的交互方式,以自然语言和计算机进行有效的交互是听上去理所当然,但实际上一直都不太成熟的方式。而ChatGPT给我们带来了新的希望,我认为之后这个技术足够成熟之后将会改变很多现有的交互逻辑。可以设想,假如以后AI能正确理解绝大部分的自然语言,那么是不是很多任务都不需要用鼠标和键盘来操作了?而根据网友给出的参考资料,有人正在尝试将自然语言转化为一系列的API调用(参考最后的附录),这意味着AI生成的内容将具有可执行的特性,不同的API完全可以代替现有的人工操作,完成一场人机交互的变革。

继上一次我根据AST上下文来做可控的LiveTemplate之后,我继续尝试了提取代码的AST节点并结构化其中的语义信息配合可视化来提高日常工作效率。但短期内无论从安全角度还是对成果负责的角度来说,程序生成的结果,或者说AI的动作都必须经过人工的确认以避免AI失控造成不好的后果。也就是说在相当长的一段时间内,AI的操作必须要可观测、可干预。以此为前提让我有了一个科幻的想法:我对电脑用自然语言下达任务后,电脑在我的监视下逐步完成任务。选择离我最近的场景来说就是日常的编码工作在有详细设计的情况下是否有希望完全自动化?

可行性分析

现有的代码生成AI大多是基于工程内已有的文件、注释、当前文件光标的上下文来猜测并生成代码,但这里面缺少了一个重要的信息就是目的。AI无法准确猜测人的意图,比如完成某个API的编码通常会分成接入层、业务层、数据层,多层次+多个方法的组合。AI每次只能预测我选定光标位置的代码内容,而无法连续跳跃多个层次来完成这个任务,依然需要人工大量操作IDE。如果能以自然语言提供给AI这个目的,是否有可能让AI自行完成这一系列的动作呢?由此会带来的一系列问题。开发人员对IDE的操作是否能通过文本精确的描述?开发人员操作IDE时依赖的信息有没有可能被收集起来并打上标记?如果将我日常操作IDE的记录和操作IDE时候的信息完整的记录下来并打上标记,能否训练出一个AI来理解并代替我进行IDE的操作?

以我目前的AI水平还停留在手写数字识别的入门级别,虽然有计划学习相关知识,不过并不是抱很大的希望能独立搞定模型的设计、训练之类如此专业的任务。但以我目前的能力,处理点数据、集成已有的功能还是不成什么问题的。 因此我有一个长期计划的想法,设计并收集开发操作IDE的上下文信息,包括但不限于工程类型、文件组织结构、版本控制信息、产物信息、光标上下文信息等。依赖这些详细的信息,自动或手动的分析任务场景打上标记作为下一步AI训练的基础数据。抽取并实现一组API来获取、操作IDE内的动作并实时的反馈到屏幕上供人工干预这个过程。至于这个AI怎么训练,那可以将这个项目开源交给AI的专业人士搞定,我可以力所能及的收集数据或组合已有功能。退一步来说,就算AI搞不出来,收集的这些信息可以继续试用传统方式来处理,也能推动现一点点xxxAsCode的进程。

方案设计

项目名代号暂定为skykoma,分别取自skynet和tachikoma的一半,如果有好的名字欢迎反馈给我。整个项目拆分成若干模块分别独立实现,如果有生之年每个部分最后都能完全实现,则组合到一起。

信息收集模块:收集当前工程结构、版本控制、产物、光标上下文、IDE等信息,这些信息等价于开发员看到和了解到的信息。收集开发人员对IDE的操作序列数据。

信息处理模块:对收集到的信息做预处理,标记子序列对应的场景并用自然语言描述,在必要的位置插入人工干预的节点,以此作为训练的基础数据。

指令生成模块:接受自然语言描述的任务,生成一系列结构化指令

指令调度模块:接收一系列结构化指令并转化成具体的动作,动作的序列必须满足人工可观测、可干预、可理解,符合正常人操作的习惯,且动作序列有对应的API。理论上训练数据如果足够好可以达到部分效果,但为了可控和安全还是需要一个调度模块,为的是有机会通过程序强制干预AI的结果,加一道保险。

动作执行模块:给定具体动作并执行的同时收集结果、可视化反馈

以一个常见的场景为例:

自然语言描述:查找ClassA的所有实现类。

指令生成模块:打开搜索功能,输入关键字ClassA,从结果中定位ClassA,打开ClassA对应的文件编辑器,光标定位到ClassA的声明位置,搜索实现类(Ctrl+Alt+B)

指令调度模块插入必要指令:打开搜索功能,输入关键字ClassA,从结果中定位ClassA,判断是否能定位到ClassA(满足人工干预的要求),尝试打开ClassA对应的文件编辑器,光标定位到ClassA的声明位置,搜索实现类(Ctrl+Alt+B),收集搜索结果同时展示到屏幕上(满足可观测的要求)

指令调度模块转化指令到具体的API:打开搜索功能,输入关键字ClassA,从结果中定位ClassA,判断是否能定位到ClassA(满足人工干预的要求),尝试打开ClassA对应的文件编辑器,搜索当前文件下所有的class声明(指令调度需要生成API可支持的操作),寻找ClassA的声明位置(指令调度需要生成API可支持的操作),搜索实现类(Ctrl+Alt+B),收集搜索结果同时展示到屏幕上(满足可观测的要求)

执行模块:依赖指定调度的API结果控制IDE依次执行对应的指令

以下的ChatGPT给出的示例代码

 

概要设计

以上模块将会划分成多个开源项目,为了便于实现部分逻辑上的模块会放到同一个实际的项目中

交互层 skykoma-plugin-idea(1), skykoma-plugin-vscode(2), skykoma-chatbot(3) , skykoma-agent(待定),  skykoma-workspace(待定) 顾名思义交互层定位于用户的输入和输出,同一管理最外层的交互

数据层 skykoma-data-collector(4), skykoma-data-handler(5), 收集和处理所有相关的数据并存储、上报

逻辑层 skykoma-core(6), skykoma-cmd-generator(7), skykoma-api-transformer(8), skykoma-api-worker(9), core就是核心的模型负责自然语言处理并生成第一版指令序列,cmd-generator负责指令的调度、插值、过滤以符合前文所说的各种条件,api-transformer负责把指令序列做翻译成现存工具的API调用, worker负责调用具体的API

执行层 skykoma-api: skykoma-api-idea,skykoma-api-vscode,skykoma-api-git(10),skykoma-api-mvn(11),skykoma-api-gitlab(12),skykoma-api-github(13), 顾名思义,实现整合各个现有工具的功能,以localhost HTTP、cmdline、rpc等方式对外提供服务

里程碑规划

v0.1 搭框架

手动完成realworld或者其他什么的工程编写作为测试项目,要求满足常见的企业级开发特性。

初始化idea插件工程(https://github.com/dev-assistant/skykoma-plugin-idea),支持私有化部署,收集idea当前的项目信息。

初始化数据收集工程(https://github.com/dev-assistant/skykoma-data-collector),支持私有化部署,数据存储位置可自行选择。

skykoma-plugin-idea概要设计

架构上因为不想出现多个idea插件,因此设计一个skykoma-api-idea负责和idea的api具体交互,kykoma-plugin-idea依赖skykoma-api-idea来获得对IDE完整的感知和控制能力。plugin支持常用的LiveTemplate,设计生成规则,在固定场景下支持人工触发生成。skykoma-api-idea收集idea的状态和操作事件并上报给skykoma-data-collector达成数据收集目的。同时也可以通过websocket、http等协议监听本地端口或从外部的控制模块获取指令。

模板代码自动生成功能

模板代码生成主要依赖于LiveTemplate实现,分为静态生成和动态生成,静态生成是上下文无关的,动态生成可感知代码上下文。

静态生成

如@Autowire @Column 之类的,试用idea自带API完成命名风格的转换。

动态生成

日志:寻找上下文中可用的LOGGER,若LOGGER不存在则尝试先生成LOGGER字段,并根据当前上下文插入LOGGER语句。

SQL:寻找上下文中的ORM注解信息,根据字段类型生成默认的建表语句。

数据复制:根据上下文获取指定类的所有属性,复制到当前上下文中或指定的对象中,代替动态的反射copy避免运行时异常。

Service:增强自带的创建类过程,根据类名猜测正确的包名,一键生成带注解的Service类和接口并实现对应接口满足主流项目的风格要求,减少人工操作。

代码见 https://github.com/dev-assistant/skykoma-plugin-idea

数据上报功能

TODO 设计数据结构表示上下文,包括当前窗口信息、窗口标题、项目信息、git信息、全量AST信息等

代码见 https://github.com/dev-assistant/skykoma-data-collector

skykoma-data-collector概要设计

负责skykoma需要的数据收集工作,用多种合适的存储方案持久化用户每个操作的上下文信息和事件。语义图暂定neo4j图数据库,其他结构化信息继续使用mysql。

设计数据结构存储相关信息

有了全量AST和语义,才有可能做到
1.给定任意项目任意API、自动提取可运行的最小依赖沙盒环境
2.任意复杂业务逻辑分析,不重不漏
3.沙盒环境的修改可回填到原始项目:可debug、做测试用例、分析逻辑、修改
4.因沙河内依赖最小化了,理论上可以用自然语言总结所有的上下文和代码意图信息、为炼丹做准备。退一步即使炼丹失败,也能快速抽象出大量模板代码来使用
5.反向给定自然语言生成沙盒环境、可完成对任意项目的patch

 

参考

https://arxiv.org/pdf/2302.04761.pdf

https://arxiv.org/pdf/2211.10435.pdf

20230204尝试搭建k8s青春版

视频版

https://www.bilibili.com/video/BV1qj411T7d5/

背景

之前一直想搭建k8s,但按多年前的印象这玩意很复杂。今天先尝试个青春版k3s

安装准备

按文档说是离线在线都行,离线的需要个私有的镜像中心,但镜像中心最简便的搭建方式是跑个容器。。。死循环了啊,所以先试在线的。

家里的资源不多,尝试做个乞丐版,2~3节点就行了,先弄单机后面再加worker

环境要求

硬件按文档建议是最少1c1g,我就给2c2g吧,机器数量是2

系统要求Ubuntu是22.04

可以使用 --with-node-id 给每个节点后面增加一个随机的后缀。或者使用命令行参数 --node-name 或环境变量 $K3S_NODE_NAME 给集群的每个节点传递唯一的名字

网络每个节点需要6443 可以被访问

Flannel VXLAN 节点间通过 UDP 8472 通信

Flannel Wireguard backend 节点间通过 UDP  51820(ipv4) 51821(ipv6)

安装过程

主节点安装过程如上,疑似成功。。。

查看进程如下,可以看到/run/k3s/containerd/containerd.sock说明containerd已经在运行了

metrics-server不知道是干什么的,后面再翻翻文档。

网络监听情况如下,可以看到大部分都是本地监听,只有10250 6443是有可能对外开放的

按文档描述是个TCP的端口监听,看起来和metrics server进程有关,好像是kubelet在节点之间通讯使用的。官方原文:If you wish to utilize the metrics server, all nodes must be accessible to each other on port 10250.

6443是TCP的监听,流量方向是从Agent向Server的,应该是worker节点向master注册数据用的。官方描述为 supervisor and Kubernetes API Server

按文档所说配置文件内容如下

按文档描述会生成这几个相关命令kubectl, crictl, k3s-killall.sh, and k3s-uninstall.sh。具体位置如下,均在/usr/local/bin下,所以可以从任意目录执行。

说实话k3s-killall.sh和k3s-uninstall.sh感觉并不适合放进这个位置,不知道是不是官方怕你找不到故意也放bin里了,这俩实际生产场景下完全没有全局任意目录运行的必要。万一误执行了就GG

尝试获取当前集群的节点,虽然知道只有一个,但需要看看命令是不是能正常执行,别和之前有的服务一样看着没事但实际没正常运行。。。。

这里有个需要关注的东西就是ROLES都有啥,需要看文档了。目前的control-plane顾名思义是控制面, master是主节点。不知道k8s的角色分配是不是和CDH一样能灵活转移。。。

查看TOKEN,准备安装第一个worker节点,按文档描述在这里/var/lib/rancher/k3s/server/node-token

注意,我在一个隔离环境测试,所以/var/lib/rancher/k3s/server/node-token和/etc/rancher/k3s/k3s.yaml的内容暴露了无所谓,待会会直接删除虚机,生产的千万不要轻易暴露。

按要求拼接worker的安装命令如下,到第二个机器上执行

执行到systemd卡住了(后面已确认只是单纯的慢)

再开一个shell查看进程如下

根据systemd服务注册的命令/usr/local/bin/k3s agent,可以看到大概率是执行systemctl restart k3s-agent卡住的

token本身错的可能性不大,所以大概率是K3S_URL的问题,因为我用了本地的DNS,所以写的是域名。尝试配置下HOSTS试试

保险起见我去 /var/lib/rancher/k3s/agent/containerd/containerd.log看了下,居然还在执行东西。。。难道只是单纯的慢?这时候主节点已经能看到agent了,但ROLES里是none让我比较纠结是不是正常

根据命令行参数打印更加详细的节点信息如下,这样看起来worker工作是正常的

测试

尝试构建一个服务是否能正常运行,从k8s官网看看能不能扒一个现成的yaml测试

尝试创建DEMO

尝试使用 kubectl exec进入容器

总结

相比多年前的印象,现在的k8s可以借助k3s这个青春版快速的启动一个集群,是时候更新下这个错误认知了,现在启动一个k8s测试用是相当简便并且成本很低的。下次尝试原版k8s,成功后尝试kubekey这个类似ansible一样的自动化安装工具

参考

https://docs.k3s.io/architecture

https://www.suse.com/suse-rancher/support-matrix/all-supported-versions/rancher-v2-7-1/

资源分配和实际占用统计  https://docs.k3s.io/reference/resource-profiling

自动化安装 https://kubesphere.io/zh/docs/v3.3/installing-on-linux/introduction/kubekey/

ROLES https://blog.csdn.net/Lingoesforstudy/article/details/116484624

https://kubernetes.io/zh-cn/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro/

https://blog.csdn.net/qq_44246980/article/details/120143353

20221217mongodb集群搭建

视频版

 

https://www.bilibili.com/video/BV1Lv4y1Q7xe/

环境准备

https://www.mongodb.com/docs/manual/administration/production-notes/#std-label-prod-notes-supported-platforms 所说6.0支持20.04和18.04

没说22.04支持,保险起见按文档准备系统版本

至少3个以上的奇数节点,5.0以上必须使用域名配置,节点间端口27017网络要求互通

 

1.安装

常见目录

常用命令

2.集群配置

MongoDB 的复制集是由一组保持相同数据集的 mongod 进程组成的。复制集提供了冗余和 高可用的能力,同时它是所有生产环境部署的基础

在特定情况下可以提高读取性能,因为客户端可以把读取请求发送给不同的服务器。被复制多份数据可以用于灾备或审计

复制集包含几个 data bearing nodes和可选的一个arbiter node。在data bearing nodes上有且仅有一个成员是主节点,主节点 接收所有写请求操作,一个主节点会使用 { w: "majority" } 来标识

 

设置bindIp启用远程访问,生产环境注意提前设置密码和防火墙

https://www.mongodb.com/docs/manual/reference/configuration-options/#mongodb-setting-net.bindIp

配置集群名

https://www.mongodb.com/docs/manual/reference/configuration-options/#mongodb-setting-replication.replSetName

3.灾备测试

挂掉1之后到2 上查看集群状态如下,可以发现2自动变成了主

重启1之后,再次查看,可以发现1重新加入了集群,但身份是从节点

从2写入点新数据,到1查询测试,可以发现是正常的

挂掉现在的从节点3,写入新数据后再重启3

可以发现新写入的数据依然可以正常查询

 

 

附录

 

参考

https://www.mongodb.com/docs/manual/

https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-ubuntu/#install-mongodb-community-edition

https://www.mongodb.com/docs/manual/replication/

https://www.mongodb.com/docs/manual/tutorial/deploy-replica-set/

https://www.mongodb.com/docs/manual/tutorial/deploy-replica-set-with-keyfile-access-control/#std-label-deploy-repl-set-with-auth