1、Docker简介前端
1.1 什么是dockerjava
docker的英文意思是 码头工人,意思就是搬运东西的意思,其实这和docker的特色是同样的,docker提供的就是一种容器化搬运东西(咱们的软件、程序)的过程。docker本身原本是运行在操做系统上一个程序软件,它会提供一个容器环境,使咱们的程序独立地运行在容器中,因此说,官方给docker起的这个名字也真是应景。mysql
就连图标也是这么生动形象,富有诗意,让人浮想联翩。。。。(这是去幼儿园的车,尚未拐进大学城)linux
试想下边这样一个场景:当咱们把咱们的web网站作成分布式的时候,咱们就要加服务器,而后在各个服务器配置web所须要的配置,好比:数据库、web服务器、运行时啥,这样的咱们的网站才能跑起来,可是每当咱们加服务器的时候,咱们都要再从新配置一下,很繁琐,有了docker,咱们就能够把咱们的网站和所须要的环境配置好,打成一个包(docker镜像),而后在服务器上安装docker,用docker拉取打包好的镜像,直接run(容器)起来就好了,什么都不用管了,很方便,更加的便于管理,镜像中修改配置,从新更新,全部的容器就也能修改了,咱们的网站也就修改更新了,特别的方便。nginx
1.2 docker的特色git
docker的特色包含在它的口号中github
第一句,是“Build, Ship and Run”。(搭建、运输、运行)web
第二句,“Build once,Run anywhere(一次搭建,处处运行)”。sql
看了上边的场景,咱们能够理解这两句话了,如今哪一个软件不是一次搭建、处处运行,真的都很差意思说,从最开始的java,到如今的各类跨平台前端框架(Flutter、ReactNative、Ionic啥的)、小程序框架(Taro),这是解放开发人员减小开发成本提升开发效率的三连击造福码农的事情啊,各类应用层出不穷,叫咱们情何以堪、不堪回首、首当其冲、冲锋陷阵啊,一不当心就暴露了个人文化。docker
1.3 docker和虚拟机
一说到docker,相信你们以前也了解过,那就必需要和虚拟机作一下比较,其实docker是和虚拟机是相似的东西,咱们应该知道虚拟机就是在咱们的操做系统上虚拟出来一个电脑,而后里边能够安装、运行各类各样的软件,和咱们真的电脑是差很少的,咱们能够拿着这个虚拟好的电脑(实际上是一个文件)在按了虚拟机的其余电脑上能够直接运行,里边的东西就不用咱们来回安装和配置了,也是很方便的。
docker其实提供的也是这么一种的技术,只不过它比虚拟机效率更加的高,启动快,占用资源小等一系列的优势,并且虚拟机比较笨重,这是由于虚拟机和docker来实现思想上有本质的区别,咱们能够经过下边的两张图能够对比一下:
虚拟机的运做原理:是虚拟电脑的硬件资源,把硬件资源分配出来,而后虚拟出来多个操做系统,虚拟出来的是一个完整的电脑。
docker的运做原理:虚拟的软件资源,把电脑中的网络、存储啥的分红几份虚拟成容器,咱们的软件运行在容器中,每一个容易只占用电脑的部分所须要的资源,并非一个完整的电脑。
大概就像上边那么理解吧,反正也不知道是对不对,可是看起来应该不错。
因此,从运做原理上来看,docker更加的轻量级,虚拟机更加的笨重,docker启动也十分的快,部署起来也方便,因此愈来愈多的人开始使用docker起来。
下边是一张虚拟机和docker的对比,这里要注意一下:可是docker自己并非容器,而是建立容器的工具;而虚拟机它就是虚拟机了。
2、docker中的核心概念
下面咱们来介绍使用docker的过程当中必需要掌握的概念,理解这些概念对docker的使用和学习是很是必要的。
2.1 镜像(Image)
镜像究竟是个什么东西呢,不少人在学习docker的时候都是一头雾水的,但是是歪果仁对镜像情有独钟吧,好多东西都有镜像的概念。好比咱们安装系统的.iso文件,其实就是镜像,这里你就能够把镜像认为是一种模板。咱们可使用docker根据这个模板建立容器来运行,其实更能够理解为镜像是比如github上的仓库同样,咱们能够克隆下来源代码而后运行,运行起来的代码能够是一个网站、一个应用程序啥的,这就能够叫作容器。说白了,镜像就是一堆静态的模板,运行起来的镜像就是容器。镜像通常须要咱们拉取下来,是只读的,这个咱们克隆github上的仓库是同样同样的。
docker镜像中有分层的概念,就是一个镜像可能基于好几个镜像,好比一个web运行环境可能须要操做系统ubuntu、数据库mysql、.net core runtime运行时,那咱们拉取的这个镜像就会包好这好几个镜像,这就好像咱们前边说的打包好的运行环境同样,直接就拉下来一个小电脑同样。
2.2 容器(Container)
当咱们拉取了一个镜像,而后run一下,就会根据这个镜像运行出来一个容器,运行的容器就好像咱们的应用程序同样,能够访问能够中止,咱们运用屡次run命令,就运行了不少不少容器,也能够说是镜像的实例。从这个角度来看,咱们能够把镜像看做是类,容器看做new出来的实例,也是很合适的。
2.3 仓库(Repository)
存放镜像的地方就是仓库,就比如存放代码的地方是github同样,咱们就把github称为代码的仓库,github算是最大的仓库。那么存放docker镜像的地方咱们叫作dockerhub,是docker的中央仓库。其实已经有dockerhub这个网站了(https://hub.docker.com/),这就是 存放docker镜像的官方仓库,好多官方的也保存在这里,保证了镜像的安全性和可靠性,咱们能够从上边拉取一下镜像来运行咱们的软件。固然咱们也能够制做好咱们本身镜像推送上去,不过这些确定是要官方审核的,防止有些人写入一些恶意代码。不过咱们能够推到咱们本身的dockerhub上去,供咱们本身使用,这个就好咱们的github帐号同样了,属于私有镜像了。
2.4 数据卷(Volumn)
实际上咱们的容器就好像是一个简易版的操做系统,只不过系统中只安装了咱们的程序运行所须要的环境,前边说到咱们的容器是new出来的实例,既然是new出来的实例那就会销毁,那若是销毁了咱们的程序产生出的须要持久化的数据怎么办呢,容器运行的时候咱们能够进容器去查看,容器一旦销毁就什么都没有了。因此数据卷就是来解决这个问题的,是用来作数据持久化到咱们的宿主机上容器间的数据共享,简单的说就是将宿主机的目录映射到容器中的目录,应用程序在容器中的目录读写数据会同步到宿主机上,这样容器产生的数据就能够持久化了,好比咱们的数据库容器,就能够把数据存到咱们宿主机上的真实磁盘上了。
docker中基本的概念已经说了,下面咱们就能够来使用docker了。
3、docker的安装与使用
因为docker的服务端只能运行在linux操做系统上,固然咱们学习也能够用windows来安装docker,可是比较麻烦,须要开启一系列的配置,咱们仍是暂时在一台装有虚拟机的linux系统上来学习docker。这里咱们以linux ubuntu 16.04 版原本学习。
3.1 docker的安装
咱们先执行命令安装docker
1. 执行 sudo apt-get update 更新软件包
2. 执行 sudo apt-get -y install docker.io 安装docker
3. 输入 docker version 检查docker是否安装成功
若是有下面的输出,说明docker安装成功
3.2 docker的使用
docker --help 查看帮助信息,通常的软件都会有这个命令,再也不多说。
docker version 查看docker的版本。
docker info 查看docker的基本信息,有多少个容器、镜像什么的。
docker images 查看本机上的全部镜像。
REPOSITORY:仓库,也是镜像名称。
TAG:标签,也是版本号,镜像会有不一样的版本号。
IMAGE ID:镜像id,根据这个id咱们能够区分不一样的镜像,也能够对某个镜像进行操做。
CREATED:建立时间。
SIZE:镜像的大小。
当前个人机器上没有一个镜像,显示以下:
docker pull <镜像名称>:[标签名称]:拉取镜像,默认不写标签名称拉取最新的镜像。
咱们输入docker pull hello-world 拉取最新的hello-world镜像
docker run <镜像名称> :运行一个镜像,这时候就变成一个容器了,至关于new 一个Image了。下边咱们run hello-world 运行这个镜像,输出如下信息:
至此,咱们的docker的hello-world已经运行成功了,接下来咱们来启动一个nginx服务器,来从外边访问咱们容器里的nginx看看。
一样咱们先拉取nginx镜像 docker pull nginx,而后等待拉取完成,运行nginx容器,docker run -p 8080:80 nginx
而后咱们用自带的浏览器来访问8080端口,出现welcom to nginx 表示启动成功。
docker的使用方法基本就是上边这样了,接下来咱们就能够看一下详细的参数。
3.3 docker的命令
3.3.1 镜像命令:
docker images 查看本机的镜像。
REPOSITORY:仓库,也是镜像名称。
TAG:标签,也是版本号,镜像会有不一样的版本号。
IMAGE ID:镜像id,根据这个id咱们能够区分不一样的镜像,也能够对某个镜像进行操做。
CREATED:建立时间。
SIZE:镜像的大小。
docker rmi 删除本地的镜像,加上一个参数-f表示强制删除,由于有时候如有运行的相关容器的时候是不能删除的,如:docker rmi -f nginx 强行中止容器并删除镜像,无论是否有占用状况。
docker search 根据镜像名称搜索远程仓库中的镜像,能够看一下查到全部相关名称的镜像,能够选择咱们要拉取哪一个镜像,下边是搜索nignx相关的镜像,红色部分ok 说明是官方镜像。
docker pull <镜像名称>:[标签名称]:拉取镜像,默认不写标签名称拉取最新的镜像。
docker push 推送镜像,当咱们制做了咱们本身的镜像时,咱们就能够推送到咱们本身的docker hub上去。
3.3.2 容器命令
有了镜像咱们就能够new一个镜像实例了,也就是咱们所说的容器。
docker run :基于某个镜像运行一个容器,若是本地有这个镜像就根据本地的镜像建立,若是没有,就去远程拉取一个镜像再建立,参数以下:
-d:启动一个容器,后台运行,不会占用咱们当前的控制台,通常都要加上,以前咱们启动nginx没有指定这个参数,就会占用当前控制台,会一直挂起,有了这个命令就不会占用了。
-i:以交互模式运行容器,一般会和-t一块儿来使用(-it)。
-t:为容器也建立一个命令行窗口,是容器内容的命令行窗口,好比咱们拉取一个ubuntu的镜像,咱们想要在这个操做系统镜像里边执行一些命令,那就须要这个参数了。
-P:这个是大写的P,指定宿主机的随机端口映射到容器内部的端口。
-p:这个是小写的p,指定某个具体端口映射到容器内部端口,好比前边咱们用-p 8080:80,就是让宿主机的8080端口映射到容器内的80端口,这样咱们就能够在外部用8080端口访问咱们容器内部的nginx了(默认容器必须有一个外部的映射端口,否则访问不了)。
-v:指定宿主机与容器内部的目录映射,就是以前的数据卷所须要的参数,好实现数据的持久化和同步。
--name="mynginx":为容器指定一个名称,若是没有指定,那就分配一个随机名称。
下面用参数重启启动咱们的nginx镜像:docker run -itd -p 8848:80 --name="mynginx" nginx
docker ps 显示正在运行的容器,加一个参数-a 能够看到中止中的容器
docker stop 中止容器 。
docker kill 强制中止容器。
docker restart 重启容器。
docker rm 删除容器,删除后容器就不在了,就不能重启和中止了。
docker inspect 查看容器的详细信息。
以上就是差很少咱们经常使用的命令,具体的其余更多的功能咱们能够查看官方文档 https://docs.docker.com/get-started/。
4、Dockerfile
上边都是咱们拉取别人的镜像,咱们实际上也能够制做本身的专属镜像,根据咱们的须要,配置好咱们本身的镜像来使用。Dockerfile就是用来构建咱们的镜像的文件,在里边能够写一些命令来构建咱们的镜像,构建好后发布到docker hub就能够供别人拉取使用了。
Dockerfile是一个没有后缀名的文本文件,咱们经过写入一些命令来实现镜像的构建。下面咱们先来看看Dockerfile是怎样来编写的。下边的命令标识形式<> 表明须要的参数,[ ] 是可选参数。
FROM:指定基础镜像,全部构建的镜像都必须有一个基础镜像,且FROM命令必须是Dockerfile的第一个命令。
FROM <image> [AS <name>] 指定从一个镜像构建 AS 起一个新的镜像名字。
FROM <image>[:<tag>] [AS <name>] 指定镜像的版本tag。
例如:FROM mysql:5.0 AS database
MAINTAINER:镜像维护人的信息。
MAINTAINER <name>
例如:MAINTAINER haha lsdjfl@163.com
RUN:构建镜像时要执行的命令。
RUN <command>
例如:RUN ["executable", "param1", "param2"] RUN ["dotnet restore","*.csproj"]
ADD:将本地的文件添加复制到容器中去,压缩包会解压,能够访问网络上的文件,会自动下载。
ADD <src> <dest>
例如:ADD *.csproj /app 添加csproj文件到容器中的app目录下。
COPY:功能和ADD同样,可是只是复制,不会解压或者下载文件。
CMD:启动容器后执行的命令,和RUN不同,RUN是在构建镜像是要运行的命令。当使用docker run运行容器的时候,这个能够在命令行被覆盖。
CMD ["executable", "param1", "param2"]
ENTRYPOINT:也是执行命令,和CMD同样,只是这个命令不会被命令行覆盖。
ENTRYPOINT ["executable", "param1", "param2"]
例如:ENTRYPOINT ["donnet", "myapp.dll"]
LABEL:为镜像添加元数据,key-value形式的。
LABEL <key>=<value> <key>=<value> <key>=<value> ....
例如:LABEL version="1.0" description="这是一个web应用"
ENV:设置环境变量,有些容器运行时会须要某些环境变量 好比:JAVA_HOME。
ENV <key> <value> 一次设置一个环境变量。
ENV <key>=<value> <key>=<value> <key>=<value> .... 设置多个环境变量。
例如:ENV JAVA_HOME /usr/java1.8/
EXPOSE:暴露对外的端口。
EXPOSE <port>
例如:EXPOSE 80
这里指的是容器内部程序的端口,虽然会和宿主机的同样,可是实际上是两个端口,容器运行时,须要用-p 映射外部端口才能访问到容器内的端口。
VOLUME:指定数据持久化的目录,官方语言叫作挂载。
VOLUME /var/log 指定容器中须要被挂载的目录,会把这个目录映射到宿主机的一个随机目录上,实现数据的持久化和同步。
VOLUME ["/var/log","/var/test".....] 指定容器中多个须要被挂载的目录,会把这些目录映射到宿主机的多个随机目录上,实现数据的持久化和同步。
VOLUME /var/data var/log 指定容器中的var/log目录挂载到宿主机上的/var/data目录,这种形式能够手动指定宿主机上的目录。
WORKDIR:设置工做目录,设置完工做目录以后 ,上边的RUN、CMD、COPY、ADD等的工做目录都变成这个了。
WORKDIR <path>
例如:WORKDIR /app/test
USER:指定运行命令时所使用的用户,为了安全和权限起见,有的用户可能权限高,有的用户可能权限低,根据要执行的命令选择不一样的用户。
USER <user>:[<group>]
例如:USER test
ARG:设置构建镜像是要传递的参数。
ARG <name>[=<value>]
例如:ARG name=sss
以上是差很少构建Dockerfile时所使用的命令的,构建时命令是从上到下顺序执行的,可能后边的命令须要前边命令的结果,使用 docker build 编译Dockerfile 就能够构建咱们的镜像了。
docker build 可使用参数 -f 指定Dockerfile的目录,默认是在当前目录下找;-t 指定构建的镜像的名称和标签,例如:docker build -f ./aa/bb -t myimage:1.0
5、构建咱们本身的镜像
有了上面的基础,咱们就能够构建咱们本身的镜像了,而后还能够上传到咱们本身的docker hub上供别人拉取使用。接下里咱们就来实现如下。这里参考了官方的构建步骤:https://docs.docker.com/engine/examples/dotnetcore/
5.1 建立一个mvc项目
首先找一个目录,建立一个文件夹DockerDemo,而后在该目录下执行命令dotnet new mvc,建立咱们的mvc程序,以下:
5.2 添加Dockerfile文件
咱们直接添加一个名称为Dockerfile的文件,而后输入一下命令:
#构建sdk镜像,是为了进行编译、发布咱们的web应用 FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env # 在容器中设置一个/app目录 WORKDIR /app # 复制csproj文件 到当前目录下(app目录下) 并执行dotnet restore 还原包 COPY *.csproj ./ RUN dotnet restore # 再复制其余剩余的文件到当前目录,执行发布命令,用Release模式 而且输出到out文件夹 COPY . ./ RUN dotnet publish -c Release -o out #构建运行时镜像 FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 # 设置运行时镜像一个/app目录 WORKDIR /app # 复制以前的镜像的产物中的 /app/out目录下的文件 到当前新镜像的 /app录下(当前目录) COPY --from=build-env /app/out . # 执行dotnet 命令,运行咱们的web应用 ENTRYPOINT ["dotnet", "DockerDemo.dll"]
我用vscode添加Dockerfile直接变成了一个鲸鱼的图标,说明是一个Docker文件,还有高亮:
5.3 构建Docker镜像
咱们直接把DockerDemo这个文件夹直接复制到虚拟机中,我复制到了Desktop下:
而后进入到DockerDemo目录下,直接执行命令 docker build -t dockerdemo . ,这句命令的意思是 使用当前目录下的Dockerfile构建镜像dockerdemo,注意构建的镜像名称必须为小写,不然会报错。
而后就是等待构建了,可能会比较慢, 若是想快的话,能够换成国内的镜像源,这里就不说了,由于我也懒得换。
此次构建过程会分为两步,由于有两个镜像,构建完成后,咱们使用docker images 查看,会发现有咱们新构建的镜像dockerdemo:
5.4 运行容器
接下来咱们输入命令 docker run -d -p 8848:80 --name myapp dockerdemo,运行一个容器,名称叫作myapp
使用docker ps 查看运行中的容器:
5.5 访问咱们的mvc程序
在虚拟机的浏览器中输入 http://localhost:8848,或者在你的电脑上输入虚拟机的地址来访问 http://192.168.226.130:8848/ (这个是个人地址),显示以下,表名成功:
6、发布镜像
咱们已经构建好了咱们的镜像,接下来咱们就把镜像推送到咱们本身的docker仓库中去,这一步和github是彻底同样的,就像把咱们的代码推送到github上同样。
6.1 建立帐号
首先,咱们须要建立一个dockerhub帐号,登陆https://hub.docker.com/,根据提示注册帐号,这一步就不细说了。
6.2 登陆
命令行输入docker login,输入咱们的帐号密码,进行登陆。
6.3 推送镜像
推送镜像以前,首先要标记咱们的镜像,也就是给咱们的镜像起一个名字,使用命令 docker tag <image> <username>/<repository>:<tag>,下边咱们就标记咱们刚才的dockerdemo的镜像:
使用命令 docker tag dockerdemo emmaccc/dockerdemo:1.0.0
查看咱们刚才标记过的镜像:
使用命令 docker push emmaccc/dockerdemo:1.0.0 推送镜像,等待一段时间后推送成功,就能够在本身dockerhub帐号上看见了
6.4 使用镜像
推送成功以后,咱们就能够在任意一台安装了docker的计算机上来拉取咱们镜像,直接run启动咱们的web应用了。
docker run -p 4396:80 emmaccc/dockerdemo:1.0.0,运行以后,无需担忧各类依赖、配置,也不用在你的新主机上安装任何东西,直接run运行就好了,这也docker独特的魅力所在。
6、总结
学习docker,前先后后看了好几遍,到底是个什么玩意啊,好半天才看懂,docker的基本使用就差很少了,接下来估计又是k8s了,唉,东西真多,感受全it界都在造轮子吧,非要搞这个搞那个,没办法,仍是得跟着大佬们走,若是你真的还不明白,那就送你一句话。
web放tomcat里,tomcat放docker里,docker放k8s里,k8s放操做系统上,绕了一大圈,扯淡呢,咋不直接web放操做系统上直接运行呢。