docker笔记7--Docker常见操作

时间:2022-10-19 16:01:28


docker笔记7--Docker常见操作

1 docker 简介

1.1 基本概念

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

  1. 仓库
    仓库(Repository)是集中存放镜像的地方,大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现;
    目前 Docker 官方维护了一个公共仓库 Docker Hub, 一般使用这个仓库即可,也可以根据需要使用其它厂家的开源仓库,如阿里云的仓库。
  2. 镜像
    镜像是一个包含很多指令的只读模版,它可以用来创建docker 容器。
    通常一个镜像是基于另外一个镜像生成的,一般会在上面添加一些自定义部分,如工具资源、业务应用。
  3. 容器
    容器是一个可执行镜像的实例,我们可以通过 docker api或cli 对容器进行create、start、stop、move或者delete一个容器。 也可以连接一个容器到1个或者多个为例,并为容器附加存储,甚至可以基于容器当前状态创建一个新的镜像。

1.2 安装方法

  1. 通过源安装
    按照官方文档,添加源安装,此处以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)
  1. 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 安装或者下载解压安装
  2. 命令安装
    wget -qO- https://get.docker.com | sh 或者 curl -fsSL get.docker.com | sh 即可完成docker安装,该方法安装的为最新版本docker
  3. 使用国内阿里云源安装
    使用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版本]
  1. 二进制安装
    从下载二进制文件,解压文件,并 拷贝文件到/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. 升级方式
    升级方法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

  1. 安装方法
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. 测试方法
    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 |
  1. 也可以使用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 基础命令

  1. docker run --name=container_name [-p pc_port:container_port] [-v pc_path_file:container_path_file] image_name
    若添加参数 --net host ,则直接使用本地网络,不需要单独映射
  2. docker rename old_name new_name
  3. docker stats container_name
  4. docker inspect container_name
  5. docker exec -it [--user root] container_name bash 通过--user就可以使用root用户进入容器了

2.2 容器操作命令

  1. 基础操作
    删除docker0
    ip link delete docker0
  2. 卷操作
查看所有的卷
docker volume ls
删除所有未使用的数据,包括没有停止的容器、没有使用网络、dangling images 和 dangling build cache
docker system prune
删除未使用的卷
docker
  1. 容器自动重启
新建容器的时候配置自动重启 docker run –restart=always

配置自动重启 docker update –restart=always <CONTAINER ID>
关闭自动重启 docker update –restart=no <CONTAINER ID>

docker update --restart=no nacos-standalone-mysql
  1. 其它常见操作
1. 删除所有 Exited 的容器
docker ps -a|grep Exit|awk '{print $1}'|xargs docker rm

2.3 镜像操作命令

  1. 镜像保存与加载
    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
  1. 批量保存-加载镜像
批量保存:
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
  1. 将容器保存为镜像
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OPTIONS说明:
-a :提交的镜像作者;
-c :使用Dockerfile指令来创建镜像;
-m :提交时的说明文字;
-p :在commit时,将容器暂停。
案例:
docker commit -m "installed earch-pro and theme-comscore" -a "xg"
  1. 清理不用的镜像
docker image prune -fa --filter "until=240h"
清理 10天前且没有被使用的镜像
  1. 查看容器、镜像占用空间
[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 常见问题

  1. 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命令
  2. docker 启动报错–Starting docker (via systemctl): docker.serviceJob for docker.service failed because the control process exited with error code
  3. docker笔记7--Docker常见操作

  4. 解决方法: 删掉/var/lib/docker 目录,去掉docker/daemon.json中不必要参数,重启docker即可
  5. 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"]
}
  1. 安装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)
  1. docker 内update报错 Couldn’t create temporary file /tmp/apt.conf.Skg48r for passing config to apt-key
    解决方法:调整/tmp权限为777
  2. 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
  1. ​docker-hub/download-rate-limit/​

6 说明

参考文档:
​​​docker 官文主页​