docker笔记7--Docker常见操作
1 docker 简介
1.1 基本概念
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
- 仓库
仓库(Repository)是集中存放镜像的地方,大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现;
目前 Docker 官方维护了一个公共仓库 Docker Hub, 一般使用这个仓库即可,也可以根据需要使用其它厂家的开源仓库,如阿里云的仓库。 - 镜像
镜像是一个包含很多指令的只读模版,它可以用来创建docker 容器。
通常一个镜像是基于另外一个镜像生成的,一般会在上面添加一些自定义部分,如工具资源、业务应用。 - 容器
容器是一个可执行镜像的实例,我们可以通过 docker api或cli 对容器进行create、start、stop、move或者delete一个容器。 也可以连接一个容器到1个或者多个为例,并为容器附加存储,甚至可以基于容器当前状态创建一个新的镜像。
1.2 安装方法
- 通过源安装
按照官方文档,添加源安装,此处以Ubuntu为例,其它系统一官文为主
1)向系统添加官方Docker存储库的GPG密钥:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
2)add-apt-repository 是由 Python-software-properties这个工具包提供的,所以要先安装python-software-properties 才能使用 add-apt-repository
apt-get install python-software-properties
apt-get update
3)将Docker存储库添加到APT源
4)使用来自新添加的repo的Docker包更新包数据库:add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt-get update
确保你要安装的是Docker repo而不是默认的Ubuntu 16.04 repo
apt-cache policy docker-ce(看到docker-ce相关的版本信息)
5)apt-get install -y docker-ce(默认为最新版本,也可以指定版本安装)
docker-compose安装,pip 安装或者下载解压安装 - 命令安装
wget -qO- https://get.docker.com | sh 或者 curl -fsSL get.docker.com | sh 即可完成docker安装,该方法安装的为最新版本docker - 使用国内阿里云源安装
使用su - 进入root用户:
阿里云-Docker CE镜像sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" sudo apt-get update sudo apt-get install docker-ce pip install docker-compose [Ubuntu使用国内源安装指定Docker版本](https://blog.csdn.net/M82_A1/article/details/98870376)
- 二进制安装
从 下载二进制文件,解压文件,并 拷贝文件到/usr/bin 目录1)解压 tar zxvf docker-19.03.14.tgz 2)拷贝 cp docker/* /usr/bin/ 3)新建docker组 groupadd docker 注意:此处一定要添加docker组,否则启动时候会报类似下面这样的错误: docker.serviceJob for docker.service failed 4)新建可执行shell文件,并添加相关内容 touch /etc/init.d/docker chmod 755 /etc/init.d/docker 增加如下内容(实际建议从已有的系统上拷贝一个近似版本的文件): #!/bin/sh set -e ### BEGIN INIT INFO # Provides: docker # Required-Start: $syslog $remote_fs # Required-Stop: $syslog $remote_fs # Should-Start: cgroupfs-mount cgroup-lite # Should-Stop: cgroupfs-mount cgroup-lite # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Create lightweight, portable, self-sufficient containers. # Description: # Docker is an open-source project to easily create lightweight, portable, # self-sufficient containers from any application. The same container that a # developer builds and tests on a laptop can run at scale, in production, on # VMs, bare metal, OpenStack clusters, public clouds and more. ### END INIT INFO export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin BASE=docker # modify these in /etc/default/$BASE (/etc/default/docker) DOCKERD=/usr/bin/dockerd # This is the pid file managed by docker itself DOCKER_PIDFILE=/var/run/$BASE.pid # This is the pid file created/managed by start-stop-daemon DOCKER_SSD_PIDFILE=/var/run/$BASE-ssd.pid DOCKER_LOGFILE=/var/log/$BASE.log DOCKER_OPTS= DOCKER_DESC="Docker" # Get lsb functions . /lib/lsb/init-functions if [ -f /etc/default/$BASE ]; then . /etc/default/$BASE fi # Check docker is present if [ ! -x $DOCKERD ]; then log_failure_msg "$DOCKERD not present or not executable" exit 1 fi check_init() { # see also init_is_upstart in /lib/lsb/init-functions (which isn't available in Ubuntu 12.04, or we'd use it directly) if [ -x /sbin/initctl ] && /sbin/initctl version 2>/dev/null | grep -q upstart; then log_failure_msg "$DOCKER_DESC is managed via upstart, try using service $BASE $1" exit 1 fi } fail_unless_root() { if [ "$(id -u)" != '0' ]; then log_failure_msg "$DOCKER_DESC must be run as root" exit 1 fi } cgroupfs_mount() { # see also https://github.com/tianon/cgroupfs-mount/blob/master/cgroupfs-mount if grep -v '^#' /etc/fstab | grep -q cgroup \ || [ ! -e /proc/cgroups ] \ || [ ! -d /sys/fs/cgroup ]; then return fi if ! mountpoint -q /sys/fs/cgroup; then mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup fi ( cd /sys/fs/cgroup for sys in $(awk '!/^#/ { if ($4 == 1) print $1 }' /proc/cgroups); do mkdir -p $sys if ! mountpoint -q $sys; then if ! mount -n -t cgroup -o $sys cgroup $sys; then rmdir $sys || true fi fi done ) } case "$1" in start) check_init fail_unless_root cgroupfs_mount touch "$DOCKER_LOGFILE" chgrp docker "$DOCKER_LOGFILE" ulimit -n 1048576 # Having non-zero limits causes performance problems due to accounting overhead # in the kernel. We recommend using cgroups to do container-local accounting. if [ "$BASH" ]; then ulimit -u unlimited else ulimit -p unlimited fi log_begin_msg "Starting $DOCKER_DESC: $BASE" start-stop-daemon --start --background \ --no-close \ --exec "$DOCKERD" \ --pidfile "$DOCKER_SSD_PIDFILE" \ --make-pidfile \ -- \ -p "$DOCKER_PIDFILE" \ $DOCKER_OPTS \ >> "$DOCKER_LOGFILE" 2>&1 log_end_msg $? ;; stop) check_init fail_unless_root if [ -f "$DOCKER_SSD_PIDFILE" ]; then log_begin_msg "Stopping $DOCKER_DESC: $BASE" start-stop-daemon --stop --pidfile "$DOCKER_SSD_PIDFILE" --retry 10 log_end_msg $? else log_warning_msg "Docker already stopped - file $DOCKER_SSD_PIDFILE not found." fi ;; restart) check_init fail_unless_root docker_pid=`cat "$DOCKER_SSD_PIDFILE" 2>/dev/null` [ -n "$docker_pid" ] \ && ps -p $docker_pid > /dev/null 2>&1 \ && $0 stop $0 start ;; force-reload) check_init fail_unless_root $0 restart ;; status) check_init status_of_proc -p "$DOCKER_SSD_PIDFILE" "$DOCKERD" "$DOCKER_DESC" ;; *) echo "Usage: service docker {start|stop|restart|status}" exit 1 ;; esac 5)启动docker # /etc/init.d/docker start [ ok ] Starting docker (via systemctl): docker.service.
- 升级方式
升级方法1:卸载旧的docker,重新安装新版本
卸载方法:apt-get remove docker docker-engine docker.io containerd runc
重新添加源,并安装最新docker:apt-get install docker-ce docker-ce-cli containerd.io
how-to-completely-uninstall-docker
1.3 nvidia-docker 安装
使用1.2 中的方法安装普通docker后,再安装nvidia-docker
- 安装方法
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | apt-key add - distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list > /etc/apt/sources.list.d/nvidia-docker.list apt-get update apt-get install -y nvidia-docker2 nvidia-container-runtime 安装成功后,daemon.json中会有对应的 runtimes参数(data-root是自己加的),内容如下: { "runtimes": { "nvidia": { "path": "nvidia-container-runtime", "runtimeArgs": [] } }, "data-root": "/home/docker" }
- 测试方法
1)下载cuda镜像,直接在dockerhub 搜cuda即可,笔者使用 nvidia/cuda:10.2-base
2)使用如下命令测试
docker run --runtime=nvidia --rm nvidia/cuda:10.2-base nvidia-smi
输出显卡信息:
也可以使用gpus device=1 来查看1号卡的信息Thu Oct 15 08:33:15 2020 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 450.57 Driver Version: 450.57 CUDA Version: 11.0 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 GeForce GTX 108... On | 00000000:04:00.0 Off | N/A | | 21% 25C P8 9W / 250W | 1MiB / 11178MiB | 0% Default | | | | N/A | +-------------------------------+----------------------+----------------------+ | 1 GeForce GTX 108... On | 00000000:08:00.0 Off | N/A | | 21% 19C P8 9W / 250W | 1MiB / 11178MiB | 0% Default | | | | N/A | +-------------------------------+----------------------+----------------------+
docker run --gpus device=1 --rm nvidia/cuda:10.2-base nvidia-smi
注意:
测试的时候最好指定docker版本,否则容易出现cuda和驱动版本不一致的错误;
–gpus 参数为较新版本的参数,需要升级docker版本,笔者使用当前最新 19.03.13
2 常见命令
2.1 基础命令
- docker run --name=container_name [-p pc_port:container_port] [-v pc_path_file:container_path_file] image_name
若添加参数 --net host ,则直接使用本地网络,不需要单独映射 - docker rename old_name new_name
- docker stats container_name
- docker inspect container_name
- docker exec -it [--user root] container_name bash 通过--user就可以使用root用户进入容器了
2.2 容器操作命令
- 基础操作
删除docker0
ip link delete docker0 - 卷操作
查看所有的卷 docker volume ls 删除所有未使用的数据,包括没有停止的容器、没有使用网络、dangling images 和 dangling build cache docker system prune 删除未使用的卷 docker volume prune
- 容器自动重启
新建容器的时候配置自动重启 docker run –restart=always 配置自动重启 docker update –restart=always <CONTAINER ID> 关闭自动重启 docker update –restart=no <CONTAINER ID> docker update --restart=no nacos-standalone-mysql
- 其它常见操作
1. 删除所有 Exited 的容器 docker ps -a|grep Exit|awk '{print $1}'|xargs docker rm
2.3 镜像操作命令
- 镜像保存与加载
docker save -o filename image-name 可以将指定版本的镜像保卫为某个镜像包,docker load -i filename 可以将保存的镜像加载到系统中,案例如下:docker save -o flannel-v0.12.0-amd64.tar.gz quay.io/coreos/flannel:v0.12.0-amd64 docker load -i flannel-v0.12.0-amd64.tar.gz
- 批量保存-加载镜像
批量保存: docker images|tail -n +2|awk '{print $1":"$2, $1"-"$2".tar.gz"}'|awk '{print $1, gsub("/","-") $var}'|awk '{print "docker save -o " $3,$1}' > save_img.sh && bash save_img.sh 批量加载(进入到镜像所在的目录,该目录不要保留其它无关的文件): for i in $(ls);do docker load -i $i; done
- 将容器保存为镜像
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] OPTIONS说明: -a :提交的镜像作者; -c :使用Dockerfile指令来创建镜像; -m :提交时的说明文字; -p :在commit时,将容器暂停。 案例: docker commit -m "installed earch-pro and theme-comscore" -a "xg" 391449280df8 sre_gitbook:v1.0
- 清理不用的镜像
docker image prune -fa --filter "until=240h" 清理 10天前且没有被使用的镜像
- 查看容器、镜像占用空间
[root@worker-k8s003 lib]# docker system df TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 104 33 51.4GB 29.29GB (56%) Containers 100 92 3.67GB 2.404GB (65%) Local Volumes 0 0 0B 0B [root@worker-k8s003 lib]# docker system df -v Images space usage: REPOSITORY TAG IMAGE ID CREATED ago SIZE SHARED SIZE UNIQUE SiZE CONTAINERS registry-vpc.cn-shanghai.aliyuncs.com/xmotors_dtp/gta-console dev-21.52.2112281927 ec4fddb33230 15 hours ago ago 1.275GB 944.2MB 331.1MB 1 registry-vpc.cn-shanghai.aliyuncs.com/xmotors_dtp/account 1.6.13 8c7145786dc7 16 hours ago ago 1.186GB 917.8MB 268.5MB 1 ...... Containers space usage: CONTAINER ID IMAGE COMMAND LOCAL VOLUMES SIZE CREATED ago STATUS NAMES b72dfb04309f registry-vpc.cn-shanghai.aliyuncs.com/xmotors_dtp/account "docker-entrypoint..." 0 0B 31 minutes ago ago Up 31 minutes k8s_account_account-696d9f5b77-ln29l_pi-prod_97bd8041-684a-11ec-8646-00163e0630d4_0 3f8ec85c0a80 99e59f495ffa "/pause" 0 0B 31 minutes ago ago Up 31 minutes k8s_POD_account-696d9f5b77-ln29l_pi-prod_97bd8041-684a-11ec-8646-00163e0630d4_0 ... Local Volumes space usage: VOLUME NAME LINKS SIZE
2.4 常见配置
配置docker默认存储路径
$ cat /etc/docker/daemon.json
{
"hosts":[
"unix:///var/run/docker.sock"
],
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 1000000,
"Soft": 1000000
}
},
"ipv6": false,
"iptables": true,
"data-root": "/home/docker"
}
一般最好设置iptables为true,否则会出现容器内部无法访问公网的现象
改目录这个事情 有很多手段,dameon.json 是一种,直接软链接var/lib/docker也是一种 加-g也是一种
或者# cat /etc/default/docker, 追加 export DOCKER_OPTS=“-g /home/docker”
mac 设置方法:
注意: 早期docker版本使用的是graph,较新版本使用的是data-root
% cat ~/.docker/daemon.json
{
"experimental" : false,
"debug" : true,
"registry-mirrors":["https://docker.mirrors.ustc.edu.cn","http://hub-mirror.c.163.com"],
"data-root": "/home/xg/file/docker"
}
dockerd重启但容器不重启方法
在 /etc/docker/daemon.json 中配置live-restore true,然后重启dockerd即可
{
"live-restore": true
}
3 Dockerfile实例
3.1 构建 flask dockerfile
新建dockerfile
FROM ubuntu:16.04
RUN mkdir -p /home/flask
WORKDIR /home/flask
COPY app.py .
COPY sources.list /etc/apt
RUN install apt-transport-https -y && apt-get update && apt-get install curl -y && apt-get install python3 -y && apt-get install python3-pip -y && pip3 install flask
CMD python3 app.py
flask 案例
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_root():
print('v1.2 Hello Root!\n')
return 'v1.2 Hello Root!\n'
@app.route('/hello')
def hello_world():
print('v1.2 Hello World!\n')
return 'v1.2 Hello World!\n'
if __name__ == '__main__':
app.run(host='0.0.0.0')
sources.list 源
# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://archive.ubuntu.com/ubuntu/ xenial main restricted
# deb-src http://archive.ubuntu.com/ubuntu/ xenial main restricted
## Major bug fix updates produced after the final release of the
## distribution.
deb http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted
# deb-src http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted
## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team. Also, please note that software in universe WILL NOT receive any
## review or updates from the Ubuntu security team.
deb http://archive.ubuntu.com/ubuntu/ xenial universe
# deb-src http://archive.ubuntu.com/ubuntu/ xenial universe
deb http://archive.ubuntu.com/ubuntu/ xenial-updates universe
# deb-src http://archive.ubuntu.com/ubuntu/ xenial-updates universe
deb http://archive.ubuntu.com/ubuntu/ xenial multiverse
# deb-src http://archive.ubuntu.com/ubuntu/ xenial multiverse
deb http://archive.ubuntu.com/ubuntu/ xenial-updates multiverse
# deb-src http://archive.ubuntu.com/ubuntu/ xenial-updates multiverse
deb http://archive.ubuntu.com/ubuntu/ xenial-backports main restricted universe multiverse
# deb-src http://archive.ubuntu.com/ubuntu/ xenial-backports main restricted universe multiverse
build 镜像, 起服务
在当前目录新建镜像
docker build -t ubuntu_flask:v1.0 .
起服务端口为5000
docker run --name=flask -d -p 5000:5000 ubuntu_flask:v1.0
对镜像打tag
docker tag ubuntu_flask:v1.0 dockerhub.xxx.com/xg/ubuntu_flask:v1.0
上传镜像到dockerhub
docker push dockerhub.xxx.com/xg/ubuntu_flask:v1.0
3.2 构建带cron 和 CST时区镜像
FROM ubuntu:20.04
RUN mkdir -p /home/
WORKDIR /home/
COPY alarm_and_notify.py .
COPY root /var/spool/cron/crontabs/root
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y apt-utils && apt-get install inetutils-ping -y && apt-get install telnet -y && apt-get install curl -y && apt-get install cron && apt-get install screen -y && apt-get install vim -y \
&& apt-get install tzdata -y && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata \
&& apt-get install python3 -y && apt-get install python3-pip -y && pip3 install elasticsearch && pip3 install requests && pip3 install schedule && pip3 install pytz
CMD service cron start && sleep infinity
# CMD python3 -u /home/alarm_and_notify.py
注意: 需要将cron命令提前写到root文件内
4 常见问题
-
Got permission denied while trying to connect to the Docker daemon socket
docker进程使用Unix Socket而不是TCP端口。而默认情况下,Unix socket属于root用户,因此需要root权限才能访问。
解决方法,将当前用户添加到docker组,更新docker组即可,如下:
gpasswd -a yourUser docker #添加用户到docker
newgrp docker #更新docker用户组
更新完后即可使用该用户执行docker命令 -
docker 启动报错–Starting docker (via systemctl): docker.serviceJob for docker.service failed because the control process exited with error code
解决方法: 删掉/var/lib/docker 目录,去掉docker/daemon.json中不必要参数,重启docker即可 -
docker build 出现 Temporary failure resolving ‘archive.ubuntu.com’
解决方法:在daemon 中添加如下dns,并 docker restart 即可$ cat /etc/docker/daemon.json { "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "dns": ["8.8.8.8", "8.8.4.4", "2001:4860:4860::8888", "2001:4860:4860::8844"] }
-
安装docker 的时候提示 NO_PUBKEY 6ED91CA3AC1160CD
W: GPG 错误:https://nvidia.github.io/libnvidia-container/stable/ubuntu18.04/amd64 InRelease: 由于没有公钥,无法验证下列签名: NO_PUBKEY 6ED91CA3AC1160CD W: GPG error: https://nvidia.github.io/libnvidia-container/stable/ubuntu18.04/amd64 InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 6ED91CA3AC1160CD 解决方法: apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6ED91CA3AC1160CD(此处的key即为上面提示的key)
-
docker 内update报错 Couldn’t create temporary file /tmp/apt.conf.Skg48r for passing config to apt-key
解决方法:调整/tmp权限为777 -
Error response from daemon: too many requests
报错: # docker pull busybox Using default tag: latest Error response from daemon: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit 解决方法:用户dockerhub账户登录 # docker login --username dockerhubxg Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded 登录后正常拉取镜像 # docker pull busybox Using default tag: latest latest: Pulling from library/busybox f531cdc67389: Pull complete Digest: sha256:ae39a6f5c07297d7ab64dbd4f82c77c874cc6a94cea29fdec309d0992574b4f7 Status: Downloaded newer image for busybox:latest 退出登录: # docker logout Removing login credentials for https://index.docker.io/v1/
-
国内无法拉docker镜像问题
方法1: 直接将原始镜像加上 daocloud的前缀,如下: 参考: https://github.com/DaoCloud/public-image-mirror m.daocloud.io/docker.io/library/python:3.10-slim -> 在原镜像前加 m.daocloud.io/docker.io/library/ 即可 方法2: 参考 [解决目前Docker Hub国内无法访问方法汇总] (https://juejin.cn/post/7382524261683724329) , 配置如下mirros即可 vim /etc/docker/daemon.json { "registry-mirrors": ["https://docker.m.daocloud.io","https://dockerproxy.com","https://docker.nju.edu.cn","https://hub-mirror.c.163.com", "https://registry.aliyuncs.com", "https://docker.mirrors.ustc.edu.cn"], "data-root": "/data/docker" }
5 说明
参考文档:
docker 官文主页