docker入门笔记
一、docker解决了什么痛点
代码从开发环境到部署到测试环境经常会出现各种问题,我们开发人员会说“在我电脑上还跑的”。Docker出现解决了开发环境和测试与线上环境不一致、配置复制的痛点。
在docker出现前,针对开发与线上环境不一致的情况常用常用的解决方案是
虚拟机,虚拟机能够还原软件的运行环境。但虚拟机存在着以下缺点:
- 资源占用多。虚拟机会独占一部分内存和硬盘空间,它运行时,其他程序就不能使用,可能会造成资源的浪费的。
- 冗余步骤多。虚拟机是一个完整的OS,一些系统级的操作步骤,无法跳过,比如用户登录。
- 启动慢。OS启动慢。
Linux容器,Linux Containers 缩写为
LXC
,Linux容器不是模拟OS,而是将进程隔离。或者说是在正常进程的外面套了一哥保护层。对于容器的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。由于容器是进程级别的,相较于虚拟机有众多优势:
- 启动快。容器里面的应用直接就是底层系统的一个进程,而不是虚拟机内部的进程。启动容器相当于启动本机的一个进程,而不是启动一个OS,速度很快。
- 资源占用少。容器只占用需要的资源,不占用没有用到的资源。多个容器可以共享资源,虚拟机都是独享资源。
- 体积小。容器只包含需要用到的组件,而虚拟机是整个OS的打包。
Docker属于Linux容器的一种封装,提供了简单易用的容器接口
Docker的用途
- 提供一次性的环境。比如,本地测试他人的软件,持续集成的时候提供单元测试和构建环境。
- 提供弹性的云服务。因为Docker容器可以随开随用,很适合扩容和缩容。
- 组建微服务架构。通过多个容器,一台机器可以跑多个服务。
Docker 的Image
Docker 把应用程序及其依赖,打包在image文件里面。只有通过这个文件才能生成Docker容器,image文件可以看成容器的模板。Docker根据image文件生成容器实例。同一image可以生成多个同时运行的实例。image是二进制文件,实际开发中,一个image文件往往通过继承另一个image文件,加上一个个性化设置而生成。
二、Docker常用的命令
-
搜索镜像
docker search imageName:tag
-
下载镜像
docker pull image:tag
-
查看镜像
docker image list
-
运行镜像
docker run -it -d -p localPort:ContainerPort --name ContainerName image Command
每次运行后,都会生成一个容器实例- -i 以交互模式运行容器
- -t 为容器重新分配一个伪输入终端,通常与
-i
同时使用 - -d 容器运行在后台
- -p 容器端口映射到宿主机的端口上,用法为
-p 宿主机端口:容器端口
,类似的端口映射命令有-P
不用接参数,表示将容器暴露的所有端口号,但是映射到宿主机的任意端口,可以通过docker port ContainerId
查看容器的端口映射。 - –name 给运行的容器设置一个别名
- Command 在启动容器后,执行该命令。值得注意的是:用户在
docker run
后指定了命令,会覆盖Dockerfile
中指定的CMD命令
-
查看容器
docker ps
只能查看运行状态的containerdocker ps -a
可以查看所有的containerdocer ps -a --no-trunc
查看所有容器及其启动命令,这个还是很有用的 -
启动容器,前提是要存在该container
docker start containerId
-
清除容器。
docker rm container
-
清除镜像,需要先关闭并清除该镜像的container,最后清除镜像
docker rmi image:tag
-
登录容器
- ssh
2.docker attach containerId
阻塞式,所有用户看到同一个窗口,若使用CTRL+D或者exit退出命令行窗口,也会同时退出容器。若仅需退出CLI,使用CTRL+P+D
3.docker exec -it containerId sh
推荐使用
- ssh
-
查看docker 端口映射
docker port containerId
-
查看docker container的详细信息
docker inspect containerId
-
查看docker container运行的日志
docker logs container
-
容器与宿主机互相拷贝文件:
-
docker cp CONTAINER:SRC_PATH DEST_PATH
-
docker cp SRC_PATH CONTAINER:DEST_PATH
-
三、Dockerfile的关键字和exec与shell
FROM ubuntu:16.04
MAINTAINER tangweiyang <tangweiyang@baijiahulian.com>
ADD jdk-8u251-linux-x64.tar.gz /software/jdk
ENV JAVA_HOME /software/jdk/jdk1.8.0_251
ENV CLASSPATH .;$JAVA_HOME/lib/dt.jar;$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin
RUN apt-get update && \
apt-get install maven3 &&\
apt-get install git
EXPOSE 80
ENTRYPOINT ["/bin/ping","-c","4"]
CMD ["localhost"]
-
FROM <image>
指定构建镜像的基础镜像,如果本地没有指定的镜像,则会自动FROM
必须是Dockerfile
中非注释行的第一个指令。如果FROM
语句没有指定镜像标签,则tag
默认为lastest
-
MAINTAINER <name>
标记作者 -
RUN cmd
在当前镜像基础上执行指定命令,并提交为新的镜像。后续的RUN
都在之前RUN
提交后的镜像为基础,镜像是分层的,可以通过一个镜像的任意一个历史提交节点创建。docker history image
查看image构建的历史。RUN
有两种方式:shell
模式和exec
-
RUN executable param1,param2 # shell
-
RUN ["executable","param1","param2"] # exec,无法使用变量
-
-
CMD
在构建镜像后,则会执行CMD
后的命令。CMD
在Dockerfile中只能使用一次,如果有多个CMD
只有最后一个才能执行。CMD
的目的是为了在启动容器时提供一个默认的命令选项,如果用户在启动时指定了运行的命令,则会覆盖CMD
指定的命令。-
CMD "executable" "param1" "param2"
-
CMD ["/bin/bash","-l"]
两种方式的区别 第一种会采用
/bin/sh
执行命令 ,第二种采用exec
执行,具体区别表现在pid和实际执行的命令docker ps -a --no-trunc
是否加上了/bin/sh -c
RUN命令值得注意的一点:使用
docker run
可以覆盖CMD指令。如果我们在Dockerfile里指定了CMD指令,而同时在docker run 命令行中也指定了要运行的命令,命令行中指定的命令将会覆盖CMD指令 -
-
ENTRYPOINT
功能和CMD
是类似的,方法也是类似的。ENTRYPOINT ["executable","param1"]
可以避免执行命令时被添加/bin/sh -c
ENTRYPOINT
指令不会被docker run
输入的命令覆盖,但会将输入的cmd拼接到ENTRYPOINT
后面eg: 举一个端口开放不成功的错误案例
-
Dockerfile
FROM ubuntu:16.04 COPY ./target/demo.jar /apps/instance/ EXPOSE 80 ENTRYPOINT ["java","-jar","/apps/instance/demo.jar"]
-
docker run
命令docker run -it demo_image -p 8080:80
排查过程首先看了程序是否启动了
docker ps -a
,发现container是启动了的,但是宿主机8080端口没有被占用,具体查看启动的命令后docker ps -a --no-trunc
java -jar /apps/instance/demo.jar -p 8080:80
问题找到了,就是
docker run
的命令拼接到了ENTRYPOINT
。
但如果在
docker run
时需要覆盖Dockerfile中的ENTRYPONT
,可以在docker run -it image --entrypoint cmd
-
-
WORKDIR
每次创建一个容器,在容器内部设置一个工作目录,ENTRYPOINT
和CMD
指定的程序会在这个目录下执行(切换到工作目录下)-w
覆盖WORKDIR
-
ENV
配置环境变量,其他Dockerfile指令中$varibale
使用已有变量,docker run -e "xx=xx"
传递环境变量 -
USER
指定container运行的用户 ,默认是root
,也可以通过-u
设置用户 -
VOLUME
给容器添加卷,卷可以被多个容器所共用,对卷的使用时立即生效的,卷会保留到没有任何容器再使用它VOLUME ["/opt","/data"]
-
ADD
和COPY
将本地文件或网络资源拷贝到镜像中,两者有些区别ADD
会提取和解压文件