生命在于运动,技术在于折腾。
Argo CD 实践 GitOps
介绍 书接上文 OneDev 自建 Git 服务和 CI/CD,这次通过 ArgoCD 实现项目部署,项目编译、镜像构建依然通过 OneDev 流水线实现。当然用别的 Git 服务也是可以的。 Argo CD 被实现为一个 kubernetes 控制器,它持续监控正在运行的应用程序并将当前的活动状态与所需的目标状态(如 Git repo 中指定的)进行比较。Argo CD 报告和可视化差异,同时提供自动或手动将实时状态同步回所需目标状态的工具。 上次 git 仓库只有一个,这次 git 仓库分为两个 wx-msg-push 为项目代码 gitops 应用部署定义 整体流程为: wx-msg-push 正常开发提交 当创建 tag 推送时,触发 OneDev 流水线构建 检出 wx-msg-push 代码,在容器中编译可执行文件,生成多平台可执行文件压缩包制品 通过 kaniko 构建 wx-msg-push 项目镜像,推送至镜像仓库 检出 gitops 代码,修改 wx-msg-push 项目 yaml 文件的镜像版本后 push 在 argocd 中发现 gitops 配置变更 同步应用最新状态 安装部署 高可用配置请参考 High Availability $ kubectl create namespace argocd $ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml 安装之后默认会启用 TLS 验证和 http 强制跳转至 https。 我这里不需要,直接修改 argocd-server 配置 kubectl -n argocd edit deployments.apps argocd-server,增加运行 insecure 运行参数,取消该限制。 ...
OneDev 自建 Git 服务和 CI/CD
介绍 今天介绍一个可以自建的开源 Git 服务 OneDev, 功能强大,资源占用少,国人 Java 开发。 开箱即用的符号跳转、符号搜索 全功能的 CI/CD,支持 GUI 强大易用的 Commit/Issue/Build/Pull Request 查询语言 代码标注和讨论 更多功能特性看官网说明 目前不足是全英文,文档简洁,还不知道什么时候支持中文,也不算什么大事。另外小 Bug 多,不过作者修复神速。 部署安装 运行环境 k8s v1.21.5,容器运行时 containerd。 安装方式直接参考官方文档 helm 装就完事,除了在 k8s 运行也可以直接 docker run 和裸机跑。 helm 安装完成会创建一个 onedev 的 service type 是 LoadBalancer,由于我使用 apisix ingress 所以直接改成 ClusterIP 然后外面再套负载均衡走流量。细节不展开了可以参考实践 Apache APISIX Ingress。 符号跳转、搜索 支持 Java, JavaScript, C, C++, CSharp, Go, PHP, Python, CSS, SCSS, LESS and R 语言,IDE 级别的功能。 据作者说使用 ANTLR 分析主流语言的语法,并提取符号定义进行增量存储,速度快,占用空间小。 ...
实践 Apache APISIX Ingress
介绍 Apache APISIX 是一个动态、实时、高性能的 API 网关。基于 Nginx 和 Etcd 实现。 作为 API 网关,APISIX 提供了灵活插件机制、动态上游、动态路由、灰度发布、熔断限流、身份认证、可观测性、Serverless、Wasm等功能。可以处理L4、L7层的流量支持HTTP、HTTPS、TCP、UDP、MQTT、gRPC等协议。 安装部署 在 kubesphere 中创建一个 Workspace,添加 APISIX Helm Chart 仓库 https://charts.apiseven.com/。 然后新建一个 ingress-apisix 的 projects,也就是 namespace。在该 project 下创建一个 apisix App,选择刚才添加的仓库。创建 apisix 会同时创建 APISIX Gateway + Dashboard + Ingress Controller。 版本选择 0.10.0 [2.14.1] 我最终的配置: global: imagePullSecrets: [] apisix: enabled: true enableIPv6: true setIDFromPodUID: false customLuaSharedDicts: [] luaModuleHook: enabled: false luaPath: '' hookPoint: '' configMapRef: name: '' mounts: - key: '' path: '' enableCustomizedConfig: false customizedConfig: {} image: repository: apache/apisix pullPolicy: IfNotPresent tag: 2.14.1-alpine kind: Deployment replicaCount: 1 podAnnotations: {} podSecurityContext: {} securityContext: {} podDisruptionBudget: enabled: false minAvailable: 90% maxUnavailable: 1 resources: {} nodeSelector: {} tolerations: [] affinity: {} podAntiAffinity: enabled: false timezone: Asia/Shanghai extraEnvVars: [] nameOverride: '' fullnameOverride: '' gateway: type: NodePort externalTrafficPolicy: Cluster externalIPs: [] http: enabled: true servicePort: 80 containerPort: 9080 tls: enabled: false servicePort: 443 containerPort: 9443 existingCASecret: '' certCAFilename: '' http2: enabled: true stream: enabled: false only: false tcp: [] udp: [] ingress: enabled: false annotations: {} hosts: - host: apisix.local paths: [] tls: [] admin: enabled: true type: ClusterIP externalIPs: [] port: 9180 servicePort: 9180 cors: true credentials: admin: edd1c9f034335f136f87ad84b625c8f1 viewer: 4054f7cf07e344346cd3f287985e76a2 allow: ipList: - 0.0.0.0/0 plugins: - api-breaker - authz-keycloak - basic-auth - batch-requests - consumer-restriction - cors - echo - fault-injection - grpc-transcode - hmac-auth - http-logger - ip-restriction - ua-restriction - jwt-auth - kafka-logger - key-auth - limit-conn - limit-count - limit-req - node-status - openid-connect - authz-casbin - prometheus - proxy-cache - proxy-mirror - proxy-rewrite - redirect - referer-restriction - request-id - request-validation - response-rewrite - serverless-post-function - serverless-pre-function - sls-logger - syslog - tcp-logger - udp-logger - uri-blocker - wolf-rbac - zipkin - traffic-split - gzip - real-ip - ext-plugin-pre-req - ext-plugin-post-req - server-info stream_plugins: - mqtt-proxy - ip-restriction - limit-conn pluginAttrs: {} extPlugin: enabled: false cmd: - /path/to/apisix-plugin-runner/runner - run customPlugins: enabled: true luaPath: /opts/custom_plugins/?.lua plugins: - name: prometheus attrs: export_addr: ip: 0.0.0.0 port: 9091 configMap: name: prometheus mounts: [] updateStrategy: {} extraVolumes: [] extraVolumeMounts: [] discovery: enabled: false registry: null logs: enableAccessLog: true accessLog: /dev/stdout accessLogFormat: >- $remote_addr - $remote_user [$time_local] $http_host \"$request\" $status $body_bytes_sent $request_time \"$http_referer\" \"$http_user_agent\" $upstream_addr $upstream_status $upstream_response_time \"$upstream_scheme://$upstream_host$upstream_uri\" accessLogFormatEscape: default errorLog: /dev/stderr errorLogLevel: warn dns: resolvers: - 127.0.0.1 - 172.20.0.10 - 114.114.114.114 - 223.5.5.5 - 1.1.1.1 - 8.8.8.8 validity: 30 timeout: 5 initContainer: image: busybox tag: 1.28 autoscaling: enabled: false minReplicas: 1 maxReplicas: 100 targetCPUUtilizationPercentage: 80 targetMemoryUtilizationPercentage: 80 configurationSnippet: main: '' httpStart: '' httpEnd: '' httpSrv: '' httpAdmin: '' stream: '' serviceMonitor: enabled: false namespace: '' name: '' interval: 15s path: /apisix/prometheus/metrics metricPrefix: apisix_ containerPort: 9091 labels: {} annotations: {} etcd: enabled: true host: - 'http://etcd.host:2379' prefix: /apisix timeout: 30 auth: rbac: create: false user: '' password: '' tls: enabled: false existingSecret: '' certFilename: '' certKeyFilename: '' verify: true sni: '' service: port: 2379 replicaCount: 3 dashboard: enabled: true service: type: NodePort ingress-controller: enabled: true config: apisix: serviceNamespace: ingress-apisix serviceMonitor: enabled: true namespace: ingress-apisix interval: 15s 慢慢等待相关镜像下载运行完成。找到 apisix-dashboard Service 的 Node port 在浏览器中打开进入 dashboard,默认用户名、密码都是 admin。 ...
KubeSphere k8s 集群管理
介绍 KubeSphere 是一个 k8s 集群管理平台,可以管理多云多集群,进行统一的应用分发和运维管理,避免云厂商绑定。提供了运维友好的操作界面,支持多租户,DevOps,服务网格,多种监控纬度。 目前稳定版是 KubeSphere v3.2.1,我之前装的 k8s 集群是 v1.22.7,KubeSphere 目前对 v1.22 是实验性支持,为了避免踩坑先把 k8s 集群重装了 v1.21.5。 安装使用 KubeSphere 的安装步骤就省略了,直接按官网的走就可以。记得要给 k8s 配默认 StorageClass,生产环境建议直接上云存储或者 rook+ceph,我为了节省资源直接就用 NFS 了。 NFS 安装配置参考: How to Install and Configure an NFS Server on Ubuntu 20.04 How To Set Up an NFS Mount on Ubuntu 20.04 KubeSphere 安装: 在 Kubernetes 上安装 KubeSphere 安装完成后随便找个节点访问 30880 端口进入 dashboard。 登录之后进入 defult 集群,在配置多集群前只有这一个。默认展示当前集群资源用量。 界面可以切换中文显示。Projects 等同于 k8s 中的 namespace 概念,Projects 之上还有一层 workspace,用于多租户资源、计费隔离,当然也有用户权限管理。 Nodes 可以看到集群节点状态 ...
Ubuntu 20.04 下部署 k8s v1.22.7 集群
介绍 虽然是一篇 k8s 的部署文,但也充满了曲折。归其原因也是基础一般。 本文并未涉及 k8s 多主高可用,可参考其它文章通过 ipvs 来实现。 首先通过上次的文章组网 通过 Netmaker 配置 WireGuard 跨 VPC 组网,组网完成部署 k8s、k3s 都可以,我这三台小弱鸡更适合 k3s。 hostname 外网ip 内网ip wg ip os ten-1 62.234.xxx.xxx 172.21.0.1 10.1.0.1 Ubuntu 20.04 ten-2 82.156.xxx.xxx 10.0.8.1 10.1.0.2 Ubuntu 20.04 ten-3 81.70.xxx.xxx 10.0.24.1 10.1.0.3 Ubuntu 20.04 先说下为何换到了 Ubuntu,之前在 CentOS 7.6 下已经组网完成且部署完 k8s ,使用中发现容器经常报这个错 failed to write 1 to memory.kmem.limit_in_bytes xxxx memory.kmem.limit_in_bytes: operation not supported,内存指令相关错误。 尝试将容器内存资源限制删除,该错误可消失恢复正常。 这也不是长久之计,网上参考别人经验,我当时内核为 5.16,可以降级内核解决,但是我要用 WireGuard 低版本内核就使不了。 索性换了系统算了,且 Ubuntu 20.04 的 5.4 内核已经包含了 WireGuard,而且也没见人说 Debian 系有 memory.kmem.limit_in_bytes 的问题。 ...
通过 Netmaker 配置 WireGuard 跨 VPC 组网
介绍 最近云服务商做活动,手里云主机又多了一个,国内的有三台了,可以组个 k8s 集群了。本文介绍如何跨 VPC 组网,机器情况如下。 hostname 外网ip 内网ip os ten-1 62.234.xxx.xxx 172.21.0.1 CentOS 7.6 ten-2 82.156.xxx.xxx 10.0.8.1 CentOS 7.9 ten-3 81.70.xxx.xxx 10.0.24.1 CentOS 7.6 MacBook - - Darwin 10.15.6 WireGuard 是由 C 语言写的开源 VPN 方案。概括来讲更快、更简单、更安全,Linux 内核 5.6 版本开始自带。且支持全平台。 Netmaker 是一个可视化操作工具,方便我们对 WrireGuard 的配置管理,相比于直接写配置,当节点多起来会便捷不少。 简单说下运行流程,Netmaker 分服务端和客户端,客户端是 netclient。我们在 Netmaker 上创建虚拟网络,然后在想要加入网络的节点上通过 netclient 加入。Netmaker 会对加入网络的节点自动同步 WireGuard 的配置信息,创建相应的路由规则,之后节点与节点之间的通信直接进行。 本文只是介绍了一部分 Netmaker 功能,更多内容请看 Netmaker 官方文档。 为了方便 CentOS 内核都已升级至 5.16,自带了 WireGuard。升级内核教程很多就不多说了。 Netmaker 部署 在 ten-1 上先创建所需目录 $ mkdir -p /etc/netclient/config $ mkdir -p /data/netmaker 直接容器化部署,compose yml 如下: ...
关于学习和记忆的原理《考试脑科学》
近期阅读了《考试脑科学:脑科学中的高效记忆法》做个笔记。该书前面讲解了人脑记忆的原理,海马体、杏仁核、θ波等。后面讲解了记忆的种类,人处于什么状态记忆力更好等等。 《高中生学习法》出版已有十余年。这期间,脑科学研究不断进步,十几年前无法解释的事情现在已 经开始逐渐明晰。同时,书中有些内容甚至已经被明确证实是错误的。也就是说,《高中生学习法》 这本书,仅十余年就已落后于时代了。 需要说明的是《考试脑科学》是《高中生学习法》(出版于2002年)的修订版。《考试脑科学》原书于2011年出版,中文翻译版于2019年出版。现在2022年已经又过去十年了,不知道脑科学进步没。 ◆ 2-4 蛮干终究是徒劳 潜在记忆的保存时间只有 1 个月左右,如果不在 1个月以内复习学到的知识,潜在记忆就无法发挥作用了。 意思是一个月之后再去复习和学习新知识没有什么区别 在复习时也要像初次学习那样用功,不仅要用眼看,还要动笔写、出声读,尽可能地调动自己的感官。这样一来,通过视觉、听觉、触觉等传达的信息都会对刺激海马体起到积极作用。 刺激方面越多对知识的记忆越深刻 结合海马体的性质,我建议大家按照如下计划展开复习。第 1 次复习:学习后的第 2 天第 2 次复习:第 1 次复习 1 周后第 3 次复习:第 2 次复习 2 周后第 4 次复习:第 3 次复习 1 个月后 ◆ 3-2 童心是提高成绩的“营养素” 畅销书作家韦恩·戴尔 5 曾这样说:“一个人在早上醒来后,首先想到的是‘很好,新的一天开始了’,还是‘哎,怎么又要起床了’,完全取决于他的心态。”确实如此。学习也和心情有关,我们要像孩子一样,无论在何时都应该保持一颗易受感动的心。包含好奇心和憧憬心的“童心”,正是促使θ波出现的重要因素。 大家上学时应该都有过的经历,感兴趣的科目学起来很快,没兴趣的怎么学也不会。这里可以说是做了解释,当你对知识好奇、感兴趣时会出现 θ脑电波,θ波的出现有对记忆力增强的效果,可以事半功倍。 ◆ 3-5 狮子记忆法 通过狮子记忆法,我们可以推测出饥饿、走动和降低室温这 3 种能提高记忆力的技巧。 如果要解释得稍微专业一些,那就是当肚子饿的时候我们的胃会分泌一种名为食欲刺激激素 (ghrelin)的饥饿激素。这种饥饿激素能随血液循环进入海马体,促使海马体神经元产生LTP。相反,在吃饱后不仅饥饿激素的水平会降低,而且血液还会相对集中于胃部和肠道,这往往会导致脑 的活动水平降低。 来回走动及坐车或脑能感知到正在移动时会自动产生θ波。 ◆ 4-3 睡眠和记忆 在睡觉前把题目过一遍也是一种很重要的学习技巧。 ◆ 4-6 能有效利用全天时间的学习方案 饭前处于饥饿状态,正适合学习。睡觉前也是学习的黄金期。早饭或晚饭后处于饱腹状态时,不学习也不要紧。 睡觉前非常适合学习那些需要记忆的知识,比如数据库原理、调度器原理;上午可以说是人在一天之中最清醒的时间,用来学习对逻辑思维能力要求比较高的比如刷题;最后,因为在早上刚起床的这段时间内不适合背诵,所以只要做一些简单的计算或者复习就可以了。 做了些修改替换,哈哈。 ◆ 5-2 面对失败,毫不气馁的积极态度最重要 每次经历失败后,我们都应该思考下一次要怎么做才能成功。如果还是失败了,就再次思考其他解决方案……像这样不断循环下去。失败的次数越多,就越能形成准确牢固的记忆。即使偶尔取得了几次不错的成绩,对于大家来说其实也并没有什么实质性的收获。所以,即使考试成绩不理想也没必要闷闷不乐,大家可以转换思维,把它当作一件好事而非坏事。失败后最重要的是带着疑问找出失败原因,并想出解决方案 ...