1.  镜像操作

# 搜索镜像:docker search + 镜像名字
$ docker search python
# 从registry拉取镜像:docker pull + 镜像名字:版本号
$ docker pull python:3.8
# 查看本地镜像: docker images
$ docker images
# 使用Dockerfile创建镜像: docker build + 目录,.代表当前目录,-t表示加标签
$ docker build -t mypython  .
# 删除一个或多个镜像: docker rmi + 镜像1 + 镜像2
$ docker rmi mypython mypython2
# 删除未使用过的镜像
$ docker image prune -a
# 给镜像加标记:docker tag 镜像标签 新镜像标签名
$ docker tag mypython my_python
# 把镜像保存为.tar文件: docker save 镜像 > 文件
$ docker save mypython > mypython.tar
# 从.tar文件载入镜像: docker load -i .tar文件
$ docker load -i mypython.tar
# 根据容器创建镜像:docker commit 容器名 镜像名
$ docker commit

2. 容器操作 


# 创建容器: docker create + 选项(-i, -t, -d, -p, -v, -e) + 镜像
$ docker create --name mypython_1 -it -p 5000:5000 mypython
# 各选项含义
# -i:以交互模式运行容器,通常与-t 同时使用;
# -d:后台运行容器,并返回容器ID;
# -p:端口隐射, 宿主机在前,容器在后
# -t:为容器重新分配一个伪输入终端,通常与-i 同时使用;
# -v:目录挂载
# --entrypoint: 指定进入点
# --restart=always: 服务重启
# 启动容器:docker start + 容器名
$ docker start mypython_1
# 创建 + 运行容器: docker run + 选项 + 镜像 + 命令
$ docker run --name mypython_1 -d -p 8000:5000 mypython
$ docker run -it debian /bin/bash
# 查看正在运行中的容器:docker ps
$ docker ps
# 查看所有容器,包括停止运行的容器: docker ps -a
$ docker ps -a
# 停止一个正在运行的容器: docker stop 容器
$ docker stop mypython_1
# 重启容器:docker restart + 容器名
$ docker restart mypython_1
# 容器重命名:docker rename 老名字 新名字
$ docker rename mypython_1 mypython_2
# 删除一个容器:docker rm 容器名
$ docker rm mypython_1
# 强制删除一个正在运行的容器:docker rm -f 容器名
$ docker rm -f mypython_1
# 删除已停止运行的所有容器: docker container prune
$ docker container prune
# 拷贝文件,从容器到宿主机:docker cp 容器名:容器内路径 宿主机文件路径
$ docker cp mypython_1:/login.html login.html
# 拷贝文件,从宿主机到容器:docker cp 宿主机文件路径 容器名:容器内路径
$ docker cp login.html mypython_1:/login.html 
# 进入运行的容器,执行命令: docker exec + 选项 + 容器名 + 命令 + 参数
# 推荐大家使用 docker exec命令,因为此退出容器终端,不会导致容器的停止
$ docker exec -it mypythonx_1 /bin/bash
$ docker exec -it mypython_1 /bin/bash start.sh
# 查看容器端口映射:docker port 容器名
$ docker port mypython_1
# 查看容器内已修改文件:docker diff 容器名
$ docker diff mypython_1
# 查看容器日志:docker logs + 容器名
$ docker logs mypython_1
# 查看容器内运行进程:docker top + 容器名
$ docker top mypython_1
# 查看容器的底层信息:docker inspect + 容器名
$ docker inspect mypython_1
# 利用inspect命令查看容器的IP地址
$ docker inspect mypython_1 | grep "IPAddress"
# 查看运行容器的统计数据:docker stats
$ docker stats

  3.  Dockerfile详解

命令

描述

示例

FROM

指定基础镜像

FROM python:3.8

MAITAINER

维护人

MAITAINER  专职

COPY

复制文件或目录

COPY .  /usr/src/app

ADD

复制文件并自动解压

ADD myfile.tar /usr/src/app

RUN

创建镜像时要执行的命令

RUN pip install -r requirements.txt -i 

https://pypi.tuna.tsinghua.edu.cn/simple

USER

切换执行后续命令的用户和用户组, 但这个用户必需首先已使用RUN的命令进行创建好了。

RUN groupadd -r redis && useradd -r -g redis redis; USER redis(切换用户)

WORKDIR

指定工作目录

WORKDIR /usr/src/app

CMD

给启动的容器指定默认要运行的程序。运行 docker run 时如果使用了 --entrypoint 选项,将覆盖 CMD 指令指定的程序。

CMD

[ "pypy3", "/usr/src/app/docker_test03/app.py" ]

ENV

设置环境变量

ENV APP_HOME /html/myapp

ENTRYPOINT

容器启动时指定运行程序的入口点。同CMD,但其不会被覆盖,可以和docker run命令传递的参数进行拼接执行。

如果设置:ENTRYPOINT ["nginx", "-c"] , 运行$ docker run mynginx_1 -c /etc/nginx/myweb.conf将默认执行命令:nginx -c /etc/nginx/myweb.conf

VOLUME

定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

VOLUME /tmp

EXPOSE

暴露容器端口,端口会暴露给link到当前容器或通过网络连接的容器,不会和宿主机端口映射关系。

EXPOSE 8080

 一个示例Dockerfile如下所示:

# 基于的基础镜像
FROM pypy:3.7

# 设置app文件夹是工作目录
WORKDIR /usr/src/app

# COPY指令和ADD指令功能和使用方式类似。只是COPY指令不会做自动解压工作。。
COPY . /usr/src/app

# 执行指令,安装依赖
# RUN pip install --no-cache-dir -r requirements.txt
RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

# 执行命令
CMD [ "pypy3", "/usr/src/app/docker_test03/app.py" ]

使用编写好的Dockerfile创建镜像: -t: 镜像名称:TAG,    . 代表Dockerfile在当前目录

sudo docker build -t flask_app:v1 .

 使用创建好的镜像创建容器,将容器内的app.py挂载到宿主机

sudo docker create --name flask_app01 -it -p 8000:8000 --restart=always -v /home/mayanan/docker_test/docker01/app.py:/usr/src/app/app.py flask_app:v1

 启动创建好的容器

sudo docker start flask_app01

 创建容器,启动容器可以一步搞定:创建并启动容器

sudo docker run --name flask_app01 -d -p 8000:8000 --network my-docker-compose-network --restart=always -v /home/mayanan/docker_test/docker01/app.py:/usr/src/app/app.py flask_app:v1

4. 网络操作


Docker network 是主要是用做容器之间的通信,即组建容器之间的局域网,然后加入这个网络的容器可以使用别名(network-alias, 比如web, db)或者IP地址进行通信,就如同局域网中主机之间的相互访问。


Docker网络驱动模式

Docker 的网络驱动默认情况下有四个:bridge、host、overlay 和 macvlan,还有一个特殊的网络驱动none 用于禁止容器访问网络。

  • bridge:默认的网络驱动程序。如果在创建的时候没有指定网络驱动,则默认使用 bridge,也就是桥接网络。跟虚拟机的网络地址转换差不多,通过一个内部的子网向容器提供 IP 和网络。
  • host:容器会直接与宿主系统共享 IP 地址和网络,但是其它(例如存储,进程命名空间和用户命名空间)相对宿主机隔离的。
  • overlay:覆盖网络模式可以将不同的Dockerd守护进程连接在一起,该网络模式支持集群容器之间相互通信,以及集群和某个单机版独立容器直接相互通信。该网络模式使用场景比较广泛,通常集群部署时会使用该模式。
  • macvlan:这个网络驱动有点像虚拟机的桥接模式,它可以让你的容器直接连接到你的物理网络,比如连接到你的路由器,让物理网络来提供 IP 地址和网络。
  • none: 禁用容器所有网络。通常与自定义网络驱动程序一起使用。

创建一个network

# mysite1-network是局域网的名字,可以自定义。默认bridge模式。
$ docker network create mysite1-network 

# 利用--driver或-d指定使用bridge驱动,创建mysite2-network网络
$ docker network create –-driver bridge mysite2-network

# 查看已创建的network列表
$ docker network ls  

# 查看网络详情
$ docker network inspect mysite1-network

将容器连接到network

# 运行新的容器,并加入到mysite1-network网络中
# --network 表示这个容器要连接到的网络
# --network-alias 表示这个容器在此网络中的名称,也可以使用--ip来指定容器的ip

$ docker run --name=docker-web -d --network=mysite1-network 
--network-alias=web docker-web-image

# 将已经在运行的容器加入网络使用以下命令, 容器名为docker-web,别名为web
$ docker network connect --alias=web --network=mysite1-network docker-web

# 连接网络时为docker-web容器指定ip地址
$ docker network connect --ip=192.10.36.122 multi-host-network docker-web

# 断开docker-web容器与mysite1-network的连接
$ docker network disconnet mysite1-network docker-web

删除network

# 删除mysite1-network网络
$ docker network rm mysite1-network