前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Docker in Docker容器化版的“盗梦空间”

Docker in Docker容器化版的“盗梦空间”

作者头像
SRE运维手记
发布2024-08-30 17:08:44
1180
发布2024-08-30 17:08:44
举报
文章被收录于专栏:SRE运维手记

Docker in Docker(DinD) 是一种容器虚拟化嵌套技术,它允许用户在容器内部运行 Docker 容器,层层嵌套,从而实现更复杂的容器化操作和构建环境 。

01、背 景

Kubernetes集群计划迁移至1.24版本的集群,底层容器运行时换成了Containerd,然而当前的CI/CD流水线大多地方使用到了docker指令,要改成Containerd指令成本巨大,如何以最小的改动,最为高效地完成迁移便成了难题,为了攻克这个难题我们引入了DinD的方案进行实现,流水线都不用做任何改动,简直完美。

02、Containerd的由来

我们顺便了解下Containerd的由来,据说,在很早之前,Kubernetes就放风不再支持Docker,主要原因是Docker不支持其引入的CRI(容器运行时接口),还需要额外维护docker-shim组件,费时费力。

2015年,为了应对这一挑战,Docker 公司决定将容器运行时从 Docker 引擎中分离出来,并支持 CRI,将这个项目命名为 Containerd。

2017年,被捐赠给云原生计算基金会(CNCF),后来成为了 CNCF的顶级开源项目。

Containerd专注于容器的生命周期管理,包括容器的创建、启动、停止和删除等。这种专注使其更轻量、高效,并且与 Kubernetes 的设计理念更为契合,简化了集群管理的复杂性,提升了系统的性能和可靠性。

03、方案说明

为了使 Jenkins Slave 能够使用 Docker 命令,我们需要将 Docker 二进制文件和 docker.sock(套接字)映射到容器中。我们并不需要在容器内启动一个 Docker 进程,因为只要 Docker 的二进制文件能够通过 docker.sock 与守护进程通信即可。

如上图,我们大致会执行以下步骤:

1. 运行Docker daemonset,将K8S Node的/var/run/docker-ci映射到容器的/var/run/docker目录

2. 将K8S Node的/var/run/docker-ci中的docker.sock和docker映射到Jenkins Slave中

04、操作步骤

将下面内容保存为docker-ci-daemonset.yaml,然后通过kubectl apply进行部署

代码语言:javascript
复制
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: docker-ci     # 因为是用来做docker镜像构建的,所以我把他命名为docker-ci
  namespace: default  # 命名空间,我是放在default命名空间下,可以自行修改
spec:
  selector:
    matchLabels:
      app: docker-ci
  template:
    metadata:
      labels:
        app: docker-ci
    spec:
      initContainers:
      - name: init-sysctl
        image: busybox
        command:
          - rm
          - '-f'
          - /var/run/docker.sock  # 启动前,删除一下docker.sock,防止因异常原因退出留有残留文件,影响docker启动
        resources: {} 
        volumeMounts:
          - name: host
            mountPath: /var/run  # 将宿主机卷挂载到init容器
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        imagePullPolicy: Always
        securityContext:
          privileged: true       # 赋予容器特权
      containers:
      - name: docker-ci
        image: 'docker:20.10.24-dind'  # Docker-in-Docker镜像
        command:
        - dockerd
        - --host=unix:///var/run/docker.sock
        - --host=tcp://0.0.0.0:8000
        securityContext:
          privileged: true   # 赋予容器特权
        resources:
          limits:
            cpu: '2'
            memory: 4Gi
          requests:
            cpu: 300m
            memory: 500Mi
        volumeMounts:
        - mountPath: /var/run
          name: host  # 将宿主机卷挂载到主容器
        lifecycle:  
          postStart:  # 添加postStart钩子
            exec:
              command:
                - sh
                - -c
                - |
                  if [ -e /var/run/docker/docker ]; then
                    rm -f /var/run/docker/docker
                  fi
                  cp -a /usr/local/bin/docker /var/run/docker/
      volumes:
      - name: host
        hostPath:
          path: /var/run/docker-ci  # 创建一个目录,避免将/var/run的所有文件挂载到容器中

好了,接下来就是修改Jenkins的配置,我们在需要用到docker指令的容器配置模版加上docker二进制和docker.sock的映射即可,如

代码语言:javascript
复制
- name: "jnlp"
    image: "jenkins/jnlp-slave:3.27-1"
    args: "^${computer.jnlpmac} ^${computer.name}"
    resourceRequestCpu: "100m"
    resourceLimitCpu: "500m"
    resourceRequestMemory: "500Mi"
    resourceLimitMemory: "2048Mi"
  workspaceVolume:
    emptyDirWorkspaceVolume:
      memory: false
  volumes:
  - hostPathVolume:
      hostPath: "/var/run/docker-ci/docker.sock"
      mountPath: "/var/run/docker.sock"
  - hostPathVolume:
      hostPath: "/var/run/docker-ci/docker/docker"
      mountPath: "/usr/bin/docker"

完成上述步骤,就可以在发布流程中使用docker指令了。

05、总 结

虽然DinD可以完美解决我的难题,但是也存在弊端,如安全性问题、容器不稳定等,都是我们需要关注的,这期就分享到这里,谢谢!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SRE运维手记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档