一、Docker简介
Docker 是一个开源的应用容器引擎,让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器(container)中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app)。几乎没有任何性能开销,可以很容易地在机器和数据中心中运行,最重要的是,他们不依赖于任何语言、框架或包装系统。
Docker是dotCloud公司开源的一个基于LXC的高级容器引擎,源代码托管在Github上,基于GO语言并遵从Apache2.0协议开源。
Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版)。
2017年年初,docker公司将原先的docker开源项目改名为moby。moby是继承了原先的docker的项目,是社区维护的开源项目,谁都可以moby的基础上打造自己的容器产品。
docker-ce是docker公司维护的开源项目,是一个基于moby项目的免费的容器产品。docker-ee是docker公司维护的闭源产品,是docker公司的商业产品。moby是源代码,docker-ce和docker-ee是容器产品,是rpm包。
1.1 沙盒
沙盒也叫沙箱,英文sandbox,在计算机领域指一种虚拟技术,且多用于计算机安全技术。安全软件可以让它在沙盒中运行,如果含有恶意行为,则禁止程序的进一步运行,而这不会对系统造成任何危害。
1.2 LXC
LXC为Linux Container的缩写。Linux Container容器时一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。
LXC主要通过来自Kernel的namespace实现每个用户实例之间的相互隔离,通过cgroup实现对资源的配额和度量。
1.3 Docker核心技术
Namespace:实现Container的进程、网络、消息、文件系统和主机名的隔离。
Cgroup:实现对资源的配额和度量。Cgroup的配额,可以指定实例使用的CPU个数,内存大小等。就像vmware虚拟机中的硬件配置参数。
docker镜像相当于,对程序+程序依赖的库打一个包。软件是依赖操作系统中的库或二进制文件。如果我们把软件所依赖的库和二进制文件打包在一起发布,不用物理机系统上的文件,也就不依赖操作系统了。
1.4 LOGO
docker服务相当于鲸鱼,container容器就是集装箱。
container:集装箱,容器。
docker:码头工人。
二、Docker的应用场景
- Web 应用的自动化打包和发布。
- 自动化测试和持续集成、发布。
- 在服务型环境中部署和调整数据库或其他的后台应用。
- 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。
三、Docker容器技术和虚拟机对比
Docker容器技术和虚拟机技术,都是虚拟化技术。但Docker相对于VM虚拟机,少了虚拟机操作系统这一层,所以Docker效率比虚拟机高。
3.1 优点
1、比VM小,比VM快,Docker容器的尺寸减少相比整个虚拟机大大简化了分布到云和从云分发时间和开销。Docker启动一个容器实例时间很短,一两秒就可以启动一个实例。
2、Docker使应用程序能够快速从组件组装和避免开发和生产环境之间的摩擦。
3、Docker支持Unix/Linux操作系统,也支持Windows或Mac
3.2 缺点局限性
Docker用于应用程序时是最有用的,但并不包含数据。日志、跟踪和数据库等通常应放在Docker容器外。一个容器的镜像通常都很小,不适合存储大量数据,存储可以通过外部挂载的方式使用。比如使用NFS、ipsan、MFS等,-v映射磁盘分区。
一句话:Docker只用于计算,存储交给别人。Oracle不适合使用Docker来运行,太大量,存储的数据太多。
四、Docker工作流程
服务器A上运行Docker Engine服务,在Docker Engine上启动很多容器container,从外围Docker Hub 上把image操作系统镜像下载来放到container容器运行,这样一个容器的实例就运行起来了。最后,通过Docker client对Docker容器虚拟化平台进行控制。
dockerhub:dockerhub是Docker官方的镜像存储点,其中提供了很多常用的镜像供用户下载,如ubuntu,centos等系统镜像。通过dockerhub用户也可以发布自己的docker镜像,为此用户需要注册一个账号,在网站上创建一个docker仓库。
五、Docker特性
- 文件系统隔离:每个进程容器运行在一个完全独立的根文件系统里。
- 资源隔离:系统资源,像CPU和内存等可以分配到不同的容器里,使用cgroup。
- 网络隔离:每个进程容器运行在自己的网络空间,虚拟接口和IP地址。
- 日志记录:Docker将会收集和记录每个进程容器的标准流(stdout/stderr/stdin),用于实时检索或批量检索。
- 变更管理:容器文件系统的变更可以提交到新的镜像中,并可重复使用以创建更多的容器。无需使用模板或手动配置。
- 交互式shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上,例如运行一个一次性交互shell。
六、Ubuntu Docker 安装
6.1使用官方安装脚本自动安装
安装命令如下:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
也可以使用国内 daocloud 一键安装命令:
curl -sSL https://get.daocloud.io/docker | sh
6.2 检查docker版本号
docker --version
6.3 用docker运行hello-world
$ sudo docker run hello-world
$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete Digest: sha256:c3b4ada4687bbaa170745b3e4dd8ac3f194ca95b2d0518b417fb47e5879d9b5f
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
6.4 配置docker加速
由于国内访问直接访问Docker hub网速比较慢,拉取镜像的时间就会比较长。一般我们会使用镜像加速或者直接从国内的一些平台镜像仓库上拉取。
我比较常用的是网易的镜像中心和daocloud镜像市场。
daocloud镜像市场:https://hub.daocloud.io/
创建/etc/docker/daemon.json
文件并配置如下内容:
vi /etc/docker/daemon.json
{
"registry-mirrors" : [
"http://hub-mirror.c.163.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
重启docker
systemctl enable docker && systemctl restart docker
七、Docker部署SpringBoot项目
7.1 创建SpringBoot项目
新建hello接口
package com.alanchen.docker;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Alan Chen
* @description
* @date 2021/9/22
*/
@RestController
@RequestMapping("docker")
public class HelloDockerController {
@GetMapping("/hello")
public String hello(){
return "Hello SpringBoot with Docker!";
}
}
用Postman测试hello接口
7.2 打包SpringBoot项目为jar包
7.3 将jar包上传到阿里云ECS服务器(Ubuntu)
scp E:/code/docker/target/docker-0.0.1-SNAPSHOT.jar root@47.105.146.74:/data/docker-demo/docker-0.0.1-SNAPSHOT.jar
前提:需要现在ECS服务器上,建立/data/docker-demo
目录
7.4 编写Dockerfile文件
进入/data/docker-demo
目录,编写Dockerfile文件
cd /data/docker-demo
vi Dockerfile
# 基础镜像使用java
FROM java:8
# 作者
MAINTAINER eangulee chenyan900520@126.com
# VOLUME 指定了临时文件目录为/tmp。
# 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为app.jar
ADD *.jar app.jar
# 运行jar包
RUN bash -c 'touch /app.jar'
#指定容器启动时要执行的命令,但如果存在CMD指令,CMD中的参数会被附加到ENTRYPOINT指令的后面
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
VOLUME
指定了临时文件目录为/tmp
。其效果是在主机/var/lib/docker
目录下创建了一个临时文件,并链接到容器的/tmp
。
该步骤是可选的,如果涉及到文件系统的应用就很有必要了。
/tmp
目录用来持久化到Docker
数据文件夹,因为Spring Boot
使用的内嵌 Tomcat 容器默认使用/tmp
作为工作目录项目的 jar 文件作为 app.jar
添加到容器的ENTRYPOINT
执行项目app.jar
。
为了缩短Tomcat
启动时间,添加一个系统属性指向/dev/./urandom
作为Entropy Source
。
如果是第一次打包,它会自动下载Java 8的镜像作为基础镜像,以后再制作镜像的时候就不会再下载了。
/data/docker-demo
目录文件如下
7.5 制作镜像
在/data/docker-demo
目录下执行命令,-t 参数是指定此镜像的tag名
docker build -t springbootdemodocker .
注意:最后有一个点.
制作完成后通过docker images
命令查看我们制作的镜像
7.6 启动容器
docker run -d -p 8081:8080 springbootdemodocker
-d参数是让容器后台运行
-p 是做端口映射,此时将服务器中的8081端口映射到容器中的8080(项目中端口配置的是8080)端口。
注意:阿里云ECS要开放8081端口
7.7 Postman访问hello接口
7.8 常用命令
# 查看镜像
docker images
# 查看运行容器
docker ps
# 查看所有容器
docker ps -a
# 启动容器
docker start 050cdb6e6c4c
# 进入容器 docker exec -it(gitlab的容器名称或id) bash
docker exec -it 268648f0baba bash
# 查看日志
docker logs b2a4046cd6cb
# 停止容器
docker stop b2a4046cd6cb
# 删除容器
docker rm -f b2a4046cd6cb
7.9 删除镜像
docker rmi springbootdemodocker
删除失败,这里提示镜像有被容器在使用中
root@iZm5eetszs07500os8erolZ:/data/docker-demo# docker rmi springbootdemodocker
Error response from daemon: conflict: unable to remove repository reference "springbootdemodocker" (must force) - container 73f200c43f18 is using its referenced image 169c314099d1
根据提示,先删除是使用的容器container 73f200c43f18
,如果有多个,按此步骤重复进行删除即可。
root@iZm5eetszs07500os8erolZ:/data/docker-demo# docker rm 73f200c43f18
73f200c43f18
再执行删除springbootdemodocker
root@iZm5eetszs07500os8erolZ:/data/docker-demo# docker rmi springbootdemodocker
Untagged: springbootdemodocker:latest
Deleted: sha256:169c314099d19f734342a0c394004815b1d71d129780306cb8a02a8c34192fae
Deleted: sha256:e065cf4dceeb81b43bd115791a33c6154426e01ff560f5f18abc946438d1d9f9
Deleted: sha256:db8ef1e3b08b9d3687ce2bc238db0704812bff55adc56c4b6a1c3f1e00ba3c5e
Deleted: sha256:f5c3f52e1c6bf7f280c377ae871d469ef5d1e4830932c9dda2ee7d5c155f9b23
Deleted: sha256:1a11d099053d15ed4f63dd7a865f9c7f8d4df1474738558bdea5a3975ba911d9
Deleted: sha256:34d1333a3e2354dc9fc0d2dbf201093294793ba9558c6e7bf8a2af82dd689838
Deleted: sha256:790a330a1ea1833657dd218dfda5aea6386fc85de8666ab410d816a962a2f992