本篇博文目录:
1.Docker容器的理解
程序部署运行的演变过程从最初单台物理机到通过虚拟机方式,最后到利用容器的方式进行部署。
物理机时代部署应用存在的问题就是部署非常慢,成本很高,资源浪费,难于扩展与迁移并且受制于硬件。
虚拟机时代避免与硬件直接接触,硬件环境的配置是可以手动配置,避免了资源浪费,并且虚拟机时代可以实现多部署,资源分配的时候类似于资源池通过Hypervisor进行分配,分配的资源是相互隔离且很容易扩展,当资源不够时可以通过Hypervisor分配资源给不足的机器。
在虚拟机时代应用程序部署之前需要先安装虚拟机的操作系统,这样的方式消耗资源并且多个虚拟机的资源是相互隔离的无法做到环境的一致性即在一台上面进行了部署可以正常运行当换到另一台虚拟机上部署后或许会出现无法运行的情况,解决办法就是将能够运行的系统的镜像cpoy到另外一台机器上,这样就保证了环境的一致性,但是这种方式非常的麻烦所以才会出现容器化时代。
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker的应用场景如下图所示:
Docker的发展情况如下:
2.Docker的安装(Linux centos7.0)
安装教程地址:https://www.runoob.com/docker/centos-docker-install.html
Linux centos7.0安装过程如下:
安装Docker底层工具: sudo yum install -y yum-utils device-mapper-persistent-data lvm2
修改安装源阿里云安装源:sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新仓库的源信息:sudo yum makecache fast
安装Docker:sudo yum -y install docker-ce
Docker服务化:sudo service docker start
启动Docker:service docker start
查看Docker的版本:docker version
从镜像厂库拉去hello-world项目:docker pull hello-world
docker启动hello-world项目:docker run hello-world
(出现Hello from Docker!表示Docker安装成功!)
3.Docker体系结构
Docker是一个提供开发,打包,运行应用的平台,应用程序通过Docker Engine(Docker引擎)来获取相关硬件资源。
Docker引擎由server(服务端)又称docker daemon(守护进程),REST API(网络连接) 和Clent (客户端)docker CLI组成。
关于容器,镜像和Docker三者的理解你可以通过这篇博文进行学习:https://www.jianshu.com/p/f23b20ffd1de,简单理解Docker相当于一艘船,容器相当于运货的集装箱,放在船上,而镜像就是需要运送的货物。
Docker客户端Client通过Rest API与Docker daemon建立连接,客户端向Docker daemon发送相关命令(docker build,docker pull和docker run…)如Client向Docker daemon发送docker pull tomcat拉去tomcat的镜像,如果本地(Images)没有该镜像就需要从注册中心(第三方提供的镜像厂库)获取tomcat镜像,获取到后放入到本地中(私有仓库),如果本地有该镜像直接获取,当发送docker run tomcat命令后容器会将tomcat镜像放入容器中进行执行。
案例演示,安装通过Docker安装Tomcat,并运行:
查询相关镜像的Docker命令,查询网址为:https://hub.docker.com/_/tomcat
Tomcat的Docker指令为:docker pull tomcat
: (从远处厂库中拉去镜像到本地)
查看当前本地镜像,使用sudo docker images
,存在tomcat的镜像表示下载成功!
运行镜像,使用sudo docker run -d -p 8959:8080 tomcat
: (将tomcat镜像放入到容器中进行执行,这里的参数-d表示后台运行,-p表示绑定端口,第一个端口为物理机端口,第二个端口为容器映射的端口,8959:8080表示当用户访问当前这台机器的8959端口的时候会去执行docker容器的8080端口上的程序)
访问8959端口,熟悉的Tomcat界面出现,通过docker部署tomcat成功!:
备注:关于无法访问出现404问题,你可以参照这篇博文:https://blog.csdn.net/qq_45471034/article/details/108671366
4.利用Dockerfile构建自定义镜像
Dockerfile文件是Image镜像的描述文件,用来描述镜像需要进行怎样的操作。
实例练习,在Tomcat中运行指定网页页面index.html
在dockertemp目录下创建docker-web目录,并在该目录下创建index.html文件,文件内容如下(dockertemp目录是自己创建的一个普通文件夹位于/usr/local/dockertemp ,使用命令mkdir dockertemp):
在dockertemp文件下创建Dockerfile文件:
Dockerfile文件中的内容如下(Dockerfile文件没有任何后缀,使用touch Dockerfile命令创建):
使用 sudo docker build -t dudu/mydocker-web:1.0 /usr/local/dockertemp
构建镜像
运行新建的镜像:
我们可以通过 sudo docker exec -it 11cd1fbdcf9a /bin/bash
命令查看一下镜像目录情况:
使用exit退出(可以当做一种客户端):
访问index.html网页( 访问成功!
):
我们可以通过 sudo docker history IMAGE ID
查看镜像的运行情况:
5.Dockerfile基础命令讲解
FROM命令用于制作基准镜像,有二种方式,方式1基于已有镜像进行扩展,方式2不依赖任何镜像进行扩展。前文例子中使用的FROM tomcat : latest 命令就是基于tomcat镜像进行扩展的,latest表示版本,如FROM tomcat:9.0.22-jdk8-openjdk就是基于9.0.22-jdk8-openjdk版本的镜像,如果不依赖于任何镜像使用FROM scratch命令(非常少见)。
LABEL命令用于说明信息,说明某条命令是干什么的,也就是程序设计里的注释。
WORKDIR命令用来设置工作目录,可以理解为Liunx中的cd命令,不同的是如果目录中某个文件不存在会自动创建。
ADD命令用于复制文件,具有解压缩的功能,使用ADD命令复制压缩文件到某个目录下会自动解压缩,并且ADD还具备添加远程文件功能。
ENV命令用于设置环境常量。
EXPOSE命令用于容器端口的暴露,将容器内部端口暴露给物理机。
前文中使用的
sudo docker run -d -p 8000.:8080 镜像id
命令,其中8080就是容器暴露的端口,而这里的8000表示的是物理机的端口号,当我们访问物理机8000端口的时候会去执行容器8080端口上的镜像。
6.Docker中的分层(Layer)
通过上文的学习,我们可以发现在一个镜像的基础进行扩展,并且一个基准镜像可以融入多个镜像,在Docker中镜像和容器存在分层的概念,分为镜像层和容器层,镜像层用来管理各种镜像,而容器层用来管理容器的读和写。
在基准镜像中进行扩展的镜像只有一个,但是执行镜像中各个子镜像的容器确有多个。
实例演示:
在dockertemp目录下创建docker_layer目录,并在该目录下创建Dockerfile文件:
Dockerfile文件内容如下:
使用 sudo docker build -t layer /usr/local/dockertemp/docker_layer
命令构建layer镜像 ( 每一层的镜像都会有一个不同的容器进行执行
):
对Dockerfile文件中后二条命令进行修改,然后重新构建镜像:
采用分层的概念可以提高镜像构建效率。
7.Dockerfile运行指令
RUN,CMD和ENTRYPOINT都是用来执行命令,不同的是执行的时间点不同。 RUN命令在Build构建镜像的时候执行,ENTRYPOINT和CMD都是在容器启动的时候执行,并且CMD在容器启动后也可以执行。
Run命令有以下二中命令格式,Shell命令格式和Exec命令格式。
Shell方式使用Shell执行时,当前shell是父进程,会生成一个子shell进程,然后在这个子进程中执行脚本。脚本执行完毕,退出子shell,回到当前shell。
使用Exec方式,会用进程替换当前shell进程,并且保持PID不变,执行完毕,直接退出,不回到之前的shell环境。
ENTRYPOINT命令又叫入口点用于在容器启动时执行命令,在Dockerfile中可以运行有多个入口点,但是只有文档最后一个入口点会被执行,ENTRYPOINT命令推荐使用Exec模式。
CMD命令用于设置默认执行的命令,CMD命令和ENTRYPOINT命令一样可以在Dockerfile中出现多个CMD,只有最后一个会被执行,推荐使用Exec格式。
实例练习:
在dockertemp目录下创建shell目录,并在该目录下创建Dockerfile文件:
Dcokerfile文件如下:
使用 sudo docker build -t shell /usr/local/dockertemp/shell
构建镜像:
启动容器:
在Dockerfile文档中末尾新增加一条CMD命令,并重新构建容器,并运行:
CMD在Dockerfile文档中有多条命令,只执行最后一条CMD命令:
当在外部设置了CMD命令,文档里面的所有CMD命令都会失效:
ENTRYPOINT和CMD都是在容器执行后执行,不同的是ENTRYPOINT执行固定的命令:
CMD可以提供动态的参数(附加参数到命令上):
运行效果:
动态修改CMD的参数为-aux:
8.MySQL快速部署与初始数据
案例:通过docker安装Mysql数据库并部署数据库于初始化数据。
在dockertemp目录下创建sampledb目录,并在该目录下创建init.sql:
Msql数据库脚本init.sql的内容如下:
详细SQL脚本内容如下:
create database `docker_mysql`;
use docker_mysql;
-- 建表
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` bigint(20) NOT NULL,
`created_at` bigint(40) DEFAULT NULL,
`last_modified` bigint(40) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`first_name` varchar(255) DEFAULT NULL,
`last_name` varchar(255) DEFAULT NULL,
`username` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- 插入数据
INSERT INTO `user` (`id`, `created_at`, `last_modified`, `email`, `first_name`, `last_name`, `username`)
VALUES
(0,1490257904,1490257904,'john.doe@example.com','John','Doe','user');
下载MySQL镜像,地址https://hub.docker.com/_/mysql:
使用 docker pull mysql:5.7
拉起mysql镜像:
将.sh.sql和.sql.gz后缀的文件放入到/docker-entrypoint-initdb.d中,容器会去执行和扩展:
所以我们编辑Dockerfile文件,将init.sql文件放入到/docker-entrypoint-initdb.d中即可:
Dockerfile文件内容:
构建镜像文件sampledb:
运行容器: sudo docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=root sampledb
MySQL镜像官网 https://hub.docker.com/_/mysql 对MySQL镜像怎么启动有详细的说明:
包括环境变量的说明,更多详细信息请查阅MySQL镜像官网:
使用netstat -ano 查询端口情况,3310端口成功启动:
使用Navicat 连接数据库,查看部署的数据库情况:
9.发布镜像到DockerHub
在DockerHub上创建自己的仓库:
使用 sudo docker login
终端登入到docker:
将前文练习的docker-web镜像上传到仓库中,先重新构建一个和远程仓库一样名字的镜像:
使用 sudo docker push itguye/hellodocker:1.0
将镜像push到远程仓库:
使用 sudo docker rmi itguye/hellodocker:1.0
删除本地的镜像:
使用 sudo docker pull itguye/hellodocker:1.0
从远程仓库中拉起镜像:
使用 sudo docker run -d -p 8003:8080 itguye/hellodocker:1.0
运行镜像:
访问: http://www.itguye.top:8003/docker-web/index.html 成功!