Docker命令源代码
Docker的源代码全部是用Go语言写的。其中,
- commands.go 是docker的命令行接口,是对REST API的一个轻量级封装。
- Engine API, REST API的路由(接受commands.go中的请求,转发到server.go)
- server.go, 大部分REST API的实现
查看当前Docker版本:
$ docker --version
Docker version 1.13.1, build c301b04-unsupported
$ docker-compose --version
docker-compose version 1.20.1, build 5d8c71b
升级Docker版本
卸载旧版本
$ sudo dnf remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
# 删除的软件包
Removed:
container-selinux.noarch 2:2.55-1.fc28
docker.x86_64 2:1.13.1-51.git4032bd5.fc28
docker-common.x86_64 2:1.13.1-51.git4032bd5.fc28
policycoreutils-python-utils.noarch 2.7-18.fc28
python3-policycoreutils.noarch 2.7-18.fc28
atomic-registries.x86_64 1.22.1-2.fc28
checkpolicy.x86_64 2.7-7.fc28
container-storage-setup.noarch 0.8.0-3.git1d27ecf.fc28
criu.x86_64 3.8.1-1.fc28
docker-rhel-push-plugin.x86_64 2:1.13.1-51.git4032bd5.fc28
libnet.x86_64 1.1.6-15.fc28
oci-register-machine.x86_64 0-6.1.git66fa845.fc28
oci-systemd-hook.x86_64 1:0.1.15-1.git2d0b8a3.fc28
oci-umount.x86_64 2:2.3.4-1.git87f9237.fc28
protobuf-c.x86_64 1.3.0-4.fc28
python3-IPy.noarch 0.81-21.fc28
python3-audit.x86_64 2.8.3-3.fc28
python3-libsemanage.x86_64 2.7-12.fc28
python3-pytoml.noarch 0.1.14-5.git7dea353.fc28
python3-setools.x86_64 4.1.1-6.fc28
skopeo-containers.x86_64 0.1.29-5.git7add6fc.fc28
subscription-manager-rhsm-certificates.x86_64 1.21.2-3.fc28
为安装docker添加repo:
# 查看是否安装了dnf-plugins-core软件包
$ dnf list dnf-plugins-core
# 如果没有安装,则
$ sudo dnf -y install dnf-plugins-core
# 添加repo
$ sudo dnf config-manager \
--add-repo \
https://download.docker.com/linux/fedora/docker-ce.repo
安装docker CE
# 列出repo中Docker CE的版本:
$ dnf list docker-ce --showduplicates | sort -r
docker-ce.x86_64 18.06.0.ce-3.fc28 docker-ce-stable
docker-ce.x86_64 18.03.1.ce-3.fc28 docker-ce-stable
# 安装最新的稳定版本
$ sudo dnf install docker-ce
Installed:
docker-ce.x86_64 18.06.0.ce-3.fc28 checkpolicy.x86_64 2.7-7.fc28
container-selinux.noarch 2:2.55-1.fc28 policycoreutils-python-utils.noarch 2.7-18.fc28
python3-IPy.noarch 0.81-21.fc28 python3-audit.x86_64 2.8.3-3.fc28
python3-libsemanage.x86_64 2.7-12.fc28 python3-policycoreutils.noarch 2.7-18.fc28
python3-setools.x86_64 4.1.1-6.fc28
# 安装指定版本
$ sudo dnf -y install docker-ce-<VERSION STRING>
更新后版本
$ docker --version
Docker version 18.06.0-ce, build 0ffa825
$ docker-compose --version
docker-compose version 1.20.1, build 5d8c71b
Docker守护进程的启动:
$ sudo systemctl start docker #建议使用的启动方式
Redirecting to /bin/systemctl start docker.service
$ sudo service docker start
Redirecting to /bin/systemctl start docker.service
$ sudo systemctl start docker.service
Docker守护进程的停止/查看状态:
$ sudo systemctl status docker.service
docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Active: active (running) since Fri 2018-08-10 08:50:42 CST; 3s ago
Docs: http://docs.docker.com
Main PID: 5344 (dockerd-current)
Tasks: 31 (limit: 8192)
Memory: 26.6M
CGroup: /system.slice/docker.service
└─5344 /usr/bin/dockerd-current --add-runtime oci=/usr/libexec/docker/docker-runc-current --default->
$ sudo systemctl stop docker.service
$ sudo systemctl restart docker.service
查看docker运行状态和基本信息
$ sudo docker info
该命令可以显示docker守护进程运行状况的缩影,包括容器个数、镜像个数、Daemon版本、使用的存储驱动等信息。
Tips - 设置软连接避免Docker占用存储过大导致根分区空间不足
Docker的根目录(Root Dir): /var/lib/docker ,一般挂载在根分区,该路径下存储了很多内容,当使用Docker越来越多时,Docker开始占用大量的空间,为避免根分区空间不足导致系统无法运行。需要考虑新的解决方案。
参考CentOS7更改Docker默认镜像和容器存储位置资料中旨在不添加docker.conf文件的方式下,使用软链接的方法进行改变根目录。具体方法如下:
- 准备工作之停止docker守护进程
$ sudo systemctl stop docker
- 准备工作之查看/var/lib/docker属性,确认剩余存储空间(free space)
# df -hl /var/lib/docker
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/fedora-root 77G 17G 57G 23% / //此时挂载点为/,存储剩余空间为57GB
- 准备工作之备份数据
# cp -rp /var/lib/docker /data // 此处"/data"是一个硬盘空间较大的一个挂载点
//将原/var/lib/docker目录修改为其它名字,如/var/lib/docker-backup
# mv /var/lib/docker/ /var/lib/docker-backup-20180814
- 创建软连接
# ln -s /data/docker /var/lib/docker
- 确认软连接能够正常工作
# df -hl /var/lib/docker
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/data-data 7.3T 18G 7.3T 1% /data //此时挂载点已经变成了/data,存储剩余空间为7.3TB
- 启动docker守护进程
$ sudo systemctl start docker
- 使用docker info确认docker守护进程使用新存储位置
现在已存在的数据应该在软链的源目录内, 新的容器和镜像也将存储在新的位置,即 /data/docker 。
# docker info //查看显示的信息,确认数据无丢失
# docker info |grep Root //仅查看docker根目录变更情况
Docker Root Dir: /data/docker
- 无法启动错误排查
因为磁盘挂载或其他原因,如/data/docker
不可用,会导致docker无法启动。
$ ll -l /var/lib/docker
$ sudo systemctl start docker
Job for docker.service failed because the control process exited with error code.
See "systemctl status docker.service" and "journalctl -xe" for details.
$ sudo systemctl status docker.service
docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Process: 17769 ExecStart=/usr/bin/dockerd -H fd:// (code=exited, status=1/FAILURE)
Main PID: 17769 (code=exited, status=1/FAILURE)
修复后,解决docker无法重启的问题。
Tips - 创建docker用户组免sudo使用docker命令
Docker守候进程绑定的是一个unix socket,而不是TCP端口。这个套接字默认的属主是root,其他是用户可以使用sudo命令来访问这个套接字文件。因为这个原因,docker服务进程都是以root帐号的身份运行的。
为了避免每次运行docker命令的时候都需要输入sudo,可以创建一个docker用户组docker,并把相应的用户添加到这个分组里面。当docker进程启动的时候,会设置该套接字可以被docker这个分组的用户读写。这样只要是在docker这个组里面的用户就可以直接执行docker命令了。
警告:该dockergroup等同于root帐号. 具体方法如下:
# 使用有sudo权限的帐号登录到服务器系统,如用户${USER}
# 新建用户组docker之前,查看用户组中有没有docker组
$ sudo cat /etc/group | grep docker
# 添加docker用户组
$ sudo groupadd docker
# 把用户[brian]加到docker用户组[docker]中
$ sudo usermod -a -G docker brian
# 查看当前用户组是否变更
$ groups
# 切换用户,确保当前用户所在用户组已变更
$ su root 切换到root用户
$ su ${USER} 再切换到原来的用户, groups配置才生效
# 重启docker后台服务
$ sudo service docker restart
# 使用docker info确认是否成功
$ docker info
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.26/info: dial unix /var/run/docker.sock: connect: permission denied
# 确认/var/run/docker.sock权限
# 修改前
$ ls -al /var/run/docker.sock
srw-rw----. 1 root docker 0 Aug 10 09:20 /var/run/docker.sock //这说明docker组具备rw权限,应该可以免sudo使用docker命令了
# 如果还不能,说明你当前用户可能不在docker组中;也可以修改文件权限让其他人也可以直接使用docker命令
$ sudo chmod a+rw /var/run/docker.sock //增加其他人rw权限
# 修改后
$ ls -al /var/run/docker.sock
srw-rw-rw-. 1 root docker 0 Aug 10 09:20 /var/run/docker.sock
# 再次使用docker info确认是否成功
$ docker info
配置Docker daemon
Docker Engine V1.12 之后版本,用户可以自行创建 daemon.json 文件对 Docker Engine 进行配置和调整。当我们需要对docker服务进行调整配置时,不用去修改主文件 docker.service的参数,通过daemon.json配置文件来管理,更为安全、合理。默认情况下,该文件不存在。linux系统中配置文件的默认位置为:/etc/docker/daemon.json
。
- 该文件作为 Docker Engine 的配置管理文件, 里面几乎涵盖了所有 docker 命令行启动可以配置的参数。
- 不管是在哪个平台以何种方式启动, Docker 默认都会来这里读取配置。使用户可以统一管理不同系统下的 docker daemon 配置。
- 相关参数的使用说明,可以参阅 man dockerd 帮助信息
- 配置使用镜像加速器服务
配置使用阿里云面向个人开发者的镜像加速器服务,用户登录容器镜像服务控制台后,在左侧导航栏选择镜像工具>镜像加速器,在镜像加速器页面就会显示为您独立分配的加速器地址。
加速器地址:[系统分配前缀].mirror.aliyuncs.com
配置registry-mirrors
数组,提供镜像加速服务的url地址。
- 配置使用企业私有镜像仓库
配置insecure-registries
数组,提供私有镜像仓库的url地址。
示例daemon.json文件如下:
{
"registry-mirrors": [
"https://mapxyz.mirror.aliyuncs.com"
],
"insecure-registries": [
"http://docker.mapxyz.com",
"http://docker-v2.mapxyz.com",
]
}
修改配置文件之后需要重启docker生效
sudo systemctl restart docker.service
镜像相关命令
获取镜像
$ docker pull [image_name]
添加自建镜像源
# 创建或修改 /etc/docker/daemon.json 文件
sudo vim /etc/docker/daemon.json
# 写入
{
"registry-mirrors": ["https://docker.XXX.com"],
"insecure-registries": []
}
# 重启
$ systemctl restart docker
如果提示"Trying to pull repository [docker_image_name]...
ERROR: unauthorized: authentication required",则可能需要登录访问
$ docker login docker.XXX.com
查看镜像的环境变量(调用env):
$ docker run ubuntu env
容器相关命令
运行/停止容器
运行容器:
$ docker run phdbrianlee/docker-whale
docker run参数说明:
- -d 在后台运行容器
- --name 定义容器名称,如不定义则系统将给一个随机名称
- --restart 自动重启容器标志,取值always或on-failure,如--restart=on-failure:5
停止守护式容器运行
$ sudo docker stop {container name hopeful_brown}
重新启动已经停止运行的容器
$ sudo docker start {container name hopeful_brown}
$ sudo docker restart {container id 51368c7046d6}
查看容器的IP地址:
$ docker run ubuntu ip -r -o addr show eth0
查看容器列表
# 查看当前正在运行的容器
$ docker ps
# 查看本机所有的容器列表
$ docker ps -a
# 返回最近运行的容器的id
$ docker ps -l -q
# 查找某个正在运行的容器
$ docker ps |grep [search_key]
删除容器
# 删除没在运行的容器
$ sudo docker rm {container id 51368c7046d6}
$ sudo docker rm {container name sick_elion}
# Tips: 删除所有没有运行的容器(列出所有容器的id,然后根据id删除容器):
$sudo docker rm 'docker ps -a -q'
$sudo docker rm $(docker ps -a -q)
容器内进程相关操作
查看容器内进程
$docker top {container name hopeful_brown}
容器详细检查
$docker inspect {container name|ID}
在容器内运行进程——运行后台任务
$ sudo docker exec -d fffb22600ef1 touch /etc/new_config_file
在容器内运行进程——运行交互命令(交互式Shell)
$ sudo docker exec -t -i fffb22600ef1 /bin/bash
docker exec参数说明:
- -t 为容器分配一个伪tty终端
- -i 开启容器的持久标准输入(STDIN)
查看容器日志
$docker logs {container name hopeful_brown}
$ docker logs --tail 10 hopeful_brown 获取日志最后10行
$ docker logs --tail 0 -f hopeful_brown 跟踪容器最新日志而不必读取整个日志文件
Ctrl+C退出跟踪
容器打包和镜像迁移
# 将容器内的修改内容提交为镜像
$ docker commit {container id} new-image
# 镜像导出/打包
$ docker save new-image > /tmp/new-image.tar
# 拷贝到其他机器上,再导入
$ docker load < /tmp/new-image.tar
错误排查
- fedora 31 docker cgroups挂载点不存在
# 使用docker run报错
docker: Error response from daemon: cgroups: cgroup mountpoint does not exist: unknown.
# 使用docker-compose 报错
$ docker-compose up -d
Creating [container-name] ... error
ERROR: for mapboom_tile_service_redis Cannot start service redis: b'cgroups: cgroup mountpoint does not exist: unknown'
ERROR: for redis Cannot start service redis: b'cgroups: cgroup mountpoint does not exist: unknown'
ERROR: Encountered errors while bringing up the project.
方案一:
$ sudo dnf install grubby
$ sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0"
$ reboot
方案二:
[root@localhost yeqiang]# sudo vim /boot/efi/EFI/fedora/
kernelopts后面增加systemd.unified_cgroup_hierarchy=0
saved_entry=0
menu_auto_hide=0
boot_success=1
kernelopts=root=/dev/mapper/fedora_localhost--live-root ro resume=/dev/mapper/fedora_localhost--live-swap rd.lvm.lv=fedora_localhost-live/root rd.lvm.lv=fedora_localhost-live/swap rhgb rd.driver.blacklist=nouveau systemd.unified_cgroup_hierarchy=0
boot_indeterminate=3
重启