首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用docker in docker

使用docker in docker

作者头像
jeremyxu
发布于 2019-03-13 06:40:11
发布于 2019-03-13 06:40:11
4.7K00
代码可运行
举报
运行总次数:0
代码可运行

工作中需要在容器里操作docker镜像,而且又不想污染宿主机上的docker镜像,找到了docker in docker(dind)的方案,这里记录一下。

容器里用dind

首先直接用docker容器作试验,试验一下功能:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 启动docker in docker
docker run --privileged -v `pwd`/ca.crt:/etc/docker/certs.d/myregistrydomain.com/ca.crt -d --name dockerd docker:stable-dind --registry-mirror=https://myregistrydomain.com

# 在另一个容器里拉取镜像,从输出来看,拉取镜像是成功了的
docker run --rm --link dockerd:docker docker:stable docker pull busybox:latest

# 在宿主机上检查,并没有看到拉取的镜像,说明没有污染宿主机的docker镜像
docker images | grep busybox

使用还是比较简单的。

这里注意两点:

  1. 为了拉取镜像加速,我这里使用了自己架设的docker registry服务,因此dockerd加了参数--registry-mirror=https://myregistrydomain.com
  2. 自己架设的docker registry服务使用的是自签名证书,因此参考官方文档,还设置了自签名证书对应的ca证书/etc/docker/certs.d/myregistrydomain.com/ca.crt

在看官方文档时,发现文档上说有些版本的docker需要设置在操作系统级别信任证书,不过我目前还没遇到这种情况,这里稍微关注一下。

k8s里使用dind

简单写个deployment的k8s描述文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: docker-test
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: docker-test
    spec:
      containers:
        - name: dockerd
          image: 'docker:stable-dind'
          securityContext:
            privileged: true
          args: ["--registry-mirror=https://myregistrydomain.com"]
          volumeMounts:
          - name: cert-volume
            mountPath: /etc/docker/certs.d/myregistrydomain.com/
        - name: docker-cli
          image: 'docker:stable'
          env:
          - name: DOCKER_HOST
            value: 127.0.0.1:2375
          command: ["/bin/sh"]
          args: ["-c", "docker info >/dev/null 2>&1; while [ $? -ne 0 ] ; do sleep 3; docker info >/dev/null 2>&1; done; docker pull library/busybox:latest; docker save -o busybox-latest.tar library/busybox:latest; docker rmi library/busybox:latest; while true; do sleep 86400; done"]
      volumes:
      - name: cert-volume
        configMap:
            name: registry-ca-cert

这里在pod里跑两个容器,其中一个dockerd,另外一个是使用docker命令的容器,这里注意两点:

  1. 同样因为使用了私有的registry服务,而且证书是自签名的,dockerd容器要作一些配置
  2. 因为两个container共享相同的网络空间,因此直接设置好DOCKER_HOST环境变量,docker-cli里就可以直接用docker命令了,因为不确定两个容器的启动顺序,这里用一段脚本做了个等待的处理docker info >/dev/null 2>&1; while [ $? -ne 0 ] ; do sleep 3; docker info >/dev/null 2>&1; done;

然后用kubectl apply -f docker-test.yaml把这个deployment部署起来,简单检查一下,一切正常。

docker in docker的原理

docker in docker的原理还是比较简单的,可以参考wrapdocker源码,其实就是挂载cgroup、tmpfs、securityfs、cgroup的SUBSYS、关掉不需要的文件描述符、最后启动dockerd。wrapdocker源码里注释写得比较清楚。

用golang语言操作dockerd

运维时用docker命令来操作dockerd还是比较好的,但有时希望以编程的方式操作dockerd,这时docker的sdk就派上用场了,可以参考官方文档示例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import (
    "context"
    "os"

    "github.com/docker/docker/client"
    "github.com/docker/docker/api/types"
    "github.com/docker/docker/api/types/container"
    "github.com/docker/docker/pkg/stdcopy"
)

func main() {
    ctx := context.Background()
    cli, err := client.NewClientWithOpts(client.FromEnv)
    if err != nil {
        panic(err)
    }
    cli.NegotiateAPIVersion(ctx)

    reader, err := cli.ImagePull(ctx, "docker.io/library/alpine", types.ImagePullOptions{})
    if err != nil {
        panic(err)
    }
    io.Copy(os.Stdout, reader)

    resp, err := cli.ContainerCreate(ctx, &container.Config{
        Image: "alpine",
        Cmd:   []string{"echo", "hello world"},
    }, nil, nil, "")
    if err != nil {
        panic(err)
    }

    if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
        panic(err)
    }

    statusCh, errCh := cli.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning)
    select {
    case err := <-errCh:
        if err != nil {
            panic(err)
        }
    case <-statusCh:
    }

    out, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true})
    if err != nil {
        panic(err)
    }

    stdcopy.StdCopy(os.Stdout, os.Stderr, out)
}

参考

  1. https://hub.docker.com/_/docker/
  2. https://docs.docker.com/registry/insecure/#use-self-signed-certificates
  3. https://github.com/jpetazzo/dind
  4. https://www.docker-cn.com/registry-mirror
  5. https://docs.docker.com/develop/sdk/
  6. https://docs.docker.com/develop/sdk/examples/
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-02-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
详解docker实战之搭建私有镜像仓库 - kurbernetes
1、实战目的 搭建企业私有的镜像仓库,满足从开发环境推送和拉取镜像。当我们使用k8s来编排和调度容器时,操作的基本单位是镜像,所以需要从仓库去拉取镜像到当前的工作节点。本来使用公共的docker hub完全可以满足我们的需求,也非常方便,但是上传的镜像任何人都可以访问,其次docker hub的私有仓库又是收费的,所以从安全和商业两方面考虑,企业必须搭建自己的私有镜像仓库。 2、搭建私有仓库 2.1、生产证书 为了保证镜像传输安全,从开发环境向私有仓库推送和拉取镜像时,一般使用https的方式(备注:
justmine
2018/06/13
1.4K0
超详细记录公司多用户Docker仓库创建安全认证和应用
王小雷
2018/01/02
1.7K0
超详细记录公司多用户Docker仓库创建安全认证和应用
Docker 深入篇之 Build 原理
使用 Docker 时,最常用的命令无非是 docker container 和 docker image 相关的子命令,当然最初没有管理类命令(或者说分组)的时候,最常使用的命令也无非是 docker run docker commit docker build 和 docker images 这些。
Jintao Zhang
2018/10/10
2.1K0
Go每日一库之121:moby(操作docker容器)
在日常开发中,测试是不可避免的,在针对DAO层的代码写测试用例的时候,直接将依赖的存储服务(比如mongodb)的client给mock掉,可能达不到检验代码中语法或数据操作正确性的目的。如果在本地起一个相关的存储服务又会由于不同的项目带来环境的污染,并且测试代码由于依赖本地环境可能导致多人协作困难。在云原生时代,你可能第一想到的就是利用docker container 来解决环境问题,而本文所推荐的就是用 go 语言来操作docker的开源项目。
luckpunk
2023/09/30
1.2K0
(WJW)构建企业级Docker_Registry_V2
(WJW)构建企业级Docker_Registry_V2 目前Docker Registry版本是2.2,也是当前最新的版本. Registry2.2的特性有,目前是用go语言去写的,性能提升比v1
白石
2019/08/23
4450
如何在 Docker 中使用 Docker
在 CI 中,通常会有一个 CI Engine 负责解析流程,控制整个构建过程,而将真正的构建交给 Agent 去完成。例如,Jenkins 、GitLab 均是如此。
陈少文
2020/12/06
2.4K0
如何在 Docker 中使用 Docker
集成Harbor镜像仓库(HTTPS)
Harbor主页在:https://vmware.github.io/harbor/,Harbor是由Vmware中国团队开发并开源的Docker镜像仓库。
Criss@陈磊
2019/08/01
2K0
如何构建企业级Docker Registry Server
很多人问我,虚拟机镜像和docker镜像的区别是什么?其实区别非常明显,我们可以通过阅读Dockerfile文件就可以知道这个镜像都做了哪些操作,能提供什么服务;但通过虚拟机镜像,你能一眼看出来虚拟机镜像里面多做了哪些操作,能提供什么服务吗?更突出的是我们都说是mysql镜像,Wordpress镜像,从不说是虚拟机镜像。这点就更能说明docker是更贴近应用的,不单单是解决底层运行环境。 那么有了docker又如何呢? 我们可以快速构建,整体打包 (Build),在这个过程中主要是运维和研发需要更多的协
CSDN技术头条
2018/02/11
7540
巧妙调试docker容器
工作中经常发现一些第三方写的docker容器运行有问题,这时我们会通过docker logs命令观察容器的运行日志。很可惜,有时容器中运行的程序仅从日志很难查明问题。这时我们会通过docker exec在目标容器中执行某些命令以探查问题,有时却发现一些镜像很精简,连基本的sh、bash、netstat等命令都没包含。这时就很尴尬了,诊断问题很困难。
jeremyxu
2019/05/06
1.3K0
harbor搭建企业docker私有镜像仓库
# curl -fsSL https://get.docker.com/ | sh
聂伟星
2020/07/12
2.7K0
4.Docker学习之进阶使用
描述: 本章主要学习与记录了在进一步学习Docker容器中的一些基础名称解析与Docker与一些辅助软件配合使用来增加工作效率以及简化运维流程;
全栈工程师修炼指南
2022/09/28
1.6K0
4.Docker学习之进阶使用
Docker 使用指南 (二):搭建本地仓库
去中央仓库下载镜像有时候非常的慢,所以 docker 本地仓库和 gitlab 类似,都是为了便于公司内部人员的使用。 一.本地安装 本次实验环境:腾讯云服务器 CentOS 6.7 x86_64 #
田飞雨
2016/07/20
8K1
Docker 使用指南 (二):搭建本地仓库
Kubernetes 1.8.6 集群部署–Docker私有仓库(九)20180411更新
搭建Docker私有镜像仓库 安装docker # yum -y install docker # systemctl start docker && systemctl enable docker 使用自签名进行安全认证 创建存放证书和密钥的certs目录 # mkdir -p /docker/certs # chcon -Rt svirt_sandbox_file_t /docker/certs/ 修改/etc/pki/tls/openssl.cnf配置文件 在该文件的[ v3_ca ]配置项中添加
老七Linux
2018/05/31
1.2K0
如何使用Skopeo做一个优雅的镜像搬运工
[TOC] 0x00 基础介绍 描述: 作为公司内部 PaaS toB 产品的打包发布人员,容器镜像对我们打工人而言就像是工地上的砖头 🧱,而我的一部分工作就是将这些砖头在各个仓库之间搬来搬去,最终
全栈工程师修炼指南
2022/09/29
4.8K0
如何使用Skopeo做一个优雅的镜像搬运工
docker registry V2私有仓库搭建
确认registry server是UP状态,docker ps -a | grep registry
字母哥博客
2020/09/23
6930
docker安装harborps
通过github获取离线安装包,地址:https://github.com/goharbor/harbor/releases,可以根据自己的需要下载自己需要的release版本,这里使用的是v2.2.1,下载对应的离线安装包[harbor-
ruochen
2021/12/04
1.6K0
使用 Tekton Sidecar 实现 Docker IN Docker 构建
在 Tekton 中有一项 Sidecar 功能,和 Pod 中的 Sidecar 类似,它也是一个容器,用于和 Task 任务的 Steps 中指定的容器一起运行,为这些 Steps 的执行提供一些辅助支持,比如 Sidecar 可以运行一个 logging daemon、更新共享 volume 上的文件或者提供网络代理等功能。
我是阳明
2021/06/25
1.3K0
使用 Tekton Sidecar 实现 Docker IN Docker 构建
Docker实践之06-访问仓库
仓库(Repository)是集中存放镜像的地方。 一个容易和仓库混淆的概念是注册服务器(Registry),实际上注册服务器是管理仓库(Repository)的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。 例如:对于仓库地址dl.dockerpool.com/ubuntu来说, dl.dockerpool.com是注册服务器地址, ubuntu是仓库名。大部分时候,并不需要严格区分这两者的概念。
编程随笔
2022/09/09
1.8K0
Docker实践之06-访问仓库
一文搞懂 Minikube 底层原理
随着容器技术的井喷式发展及落地,通常情况下,我们将 Kubernetes 描述为“将 Linux 容器集群作为单个系统进行管理,以加速开发并简化维护”。与此同时,企业应用服务进行容器化改造时避免不了学习和使用 Kubernetes 。然而能够在环境中完整部署一整套多节点的 Kubernetes 集群,对于刚接触这块体系的 Devops 人员来说确实有一定的难度... ...
Luga Lee
2021/12/08
2.6K0
一文搞懂 Minikube 底层原理
Gitlab持续集成中Dood与Dind应该怎么玩?
在通过jenkins或Gitlab使用Docker容器化构建服务的时候,我们会遇到两种构建的方式,分别是DIND与DOOD,这两种的构建的方式却有着很大的差异,接下来分别介绍两种构建方式的区别:
公众号: 云原生生态圈
2020/11/02
4.9K2
Gitlab持续集成中Dood与Dind应该怎么玩?
相关推荐
详解docker实战之搭建私有镜像仓库 - kurbernetes
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档