一看就懂-Docker容器化

网友投稿 240 2022-10-24

一看就懂-Docker容器化

作者:Flaming丶淡蓝

一、Docker简介

1.1 什么是docker

docker的英文意思是 码头工人,意思就是搬运东西的意思,其实这和docker的特点是一样的,docker提供的就是一种容器化搬运东西(我们的软件、程序)的过程。docker自己本来是运行在操作系统上一个程序软件,它会提供一个容器环境,使我们的程序独立地运行在容器中,所以说,官方给docker起的这个名字也真是应景。

就连图标也是这么生动形象,富有诗意,让人浮想联翩。。。。(这是去幼儿园的车,还没有拐进大学城)

试想下边这样一个场景:当我们把我们的web网站做成分布式的时候,我们就要加服务器,然后在各个服务器配置web所需要的配置,比如:数据库、web服务器、运行时啥,这样的我们的网站才能跑起来,但是每当我们加服务器的时候,我们都要再重新配置一下,很繁琐,有了docker,我们就可以把我们的网站和所需要的环境配置好,打成一个包(docker镜像),然后在服务器上安装docker,用docker拉取打包好的镜像,直接run(容器)起来就行了,什么都不用管了,很方便,更加的便于管理,镜像中修改配置,重新更新,所有的容器就也能修改了,我们的网站也就修改更新了,特别的方便。

1.2 docker的特点

docker的特点包含在它的口号中

第一句,是“Build, Ship and Run”。(搭建、运输、运行)

第二句,“Build once,Run anywhere(一次搭建,到处运行)”。

1.3 docker和虚拟机

一说到docker,相信大家之前也了解过,那就必须要和虚拟机做一下比较,其实docker是和虚拟机是类似的东西,我们应该知道虚拟机就是在我们的操作系统上虚拟出来一个电脑,然后里边可以安装、运行各种各样的软件,和我们真的电脑是差不多的,我们可以拿着这个虚拟好的电脑(其实是一个文件)在按了虚拟机的其他电脑上可以直接运行,里边的东西就不用我们来回安装和配置了,也是很方便的。

docker其实提供的也是这么一种的技术,只不过它比虚拟机效率更加的高,启动快,占用资源小等一系列的优点,而且虚拟机比较笨重,这是因为虚拟机和docker来实现思想上有本质的区别,我们可以通过下边的两张图可以对比一下:

虚拟机的运作原理:是虚拟电脑的硬件资源,把硬件资源分配出来,然后虚拟出来多个操作系统,虚拟出来的是一个完整的电脑。

docker的运作原理:虚拟的软件资源,把电脑中的网络、存储啥的分成几份虚拟成容器,我们的软件运行在容器中,每个容易只占用电脑的部分所需要的资源,并不是一个完整的电脑。

大概就像上边那么理解吧,反正也不知道是对不对,但是看起来应该不错。

所以,从运作原理上来看,docker更加的轻量级,虚拟机更加的笨重,docker启动也十分的快,部署起来也方便,所以越来越多的人开始使用docker起来。

下边是一张虚拟机和docker的对比,这里要注意一下:但是docker本身并不是容器,而是创建容器的工具;而虚拟机它就是虚拟机了。

二、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这个网站了(存放docker镜像的官方仓库,好多官方的也保存在这里,保证了镜像的安全性和可靠性,我们可以从上边拉取一下镜像来运行我们的软件。当然我们也可以制作好我们自己镜像推送上去,不过这些肯定是要官方审核的,防止有些人写入一些恶意代码。不过我们可以推到我们自己的dockerhub上去,供我们自己使用,这个就好我们的github账号一样了,属于私有镜像了。

2.4 数据卷(Volumn)

实际上我们的容器就好像是一个简易版的操作系统,只不过系统中只安装了我们的程序运行所需要的环境,前边说到我们的容器是new出来的实例,既然是new出来的实例那就会销毁,那如果销毁了我们的程序产生出的需要持久化的数据怎么办呢,容器运行的时候我们可以进容器去查看,容器一旦销毁就什么都没有了。所以数据卷就是来解决这个问题的,是用来做数据持久化到我们的宿主机上容器间的数据共享,简单的说就是将宿主机的目录映射到容器中的目录,应用程序在容器中的目录读写数据会同步到宿主机上,这样容器产生的数据就可以持久化了,比如我们的数据库容器,就可以把数据存到我们宿主机上的真实磁盘上了。

docker中基本的概念已经说了,下面我们就可以来使用docker了。

三、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 查看容器的详细信息。

以上就是差不多我们常用的命令,具体的其他更多的功能我们可以查看官方文档 hub就可以供别人拉取使用了。

Dockerfile是一个没有后缀名的文本文件,我们通过写入一些命令来实现镜像的构建。下面我们先来看看Dockerfile是怎样来编写的。下边的命令标识形式<> 代表需要的参数,[ ] 是可选参数。

FROM:指定基础镜像,所有构建的镜像都必须有一个基础镜像,且FROM命令必须是Dockerfile的第一个命令。

FROM [AS ]   指定从一个镜像构建 AS 起一个新的镜像名字。

FROM [:] [AS ]  指定镜像的版本tag。

例如:FROM mysql:5.0  AS database

MAINTAINER:镜像维护人的信息。

MAINTAINER 

例如:MAINTAINER  haha  lsdjfl@163.com

RUN:构建镜像时要执行的命令。

RUN

例如:RUN ["executable", "param1", "param2"]    RUN ["dotnet restore","*.csproj"]

ADD:将本地的文件添加复制到容器中去,压缩包会解压,可以访问网络上的文件,会自动下载。

ADD  

例如: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 =  =  =  ....

例如:LABEL version="1.0"  description="这是一个web应用"

ENV:设置环境变量,有些容器运行时会需要某些环境变量 比如:JAVA_HOME。

ENV       一次设置一个环境变量。

ENV  =  =  =  ....  设置多个环境变量。

例如:ENV  JAVA_HOME  /usr/java1.8/

EXPOSE:暴露对外的端口。

EXPOSE

例如: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

例如:WORKDIR  /app/test

USER:指定运行命令时所使用的用户,为了安全和权限起见,有的用户可能权限高,有的用户可能权限低,根据要执行的命令选择不同的用户。

USER  :[]

例如:USER  test

ARG:设置构建镜像是要传递的参数。

ARG  [=]

例如:ARG  name=sss

以上是差不多构建Dockerfile时所使用的命令的,构建时命令是从上到下顺序执行的,可能后边的命令需要前边命令的结果,使用 docker build 编译Dockerfile 就可以构建我们的镜像了。

docker build 可以使用参数 -f 指定Dockerfile的目录,默认是在当前目录下找;-t 指定构建的镜像的名称和标签,例如:docker build -f  ./aa/bb -t myimage:1.0

五、构建我们自己的镜像

有了上面的基础,我们就可以构建我们自己的镜像了,然后还可以上传到我们自己的docker hub上供别人拉取使用。接下里我们就来实现以下。这里参考了官方的构建步骤:创建一个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程序

在虚拟机的浏览器中输入 创建账号

首先,我们需要创建一个dockerhub账号,登录登录

命令行输入docker login,输入我们的账号密码,进行登录。

6.3 推送镜像

推送镜像之前,首先要标记我们的镜像,也就是给我们的镜像起一个名字,使用命令 docker 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独特的魅力所在。

六、总结

学习docker,前前后后看了好几遍,究竟是个什么玩意啊,好半天才看懂,docker的基本使用就差不多了,接下来估计又是k8s了,唉,东西真多,感觉全it界都在造轮子吧,非要搞这个搞那个,没办法,还是得跟着大佬们走,如果你真的还不明白,那就送你一句话。

web放tomcat里,tomcat放docker里,docker放k8s里,k8s放操作系统上,绕了一大圈,扯淡呢,咋不直接web放操作系统上直接运行呢。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:采用OCP线程协议的总线接口实现3D图形的构建模块方案
下一篇:skywalking源码解析javaAgent工具ByteBuddy应用
相关文章

 发表评论

暂时没有评论,来抢沙发吧~