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源
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs)
- 4)使用来自新添加的repo的Docker包更新包数据库:
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用户:
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版本]
- 二进制安装
从下载二进制文件,解压文件,并 拷贝文件到/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
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
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
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
输出显卡信息:
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 |
- 也可以使用gpus device=1 来查看1号卡的信息
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
- 容器自动重启
新建容器的时候配置自动重启 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
- 批量保存-加载镜像
批量保存:
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"
- 清理不用的镜像
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"
}
改目录这个事情 有很多手段,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"
}
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 案例
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
# deb http://archive.canonical.com/ubuntu xenial partner
# deb-src http://archive.canonical.com/ubuntu xenial partner
# deb http://security.ubuntu.com/ubuntu/ xenial-security main restricted
# deb-src http://security.ubuntu.com/ubuntu/ xenial-security main restricted
# deb http://security.ubuntu.com/ubuntu/ xenial-security universe
# deb-src http://security.ubuntu.com/ubuntu/ xenial-security universe
# deb http://security.ubuntu.com/ubuntu/ xenial-security multiverse
# deb-src http://security.ubuntu.com/ubuntu/ xenial-security 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
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
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
- docker-hub/download-rate-limit/
6 说明
参考文档:
docker 官文主页