Kubernetes - Federation
跨地域 使用单一集群,可以管控多个地域的机器,底层网络需要打通 Service 优先级:zone > region > other 集群联邦必要性 单一集群的管理规模有上限 数据库存储 etcd 作为 Kubernetes 集群的后端存储数据库,对空间大小(8G)的要求比较苛刻 内存占用 Kubernetes 的 API Server 作为 API 网关,会缓存该集群的所有对象 其它的 Kubernetes Controller 也需要对监听的对象构建客户端缓存 控制器复杂度 Kubernetes 的一个业务流程由多个对象和控制器联动完成 随着对象数量的增长,控制器的处理耗时也会增长 单一计算节点的资源有上限 可量化资源:CPU、Memory 等 不可量化资源:端口数量(限制 Service NodePort)、进程数量等 故障域控制 集群规模越大,控制面组件出现故障时的影响范围越大 方案:将大规模的数据中心切成多个规模相对较小的集群,每个集群控制在一定规模 应用 HA 多数据中心部署来保障跨地域高可用 混合云 私有云 + 公有云 职责 跨集群同...
Kubernetes - Istio
CRD 核心为 networking 12345678910111213141516171819202122$ istioctl versionclient version: 1.19.3control plane version: 1.19.3data plane version: 1.19.3 (2 proxies)$ k get crdNAME CREATED ATauthorizationpolicies.security.istio.io 2022-12-27T02:58:37Zdestinationrules.networking.istio.io 2022-12-27T02:58:37Zenvoyfilters.networking.istio.io 2022-12-27T02:58:37Zgateways.networking.istio.io 2022-12-27T02:58:37Zistiooperators.install.istio.io...
Kubernetes - Envoy
Kubernetes Kubernetes 主要基于 Kernel 技术栈,缺少精细化的高级流量治理 Kubernetes 已有的流量治理能力:Service + Ingress Service 在 L4,基于 Kernel 技术栈,无法实现精细化的高级流量管理 Ingress 在 L7,主要针对入站流量 架构演进单体 访问服务 微服务 业务代码一般会集成统一的 SDK,耦合了很多平台侧的能力 Service MeshSidecar Service Instance 与 Sidecar Proxy 在同一个 Network Namespace,相当于一个 loopback,可以明文传输 能力下沉 通过 Sidecar 来实现微服务治理,业务部门更聚焦于业务逻辑 Istio特性 HTTP、gRPC、WebSocket、TCP 的自动负载均衡 通过丰富的路由规则实现重试、故障转移、故障注入,可以对流量行为进行细粒度控制 可插入的策略层和配置 API,支持访问控制、速率限制和配额 对出入集群入口和出口中的所有流量的自动度量指标、日志记录和跟踪 通过强大的基于身份的验证和授权,...
Kubernetes - Scaling
Aggregated APIServer 123456789101112131415161718192021222324$ k get apiservices.apiregistration.k8s.ioNAME SERVICE AVAILABLE AGEv1. Local True 36dv1.admissionregistration.k8s.io Local True 36dv1.apiextensions.k8s.io Local True 36dv1.apps Local True ...
Kubernetes - Helm
特性 Helm Chart 是创建一个应用实例的必要的配置组,即 Spec 集合 配置信息被归类为模板和值,经过渲染后生成最终的对象 所有配置可以被打包进一个可以发布的对象中 Release 为一个特定配置的 Chart 的实例 组件 只有客户端,没有服务端 Client 本地 Chart 开发 管理 Repository 管理 Release 与 Library 交互 发送需要安装的 Chart 请求升级或者卸载存在的 Release Library 负责与 API Server 交互 基于 Chart 和 Configuration 创建一个 Release 把 Chart 安装到 Kubernetes,并提供相应的 Release 对象 升级 + 卸载 采用 Kubernetes 存储所有配置信息 - 无需服务端 实践 开发 123456789101112131415161718$ h create myappCreating myapp$ tree myappmyapp├── Chart.yaml├── charts├── templates│ ├── NOTES.tx...
Kubernetes - Operator
应用接入应用容器化开销风险 Log Driver Blocking mode Non-Blocking mode 共享 Kernel 共享系统参数配置 进程数共享 fd 数共享 主机磁盘共享 资源监控应用视角 容器中看到的资源是主机资源 top Java Runtime.availableProcessors() cat /proc/cpuinfo cat /proc/meminfo df -k 影响应用 Java Concurrent GC Thread Heap Size 线程数不可控 判断规则 查询 /proc/1/cgroup 是否包含 kubepods 关键字 12345678910111213141516171819202122232425262728293031323334$ cat /proc/1/cgroup12:cpuset:/11:devices:/init.scope10:blkio:/init.scope9:freezer:/8:net_cls,net_prio:/7:pids:/init.scope6:pe...
Go - Pointer
指针类型 指针类型是依托某一类型而存在的 对于某一类型 T,以 T 为基类型的指针类型为 *T unsafe.Pointer 不需要基类型,用于表示一个通用指针类型 任何指针类型和 unsafe.Pointer 可以相互显式转换 1234567type T struct{}func main() { var p *T var p1 = unsafe.Pointer(p) // 任意指针类型 -> unsafe.Pointer p = (*T)(p1) // unsafe.Pointer -> 任意指针类型} 如果指针类型变量没有被显式赋予初值,默认值为 nil 123456type T struct{}func main() { var p *T println(p == nil) // true} 给指针类型变量赋值 123var a int = 13var p *int = &a // &...
Go - Type Constraint
限制 对泛型函数的类型参数以及泛型函数中的实现代码设置限制 泛型函数的调用者只能传递满足限制条件的类型实参 泛型函数内部也只能以类型参数允许的方式使用这些类型实参值 在 Go 中,使用类型参数约束来表达这种限制条件 函数普通参数在函数实现中可以表现出来的性质与可以参与的运算由参数类型限制 泛型函数的类型参数由约束来限制 内置约束any 最宽松的约束 无论是泛型函数还是泛型类型,其所有的类型参数声明中都必须显式包含约束 可以使用空接口类型来表达所有类型 123func foo[T interface{}](sl []T) {}func bar[T1 interface{}, T2 interface{}](t1 T1, t2 T2) {} 空接口类型的不足:使得声明变得冗长、复杂、语义不清 builtin/builtin.go12// any is an alias for interface{} and is equivalent to interface&...
Go - Type Parameter
不支持 Feature Desc 泛型特化 编写一个泛型函数针对某个具体类型的特殊版本 元编程 编写在编译时执行的代码来生成在运行时执行的代码 操作符方法 不能将操作符视为方法并自定义其实现 变长类型参数 容器重复代码123456789101112131415161718192021222324252627func maxInt(sl []int) int { if len(sl) == 0 { panic("empty slice") } max := sl[0] for _, v := range sl[1:] { if v > max { max = v } } return max}func maxString(sl []string) string { if len(sl) == 0 { panic("empt...
Go - GC
逃逸分析 在传统的不带 GC 的编程语言中,需要关注对象的分配位置,是分配在堆上还是栈上 Go 集成了逃逸分析功能来自动判断对象是应该分配在堆上还是栈上 只有在代码优化时,才需要研究具体的逃逸分析规则 escape.go123456package mainfunc main() { var m = make([]int, 10240) println(m[0])} 1234$ go build -gcflags='-m' escape.go# command-line-arguments./escape.go:3:6: can inline main./escape.go:4:14: make([]int, 10240) escapes to heap 较大的对象会被放在堆上 如果对象分配在栈上,其管理成本比较低,只需要挪动栈顶寄存器就可以实现对象的分配和释放 如果对象分配在堆上,需要经过层层的内存申请过程 逃逸分析和垃圾回收结合,可以极大地降低开发者的心智负担,无需再担心内存的分配和释放 抽象成本 Rust - 零成本抽象 ...















