基于Google云原生工程师的kubernetes最佳实践(一)

本文介绍了Google云原生工程师推荐的Kubernetes容器使用最佳实践,包括选择官方镜像、静态安全扫描、减小基础镜像大小、采用多阶段构建、使用非root用户、只读挂载、单进程运行和利用dumb-init避免僵尸进程等。
摘要由CSDN通过智能技术生成

目录

前言

一、构建容器篇

不要信任任意的基础镜像,尽量使用官方镜像

使用工具对容器镜像进行静态安全扫描分析

使用尽可能小的基础镜像,减少attack surface

采用builder模式,将编译环境和运行时环境分离

在容器内使用非root用户运行进程

将容器文件系统挂载为只读

每个容器只运行一个进程。进程不要在失败时重启,应干净地退出

将日志打印到stdout/stderr,而不是文件。

使用类似dumb-init工具防止僵尸进程

Google云原生工程师最佳实践指南下载


前言

        Kubernetes作为广泛使用的容器编排平台,具有很强的灵活性。但要发挥它的全部潜力,避免使用中的各种陷阱,还需要遵循一些最佳实践。本文将从Google云原生工程师发布的Kubernetes_Best_Practices PDF文件分析,结合自身经验从构建容器、部署应用、服务发现、集群管理等几个方面,总结kubernetes的最佳实践。

一、构建容器

不要信任任意的基础镜像,尽量使用官方镜像

        在构建容器时,我们常常要基于一个base image。但是,如果使用一些来源不明的base image,很可能存在安全隐患。因为你不知道image作者是否在系统中留下了后门。因此,尽量选择官方镜像作为base image,如果没有官方镜像,也要尽量选择可信赖的来源。


使用工具对容器镜像进行静态安全扫描分析

        即使我们选择了可信的base image,也不能完全放心。因为在往下构建的过程中,我们可能会引入一些有漏洞的依赖。因此,在构建完成后,要使用trivy等工具对容器镜像进行静态安全扫描分析,及时发现和修复漏洞。往往容器安全更容易让人忽略,可能使用的基础镜像本身就带有一些系统级别的安全漏洞

下图为使用trivy扫描centos某版本的基础镜像的输出结果


使用尽可能小的基础镜像,减少attack surface

        一个原则是容器镜像要尽量小,其中包含的组件尽量少。这样可以减小容器的attack surface,降低被攻击的风险。比如对于node.js应用,使用node:alpine要优于使用node镜像。node:alpine是一个面向安全的最小化的node基础镜像,而node镜像中包含了很多调试工具,是不必要的。

Alpine与主流基础镜像Centos等区别:

        Alpine Linux使用了musl作为其标准C库(libc)。musl是一个轻量级的C库实现,专为嵌入式系统和容器环境设计。musl与glibc相比,体积更小,启动速度更快,但在功能和兼容性方面有一些限制。
        CentOS使用的是glibc(GNU C Library)作为标准C库。glibc是一个功能完善、广泛使用的C库实现,提供了丰富的系统调用和库函数。glibc与Linux生态系统高度兼容,支持广泛的软件包和应用程序。


采用builder模式,将编译环境和运行时环境分离

        多阶段构建(Multi-stage Builds)是Docker 17.05版本引入的一个新特性。它允许在一个Dockerfile中使用多个FROM指令,每个FROM指令都可以使用不同的基础镜像,并且每个FROM指令都开始一个新的构建阶段。

        多阶段构建的主要目的是将构建过程分为多个独立的阶段,每个阶段生成一个独立的镜像。后续阶段可以使用前面阶段生成的镜像作为基础镜像,从而实现构建环境和运行环境的分离,有效减小最终镜像的体积。

Multi-stage Builds Dockerfile示例

# 第一阶段:构建阶段
FROM golang:1.16-alpine AS builder
 
WORKDIR /app
 
# 复制Go模块文件并下载依赖
COPY go.mod go.sum ./
RUN go mod download
 
# 复制应用程序源码并构建
COPY . .
RUN go build -o main .
 
# 第二阶段:运行阶段
FROM alpine:latest
 
WORKDIR /app
 
# 从构建阶段复制构建好的二进制文件
COPY --from=builder /app/main .
 
# 设置容器的默认启动命令
CMD ["./main"]



在容器内使用非root用户运行进程

FROM node:14
 
RUN useradd --create-home appuser
USER appuser


将容器文件系统挂载为只读

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.19
        volumeMounts:
        - name: nginx-root
          mountPath: /usr/share/nginx/html
          readOnly: true             #将文件系统设置为只读
      volumes:
      - name: nginx-root
        emptyDir: {}


每个容器只运行一个进程。进程不要在失败时重启,应干净地退出

        遵循一个容器只运行一个进程的最佳实践,可以使容器的行为更加一致可预测。当该进程异常退出时,容器也会完全终止,而不是留下孤儿进程。这样更容易进行监控和管理。同时,要让进程在发生错误时能够适当地退出而不是重启,促进容器的不可变性和幂等性。

        不要通过systemd等方式将业务进程封装成容器,否则可能导致业务进程变为孤儿进程,容器无法准确监控其状态。这可能会出现业务进程卡死,而容器仍在运行的情况。


将日志打印到stdout/stderr,而不是文件。

        容器中的进程应该将日志信息直接写到stdout和stderr,而不是写到文件系统中的日志文件。Kubernetes会自动收集和管理容器的stdout和stderr输出,以提供集中式的日志解决方案。


使用类似dumb-init工具防止僵尸进程

        在容器中使用类似dumb-init这样的工具来避免出现僵尸进程是一种很好的实践。僵尸进程是指一个子进程在父进程退出后,仍然保留在进程表中的进程。如果不加以处理,僵尸进程会一直占用系统资源,并且在容器退出后也不会自动清理。

        dumb-init是一个非常小巧的系统工具,它的作用是在容器启动时先启动一个监护进程(dumb-init),此后容器内的其他进程都将作为dumb-init的子进程运行。这样当子进程退出时,dumb-init就会正常接管它们的終止狀態信號,避免出现僵尸进程。

dumb-init Dockerfile示例

FROM ubuntu:18.04

# 安装dumb-init
RUN apt-get update && apt-get install -y dumb-init

# 应用程序代码...

# 使用dumb-init启动应用
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD ["executable", "param1", "param2"]

 在这个例子中:

        1. 我们从Ubuntu 18.04基础镜像开始构建。
        2. 安装dumb-init工具。
        3. 复制应用程序代码(步骤省略)。
        4. 使用ENTRYPOINT将dumb-init设置为入口点。
        5. CMD指令指定了实际要运行的应用程序及其参数。

        当启动该容器时,dumb-init会先启动,然后调用CMD指定的命令启动应用程序进程。应用程序进程将作为dumb-init的子进程运行。如果应用进程异常退出,dumb-init会正确处理它的终止信号,避免出现僵尸进程。

        使用dumb-init的另一个好处是,它还会正确处理信号,并将它们传递给应用程序进程。这对于基于信号的正常关停流程非常有帮助。

        总之,dumb-init是一个非常轻量且有用的工具,能够解决容器中常见的僵尸进程问题,并提高容器进程的健壮性。许多公司和项目都在使用它来改善容器的运行时行为。

Google云原生工程师最佳实践指南下载

Kubernetes_Best_Practices.pdficon-default.png?t=N7T8https://c74p900o8m.feishu.cn/docx/S84ddjQg2oQRpMxxOykcdP8Snsc

  • 25
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值