基础
容器相关
- ps-查看运行中的docker容器
- logs-查看docker日志
- exec-执行docker中的命令
- cp-复制文件
- create-从镜像创建容器
- run-从镜像启动容器
- rm-删除容器
- start-启动停掉的容器
- stop-终止的容器
- kill-强行终止容器
- inspect-查看容器的信息
镜像相关
- images-查看本地镜像
- search-在dockerhub搜索镜像
- pull-从dockerhub上拉取镜像
- tag-对镜像设置标签
- push-推送镜像至镜像仓库
- login-登录镜像仓库
- rmi-删除镜像
- Dockerfile-文件格式
- build-构建镜像
- commit-构建镜像
- import-导入容器
- export-导出容器
- save-存出镜像
- load-载入镜像
- 附-容器与镜像的概念
概念
Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。
docker是一个容器可以是一个虚拟的系统,并不一定是一个系统,比如一个docker容器可以只有1k大小(比如hello-world镜像),简单的只有一个脚本,执行完脚本docker自动关闭,当然容器中也可以是一个系统,这样可以对系统进行一些操作,部署项目,安装redis软件等,但是这样存在一个问题,如果一个服务器上既部署又有redis数据库等,那这个服务器需要安装n个docker容器,每个容器中安装一个软件,或者安装一个容器,其中安装所有的软件
ps-查看运行中的docker容器
docker ps
- -a, --all Show all containers (default shows just running)
- -f,
- --filter filter Filter output based on conditions provided
- --format string Pretty-print containers using a Go template
- --help Print usage
- -n,
- --last int Show n last created containers (includes all states) (default -1)
- -l,
- --latest Show the latest created container (includes all states)
- --no-trunc Don't truncate output
- -q,
- --quiet Only display numeric IDs
- -s,
- --size Display total file sizes
logs-查看docker日志
docker logs -f kanche-bridge_kanche-bridge-v1_1
该命令可以查看启动的服务和停掉的服务的日志
假设 application 是 Docker容器内部运行的应用,
那么对于应用的第一部分标准输出(stdout)日志,
Docker Daemon 在运行这个容器时就会创建一个协程(goroutine),负责标准输出日志。<br/><br/>
由于此 goroutine 绑定了整个容器内所有进程的标准输出文件描述符,
因此容器内应用的所有标准输出日志,都会被 goroutine 接收。<br/><br/>
goroutine 接收到容器的标准输出内容时,立即将这部分内容,
写入与此容器—对应的日志文件中,
日志文件位于/var/lib/docker/containers/<container_id>,文件名为<container_id>-json.log。<br/><br/>
至此,关于容器内应用的所有标准输出日志信息,
已经全部被 Docker Daemon 接管,并重定向到与容器—对应的日志文件中。<br/><br/>
因此可以通过docker log或 查看物理机上的文件 两种方式查看日志
以下简要介绍 docker logs 命令下各参数的含义:
无参数:直接显示容器的所有日志信息
tail:从尾部开始按需显示容器日志
since:从某个时间开始显示容器日志
timestamp:显示容器日志时显示日志时间戳
f:将当前时间点,容器日志文件<container-id>-json.log中的日志信息全部打印;此时间点之后所有的日志信息与日志文件无关,直接接收goroutine往日志文件中写的文件描述符,并显示
exec-执行docker中的命令
docker exec -it kanche-bridge_kanche-bridge-v1_1 bash
version-查看docker的版本信息
docker version
images-查看本地镜像
docker images
镜像是对容器状态的保存
cp-复制文件
将容器中的某个文件复制到本地
docker cp kanche-bridge_kanche-bridge-v1_1:kanche-bridge.jar /tmp/
容器路径必须是绝对路径,否则只能cp0字节,即cp失败
docker cp kanche-bridge_kanche-bridge-v1_1:/opt/docker/kanche-bridge.jar /tmp/
search-从docker hub上搜索镜像
docker search redis:
Search the Docker Hub for images
pull-从dockerhub上拉取镜像
liukaideMacBook-Pro:~ liukai$ docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
5b0f327be733: Pull complete
Digest: sha256:1f1404e9ea1a6665e3664626c5d2cda76cf90a4df50cfee16aab1a78f58a3f95
Status: Downloaded newer image for hello-world:latest
若是私有镜像仓库,需要登录,具体参考login;可通过
:
指定版本号,如hello-world:1.0.0-test
,若不指定则表示获取版本号为latest的镜像
create-从镜像创建容器
``` docker create -it ubuntu:latest ``` > 与run的区别在于,create创建后的容器是stop状态,需要通过docker start 命令启动run-启动容器
通过docker run命令可以启动某一个镜像,并运行一个命令 `docker容器可以理解为在沙盒中运行的进程。这个沙盒包含了该进程运行所必须的资源,包括文件系统、系统类库、shell 环境等等。但这个沙盒默认是不会运行任何程序的。你需要在沙盒中运行一个进程来启动某一个容器。这个进程是该容器的唯一进程,所以当该进程结束的时候,容器也会完全的停止。`- docker run -i -t centos6.8
这个容器一执行就会进入到默认的线程”/bin/bash”,直接进入控制台操作。当退出控制后后,容器会被终止
- docker run -i -t -d centos6.8
这个容器一执行,会自动执行默认的线程”/bin/bash”,但是不会让你马上进入控制台操作。将会在后台执行,用docker ps 可以看到当前运行的控制台。进入容器可是使用docker attach“container name or id” or docker exec *** bash。
- docker run -d centos6.8 ping www.docker.com
这个容器将永久在后台执行,因为ping这个线程不会停止。除非你停止了ping的线程。
- [root@CentOS7.2 ~]#docker run -d --restart=always centos6.8 ping www.docker.com
这个容器将永久在后台执行,因为ping这个线程不会停止。如果你把ping这个线程终止了,那么容器会重启继续执行ping功能
- docker run -d --name=server-dbcentos6.8-mysql /usr/bin/mysql_safe -d
这时候我们这个容器的名称为server-db,同时激活了数据库mysql的后台线程,让它不断的跑,这时候我们的容器也不会被关闭
- docker run -d --name=server-http --link=server-db centos6.8-httpd /usr/bin/httpd --DFOREGROUND
我们执行了apache的服务器让它不断的在后台执行,同时,在php里配置mysql的服务器名称为”server-db”,直接用server-db命名就可以了。不需要输入ip地址之类的。我们的server-http指定连接了server-db。server-db在server-http里会被当做一个DNS解析来获取相应的连接ip。 --link表示将该容器与另一个容器关联,即在该容器的hosts中添加另一个容器的配置;也可通过“echo 172.18.0.2 d85ab91161fd mysql >> hosts”向hosts写入内容
- docker run -d --name=server-db -p 3306:3306 centos6.8-mysql /usr/bin/mysql_safe –d
指定了服务器宿主机的3306端口映射到容器的3306端口,暴露出去。
- docker run -d --name=server-http --link=server-db -p 8080:80centos6.8-httpd /usr/bin/httpd --DFOREGROUND
指定了服务器宿主机的8080端口映射到容器80端口,暴露出去。
- docker run -d --name=server-db -p 3306:3306 -v /server/mysql-data:/mysql-data centos6.8-mysql /usr/bin/mysql_safe –d
将宿主机的数据库目录/server/mysql-data挂载到server-db上,你会发现,在server-db根目录下你会发现有一个新的文件夹mysql-data,同时里面的文件内容和宿主机下/server/mysql-data一样。
- docker run -it --rm centos6.8
我们进入了容器的控制台,当我们在容器内部exit退出控制台的时候,容器将被终止,同时自动删除。
- docker run -t -i --rm --link db:db training/webapp /bin/bash
- --rm表示容器终止后立刻删除
- --link让容器之间安全的进行交互
- --link name:alias: 其中name是要链接的容器名称;alias是这个连接的别名
- --link进行的操作:1. 设置环境变量,如 端口等 2. 更新/etc/hosts文件,将欲连接的容器在本容器中设置hosts
run命令常用的参数
命令格式:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
-d, --detach=false 指定容器运行于前台还是后台,默认为false
-i, --interactive=false 打开STDIN,用于控制台交互
-t, --tty=false 分配tty设备,该可以支持终端登录,默认为false
-u, --user="" 指定容器的用户
-a, --attach=[] 登录容器(必须是以docker run -d启动的容器)
-w, --workdir="" 指定容器的工作目录
-c, --cpu-shares=0 设置容器CPU权重,在CPU共享场景使用
-e, --env=[] 指定环境变量,容器中可以使用该环境变量
-m, --memory="" 指定容器的内存上限
-P, --publish-all=false 指定容器暴露的端口
-p, --publish=[] 指定容器暴露的端口
-h, --hostname="" 指定容器的主机名
-v, --volume=[] 给容器挂载存储卷,挂载到容器的某个目录
--volumes-from=[] 给容器挂载其他容器上的卷,挂载到容器的某个目录
--cap-add=[] 添加权限,权限清单详见:http://linux.die.net/man/7/capabilities
--cap-drop=[] 删除权限,权限清单详见:http://linux.die.net/man/7/capabilities
--cidfile="" 运行容器后,在指定文件中写入容器PID值,一种典型的监控系统用法
--cpuset="" 设置容器可以使用哪些CPU,此参数可以用来容器独占CPU
--device=[] 添加主机设备给容器,相当于设备直通
--dns=[] 指定容器的dns服务器
--dns-search=[] 指定容器的dns搜索域名,写入到容器的/etc/resolv.conf文件
--entrypoint="" 覆盖image的入口点
--env-file=[] 指定环境变量文件,文件格式为每行一个环境变量
--expose=[] 指定容器暴露的端口,即修改镜像的暴露端口
--link=[] 指定容器间的关联,使用其他容器的IP、env等信息
--lxc-conf=[] 指定容器的配置文件,只有在指定--exec-driver=lxc时使用
--name="" 指定容器名字,后续可以通过名字进行容器管理,links特性需要使用名字
--net="bridge" 容器网络设置:
bridge 使用docker daemon指定的网桥
host //容器使用主机的网络
container:NAME_or_ID >//使用其他容器的网路,共享IP和PORT等网络资源
none 容器使用自己的网络(类似--net=bridge),但是不进行配置
--privileged=false 指定容器是否为特权容器,特权容器拥有所有的capabilities
--restart="no" 指定容器停止后的重启策略:
no:容器退出时不重启
on-failure:容器故障退出(返回值非零)时重启
always:容器退出时总是重启
--rm=false 指定容器停止后自动删除容器(不支持以docker run -d启动的容器)
--sig-proxy=true 设置由代理接受并处理信号,但是SIGCHLD、SIGSTOP和SIGKILL不能被代理
docker run --name mysql_test_2 -e MYSQL_ROOT_PASSWORD=my-secret-pw -p 3307:3306 -id 5709795eeffa
rm-删除容器
rm 容器NAME :根据容器NAME删除对应的容器
rmi-删除镜像或tag
- docker rmi imageid: 根据镜像id删除镜像;如果该id关联多个tag,则无法删除成功
- docker rmi hello-world-test2:根据tag删除对应的镜像,如果该tag对应的镜像无其它关联tag,则删除该镜像,如果存在其它关联tag,则删除该tag
调用该命令删除镜像前需要确保该镜像对应的容器已全部删除,否则该镜像无法删除
start-启动停掉的容器
使用`docker ps -a`查看容器,发现存`Exited (0) 2 hours ago`状态的容器,使用`docker start name`启动容器 > name 为ps最后一个name字段,id无效果 可以使用 docker start name1 name2 name3 启动多个容器stop-终止的容器
``` docker stop [-t | --time [=10]] ``` stop命令会向容器发送SIGTERM信号,等待一段时间后(默认为10s),再发送SIGKILL信号终止容器kill-强行终止容器
直接发送SIGKILL信号强行终止容器Dockerfile-文件格式
1. 概念
Dockerfile用来创建一个自定义的image,包含了用户指定的软件依赖等。
当前目录下包含Dockerfile,使用命令build来创建新的image,并命名为edwardsbean/centos6-jdk1.7:
docker build -t edwardsbean/centos6-jdk1.7 .
2. Dockerfile关键字
如何编写一个Dockerfile,格式如下:
-
FROM:基于哪个镜像,同一Dockerfile中创建多个镜像时,可使用多个FROM指定,但是每个镜像仅限一次
-
RUN:将对镜像执行跟随的命令。每运行一条RUN指令,镜像添加新的一层,并提交。
- 格式为
RUN [command]
或RUN ["EXECUTABLE","PARAM1","PARAM2"]
- 前者将在shell终端中运行命令,即/bin/sh -c;
- 后者则使用exec执行
- 指定使用其他终端可以通过第二种方式实现,例如
RUN ["/bin/bash","-c","echo hello"]
- 格式为
-
MAINTAINER:镜像创建者信息
-
CMD:container启动时执行的命令,但是一个Dockerfile中只能有一条CMD命令,多条则只执行最后一条CMD。CMD主要用于container时启动指定的服务,当docker run command的命令匹配到CMD command时,会替换CMD执行的命令。
- CMD ["EXECUTABLE","PARAM1","PARAM2"]使用exec执行,推荐方式
- CMD command param1 param2 在/bin/sh中执行,提供给需要交互的应用
- CMD ["param1","param2"]提供给ENTRYPOINT的默认参数
例:CMD echo hello world
运行结果:<br/>
edwardsbean@ed-pc:~/software/docker-image/centos-add-test$ docker run centos-cmd<br/>
`hello world`</br>
一旦命令匹配:</br>
edwardsbean@ed-pc:~/software/docker-image/centos-add-test$ docker run centos-cmd echo hello edwardsbean<br/>
`hello edwardsbean`
-
ENTRYPOINT:container启动时执行的命令,但是一个Dockerfile中只能有一条ENTRYPOINT命令,如果多条,则只执行最后一条。ENTRYPOINT不可被docker run 提供的参数覆盖
- ENTRYPOINT ["EXECUTABLE","PARAM1","PARAM2"]
- ENTRYPOINT command param1 param2 (shell中执行)
-
USER:指定运行容器时的用户名或UID,后续的RUN也会使用指定用户
如:
ENTRYPOINT ["memcached"]
USER daemon
- EXPOSE:
container内部服务开启的端口。
主机上要用还得在启动container时,做host-container的端口映射:
docker run -d -p 127.0.0.1:33301:22 centos6-ssh
container ssh服务的22端口被映射到主机的33301端口
- ENV
ENV [KEY] [VALUE]用来设置环境变量,比如:
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8
- ADD:将文件 src 拷贝到container的文件系统对应的路径 dest,所有拷贝到container中的文件和文件夹权限为0755,uid和gid为0,如果文件是可识别的压缩格式,则docker会自动解压为目录;也可以是一个URL
- 如果要ADD本地文件,则本地文件必须在 docker build PATH,指定的PATH目录下
- 如果要ADD远程文件,则远程文件必须在 docker build PATH,指定的PATH 目录下。比如:
docker build github.com/creack/docker-firefox
docker-firefox目录下必须有Dockerfile和要ADD的文件
注意:使用docker build - somefile 方式进行build,是不能直接将本地文件ADD到container中。只能ADD url file.
ADD只有在build镜像的时候运行一次,后面运行container的时候不会再重新加载了。
- COPY: 复制本地主机的目录为容器中的目录,当目标路径不存在时,会自动创建;当使用本地目录为源目录时,推荐使用COPY
-
VOLUME:可以将本地文件夹或者其他container的文件夹挂载到container中。
-
WORKDIR:为后续的RUN,CMD,ENTRYPOINT指定配置工作目录,可使用多个WORKDIR指令
-
ONBUILD:ONBUILD配置当所创建的镜像作为其他新创建的基础镜像时,所执行的操作指令。
# 构建镜像image-a
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
# 当某镜像FROM image-a时,会自动执行ONBUILD指令内容,等价于在后面添加了两条指定
build-构建镜像
格式:
Usage: docker build [OPTIONS] PATH | URL | -
例子:
docker build -t imageName -f Dockerfile path
PATH:指定本地的路径,该路径为Dockerfile及Docker中操作文件的默认路径
- -f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile')
- -t, --tag list Name and optionally a tag in the 'name:tag' format
commit-构建镜像
docker commit -m "comment" -a " author " imageId imageTag
inspect-查看容器的信息
docker inspect 容器名/容器id:查看容器的配置信息:容器名,环境变量, 运行命令, 主机配置,网络配置,数据卷配置。 比如 Mounts表示docker容器的挂载信息,若挂载了物理机,则部署新的docker 文件夹内容不会丢 > 该命令同样可查看镜像信息export-导出容器
导出已经创建的容器到一个文件 docker export 7691a814370e > ubuntu.tarimport-导入容器
docker import 从容器快照文件中再导入为镜像 $ cat ubuntu.tar | sudo docker import - test/ubuntu:v1.0根据某url导入容器
docker import http://example.com/exampleimage.tgz example/imagerepo
save-存出镜像
# 将镜像 ubuntu:14.04 存出为文件 ubuntu_14.04.tar
docker save -o ubuntu_14.04.tar ubuntu:14.04
load-载入镜像
# 从本地文件中导入到本地镜像库
docker load --input ubuntu_14.04.tar
或
docker load < ubuntu_14.04.tar
docker load与docker import的区别:
容器快照文件将丢弃所有的历史记录和无数据信息(仅保存容器当时的快照状态)
而镜像存储文件将保存完整记录,体积也更大。
此外,从容器快照文件导入时可以重新指定标签等元数据信息
tag-对镜像设置标签
- docker tag hello-world cnkevin/cnkevin-jre:1.0.0-test
tag用于标识镜像仓库,如果为dockerhub,则只需要
user/image:tag
即可,若为个人仓库,则需要harbor.xxx.com/user/image:tag
,docker push
时根据tag上传至相应的镜像仓库
tag-对镜像设置标签
- docker push cnkevin/cnkevin-jre:latest
unauthorized: authentication required
通过docker login命令登陆镜像仓库
login-登录镜像仓库
- docker login harbor.xxx.com :登陆个人镜像仓库,若省略harbor.xxx.com则表示登陆dockerhub
- docker login后会在~/.docker/下生成一个config.json保存docker登录信息
- docker tag必须将镜像文件打标为 harborurl/user/image的形式,push时会根据harborurl去.docker/config.json中查找用户登录信息,并推送镜像
- 如果向非hub.docker.com推送镜像 需要tag为 harbor.xxx.com/xxx/java-jre但是向dockerhub推送只需要tag为userid/image即可,但是前提是通过docker login登录docker hub,并且不可加任何地址,若加地址应为docker.io,而非hub.docker.com
> cat .docker/config.json
{
"auths": {
"harbor.xxx.com": {
"auth": "YWRtaW46SGFyYm9yQFl4cWljaGUyMDE4IQ=="
},
"https://index.docker.io/v1/": {
"auth": "Y25rZXZpbjprYWkxMjM0NTY="
}
}
}
附
附1-容器与镜像的概念
- 容器:虚拟机的概念,无论启动中还是关闭,均为容器
- 镜像:将虚拟机的某个状态,保存为镜像,可根据镜像还原容器