sudo docker run -d -p 127.0.0.1:8080:80 --name containerName repositoryName/imageName command
-p
参数用于配置容器与宿主机的端口链接,如上述命令是把容器的80映射到宿主机127ip的8080端口上,当其中有参数被省略时,则会使用默认(随机)参数。当我们使用-P
的时候,会将容器的80绑定到一个宿主机随机端口,然后将dockerfile中EXPOSE指定的端口全部公开.
command
命令是直接在容器内运行的内容,通常用于打开需要的服务
我们可以使用docker ps -l
命令查看所有容器被映射的端口,也可以使用docker port uuid 80
查看这一容器80端口被映射到的宿主机端口位置。
2.6 Dockerfile指令
Link to heading
2.6.1 CMD
Link to heading
CMD指令用于指定容器启动时运行的命令(而RUN指令的只是在被构建时候运行),通常的格式为
Docker一直推荐使用数组来设置需要执行的命令。同时我们需要牢记docker run
命令会覆盖CMD指令,同时要知道再Dockerfile中只能指定一条CMD指令,如果指定了多条则只有最后一条会被运行。
2.6.2 ENTRYPOINT
Link to heading
这个指令与CMD十分类似,而最大的区别在于其不会被命令中的指令覆盖
实际上所有的指令都会作为参数传入ENTRYPOINT
中。
在使用这个指令的时候我们也会使用数组进行内容的传输
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]
将这个命令,CMD
命令以及docker run
时选择的命令进行组合,可以得到默认参数的使用方法。
ENTRYPOINT ["/usr/sbin/nginx"]
CMD["-h"]
docker run -t -i repositoryName/imageName -g "daemon off;"
在默认情况下,会使用CMD命令中的-h参数,但在run的时候如果添加了新的参数,则会对其进行覆盖,以此实现默认参数的效果。
2.6.3 WORKDIR
Link to heading
这个指令可以在容器内部设置一个工作目录(切换内部的路径),用于CMD
与ENTRYPOINT
的执行。
WORKDIR /opt/webapp
CMD command
我们为command指令设置了路径
我们可以在run的时候通过-w
来覆盖工作的目录。
2.6.4 ENV
Link to heading
在镜像构建的过程中设置环境变量,这个环境变量可以在之后任何RUN指令中使用,就如同在命令前面指定了环境变量的前缀。
ENV RVM_PATH=/home/rvm TARGET_FIR=/opt/app
RUN gem install unicorn
WORKDIR $TARGET_FIR
参数解释:
设置了RVM_PATH
与TARGET_FIR
两个环境变量,第一个可以为第二条RUN
指令提供前缀条件,变成如RVM_PATH=/home/rvm RUN gem install unicorn
而第二个则被用于提供了工作目录的位置。
注意:在Dockerfile中设置的环境变量都是在容器中具有持久化作用的,而如果只是在使用docker run
时候加入-e
来传递的环境变量则只在运行的时候有效。
2.6.5 USER
Link to heading
指定这个镜像以什么用户去运行,可以通过指定用户名(或uid)以及组(或gid)来选择。如果不选择默认会使用root
USER user
USER user:group
USER uid
USER uid:gid
2.6.6 VOLUME
Link to heading
用来向基于镜像创建的容器添加卷(可以存在于一个或者多个容器内的特定的目录),卷可以绕过联合文件系统并提供共享以及持久化的数据功能,卷的功能可以让我们**把数据、数据库或者其他内容添加到镜像而不是将内容提交到镜像。**通常用来测试容器和内部的应用程序代码。管理日志,处理内部数据库。
VOLUME ["/opt/project",/data]
参数解释:
为基于此镜像的任何容器创建了这两个挂载点。
2.6.7 ADD
Link to heading
将构建环境下的文件和目录复制到镜像之中,需要指定源文件位置和目的文件位置两个参数。
ADD contentPath aimPath
参数解释:
contentPath
是上下文的文件,通过末尾的字符来判断是目录还是文件,如果以/
结尾的就被认为是目录。
在处理本地文件的时候,当归档文件被指定为源文件的时候,docker会把文件自动解开。(以URL指定目前不行)
aimPath
是镜像内的目标位置,如果目录不存在的话,会自动创建这样的新目录,其模式为文件模式为0755。
ADD
指令会使得构建的缓存变得无效,当添加后,所有的后续指令都需要重新进行构建。
2.6.8 COPY
Link to heading
与ADD
命令基本类似,但不会做文件提取以及解压等方面的内容,需要注意,所有的文件源路径都必须是在Dockerfile的相对文件夹下,不能复制这个目录以外其他目录的内容。
2.6.9 LABEL
Link to heading
这个指令可以为docker添加元数据,以键值对的形式展现出来。
LABEL version="1.0" location="China" type="Web"
推荐将所有的元数据都放入一条LABEL指令中,防止构建过多的镜像层。
我们可以通过docker inspect repositoryName/imageName
来查看容器内部的标签。
2.6.10 STOPSIGNAL
Link to heading
用于设置停止容器的时候发送什么系统调用信号给容器,这信号必须是内核系统调用表中合法的数字(9)或者SIGNAME格式中信号名称(如SIGKILL)。
2.6.11 ARG
Link to heading
用来定义可以在docker build
命令运行的时候传递给构建运行的变量,在构建时候可以根据dockerfile中定义过的变量进行传递
ARG build
ARG webapp_user=user
定义了两个变量,第二个给了一个默认值,接下来可以在使用docker build --build-arg build=1234
这样的命令来添加参数
2.6.12 ONBUILD
Link to heading
为当前的镜像添加触发器,当这个镜像被用作为其他镜像的基础镜像的时候,该镜像中的触发器会被执行。触发器会在下一个继承他的镜像的FORM
之后添加这些被触发的指令
ONBUILD ADD . /app/src
ONBUILD RUN cd /app
此处使用了两条命令,当有新的镜像Dockerfile继承当前的镜像时候,运行后回在FORM之后插入这两句话
注意:触发器只能被子镜像继承,当孙镜像运行时候则不会再进行继承。
2.7 删除自己的镜像
Link to heading
当我们不再需要一个镜像的时候,我们可以使用
sudo docker rmi repositoryName/imageName1 repositoryName/imageName2
来删除这个镜像,这一行为同时也会删除构建这个镜像的时候所产生的每一层镜像,后面也可以不断往后罗列镜像,这将删除这镜像列表里面全部的镜像。
2.8 Docker镜像的管理
Link to heading
我们可以把自己在本地构建完成的镜像推送到远程仓库(默认为DockerHub),通过使用
docker push repositoryName/imageName
就可以将自己的镜像上传至自己的远程仓库之中。
而除了这种方式,我们可以选择使用自动构建,这只需要将Github中含有Dockerfile文件的仓库链接到Docker Hub上,当我们向github推送时候,dockerhub也会自动更新(但这种方式就不可以使用docker push
来发布镜像)。
三、Docker实战操作
Link to heading
3.1 卷的挂载
Link to heading
有些时候外面不想把应用或者代码构建到镜像之中
同时对代码进行开发与测试
代码改动十分频繁,不想在开发过程中重构镜像
希望在多个容器之间共享代码
这时候我们就需要使用docker的卷挂在来实现,通过在运行容器的时候使用-v 宿主机目录:容器内目录:读写权限
来对本地与容器内的文件进行映射挂载。
docker run -d -p 80 --name web -v ./web:/var/www/html/website:ro repositoryName/imageName2 cmd
3.2 容器的链接
Link to heading
3.2.1Docker Networking
Link to heading
Docker Networking允许用户创建自己的网络,容器可以通过这个网络来互相通信,接下来是一些常用的管理指令。
sudo docker network create name #创建一个桥接网络并命名为name
sudo docker network inspect name #查看这个网络的信息
sudo docker network ls # 查看当前系统中的所有网络
sudo docker network rm # 删除一个网络
当有网络后,我们在运行容器时候可以加上–net=name
的标识符,把容器加入指定的网络之中。在网络内部启动的容器,docker会感知到所有在这个网络下的容器,并把这些信息都通过到当前容器的/etc/hosts
文件把所有地址都保存到DNS之中。
在网络之中的任何容器的地址,都可以通过hostname.app
的形式被解析,当一个容器重启的时候,它们的IP地址也会被自动更新(即对容器底层的修改不会对程序的正常工作产生影响)
3.2.2 Docker链接
Link to heading
在使用run
对容器进行运行的时候,我们增加--link containerName:linkName
创建了客户联系,此时被运行的容器被称为客户容器,而另一个则是服务,我们为这个服务增加了linkName作为别名,这可以让我们一致的访问容器公开的信息,且无须关注底层容器的名字。
将容器连接在一起可以让客户容器任意访问另一个容器,而不用对外公开端口。
四、Docker编配和服务发现
Link to heading
4.1 Docker Compose
Link to heading
Dockers Compose通常被用于简单的Docker容器编配使用YAML
文件定义一组需要启动的容器,以及容器运行时的属性,这些容器可以被称为是服务。我们可以很快的使用Compose来创建多容器应用栈。
安装:使用pip install -U docker-compose
可以进行最新版本的快速安装
当应用的镜像构建完成之后,我们可以使用Compose来创建需要的服务,并定义启动时候需要的属性,这些属性都会被放置与YAML
文件之中,样例:
web:
image : shenvinci/flask
command : python app.py
ports :
- "5000:5000"
volumes :
- .:/composeapp
links :
- redis
redis:
image : redis
参数解释:
开启了分别名为web
与redis
的两个容器文件,并为其配置了相应的参数,Compose会使用这些参数生产多个容器并组成相应的容器栈。
当切换至有YAML
文件的目录下后,我们有一些常用的指令
docker-compose up -d # 在后台运行容器栈
docker-compose ps # 列出本地docker-compose.yml 文件中正在运行的所有服务
docker-compose stop # 停止正在运行的所有服务
docker-compose kill # 强制杀死正在运行中的服务
docker-compose rm # 删除docker-compose服务