Hero Image
基本语法梳理

源文件 原文件使用UTF-8编码,对Unicode支持良好。每个源文件都属于包的一部分,在文件头部用package声明所属包的名称 1package main 2func main(){ 3 println("hello world!!") 4} 以.go作为文件扩展名,语句结束分号会被默认省略,支持C样式注释。入口函数main没有参数,且必须放在main包中 用import导入标准库或第三方包 1package main 2import{ 3 "fmt" 4} 5 6func main(){ 7 fmt.Println("hello world!") 8} 可以直接运行或者编译为可执行文件 变量 使用var定义变量,支持类型推断。基础数据类型划分清晰明确,有助于编写跨平台应用。编译器确保变量总是被初始化为0,避免出现意外状况。 1package main 2func main(){ 3 var x int32 4 var s="hello world!" 5 // 两个数据之间默认使用空格隔开 6 println(x,s) 7} 在函数内部,还可以省略var关键字,使用更简单的定义模式。 1package main 2 3//y := 200 // 该声明方式仅在函数内部使用,不可用来声明全局变量 4func main() { 5 x := 100 6 println(x) 7} 编译器将未使用的局部变量定义当做错误 表达式 Go仅有三种流控制语句 if 1package main 2 3func main() { 4 x := 100 5 if x > 0 { 6 print("x") 7 } else if x < 0 { 8 print("-x") 9 } else { 10 print("0") 11 } 12} switch 1package main 2 3func main() { 4 x := 0 5 switch { 6 case x > 0: 7 print("x") 8 case x < 0: 9 print("-x") 10 default: 11 print("0") 12 } 13} for 1func main() { 2 for i := 0; i < 5; i++ { 3 println(i) 4 } 5 for i := 4; i >= 0; i-- { 6 println(i) 7 } 8} 1package main 2 3func main() { 4 x := 0 5 for x < 5 { // 相当于 while(x<5) 6 println(x) 7 x++ 8 } 9} 1package main 2 3func main() { 4 x := 4 5 for { // 相当于while(true) 6 println(x) 7 x-- 8 if x < 0 { 9 break 10 } 11 } 12} 在迭代遍历时,for…range除了元素外,还可以返回索引

Hero Image
容器技术基础

为什么容器里只能跑“一个进程”? 为什么我原先一直在用某个JVM参数,在容器里就不好使了? 为什么kubernetes就不能固定IP地址?容器网络联不通又该如何去debug? Kubernetes中的StatefulSet和Operator到底什么区别?PC和PVC这些概念又该怎么用? Linux进程模型对容器本身的重要意义,控制器模式对整个K8s项目提纲挈领的作用? 从PaaS到K8s PaaS PaaS(Platform as a Service) 应用托管。 Docker镜像,其实就是一个压缩包,直接由一个完整的操作系统的所有文件和目录构成。 其实只打包了文件系统,不包括操作系统的内核。各种内核相关的模块或者特性支持完全依赖于宿主机。 通过docker build 打包镜像,docker run 运行镜像,docker run创建的沙盒,就是使用Linux Cgroups和Namespace机制创建出来的隔离环境。解决了应用打包这个根本性问题。 Swarm swarm 提供集群管理功能 单机docker项目 1docker run <container-name> 多机docker项目 1docker run -H 'swarm cluster API' <container-name> Fig 项目 Fig项目第一次在开发者面前提出了容器编排(Container Orchestration)的概念。 加入用户现在需要部署的是应用容器A、数据库容器B、负载均衡容器C,那么Fig就允许用户把ABC三个容器定义在一个配置文件中, 并且可以指定他们之间的关联关系,比如容器A需要访问数据库B。定义好之后,只需要执行一条非常简单的指令。 1fig up Fig就会把这些容器的定义和配置交给DockerAPI按照访问逻辑一次创建。而容器A和B之间的关联关系,也会交给docker的Link功能通过写入hosts文件的方式进行配置。更重要的是,你还可以在Fig的配置文件里定义各种容器的副本个数等编排参数。 Fig 项目被Docker收购后更名为Compose。 Libcontainer LibContainer -> RunC 以RunC为依据,制定容器和镜像的标准和规范。 OCI(Open Container Initiative), 意在将容器运行时和镜像的实现从Docker项目中完全剥离出来。 Containerd 容器运行时 进程隔离与限制 程序被执行起来,它就从磁盘上的二进制文件,变成了计算机 内存中的数据,寄存器里的值,堆栈中的指令、被打开的文件,以及各种设备的状态信息的一个集合。像这样一个程序运行起来后的计算机执行环境的总和,就是:进程。 对于进程来说,它的静态表现就是程序,一个二进制文件;而一旦运行起来,就变成了计算机数据和状态的总和,这就是进程的动态表现。 容器技术的核心功能,就是通过约束和修改进程的动态表现,从而为其创造出一个“边界”。对于大多数Linux容器来说, Cgroups是用来制造约束的主要手段, 而Namespace技术则是用来修改进程视图的主要方法。 隔离 1docker run -it busybox /bin/sh What is BusyBox?

Hero Image
怎么成为K8s的Contributor

Important Doc Contributor Cheat Sheet 加入SIG SIG(Special Interest Groups) 是Kubernetes社区中关注特定模块的永久组织。 作为刚参与社区的开发者,可以从sig/app, sig/node, sig/scheduling 这几个SIG开始。 KEP KEP(Kubernetes Enhancement Proposal)。对于功能和API的修改都需要先在kubernetes/enhancements仓库对应SIG的目录下提交Proposal才能实施。所有的Proposal都必须经过讨论,通过社区SIG Leader的批准。 很多不熟悉Kubernetes工作流的开发者会在社区中直接提交一个包含API改动的commit,但是如果这类commit没有对应的KEP 是不会被社区合入的。 项目设计 所有进入开发状态的功能都会有一个非常详细的KEP。KEP有一个详细的模板,设计是非常规范的。我们再日常的开发中也可以使用类似的格式写设计文档或者技术文档。 最近几年新实现的功能都会有着比较详细的KEP文档 分布式协作 Kubernetes 中所有的社区会议都会使用Zoom录制,并上传到Youtube。大多数的讨论和交流也对会再对应的issue和PR中。 每个提交的PR都要通过2K以上的成员的review以及几千个单元测试、集成测试、端到端测试以及扩展性测试,这些测定共同保证了项目的稳定性。 kubernetes/test-infra 项目中包含了Kubernetes的测试基础配置。 很多端到端的测试都会启动Kubernetes集群,并在真实的环境中测试代码的逻辑,这些测试可能一次会执行几十分钟,并且有一定概率出现Flaky。 影响力 提高个人和公司在开源社区的影响力,也是参与社区的重要目的。 对个人来说,参与开源项目可以快速理解项目的实现原理以及工作流程。如果想要在未来从事相关的工作,参与开源项目一定是加分项。 对公司来说,参与开源项目可以提高公司在开源社区的话语权,提高公司的技术影响力。足够的话语权也会让开源社区在关键需求上有较快的支持,减少与社区代码的分叉,降低维护成本,并满足公司内部的需求。 操作指南 参与开源项目并不一定要从非常复杂的功能或者Proposal开始。任何一个对代码库有利的PR都是值得提交的。修复代码中的typo 或者静态检查错误,作为最开始的工作是没有任何问题的。这能够帮我们快速热身。不过在熟悉了kubernetes的提交流程之后就没有必要做类似的提交了,以为所有的提交都需要Reviewer和Approver的批准,我们应该尽可能的做有意义的变动,减少他们的工作量。 从阅读源码开始 我们可以从自己熟悉的模块入手,了解该模块的实现原理,在阅读代码的过程中,我们很容易发现源代码中的一些typo和缺陷,这个时候就可以提交PR修复这些问题。 从静态检查开始 .golint_failures 文件中忽略了几百个Package中的静态检查,你可以在其中选择合适的Package作为成为Kubernetes贡献者的而第一步。 从项目管理开始 也可以选择Kubernetes的项目管理, sig/release. 选取第一个kubernetes问题 issue 列表 使用tag过滤问题 “good first issue” “help wanted” 这些标签表明了对新手非常友好。有时候问题也会被打上错误标签,也许是技术难度被低估了。 TODO 搜索代码库里的TODO。 Go 语言的开发规范、分布式社区的治理方式 代码需要每天都看,留出专门的时间来查看Kubernetes的源码,对它的核心组件的实现看看,构建一下, 测试一下,修一下Bug,typo等。 一般半年之后,你就可以熟悉基础项目,并且开始贡献代码。 当你已经和团队协作的很熟悉,就会自然承接一些子任务,然后团队就会赋予你写的权限,这样就可以顺理成章的成为Kubernetes的committer。这个时候你就是这个子项目的maintainer了 TODO 加入 Kubenetes Slack Channle 加入邮件列表 加入SIG 参加社区会议 提issue 如何提交PR

Hero Image
自控力

自控力 The WillPower Instinct “意志力学科”这门课汇集了心理学、经济学、神经学、医学领域关于自控的最新洞见,告诉人们如何改变旧习惯,培养健康的新习惯、克服拖延、抓住重点、管理压力。阐述了为何人们会在诱惑前屈服,以及怎样才能抵挡住诱惑。此外,它还提出了理解自控局限的重要性,以及培养意志力的最佳决策。 对于意志力科学的理解有助于培养自控力,让人们更有精力追逐最重要的东西。自控的策略有助于人们抵制各种各样的诱惑。 为了成功做到自控,你必须知道自己为何失败 提高自控力的最有效途径在于,弄清自己如何失控、为何失控。意识到自己有多容易失控,并非意味着你是一个失败者。恰恰相反,这将有助于你避开意志力失效的陷阱。研究表明,自诩为意志坚定的人反而最容易在诱惑面前失控。因为他们无法预测自己在何时何地、会由于何种原因失控。他们在面对挫折时更容易吃惊,在陷入困境时更容易放弃。 自知之明是自控的基础。认识到自己意志力存在问题,则是自控的关键。 当我们屈从于诱惑或者拖着不该做的事时,是什么拖了我们的后腿?是哪些致命的错误?更重要的是,我们如何寻找机会,避免来犯同样的错误。我们怎样从失败中汲取经验,为成功铺平道路? 这些行为虽不完美,却是人之常态。每个人都在以某种方式抵制诱惑、癖好、干扰和拖延。这不是个体的弱点或个人的不足,而是普遍的经验,是人所共有的状态。 理论固然好,但是数据更重要。 沉迷于电视剧不能自拔 总是幻想或者希望自己和主角处于同样的状态,同样可以随心所欲的处理各种困境。更不想进一步打破自己的幻想,不想回归现实。可事实却是,越沉浸于其中,却又距离故事中的主角远了一步。这个世界上有太多看不完的故事,不是每个故事都需要去读,选择重要的,选择真正有意义,有营养的文化饕餮。