Docker简介
Docker简介
历史的演化
1)物理机时代:进程耦合,共享文件资源。资源抢占时,一个应用CPU过高会影响其它应用
2)虚拟化:虚拟机建立在虚拟硬件层之上,每个虚拟机都有独立的内核和用户程序以及依赖库,VM需要安装操作系统。
3)容器化技术:而 docker 容器建立在宿主机内核和 docker 服务之上,使用共同的内核,每个容器仅仅是用户程序。
虚拟机完整虚拟了内核和用户空间,而 docker 仅仅虚拟了用户空间,那么 docker 必然更轻量、更快。
抛出一个疑问:既然 docker 容器只是一个进程,为什么我们使用的时候感觉和虚拟机很像?在容器里使用 ps 看不到其它进程,看不到其它文件等等?
答:Docker通过namespace实现了资源隔离,通过cgroups实现了资源限制
docker底层 资源隔离知乎参考文章:https://zhuanlan.zhihu.com/p/67021108
Docker 镜像和容器解释
Docker镜像—Docker资源库(容器锁需要所有文件的集合),类似Win7操作系统中的光盘 Build once,Run anywhere
docker Pull [OPTIONS] NAME[:TAG] 从资源库拉取一个镜像到我们本地,但是镜像是只读的,相当于安装文件,
如果想提供服务,还需要docker run命令
docker run [OPTIONS] IMAGE [:TAG] [COMMAND][ARG...] 创建对应的容器,并启动服务
Docker容器—是镜像的实列,和系统其它部分隔离开的进程集合,由Docker镜像创建。
所有的镜像和容器默认存放在宿主机的 cd /var/lib/docker 目录中
Docker快速部署Tomcat
1)docker pull tomcat 拉取镜像
作为tomcat 只有镜像,只是死的文件,需要将其创建对应的容器才能提供服务
2)docker run tomcat 启动容器
此时浏览器访问ip:8080是访问不了的,因为浏览器访问的是宿主机而不是容器
3)docker run --name tomcat01 -p 8080:8080 -d tomcat 宿主机端口和容器端口绑定
--name tomcat01: 容器的名字
-p 8080:8080:将容器的 8080 端口映射到主机的 8080 端口。
-d :表示后台运行容器
补充命令:
docker ps -a 查找所有容器
docker stop <容器ID> 停止容器
docker start <容器ID> 启动一个停止的容器
docker rm -f <容器ID> 删除一个容器
docker exec -it <容器ID> /bin/bash 进入容器后台
it 采用交互的命令执行 /bin/bash 开启一个接收命令的终端
exit 退出容器
tomcat容器内部结构
上面的docker run命令包括了了三个组件
1.Apache Tomcat/8.5.46
2.jdk(1.8.0_222) 进入容器之后 java-version可以查看
3.Linux(Red Hat 4.8.5-28) min版本的操作系统 进入容器之后 cat/proc/version可以查看
使用Dockerfile构建镜像
1)Dockerfile就是构建docker镜像的一个配置文件
简单点来说:它可以让用户个性定制化Docker镜像。因为工作环境中的需求各式各样,网络上的镜像很难满足实际中的要求。
docker 提供了更方便强大的方式构建镜像,即 Dockerfile。Docker通过读取Dockerfile中的指令按步自动生成镜像
docker build -t 镜像名 <:tags> DockerFile 目录(.表示当前目录) 使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。
举例:使用Dockerfile部署:在原有tomcat安装完的基础上,将我们名为docker-web的应用发布到tomcat镜像中
#FROM为指定基础镜像 FROM tomcat:latest # 指定shell语句 运行在哪个目录下 不存在则创建 WORKDIR /user/local/tomcat/webapps #COPY 命令用于将文件拷贝到镜像中。COPY <源路径> <目标路径> COPY docker-web ./docker-web
# RUN 命令即用来在容器中执行命令的,相当于你之前手动在 docker 里面执行命令。
RUN echo "======end======"
RUN命令和ENTRYPOINT区别:
两者都是用于执行命令,区别在于执行命令的时机不同,
RUN命令适用于在 docker build 构建docker镜像时执行的命令
而ENTRYPOINT命令是在 docker run 执行docker镜像构建容器时使用
cd 到dockerfile文件
构建镜像:docker build -t sunkun/mywebapp:1.0 . (因为在dockerfile当前目录下 可以用.表示dockerfile文件的目录)
sunkun/mywebapp:1.0 是我们镜像的名字(机构名+镜像名+版本组成)
运行镜像:docker run -d -p 8080:8080 sunkun/mywebapp:1.0
此时在访问ip:port/docker-web就可以通过tomcat访问到我们部署的项目了
踩坑点:
如果可以访问tomcat欢迎页(ROOT目录),但不了可以访问webapps下的目录
更改conf下的server.xml配置(增加下面加粗的配置 让tomcat可以直接访问webapps下面的路径)
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Context path="" docBase="" debug="0" reloadable="true"/>
2)镜像分层
镜像构建时,会一层层构建,前一层是后一层的基础。
分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层。
每条命令会构建一层,所以不要写太多层 RUN,也不要只有一层,单独的功能模块组合到一层,更利于快速构建以及复用。
Dockerfile文件
FROM centos RUN ["echo","aaa"] RUN ["echo","bbb"] RUN ["echo","ccc"] RUN ["echo","ddd"]
更改Dockerfile文件,重新build
FROM centos RUN ["echo","aaa"] RUN ["echo","bbb"] RUN ["echo","ccc"] RUN ["echo","ddd"]
可以看到 前面三步因为命令没有变化,使用了已有的临时镜像,只会对发生变化的语句命令进行重新处理,生成对应的容器
这样可以极大的加快镜像的构建速度
容器间通信
link单向通信
启动容器的时候 docker run -d --name tomcat01 --link mysql tomcat 此时tomcat01就可以和mysql容器单向通信了
Bridge网桥双向通信(docker每创建一个网桥就会在宿主机上安装一个虚拟网卡)
docker network create -d bridge my-bridge 所有通过这个网桥(my-bridge)内外进行通信的容器 彼此之间默认都是互联互通的
docker network connect my-bridge tomcat01 此时tomcat01就和网桥绑定成功了
docker network connect my-bridge mysql 此时mysql就和网桥绑定成功了
此时tomcat01和mysql之间就互联互通了
容器间数据共享
原理:在宿主机上开辟一块空间,这块空间会被其他容器共享
通过设置-v 挂载宿主机目录
docker run --name 容器名 -v 宿主机路径:容器内挂载路径 镜像名
docker run --name tomcat01 -v /usr/webapps:/usr/local/tomcat/webapps tomcat
/usr/webapps 代表宿主机的user/webapps目录
/usr/local/tomcat/webapps 挂载到容器内部的 webapps目录下
tomcat01 容器运行的名称
tomcat 镜像名
如:docker run --name tomcat03 -p 8888:8080 -d -v /usr/webapps:/usr/local/tomcat/webapps tomcat
Docker-compose容器编排工具
一个项目上线,需要Nginx Tomcat MySQL,通过Docker-Compose 的yml脚本可以帮助我们先安装MySQL容器,在安装Tomcat容器,在安装Nginx容器,同时彼此形成依赖关系
Docker-Compose单机多容器部署工具,通过yml文件定义多容器如何部署
Docker-compose通过yml文件帮助我们部署了多个容器,并且将这些容器彼此之间进行有效的配置和互通互联