Security - OPA Gatekeeper
Overview & Architecture
In Kubernetes, Admission Controllers enforce policies on objects during create, update, and delete operations.Admission control is fundamental to policy enforcement in Kubernetes.
For example, by deploying OPA as an admission controller you can
Require specific labels on all resources.
Require container images come from the corporate image registry.
Require all Pods specify resource requests and limits.
Prevent conflicting Ingress objects from being created.
Admission con ...
Security - OPA Core
Glance
Use OPA for a unified toolset and framework for policy across the cloud native stack.
Use OPA to decouple policy from the service’s code so you can release, analyze, and review policies without sacrificing availability or performance.
Declarative
Express policy in a high-level, declarative language that promotes safe, performant, fine-grained controls.
Use a language purpose-built for policy in a world where JSON is pervasive.
Iterate, traverse hierarchies, and apply 150+ built-ins like string manipu ...
Go - Block + Scope
Variable Shadowing1234567891011121314151617package mainimport "fmt"var a = 11func foo(n int) { // 局部变量遮蔽了同名的包级变量 a := 1 a += n}func main() { fmt.Println(a) // 11 foo(5) fmt.Println(a) // 11}
BlockExplicit Block
大括号包裹
12345678func foo() { // Block 1 { // Block 2 { // Block 3 { // Block 4 } } }}
Explicit Block 是包裹在大括号内部的声明和语句序列
如果一对大括号内没有任何声明和其它语句,为空 Block
Block 支持嵌套
Implicit ...
Go - Variable
内存边界
在编程语言中,为了方便操作内存特定位置的数据,使用变量与特定位置的内存绑定
编译器或者解析器需要知道变量所能引用的内存区域边界
动态语言
解析器可以在运行时通过对变量赋值的分析,自动确定变量的边界
一个变量可以在运行时被赋予大小不同的边界
静态语言
编译器必须明确知道一个变量的边界才允许使用该变量
但编译器无法自动分析,因此边界信息必须由开发者提供 - 变量声明
在具体实现层面,边界信息由变量的类型属性赋予
变量声明
Go 是静态语言,所有变量在使用前必须先进行声明声明:告诉编译器该变量可以操作的内存的边界信息(由变量类型信息提供)
通用
变量声明形式与主流静态语言的差异 - 将变量名放在了类型前面(方便语法糖移除 type)
如果没有显式为变量赋予初值,Go 编译器会为变量赋予类型零值
1var a int // a 的初值为 int 类型的零值 0
Go 的每种原生类型都有其默认值,即类型零值复合类型(array、struct)变量的类型零值为组成元素都为零值的结果
原生类型
类型零值
整型
0
浮点
0.0
布尔
FALSE
字符串
& ...
Go - Web
API
项目结构1234567891011121314151617$ tree.├── cmd│ └── bookstore│ └── main.go├── go.mod├── internal│ └── store│ └── memstore.go├── server│ ├── middleware│ │ └── middleware.go│ └── server.go└── store ├── factory │ └── factory.go └── store.go
逻辑结构
具体实现store
定义 Domain 和 Action
store/store.go12345678910111213141516package storetype Book struct { Id string `json:"id"` Name string `json:"name"` Authors []string `json:"authors& ...
Go - Main + Init
main.main
main 包中的 main 函数 - 所有可执行程序的用户层执行逻辑的入口函数
123456package main// 无参数 + 无返回值func main() { // 用户层执行逻辑}
可执行程序的 main 包必须定义 main 函数,否则会编译报错function main is undeclared in the main package
main.go1package main
123$ go build main.go# command-line-argumentsruntime.main_main·f: function main is undeclared in the main package
在启动了多个 goroutine 的 Go 应用中,main.main 将在 Go 应用的主 goroutine 中执行
main.main 函数返回意味着整个 Go 程序结束
除了 main 包外,其它包也可以拥有自己的 main 函数
但依据 Go 的可见性规则,非 main 包中的 main 函数仅限于包内使用
123456 ...
Go - Go Module
添加依赖
github.com/google/uuid
main.go1234567891011package mainimport ( "github.com/google/uuid" "github.com/sirupsen/logrus")func main() { logrus.Println("hello, gomodule mode") logrus.Println(uuid.NewString())}
go.mod 里的 require 字段中,没有任何 Module 提供了包 github.com/google/uuid
123$ go buildmain.go:4:2: no required module provides package github.com/google/uuid; to add it: go get github.com/google/uuid
手动 go get,下载依赖到本地 Module 缓存,并更 ...
Go - Build Mode
构建过程
确定包版本 + 编译包 + 链接目标文件(编译后得到的)
构建模式
Mode
Desc
GOPATH
不关注依赖版本
Vendor - 1.5
Reproducible Build
Go Module - 1.11
Dependency Management
GOPATH
Go 首次开源时,内置了 GOPATH 的构建模式
Go 编译器可以在本地 GOPATH 下搜索 Go 程序依赖的第三方包
如果存在,则使用这个本地包进行编译;如果不存在,则会报编译错误
main.go1234567package mainimport "github.com/sirupsen/logrus"func main() { logrus.Println("hello, gopath mode")}
无法找到依赖包而构建失败
1234567891011121314151617$ go versiongo version go1.10.8 linux/amd64$ echo $GOROOT/home/zhongming ...
Go - Project Layout
演进历史Go 1.3
以 all.bash 为代表的源码构建脚本放在了 src 的顶层目录下
123456789101112131415161718192021222324$ tree -LF 1 ./src./src/├── Make.dist├── all.bash*├── all.bat├── all.rc*├── clean.bash*├── clean.bat├── clean.rc*├── cmd/├── lib9/├── libbio/├── liblink/├── make.bash*├── make.bat├── make.rc*├── nacltest.bash*├── pkg/├── race.bash*├── race.bat├── run.bash*├── run.bat├── run.rc*└── sudo.bash*
./src/cmd 存放着 Go 可执行文件的相关目录,每个子目录都是一个 Go 工具链命令或子命令对应的可执行文件
12345678910111213141516171819$ tree -LF 1 ./src/cmd./src/cmd/├── 5a/ ...
Go - Code Structure
源文件
Go 源文件使用全小写字母形式的短小单词命名,并以 .go 扩展名结尾
如果使用多个单词,将多个单词直接连接起来,而不使用其它分隔符
即 helloworld.go,而非 hello_world.go
尽量不要使用两个以上单词组合作为文件名,否则很难辨认
Hello, World1234567package mainimport "fmt"func main() { fmt.Println("Hello, World!")}
12345678910111213$ tree.└── main.go$ go build main.go$ tree.├── main└── main.go$ ./mainHello, World!
程序结构1package main
package 是 Go 语言的基本组成单位,通常使用单个小写单词命名
整个 Go 程序仅允许存在一个 main 包
main.go12345import "fmt"func main() { fmt.Println(&quo ...