March 31, 2022
用 Goalng 开发 OPA 策略
Open Policy Agent 简称OPA是一个开源的通用策略引擎,可在整个堆栈中实现统一的、上下文感知的策略实施。OPA 已经成为了云原生计算基金会 ( CNCF) 领域的毕业项目,已经在 Kubernetes / Istio 等多个知名项目里使用 。
OPA的核心思想就是策略即代码。
它使用Rego语言开发,Rego 的灵感来自 Datalog,它是一种易于理解、已有数十年的历史的查询语言。Rego 扩展了 Datalog 以支持 JSON 等文档模型。对于它的详细介绍请参考官方文档 ,这里不再介绍,本方主要介绍如何使用Golang 来开发一个opa策略。
概述 OPA 将 策略决策 与 策略执行 分离,当您的软件需要做出策略决策时,它会查询 OPA 并提供结构化数据(例如 JSON)作为输入。 OPA 接受任意结构化数据作为输入。
对于它的输入一般称为 input, 可以为任意类型,输出也一样可以为任意类型,即可以输出布尔值 true 或 false,也可以输出一个 JSON 字符串对象。
示例 我们先从官方提供的一个 playground 开始,它是一个官方提供的在线执行平台。
从界面我们可以看出,窗口主要分四块:
左侧是 Policy窗口,即上方图的黄色部分 右上方的为用户提供数据的input 窗口,也可以直接省略不写,大部分情况下为 JSON 或 YAML 数据格式 右中间窗口为 Data ,提供数据源部分,一般是一个对接持久化数据库的存储层接口。有时规则里有一些数据需要从数据库里查询提取,如根据 input.user_id 查询出来用户的入职时间,然后在规则里根据这个入职时间进行一些逻辑判断之类。 右下方则为评估结果输出区域,在 playground 这种方式中会将全部信息都输出给我们,没有办法指定查询指定的字段值,官方提示的示例中输出为布尔值。 下面我们重点只介绍下 Policy,它才是我们本节关注的重点。
Policy Rego 策略是使用一组相对较小的类型定义的:Module、Package和Imports、Rule、Expr和Term。从本质上讲,策略由Rule 组成,这些 Rule 由一个或多个Expr对策略引擎可用的文档进行定义Expr由内在值(Term)定义,例如字符串、对象、变量等。源码在 。
February 25, 2022
一文看懂Golang 定时器源码
计时器分 Timer 和 Ticker 两种,它们底层基本是一样的,两差的区别请参考 , 这里我们的介绍对象是 Timer 。golang timer
计时器结构体 // NewTimer creates a new Timer that will send // the current time on its channel after at least duration d. func NewTimer(d Duration) *Timer { c := make(chan Time, 1) t := &Timer{ C: c, r: runtimeTimer{ when: when(d), f: sendTime, arg: c, }, } startTimer(&t.r) return t } 通过调用 NewTimer() 函数创建一个 Timer,首先创建一个长度为1的有缓冲channel,再创建一个Timer的结构体,并将 channel 置于 Timer 结构体内。
注意这里的 runtimeTimer.
January 8, 2022
了解eBPF技术
eBPF 的全称“扩展的伯克利数据包过滤器 (Extended Berkeley Packet Filter)” 来看,它是一种数据包过滤技术,是从 BPF (Berkeley Packet Filter) 技术扩展而来的。
BPF 提供了一种在 内核事件 和 用户程序 事件发生时安全注入代码的机制,这就让非内核开发人员也可以对内核进行控制。随着内核的发展,BPF 逐步从最初的数据包过滤扩展到了网络、内核、安全、跟踪等,而且它的功能特性还在快速发展中,这种扩展后的 BPF 被简称为 eBPF(早期的 BPF 被称为经典 BPF,简称 cBPF)。实际上,现代内核所运行的都是 eBPF,如果没有特殊说明,内核和开源社区中提到的 BPF 等同于 eBPF 。
使用场景及分类 根据 eBPF 的功能和使用场景,主要分类三类:
跟踪 从内核和程序的运行状态中提取跟踪信息,来了解当前系统正在发生什么。
跟踪类 eBPF 程序主要用于从系统中提取跟踪信息,进而为监控、排错、性能优化等提供数据支撑。
其中 BCC 工具集中包含的绝大部分工具也都属于这个类型。
网络 对网络数据包进行过滤和处理,以便了解和控制网络数据包的收发过程。
网络类 eBPF 程序主要用于对网络数据包进行过滤和处理,进而实现网络的观测、过滤、流量控制以及性能优化等各种丰富的功能。根据事件触发位置的不同,网络类 eBPF 程序又可以分为 XDP(eXpress Data Path,高速数据路径)程序、TC(Traffic Control,流量控制)程序、套接字程序以及 cgroup 程序。
如著名的开源项目 cilium,主要用到了ebpf 中的 XDP (eXpress Data Path,高速数据路径)技术。
安全 第三类是除跟踪和网络之外的其他类型,包括安全控制、BPF 扩展等等。
插桩技术 eBPF支持多种事件源,可以在整个软件栈中提供能见度,其实现目前主要通过两种技术,分别为 动态插桩和 静态插桩,有时候只用其中一种方式是无法实现我们的需求,这时就需要两者相互配合使用了。
November 25, 2021
Golang常见编译参数
在执行 go build 命令的时候,经常需要添加一些参数,或许是为了调试,也或许是为了生成最终部署二进制文件。
在编译特定包时需要传递参数,格式应遵守“包名=参数列表”,如
go build -gcflags -gcflags='log=-N -l' main.go -gcflags go build 可以用 -gcflags 给_go_编译器传入参数,也就是传给 go tool compile 的参数,因此可以用 go tool compile –help 查看所有可用的参数。
其中 -m 可以检查代码的编译优化情况,包括逃逸情况和函数是否内联。
-ldflags go build用 -ldflags 给go链接器传入参数,实际是给go tool link的参数,可以用go tool link –help查看可用的参数。
常用-X来指定版本号等编译时才决定的参数值。例如代码中定义var buildVer string,然后在编译时用go build -ldflags “-X main.buildVer=1.0” … 来赋值。注意-X只能给string类型变量赋值。
November 25, 2021
Golang中的 CGO_ENABLED 环境变量
Golang中的编译参数
开发中经常使用 go build 命令来编译我们的程序源码,然后将生成二进制文件直接部署,极其方便。
对于 go build 有一些参数,对于针对程序源码进行一些编译优化,下面我们对经常使用的一些参数来介绍一下。
环境变量 环境变量需要在go命令前面设置,如果多个变量的话,中间需要用“空格”分隔。下面我们介绍一个非常常见到的一些环境变量
$ CGO_ENABLED=1 GOARCH=amd64 GOOS=linux go build -o myserver main.go 除了这里给出的这几个变量外,还有一些其它变量,如 GODEBUG、GOFLAGS、GOPROXY 等,所有支持环境变量都可以在 里找到,有兴趣的话可以看看他们的作用。
这里重点介绍一下 CGO_ENABLED 环境变量对我们程序的影响。 CGO_ENABLED是用来控制golang 编译期间是否支持调用 cgo 命令的开关,其值为1或0,默认情况下值为1,可以用 go env 查看默认值。
如果你的程序里调用了cgo 命令,此参数必须设置为1,否则将编译时出错。这里直接用文档 中的一个例子验证。
package main // #include <stdio.h> // #include <stdlib.h> // // static void myprint(char* s) { // printf("%sn", s); // } import "C" import "unsafe" func main() { cs := C.CString("Hello from stdio") C.myprint(cs) C.
November 23, 2021
理解 firewalld/ufw 与iptables、netfilter 的关系
iptables 作为 Linux/Unix 下一款优秀的防火墙软件,在安全方面发挥着极其重要的作用,作为系统管理员来讲一点也不陌生。不过对于一些新手来说,复杂性是一个门槛,Linux厂商为了解决这个问题,于是推出了新的管理工具,如 Centos 下的 Firewalld 和 Ubuntu 下的ufw, 他们对新手十分友好,只需要几个很简单的命令即可实现想要的功能,再不也必为记不住iptables中的四表五键而烦恼了。 那么,是不是有了 firewalld 和 ufw就不需要iptables了呢?并不是的。
首先我们要清楚firewalld、ufw 与iptables的关系,可以理解为两者只是对iptables其进行了一层封装,它们在用户交互方面做了非常多的改进,使其对用户更加友好,不需要再记住原来那么多命令了。
而目前对于一些系统管理员来讲,大概率还是会直接使用 iptables,主要原因是灵活性,当然也有一定的历史原因。对比前面两个管理工具,他们也存在一定的问题,如只能对单条规则进行管理,详细参考相关文档。
另外对于 firewalld 还有图形界面。
除了这三个还有一个 netfilter 的东西,它又是什么呢?
firewalld/ufw 自身并不具备防火墙的功能,而是和 iptables 一样需要通过内核的 netfilter 来实现,也就是说 firewalld 和 iptables 一样,他们的作用都是用于维护规则,而真正使用规则干活的是内核的netfilter。所以iptables服务和firewalld服务都不是真正的防火墙,只是用来定义防火墙规则功能的管理工具,通过iptables将定义好的规则交给内核中的netfilter(网络过滤器来读取)从而实现真正的防火墙功能。不过由于用户一般操作的都是iptables,所以称其为
防火墙也并没有什么不妥的。
总结一下,Netfilter/Iptables 是Linux系统自带的防火墙,Iptables管理规则,Netfilter则是规则的执行者,它们一起实现Linux下安全防护。
以上就是他们四者的关系。
参考资料 https://www.cnblogs.com/kevingrace/p/6265113.html
November 23, 2021
利用代理拉取docker镜像
在日常开发中经常会遇到有些镜像在 gcr.io 仓库,其仓库是google提供的,由于国内网络环境的复杂性是无法拉取到这些镜像的,这时候就需要我们想一些办法来实现拉取了。
这里给出了两种解决方法,一种是直接使用代理,这种可以直接拉取远程镜像到本地。另一种是通过中转的方法,先找一个可以直接拉取到镜像的网络,先将存储到本地,然后再转镜像上传到三方国内可以访问的镜像,如我们最常用镜像 hub.docker.com。
代理方法 使用代理方法的时候,如果通过直接设置 http_proxy 和 https_proxy 这两个环境变量是不可行的。主要原因是 docker 并不会使用它们,需要为 docker daemon 服务的设置代理才可以。
设置docker服务代理 sudo mkdir -p /etc/systemd/system/docker.service.d/ sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf 将以下内容写入 http-proxy.conf 文件
[Service] Environment="HTTP_PROXY=http://127.0.0.1:7890" Environment="HTTPS_PROXY=http://127.0.0.1:7890" Environment="ALL_PROXY=socks5://127.0.0.1:7890" Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,.corp,.docker.io,.docker.com" 上面代理地址是本机开启的代理服务监听端口,如果代理服务在局域网内的其它机器上的话,需要更换为其 ip 地址和端口号。环境变量 NO_PROXY 表示不使用代理的域名或IP。
重启 docker 服务 root@ubuntu:~# systemctl daemon-reload root@ubuntu:~# systemctl restart docker 验证设置 root@ubuntu:~# systemctl show --property=Environment docker Environment=HTTP_PROXY=http://127.0.0.1:7890 HTTPS_PROXY=http://127.0.0.1:7890 ALL_PROXY=socks5://127.0.0.1:7890 NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,.corp,.docker.io,.docker.com 也可以使用命令 docker info 验证
root@ubuntu:~# docker info ... Debug Mode: false HTTP Proxy: http://127.
October 9, 2021
k8s解决证书过期问题
在k8s中的时间会提示证书过期问题,如
# kubectl get nodes Unable to connect to the server: x509: certificate has expired or is not yet valid 这里我们介绍一下续期方法。
注意:当前集群通过 kubeadm 命令创建。
kubeadm 安装得证书默认为 1 年,注意原证书文件必须保留在服务器上才能做延期操作,否则就会重新生成,集群可能无法恢复。
准备 这里先查看一下测试集群的证书过期时间
# kubeadm certs check-expiration [check-expiration] Reading configuration from the cluster... [check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED admin.conf Aug 30, 2022 03:18 UTC 324d no apiserver Aug 30, 2022 03:18 UTC 324d ca no apiserver-etcd-client Aug 30, 2022 03:18 UTC 324d etcd-ca no apiserver-kubelet-client Aug 30, 2022 03:18 UTC 324d ca no controller-manager.
September 13, 2021
istio在虚拟机vm下的安装方法
建议参考官方文档 https://istio.io/latest/zh/docs/setup/install/virtual-machine/ ,这里提醒大家对于命令中文版部分命令与英文版不一致,请以 英文版 为准。
对于istio在vm上的安装教程主要分为三部分。首先是在k8s的master节点生成vm连接主节点的一些配置信息,其实是在vm上应用这些配置信息,最后也就是验证连接是否成功。
本篇主要介绍“单网络”的情况, 对于”多网络“请自行参考官方文档。
vm环境准备 生成vm通讯配置信息 这里主要介绍一些新手迷惑的部分。如环境变量设置及vm注册的方式
设置环境变量 在设置变量时,对于”单网络“来讲 CLUSTER_NETWORK 和 VM_NETWORK 保留空值即可。如我这里设置如下
$ VM_APP="myapp" $ VM_NAMESPACE="vm" $ WORK_DIR="/root/myapp" $ SERVICE_ACCOUNT="vm-sa" $ CLUSTER_NETWORK="" $ VM_NETWORK="" $ CLUSTER="Kubernetes" 每个环境变量的解释: VM_APP 表示vm上应用的名称 VM_NAMESPACE 表示应用所在的namespace WORK_DIR 生成vm配置信息保留的目录,任何位置即可 SERVICE_ACCOUNT 服务运行的账号 ,即yaml文件中的 ServiceAccount 字段 CLUSTER 集群名称,默认为 Kubernetes 即可。
安装 Istio 控制平面 1 为安装创建 IstioOperator 空间 cat <<EOF > ./vm-cluster.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: name: istio spec: meshConfig: accessLogFile: /dev/stdout enableTracing: true enableEnvoyAccessLogService: true defaultConfig.
September 13, 2021
利用 docker buildx 构建多平台镜像
什么是 docker buildx Docker Buildx是一个CLI插件,它扩展了Docker命令,完全支持Moby BuildKit builder toolkit提供的功能。它提供了与docker build相同的用户体验,并提供了许多新功能,如创建作用域生成器实例和针对多个节点并发构建。
Docker Buildx包含在Docker 19.03中,并与以下Docker Desktop版本捆绑在一起。请注意,必须启用“实验特性”选项才能使用Docker Buildx。
Docker Desktop Enterprise version 2.1.0 Docker Desktop Edge version 2.0.4.0 or higher
用法 Usage: docker buildx [OPTIONS] COMMAND Extended build capabilities with BuildKit Options: --builder string Override the configured builder instance Management Commands: imagetools Commands to work on images in registry Commands: bake Build from a file build Start a build create Create a new builder instance du Disk usage inspect Inspect current builder instance ls List builder instances prune Remove build cache rm Remove a builder instance stop Stop builder instance use Set the current builder instance version Show buildx version information Run 'docker buildx COMMAND --help' for more information on a command 一般用到 create、ls 和 rm 就可以了