(一)定义与介绍

前言:与虚拟机技术比较:

  • 虚拟机(VM):在docker容器技术出现之前使用的是虚拟机技术,将一台物理机虚拟化为多台机器,可搭载不同的操作系统。但每一个虚拟机系统的消耗较大,都需安装一个完整的内核,存储空间占用也多。且系统镜像也不支持版本控制。

  • Docker容器技术:docker的一大特点就是简单轻便,物理机(宿主机)只需要安装docker环境,拉取image镜像,则可以通过该镜像创建一个或多个系统实例(Docker称为容器,容器间相互隔离互不影响),且image镜像与虚拟机的系统镜像相比十分小。除此之外,镜像支持版本控制,Docker可以将容器进行commit提交形成一个新的镜像,可push到远端仓库,私人备份或公有到image仓库中。对于项目开发而言,idea可以配置dockerfile实现Java项目的自动化部署。

4大概念:容器(Container),镜像(Images),仓库(Repository),宿主机(物理机)

  • 仓库Repository:可指定配置源,是镜像存储的地方,可从此处拉取镜像(pull),或者将本地的镜像进行提交(push)

  • 镜像Image:系统或环境的镜像文件,可由其创建并运行(run)出容器实例(container)。镜像可从仓库拉取(pull)获得,或者从现有容器commit提交得到一份新的镜像Image

  • 容器Container:由镜像创建的容器实例,初始状态下各个容器实例环境相同,互不影响。容器分为两个状态:运行和停止

  • 宿主机(物理机):即就是运行docker环境的这台物理机

从公有仓库拉取的镜像可以进行自定义化,然后发布到公有仓库,或是自己的私有仓库上。

同一份镜像可以产生多个容器(实例),且这些容器初始环境完全相同,且互不影响,相互隔离(文件,ip等,进程)

(二)Docker环境配置

镜像源指定:为了下载更快,可指定为阿里云(将会影响docker search的结果和docker pull的速度)

阿里源Docker服务网站:阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台

"registry-mirrors": [

"https://8rzbqaxd.mirror.aliyuncs.com"

],

  • Windows下直接安装Docker Desktop即可

注意:

由于win10新版本提供了wsl2版的Linux,即Windows自带一个Linux内核,若Docker开启了wsl2的支持,则高级配置不会展示出:CPU,内存,磁盘,容器磁盘镜像目录等配置项。

Resources-Advance选项卡指定容器的配置,以及生成容器Container的磁盘镜像位置vhdx

Resources-File Sharing选项卡指定共享文件夹,即将宿主机(物理机)的某些目录用来挂载到容器中,可供容器使用

在Windows下的docker提供了两种container模式,可通过右键进行切换:但优先选择LinuxContainer

  1. LinuxContainer:可运行基于Linux内核和Windows内核的容器(运用Hyper-V技术)

  2. WindowsConainer:仅可运行基于Windows内核的容器

Image镜像的下载目录在windows平台下不方便配置,因为在LinuxContainer模式下,镜像Image文件都是下载到一个虚拟的Linux目录中的(通过docker info命令可查),若为WindowsContainer模式,则可以配置。

  • Linux Ubuntu(18.04)下:

#若存在老版本先卸载之前的sudo apt-get remove docker docker-engine docker.io containerd runc#更新源sudo apt-get update#安装curl工具sudo apt-get install curl#添加docker的GPG密钥curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -#验证密钥sudo apt-key fingerprint 0EBFCD88#安装添加源工具sudo apt install software-properties-common#指定仓库sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"#再次更新源sudo apt-get update#安装docker-ce(社区版),cli客户端,以及解耦apisudo apt-get install docker-ce docker-ce-cli containerd.io

验证docker环境:

docker -v

#或者

systemctl status docker

Ubuntu版的docker配置:

全局配置文件在:/etc/default/docker

sudo vim /etc/default/docker

修改镜像下载目录与修改容器磁盘镜像文件目录

默认配置可以通过docker info命令查看

该文件夹包含了下载的image和container文件夹

若需要修改,则要修改:/etc/systemd/system/multi-user.target.wants/docker.service文件

sudo vim /etc/systemd/system/multi-user.target.wants/docker.service

修改为其他位置即可

配置阿里源:创建/etc/docker/daemon.json,并写入以下内容:然后重启服务systemctl restart docker

{

"registry-mirrors": [

"https://8rzbqaxd.mirror.aliyuncs.com"

]

}

(三)基本Docker命令

  • 镜像Images相关 (镜像名要求全小写)【一般为docker image xxx】

#获取当前所配置的源下,与输入的关键字相关的可提供下载的镜像(存放在远端的仓库)

docker search <关键字>

#按版本筛选(加标签)

docker search <关键字>:<tag>

例:docker search centos,docker search ubuntu:18.04

其中offical代表官方,automated代表自动构建产生的镜像

注意:官方镜像系统内容很少,有时缺少基本工具,如:ifconfig,ping,sudo之类,需要运行容器后自己安装

#拉取镜像

docker image pull <imageName/imageID>

#拉取镜像(指定版本),需到其官网查看他在docker hub上该版本的tag

docker image pull <imageName>:<tag>

#将镜像推送到远端仓库(imageName要求包含远端仓库地址)

docker image push <imageName>:<tag>

#查看所有已有的镜像

docker image ls

#创建容器并运行(最基础的)(可指定tag)

docker run --name <newContainerName> <imageName>:<tag>

#删除已有镜像(tag不为latest时,需要指定tag)【确保无本镜像创建的container】

docker image rm <imageName>

#镜像重命名

#此时会生成一个id相同的新镜像,手动删除之前不要的即可(可指定tag)

docker image tag <imageName> <newImageName>

#查看镜像详细信息(可指定tag)

docker image inspect <imageName>

  • 容器Container相关【一般为docker container xxx】

#查看容器列表(正在运行的)

docker container ls

#查看容器列表(所有的)

docker container ls -a

#运行已存在的容器

docker container start <containerName>

#停止某个运行的容器

docker container stop <containerName>

#重启某个容器

docker container restart <containerName>

#删除某个容器(确保该容器已停止运行)

docker container rm <containerName>

#容器重命名

docker container rename <containerName> <newName>

#进入某一正在运行容器(终端模式)

docker container exec -it <containerName> /bin/bash

#退出某容器(在容器终端中执行)

exit

#查看容器的占用情况(实时占用情况[CPU,RAM,NET])

docker container stats <containerName>

#查看某容器的详细信息(端口映射,磁盘映射,虚拟网段IP,维护者等等)

docker container inspect <containerName>

(四)容器的网络/存储隔离以及共享目录的配置

以下操作与image镜像本身无关,都是在执行run命令时配置(run配置参数只跟container实例,与image镜像无关)

  • 网络隔离(下能通上,上不通下【与路由器以路由方式嵌套理解相同】)

容器间网络互通(不管是不是由同一镜像产生的容器实例),因为他们在同一个虚拟网段下(默认在172.17.0.1),且这些容器都可以ping通宿主机(物理机)也可以通过物理机连接互联网(因为访问上层网络没有问题),但对于宿主机来说,其无法直接访问(ping通)任何一个容器,因为虚拟网段是模拟出来的,他是宿主机所在的下一级网段,没办法直接访问。

【这点和路由器之间以路由模式相接相同,假如192.168.1.1为一个路由,192.168.1.2为子路由,他的网关地址为192.168.123.1,其存在2个主机:192.168.123.2与192.168.123.3,此处通过192.168.1.x的主机直接直接访问192.168.123.x不可能访问成功,因为路由访问只能访问同级和上级的网络,只能访问192.168.123.x所属的上层网络ip:192.168.1.2,由该路由器配置DMZ/端口映射到其子层网络】

查看容器所在网段配置(类似于172.17.0.X)

docker network inspect bridge

【解决方案:对容器开启端口映射】

因此为了能让宿主机能访问【必然如此,不然在容器里运行的服务暴露不出来】,docker在执行run命令的时候提供了可配置的参数

#指定单个端口

docker run -dit --name <想取的容器名> -p <宿主机端口>:<容器内服务端口> <镜像名>

#指定多个端口

docker run -dit --name <想取的容器名> -p <宿主机端口>:<容器内服务端口> -p <宿主机端口>:<容器内服务端口> <镜像名>

注意:

  1. 只能在首次创建容器运行时(docker run命令)候指定端口映射,已有的容器无法添加

  2. 指定端口映射创建出来的容器container以后就直接启动,无需再次指定端口,只需确保宿主机端口未被占用即可开启

  3. 若实在要对已有容器container添加/修改端口映射,只能将当前容器提交commit为一个新的镜像,然后再用该镜像run一个新的容器(此时指定端口映射)

docker container commit <containerName> <newImageName>

  • 存储隔离

Docker容器Container实例之间的存储是相互隔离,互不影响的,容器Container产生的文件叫做磁盘镜像文件(DiskImage)这点和虚拟机相同,他的位置根据之前在DiskImageLocation目录:vhdx文件大小上限可以配置。默认64GB,所有容器Container实例的数据都存在这一个磁盘镜像文件中

  • 共享目录配置

Docker容器可共享使用宿主机(物理机)中的某一文件目录,该文件目录需要事先配置为共享文件夹,然后在首次创建并运行容器时追加-v参数进行指定(与端口映射相同,只能在这个时机指定)

[Windows指定共享目录]

(本步骤是对windows文件夹的权限指定,即让docker拥有以下文件夹权限)

[Linux(Ubuntu)指定共享目录]

无需额外配置,只需在docker run时指定-v参数即可

【磁盘映射参数(也可指定多个)】

#-v <宿主机目录>:<容器环境需要挂载的地方>

#例

docker run -dit --name testMultiFolderMapping -v E:/DockerShareFolder:/mnt/folder1 -v E:/Share:/mnt/folder2  ercircle/ubuntu_server

  • 超级权限(一般不需要)

在首次创建并运行run容器container实例时,添加以下参数:--privileged=true可以配置容器内环境具备超级管理员的权限。甚至允许在容器中再次搭建docker

--privileged=true

#例

docker run -dit --name Test --privileged=true ercircle/ubuntu_server

  • 指定时区(可安装后提交为镜像,以后直接使用这个镜像)

容器时间默认和宿主机相同,但时区使用的是UTC+0即太平洋时区,要改为东八区,由于docker容器的权限有限,需要安装tzdata来调整

sudo apt-get install tzdata

  • 配置某一容器自动启动

可以在首次docker run时追加参数,也可以对已有的container进行设置

#首次运行时指定该容器实例自启

docker run --restart=always

#对已有的容器设置为自启

docker update --restart=always <CONTAINER ID>

(五)修改Docker镜像并push至库

核心概念:

  • 镜像的仓库没有版本控制,每一次提交都是一个新的镜像,新的镜像和之前没有关系(imageName相同,tag不同也算是不同的image)

  • 镜像Image本身不可修改,所谓的修改是对其生成的容器Container实例进行操作后,提交commit后为一个新的镜像

提交Commit命令:

#对于某镜像的容器实例修改后提交为一个新的镜像(镜像名可与之前的相同(但此时必须指定tag【一般设置为版本号】))

docker container commit -m "本次提交内容" -a "作者信息" <containerName> <newImageName>:<可指定tag(代表版本)>

配置阿里云镜像管理服务:

将自己的镜像push到阿里云镜像管理服务中(自己的远端镜像仓库)

官网:阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台

(1)准备工作:配置账户密码,创建命令空间,确定好地域节点名

(2)创建命名空间,创建镜像仓库(使用本地仓库模式)

(3)执行docker命令登录到目标节点:

docker login --username=五航战瑞鹤酱 registry.cn-shanghai.aliyuncs.com

(4)列出本地镜像,确定要提交的镜像id或者名字,执行tag操作修改image名

Tag后原image不影响,依然存在,会产生一个imageId相同,imageName为新设置的镜像,新设置的镜像name需要指定为固定格式:地域节点/com/命名空间/镜像仓库名:,tag一般指定为版本号

docker tag [ImageId] registry.cn-shanghai.aliyuncs.com/zuikaku/pilipili-web-ubuntu:1.0

(5)执行提交push操作

docker push registry.cn-shanghai.aliyuncs.com/zuikaku/pilipili-web-ubuntu:1.0

push完成后,在镜像版本中可以看到这次push的记录,未指定tag,则默认为latest(最新的)

如果后续需要拉取,则到基本信息中:执行docker pull

docker pull registry.cn-shanghai.aliyuncs.com/zuikaku/init-ubuntu:<镜像版本号>

(六)在项目中使用dockerfile实现自动化部署

[1]修改docker.service

Ubuntu版的docker目录在:/etc/systemd/system/multi-user.target.wants/docker.service

ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock

修改完后重新应用

systemctl daemon-reload systemctl restart docker

访问2375端口进行验证

[2]项目中配置docker

  • pom.xml添加docker的maven插件依赖

<!--使用docker-maven-plugin插件--><plugin><groupId>com.spotify</groupId><artifactId>docker-maven-plugin</artifactId><version>1.0.0</version><configuration><!--指定生成的镜像名--><imageName>nanoda/${project.artifactId}</imageName><!--指定标签(一般为版本)--><imageTags><imageTag>1.2</imageTag></imageTags><!-- 指定 Dockerfile 路径:项目根目录--><dockerDirectory>${project.basedir}</dockerDirectory><!--指定远程 docker api地址--><dockerHost>http://www.zuikakuedu.top:2375</dockerHost></configuration></plugin>
  • 项目根目录添加Dockerfile文件

Dockerfile的组成成分:

#指定以哪个image作为初始镜像(此处可指定为公有仓库链接)【推荐先在宿主机把该image事先pull下来,避免docker build时因权限不足的报错】

FROM <镜像远端地址>

#指定该镜像的维护者信息

MAINTAINER <维护者姓名> <联系邮箱(可选)>

#添加哪些文件到目标镜像的目录(一般添加jar包,为tar时会自动解压,镜像环境的目录不存在时会自动创建)

ADD <以项目目录根目录下的文件或目录(相对路径)> <镜像环境的目标目录(绝对路径)>

#指定需要在目标镜像产生的容器中执行的初始化操作(可按顺序指定多条)

RUN <Linux命令1>

RUN <Linux命令2>

#指定需要暴露的端口(仅声明要暴露的端口,方便-P自动映射,手动映射依然需要在run时指定-p参数)

EXPOSE <端口1> <端口2>

#指定挂载点,自动实现路径映射,宿主机地址为随机生成(可通过docker container inspect查看,若要手动指定需要run时指定-v参数)

VOLUME ["/mnt/folder1","/mnt/folder2"]

#指定环境,如JDK,Tomcat目录,编码环境等

ENV LANG C.UTF-8

#指定容器创建完成的运行的命令,容器从关闭状态变为启动后执行的命令(一般用于启动某程序,或者执行某shell)

ENTRYPOINT ["Linux命令","参数1","参数2",...]

案例:

FROM registry.cn-shanghai.aliyuncs.com/zuikaku/ubuntu1804-init-env:1.0

MAINTAINER  nanoda tanyu159@live.com

ADD target/oc-0.0.1-SNAPSHOT.jar /home/admin/ZuikakuOnlineCourse/oc.jar

RUN mkdir /home/admin/ZuikakuOnlineCourse/storage

EXPOSE 9091

ENV LANG C.UTF-8

ENTRYPOINT ["nohup","java","-jar","/home/admin/ZuikakuOnlineCourse/oc.jar",">log.txt","&"]

【3】先执行项目package打包

Maven-Package执行打包生成target,确认jar包存在

【4】再执行docker build操作(如果需要重新build,需先进行maven-clean重新打包在docker build,清除docker的一些临时文件)

【5】回到宿主机docker run该新镜像

docker run -dit --name zuikaku-oc -p 9091:9091 -v /home/admin/ZuikakuOnlineCourse/storage/:/home/admin/ZuikakuOnlineCourse/storage nanoda/oc:1.1

特别注意:

可以发现,在进行docker自动化部署,开启2375端口,在项目中指定目标地址:端口,直接执行docker build命令是没有任何身份验证的,这也就说明存在漏洞,黑客可以扫描公网ip及其该端口注入内容,因此2375端口不应在公网开启,仅在局域网内访问,应该挂入vpn或者使用堡垒机的方式进行网络连接,实现docker build

(7)docker可视化管理工具portainer

portainer提供了一种可视化管理docker的方式,本质是一个网页后台,其本身也是作为docker的image存在,使用流程如下:

【1】搜索该镜像:docker search portainer

【2】拉取该镜像:docker image pull portainer/portainer

【3】运行该镜像:需指定端口映射,容器内端口为9000,并开启超级权限和目录映射

docker run -d --name portainerUI -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer

【4】放开防火墙,在外网访问该服务

更多教程,可见我的官方网站:最咔酷线上教程:www.zuikakuedu.cn

一篇文章上手docker(原理,部署,使用,坑)相关推荐

  1. 看菜鸟如何用一篇文章学Docker(超详细)

    文章目录 Docker镜像加载原理 Docker常用的命令 关于容器命令 其他常用命令 进入当前正在运行的容器 docker容器文件移动复制 docker 安装测试命令 commit镜像 安装可视化工 ...

  2. 一篇文章理解Promise原理

    前提掌握知识: 微任务包括: MutationObserver.Promise.then()或reject().Promise为基础开发的其它技术,比如fetch API.V8的垃圾回收过程.Node ...

  3. 一篇文章上手SSH开发,单表全过程,全代码

    1 SSH项目的一些部署 1.1 项目目标与版本介绍 1.2 SSH知识分析 2 SSH项目 2.0 项目的前期部署 2.1 创建项目 2.2 前端的一些jsp 2.3 web.xml 2.4 实体类 ...

  4. 一篇文章了解保偏光纤原理、快慢轴、保偏拍长、消光比

    什么是保偏(PM)光纤? 从理论上来说,光纤是圆芯的应该不会产生双折射,并且光纤的偏振态在传播过程中是不会改变的.然而,在实际中,常规光纤在生产过程中,会受到外力作用等原因,使光纤粗细不均匀或弯曲等, ...

  5. 如何优雅的在 vue 中使用 非响应式对象_一篇文章上手Vue3中新增的API

    1. 初始化项目 // ① npm i -g @vue/cli // ② vue create my-project // ③ npm install @vue/composition-api -S/ ...

  6. [ATF]-MTK:一篇文章了解ATF原理

    关键词: Non-cacheable,Cacheable, non-shareable,inner-shareable,outer-shareable, optee.ATF.TF-A.Trustzon ...

  7. 一篇文章理解vuex原理

    vuex作用: 组件的通信成本很高,所以为了简化组件间通信(共享数据),vue提供了vuex插件.是基于flux思想实现的. flux 是由react团队提供的数据通信架构思想.解决网状通信的问题.实 ...

  8. 使用Docker快速部署Gitlab

    目录 什么是Docker Linux安装Docker Win10安装Docker 使用Docker安装Gitlab 使用阿里的镜像加速 安装Gitlab镜像 运行gitlab镜像 配置Docker 提 ...

  9. c++ socket线程池原理_一篇文章看懂 ThreadLocal 原理,内存泄露,缺点以及线程池复用的值传递问题...

    编辑:业余草来源:https://www.xttblog.com/?p=4946 一篇文章看懂 ThreadLocal 原理,内存泄露,缺点以及线程池复用的值传递问题. ThreadLocal 相信不 ...

最新文章

  1. Excel VBA两两个体距离矩阵转化为数据库格式
  2. mysql的还原_MySQL 还原
  3. centos 7 minimal connect: Network is unreachable和ifconfig command not found
  4. 由浅到深理解ROS(3)-命名空间
  5. linux登录指令 pgsql_命令行方式登录PostgreSQL
  6. ylbtech-LanguageSamples-Struct(结构)
  7. 未来已来?揭开量子计算机的神秘面纱
  8. bzoj 1681: [Usaco2005 Mar]Checking an Alibi 不在场的证明(BFS)
  9. 第三节: 串口通信(用CubeMX学习STM32)
  10. java线程视频教程_java线程视频教程
  11. 三年探索:一条自控、电信/科类学生的技术成长路线
  12. c语言输入abc求方程的根,编写程序,输入系数abc,计算任意二次方根的实根
  13. 运动想象EEG背景知识
  14. “京东红”托起“松石绿” 湖北十堰让世界发现中国珠宝之美
  15. redhat 7 手册
  16. Unity3D学习:飞碟游戏进化版
  17. 文化产业如何面对大数据时代
  18. 2020.7.25T2魔道研究(jz暑假训练day10)
  19. Citrix虚拟化技术之五XenServer6.2资源池配置
  20. 刚认识的,推荐赚钱能力超级硬核的美女、大佬的公众号!

热门文章

  1. A. Arithmetic Array
  2. 17位时间戳转换为Unix时间戳及转换工具,代码实现转换 WebKit/Chrome Timestamp Converter
  3. kindle paperwhite3 android,Kindle Paperwhite3入手20天感受
  4. 手机计算机数字游戏怎么玩,计算器游戏攻略
  5. 从突变到新抗原:肿瘤与免疫系统之间的一场豪赌!
  6. 通用AI元素识别在UI自动化测试的最佳实践
  7. android 设置打印级别
  8. C++解决猜大小问题
  9. HyperLynx(十六)PCI-E的设计与仿真
  10. JAVA删除pdf空白页_如何从iText中的PDF中删除空白页面