已有 containerd 的情况下部署二进制 docker 共存
文章目录
- @[toc]
- 学习目的
- 开始学习
- dockerd
- 启动 containerd
- 准备配置文件
- 启动 containerd
- 启动 docker
- 准备配置文件
- 启动 docker
- 环境验证
- 停止 docker 和 containerd
文章目录
- @[toc]
- 学习目的
- 开始学习
- dockerd
- 启动 containerd
- 准备配置文件
- 启动 containerd
- 启动 docker
- 准备配置文件
- 启动 docker
- 环境验证
- 停止 docker 和 containerd
学习目的
使用容器的方式做一些部署的交付,相对方便很多,不需要担心别人的环境缺少需要的依赖(比如 python 库,ansible 模块等),在 k8s 普及的情况下,也要想办法不污染本地的环境
开始学习
- 阿里云 docker-ce-linux-x86 二进制文件下载地址
dockerd
dockerd
是管理容器的持久进程- Docker 对守护程序和客户端使用不同的二进制文件
dockerd
支持命令行,配置文件和环境变量的方式来配置启动参数
- 命令行和配置文件选项优先于环境变量
- 配置文件存在的参数不能和命令行的参数一样
- Linux 上允许的配置选项的完整示例,具体参数作用,可以看 dockerd 官方文档
{
"allow-nondistributable-artifacts": [],
"api-cors-header": "",
"authorization-plugins": [],
"bip": "",
"bridge": "",
"builder": {
"gc": {
"enabled": true,
"defaultKeepStorage": "10GB",
"policy": [
{ "keepStorage": "10GB", "filter": ["unused-for=2200h"] },
{ "keepStorage": "50GB", "filter": ["unused-for=3300h"] },
{ "keepStorage": "100GB", "all": true }
]
}
},
"cgroup-parent": "",
"containerd": "/run/containerd/containerd.sock",
"containerd-namespace": "docker",
"containerd-plugins-namespace": "docker-plugins",
"data-root": "",
"debug": true,
"default-address-pools": [
{
"base": "172.30.0.0/16",
"size": 24
},
{
"base": "172.31.0.0/16",
"size": 24
}
],
"default-cgroupns-mode": "private",
"default-gateway": "",
"default-gateway-v6": "",
"default-network-opts": {},
"default-runtime": "runc",
"default-shm-size": "64M",
"default-ulimits": {
"nofile": {
"Hard": 64000,
"Name": "nofile",
"Soft": 64000
}
},
"dns": [],
"dns-opts": [],
"dns-search": [],
"exec-opts": [],
"exec-root": "",
"experimental": false,
"features": {
"cdi": true,
"containerd-snapshotter": true
},
"fixed-cidr": "",
"fixed-cidr-v6": "",
"group": "",
"host-gateway-ip": "",
"hosts": [],
"proxies": {
"http-proxy": "http://proxy.example.com:80",
"https-proxy": "https://proxy.example.com:443",
"no-proxy": "*.test.example.com,.example.org"
},
"icc": false,
"init": false,
"init-path": "/usr/libexec/docker-init",
"insecure-registries": [],
"ip": "0.0.0.0",
"ip-forward": false,
"ip-masq": false,
"iptables": false,
"ip6tables": false,
"ipv6": false,
"labels": [],
"live-restore": true,
"log-driver": "json-file",
"log-format": "text",
"log-level": "",
"log-opts": {
"cache-disabled": "false",
"cache-max-file": "5",
"cache-max-size": "20m",
"cache-compress": "true",
"env": "os,customer",
"labels": "somelabel",
"max-file": "5",
"max-size": "10m"
},
"max-concurrent-downloads": 3,
"max-concurrent-uploads": 5,
"max-download-attempts": 5,
"mtu": 0,
"no-new-privileges": false,
"node-generic-resources": [
"NVIDIA-GPU=UUID1",
"NVIDIA-GPU=UUID2"
],
"oom-score-adjust": 0,
"pidfile": "",
"raw-logs": false,
"registry-mirrors": [],
"runtimes": {
"cc-runtime": {
"path": "/usr/bin/cc-runtime"
},
"custom": {
"path": "/usr/local/bin/my-runc-replacement",
"runtimeArgs": [
"--debug"
]
}
},
"seccomp-profile": "",
"selinux-enabled": false,
"shutdown-timeout": 15,
"storage-driver": "",
"storage-opts": [],
"swarm-default-advertise-addr": "",
"tls": true,
"tlscacert": "",
"tlscert": "",
"tlskey": "",
"tlsverify": true,
"userland-proxy": false,
"userland-proxy-path": "/usr/libexec/docker-proxy",
"userns-remap": ""
}
启动 containerd
这里用 docker 二进制文件里面的 containerd 命令启动
准备配置文件
disabled_plugins = []
imports = []
oom_score = 0
plugin_dir = ""
required_plugins = []
root = "/approot/docker-27.2.0/containerd-data"
state = "/approot/docker-27.2.0/containerd-state"
temp = ""
version = 2
[cgroup]
path = ""
[debug]
address = ""
format = ""
gid = 0
level = ""
uid = 0
[grpc]
address = "/approot/docker-27.2.0/containerd-data/containerd.sock"
gid = 0
max_recv_message_size = 16777216
max_send_message_size = 16777216
tcp_address = ""
tcp_tls_ca = ""
tcp_tls_cert = ""
tcp_tls_key = ""
uid = 0
[metrics]
address = ""
grpc_histogram = false
[plugins]
[plugins."io.containerd.gc.v1.scheduler"]
deletion_threshold = 0
mutation_threshold = 100
pause_threshold = 0.02
schedule_delay = "0s"
startup_delay = "100ms"
[plugins."io.containerd.grpc.v1.cri"]
device_ownership_from_security_context = false
disable_apparmor = false
disable_cgroup = false
disable_hugetlb_controller = true
disable_proc_mount = false
disable_tcp_service = true
drain_exec_sync_io_timeout = "0s"
enable_selinux = false
enable_tls_streaming = false
enable_unprivileged_icmp = false
enable_unprivileged_ports = false
ignore_deprecation_warnings = []
ignore_image_defined_volumes = false
max_concurrent_downloads = 3
max_container_log_line_size = 16384
netns_mounts_under_state_dir = false
restrict_oom_score_adj = false
sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9"
selinux_category_range = 1024
stats_collect_period = 10
stream_idle_timeout = "4h0m0s"
stream_server_address = "127.0.0.1"
stream_server_port = "0"
systemd_cgroup = false
tolerate_missing_hugetlb_controller = true
unset_seccomp_profile = ""
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/approot/docker-27.2.0/bin"
conf_dir = "/approot/docker-27.2.0/containerd-data/cni"
conf_template = ""
ip_pref = ""
max_conf_num = 1
[plugins."io.containerd.grpc.v1.cri".containerd]
default_runtime_name = "runc"
disable_snapshot_annotations = true
discard_unpacked_layers = false
ignore_rdt_not_enabled_errors = false
no_pivot = false
snapshotter = "overlayfs"
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = ""
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
BinaryName = ""
CriuImagePath = ""
CriuPath = ""
CriuWorkPath = ""
IoGid = 0
IoUid = 0
NoNewKeyring = false
NoPivotRoot = false
Root = ""
ShimCgroup = ""
SystemdCgroup = true
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = ""
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options]
[plugins."io.containerd.grpc.v1.cri".image_decryption]
key_model = "node"
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = ""
[plugins."io.containerd.grpc.v1.cri".registry.auths]
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.headers]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
tls_cert_file = ""
tls_key_file = ""
[plugins."io.containerd.internal.v1.opt"]
path = "/approot/docker-27.2.0/containerd-data"
[plugins."io.containerd.internal.v1.restart"]
interval = "10s"
[plugins."io.containerd.internal.v1.tracing"]
[plugins."io.containerd.metadata.v1.bolt"]
content_sharing_policy = "shared"
[plugins."io.containerd.monitor.v1.cgroups"]
no_prometheus = false
[plugins."io.containerd.runtime.v1.linux"]
no_shim = false
runtime = "runc"
runtime_root = ""
shim = "containerd-shim"
shim_debug = false
[plugins."io.containerd.runtime.v2.task"]
platforms = ["linux/amd64"]
sched_core = false
[plugins."io.containerd.service.v1.diff-service"]
default = ["walking"]
[plugins."io.containerd.service.v1.tasks-service"]
rdt_config_file = ""
[plugins."io.containerd.snapshotter.v1.aufs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.btrfs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.devmapper"]
async_remove = false
base_image_size = ""
discard_blocks = false
fs_options = ""
fs_type = ""
pool_name = ""
root_path = ""
[plugins."io.containerd.snapshotter.v1.native"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.overlayfs"]
mount_options = []
root_path = ""
sync_remove = false
upperdir_label = false
[plugins."io.containerd.snapshotter.v1.zfs"]
root_path = ""
[plugins."io.containerd.tracing.processor.v1.otlp"]
[proxy_plugins]
[stream_processors]
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]
accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
path = "ctd-decoder"
returns = "application/vnd.oci.image.layer.v1.tar"
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]
accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
path = "ctd-decoder"
returns = "application/vnd.oci.image.layer.v1.tar+gzip"
[timeouts]
"io.containerd.timeout.bolt.open" = "0s"
"io.containerd.timeout.shim.cleanup" = "5s"
"io.containerd.timeout.shim.load" = "5s"
"io.containerd.timeout.shim.shutdown" = "3s"
"io.containerd.timeout.task.state" = "2s"
[ttrpc]
address = ""
gid = 0
uid = 0
启动 containerd
nohup /approot/docker-27.2.0/bin/containerd --config config/containerd.toml &> /approot/docker-27.2.0/logs/containerd.log &
echo $! > /approot/docker-27.2.0/containerd.pid
启动 docker
准备配置文件
{
"data-root": "/approot/docker-27.2.0/docker-data",
"containerd": "/approot/docker-27.2.0/containerd-data/containerd.sock",
"default-address-pools": [
{
"base": "172.20.0.0/16",
"size": 24
}
],
"hosts": [
{
"unix": "/approot/docker-27.2.0/docker-data/docker.sock"
}
],
"experimental": true,
"init-path": "/approot/docker-27.2.0/bin/docker-init",
"log-driver": "json-file",
"log-format": "json",
"log-level": "",
"log-opts": {
"max-file": "5",
"max-size": "100m"
},
"pidfile": "/approot/docker-27.2.0/docker-data/docker.pid",
"runtimes": {
"runc": {
"path": "/approot/docker-27.2.0/bin/runc"
}
},
"userland-proxy-path": "/approot/docker-27.2.0/bin/docker-proxy"
}
启动 docker
nohup /approot/docker-27.2.0/bin/dockerd --config-file /approot/docker-27.2.0/config/daemon.json &> /approot/docker-27.2.0/logs/docker.log &
环境验证
首先用系统自带的 containerd 来拉取镜像
ctr image pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9
查看拉取的镜像信息
ctr image ls
正常情况下,会有类似如下的返回
REF TYPE DIGEST SIZE PLATFORMS LABELS
registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9 application/vnd.docker.distribution.manifest.list.v2+json sha256:7031c1b283388d2c2e09b57badb803c05ebed362dc88d84b480cc47f72a21097 314.0 KiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x,windows/amd64 -
查看独立安装的 containerd 是否能看到镜像
- 通过
--address
来指定 sock 文件,正常情况下是看不到有镜像的
ctr --address /approot/docker-27.2.0/containerd-data/containerd.sock image ls
使用 docker 命令来查看,正常情况下,也是看不到有镜像的
/approot/docker-27.2.0/bin/docker --host unix:///approot/docker-27.2.0/docker-data/docker.sock image ls
使用 docker 命令尝试镜像构建,下面简单准备一个 dockerfile
FROM docker.m.daocloud.io/alpine:3.20
ENV LANG="en_US.UTF-8"
ENV LANGUAGE="en_US:en"
ENV LC_ALL="en_US.UTF-8"
RUN echo "https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.20/main" > /etc/apk/repositories && \
echo "https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.20/community" >> /etc/apk/repositories && \
apk add --no-cache --update --verbose vim jq net-tools && \
rm -rf /var/cache/apk /tmp /sbin/halt /sbin/poweroff /sbin/reboot
构建镜像
/approot/docker-27.2.0/bin/docker --host unix:///approot/docker-27.2.0/docker-data/docker.sock build -t base-image-1.0:alpine-3.20 .
启动 docker 容器验证,一切都正常
/approot/docker-27.2.0/bin/docker --host unix:///approot/docker-27.2.0/docker-data/docker.sock run -d -p 8080:80 docker.m.daocloud.io/openresty/openresty:latest
停止 docker 和 containerd
docker
kill $(cat /approot/docker-27.2.0/docker-data/docker.pid)
kill $(cat /approot/docker-27.2.0/containerd.pid)