Fsck

起因 在一次使用虚拟机的时候,发现 Linux 系统进入了 Initramfs,无法正常进入系统,推测可能是系统异常关机导致磁盘文件损坏导致的。 解决 网上搜寻了一些解决方法,普遍的推荐方法是使用 Linux 命令 fsck 命令来修复磁盘文件。 费了好大劲进入另一个系统使用 fsck.ext4 -f /dev/sda1 来检查修复磁盘文件 (我所使用的 linux 系统磁盘是 ext4 格式的)。 接下来我来介绍下 fsck 的使用。 fsck fsck(file system consistency check)是 Unix 和类 Unix 系统上用于检查文件系统完整性的工具。 语法:fsck [选项] [文件系统] 常见参数: -f 强制检查文件系统,不管是否有损坏 -p 自动修复文件系统错误 -q 做一个快速检查,以确定文件系统是否被干净地卸载。 -y 关闭互动模式,询问全部选择 y 参考 https://web.archive.org/web/20150529001726/http://www.manpagez.com/man/8/fsck/ https://zh.wikipedia.org/zh-hans/Fsck https://zh.wikipedia.org/wiki/Unix%E5%AE%9E%E7%94%A8%E7%A8%8B%E5%BA%8F%E5%88%97%E8%A1%A8

二月 19, 2022 · overstarry

GRPC 单向安全连接

从本篇开始,我将介绍加强 gRPC 的安全性的一系列措施。本篇介绍使用 TLS 加密 gRPC 通信的第一篇文章:gRPC 单向安全连接。 TLS 协议介绍 传输层安全性协议(英语:Transport Layer Security,缩写作 TLS),及其前身安全套接层(Secure Sockets Layer,缩写作 SSL)是一种安全协议,目的是为互联网通信提供安全及数据完整性保障。网景公司(Netscape)在 1994 年推出首版网页浏览器,网景导航者时,推出 HTTPS 协议,以 SSL 进行加密,这是 SSL 的起源。IETF 将 SSL 进行标准化,1999 年公布第一版 TLS 标准文件。随后又公布 RFC 5246(2008 年 8 月)与 RFC 6176(2011 年 3 月)。在浏览器、邮箱、即时通信、VoIP、网络传真等应用程序中,广泛支持这个协议。主要的网站,如 Google、Facebook 等也以这个协议来创建安全连线,发送数据。目前已成为互联网上保密通信的工业标准。 SSL 包含记录层(Record Layer)和传输层,记录层协议确定传输层数据的封装格式。传输层安全协议使用 X.509 认证,之后利用非对称加密演算来对通信方做身份认证,之后交换对称密钥作为会谈密钥(Session key)。这个会谈密钥是用来将通信两方交换的数据做加密,保证两个应用间通信的保密性和可靠性,使客户与服务器应用之间的通信不被攻击者窃听。 单向安全连接 通过安全的连接进行传输数据非常重要,那么如何在 gRPC 中使用 TLS 保护 gRPC 通信呢?TLS 认证机制集成在了 gRPC 库中,这使得 gRPC 可以很方便使用 TLS 进行安全连接。 客户端和服务端之间的安全传输可以采用单向或双向的方式来实现。本文主要介绍 单向安全连接。 在单向安全连接中,只有客户端会校验服务端,以确保它所接收的数据来自预期的服务器,在建立连接时,服务端会与客户端共享其公开证书,客户端会校验收到的证书。这是通过证书授权中心完成的。证书校验完成后,客户端会使用密钥加密数据。 要启用 TLS,需要证书和密钥 (xx.key,xx.pem/xx.crt),前者是用于签名和扔着公钥,后者用于分发自签名 X.509 公钥。证书和密钥的生成这里就不过多介绍了,需要的可以自行了解。 ...

二月 12, 2022 · overstarry

Log_and_trace

本篇文章讲述了如何将 loki 和 tempo 结合进行分布式追踪。日志和 trace 结合使用的方案有很多,由于 loki 官方自带了 trace 结合的配置,不用进行过多的二次开发,所以这里采用 loki 和 tempo 结合的方案。 loki 和 tempo 是什么就不过多介绍,安装流程也省略。这里主要讲如何配置。 配置 这里我们采用普遍的方案,使用 grafana 来展示日志和 trace。 配置 loki 在 grafana , 打开数据源配置界面,新建 loki 数据源,并且配置好地址,如下图所示点击 Save & Test, 如果配置正确,则会出现 Data source connected and labels found. 标志。 配置 tempo 同配置 loki 一致,新建 grafana 数据源,选择 tempo,配置好相应的 url 数据,点击测试,出现 Data source connected and labels found. 标志,就表示配置成功。 在 tempo 配置页面的底部可以看到一个配置栏目 Trace to logs,可以选择相应的日志数据源,这里我们选择 loki. ...

一月 27, 2022 · overstarry

K8s_Finalizers

起因 在我们日常使用 k8s 中,可能会遇到这样的情况:在删除 namespace 时,往往会遇到资源没有被删除的情况,资源处于 terminating 的状态,这时我们该如何解决了,寻找到的解决方法往往是如下: 1 运行以下命令查看处于 terminating 状态的资源 (这里以 namespace 为例): kubectl get namespaces 2 选择一个 Terminating namespace,并查看 namespace 中的 finalizer。运行以下命令: kubectl get namespace <terminating-namespace> -o yaml 得到类似这样的信息: apiVersion: v1 kind: Namespace metadata: creationTimestamp: "2021-01-20T15:18:06Z" deletionTimestamp: "2021-01-21T02:50:02Z" name: <terminating-namespace> resourceVersion: "3249493" selfLink: /api/v1/namespaces/knative-eventing uid: f300ea38-c8c2-4653-b432-b66103e412db spec: finalizers: - kubernetes status: phase: Terminating 3 导出 json 格式到 tmp.json: ...

一月 23, 2022 · overstarry

Casbin 学习 1

从本篇文章开始,将由我来开始介绍访问控制框架的基础知识,本篇文章是 casbin 系列文章的第一篇,主要介绍一些 casbin 的概念和基础知识。 概述 casbin 是一个开源的访问控制框架,它的目标是让开发人员可以更加简单的控制访问控制,支持多种访问控制模型,支持多种编程语言 (各种编程语言支持的程度可以查看官网的文档)。 casbin 可以 支持自定义请求的格式,默认的请求格式为{subject, object, action}。 具有访问控制模型 model 和策略 policy 两个核心概念。 支持 RBAC 中的多层角色继承,不止主体可以有角色,资源也可以具有角色。 支持内置的超级用户 例如:root 或 administrator。超级用户可以执行任何操作而无需显式的权限声明。 支持多种内置的操作符,如 keyMatch,方便对路径式的资源进行管理,如 /foo/bar 可以映射到 /foo* Casbin 不支持的是: 身份认证 authentication(即验证用户的用户名和密码),Casbin 只负责访问控制。应该有其他专门的组件负责身份认证,然后由 Casbin 进行访问控制,二者是相互配合的关系。 管理用户列表或角色列表。Casbin 认为由项目自身来管理用户、角色列表更为合适,用户通常有他们的密码,但是 Casbin 的设计思想并不是把它作为一个存储密码的容器。而是存储 RBAC 方案中用户和角色之间的映射关系。 工作原理 在 Casbin 中,访问控制模型被抽象为基于 PERM (Policy, Effect, Request, Matcher) 的一个文件。因此,切换或升级项目的授权机制与修改配置一样简单。您可以通过组合可用的模型来定制您自己的访问控制模型。例如,您可以在一个 model 中结合 RBAC 角色和 ABAC 属性,并共享一组 policy 规则。 adapters 在 Casbin 中,策略存储作为 adapter(Casbin 的中间件) 实现。Casbin 用户可以使用 adapter 从存储中加载策略规则 (aka LoadPolicy()) 或者将策略规则保存到其中 (aka SavePolicy())。为了保持代码轻量级,我们没有把 adapter 代码放在主库中。 ...

一月 12, 2022 · overstarry

Go 如何使用私有仓库模块

今天我来讲一讲在 golang 中如何在项目中引用私有仓库吧,在我们的实际生产开发中,往往需要在项目中引用内部代码管理平台上的仓库代码,接下来我来介绍如何在 golang 中使用私有仓库模块。 设置 1 我们的私有代码往往存储在内部的代码管理平台 (如 gitlab, gittee 等) 上,假设我们的地址是 git.xx.vip. 接下来开始设置一些配置项。 2 设置 GOPRIVATE 变量。 我们先设置 GOPRIVATE 环境变量,GOPRIVATE 会将 GOPRIVATE 变量值所匹配的路径前缀视为私有模块,就不会使用代理和进行校验。设置了 GOPRIVATE 变量后,GONOPROXY 和 GONOSUMDB 环境变量 也会接收同样的值。 3 设置 GOINSECURE 变量 我们的 gitlab 等代码管理平台往往没有使用 https 协议,所以我们需要设置 GOINSECURE 变量,GOINSECURE 变量中的值以逗号分隔,其中的每一个值在 go get 时 不会进行 https 协议的校验,只会采用 http 协议。 4 go get 设置完以上步骤后,可以执行 go get 看看效果,具体命令: go get -v git.xx.vip/swords/xkratos 可以看到相应的库已经顺利拉取成功,并且输出了相应的版本信息 参考 https://go.dev/ref/mod https://go.zhangdeman.cn/archives/62430e03.html https://forum.golangbridge.org/t/using-go-get-to-retrieve-modules-packages-from-a-private-server/17896/6 https://github.com/GoogleCloudPlatform/govanityurls

一月 12, 2022 · overstarry

GRPC 多路复用

今天来讲一讲 gRPC 的多路复用,gRPC 的多路复用是指 一个 gRPC 服务器端可以运行多个 gRPC 服务,也允许多个客户端存根使用同一个 gRPC 客户端连接。 我们继续沿用前面的代码来讲解如何使用多路复用。 多个 gRPC 服务共享同一个服务器端 假如在订单服务中,为了管理的需求,需要在同一个服务端运行另一个 RPC 服务,这样客户端就能重用同一个连接,这样就可以按需调用相应的服务。通过相应的服务器端注册函数,可以使多个服务注册在同一个服务器端。 具体代码如下: func main() { initSampleData() lis, err := net.Listen("tcp", port) if err != nil { log.Fatalf("failed to isten: %v", err) } s := grpc.NewServer(grpc.UnaryInterceptor(orderUnaryServerInterceptor)) ordermgt_pb.RegisterOrderManagementServer(s, &orderMgtServer{}) user_pb.RegisterUserManagementServer(s, &userMgtServer{}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } } 这样就是多个 gRPC 服务共享同一个服务端连接,这样就可以按需调用相应的服务。同理,通过客户端,可以在两个 gRPC 客户端存根间共享相同的 gRPC 客户端连接。 两个 gRPC 客户端存根共享同一个客户端连接 如代码所示,两个 gRPC 服务在同一个 gRPC 服务器端运行,所以可以创建一个 gRPC 连接,并在两个服务创建 gRPC 客户端实例时使用这个连接。 func main() { conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() client := pb.NewOrderManagementClient(conn) ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() heclien := hwpb.NewGreetingClient(conn) } 小结 在我们的日常使用中,通常不会出现两个服务间共享同一个服务器端连接的情况。 ...

一月 9, 2022 · overstarry

Trace_in_sql

使用分布式链路追踪查看 sql 的执行情况 今天我们来讲一讲如何在 go 语言中使用 OpenTelemetry 链路追踪追踪 sql 的执行情况 (执行时间、语句等)。 初始化 我们这里需要有一个采用了数据库的项目,为了使用方便,我们这里采用了 ent 来进行数据库的操作。 初始化数据库实体 为了演示方便,我们这里简单定义一个 user 实体,user 有 2 个成员字段 id 和 name。 $ ent init User package schema import ( "entgo.io/ent" "entgo.io/ent/schema/field" ) // User holds the schema definition for the User entity. type User struct { ent.Schema } // Fields of the User. func (User) Fields() []ent.Field { return []ent.Field{ field.Int("id"), field.String("name"), } } // Edges of the User. func (User) Edges() []ent.Edge { return nil } 执行 go run -mod=mod entgo.io/ent/cmd/ent generate ./schema,就会生成一系列的文件。 ...

十二月 31, 2021 · overstarry

GRPC 元数据

今天我来讲一讲 gRPC 元数据的使用,以及如何获取元数据。gRPC 应用程序通常会通过 gRPC 服务和消费者之间的 RPC 来共享信息。在大多数场景中,某些与服务端业务逻辑相关的信息会作为远程调用方法的参数,但在某些场景可能存在与服务端业务上下文无关的数据,这些数据不应该通过参数来传递,而应该通过 gRPC 元数据来处理传递。元数据的结构构造是 K-V 形式,其中 k 为字符串,v 为任意类型。 接下来就介绍如何在 客户端和服务端之间使用元数据来传递数据。 创建和查询元数据 在 gRPC 应用程序中,创建元数据非常简单,在 go 语言中有两种方式创建元数据:1) 通过 metadata.New(map[string]string{“key1”:“val1”}) 函数创建;2) 通过 metadata.Pairs 来创建元数据对,相同的 key 会被合并为切片数组。 md := metadata.New(map[string]string{"foo": "bar"}) md := metadata.Pairs( "key1", "value1", "key2", "value2", ) 二进制数据也可以设置为元数据值,以元数据值形式所设置的二进制数据在发送前都会进行 base4 编码,在传输过程中会被解码。 在客户端或服务端读取元数据,可以通过传入的 RPC 上下文和 metadata.FromIncomingContext 函数来获取元数据。 md, metadataAvailble := metadata.FromIncomingContext(ctx) 接下来讲解客户端和服务端如何发送和接受元数据。 客户端发送接收元数据 在客户端,要发送元数据,可以创建元数据并将其设置到 RPC 上下文中。在 go 语言中有两种方式实现,可以使用 NewOutgoingContext 函数创建,也可以使用 AppendToOutgoingContext 函数来将元数据附加到 RPC 上下文中,使用 NewOutgoingContext 会替换掉上下文中已有的元数据。在创建完带有元数据的上下文后,就可以用于 RPC 中了。在上下文中设置的元数据会转换成 header 信息。 // 客户端发送元数据 // ****** Metadata : Creation ***** md := metadata.Pairs( "timestamp", time.Now().Format(time.StampNano), "kn", "vn", ) mdCtx := metadata.NewOutgoingContext(context.Background(), md) ctxA := metadata.AppendToOutgoingContext(mdCtx, "k1", "v1", "k1", "v2", "k2", "v3") // Search Order searchStream, _ := client.SearchOrders(ctxA, &wrapper.StringValue{Value: "Google"}) for { searchOrder, err := searchStream.Recv() if err == io.EOF { log.Print("EOF") break } if err == nil { log.Print("Search Result : ", searchOrder) } } // 在 gRPC 中接受元数据 var header,trailer metadata.MD r,err := client.SomeRPC( ctx, someReq, grpc.Header(&header), grpc.Trailer(trailer), ) stream, err := client.SomeStreamingRPC(ctx) header, err := stream.Header() trailer := stream.Trailer() 从对应的 RPC 获取到值时,就可以像处理 map 一样进行,对元数据进行相应处理。 ...

十二月 25, 2021 · overstarry

Golang 多版本共存

为什么要使用多个 go 版本 在我们的日常项目开发中,我们可能会使用多个不同的版本的 go 语言,来进行应用的测试,因为不同的版本有着不同的性能优化,可以通过对不同版本情况的测试,选择线上使用的版本。 如何安装多个 go 版本 可能会有人说,可以通过多个不同的 go 安装包来安装,这种方法是可行的,但 go 官方提供了另一种方法来方便安装。 1 使用 go install 命令安装相应版本的 go , 例如: go install golang.org/dl/go1.18.0beta1@latest 2 使用相应命令下载,例如我前面安装的是 go1.18.0beta1,那就使用 go1.18.0beta1 download 下载。 3 下载完毕可以使用对应的版本测试,例如:go1.18.0beta1 version 参考 https://go.dev/doc/manage-install

十二月 18, 2021 · overstarry