docker mirror加速站
针对 docker cloudflare.docker.com 超时问题,目前测试中科大等都已经失效了。
下面的亲测可用:Daocloud 镜像加速器地址:https://docker.m.daocloud.io
编辑 /etc/docker/daemon.json, 增加如下:
"registry-mirrors": ["https://docker.m.daocloud.io"]
针对 docker cloudflare.docker.com 超时问题,目前测试中科大等都已经失效了。
下面的亲测可用:Daocloud 镜像加速器地址:https://docker.m.daocloud.io
编辑 /etc/docker/daemon.json, 增加如下:
"registry-mirrors": ["https://docker.m.daocloud.io"]
先login
docker login registry.gitlab.com
输入正确的的账号和密码。然后 token就会被自动保存在:
/root/.docker/config.json
账号一般是邮箱
后面就可以像使用普通镜像一样直接run了
安装后提示:
docker is already the newest version (1.5-2)
但是运行docker 命令提示找不到。
然后重新安装:
curl -sSL https://get.docker.com/ | sudo sh
提示:
The repository 'https://download.docker.com/linux/ubuntu bookworm Release' does not have a Release file.
cd /etc/apt/sources.list.d/
发现有个 archive_uri-https_download_docker_com_linux_ubuntu-bookworm.list
rm archive_uri-https_download_docker_com_linux_ubuntu-bookworm.list
删除后再执行,就正常了。
Client: Docker Engine - Community
Version: 25.0.3
API version: 1.44
Go version: go1.21.6
Git commit: 4debf41
Built: Tue Feb 6 21:14:25 2024
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 25.0.3
API version: 1.44 (minimum version 1.24)
Go version: go1.21.6
Git commit: f417435
Built: Tue Feb 6 21:14:25 2024
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.28
GitCommit: ae07eda36dd25f8a1b98dfbf587313b99c0190bb
runc:
Version: 1.1.12
GitCommit: v1.1.12-0-g51d5e94
docker-init:
Version: 0.19.0
GitCommit: de40ad0
这两天因为某个需求,一直在研究这个问题。
网上都看了,什么ipv6 subnet daemon.json 之类的,都是一通抄,还是没有能说明白关键联系的,很多都是抄的碎片化信息。
因为说不清楚关联,所以就没法在实际环境中结合实际灵活解决问题。
docker的版本问题。初步结论是:docker engine 的版本大于等于20.10.2 。参见:https://zhuanlan.zhihu.com/p/342633966
经过验证,如果版本不对,在配置daemon.json时,就会报错,令人莫名, 实际是版本的ipv6支持问题,不支持新字段。
注意:系统默认的docker版本是跟这个系统的代码版本库走的,所以想要最新的docker版本,首先要确认自己的系统,否则要手动安装。
这个也是网上看到最多的:
{
"ipv6": true,
"fixed-cidr-v6": "fd00::/80",
"experimental": true,
"ip6tables": true
}
在跳过了docker版本的坑,这里就可以配置了。这里核心的是那个fixed-cidr-v6, 很多人看不懂这个,不知道这个要怎么改,这个就要自己实际弄懂ipv6的子网了,要根据自己的外网IPV6地址,配置实际的子网段。参见 https://docs.docker.com/engine/daemon/ipv6/
docker inspect xxx
检查 Networks 字段,下面对应就是network的对象,如下例子就是 bridge:
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "xxx",
"EndpointID": "xxx",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "fd17::1",
"GlobalIPv6Address": "fd17::242:ac11:2",
"GlobalIPv6PrefixLen": 64,
"MacAddress": "xxx",
"DriverOpts": null
}
}
然后我们继续检查 bridge对ipv6的支持情况:
docker network inspect bridge
我们检查EnableIPv6字段:
"Name": "bridge",
"Id": "xxx",
"Created": "xxx",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": true,
如果是true,则证明此bridge网络已经支持ipv6
docker run --rm -it busybox ping -6 -c4 ipv6-test.com
docker run --rm -it busybox ifconfig
正常返回,就说明系统的docker ipv6能力正常
效果相当于endpoint 中的脚本跟上cmd 中的参数
ubuntu下,在-v参数映射时,出现 read-only file system
解决:默认是支持home下的路径
所以暂时就一个可选项:gitlab
放一个相关的比较参考图:
你可以在ghcr.io上存储和管理你的Docker和OCI镜像。
容器服务器支持外部layer,比如windows 镜像。
登陆ghcr.io建议使用GITHUB_TOKEN工作流来提高安全性。
$ export CR_PAT=YOUR_TOKEN
$ echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin
> Login Succeeded
$ docker push ghcr.io/OWNER/IMAGE_NAME:latest
or
$ docker push ghcr.io/OWNER/IMAGE-NAME:2.5
当第一次发布容器时,默认是私有的,需要改变可见性,需要自己去设置:Configuring a package's access control and visibility
$ docker inspect ghcr.io/OWNER/IMAGE_NAME
$ docker rmi ghcr.io/OWNER/IMAGE_NAME:latest
$ docker pull ghcr.io/OWNER/IMAGE_NAME@sha256:82jf9a84u29hiasldj289498uhois8498hjs29hkuhs
docker pull ghcr.io/OWNER/IMAGE_NAME
$ docker pull ghcr.io/OWNER/IMAGE_NAME:1.14.1
$ docker pull ghcr.io/OWNER/IMAGE_NAME:latest
$ docker build -t hello_docker .
$ docker images
> REPOSITORY TAG IMAGE ID CREATED SIZE
> ghcr.io/my-org/hello_docker latest 38f737a91f39 47 hours ago 91.7MB
> ghcr.io/my-username/hello_docker latest 38f737a91f39 47 hours ago 91.7MB
> hello-world latest fce289e99eb9 16 months ago 1.84kB
$ docker tag 38f737a91f39 ghcr.io/OWNER/NEW_IMAGE_NAME:latest
这两天瞎折腾,因为数据库不一致的问题,一气之下把baota image删掉了,很多跟数据库相关的服务都歇了。
宝塔自用,在nas环境配合下数据库,搞个网络环境还是很方便的。
再重新拉取baota镜像时,发现怎么也访问不了,看日志,也没发现什么线索,所以才萌生了自己搞个docker的念头,主要是想定位下问题。
根据官方 www.bt.cn 最新的安装脚本制作了最新的 docker镜像:
https://gitlab.com/hiproz/baota-centos7-docker
docker run -tid --name baota --restart always -v /your-local-dir:/www -p your-local-port:8888 registry.gitlab.com/hiproz/baota-centos7-docker
查看 run.log
查看映射路径下的default.txt, 注意要使用实际映射的端口,default.txt显示的是系统内部的端口。
eg:
docker container update --restart=always 容器名字
注意,重启docker很重要,否则修改完的配置文件,重启容器后会被还原
在docker中启用systemd时,过程中出现:
Failed to get D-Bus connection: Operation not permitted
systemd维护系统服务程序,它需要特权去会访问Linux内核。而容器并不是一个完整的操作系统,只有一个文件系统,而且默认启动只是普通用户这样的权限访问Linux内核,也就是没有特权,所以自然就用不了!
添加授权:
docker run -d -name centos7 --privileged=true centos:7 /usr/sbin/init
增加授权会提高风险,需要仔细评估具体的运行脚本和命令,避免对宿主造成安全风险
根据Walsh所说,容器中没有systemd最大的问题是它“退回到了使用初始化脚本之前。”每个镜像作者都在容器内创建自己的疯狂的启动脚本,而不是使用软件包作者精心制作的启动脚本。他演示了在具有systemd的容器内,服务初始化是何尝的简单,创建一个运行Apache httpd服务器的容器,其Dockerfile只有三行:
FROM fedora
RUN yum -y install httpd; yum clean all; systemctl enable httpd;
CMD [ "/sbin/init" ]
参考:
1. https://lwn.net/Articles/676831/ http://dockone.io/article/1093 (翻译)
为了保持最精简的系统,默认的系统镜像是没有额外应用的,任何需要的应用几乎都要自己来安装。
默认docker使用的是宿主网卡,只可以直接访问外网的,如果访问外部网络有问题,请检查安装过程或者使用的镜像。
关于linux选用哪个系统好的问题,理论上hub.docker.com上各个官方的都差不多,哪个用的习惯就用那个。抛开具体的产品开发环境和团队系统要求,目前还是ubuntu的最多些。如果没有特殊要求,我们一般推荐ubuntu来做docker环境。
对于ubuntu新系统,第一步要 apt-get update,其他的系统同理。然后再安装其他需要的软件,否则可能提示找不到对应的包。
apt-get install iputils-ping
volume相关指令
Command Description
docker volume
create Create a volume
docker volume
inspect Display detailed information on one or more volumes
docker volume
ls List volumes
docker volume
prune Remove unused local volumes
docker volume
rm Remove one or more volumes
docker volume
update Update a volume (cluster volumes only)
查询依赖
docker image inspect --format='{{.RepoTags}} {{.Id}} {{.Parent}}' $(docker image ls -q --filter since=xxxxxx)
xxxxxx标识的就是被依赖的image id
this deletes ALL STOPPED containers, images, volumes.
docker system prune --all --volumes
创建
可以在hub.docker.com上创建一个新的repo,或者自己复制一个现有的repo.
绑定github后,也可以直接通过Dockerfile来发生成最新的镜像
查看镜像列表
docker images
查看容器列表
docker ps
查看所有的容器
docker ps -a
查看最近创建的容器
docker ps -l
查找在指定 image 之后创建的 image 中的父 image
docker image inspect --format='{{.RepoTags}} {{.Id}} {{.Parent}}' $(docker image ls -q --filter since=xxxxxx)
获取镜像
docker pull name/reponame
删除
docker rm Remove one or more containers
docker rmi Remove one or more images
删除已经退出运行的容器
docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker rm
删除none镜像
docker images |grep none |awk '{print $3}'|xargs docker rmi
要删除全部image的话
docker rmi $(docker images -q)
停止所有容器
停止容器,才能删除所包含的image
docker stop $(docker ps -a -q)
ssh登录docker
在开发阶段免不了需要ssh上去进行现场配置。
从ssh启动docker:
docker run -it username/imagename /bin/bash
ssh登陆,并挂载本地目录,默认读写权限:
docker run -it -v 宿主绝对路径:docker绝对路径 username/imagename /bin/bash
这样启动的入口进程是bash,整整需要启动的服务进程,再此模式下要自己手动启动
attach
docker attach --sig-proxy=false $CONTAINER_ID
如果当前的不是bash,attach上去也无法进行ssh,只有是上面这种直接启动ssh并后台运行的情况,attach上去,才进入ssh
exec
在Docker1.3版本开始,提供了一个更方便的命令exec。可以直接在容器内运行命令。所以我们ssh登录docker最方便的是exec:
docker exec -ti 7f16264f7ab4 /bin/bash
detach
docker没有专用的命令,目前不能使用eixit,因为会导致主进程退出。使用ctl+p+ctl+q来detach当前的进程
查看底层信息,比如IP等
docker inspect --format='{{.NetworkSettings.IPAddress}}' $CONTAINER_ID
commit
docker commit CONTAINER_ID docker_hub用户名/镜像名:tagname
push
docker push docker_hub用户名/镜像名:tagname
docker hub的使用
如果你使用hub.docker.com来管理你的镜像,那么就涉及到账户登录,如果你docker pull时遇到如下的提示:
unauthorized: incorrect username or password
那么说明你登录信息过期了,需要重新登录:
docker login
查看日志
查看最新30分钟的日志:
docker logs --since 30m CONTAINER_ID
其他需求,请详细查看logs 的参数
查看详细信息
docker inspect id|name
其他参考
资深专家都知道的 Docker 常用命令---源英文:Top Docker Commands Any Expert Should Know
Docker之容器的创建、启动、终止、删除、迁移等
docker入门——构建镜像
DEBIAN_FRONTEND这个环境变量,告知操作系统应该从哪儿获得用户输入。如果设置为"noninteractive",你就可以直接运行命令,而无需向用户请求输入(所有操作都是非交互式的)。
这在运行apt-get命令的时候格外有用,因为它会不停的提示用户进行到了哪步并且需要不断确认。非交互模式会选择默认的选项并以最快的速度完成构建。
请确保只在Dockerfile中调用的RUN命令中设置了该选项,而不是使用ENV命令进行全局的设置。因为ENV命令在整个容器运行过程中都会生效,所以当你通过BASH和容器进行交互时,如果进行了全局设置那就会出问题。
正确的做法 - 只为这个命令设置ENV变量
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python3
错误地做法 - 为接下来的任何命令都设置ENV变量,包括正在运行地容器
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get install -y python3
我的示例如下:
FROM ubuntu:trusty
MAINTAINER mryqu
RUN \
DEBIAN_FRONTEND=noninteractive apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get -y install wget curl && \
DEBIAN_FRONTEND=noninteractive apt-get -y autoremove && \
DEBIAN_FRONTEND=noninteractive apt-get clean
这两天开始学习docker,发现docker确实很强大,让网站部署和维护的效率大大提高。遂准备将手头维护的几个小站,全部docker化。整理的过程中感觉到,docker可以以功能或者进程为单位进行部署和维护,不用再花时间在繁琐的配置上面,但是docker和宿主之间的数据共享以及docker间的数据共享仍然是让人头疼和操心的地方。正好翻到官方文档,看到相关内容,遂决定翻译一下,水平有限,欢迎吐槽。
几个基本概念:
docker: 一种容器管理技术,这里也指既有的开发工具链。
container: 容器
image: 镜像
volum:卷 [译者:卷可以理解成计算机中的文件路径]
原文链接:Manage data in containers
翻译正文:
之前我们介绍了docker基本概念,学习了docker 镜像如何工作以及docker之间的网络和联系。这章节我们将继续讨论怎么在docker内和docker之间管理数据。
我们将着重讨论两种你所能管理docker数据的方式
数据卷是一种特殊的存在于一个或者多个docker内部的不同于Union File System的目录。数据卷提供多种有用的特性用来持久化和共享数据:
数据卷被设计用来持久化存储数据,独立于容器的生命周期。当你删除容器时,docker并不会自动删除数据卷,不使用的数据卷,也不会替你“垃圾回收”。
你可以通过 -v 标示在 docker create 和 docker run 命令中给容器增加一个数据卷。你可以多次使用 -v 增加多个数据卷。让我们给我们的web应用容器挂载一个单独的数据卷。
$ docker run -d -P --name web -v /webapp training/webapp python app.py
这条指令将会在容器内部的 /webapp 路径下创建一个新卷。
注意:你也可以使用 VOLUME 指令在 Dockerfile 文件中添加一个或者多个卷到容器中。
docker中的卷默认是读写权限,但你也可以设置为只读。
$ docker run -d -P --name web -v /opt/webapp:ro training/webapp python app.py
你可以使用 ‘docker inspect’ 指令来查看一个卷。
$ docker inspect web
输出将会提供详细的容器配置和卷信息。输出格式类似如下:
Mounts": [ { "Name": "fac362...80535", "Source": "/var/lib/docker/volumes/fac362...80535/_data", "Destination": "/webapp", "Driver": "local", "Mode": "", "RW": true } ]
你将看到‘Source’表示的是宿主路径,‘Destination’表示的是容器路径。 RW 用来标示这个卷的读写属性。
通过 -v 标示你可以挂载一个宿主目录到容器中。
$ docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
这条命令将宿主的 /src/webapp 挂载到容器的 /opt/webapp 卷上。如果 /opt/webapp 已经存在,/src/webapp 将会覆盖但是不会移除已有的文件。当挂载的卷移除后,原先被覆盖的内容将可以再次使用。这个和mount的行为是一致的。
container-dir 必须是绝对路径,比如 /src/docs。host-dir可以是绝对路径,也可以是一个已经声明过的数据卷。如果你指定host-dir为绝对路径,docker将会按你指定的路径挂载,如果你提供的是一个声明的卷,docker将会按照name 指定的名称创建一个声明的卷。
一个 name 声明的卷必须以字母开头,后面跟随z-z0-9,_,. 或者 -。绝对路径都以 / 开始。
例如,你可以用/foo 或者 foo 作为一个 host-dir.如果你使用 /foo ,docker 创建一个挂载点。如果你使用 foo, docker 创建一个声明的卷。
如果你在 Mac 或者 Windows 上使用 docker,你的docker后台只能拥有有限的权限。docker尝试着自动分享你的 /User 或者 C:\Users 目录,所以在OS X上挂载如下:
docker run -v /Users/<path>:/<container path> ...
windows上如下:
docker run -v /c/Users/<path>:/<container path> ...
其他来自虚拟机的目录,比如你想共享virtualbox 中的某些目录,你需要做些额外的工作。在 virtualbox下,你先要使宿主的目录变成共享,然后才能使用 -v 来挂载。
挂载宿主的目录对测试来说很有用。比如你可以在容器中挂载源码,然后修改代码,实时看修改后的执行效果。宿主的路径必须是绝对路径,如果路径不存在,docker就会在本地创建它。这种 auto-creation 将会被移除。
这里我们仍然挂载 /src/webapp 目录,但是增加了ro选项来声明挂载的目录是只读的。
$ docker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py
注意:宿主目录是主机相关的,所以你不能在Dockerfile中挂载一个宿主目录,因为镜像要可移植,而不同的主机有不同的目录结构。
Labeling 系统例如 SELinux 要求数据卷被容器挂载时要标示。如果没有标示,安全系统可能会阻止容器内的进程访问卷的内容。默认情况下,docker不会改变操作系统的卷标识。
要在容器的上下文中修改卷标识,你需要在挂载时增加 :z 或者 :Z 标识。z 表示多个容器共享卷内容,所以docke用共享标识来标示卷内容,共享的标识允许多个容器读写内容。Z 表示docker用私有的标识来标示卷内容,所以只有当前的容器能访问这个私有的卷内容。
-v 也可以用来挂载一个单独的文件而不仅仅是目录:
$ docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
这个指令将会让你进入容器的命令行,能获取宿主的历史纪录,并且退出时,宿主的历史记录能纪录容器的指令操作。
注意:许多编辑工具包括 vi ,sed --in-place 等可能会导致inode数据结构变更。自从docker1.1.0后,此类操作会导致" sed:cannot rename ./sedKdj9Dy:Device or resource busy"。[In the case where you want to edit the mounted file, it is often easiest to instead mount the parent directory.][译者:这句不是很明白什么意思,望看到的网友指点]
如果你有一些希望分享给多个容器的持久化数据,或者想从 non-persistent 容器中使用这些数据,最好的办法是创建一个命名的数据卷容器,然后从从容器中挂载使用数据。
让我们创建一个共享数据卷的容器。这个容器不运行应用,它提供 training/postgres 镜像,这样所有的容器都共用统一的接口,从而节省空间。
$ docker create -v /dbdata --name dbdata training/postgres /bin/true
你可以在其他的容器中用 --volumes-from 标示来挂载 /dbdata 卷。
$ docker run -d --volumes-from dbdata --name db1 training/postgres
和
$ docker run -d --volumes-from dbdata --name db2 training/postgres
这个例子里,如果 postgres 镜像已经包含一个叫做 /dbdata 的目录,将会隐藏这个目录,只有挂载的可见。
你可以多次使用 --volumes-from 从多个容器中挂载多个卷。
你也可以用 db1 db2 来引用 dbdata。
$ docker run -d --name db3 --volumes-from db1 training/postgres
如果你删除挂载了卷的容器,包括初始的dbdata 或者子序列的 db1 db2等,这些卷将不会被删除。如果你要删除卷,你需要明确的调用 docker rm -v,这个操作可以让你去在容器之间更新,或者高效的迁移数据。
注意:当你删除一个容器不带 -v 时,docker不会警告提醒你。当你不带 -v 删除容器时,将会出现‘挂起’的数据卷,这些卷不再被容器引用。‘挂起’的卷很难避免,并且占用空间。我们在尽力提升卷管理功能,参见pull request #14214
数据卷的另外一个有用的功能是用来备份,恢复和迁移数据。我们使用 --volumes-from 来创建一个新容器并挂载数据卷:
$ docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
示例中我们启动了一个新容器并且从dbdata 容器挂载了数据卷。我们把宿主本地路径挂载成 /backup.最后,我们用tar命令将dbdata数据卷备份进backup.tar,并存入 /backup目录。当命令结束时,我们将在本地目录下得到一个dbdata的备份。
你可以用它来恢复到之前备份的容器里,或者其他的容器:
docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
然后 un-tar 备份的文件到新的容器数据卷中:
$ docker run --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar"
你可以使用上面的方法来自动化地备份迁移和恢复数据。
多个容器可以共享一个或者多个数据卷,但是同时写入的时候会发生冲突。
数据卷在宿主里面是可以直接操作的。你可以使用普通的linux工具操作它们。但是建议你不要这样直接做,因为容器和应用并不知道你的操作,这可能会导致数据操作冲突。
我们学习了很多关于怎么使用docker,接下来我们将看到怎么将docker和Docker Hub上的服务例如自动编译,创建私有仓库等结合起来使用。
Go to Working with Docker Hub
完!
译者:本文中的部分命令参数是过时或者错误的,但这些可以忽略,并不影响我们理解指令的正确用法。
最近开始做docker相关的学习和技术准备,准备将目前的一些基础服务,通过docker做同构或者异构分布式调整,提升运维效率和系统稳定性。
我的系统:
Linux chicago1 3.2.0-4-amd64 #1 SMP Debian 3.2.41-2 x86_64 GNU/Linux
Docker要求Kernel 3.8+,幸运的是, wheezy-backports 目前有Kernel 3.16 , 该版本正式支持Docker。
在文件 /etc/apt/sources.list中添加如下行
deb http://http.debian.net/debian wheezy-backports main
然后安装linux-image-amd64包 (注意使用 -t wheezy-backports)
sudo apt-get update
sudo apt-get install -t wheezy-backports linux-image-amd64
使用get.docker.com 的脚本:
curl -sSL https://get.docker.com/ | sh
为了卸载Docker包:
$ sudo apt-get purge lxc-docker
为了永久卸载Docker及其依赖包,你应该这样:
$ sudo apt-get autoremove --purge lxc-docker
命令将不会移除镜像,容器,数据卷,或者用户创建的配置文件。如果你希望删除所有镜像,容器,数据卷 ,运行如下命令:
$ rm -rf /var/lib/docker
你必须手动删除用户创建的配置项。