Docker入门
容器就是将软件打包成标准化单元,以用于开发,交付和部署。
- 容器镜像是轻量的,可执行的独立软件包,包含软件运行需要的所有内容:代码,运行时环境,系统工具,系统库和设置
- 容器化软件基于Linux和Windows,在任何环境中都能始终如一地运行
- 容器赋予软件独立性,使其免受外在环境差异的影响,从而有助于减少团队间在相同基础设施运行不同软件时的冲突
什么是Docker
一个开源的应用容器引擎,基于GO语言并遵守Apache2.0协议开源。Docker可以让开发者打包的应用以及依赖包到一个轻量级,可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。 容器是完全使用沙箱机制的,相互之间不会由任何接口,容器性能的开销机器低。
底层基于 LXC
, 是 linux
内核提供的功能. docker
可以隔离操作系统的环境, 使应用运行在一个独立的空间内.
NameSpace
命名空间 另外一个维度的隔离技术,CGroup
是物理层面的, 而NameSpace
则是逻辑层的分配, 例如: PID, 用户, 网络, IPC 以及 UTS 等系统资源. 不同的 NameSpace 彼此透明, 互不干扰.CGroup
Control Group 可以用来限定一个进程的资源使用, 比如 cpu, 内存, 磁盘 和 网络IO.UnionFS
字面意思, 多个目录挂载在同一个目录下面(逻辑上), 而这些目录其实物理上是分开的. 修改源目录的话, 挂在下的文件也会更新, 但是修改挂载下的文件, 源目录的文件不会受到影响. 利用这个, docker 就可以实现镜像分层了, 就是可以基于某个base
镜像创建, 一层层叠加新的逻辑, 制作类似于maven仓库的东西–docker hub, 这个也是docker
最大的优势之一.
boot file system: bootFS
, 包含操作系统的 bootloader
和 kernel
. 启动完成后, linux
内核加载到内存, bootFS
就会被卸载掉.
root file system: rootFS
, 典型的目录结构, 例如 /dev
, /bin
, /etc
… 在 linux 启动时, rootFS 是只读模式的, 在启动完成之后才改为 读写模式.
当容器修改了基础镜像的内容,其它容器的文件是否会变化?不会。利用镜像写时拷贝技术, 某个容器对镜像的修改会被限制在单个容器内,这样就可以对基础镜像进行功能的叠加了。
这个就是容器的 Copy-on-Write
特征。
FROM debian
RUN apt-get install emacs
RUN apt-get install apache2
CMD ["/bin/bash"]
执行 docker build .
创建容器镜像.
当使用 docker run
启动这个容器时,会在镜像的顶部添加一个新的可写层,这一层也叫做 容器层。容器启动后, 其内应用的所有对容器的改动, 文件的增删改操作都会只发生在容器层, 对容器层下面的所有只读镜像层时没有影响的。
为何使用Docker
- 快速,一致地交付应用程序。容器非常适合持续集成和持续交付(CI/CD)
- 响应式部署和扩展。允许高度可移植的工作负载,Docker容器可以在开发者本机,数据中心的物理或者虚拟机上,云服务上或者混合环境中运行
- 在同一个硬件上运行更多工作负载。Docker轻巧快速,它为虚拟机管理程序的虚拟机提供了可行,经济,高效的替代方案,可为业务提供更多的计算能力。非常适合高密度环境以及中小型部署,用更少的资源做更多的事情
基本架构
Docker使用客户端-服务端(C/S)架构。
- Docker Client 客户端
- Docker daemon 守护进程
- Docker Image 镜像
- Docker Container 容器
- Docker Registry 仓库
- Docker通过客户端连接守护进程,向守护进程发送命令请求,守护进程通过一系列操作返回结果
- Docker客户端可以连接本地或者远程的守护进程
- Docker客户端和服务器通过socket或RESTFul API进行通信。
Docker容器通过Docker镜像创建。
- Docker镜像,用于创建Docker容器的模板
- Docker容器,独立运行的一个或一组应用
- Docker客户端,通过命令行或者其它工具使用Docker API
- Docker主机,一个物理或者虚拟的机器用于执行Docker守护进程和容器
- Docker仓库,保存镜像的地方,有点像版本控制中的代码仓库
- Docker Hub,提供大量的镜像集合
- Docker Machine,一个简化Docker安装的命令行工作,通过简单的命令即可在各个平台上安装Docker
Docker是一种轻量的虚拟化技术,提供类似虚拟机的隔离功能,并使用一个分层的联合文件系统技术管理镜像,能简化环境的运维过程。
安装配置
安装可以参考CentOS安装配置
换源
Docker官方中国区: https://registry.docker-cn.com
网易: http://hub-mirror.c.163.com
USTC: https://docker.mirrors.ustc.edu.cn
# 直接修改
docker run hello-world --registry-mirror=https://docker.mirrors.ustc.edu.cn
# 修改 /etc/default/docker,加入 DOCKER_OPTS="镜像地址",可以有多个
DOCKER_OPTS="--registry-mirror=https://docker.mirrors.ustc.edu.cn"
# 使用json的方式 位置 /etc/docker/daemon.json
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://x.mirror.aliyuncs.com"]
}
基本使用
# 拉取镜像
docker pull images
# 镜像打tag
docker tag imageName newIamgeName
# 推镜像
docker push imageName
# 运行中的容器
docker ps
# 已经下载的镜像
docker images
# 创建容器
docker create --name redis-node01 -v /data/redis-data/node01:/data -p 6379:6379 redis
# 创建并启动
docker run --privileged=true --name zookeeper --publish 2181:2181 zookeeper:latest
# 启动容器
docker start container
# 查看容器id
docker ps -a
# 主机复制到容器
sudo docker cp host_path containerID:container_path
# 容器复制到主机
sudo docker cp containerID:container_path host_path
# 进入交互式终端
docker exec -it container /bin/bash
# 查看容器信息
docker inspect container
# 停止/删除容器
docker stop container
docker rm container
# 查看log
docker logs containerId
Docker与虚拟机的区别
虚拟机也是一种虚拟化技术,它与Docker最大的区别在于它是通过模拟硬件,并在硬件上安装操作系统来实现。
Docker的守护进程与操作系统进行通信,为各个容器分配资源;将容器与操作系统隔离,并将各个容器互相隔离。虚拟机启动满,而Docker启动可以在数毫秒内;由于没有臃肿的从操作系统,Docker可以节省大量的磁盘空间以及其它系统资源。
虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。在实体计算机中能够完成的工作在虚拟机中都能够实现。在计算机中创建虚拟机时,需要将实体机的部分硬盘和内存容量作为虚拟机的硬盘和内存容量。每个虚拟机都有独立的CMOS、硬盘和操作系统,可以像使用实体机一样对虚拟机进行操作。
- 虚拟机是一台物理机上,利用虚拟化技术,虚拟出多个操作系统,每个操作系统之间是隔离的。docker是开源的应用容器引擎,需要先在电脑安装操作系统,然后再安装Docker容器管理器。
- 虚拟机是在硬件级别进行虚拟化,而Docker是在操作系统的层面虚拟机。
- 虚拟机通过模拟硬件搭建操作系统,而Docker则是复用操作系统。
- 虚拟机实现了操作系统之间的隔离,Docker只是进程间的隔离,所以虚拟机的隔离级别更高,安全性更强
- Docker的运行速度更快,文件更小
SpringBoot容器化改造
Provider,服务提供者
# 环境变量 ServerPort
server.port=${ServerPort}
mybatis.mapperLocations=classpath:mapping/*.xml
#配置数据库链接等数据源
spring.datasource.name=mianshi
spring.datasource.url=jdbc:mysql://${Mysql_Host_And_Port}/mianshi?useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=${Mysql_User}
spring.datasource.password=${Mysql_Password}
#使用druid做链接池管理
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driverClassName=com.mysql.jdbc.Driver
#add-mappings=true表示如果所有的controller都没有命中,则使用默认的静态资源处理器做匹配
spring.resources.add-mappings=true
spring.mvc.throw-exception-if-no-handler-found=true
#接入前端静态资源页面
spring.mvc.static-path-pattern=/static/**
#thymeleaf相关的配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
#dubbo配置
spring.application.name=dubbo_provider
#Dubbo provider configuration
dubbo.application.name=dubbo_provider
dubbo.registry.protocol=zookeeper
dubbo.registry.address=zookeeper://${Zookeeper_Host_And_Port}
dubbo.protocol.name=dubbo
dubbo.protocol.port=${Dubbo_Port}
#扫描注解包通过该设置将服务注册到zookeeper
dubbo.scan.base-packages=com.imooc.mianshi
Consumer,服务消费者
server.port=${ServerPort}
mybatis.mapperLocations=classpath:mapping/*.xml
#配置数据库链接等数据源
spring.datasource.name=mianshi
spring.datasource.url=jdbc:mysql://${Mysql_Host_And_Port}/mianshi?useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=${Mysql_User}
spring.datasource.password=${Mysql_Password}
#使用druid做链接池管理
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driverClassName=com.mysql.jdbc.Driver
#add-mappings=true表示如果所有的controller都没有命中,则使用默认的静态资源处理器做匹配
spring.resources.add-mappings=true
spring.mvc.throw-exception-if-no-handler-found=true
#接入前端静态资源页面
spring.mvc.static-path-pattern=/static/**
#thymeleaf相关的配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
#dubbo配置
dubbo.application.name=dubbo_consumer
dubbo.registry.protocol=zookeeper
dubbo.registry.address=zookeeper://${Zookeeper_Host_And_Port}
Dockerfile
使用类似 UnionFS
技术去定义 docker
镜像的依赖,然后使得其可以做 UnionFS
镜像覆盖来制作自定义镜像。
# 基于 jdk8 进行改造
FROM java:8
COPY ./target/mianshi-0.0.1-SNAPSHOT.jar app.jar
# 更新文件的时间
RUN bash -c "touch /app.jar"
# 指令参数
CMD ["-jar","app.jar"]
ENTRYPOINT ["java"]
# 打包镜像. 在有 dockerfile 的目录下执行
docker build -t name .
# 启动服务端. 植入环境变量
docker run -itd -p 8881:8080 -p 28881:20880 --env ServerPort=8080 --env Mysql_Host_And_Port=127.0.0.1:3309 --env=Mysql_User=root --env Mysql_Password=root --env Zookeeper_Host_And_Port=127.0.0.1:2183 --env Dubbo_Port=20880 mainshi
# 启动客户端
docker run -itd -p 8882:8080 --env ServerPort=8080 --env Mysql_Host_And_Port=127.0.0.1:3309 --env=Mysql_User=root --env Mysql_Password=root --env Zookeeper_Host_And_Port=127.0.0.1:2183 mainshiclient