Kubernetes externaltrafficpolicy 简介

前言 最近在使用 Kubernetes 查看 pod 日志时,发现 pod 日志显示的 ip 不是真实的请求者 ip, 而是 Node 节点的 ip。通过查阅资料发现可以通过设置 externalTrafficPolicy 来显示真实的 IP。 本文对 externaltrafficpolicy 进行一个简单的介绍。 简介 ExternalTrafficPolicy 是 Kubernetes Service 对象的一个属性,它决定了流量如何从集群外部访问 Service。有两个可选值:Cluster 和 Local。 Cluster 模式: 在 Cluster 模式下,流量将通过负载均衡器分发到 Service 的所有 Pod 上。这是传统的负载均衡方式,适用于需要水平扩展和容错的场景。负载均衡器会将流量平均分配给所有可用的 Pod,从而实现负载均衡。 Local 模式: 在 Local 模式下,流量将直接访问与请求最近的节点上运行的 Pod。这种方式避免了负载均衡器的介入,直接将流量定向到本地的 Pod 上。这样可以减少延迟,并且在负载均衡器发生故障时仍然保持可用性。 区别 两种模式有什么区别呢? Cluster 模式 Cluster 模式是默认的模式,Kube-proxy 不管容器在哪个节点上,会公平的转发到某一个节点上,在转发时会替换掉源 ip,变成转发的上一个节点的 ip.原因是 Kube-proxy 在做转发的时候,会做一次 SNAT (source network address translation),所以源 ip 变成了上一个节点的 ip 地址。 这个模式的优点是负载均衡比较好,缺点是由于转发,可能会有性能损耗。 Local 模式 Local 模式下,请求只转发给本机的容器,不会转发给其它节点的容器,保留了源 ip。 ...

十二月 3, 2023 · 1 分钟 · overstarry

clarity 学习

前言 最近发现了一个新的工具-clarity, clarity 是一种免费工具,用于捕获用户使用网站。安装非常简单,可以在数分钟内开始获取数据。 clarity 有以下功能特点: 热点地图:为你的所有页面自动生成。查看用户点击的位置、他们忽略的内容以及滚动的距离。 insights: 快速发现用户在何处感到灰心,并将这些问题转化为机会。 Google Analytics: 可以方便的与 Google Analytics 关联。 会话录制:观看用户如何使用你的网站。了解运行顺畅的地方、需要改进的内容,并测试新想法。 copilot: 使用由 GPT 构建的直观对话体验来理解你的分析数据。 接下来就开始介绍 clarity 的简单使用。 clarity 使用 创建项目 登录成功后,可以选择网站或者移动项目,这里选择网站,输入相应的信息。 配置代码 填完信息,需要配置相应的代码信息,可以看到有 2 种方法,一种是知名第三方平台提供的快捷配置方法另一种是手动添加代码。这里选择手动添加代码。 配置信息 根据导览,可以配置一些信息,例如与 ga 关联,屏蔽一些隐私信息。 查看数据 根据导览的指引配置完信息后,第二天再次登录系统就可以看到数据了。可以看到有 4 个主要的模块栏目:仪表盘、录制、热度地图、ga,接下来分别介绍这 4 个部分。 仪表盘 仪表盘主要就是用户在你网站上访问的整体数据的展现。 录制 录制通过名字就可以得知这个是对用户在你页面上浏览情况的录制,可以看到用户的访问的整体情况,点击了哪些元素等。 热度地图 热度地图可以看到网站的哪些页面经常被访问,被访问的页面哪些部分经常被点击。 Google Analytics Google Analytics 主要就是 ga 的数据了。 ...

十一月 24, 2023 · 1 分钟 · overstarry

Postgresql CTE 表达式

前言 本文介绍如何使用 CTE 表达式来简化 PostgreSQL 中的一些复杂查询。那 CTE 表达式是什么呢? CTE 介绍 在 PostgreSql 中 WITH 提供了一种方式来书写在一个大型查询中使用的辅助语句。这些语句通常被称为公共表表达式或 CTE(Common Table Expressions),它们可以被看成是定义只在一个查询中存在的临时表。在 WITH 子句中的每一个辅助语句可以是一个 SELECT、INSERT、UPDATE 或 DELETE,并且 WITH 子句本身也可以被附加到一个主语句,主语句也可以是 SELECT、INSERT、UPDATE 或 DELETE。在 PostgreSQL 中,WITH 子句提供了一种编写辅助语句的方法,以便在复杂的查询中使用。 使用 该如何创建 CTE 呢,创建 CTE 的语句如下: WITH cte_name AS ( SELECT column1, column2, ... FROM table_name WHERE condition ... ) SELECT * FROM cte_name; 在日常查询中 CTE 用于哪些场景呢: 递归查询:CTE 表达式常用于执行递归查询。通过在 CTE 表达式中引用自身,可以简洁地实现递归操作。 复杂查询:CTE 表达式可以用于构建复杂的查询,将查询逻辑分解为更易于理解和维护的部分。每个 CTE 子查询块可以负责不同的逻辑操作,最终组合成一个完整的查询。 数据转换和重组:CTE 表达式可以用于对数据进行转换和重组。通过在不同的 CTE 子查询块中选择、过滤和连接数据,可以生成新的结果集。 递归查询 WITH 表达式如何实现递归查询呢,可以通过添加 RECURSIVE 修饰符来实现。下面是一个示例: ...

十一月 19, 2023 · 1 分钟 · overstarry

Go 设计模式 - 策略模式

今天介绍一个常见的设计模式 - 策略模式,并基于一个简单的例子来讲解。 策略模式介绍 策略模式(Strategy Pattern)是一种行为型设计模式,它将一组算法封装成独立的对象,并使它们可以互相替换。这样做的好处是,可以在运行时动态地改变对象的行为,而不需要修改使用该对象的代码。 何时可以使用策略模式呢 我们在用 GO 编程的时候经常碰到多层控制语句,一层又一层,既不优雅,也不利于后续维护。比如下述这种: if xxx { // do something } else if xxx { // do something } else if xxx { // do something else { } 虽然按这种模式写起来简单快捷,但它也违背了面向对象的两个原则: 单一职责原则:多个控制语句,意味着拥有多种功能; 开闭原则:当要进行修改时,原有代码不可避免要被修改; 此时就可以采用策略模式来替换这类多层控制语句。 go 实现策略模式 go 语言该怎么实现策略模式呢? 在 Go 语言中,策略模式可以通过接口和函数来实现。首先,我们定义一个接口,该接口声明了算法执行的方法。然后,我们可以为每个具体的算法实现一个结构体,并实现接口中的方法。最后,我们可以在需要使用算法的地方,通过接口来调用具体的算法。 下面通过一个简单的例子来讲解策略模式,现在有这样一个场景我们现在有 2 个数据表,这 2 个数据表拥有相同的字段,都可以根据 name 来查询某个数据,我们需要根据参数的不同来决定使用哪种表进行查询,在没有使用策略模式时,我们往往使用大量的 if 来实现这个操作。 接下来由我来介绍策略模式来实现相同的操作。 先定义查询操作的接口: type DataStrategy interface { Query(name string) } 定义 2 张表的查询 struct,并实现 DataStrategy 接口: // table1 通过 table1 来查询 type table1 struct{} func (s *table1) Query(name string) { fmt.Println("table1 query") } // table2 type table2 struct{} func (s *table2) Query(name string) { fmt.Println("table2 query") } 再定义 Data 对象用来执行不同的策略: ...

十一月 11, 2023 · 1 分钟 · overstarry

Go1.22 新循环语义

前言 前段时间看到了一个提案,是关于 go for 循环的一个提案,根据提案看到了去年 rsc 在社区发出的讨论,讨论的内容主要是为了解决 for 循环变量的问题,是什么样的问题呢,常见的例子如下: var all []*Item for _, item := range items { all = append(all, &item) } 这段代码有一个问题,循环结束后,all 的内容是包含了 len(all) 个相同的指针,指针指向迭代的最后一个 item。为什么会发生这种情况呢,因为 item 变量是每个循环的而不是每次迭代的,&item 每次迭代都是相同的,并且每次迭代都会被覆盖。 怎么解决呢,最简单的方法就是添加 item := item 这段代码: var all []*Item for _, item := range items { item := item all = append(all, &item) } 我在使用 Goroutine 协程时也经常遇到这种问题。这种错误已导致许多公司出现生产问题,包括 Lets Encrypt 公开记录的问题。 go 社区为了解决这个问题,打算将循环变量改为每次迭代,即隐式的添加上面的代码。由于其它一些原因,直到今年的 6 月才正式决定在 go 1.21 中添加 GOEXPERIMENT=loopvar 进行相应的尝试,并且将在 go1.22 版本中正式推出。 为了确保与现有代码的向后兼容性,新语义将仅适用于声明 go 1.22 或稍后在其 go.mod 文件中声明的模块中包含的包。 特性测试 我们通过不同版本运行的结果来对比 package main import "fmt" func main() { var prints []func() for _, v := range []int{1, 2, 3} { prints = append(prints, func() { fmt.Println(v) }) } for _, print := range prints { print() } } 没使用旧版本运行的结果是: ...

十一月 4, 2023 · 1 分钟 · overstarry

apisix 代理 gRPC 服务

最近需要使用 apisix 来代理 gRPC 服务,本文记录一下 apisix 代理 gRPC 服务以及实践过程中遇到的一些问题。 准备 在接下来的步骤前,我们需要准备一个 gRPC 服务,我们使用 kratos 简单启动一个 gRPC 服务: $ kratos new hellowrold $ cd helloworld $ kratos run 一个简单的 gRPC 服务就启动了,我们先直接请求 gRPC 服务看看,通过 postman 请求接口后,接口顺利返回相应的值。 接下来我们开始本篇的主要内容:apisix 代理服务。 apisix 代理 gRPC 服务 我们使用 apisix admin 接口创建 Route: upstream 的 scheme 指定为 grpc 或 grpcs,nodes 指定需要代理的服务地址。 curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "methods": ["POST", "GET"], "uri": "/helloworld.v1.Greeter/SayHello", "upstream": { "scheme": "grpc", "type": "roundrobin", "nodes": { "127.0.0.1:9001": 1 } } }' ...

十月 20, 2023 · 1 分钟 · overstarry

Go 漏洞管理工具 govulncheck

前言 在 7 月份 go 团队正式推出了官方的漏洞检测工具 - govulncheck, govulncheck 默认向 https://vuln.go.dev/ 漏洞数据库请求,对数据库的请求不包含代码只有使用的包,你也可以使用 -db 来指导所使用的漏洞数据库,所使用的数据库必须实现相应的规范。 govulncheck 具有以下限制: Govulncheck 在分析函数指针和接口调用时采用保守的方法,这可能导致一些情况下的误报或不准确的调用堆栈。 使用 reflect 进行的函数调用对于静态分析是不可见的。仅通过这些调用才能访问的易受攻击的代码将不会被报告。使用 unsafe 包可能导致漏报。 由于 Go 二进制文件不包含详细的调用信息,govulncheck 无法显示检测到的漏洞的调用图。对于二进制文件中但无法访问的代码,它可能还会报告误报。 目前还不支持 silencing 漏洞发现。请参阅 https://go.dev/issue/61211。 Govulncheck 只能读取使用 Go 1.18 及更高版本编译的二进制文件。 对于无法提取符号信息的二进制文件,govulncheck 会报告二进制文件所依赖的所有模块的漏洞。 govulncheck 架构图 govulncheck 还提供了一个可用的 API govulncheck,使开发者能够方便的将 govulncheck 集成到各种工具之中。 安装 通过以下命令安装 govulncheck: go install golang.org/x/vuln/cmd/govulncheck@latest 使用 安装完 govulncheck 后,我们就可以使用了,进入项目路径中,执行 govulncheck ./... 。 以下是我的一个项目的输出: Scanning your code and 508 packages across 71 dependent modules for known vulnerabilities... Vulnerability #1: GO-2023-2102 HTTP/2 rapid reset can cause excessive work in net/http More info: https://pkg.go.dev/vuln/GO-2023-2102 Standard library Found in: net/[email protected] Fixed in: net/[email protected] Example traces found: #1: cmd\xxx\main.go:94:19: xxx.main calls kratos.App.Run, which eventually calls http.Server.Serve #2: cmd\xxx\main.go:94:19: xxx.main calls kratos.App.Run, which eventually calls http.Server.ServeTLS Vulnerability #2: GO-2023-2043 Improper handling of special tags within script contexts in html/template More info: https://pkg.go.dev/vuln/GO-2023-2043 Standard library Found in: html/[email protected] Fixed in: html/[email protected] Example traces found: #1: cmd\xxx\main.go:94:19: xxx.main calls kratos.App.Run, which eventually calls template.Template.Execute #2: cmd\xxx\main.go:94:19: xxx.main calls kratos.App.Run, which eventually calls template.Template.ExecuteTemplate Vulnerability #3: GO-2023-2041 Improper handling of HTML-like comments in script contexts in html/template More info: https://pkg.go.dev/vuln/GO-2023-2041 Standard library Found in: html/[email protected] Fixed in: html/[email protected] Example traces found: #1: cmd\xxx\main.go:94:19: xxx.main calls kratos.App.Run, which eventually calls template.Template.Execute #2: cmd\xxx\main.go:94:19: xxx.main calls kratos.App.Run, which eventually calls template.Template.ExecuteTemplate === Informational === Found 3 vulnerabilities in packages that you import, but there are no call stacks leading to the use of these vulnerabilities. You may not need to take any action. See https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck for details. Vulnerability #1: GO-2023-2045 Memory exhaustion in QUIC connection handling in crypto/tls More info: https://pkg.go.dev/vuln/GO-2023-2045 Standard library Found in: crypto/[email protected] Fixed in: crypto/[email protected] Vulnerability #2: GO-2023-2044 Panic when processing post-handshake message on QUIC connections in crypto/tls More info: https://pkg.go.dev/vuln/GO-2023-2044 Standard library Found in: crypto/[email protected] Fixed in: crypto/[email protected] Vulnerability #3: GO-2023-1988 Improper rendering of text nodes in golang.org/x/net/html More info: https://pkg.go.dev/vuln/GO-2023-1988 Module: golang.org/x/net Found in: golang.org/x/[email protected] Fixed in: golang.org/x/[email protected] Your code is affected by 3 vulnerabilities from the Go standard library. Share feedback at https://go.dev/s/govulncheck-feedback. 输出内容分为 2 块,第一块是 Vulnerability 信息,是项目中存在的漏洞,可以看到发现了 3 个漏洞及具体的原因、触发函数、发现的版本和修复的版本。第二块是 Informational 是一些没有直接引用的包中存在的安全漏洞。 ...

十月 14, 2023 · 2 分钟 · overstarry

Go WSDL

最近在实现一个功能时需要使用第三方的接口,由于第三方只提供了一个 WSDL 文件的链接,于是研究了 golang 如何解析 WSDL 并调用相应接口,本文就是介绍 WSDL 和 go 如何解析并调用。 WSDL 介绍 WSDL 是 Web Services Description Language(Web 服务描述语言)的缩写。它是一种用于描述基于 Web 服务的通信协议和消息格式的 XML 格式语言。 WSDL 被广泛用于描述 Web 服务的接口和操作。它定义了 Web 服务所提供的功能、方法、参数、数据类型以及与服务进行交互的方式。通过 WSDL 文件,客户端应用程序可以了解如何与特定的 Web 服务进行通信。 WSDL 文件通常包含以下几个主要部分: 服务定义:描述了 Web 服务的名称、命名空间和位置。 类型定义:定义了 Web 服务中使用的数据类型,例如字符串、整数等。 消息定义:定义了 Web 服务中使用的消息格式,包括输入和输出消息。 操作定义:定义了 Web 服务的操作或方法,包括输入和输出消息以及相关的参数。 绑定定义:定义了 Web 服务使用的通信协议和消息格式,例如 SOAP(Simple Object Access Protocol)和 HTTP(Hypertext Transfer Protocol)。 服务定义:将服务、绑定和端口等部分组合在一起,定义了 Web 服务的完整描述。 使用 WSDL,开发人员可以生成客户端代码,使其能够与 Web 服务进行交互。客户端可以根据 WSDL 文件了解 Web 服务的结构和可用方法,以便正确地构造请求和解析响应。 总之,WSDL 是一种用于描述 Web 服务接口和操作的语言,它提供了一种标准化的方式来描述和访问 Web 服务。 ...

九月 23, 2023 · 1 分钟 · overstarry

Nginx Ingress http 请求 413 状态码问题及解决方法

问题 最近在调用一个上传文件的接口时,发现接口调用响应状态码为 413,并且控制台显示跨域错误信息。查找了相关信息,得知 413 状态码表示请求的包体过大导致的。 出现这种情况,我想到了 2 种解决方案:1) 调整上传文件的方式 2) 调整网关的参数。 综合目前的现况,采取了第二种方式调整网关客户端请求体最大值的参数。 解决 通过查阅 nginx ingress 的文档,得知可以添加 nginx.ingress.kubernetes.io/proxy-body-size 注解来设置请求体的最大值,设置 nginx.ingress.kubernetes.io/proxy-body-size 值为合适的值后,再请求接口发现接口顺利响应。 小结 本文介绍了客户端请求接口时,由于 nginx 默认 proxy-body-size 参数太小,导致请求 413 的问题及相应的解决方案。 参考 https://opendocs.alipay.com/support/01rb44 https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md#custom-max-body-size

九月 16, 2023 · 1 分钟 · overstarry

playwright-go 浏览器截图

以前的文章介绍了 chromedp 进行浏览器网页截图,这次介绍一种新的网页截图的方法——即使用 playwright 进行浏览器网页截图。 playwright 介绍 Playwright 是一个用于自动化浏览器操作的开源工具集。它由微软开发并于 2020 年发布,旨在提供一种跨浏览器、跨平台的解决方案,可用于测试 Web 应用程序、编写爬虫、执行自动化任务等。 Playwright 支持多种主流浏览器,包括 Chrome、Firefox、Safari 和 Edge,它提供了一组简单易用的 API,可以模拟用户与 Web 页面的交互行为,例如点击、填写表单、导航等。与其他类似工具相比,Playwright 的一个重要特点是它的跨浏览器支持,这意味着你可以使用相同的代码在不同浏览器上运行你的自动化任务,而不需要为每个浏览器单独编写代码。 Playwright 还提供了强大的调试功能,可以帮助开发人员在自动化过程中定位和解决问题。它支持截图和录制操作,使得调试变得更加直观和高效。 另外,Playwright 还具有一些高级功能,例如可以模拟不同的设备、网络环境和地理位置,以及支持并发执行多个浏览器实例等,这些功能使得它在编写复杂的自动化任务时非常有用。 由于我日常主要使用 go 语言进行开发,所以本文的内容主要以 playwright 的 go 模块 playwright-go 为主要介绍。 安装 go get -u github.com/playwright-community/playwright-go 安装相关浏览器和操作系统依赖项: go run github.com/playwright-community/playwright-go/cmd/playwright@latest install --with-deps # Or go install github.com/playwright-community/playwright-go/cmd/playwright@latest playwright install --with-deps 也可以在代码中使用以下代码安装:err := playwright.Install() 通过安装截图可以看出安装了 3 大主流浏览器和 ffmpeg。 例子 接下来我们看一个官方的例子,从 Hacker News 中抓取当前投票最高的项目。 package main import ( "fmt" "log" "github.com/playwright-community/playwright-go" ) func main() { pw, err := playwright.Run() if err != nil { log.Fatalf("could not start playwright: %v", err) } browser, err := pw.Chromium.Launch() if err != nil { log.Fatalf("could not launch browser: %v", err) } page, err := browser.NewPage() if err != nil { log.Fatalf("could not create page: %v", err) } if _, err = page.Goto("https://news.ycombinator.com"); err != nil { log.Fatalf("could not goto: %v", err) } entries, err := page.Locator(".athing").All() if err != nil { log.Fatalf("could not get entries: %v", err) } for i, entry := range entries { title, err := entry.Locator("td.title > span > a").TextContent() if err != nil { log.Fatalf("could not get text content: %v", err) } fmt.Printf("%d: %s\n", i+1, title) } if err = browser.Close(); err != nil { log.Fatalf("could not close browser: %v", err) } if err = pw.Stop(); err != nil { log.Fatalf("could not stop Playwright: %v", err) } } ...

九月 2, 2023 · 3 分钟 · overstarry