
Docker in Docker
Docker in Docker是指在容器中运行Containerd,使用docker:dind 镜像并设置为privilege 模式运行。
console
$docker run --privileged --name some-docker -d \--network some-network --network-alias docker \-e DOCKER_TLS_CERTDIR=/certs \-v some-docker-certs-ca:/certs/ca \-v some-docker-certs-client:/certs/client \docker:dind
TLSH2
从18.09+开始, 如果设置了DOCKER_TLS_CERTDIR 环境变量,dind默认会启用TLS,并降证书生成到DOCKER_TLS_CERTDIR 指定的目录。
启用了TLS后Docker进行会以下面的方式启动:
bash
--host=tcp://0.0.0.0:2376 --tlsverify
否则
bash
--host=tcp://0.0.0.0:2375
客户端容器需要访问dind,就需要传入证书
bash
```console$ docker run --rm --network some-network \-e DOCKER_TLS_CERTDIR=/certs \-v some-docker-certs-client:/certs/client:ro \docker:latest versionClient: Docker Engine - CommunityVersion: 18.09.8API version: 1.39Go version: go1.10.8Git commit: 0dd43dd87fBuilt: Wed Jul 17 17:38:58 2019OS/Arch: linux/amd64Experimental: falseServer: Docker Engine - CommunityEngine:Version: 18.09.8API version: 1.39 (minimum version 1.12)Go version: go1.10.8Git commit: 0dd43dd87fBuilt: Wed Jul 17 17:48:49 2019OS/Arch: linux/amd64Experimental: false
Gitlab CIH2
Gitlab CI中使用service可以额外运行一个dind容器来实现容器、镜像相关的操作
default:
image: docker:24.0.5services:- docker:24.0.5-dindbefore_script:- docker infovariables:# When you use the dind service, you must instruct Docker to talk with# the daemon started inside of the service. The daemon is available# with a network connection instead of the default# /var/run/docker.sock socket. Docker 19.03 does this automatically# by setting the DOCKER_HOST in# https://github.com/docker-library/docker/blob/d45051476babc297257df490d22cbd806f1b11e4/19.03/docker-entrypoint.sh#L23-L29## The 'docker' hostname is the alias of the service container as described at# https://docs.gitlab.com/ee/ci/services/#accessing-the-services.## Specify to Docker where to create the certificates. Docker# creates them automatically on boot, and creates# `/certs/client` to share between the service and job# container, thanks to volume mount from config.tomlDOCKER_TLS_CERTDIR: "/certs"build:stage: buildscript:- docker build -t my-docker-image .- docker run my-docker-image /script/to/run/tests
这里DOCKER_TLS_CERTDIR就是dind 文档中提到的。另外对于作为client的docker镜像,讲道理是需要设置DOCKER_HOST 变量来连接到外部的docker进程的。默认的entrypoint
已经做了相关设置
bash
# if DOCKER_HOST isn't set and we don't have the default unix socket, let's set DOCKER_HOST to a sane remote valueif [ -z "${DOCKER_HOST:-}" ] && [ ! -S /var/run/docker.sock ]; thenif _should_tls || [ -n "${DOCKER_TLS_VERIFY:-}" ]; thenexport DOCKER_HOST='tcp://docker:2376'elseexport DOCKER_HOST='tcp://docker:2375'fifi
可以看到,如有没有unix socket以及DOKCER_HOST的话,默认的设置docker 未host名,而gitlab CI的serivce的默认别名正好是根据镜像的名称来的(也可以手动指定alias)
参考: 1: docker - Official Image | Docker Hub 2: Use Docker to build Docker images | GitLab
自定义的镜像的DIND初始化H2
Dockerfile
bash
FROM eclipse-temurin:17ENV TZ="Asia/Shanghai" \DOCKER_VERSION="24.0.5" \apkArch="x86_64"# Install base packagesRUN set -eux; \apt-get update; \apt-get install -y --no-install-recommends \git; \rm -rf /var/lib/apt/lists/*; \echo "https://download.docker.com/linux/static/stable/${apkArch}/docker-${DOCKER_VERSION}.tgz" && \wget -qO "/tmp/docker-${DOCKER_VERSION}-ce.tgz" \"https://download.docker.com/linux/static/stable/${apkArch}/docker-${DOCKER_VERSION}.tgz" && \tar zxf "/tmp/docker-${DOCKER_VERSION}-ce.tgz" -C /tmp && \mv /tmp/docker/docker /usr/binCOPY docker-entrypoint.sh /usr/local/bin/RUN /__cacert_entrypoint.shENTRYPOINT ["docker-entrypoint.sh"]
entrypoint.sh
bash
#!/bin/shset -eu_should_tls() {[ -n "${DOCKER_TLS_CERTDIR:-}" ] \&& [ -s "$DOCKER_TLS_CERTDIR/client/ca.pem" ] \&& [ -s "$DOCKER_TLS_CERTDIR/client/cert.pem" ] \&& [ -s "$DOCKER_TLS_CERTDIR/client/key.pem" ]}# if we have no DOCKER_HOST but we do have the default Unix socket (standard or rootless), use it explicitlyif [ -z "${DOCKER_HOST:-}" ] && [ -S /var/run/docker.sock ]; thenexport DOCKER_HOST=unix:///var/run/docker.sockelif [ -z "${DOCKER_HOST:-}" ] && XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" && [ -S "$XDG_RUNTIME_DIR/docker.sock" ]; thenexport DOCKER_HOST="unix://$XDG_RUNTIME_DIR/docker.sock"fi# if DOCKER_HOST isn't set (no custom setting, no default socket), let's set it to a sane remote valueif [ -z "${DOCKER_HOST:-}" ]; thenif _should_tls || [ -n "${DOCKER_TLS_VERIFY:-}" ]; thenexport DOCKER_HOST='tcp://docker:2376'elseexport DOCKER_HOST='tcp://docker:2375'fifiif [ "${DOCKER_HOST#tcp:}" != "$DOCKER_HOST" ] \&& [ -z "${DOCKER_TLS_VERIFY:-}" ] \&& [ -z "${DOCKER_CERT_PATH:-}" ] \&& _should_tls \; thenexport DOCKER_TLS_VERIFY=1export DOCKER_CERT_PATH="$DOCKER_TLS_CERTDIR/client"fiexec "$@"
评论
新的评论
上一篇
Squash commits
Gitlab、Gitlab在进行Merge Pull Request都可以选择Squash将提交进行合并,但是他们在各自处理时却略有不同。 内部原理上,他们都需要使用 git merge --squash 来实现。这个命令本质上是会在当前HEAD指向的Commit节点之后,将…
下一篇
RKE2 ServiceLB
RKE2默认没有开启ServiceLB,因此Nginx Ingress也没有创建LoadBalance Service,而是使用的Hostport + Daemonset的方式。 开启ServiceLB 参数 --enable-servicelb 在官方文档中没有提及 Conf…
