Docker常用操作帅哥专供版
没错,这里的帅哥指的就是我自己
- Docker常用命令
Docker中文资源
Docker中文网站:https://www.docker-cn.com/
Docker安装手册:https://docs.docker-cn.com/engine/installation/
Docker常用教程: https://yeasy.gitbooks.io/docker_practice/content/image/pull.html
Docker 国内镜像
网易加速器:http://hub-mirror.c.163.com
官方中国加速器:https://registry.docker-cn.com
ustc的镜像:https://docker.mirrors.ustc.edu.cn
;查看版本号
docker --version
docker-compose --version
docker-machine --version
注意:
直接进入镜像, 在镜像中的操作, 在镜像关闭之后,就会还原.
如果想要做持久化,需要volume或者data container
有一个我常用的解决方案,因为我是用docker模拟服务器的.
所以我自己封装一个镜像, 装好所有想要的环境.而项目代码放在本机.
在启动镜像的时候,将主机目录映射到容器中,但是这样还是会有其他问题.
所以我建议, 以后还是要用volume或者data container 把产生的数据挂载到宿主机.
或者直接commit产生一个新的镜像出来.
volume的生存周期独立于容器,容器消亡,volume不会消亡.因此使用volume后,容器删除或重启后,数据却不会丢失
ubuntu 镜像默认的 CMD 是 /bin/bash ,如果我们直接 docker run -it ubuntu 的话,会直接进入 bash 。
我们 也可以在运行时指定运行别的命令,如 docker run -it ubuntu cat /etc/os-release 。
这就是用 cat /etc/os-release 命令替换了默认的 /bin/bash 命令了,输出了系统版本信息。
错误收集:
在今天的使用当中遇到一个问题.
//下载官方镜像
docker pull ubuntun
//以后台方式运行Ubuntu
docker run -d ubuntu
//此处正常返回了容器ID, 我当然认为运行成功了.
17f3c98f79dc361ff88787b6bafdbc445ed0e8e7f1a689efb38874f623c54f3b
//但是实际上通过docker ps 根本看不到当前有在运行,而且docker logs 什么也没有
//docker ps -a 看到他的status 为exited状态, 即已退出,也就是说,该容器运行就马上退出了
//百思不得其解
c9720c00769a ubuntu "/bin/bash" 4 seconds ago Exited (0) 5 seconds ago pedantic_keldysh
//后台发现Mac下需要一个-t参数就OK了
//原因在于镜像里面指定的默认启动程序是bash,对于Linux下的shell程序来说,tty是必须的,
//所以启动容器的时候要加上-t参数
docker run -t -d ubuntu
- 常用操作
# 删除所有容器
docker rm `docker ps -a -q`
# 停止所有容器
docker stop $(docker ps -q)
;查看镜像、容器、数据卷所占用的空间
docker system df
;目录映射
docker run -v /Users/liuhao/www:/usr/share/nginx/html -d nginx
;目录映射,:ro指定为只读
docker run --name nginx -v 主机目录:docker目录:ro -d nginx
;运行一个新容器,同时为它命名、端口映射、文件夹映射, 以redmine镜像为例
docker run --name redmine -p 9003:80 -p 9023:22 -d -v /var/redmine/files:/redmine/files -v /var/redmine/mysql:/var/lib/mysql sameersbn/redmine
- 镜像操作
;从Docker Hub查找镜像
docker search 镜像名称
;下载(不指定tag版本号,默认下载最新的一个latest版本,镜像名为全名如:pangee/lnmp)
docker pull 仓库地址 镜像名:版本号
;根据匹配信息拉取docker镜像
docker pull ${name:version}
;登陆到一个Docker镜像仓库
docker login -u 用户名 -p 密码 仓库地址
登录和退出 如果未指定镜像仓库地址,默认为官方地址
;退出一个Docker镜像仓库
docker logout -u 用户名 -p 密码
;标记本地镜像,将其归入指定用户的一仓库
docker tag image:version username/name:tag
;标记本地镜像,归类到该用户的库中,同时重新命名,设置版本号
docker tag myubuntu:v1 chinaliuhan/myubuntu:v1
;上传镜像(需要先行登录)
docker push 镜像名称:版本号
docker push chinaliuhan/myachain:v2
;列出所有本地镜像
docker images
docker image ls
;根据条件列出镜像
;如何没有${name}代表查看所有的镜像,有则代表条件搜索
docker images ${name}
;列出部分镜像
docker image ls [镜像名]
--digests 查看长ID, 删除镜像的时候可能会用得到
-q 只显示ID
;删除镜像
docker image rm 镜像名/镜像ID/镜像长ID
-f :强制删除;
--no-prune :不移除该镜像的过程镜像,默认移除;
;删除镜像,在使用过程中发现和image rm有所不同
docker rmi 镜像名/镜像ID/镜像长ID
-f :强制删除;
--no-prune :不移除该镜像的过程镜像,默认移除;
;删除所有镜像
docker rmi $(docker images)
;显示镜像信息,可以使用--format='{{GO语言模板语法}}'做格式化
docker image inspect [--format='{{GO语言模板语法}}'] 镜像ID
- 容器的使用
;显示所有docker客户端可用命令
docker
;显示所有在运行中的容器
docker ps
-a 查看所有状态下的容器,默认为正在运行中的
-q 只显示容器ID
;显示已终止的容器
docker container ls -a
-q 只显示容器ID
;停止容器
docker stop 容器ID/容器名称
;删除容器(当我们创建一个容器时,及时失败也会存在,比如--name及时失败也会占用名字)
docker rm
-f 发送 SIGKILL 信号给容器
-i 移除容器间的网络连接,而非容器本身
;删除指定的容器
docker container rm
-f 发送 SIGKILL 信号给容器
-i 移除容器间的网络连接,而非容器本身
;清理所有处于终止状态的容器
docker container prune
;获取指定命令的详细帮助信息
docker 指定命令 --help
;创建一个新的容器并运行一个命令
;使用 docker run 命令来在指定容器内运行一个应用程序
;指定容器的时候,可以用容器名也可以用容器ID
;使用容器名称的时候,如果为非latest版本,必须指定tag
docker run
-t: 在新容器内指定一个伪终端或终端(伪)tty。
-i: 以交互模式运行容器,通常与 -t 同时使用;
-e: 设置容器内的环境变量
-d: 后台运行容器,并返回容器ID;
-p: 将主机指定的端口的指定网络类型映射到容器:hostPort:containerPort,不指定主机端口则随机
-v: 同时将主机的目录,映射到容器中hostPath:containerPath,本地文件不存在时会创建在容器路径后使用:ro可以设置为只读
--mount: 和-v命令的作用差不多,区别是--mount的参数更多,本地文件不存在时会报错
--rm: 容器退出后随之将其删除
--name: 为容器指定一个名称,及时失败也会占用容器名字,需要rm掉
bash:放在镜像名后的是命令,意思是调用容器的的/bin/bash,但是有的时候bash不好使的使用还要用/bin/bash
;根据匹配规则运行指定的容器
docker run ${name}
;目录映射,:ro指定为只读
docker run --name nginx -v 主机目录:docker目录:ro -d nginx
;以交互式操作
docker run -it ubuntu:15.10 /bin/bash
;以交互式操作,同时退出容器后删除容器
docker run -it --rm nginx bash
;在容器内部运行指定的内容,这里运行ubuntu16.04 调用/bin/bash 运行echo 输出hello docker
docker run ubuntu:16.04 echo 'hello docker'
;后台模式运行,会输出容器ID
docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
; udp 标记来指定 udp 端口,运行training/webapp 下的python 启动默认工作目录下的app.py
docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
;运行容器ubuntu, 同时映射主机的指定目录到容器中
docker run -it -v /Users/liuhao/www:/home/www ubuntu /bin/bash
;运行MySQL5.7镜像,同时通过设置容器内的环境变量将root密码设置为123456
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7
docker run -d -v /home/liuhao/workSpace:/var/www/html -p 9000:9000 --link mysql:mysql --name php-fpm php:7.2-fpm
docker run -d -p 80:80 --name nginx -v /home/liuhao/workSpace:/usr/share/nginx/html --link php-fpm:php-fpm --name nginx nginx:1.15.12
;进入容器内部,需要容器被运行起来之后
docker exec -it 容器名称 /bin/bash
;进入指定容器的内部,貌似已经不能用了
docker attach 容器名称
;查看容器的信息,可以使用--format='{{GO语言模板语法}}'做格式化
docker inspect [-format='{{GO语言模板语法}}'] 容器名
;导出容器
docker export 容器名称 > 路径
;导入容器快照
docker import - 容器名称
;也可以通过指定 URL 或者某个目录来导入
docker import http://example.com/exampleimage.tgz example/imagerepo
docker load与docker import命令的区别,还必须知道docker save与docker export命令:
docker save images_name:将一个镜像导出为文件,再使用docker load命令将文件导入为一个镜像,会保存该镜像的的所有历史记录。比docker export命令导出的文件大,很好理解,因为会保存镜像的所有历史记录。
docker export container_id:将一个容器导出为文件,再使用docker import命令将容器导入成为一个新的镜像,但是相比docker save命令,容器文件会丢失所有元数据和历史记录,仅保存容器当时的状态,相当于虚拟机快照。
;查看端口映射,不指定端口则显示所有映射
docker port 容器名称 端口
;查看容器日志
docker logs -f <容器名orID>
;查看容器日志
docker container logs
;容器和主机之间的文件复制操作
docker cp 主机路径 容器ID:容器路径
docker cp 容器ID:容器路径 主机路径
;向容器中添加文件
docker add
;重启容器,比如docker的nginx一旦在容器内重启nginx,容器就会关闭,这时候我们就可以在外面重启容器
docker restart ContainerID或名称
全写:docker container restart ContainerID或名称
;启动容器,比如容器被关闭之后,要再次启动的话,可以使用该命令
docker start ContainerID或名称
全写:docker container start ContainerID或名称
- 数据卷(Volume)
数据卷可供一个或多个容器使用的特殊目录,它绕过了UFS,提供了多种可选属性使用.
1. 可在多个容器间共享使用,可以在同一个容器中同时挂载多个数据卷
2. 在数据卷中的修改可立马生效
3. 数据卷的更新不会对镜像有任何影响
4. 数据卷默认会一直存在,即使容器被删除
选择 -v 还是 -–mount 参数
Docker 新用户应该选择 --mount 参数,经验丰富的 Docker 使用者对 -v 或者 --volume 已经很熟悉了,但是推荐使用 --mount 参数。
创建数据卷可以使用docker create -v 后面参数因为我不用,所以 不在累述了
或者docker volume create 数据卷名称
;创建一个数据卷,创建数据卷不能指定目录
;如果要指定目录可以在运行容器时使用-v
docker volume create 数据卷名称
;查看数据卷列表
docker volume ls
;查看指定数据卷的详情, 可以使用--format='{{GO语言模板语法}}'格式化显示
docker volume inspect 数据卷名称
;启动容器的时候,将指定的数据卷 挂载到该容器中
docker run -d -t --mount source=数据卷名称,target=容器路径 ubuntu
;启动容器的时候,将指定的主句目录,挂载到容器中,readonly可以指定为只读
;挂载主机的指定到容器的指定目录,目录的默认权限是 读写
docker run -d -t --mount type=bind,source=主机目录,target=容器目录,readonly ubuntu
;备份数据卷
;1.创建一个新的容器
;2.挂载数据卷容器
;3.挂载宿主机本地目录作为数据卷
;4.将数据卷容器的内容备份到宿主机本地目录挂载的数据卷中
;5.完成备份操作后容器销毁
mkdir /tmp/backup
docker run --rm --volumes-from shiyanloudb -v /tmp/backup:/backup ubuntu tar cvf /backup/shiyanloudb.tar /shiyanloudata
;删除数据卷
docker volume rm 数据卷名称
;清理无主的数据卷
docker volume prune
网络操作
- docker四种网络模式
1. host模式 :
docker run 使用 --net=host指定
docker使用的网络实际上和宿主机一样
启动案例: docker run -it --name myubuntu -v /Users/liuhao/www:/www --net=host ImageID /bin/bash
$ docker run -it --name myubuntu -v /Users/liuhao/www:/www --net=host e13f3d529b1a /bin/bash
2. container模式:
使用 --net=container:container_id/container_name
多个容器使用共同的网络,看到的ip是一样的。
启动案例: docker run -it --name myubuntu --net=container:NAME_OR_ID ImageID /bin/bash
3. none 模式
使用 --net=none指定
这种模式下,不会配置任何网络。
docker run -it --name myubuntu --net=none ImageID /bin/bash
4. bridge模式
使用 --net=bridge指定
默认模式,不会指定
此模式会为每个容器分配一个独立的network namespace
- 外部访问容器
Docker 允许通过外部访问容器或容器互联的方式来提供网络服务。
要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来 指定端口映射。
当使用 -P 标记时,Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端 口。
-p 则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式
有 ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort 。
注意:
容器有自己的内部网络和 ip 地址(使用 docker inspect 可以获取所有的变量,Docker 还可以有一个可变的网络配置。)
-p 标记可以多次使用来绑定多个端口
;以后台形式运行Nginx镜像,同时将随机映射一个 49000~49900 的端口到内部容器
docker run -d -t -P Nginx
;使用 hostPort:containerPort 格式本地的 801 端口映射到容器的 801 端口,可以执行
docker run -d -t -p 801:801 Nginx
;一次绑定多个端口
docker run -d -t -p 801:801 -p 900:900 nginx
;使用 ip:hostPort:containerPort 格式指定映射使用一个特定地址
docker run -d -t -p 127.0.0.1:801:801 nginx
;使用 ip::containerPort 绑定本地的任意端口到容器的 801 端口,本地主机会自动分 配一个端口
docker run -d -t -p 127.0.0.1::801 nginx
;还可以使用 udp 标记来指定 udp 端口
docker run -d -t -p 127.0.0.1:801:801/udp nginx
;查看当前映射的端口配置,也可以查看到绑定的地址
docker port 容器名称 5000
;查看容器的信息,可以获取容器所有的变量,包括端口映射,可以使用--format='{{GO语言模板语法}}'做格式化显示
docker inspect 容器ID
; 使用 docker container ls 可以看到 端口映射关系
docker container ls
;可以通过 docker logs 命令来查看应用的信息
docker logs -f 容器ID
- 容器互联
如果你有多个容器之间需要互相连接,推荐使用 Docker Compose。
;创建一个新的 Docker 网络
;-d 参数指定 Docker 网络类型,有 。其中 overlay 网络类型用于 Swarm mode
docker network create -d bridge 网路名称
;查看网络列表
docker network ls
;删除网路
docker network rm 网络ID
;运行一个容器并连接到新建的 my-net 网络
docker run -it --rm --network 目标网络名称 ubuntu sh
;打开新的终端,再运行一个容器并加入到 my-net 网络
docker run -it --rm --network 目标网路名称 centos sh
;再打开一个新的终端查看容器信息
docker container ls
自定义镜像
- 使用commit定制镜像
;将容器保存为镜像
docker commit --author '提交人信息' --message '提交注释' 容器ID 新的名称:版本
docker commit -a '提交人信息' -m '提交注释' 容器ID 新的名称:版本
;案例
docker commit -a 'liuhao' -m 'syn blockchain' 0433eb0a2653 chinaliuhan/myachain
docker commit -a 'liuhao' -m '同步区块' b90bdec1e733 chinaliuhan/myachain:v2
;查看当前在容器中所有的具体操作和变动
docker diff 容器ID
;查看镜像列表
docker image list [镜像名]
;查看镜像内的历史记录
docker history 镜像ID
- 使用dockerfile定制镜像
行首 # 进行注释的格式
我们在定制镜像的时候可以直接使用git 的repo进行定制
也可以使用tar压缩包进行构建
所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制
除了在上面说的那种使用commit提交, 在原有容器的基础上生成镜像之外.
我们可以使用dockerfile进行单独的镜像封装
一般我们在使用dockerfile进行定制 镜像的时候,都会新建一路目录在目录中操作.
因为,dockerfile在创建镜像的时候回将上下文中的所有东西都打包,如果东西多的话这个过程会非常的慢.
要明白这一块,可能要理解一下docker的上下文关系:
就像书上说的那样,这里用我自己的理解来说明一下,docker在运行时分为docker引擎和客户端两部分,
我们在用的时候也只是在用客户端来调用引擎里的各种接口,当使用dockerfile
进行镜像构建的时候除了用RUN来运行之外,还会有COPY和ADD之类的操作,而docker build
并非是客户端来操作,而是docker引擎中构建的,这块其实我们在docker build的时候通过docker
输出的信息可以得知 Sending build context to Docker daemon 496.4MB
所以我们在构建时需要指定上下文目录所在,
如: "docker build -t mynginx ." 这里的点,意思就是讲上下文设置在当前目录
这样 Docker 引擎收到这个上下文包后,展开就会获得构建镜像所需的一切文件。
如: "COPY ./nihao.txt /home/www "这里的意思并不是说Dockerfile或docker build命令所在的目录
而是我们之前指定上下文的目录,所以我们在使用COPY用的都是相对路径,
像这种写法是不行的: "COPY /tmp/nihao.txt /home/www"或者这样也不行"COPY ../nihao.txt /home/www"
在COPY的时候会有报错提示如:COPY failed: Forbidden path outside the build context: ../www ()
COPY时不能使用软连接
;该命令是使用当前目录下的Dockerfile构建新的镜像,注意后面有一个.
;在这条命令中,使用-t指定了镜像名为新的镜像名,由于没有使用-f指令,
;所以默认使用上下文路径下名为Dockerfile的文件认为是构建镜像的"Dockerfile"。
;最后指定上下文路径,在这条命令中,上下文路径是"."即为当前目录为上下文的路径
docker build[OPTIONS]上下文路径|URL .
-t 指定新镜像的名称和版本号
-f 指定要使用的Dockerfile的所在路径
docker build -t 新镜像的名称:版本号 .
docker build -t go/helloworld:1 -f Dockerfile.one .
;上面是使用本地文件进行构建自定义镜像
;下面两句话我们使用tar压缩文件和git的repo进行构建自定义镜像以及从标准输入中读取dockerfile进行构建
;从git repo进行构建自定义镜像
;如果所给出的 URL 不是个 Git repo,而是个 tar 压缩包,那么 Docker 引擎会下载这个包,
;并自动解压缩,以其作为上下文,开始构建
docker build https://github.com/twang2218/gitlab-ce-zh.git#:8.14
docker build http://server/context.tar.gz
;从标准输入中读取Dockerfile进行构建
docker build - < Dockerfile 或者 cat Dockerfile | docker build -
;从标准输入中读取上下文压缩包进行构建
docker build - < context.tar.gz
;Dockerfile中常用的命令:
FROM
FROM <源镜像或scratch>
;镜像来源,指定基础镜像,如果使用FROM scratch 意味着你不以任何镜像为基础,
;接下来所写的指令将作 为镜像第一层开始存在
;如: FROM nginx 选择Nginx镜像作为原始镜像
;如: FROM scratch 设置的当前镜像不以任何镜像为基础,接下来所写的命令将作为镜像的第一层存在
RUN
RUN <命令>
;运行 指令是用来执行命令行命令的run是我们在dockerfile中最常用的命令
;可以用来执行命令行命令和直接的命令
;如: RUN echo '这里是测试内容' > /tmp/test.log
;如: RUN apt-get instal nginx
;如: RUN buildDeps='gcc libc6-dev make' 此处可以作为变量使用,设置变量$buildDeps,在后面可以直接用$buildDeps来替代该命令
COPY
COPY <源路径>... <目标路径>
COPY ["<源路径1>",... "<目标路径>"]
;注意COPY操作不能使用软连接
;源文件的各种元数据都会保留。比如读、写、执 行权限、文件变更时间等
;复制文件 从构建上下文的目录中的 文件/目录 复制到新的镜像内,<源路径> 可以是多个
;<目标路径>可是是绝对路径也可以是相对于工作目录的相对路径,
;工作目录可以 用 WORKDIR 指令来指定)。
;<目标路径>不需要事先创建,如果目录不存在会在复制文件前先行 创建缺失目录。
;如: COPY mytest.txt /tmp 将当前目录下的mytest.txt 复制到镜像中的/tmp目录下
;如: COPY hom* /tmp/ 使用通配符进行操作
;如: COPY hom?.txt /mydir/ 使用正则进行操作
ADD
ADD <源路径> <目标路径>
;该命令和copy差不多,但是在copy基础上增加了一些功能.
;如: <源路径>可以是一个URL,docker会自动下载到<目标路径>,下载后的权限默认为600.
;如果不想要权限,还需要增加额外的一层RUN进行权限调整.如果下载包是一个压缩包,也需要额外的RUN指令就行解压操作
;所以我们不如直接使用RUN命令,然后使用curl或wget工具下载,处理权限,解压缩,然后清理无用文件更合理.
;所以官方文档不推荐用这个命令,不太实用,官方要求尽可能是的使用COPY,因为COPY的语义很明确,就是复制文件而已.
;而 ADD 则包含了更复杂的功能,其行为也不一定很清晰。最 适合使用 ADD 的场合,就是所提及的需要自动解压缩的场合。
;因此在 COPY 和 ADD 指令中选择的时候,可以遵循这样的原则,所有的文件复制均使用 COPY 指令,仅在需要自动解压缩的场合使用 ADD 。
;
CMD
;容器启动时运行的命令,注意是容器启动的时候
如果想要在创建镜像时运行需要在RUN中配置
shell 格式: CMD <命令>
exec 格式: CMD ["可执行文件", "参数1", "参数2"...]
在指定了 ENTRYPOINT 指令后,用 CMD 指 定具体的参数。
在指令格式上,一般推荐使用 exec 格式,这类格式在解析时会被解析为 JSON 数组,因
此一定要使用双引号 " ,而不要使用单引号。
ENTRYPOINT
入口点
ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数
但是一个Dockerfile中只能有一条ENTRYPOINT命令,如果多条,则只执行最后一条
ENV
设置环境变量
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
ARG
构建参数
ARG <参数名>[=<默认值>]
VOLUME
定义匿名卷
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
EXPOSE
声明端口
EXPOSE <端口1> [<端口2>...]
WORKDIR
指定工作目录
WORKDIR <工作目录路径>
使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),
以后各层的当前目录就被改 为指定的目录,
如该目录不存在,WORKDIR 会帮你建立目录
USER
指定当前用户
USER <用户名>
和 WORKDIR 一样, USER 只是帮助你切换到指定用户而已,这个用户必须是事先建立 好的,否则无法切换。
HEALTHCHECK
健康检查
HEALTHCHECK [选项] CMD <命令> :设置检查容器健康状况的命令
HEALTHCHECK NONE :如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指 令
ONBUILD
为他人做嫁衣裳
ONBUILD <其它指令>
ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN , COPY 等,
而这些指令, 在当前镜像构建时并不会被执行。
只有当以当前镜像为基础镜像,去构建下一级镜像的时候 才会被执行。
- 使用dockerfile进行多阶段构建镜像
全部放入一个 Dockerfile
一种方式是将所有的构建过程编包含在一个 Dockerfile 中,
包括项目及其依赖库的编译、 测试、打包等流程,
这里可能会带来的一些问题:
Dockerfile 特别长,可维护性降低 镜像层次多,镜像体积较大,
部署时间变长 源代码存在泄露的风险
本文来自博客园,作者:我爱吃炒鸡,转载请注明原文链接:https://www.cnblogs.com/chinaliuhan/p/15558402.html