如果不可避免的要在容器镜像里面,打包多个容器进程这样就需要选择适当的init进程了,做的不够好就会出现很多问题。
第一个最常见的问题就是kubernetes要去优雅的终止一个进程的时候,它会发一个sigterm终止信号,让这个容器进程优雅退出,但是如果你做的不好,比如容器里面有一个初始化进程,它用来拉起主进程的,初始化进程把kubernetes的sigterm信号吃掉了,不往下传,那么就让这个应用缺少了优雅终止的可能性。到最后就暴力的被kill掉,可能引起业务故障。
如果容器镜像里面不可避免的的要用多个进程,可以使用tini这个项目,作为整个的entrypoint,它第一能够做到将终止信号传递下去,其次可以清理异常退出的子进程,避免出现僵尸进程
docker镜像管理
Docker 镜像版本管理
docker tag 与 github的版本合力
容器镜像和源代码,都支持版本的管理,都支持tag,其实可以将源码的tag和容器镜像tag一一对应起来。
kubernetes有个开发分支,叫master或者main,一般来说所有的代码分支,所有的新功能都会在master分支里面,随着功能的开发成熟,如果这个时候需要切换新的版本了,那么可以通过git命令将master分支切换为release分支,这个release切出来,不代表立刻就要发布,可能中间还要修复bug,还要去做稳定性的测试,如果中间有任何的代码变更同时要进master和release的,确保master和最新release是一起往前推进的。
当所有的1.21测试完毕了,觉得它是一个可发布版本,我们这个时候就要去构建以当前的release版本分支构建容器镜像,并且给这个容器镜像添加版本信息。
这个时候release分支后面还可能进code,因为发现了bug还需要修复,但是版本以及切掉了,那要怎样确保切掉的tag有对应的源码可以找到?这个时候在github上面可以通过git tag为这个release分支打一个快照,这样镜像的tag和源码的tag就有一个一一对应的关系了。
docker这种能力使得后面的ci/cd就非常的顺畅了,因为每发一个生产系统版本,它就是docker image的tag,这个镜像版本对应在github里面有一个自己的tag,相当于将源代码也做了一个快照,那么永远知道生产系统版本对应源代码的版本是多少。
镜像仓库
docker的优势
它不需要启动内核,使用的是主机的内核,启动其实就是应用进程的启动,毫秒级。
它不需要模拟整个操作系统了,很多时候需要跑虚拟机的时候至少1个cpu,这样利用率就很低,我就是一个容器进程,可能不怎么消耗cpu就可以将进程运行起来。不怎么占用资源,那么一个节点上面可以跑的容器就变多了。
所有依赖和数据包都在root fs里面。
基础镜像很大,可能应用部分就是几M,在拉取的时候docker会去检查说基础镜像是不是已经存在了,存在了就不会再去拉取,增量分发就保证了传输的效率,保证了对网络带宽要求没那么高。