多种方案图文并茂分分钟教你解决Kubernetes(k8s)容器安全问题(不断更新中)

news2024/11/25 8:22:54

文章目录

    • Kubernetes(k8s)Secrets in clear text environment variables 明文中的秘密环境变量
        • 问题详解
    • 解决方案一
        • STEP1: 创建Kubernetes Secret - 编写一个yaml文件
        • STEP2: 部署执行上述yaml
        • STEP3: 将Secret作为卷挂载到Pod中-在项目部署K8S.yaml中挂载Secrets
        • 代码实战案例
    • 解决方案二
        • STEP1: 创建Kubernetes Secret - 编写一个yaml文件
        • STEP2: 部署执行上述yaml
        • STEP3: 将密钥作为环境变量使用-在项目部署K8S.yaml中直接配置env
    • 解决方案三(超级推荐)
        • 创建Secret
        • 挂载Secret
        • 案例截图
    • Container is running as root 容器以root 身份运行
        • 问题详解
    • 解决方案一:制作镜像的时候就使用非root用户运行(较为麻烦,需要重新打包镜像,建议先尝试方案二,如果不行再参考这个)
        • 解决思路:修改Dockerfile或容器镜像,确保应用可以在非root用户下正常运行,使用非root用户运行容器
      • bind() to 0.0.0.0:80 failed (13: Permission denied)
        • 问题分析:
        • 问题解决:
        • 代码举例:
    • 解决方案二:使用Security Context(设置简单方便,推荐这种方案)
        • 问题示例
        • 解决方案
        • 代码实战案例
    • Do not disable default seccomp profile 不禁用默认的seccomp配置文件
        • 问题详解
    • 解决方案(超级简单)
        • 代码实战案例
    • Restrict container from acquiring additional privileges 限制容器获得额外特权
        • 问题详解
    • 解决方案
    • Mount container's root filesystem as read only 将容器的根文件系统装载为只读
        • 问题详解
    • 解决方案
        • 在 Pod 的 YAML 配置中的容器 securityContext 字段下设置 readOnlyRootFilesystem 为 true
    • Read-only file system 问题解决
      • 文件夹只读问题解决:如果你要在readOnlyRootFilesystem: true状态下,读写一个文件夹
        • 方案一:EmptyDir Volume - 动态创建一个临时存储卷,该卷的生命周期与 Pod 相同,但不持久化数据。
        • 代码实战案例
        • 方案二:HostPath Volume - 将主机上的目录挂载到容器内,适用于单节点测试或有特定需求的场景。(很少用这个,一般我们通常都是多节点,所以都不用这个挂载哦~~)
        • 方案三:PersistentVolumeClaim (PVC)-对于需要持久化存储的数据,使用 PVC 绑定到 PersistentVolume (PV),实现数据的持久化存储。(持久或者重要的数据,一定要使用这个)
          • 创建PVC
          • 挂载
        • 代码实战案例
      • 单个文件只读问题解决:如果你要在readOnlyRootFilesystem: true状态下,读写单个文件
        • 方案一:使用 EmptyDir 实现单个文件可写
        • 代码
        • 方案二:使用软链接(Symbolic Link)
        • 代码示例1:在dockerfile中使用软链接,然后打包镜像,再使用新镜像运行yaml
        • 代码示例2:在dockerfile中使用软链接,然后打包镜像,再使用新镜像运行yaml
          • ==注意事项==
        • 方案三:使用 PersistentVolumeClaim (PVC) 实现持久化文件写入
        • 代码:创建 PersistentVolumeClaim (PVC) yaml
        • 代码:部署yaml,此处以Pod为例吧~
    • [spec.jobTemplate.spec.template.spec.volumes[3].configMap.defaultMode: Invalid value: 755: must be a number between 0 and 0777 (octal), both inclusive
    • 解决方案
    • 使用Init Containers初始化你的文件夹或者文件~
        • 为什么要考虑到使用Init Containers?
        • Kubernetes不可不知的服务执行顺序
        • 如果我配置了/app/xiaojin目录为emptyDir实现可写,如何初始化这个文件夹的内容呢
    • 结语
        • 欢迎路过的小哥哥小姐姐们提出更好的意见哇~~

Kubernetes(k8s)Secrets in clear text environment variables 明文中的秘密环境变量

问题详解
  • 在Kubernetes(k8s)中,Secrets用于管理诸如密码、令牌和密钥等敏感信息。安全地存储这些密钥至关重要。然而,将密钥直接注入到明文环境变量中可能会使它们面临潜在的安全风险。
  • 在 Kubernetes 集群中,容器能够通过环境变量查询到其他 Service的信息,是因为Kubernetes 在调度Pod时,会自动为每个Service创建一组环境变量。这些环境变量包含了Service的名称、Cluster IP 地址(内部虚拟 IP)、以及 Service 监听的端口等信息。这是 Kubernetes 内置的服务发现机制的一部分,旨在帮助集群内的 Pod 之间进行通信。
  • Kubernetes通过环境变量为每个Service创建一个服务发现记录。这些记录允许Pod通过Service 名称来发现和连接到其他 Service,而无需知道它们的IP 地址或端口。

解决方案一

STEP1: 创建Kubernetes Secret - 编写一个yaml文件

注意,这里的值需要进行base64编码

apiVersion: v1
kind: Secret
metadata:
  name: 我的密钥
type: Opaque
data:
  PASSWORD: <base64编码的密码>
  API_KEY: <base64编码的API密钥>
STEP2: 部署执行上述yaml
STEP3: 将Secret作为卷挂载到Pod中-在项目部署K8S.yaml中挂载Secrets

相较于直接注入环境变量,更安全的做法是将Secret作为卷挂载到Pod中。这样,密钥数据将以文件形式存在于容器的文件系统中。

apiVersion: v1
kind: Pod
metadata:
  name: 我的Pod
spec:
  containers:
  - name: 我的容器
    image: 我的镜像
    volumeMounts:
    - name: 密钥卷
      mountPath: /var/密钥
      readOnly: true
  volumes:
  - name: 密钥卷
    secret:
      secretName: 我的密钥
代码实战案例

下面是我写过的一个的sqlserver创建yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: xiaojin-sqlserver-dev-deployment
spec:
  replicas: 1
  selector:
     matchLabels:
       app: xiaojin-sqlserver-dev
  template:
    metadata:
      labels:
        app: xiaojin-sqlserver-dev
    spec:
      terminationGracePeriodSeconds: 30
      hostname: mssqlinst
      securityContext:
        fsGroup: 10001
      containers:
      - name: xiaojin-sqlserver-dev
        image: mcr.microsoft.com/mssql/server:2022-latest
        ports:
        - containerPort: 1433
        env:
        - name: MSSQL_PID
          value: "Developer"
        - name: ACCEPT_EULA
          value: "Y"
        - name: MSSQL_SA_PASSWORD
          valueFrom:
            secretKeyRef:
              name: xiaojin-sqlserver-dev
              key: MSSQL_SA_PASSWORD
---
apiVersion: v1
data:
  MSSQL_SA_PASSWORD: WGlhb2ppbkAxMjNoYWhh   # 等同于密码Xiaojin@123haha
kind: Secret
metadata:
  creationTimestamp: null
  name: xiaojin-sqlserver-dev
  namespace: xiaojin


---
apiVersion: v1
kind: Service
metadata:
  name: xiaojin-sqlserver-dev
  namespace: xiaojin
spec:
  type: NodePort
  selector:
    app: xiaojin-sqlserver-dev
  ports:
    - name: xiaojin-sqlserver-dev
      protocol: TCP
      port: 1433
      targetPort: 1433
      nodePort: 30034

  type: NodePort

解决方案二

STEP1: 创建Kubernetes Secret - 编写一个yaml文件

注意,这里的值需要进行base64编码

apiVersion: v1
kind: Secret
metadata:
  name: 我的密钥
type: Opaque
data:
  PASSWORD: <base64编码的密码>
  API_KEY: <base64编码的API密钥>
STEP2: 部署执行上述yaml
STEP3: 将密钥作为环境变量使用-在项目部署K8S.yaml中直接配置env

如果你非要将密钥作为环境变量使用,这种方式比直接文件挂载安全性稍低,写法如下(下面代码是复制到你的k8s.yaml部署文件里哦)

env:
- name: PASSWORD
  valueFrom:
    secretKeyRef:
      name: 我的密钥
      key: PASSWORD

解决方案三(超级推荐)

在Kubernetes中,挂载Secret以便容器能够安全地访问敏感信息(如密码、API密钥等)是一种常见做法。

创建Secret

同上,可以参考上面方案中的创建步骤

挂载Secret
apiVersion: v1
kind: Pod
metadata:
  name: my-app-secret
spec:
  containers:
  - name: my-app-container
    image: my-app-image
    volumeMounts:
    - name: secret-volume # 与volumes中定义的卷名称对应
      mountPath: "/app/secrets" # 容器内挂载路径
      readOnly: true # 为了安全,通常设置为只读
  volumes:
  - name: secret-volume # Secret卷定义
    secret:
      secretName: my-secret-name # Secret的名称
案例截图

Container is running as root 容器以root 身份运行

问题详解

当容器以root身份运行的情况下,具有包括但不限于以下几点影响:

  • 最高权限访问:容器内的进程可以不受限制地访问宿主机的资源,包括文件系统、网络接口和其他运行中的进程。
  • 修改系统配置:能够修改系统级别的配置文件,安装系统包,甚至修改内核参数。
  • 安全风险:如果容器内的服务或应用程序存在安全漏洞,攻击者可以利用root权限对整个系统造成严重影响,包括数据窃取、植入恶意软件或完全控制宿主机。

解决方案一:制作镜像的时候就使用非root用户运行(较为麻烦,需要重新打包镜像,建议先尝试方案二,如果不行再参考这个)

Kubernetes推荐使用非root用户运行容器,以遵循最小权限原则。通过指定容器以普通用户身份运行,可以显著降低潜在的安全风险。

  • (CIS_Docker_v1.2.0 - 4.1) Image should be created with a non-root user 或者遇到 /var/run/nginx.pid" failed (13: Permission denied)也一样可以采用此方案解决
解决思路:修改Dockerfile或容器镜像,确保应用可以在非root用户下正常运行,使用非root用户运行容器

dockerfile加入下面代码

RUN adduser -D xiaojin
USER xiaojin

在这里插入图片描述

k8s yaml 加入下面代码

 securityContext:
         runAsUser: 0

在这里插入图片描述

且修改以后,如果是nginx,可能还会遇到其他问题,我把你可能遇到的问题处理方案放在后面啦

bind() to 0.0.0.0:80 failed (13: Permission denied)

XXXXXXXX pm2023/06/05 08:04:39 [warn] 1#1: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2
XXXXXXXX pmnginx: [warn] the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2
Mon, Jun 5 2023 4:04:41 pm2023/06/05 08:04:39 [emerg] 1#1: bind() to 0.0.0.0:80 failed (13: Permission denied)
Mon, Jun 5 2023 4:04:41 pmnginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)
问题分析:

某些情况下,非Root用户不能绑定1024以下端口,否则会报错:没有权限绑定该端口

问题解决:
  • 修改Dockerfile中的端口配置
  • nginx.conf中的端口监听
  • k8s.yml中的服务端口暴露配置
  • containerPort配置
    所有你项目中nginx绑定的都要修改一遍哦~~
代码举例:



解决方案二:使用Security Context(设置简单方便,推荐这种方案)

Kubernetes提供了securityContext字段,允许用户在Pod或容器级别设置安全策略,比如指定运行用户(runAsUser)和组(runAsGroup),以及是否允许容器以特权模式运行(privileged)。

问题示例
  • 运行脚本无权限/bin/sh: ./bxxx.sh: Permission denied 可以采用此方案解决
StartError (failed to create containerd task: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/var/lib/kubelet/pods/149aaaaaa/volume-xxx/xxx/0" to rootfs at "/app/logs": mount /var/lib/kubelet/pods/149xxx/0:/app/logs (via /proc/self/fd/6), flags: 0x5001: not a directory: unknown)


/bin/sh: ./xxx.sh: Permission denied
解决方案
  apiVersion: v1
  kind: Pod
  metadata:
    name: my-pod
  spec:
    securityContext:
      runAsUser: 1000
    containers:
    - name: my-container
      image: my-image
      securityContext:
        runAsNonRoot: true # 重点代码
        runAsUser: 1000 # 重点代码
代码实战案例

Do not disable default seccomp profile 不禁用默认的seccomp配置文件

问题详解

在Kubernetes(k8s)中,Seccomp(Secure Computing Mode)是一种Linux内核安全特性,用于限制容器内进程可以执行的系统调用,以此增强容器的安全性并降低潜在的攻击面。Kubernetes默认为Pod提供了一个基本的Seccomp配置文件(默认配置文件),这个配置文件定义了一系列允许或拒绝的系统调用规则,旨在阻止不安全或不必要的系统调用行为。不要禁用默认Seccomp配置文件的原因包括:

  • 减少攻击面:默认的Seccomp配置有助于防止容器执行危险的系统调用,如那些可以修改系统时间、重启系统或执行其他对宿主机有潜在危害的操作。这减少了容器逃逸攻击的可能性。
  • 安全最佳实践:遵循Kubernetes社区推荐的安全最佳实践,其中就包括保留默认Seccomp配置。这有助于维护一个统一的安全标准,使得集群管理更加规范和安全。
  • 细粒度控制:虽然默认配置已经足够安全,但Kubernetes还允许自定义Seccomp配置以达到更细粒度的控制。禁用默认配置意味着放弃这种细粒度控制的机会,除非有明确且必要的理由去定制化配置。
  • 性能影响小:启用Seccomp对容器的性能影响微乎其微,尤其是在使用默认配置时。因此,保持默认配置开启不会对应用的运行效率产生显著负面影响。
  • 易于升级和维护:随着Kubernetes和Seccomp规则的发展,默认配置会不断更新以应对新的安全威胁。禁用默认配置可能意味着错过这些自动更新,增加手动维护成本和安全风险

解决方案(超级简单)

 containers:
        - image: myImage:v1
          imagePullPolicy: Always
          securityContext:                         
            seccompProfile:   # 重点代码                      
              type: RuntimeDefault  # 重点代码 
代码实战案例

Restrict container from acquiring additional privileges 限制容器获得额外特权

问题详解
  • 在 Kubernetes (k8s) 中,“Restrict container from acquiring additional privileges” 是一项安全措施,旨在限制容器运行时获得超出其初始分配权限的能力。这主要是通过 Pod 的安全上下文中的 securityContext 配置来实现的,特别是利用 runAsUser、runAsGroup、fsGroup 以及 allowPrivilegeEscalation 等字段。
  • allowPrivilegeEscalation: 这是一个布尔值,当设置为 false 时,会阻止容器内的进程提升其自身的权限(例如,从非 root 用户变为 root 用户)。这是直接限制容器获取额外权限的关键设置。

解决方案

 securityContext:                          
       allowPrivilegeEscalation: false  # 重点代码

Mount container’s root filesystem as read only 将容器的根文件系统装载为只读

问题详解
  • 在 Kubernetes (k8s) 中,将容器的根文件系统挂载为只读是一种提高容器安全性和稳定性的做法。
  • 这意味着容器内的进程不能修改其根 (/) 目录下的任何文件或目录。这对于运行无状态服务或者防止恶意修改系统文件特别有用。

解决方案

在 Pod 的 YAML 配置中的容器 securityContext 字段下设置 readOnlyRootFilesystem 为 true
apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  containers:
  - name: example-container
    image: your-container-image
    securityContext:
      readOnlyRootFilesystem: true # 这里设置了根文件系统为只读
    # 其他容器配置...
  # 其他 Pod 配置...

注意,如果你的容器需要写入文件(比如日志、临时文件或应用数据),你做了上面的配置以后,会遇到无法写入文件的问题,例如会遇到项目启动报错:Read-only file system,可参考下面的解决方案

Read-only file system 问题解决

此问题分为两种,单个文件需要权限写入以及多个文件(建议使用文件夹来管理)需要获取写入权限,下面会根据不同来进行分析解决

文件夹只读问题解决:如果你要在readOnlyRootFilesystem: true状态下,读写一个文件夹

方案一:EmptyDir Volume - 动态创建一个临时存储卷,该卷的生命周期与 Pod 相同,但不持久化数据。
   volumeMounts:
   - mountPath: /var/log   # 需要获取读写权限的文件夹
     name: temp-log-volume   # 自己命名就好
   volumes:
   - name: temp-log-volume   # 自己命名就好
     emptyDir: {}   # 不需要改动,你就这么抄就行了
代码实战案例

方案二:HostPath Volume - 将主机上的目录挂载到容器内,适用于单节点测试或有特定需求的场景。(很少用这个,一般我们通常都是多节点,所以都不用这个挂载哦~~)
   volumeMounts:
   - mountPath: /var/data
     name: host-data-volume
   volumes:
   - name: host-data-volume
     hostPath:
       path: /data/on/host
       type: Directory
方案三:PersistentVolumeClaim (PVC)-对于需要持久化存储的数据,使用 PVC 绑定到 PersistentVolume (PV),实现数据的持久化存储。(持久或者重要的数据,一定要使用这个)
创建PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

挂载
   volumeMounts:
   - mountPath: /var/persistent-data
     name: persistent-data-volume
   volumes:
   - name: persistent-data-volume
     persistentVolumeClaim:
       claimName: my-pvc
代码实战案例

因此步骤可以展开的有点多,所以可以参考我的其他文章:如何在 Kubernetes (k8s)创建并使用PersistentVolumeClaim (PVC)

单个文件只读问题解决:如果你要在readOnlyRootFilesystem: true状态下,读写单个文件

方案一:使用 EmptyDir 实现单个文件可写
  • 如果是已经存在的文件,需要设置为可写,我们可以使用Init Containers(初始化容器)把资料搞进去,下面有Init Containers用法=
  • 尽管 EmptyDir 提供的是临时存储,但它是可写的,适合存放那些不需持久保存的数据。如果确实只需要单个文件可写,可以通过在 Pod 定义中挂载 EmptyDir 卷并使用 subPath 技巧来模拟单文件写入。
代码

这个我还没试过,最近太忙啦,小伙伴帮我试试看

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  securityContext:
    readOnlyRootFilesystem: true
  containers:
  - name: my-container
    image: my-image
    volumeMounts:
    - name: temp-file-volume
      mountPath: /path/to/writable/file # 期望文件可写的位置
      subPath: writable.txt # 指定文件名
  volumes:
  - name: temp-file-volume
    emptyDir: {}
方案二:使用软链接(Symbolic Link)
  • 此种类型使用起来比较麻烦,大家酌情选择
  • 在容器启动脚本中创建一个从挂载的目录到所需文件的软链接。这要求你的应用能够接受通过软链接访问配置文件。但这种方法增加了容器配置的复杂度,并且不如直接使用subPath优雅。
  • 在readOnlyRootFilesystem: true的约束下,直接在容器的只读文件系统中创建软链接至可写位置(如外部卷或宿主机目录)是不可行的,因为创建软链接本身也算作是对文件系统的写操作。但是,你可以在构建镜像时预先创建软链接至一个预期会在运行时挂载为可写卷的目录。
代码示例1:在dockerfile中使用软链接,然后打包镜像,再使用新镜像运行yaml

下面是一个nginx镜像部署普通前端代码的dockerfile案例,代码中两个RUN指令向/entrypoint.sh文件末尾追加内容

  • 第一条指令将/dev/stdout链接到/opt/nginx/log/nginx/access.log
  • 第二条指令将/dev/stderr链接到/opt/nginx/log/nginx/error.log
FROM node:16.14.2-alpine as build
WORKDIR /app
COPY package.json .npmrc ./
RUN npm config set strict-ssl false
RUN npm config set registry https://registry.npmmirror.com && npm install

COPY . ./
RUN npm run lint:fix
RUN npm run build

FROM docker/nginx:1.25.4-bookworm
COPY --from=build /app/dist/ /usr/share/nginx/html
COPY nginx-uat.conf /etc/nginx/conf.d/default.conf

RUN useradd -m xiaojin
RUN sed -i 's|/var/|/opt/nginx/|' /etc/nginx/nginx.conf  
RUN echo '#!/bin/sh' > /entrypoint.sh    
RUN echo 'mkdir -p /opt/nginx/log/nginx' >> /entrypoint.sh 
RUN echo 'mkdir -p /opt/nginx/run' >> /entrypoint.sh 
RUN echo 'touch /opt/nginx/log/nginx/error.log' >> /entrypoint.sh   
RUN echo 'touch /opt/nginx/log/nginx/access.log' >> /entrypoint.sh   
RUN echo 'ln -sf /dev/stdout /opt/nginx/log/nginx/access.log' >> /entrypoint.sh  # 关键代码
RUN echo 'ln -sf /dev/stderr /opt/nginx/log/nginx/error.log' >> /entrypoint.sh  # 关键代码
RUN echo 'touch /opt/nginx/run/nginx.pid' >> /entrypoint.sh      
RUN echo 'chown -R xiaojin:xiaojin /opt/nginx' >> /entrypoint.sh   
RUN echo 'exec nginx -g "daemon off;"' >> /entrypoint.sh          
RUN chmod +x /entrypoint.sh                                    

CMD ["/entrypoint.sh"]    

USER xiaojin
代码示例2:在dockerfile中使用软链接,然后打包镜像,再使用新镜像运行yaml

假设现在项目中有个文件是:/app/readonly/xiaojin.json,但是目前它是只读的,我想要将它改为可写,怎么办呢?我们可以在运行时挂载一个卷到/var/data,并且应用需要写入xiaojin.json,你可以在Dockerfile中这样写代码:

# 在构建镜像时创建软链接
RUN mkdir -p /var/data && \
    ln -s /var/data/xiaojin.json /app/readonly/xiaojin.json

尽管容器的根文件系统是只读的,但通过软链接 /app/readonly/xiaojin.json 写入的数据实际上会存储在可写的/var/data/xiaojin.json中

注意事项
  • 这种方法要求在构建镜像时明确知道运行时卷的挂载点
  • 软链接本身及其目标目录(在本例中为/var/data)必须在容器启动前就存在或被正确挂载,否则软链接将无效或指向不存在的位置
  • 安全性考虑:确保软链接不会意外地指向容器中敏感或重要的文件系统部分,特别是当容器的其他部分可能对这些链接有写权限时
方案三:使用 PersistentVolumeClaim (PVC) 实现持久化文件写入

对于需要持久化的文件,应该创建一个 PersistentVolumeClaim (PVC),然后在 Pod 中挂载该 PVC。

代码:创建 PersistentVolumeClaim (PVC) yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce # 可选模式有:ReadWriteOnce、ReadOnlyMany、ReadWriteMany
  resources:
    requests:
      storage: 1Gi # 请求1GiB的存储空间
  storageClassName: standard # 如果使用动态卷,则需指定存储类名称
  • accessModes: 指定如何访问存储卷,常见的有只读多路(ReadOnlyMany)、读写一次(ReadWriteOnce)、读写多路(ReadWriteMany)。
  • resources.requests.storage: 请求的存储空间大小。
  • storageClassName: 如果希望 Kubernetes 自动为你创建 PV(使用动态存储供给),则需要指定一个存在的存储类
代码:部署yaml,此处以Pod为例吧~

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  securityContext:
    readOnlyRootFilesystem: true
  containers:
  - name: my-container
    image: my-image
    volumeMounts:
    - name: persistent-file-volume
      mountPath: /path/to/persistent/file
  volumes:
  - name: persistent-file-volume
    persistentVolumeClaim:
      claimName: my-pvc

[spec.jobTemplate.spec.template.spec.volumes[3].configMap.defaultMode: Invalid value: 755: must be a number between 0 and 0777 (octal), both inclusive

解决方案

这个一般出现在修改configMap.defaultMode的时候,解决它非常简单,yaml文件使用命令行执行,不要使用网页端修改和保存就OK了

使用Init Containers初始化你的文件夹或者文件~

为什么要考虑到使用Init Containers?
  • 当挂载点目录与已存在的目录重名时,挂载的卷(不论是EmptyDir、PersistentVolumeClaim还是ConfigMap等)会覆盖原有的目录内容。这意味着原有的目录及其内容在Pod运行期间将不可见,取而代之的是挂载卷提供的内容。
Kubernetes不可不知的服务执行顺序

在Kubernetes中,Init Containers 会比 应用容器(主容器)中的目录挂载先执行。Init Containers的设计目的就是在任何应用容器启动之前执行初始化任务,包括但不限于预填充数据、设置配置、甚至等待依赖服务就绪。具体流程如下所示:

  • Pod调度:Kubernetes调度器找到合适的节点来运行Pod。
  • 创建网络接口和存储卷:为Pod创建必要的网络接口和挂载存储卷。
  • Init Container执行:按顺序执行Init Containers,每个Init Container必须成功结束,下一个才能开始。在此阶段,应用容器尚未启动,但存储卷(包括EmptyDir)已经挂载。
  • 主容器启动:所有Init Containers成功执行完毕后,应用容器开始启动。此时,应用容器会挂载相同的存储卷,可以看到由Init Containers创建或修改的任何文件和目录。
如果我配置了/app/xiaojin目录为emptyDir实现可写,如何初始化这个文件夹的内容呢
apiVersion: v1
kind: Pod
metadata:
  name: my-app-init-xiaojin
spec:
  initContainers: # 初始化容器部分
  - name: init-xiaojin-directory
    image: busybox:latest # 使用包含基础命令的镜像,如mkdir、touch等
    command: ['sh', '-c', "mkdir -p /mnt/xiaojin && echo 'Initial content' > /mnt/xiaojin/initial_file.txt"] # 初始化命令
    volumeMounts: # 挂载卷
    - name: xiaojin-emptydir # 与下面volumes中定义的卷名称对应
      mountPath: /mnt/xiaojin # Init Container中挂载的路径
  containers: # 应用容器部分
  - name: my-app-container
    image: my-app-image
    volumeMounts:
    - name: xiaojin-emptydir
      mountPath: /app/xiaojin # 应用容器中挂载的路径
  volumes: # 卷定义
  - name: xiaojin-emptydir
    emptyDir: {} # 使用emptyDir卷

尽管Init Container直接操作的是/mnt/xiaojin,但所有在/mnt/xiaojin下的更改都会反映到与之共享相同emptyDir卷的/app/xiaojin目录中,通过共享emptyDir卷,Init Container对/mnt/xiaojin的初始化操作等同于间接初始化了/app/xiaojin目录的内容。
上面这个我是查资料写的,没试过,等我忙完了贴initContainer的实战截图

结语

  • 今天就写到这里啦~
  • 小伙伴们,( ̄ω ̄( ̄ω ̄〃 ( ̄ω ̄〃)ゝ我们明天再见啦~~
  • 大家要天天开心哦

欢迎大家指出文章需要改正之处~
学无止境,合作共赢

在这里插入图片描述

欢迎路过的小哥哥小姐姐们提出更好的意见哇~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1830086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Perl】与【Excel】

引言 perl脚本语言对于文本的处理、转换很强大。对于一些信息量庞大的文本文件&#xff0c;看起来不直观&#xff0c;可以将信息提取至excel表格中&#xff0c;增加数据分析的可视化。perl语言的cpan提供了大量模块。对于excel文件的操作主要用到模块&#xff1a; Spreadshee…

1970python高校教室管理系统mysql数据库Django框架bootstrap布局计算机软件工程网页

一、源码特点 python Django 高校教室管理系统是一套完善的web设计系统mysql数据库 &#xff0c;对理解python编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 python Django 高校教室管理系统 开发环境pycharm mys…

2.华为配置静态路由

通过配置静态路由让PC1和PC2互通 AR1 [Huawei]int g0/0/0 [Huawei-GigabitEthernet0/0/0]ip add 192.168.1.254 24 [Huawei]int g0/0/1 [Huawei-GigabitEthernet0/0/1]ip add 1.1.1.1 24 [Huawei]ip route-static 192.168.2.0 24 1.1.1.2AR2 [Huawei]int g0/0/0 [Huawei-Gig…

ARM Linux 设备树详细介绍(2)共二篇

承接上文&#xff0c;第一篇 3. Device&Tree 引发的 BSP 和驱动变更 有了 Device Tree 后&#xff0c;大量的板级信息都不再需要&#xff0c;譬如过去经常在 arch/arm/plat-xxx 和 arch/arm/mach-xxx 实施的如下事情&#xff1a; 1. 注册 platform_device&#xff0c;绑定 …

《人生海海》读后感

麦家是写谍战的高手&#xff0c;《暗算》《风声》等等作品被搬上荧屏后&#xff0c;掀起了一阵一阵的收视狂潮。麦家声名远扬我自然是知道的&#xff0c;然而我对谍战似乎总是提不起兴趣&#xff0c;因此从来没有拜读过他的作品。这几天无聊时在网上找找看看&#xff0c;发现了…

从xxl-job源码中学习Netty的使用

1. 启动与Spring实例化 com.xxl.job.core.executor.impl.XxlJobSpringExecutor.java类 继承SmartInitializingSingleton 类&#xff0c;在afterSingletonsInstantiated 实例化后方法中 调用initJobHandlerMethodRepository 把所有的xxljob任务管理起来&#xff1b; private…

ARM Linux 设备树详细介绍(1)

1. ARM&Device&Tree 起源 Linus Torvalds 在 2011 年 3 月 17 日的 ARM Linux 邮件列表宣称“this whole ARM thing is a f*cking pain in the ass”&#xff0c;引发 ARM Linux 社区的地震&#xff0c;随后 ARM 社区进行了一系列 的重大修正。 在过去的 ARM Linux 中&…

电子电气架构 --- 智能座舱功能应用

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…

springCloudAlibaba之分布式网关组件---gateway

gateway-网关 网关spring cloud gatewaygateway初体验gateway整合nacos简写方式 网关 在微服务架构中一个系统会被拆分成多个微服务。那么作为客户端(前端)要如何去调用这么多的微服务&#xff1f;如果没有网关的存在&#xff0c;我们只能在客户端记录每个微服务的地址&#xf…

工程设计问题---多盘离合器制动器设计问题

这个问题的主要目的是使多片式离合器制动器的质量最小化。在这个问题中&#xff0c;使用了五个整数决策变量&#xff0c;它们是内半径&#xff08;x1&#xff09;、外半径&#xff08;x2&#xff09;、盘厚度&#xff08;x3&#xff09;、致动器的力&#xff08;x4&#xff09;…

【Mybatis-Plus】根据自定义注解实现自动加解密

背景 我们把数据存到数据库的时候&#xff0c;有些敏感字段是需要加密的&#xff0c;从数据库查出来再进行解密。如果存在多张表或者多个地方需要对部分字段进行加解密操作&#xff0c;每个地方都手写一次加解密的动作&#xff0c;显然不是最好的选择。如果我们使用的是Mybati…

基于WPF技术的换热站智能监控系统13--控制设备开关

1、本节目的 本次工作量相对有点大&#xff0c;有点难度&#xff0c;需要熟悉MVVM模式&#xff0c;特别是属性绑定和命令驱动&#xff0c;目标是点击水泵开关&#xff0c;让风扇转动或停止&#xff0c;风扇连接的管道液体流动或静止。 &#xff0c;具体对应关系是&#xff1a;…

单向散列函数解析

目录 1. 概述 2. 单向散列函数的性质 2.1 根据任意长度的消息计算出固定长度的散列值 2.2 能够快速计算出散列值 2.3 消息不同散列值也不同 2.4 具备单向性 3. 单向散列函数的算法 3.1 MD5 3.2 SHA序列 3.3 SM3 1. 概述 针对计算机所处理的消息&#xff0c;有时候我们…

【设计模式深度剖析】【9】【行为型】【访问者模式】| 以博物馆的导览员为例加深理解

&#x1f448;️上一篇:备忘录模式 设计模式-专栏&#x1f448;️ 文章目录 访问者模式定义英文原话直译如何理解呢&#xff1f; 访问者模式的角色类图代码示例 访问者模式的应用优点缺点使用场景 示例解析:博物馆的导览员代码示例 访问者模式 访问者模式&#xff08;Visito…

计算机毕业设计hadoop+spark+hive知识图谱酒店推荐系统 酒店数据分析可视化大屏 酒店爬虫 高德地图API 酒店预测系统 大数据毕业设计

流程&#xff1a; 1.Python爬取去哪儿网全站旅游数据约10万&#xff0c;存入mysql; 2.使用pandasnumpy/hadoopmapreduce对mysql中旅游数据进行数据清洗&#xff0c;使用高德API计算地理信息&#xff0c;最终转为.csv文件上传hdfs; 3.hive建库建表导入.csv文件作为数据集&#x…

2024年汉字小达人活动还有4个多月开赛:来做18道历年选择题备考吧

结合最近几年的活动安排&#xff0c;预计2024年第11届汉字小达人比赛还有4个多月就启动&#xff0c;那么孩子们如何利用这段时间有条不紊地准备汉字小达人比赛呢&#xff1f; 我的建议是充分利用即将到来的暑假&#xff1a;①把小学1-5年级的语文课本上的知识点熟悉&#xff0…

Windows11和Ubuntu22双系统安装指南

一、需求描述 台式机电脑&#xff0c;已有Windows11操作系统&#xff0c;想要安装Ubuntu22系统&#xff08;版本任意&#xff09;。其中Windows安装在Nvme固态上&#xff0c;Ubuntu安装在Sata固态上&#xff0c;双盘双系统。开机时使用Grub控制进入哪个系统&#xff0c;效果图…

直接选择排序-C语言版本

前言 直接选择排序也是一个比较简单的排序&#xff0c;所以这里放在第二个进行讲解&#xff0c;这里和冒泡排序是有一点相似。直接选择排序和冒泡排序一样&#xff0c;也是具备一定的教学意义&#xff0c;但是没有什么实际操作的意义&#xff0c;因为直接选择排序的时间复杂度比…

云原生 Docker Swarm 使用详解

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

用Copilot画漫画,Luma AI生成视频:解锁创意新玩法

近年来&#xff0c;随着人工智能技术的不断发展&#xff0c;各种创意工具也层出不穷。今天&#xff0c;我们就来介绍一种全新的创作方式&#xff1a;使用Copilot画漫画&#xff0c;再将漫画放入Luma AI生成视频。 Copilot&#xff1a;你的AI绘画助手 Copilot是一款基于人工智…