近年来,容器和Kubernetes已经成为开发者和企业用户关注的技术趋势。本文总结了构建和管理容器以优化IT成本和提高效率的十个重要技巧。容器是Kubernetes中应用的核心载体。在创建Kubernetes工作负载时,例如创建调度、扩展或升级应用程序的规则,首先需要创建一个容器镜像,然后通过该镜像运行服务或Kubernetes工作负载。在测试图像并将其与其余应用程序代码集成后,用户通常会将图像推送到容器注册表。但是仍然有很多实用技巧可以帮助在推送之前构建和管理容器。Text通过Kubernetes,用户可以自动扩展业务,整个过程几乎没有停机时间,从而优化IT成本,提高系统可靠性。1、使用Kubernetes模型随着Kubernetes不断推出新的特性,其应用模型也在逐渐发生变化。为了保证Kubernetes集群遵循当前的Kubernetes应用模式,用户需要定期查阅Kubernetes官方文档和各个版本的发行说明。2.复用基础镜像节省时间在Kubernetes集群中创建应用容器时,用户需要构建一个Docker基础镜像,然后基于这个镜像构建部分或者全部的应用容器。有很多应用程序共享依赖、库和配置,因此共享部分的配置可以在基础镜像中完成,以实现复用。DockerHub和GoogleContainer注册中心有数以千计的基础镜像可供下载,这些镜像都是预先配置好的,可以随时使用,从而节省了大量时间。3.不要轻易相信任何镜子。虽然使用预建镜像很方便,但要格外小心,确保对它们运行特定的漏洞扫描。一些开发人员会从另一个用户创建的DockerHub中获取一个基础镜像,并将该容器推送到生产环境,这一切都是因为乍一看该镜像包含所需的包。这里有很多问题:镜像中的代码可能是错误的版本;代码可能有错误;或者更糟的是,该项目可能已被故意与恶意软件捆绑在一起。为了缓解上述问题,用户可以通过Snyder或Twistlock运行静态分析,然后将其集成到CI/CD(持续集成和持续交付)管道中,以扫描所有容器中的漏洞。一般来说,一旦发现基础镜像存在漏洞,用户应该重建整个镜像,而不是仅仅修复漏洞。容器应该是不可变的,因此需要引入补丁来重建和部署镜像。4.优化基础镜像从最精简、最可行的基础镜像开始,并在此基础上构建包。这样,就可以准确地知道容器中有什么。较小的基础镜像也减少了开销。例如,一个应用程序的大小可能只有5MB,如果您要添加一个现有的Node.js映像,然后安装所有库,整个映像的大小可能会达到600MB,但您实际上并不需要那些额外的图书馆。因此,尽量保持最精简的镜像,以:建立更快的存储空间更小的镜像拉取更快潜在威胁面更小5.确保容器只运行一个进程只有一个进程。容器与其承载的应用程序具有相同的生命周期,这意味着每个容器都应该包含一个父进程。根据GoogleCloud的说法,将容器视为虚拟机并同时运行多个进程是一个常见的错误。虽然容器可以通过这种方式实现,但它们不使用Kubernetes的自我修复特性。通常,容器和应用程序应该同时启动;同样,当应用程序停止时,容器也应该停止。如果一个容器中有多个进程,可能会出现应用状态混杂的情况,这会导致Kubernetes无法判断一个容器是否健康。6、正确处理Linux信号容器通过Linux信号控制其内部进程的生命周期。为了将应用程序生命周期与容器联系起来,有必要确保应用程序正确处理Linux信号。Linux内核使用SIGTERM、SIGKILL和SIGINIT等信号来终止进程。但是容器中的Linux会使用不同的方式来执行这些普通的信号,如果执行结果与默认的信号结果不匹配,就会导致错误和中断。创建一个专用的初始化系统可以帮助解决这个问题,例如用于容器的LinuxTini系统。该工具正确注册信号处理程序(如PID),容器化应用程序可以正确实现Linux信号以优雅地关闭孤儿和僵尸进程并完成内存回收。7、充分利用Docker的缓存构建机制。容器镜像由一系列镜像层组成,这些镜像层是通过模板或Dockerfile中的指令生成的。这些层和构建顺序通常由容器平台缓存。例如,Docker有一个可以被不同层重用的构建缓存。这个缓存可以让构建速度更快,但是要确保当前层的所有父节点都持有构建缓存,并且这些缓存没有被改变。简单的说就是需要把不变的图层放在前面,经常变化的图层放在后面。例如,假设您有一个包含步骤X、Y和Z的构建文件,并且对步骤Z进行了更改,构建文件可以在缓存中重用步骤X和Y,因为这些层在更改Z之前就已经存在,这会加快构建过程。但是,如果更改步骤X,则缓存中的图层将无法再重复使用。虽然这是一种节省时间的方便行为,但重要的是要确保所有图像层都是最新的,而不是从旧的、过时的缓存中构建的。8.使用类似Helm的包管理器Helm是Kubernetes的非官方包管理器,可以帮助安装和更新集群中运行的常见负载和容器。Helm可以使用Charts声明自定义应用程序依赖项,并提供滚动升级和回滚功能。用户可以通过已有的基础镜像,为Kubernetes集群提供常用的服务,比如数据库或者web服务;他们还可以为内部应用程序创建自定义基础镜像,创建自定义Charts可以简化部署并减少开发团队的工作量和重复工作。9.以标签和语义版本号为基本原则,用户不要使用:latest标签。这对大多数开发人员来说是显而易见的。如果您不向容器添加自定义标记,它将尝试从注册表中提取当前版本,并且容器可能不包含所需的更改。创建自定义镜像时,使用镜像标签和SemVersions来跟踪对Docker容器的更改。当它们在Kubernetes集群中运行时,Kubernetes使用图像标签来确定应该运行哪个版本。在选择Docker镜像版本机制时,应该同时考虑生产负载和开发过程,这样才能在Kubernetes中取得更好的效果。10.安全性在很多情况下,在构建Docker镜像时,需要允许容器内的应用程序访问敏感数据,例如API令牌、私钥和数据库连接字符串。将这些秘密嵌入到容器中并不是一个安全的解决方案,即使只嵌入到私有容器镜像中也是如此。将未加密的私有数据作为Docker镜像的一部分进行处理会带来许多额外的安全风险,包括网络和镜像注册表安全,并且Docker架构本身规定容器中未加密的敏感数据无法优化。相反,用户可以使用KubernetesSecrets对象将私有信息存储在容器外,这样更简单、更安全。Kubernetes提供了一个Secrets抽象,允许在Docker镜像或Pod定义之外存储私有数据。用户可以通过挂载卷或环境变量将这些信息加载到容器中。更新时,只需更换相关服务的Pod,使用新的证书即可。用户还可以通过HashicorpVault和BitnamiSealedSecrets存储隐私数据。
