Docker应用,从0到0.8

目录

一,Docker简介 

1,没有Docker时带来的问题:

2,有了Docker之后

3,Docker架构

Client

Docker daemon

Images(类似java的类)

Containers(类似java的对象)

Registry

二、Docker安装

1,安装须知

 2,安装Docker

三,Docker命令

1,Docker管理命令

2,镜像命令

 3,容器命令

四,Docker数据的持久化——数据卷

1,添加容器卷

 2,测试宿主机和容器之间数据实时共享

五,安装示例

1,总体安装步骤

2,安装tomcat

3,安装mysql

六,DockerFile

1,简要介绍

2,构建步骤

3,使用Dockerfile文件构建vim+ifconfig+jdk11的ubuntu镜像

七,Docker网络

1,网络相关命令

 2,网络模式

(1)bridge模式

(2)host模式

 (3)none模式

 (4)container模式

 (5)自定义网络

八,本地镜像发布到库

1,发布到阿里云镜像仓库

2,发布到私有镜像库

九,compose容器编排

1,简要介绍

2,安装

3,使用Docker compose构建一个包含微服务、Redis、mysql容器的项目

 十,容器监控


一,Docker简介 

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。--百度百科

Docker 是一个用于开发、发布和运行应用程序的开放平台。Docker 使您能够将应用程序与基础架构分离,以便快速交付软件。借助 Docker,您可以像管理应用程序一样管理基础架构。通过利用 Docker 的快速发布、测试和部署代码的方法,您可以显著减少编写代码和在生产环境中运行代码之间的延迟。--Docker官网

1,没有Docker时带来的问题:

一般情况下,在软件生产的过程中会同时部署多个环境:开发环境、测试环境、生产环境,而且除了在服务端的开发环境外,开发人员往往会在个人电脑部署一套单机的开发环境,导致同一个环境多次重复部署;

同时,一个中大型系统往往会有很多微服务、中间件、数据库等组件,导致每次部署一套环境都需要将所有组件安装一遍,回想一下安装一个单机版的mysql数据库需要经历多少步骤和花费多少时间,而生产中基本都要集群部署;

想一想开发人员和测试人员的那番扯皮的对话“在我这没问题啊”,除了一套环境就要重新部署一次整个系统之外,还有环境配置的问题,不同机器的环境配置可能不一样,这就导致了同一套代码能够在此处运行,但不能到彼处运行。

总之,原始搭建环境的方法,费时、费力、易出错、扩缩难

2,有了Docker之后

正如Docker官方所说:“Accelerate how you build, share, and run modern applications.”Docker加速构建、分享、运行现代的应用。Docker将组件比如mysql、redis、自己的微服务等封装、分发、部署、运行等全生命周期进行管理,使所有的组件一次打包成镜之后,在任何地方,只需要一个命令Docker run便实现了下载软件、安装软件、运行软件的功能,这个过程是非常快的(当然下载需要网络)。

Docker 提供了在松散隔离的环境中(称为容器)打包和运行应用程序的能力。隔离和安全性允许您在给定主机上同时运行多个容器。容器是轻量级的,包含运行应用程序所需的一切,因此您不需要依赖主机上当前安装的内容。您可以在工作时轻松共享容器,并确保与您共享的每个人都获得以相同方式工作的相同容器。

Docker 提供了一个工具和平台来管理容器的生命周期:

  • 使用容器开发应用程序及其支持组件。
  • 容器成为分发和测试应用程序的单元
  • 准备就绪后,将应用程序作为容器或编排服务部署到生产环境中。无论您的生产环境是本地数据中心、云提供商还是两者的混合体,其工作原理都是一样的。

所以,有了Docker之后,

(1)快速、一致的交付应用程序

开发人员在本地编写代码,并通过Docker容器与其他开发人员共享开发;开发完成之后使用Docker将程序部署到测试环境,当测试bug之后,开发人员在开发环境修复并从重新部署到测试环境,测试完成之后,将镜像部署到生产环境——整个事件的传递都是通过 镜像!

(2)响应式部署和扩展

Docker可以运行在个人电脑、物理机、虚拟机、云主机等,因为搞可移植性和轻量级特性使动态管理工作负载变得容易,近乎实时的扩缩容应用和服务。

(3)在同一硬件上运行多个负载,适合高密度环境iji需要用更少的资源做更多事情的中小型部署。

容器内的应用进程直接运行于宿主机的内核,容器内没有自己的内核且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

 每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。

Docker实质上是在已经运行的Linux上制造一个隔离的文件系统,所以它的执行效率几乎等同于所部署的Linux主机。

Docker官网https://www.docker.com/Dockerj镜像仓库https://hub.docker.com/

3,Docker架构

Docker使CS架构。从该图可以看出,如果用户在Client执行了docker run命令,如果Docker主机本地没有镜像,Docker会将其从配置的注册表中拉去(相当于执行了docker pull),如果本地有镜像,Docker将根据该镜像创建一个容器。

Docker应用,从0到0.8_第1张图片

Client

用户于Docker服务交互的方式,客户端连接Docker主机的守护进程,将用户输入的命令发送到Docker守护进程。

Docker daemon

Docker 守护进程 侦听 Docker API 请求并管理 Docker 对象,如镜像、容器、网络和卷。守护程序还可以与其他守护程序通信以管理 Docker 服务。

 此外,Docker拥有三架马车,镜像、容器、仓库:

Images(类似java的类)

镜像是一个轻量级、可执行的独立软件包,包含运行某个软件所需要的全部内容。

将应用程序和配置依赖打包成一个可交付的运行环境(包括代码、运行时所需要的库、环境变量、配置文件等),打包好形成的文件是镜像文件

镜像是一个只读模板,创建容器的模板,具有创建Docker容器的说明,告诉Docker怎么创建Docker容器,一个镜像可以创建多个容器。

只有通过镜像文件才能生成Docker容器实例

通常,一个镜像基于另一个镜像,并带有一个额外的定制。比如构建一个基于centos的镜像(基础镜像,最原始的centos镜像是能运行的最小、最内核的,没有vim编辑功能、没有网络ifconfig其他内容)并附加vim编辑器的功能。

镜像是分层的是由一层一层的文件系统组成(这种层级的文件系统叫UnionFS), 最原始的centos是一层,在其上添加vim编辑器之后便在其上添加了一层,现在的带有vim编辑功能的centos就有两层了。

Docker镜像分层,支持同构扩展现有镜像,创建一个新的镜像,类似于java继承一个基类,自己在按需扩展一个子类。

新镜像是从基础镜像一层一层叠加生成的,每安装一个软件,就在现有镜像的基础上增加一层。

联合文件系统(UnionFs)

  • 概念

一种分层的、轻量级并且高性能的文件系统,支持对文件系统的一次修改作为一次提交,一层一层的叠加文件系统。

  • 特点

是Docker镜像的基础,使镜像分层的,可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体应用镜像,每添加一个功能便在基础镜像的基础上添加了一层。

在加载时,一次同时加载多个文件系统,但从外表看来只有一个文件系统,加载时会将各层文件系统叠加起来。

  • 好处

高复用。当多个镜像都来自于同一个基础镜像时,Docker主机只需要在磁盘上保存一份基础镜像,内存中只需要加载一份基础镜像,即可被所有容器服务了。

Containers(类似java的对象)

容器是对象的可以运行实例,由Docker通过镜像创建而来。默认情况下,容器之间相互隔离。

容器就像一个简易版的Linux环境和运行在其中的应用程序。使用操作Linux的方式操作容器,在容器中运行的应用程序就如同在Linux中安装了一个应用软件。

Registry

存储Docker镜像,Docker hub是最大的公共Registry,默认情况下Docker配置在Docker hub上查找镜像,可自行配置镜像来源,比如阿里云。

集中存放镜像文件的场所。类似于Maven仓库存放jar包,github仓库存放git项目。

Docker官网提供的仓库叫Docker Hub。

国内有阿里云等镜像仓库可供我们使用。

这些都叫公开仓库,当然我们可以自己构建自己的或公司内部的仓库,叫私有仓库。

二、Docker安装

1,安装须知

(1)Docker Engine依赖于已存在并运行的LInux内核环境,Docker Engine必须不是在Linux内核系统上。

在CentOS安装Docker Engine需要CentOS 7、CentOS 8(Stream)或CentOS 9(Stream)的维护版本

安装Docker Engine需要CentOS 7、CentOS 8(流)或CentOS 9(流)的维护版本。过去的版本不支持使用或测试。

cat /etc/centos-release

#打印当前系统的相关信息
uname -r

(2)必须启用centos-extras存储库。默认情况下,此存储库是启用的,但是如果您已经禁用了它,则需要重新启用它。

(3)建议使用overlay2存储驱动。

(4)卸载老版本的Docker和Docker Engine

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

yum常用命令:

#使用 yum 查找软件包
yum search


#列出所有可安装的软件包
yum list


#列出所有可更新的软件包
yum list updates


#列出所有已安装的软件包
yum list installed


#查看某个软件是否安装
yum list installed 包名

 2,安装Docker

安装Docker Engine的三种方式:

  • 设置Docker存储库(推荐使用)
  • 手动下载安装RPM包,在没有网络的情况下使用
  • 用脚本安装Docker

①设置存储库

yum install -y yum-utils

Docker应用,从0到0.8_第2张图片

②设置镜像仓库

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

 前面我们说过,Docker官网提供了Docker hub镜像库,但由于它是国外的服务,访问起来速度慢,所以这里我们选择使用阿里云的镜像库。

③安装Docker Engine

yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin

Docker应用,从0到0.8_第3张图片

Docker应用,从0到0.8_第4张图片

如果系统提示是否接受GPG密钥,请确认指纹是否匹配“060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35”,如果匹配则接受。

这个命令会安装Docker,但不会启动Docker。它还创建了一个docker组,但是默认情况下它不会向该组添加任何用户。

 当然,也可以指定Docker版本来安装指定版本的Docker。

④启动Docker

systemctl start docker

⑤验证

docker run hello-world

这个命令下载一个测试映像,并在容器中运行它。当容器运行时,它打印一条消息并退出。 

Docker应用,从0到0.8_第5张图片

docker run内部执行过程:

Docker应用,从0到0.8_第6张图片 ---来自阳哥 

 ⑥停止Docker

systemctl stop docker

⑦卸载Docker

卸载Docker Engine、CLI、Contained、Docker Compose。但不会删除主机上的Images、containers、 volumes、customized configuration files。

yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin

删除文件和其他配置文件

rm -rf /var/lib/docker
rm -rf /var/lib/containerd

在Linux上安装Docker之后的步骤——可选https://docs.docker.com/engine/install/linux-postinstall/

三,Docker命令

1,Docker管理命令

(1)启动Docker

systemctl start docker

(2)停止Docker

systemctl stop docker

(3)重启Docker

systemctl restart docker

(4)查看Docker状态

systemctl status docker

(5)设置开机自启

systemctl enable docker

Docker应用,从0到0.8_第7张图片 (6)查看Docker帮助文档

docker --help

Docker应用,从0到0.8_第8张图片 (7)查看命令帮助文档

docker command --help 

Docker应用,从0到0.8_第9张图片

 (8)查看Docker信息

docker info

Docker应用,从0到0.8_第10张图片

2,镜像命令

(1)列出本地镜像

docker images

Docker应用,从0到0.8_第11张图片

 字段说明:

  • REPOSITORY:镜像的仓库源
  • TAG:镜像的版本号
  • IMAGE ID:镜像ID
  • CREATED:镜像创建时间
  • SIZE:镜像大小

不同的镜像由REPOSITORY:TAG或IMAGE ID表示,同一个REPOSITORY可有多个TAG版本号,就比如mysql由5.7、5.8、8.0不同版本的。

(2)查询远程中的镜像

docker search 镜像名

Docker应用,从0到0.8_第12张图片

 字段说明:

  • NAME:镜像名称
  • DESCIRIPTION:镜像说明
  • STARS:星数
  • OFFICIAL:是否是官方的
  • AUTOMATED:是否是自动构建的

(3)从远程仓库拉去镜像

docker pull 镜像名[:TAG]

Docker应用,从0到0.8_第13张图片

 没有TAG就默认最新版,=镜像名:latest

(4)查看镜像、容器、数据卷的数量和空间

docker system df

Docker应用,从0到0.8_第14张图片

 (5)删除镜像

#删除单个镜像
docker rmi -f 镜像ID

#同时删除多个镜像
docker rmi -f 镜像名1:TAG 镜像名2:TAG

#同时删除本地所有镜像
docker rmi -f $(docker images -qa)

Docker应用,从0到0.8_第15张图片

 (6)根据容器构建一个该容器的镜像(容器——>镜像)

当为一个容器新增一个功能,并希望基于当前容器创建一个新的镜像,以方便共享给其他人或环境使用。

docker commit -m="描述信息" -a="作者信息" 容器ID 自定义的要创建的目标镜像名[:自定义标签]

Docker应用,从0到0.8_第16张图片

Docker应用,从0到0.8_第17张图片

 3,容器命令

(1)新建并启动容器

docker run [OPTIONS] 镜像名 [COMMAND] [ARG...]

 前台交互式启动:

Docker应用,从0到0.8_第18张图片

后台守护式启动:

Docker应用,从0到0.8_第19张图片

OPTIONS参数:

  • --name=“容器新名字” 为运行的容器指定一个名称
  • -d:以守护进程的形式启动容器,让容器在后台运行
  • -i:以交互的形式运行容器
  • -t:为容器分配一个输入终端,使人与机器交互
  • -P:随机分配端口映射
  • -p hostPort:containerPort:指定主机和容器映射的端口号,可用多个-p指定多组映射

COMMAND命令:

/bin/bash:用/bin/bash启动一个交互式shell

(2)查看本地所有正在运行的容器

docker ps [OPTIONS]

 OPTIONS参数:

  • -a:列出所有正在运行的和历史上运行过的容器
  • -l:显示最近创建的容器
  • -n:显示最近n个创建的容器
  • -q:只显示容器编号

字段参数:

  • CONTAINER ID:容器ID
  • IMAGE:镜像名
  • COMMAND:启动容器的时候的命令
  • CREATED:创建时间
  • STATUS:容器运行状态,UP表示正在运行
  • PORTS:容器端口映射,在docker run命令由-p和-P指定
  • NAMES:容器的名称,在docker run命令中由--name命令指定

(3)退出容器的两种方式

方法一:exit  容器停止

Docker应用,从0到0.8_第20张图片

 方法二:ctrl+p+q  容器不停止,到后台运行,还可以再次进入

Docker应用,从0到0.8_第21张图片

(4)重启已停止的容器

docker restart 容器名称/容器ID

Docker应用,从0到0.8_第22张图片

 (5)停止容器

docker stop 容器ID/容器名称

Docker应用,从0到0.8_第23张图片

(6)强制停止容器

docker kill 容器ID/容器名

 (7)删除已停止的容器

#删除单个容器
docker rm 容器ID

#同时删除全部容器
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm 

Docker应用,从0到0.8_第24张图片

 (8)查看容器日志

docker logs 容器ID

Docker应用,从0到0.8_第25张图片

(9)查看容器内运行的进程

docker top 容器ID

 (10)查看容器内部细节

docker inspect 容器ID

Docker应用,从0到0.8_第26张图片

 (11)打开交互终端进入正在运行的容器

方法一:docker exec 在容器中打开新的终端,并启动新的进程;用exit时,不会使容器停止。

docker exec -it 容器ID shell命令

Docker应用,从0到0.8_第27张图片

方法二:docker attach 直接进入容器启动的终端,不会启动新的进程 ,用exit时,容器会停止。

docker attach 容器ID

 (12)将容器的文件拷贝到主机

docker cp 容器ID:容器内待拷贝文件的路径 目的主机路径

Docker应用,从0到0.8_第28张图片

 (13)导出容器的内容作为一个tar文件

docker eport 容器ID > 文件名.tar

Docker应用,从0到0.8_第29张图片

 (14)根据一个tar包创建一个新娘你的文件系统并导入为镜像

cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号

其中,镜像用户、镜像名、镜像版本号都是自定义的。 

Docker应用,从0到0.8_第30张图片

 Docker应用,从0到0.8_第31张图片

---来自阳哥 

四,Docker数据的持久化——数据卷

将docker容器内的数据保存进宿主机器的磁盘中。

Docker容器时在内存中运行的,如果没有数据持久化,Docker容器产生的数据会在容器实例删除后消失。

为了能将Docker的数据保存,Docker采用了数据卷。

此外,

数据卷可在容器之间共享和重用数据,

宿主机和Docker容器中数据的修改使双向实时的,在一个修改数据都能在另一地方实时更改。

1,添加容器卷

只需要在新建和启动容器的时候,在docker run命令中添加--privileded=true -v /书宿主机绝对路径目录:/容器内目录 的参数。

docker run -it --privileded=true -v /宿主机绝对路径目录:/容器内目录[:rw] 镜像名

参数说明:

  •  --privileded=true

开启Linux挂载目录功能,扩大容器的权限解决挂载目录没有权限的问题。

Centos7安全模块会禁止不安全的行为,目录挂载被默认为不安全行为,在SELinux里面挂载目录会被禁止掉。

使用该参数以后,容器内的root真正拥有Linux宿主机的root权限,否则只有宿主机的普通用户的权限。

  • -v

指定宿主机与容器之间目录的映射,可同时设置多组映射

  • rw ro

设置数据卷的读写规则

默认是rw,容器内可读可写

可设置ro,容器内部被限制,只能读不能写

  • --volumes-from 被继承卷规则的容器名
docker run -it --privileged=true --volumes-from 被继承的容器 --name u2 镜像名

新创建并运行的容器继承了”父类“容器的卷规则;

注意:

继承的是父类容器的规则,如果被继承的容器不在了,继承的容器不受影响。

被继承的容器、继承的容器和宿主机三者共享数据,任一处修改数据在其他都是实时更改的。

查看数据卷挂载成功:

 Docker应用,从0到0.8_第32张图片

 2,测试宿主机和容器之间数据实时共享

宿主机添加数据:

 容器查看数据:

 容器添加数据:

Docker应用,从0到0.8_第33张图片

 宿主机查看数据:

五,安装示例

1,总体安装步骤

  1. 搜索镜像 docker search redis --limit 3
  2. 拉去镜像 docker pull redis:tag
  3. 查看镜像 docker images tomcat
  4. 启动镜像 docker run -it redis /bin/bash
  5. 停止镜像 docker stop redis/容器id
  6. 移除镜像 docker remove 容器id

当然,这里只是一个总体的步骤,对于每个软件的安装都有各自的细节需要注意,比如要考虑mysql设置账号密码、redis配置等,此时,我们可以参考官方镜像仓库在提供竟像时,同时给予的“How to use this image.”这里具有安装和使用镜像的详细说明。Mysql - Official Image | Docker Hubhttps://hub.docker.com/_/mysql?tab=description

Docker应用,从0到0.8_第34张图片

2,安装tomcat

①安装:

当然docker run命令可以替代2、3、4步骤。你懂的!

Docker应用,从0到0.8_第35张图片

 ②访问tomcat首页:

Docker应用,从0到0.8_第36张图片

 问题:

  • 访问首页404:没有关闭防火墙
  • 访问首页404:如果是新版tomcat,在安装tomcat之后首页文件不在webapps中,而在webapps.dist中,需要进入容器,将webapps.dist的文件复制到webapps中
  • 启动容器时报错,是因为启动了Docker之后又操作了Linux防火墙,重启Docker即可。 

3,安装mysql

(1)mysql单机版

前面我们很容易的就创建了tomcat容器并成功使用,那MySQL能采用同样的方式安装吗?

好像不行,mysql不但要安装,还有设置账号密码、登录、创建库等。

①创建并运行MySQL容器实例

docker run -d -p 3306:3306 --privileged=true -v /mysql/log:/var/log/mysql -v /mysql/data:/var/lib/mysql -v /mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456  --name mysql mysql:5.7

 参数说明:

  • -v:几组-v参数,将mysql的日志、数据、配置文件都进行了宿主机和容器的映射,使容器中mysql的日志和数据能持久化到磁盘,同时可以在宿主机上修改配置文件达到在mysql修改配置文件的效果。
  • -e :设置环境变量
  • -e MYSQL_ROOT_PASSWORD=123456:指定mysql的root账户的密码

Docker应用,从0到0.8_第37张图片

 ②创建mysql配置i文件my.cnf

Docker应用,从0到0.8_第38张图片

 在docker中安装完mysql之后,默认编码集使latin1,不支持中文;所以添加my.cnf文件以设置编码集。

③使用mysql

  • 使用Navicat远程连接。
  • 进入容器,启动mysql命令行
  • 启动另一个mysql容器实例,并运行mysql命令行客户端连接该mysql

安装mysql主从复制

六,DockerFile

1,简要介绍

Dockerfiles是包含指令的文本文件。

Dockerfiles遵循一种特定的格式,并包含一组说明。

Docker通过从Dockerfile中读取指令来构建映像。

Docker镜像由只读层组成,每一层都来自Dockerfile中的一条指令。层按顺序堆叠,每个层都是一个增量,表示应用于前一层的更改。

Dockerfile是一个文本文件,包含将应用程序组装成Docker容器映像所需的所有必要指令。

Dockerfiles是镜像构建的关键输入,它可以基于你的独特配置促进自动化的多层镜像构建。

Dockerfile可以从简单开始,并随着需求而增长,支持需求复杂指令的镜像。

Docker可以通过从Dockerfile中读取指令来自动构建映像。Dockerfile是一个文本文档,它包含用户可以在命令行上调用的所有命令来组装图像。使用docker构建用户可以创建一个自动构建,该构建可以连续执行几个命令行指令。

构建是由Docker守护进程运行的,而不是通过CLI。构建进程所做的第一件事是将整个上下文(递归地)发送给守护进程。在大多数情况下,最好从一个空目录开始作为上下文,并将Dockerfile保存在该目录中。只添加构建Dockerfile所需的文件。

注意:

不要使用根目录/作为构建上下文的PATH,因为它会导致构建将硬盘驱动器的全部内容传输到Docker守护进程。

总之,Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。就相当于把在基础镜像的基础上,通过一条条指令添加功能的这些指令写成一个脚本。

官网介绍:

Hello Build | Docker Documentationhttps://docs.docker.com/build/hellobuild/Dockerfile reference | Docker Documentationhttps://docs.docker.com/engine/reference/builder/

2,构建步骤

  1. 编写Dockerfile文件
  2. docker build命令构建镜像
  3. docker run运行镜像创建容器实例

3,使用Dockerfile文件构建vim+ifconfig+jdk11的ubuntu镜像

①将jdk放到一个空目录下

②在相同目录下创建编写Dockerfile文件

      1 FROM ubuntu
      2 LABEL multi.label1="value1" multi.label2="value2" other="value3"
      3
      4 ENV MYPATH /usr/local
      5 WORKDIR $MYPATH
      6 #更新索引
      7 RUN apt-get update
      8 #安装vim编辑器
      9 RUN apt-get -y install vim
     10 #安装网络模块
     11 RUN apt-get -y install net-tools
     12 
     13 #安装java
     14 RUN mkdir /usr/local/java
     15 ADD jdk-11.0.15.1_linux-x64_bin.tar.gz /usr/local/java/
     16 #添加环境变量
     17 ENV JAVA_HOME /usr/local/java/jdk-11.0.15.1
     18 ENV JRE_HOME $JAVA_HOME/jre
     19 ENV CLASSPATH JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
     20 ENV PATH $JAVA_HOME/bin:$PATH
     21
     22 EXPOSE 80
     23
     24 CMD echo $MYPATH
     25 CMD echo "success--------------ok"
     26 CMD /bin/bash

简单语法解析(具体内容参考官网):

  • 文件名Dockerfile,且字母D必须大写
  • 每一行都是一条指令,指令按照从上到下的顺序执行
  • FROM、MAINTAINER、ENV等都是Dockerfile的保留字指令,每个保留字执行都必须为大写字母且后面要跟至少一个参数
  • #井号表示注释
  • FROM:初始化一个新的构建阶段,并为后续指令设置基础镜像;因此,一个有效的Dockerfile必须以一个FROM指令开始
  • LABEL:向镜像添加一些元数据信息,docker image inspect时可见
  • EVN:声明环境变量,声明之后的环境变量可在后续任何指令中使用
  • WORKDIR:指定在创建容器之后,登录终端默认进入的工作目录,如同登录liunx默认进家目录
  • RUN:指定构建容器时需要运行的命令,后跟一条linux命令,在docker build时运行这条命令
  • ADD:将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压缩tar压缩包
  • EXPOSE:告诉Docker容器在运行时监听指定的网口。实际上并不发布端口。它在构建映像的人和运行容器的人之间充当一种文档,说明哪些端口将被发布。要在运行容器时真正发布端口,可以使用docker run上的-p标志来发布和映射一个或多个端口,或者使用-p标志来发布
  • CMD:指定容器启动后要干的事情,docker run时执行
  • USER:指定镜像以什么用户执行,默认是root
  • COPY:拷贝文件和目录到镜像中
  • VOLUME:设置容器数据卷
  • ENTRYPOINT:指定一个容器启动时要运行的命令,类似于CMD指定,但不会被docker run后面的命令覆盖,而且会被当做参数送给ENTRYPOINT指令。

③docker build命令,根据Dockerfile文件构建镜像

docker build -t 新镜像名:tag Dockerfile路径

Docker应用,从0到0.8_第39张图片

Docker应用,从0到0.8_第40张图片

  ④运行镜像

Docker应用,从0到0.8_第41张图片

 此时,一个包含vim编辑器、jdk11、和网络模块的ubuntu镜像便已经创建并运行成功了,所以Dockerfile就如同一个脚本,将一条一条命令写到文档里让Docker批量执行。

七,Docker网络

为什么要有网络想必不难理解,Docker的容器之间需要互联互通以及被外部访问等,所以Docker也有自己的网络模式,就如同vmware虚拟机支持Linux有NAT模式、桥接模式、仅主机模式一样,当然也支持自定义网络模式。

我们可以配置Docker容器的网络,就如同我们可以设置Linxu虚拟机选择三种模式中的哪一种一样。

Docker有四种网络模式,bridge、host、none、container模式,当然也可自定义。

1,网络相关命令

Docker应用,从0到0.8_第42张图片

 (1)查看所有网络模式

docker network ls

 当安装Docker之后,默认会自动创建三个如上的网络模式。

(2)查看某个网络的内部信息

docker network inspect 网络名

Docker应用,从0到0.8_第43张图片

 (3)创建网络

docker network -d 网络模式 create 新网络名

Docker应用,从0到0.8_第44张图片

(4)删除网络

docker network rm 待删除的网络名

Docker应用,从0到0.8_第45张图片

 2,网络模式

(1)bridge模式

每个容器虚拟出自己的网卡,分配、设置IP等,并将容器连接到宿主机一个叫docker0的网卡(如果容器网络连接的是默认的birdge时)上,创建容器不指定网络模式的话默认采用该模式。

Docker应用,从0到0.8_第46张图片

如上图, docker启动后,宿主机会新虚拟一个叫做docker0的网卡,所有以默认bridge网络模式启动的容器都会连接到docker0网卡,这些容器和宿主机通过docker0网卡组成了一个局域网。

Docker应用,从0到0.8_第47张图片

如上图,每个网络为birdge模式的容器,都会自己虚拟出网卡,且与连接的bridge在同一个网段。 

Docker应用,从0到0.8_第48张图片

 如上图,每为docker创建一个bridge网络模式的网络,宿主机都会虚拟出一张网卡,二者在同一网段,这就使连接这一网络的容器和宿主机组成了一个局域网。

网桥docker0创建一对对等虚拟设备接口一个叫veth,另一个叫eth0,成对匹配。

  • 整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair);
  • 每个容器实例内部也有一块网卡,每个接口叫eth0;
  •  docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。

 通过上述,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一个网络下,会从这个网关下各自拿到分配的ip,此时两个容器的网络是互通的。

Docker应用,从0到0.8_第49张图片

(2)host模式

容器不虚拟自己的网卡和配置自己的IP,而是使用宿主机的IP和端口号。如下图,可以看出host网络模式的容器的网络配置信息与宿主机相同。

Docker应用,从0到0.8_第50张图片

Docker应用,从0到0.8_第51张图片

 (3)none模式

容器有独立的网络命名空间,但没有任何网络配置。如下图,可以看出容器只有本地回环地址。

Docker应用,从0到0.8_第52张图片

 (4)container模式

新创建的容器不会创建自己的网卡和配置,而是和指定的容器共享IP、端口范围等。如下图,新创建的容器的网络信息与指定的容器相同。

Docker应用,从0到0.8_第53张图片

 如下图,如果关闭指定共享的容器,则新创建的容器的网络不可用。

Docker应用,从0到0.8_第54张图片

 (5)自定义网络

docker network create -d 网络模式 新的网络名

自定义网络默认采用的是bridge模式。

①新建自定义网络

Docker应用,从0到0.8_第55张图片

 ②创建两个容器加入新建的自定义网络

Docker应用,从0到0.8_第56张图片

如上图,可以通过容器名访问同一自定义网络中的其他容器实例。如果测试的话,将会发现bridge网络是不行的!

  • 容器实例内默认网络IP生成规则:

docker容器内部的ip是有可能发生变化的。

同一局域网下容器的ip总是按照顺序排列,如果启动一个容器它的ip会从2开始(1是网关,宿主机的ip),在启动一个容器实例,ip将会是3,如果关闭实例,在启动一个实例,ip还是3。

  • 自定义网络本身就维护好了主机名和ip的对应关系

不管是通过ip访问,还是通过主机名访问都能通。

一般情况,我们都希望通过主机名访问其他容器,因为容器的ip可能会发生变化。

八,本地镜像发布到库

当我们在基本镜像添加了新功能之后,一般都需要共享给其他人使用,比如开发团队要使用同样的镜像,这时我们可以将配置好的镜像发布到阿里云镜像仓库或公司内部的镜像库,当别人使用的时候直接取pull就可以了。

1,发布到阿里云镜像仓库

①进入阿里云容器镜像服务

容器镜像服务_镜像构建_镜像授权_镜像托管-阿里云 (aliyun.com)https://www.aliyun.com/product/acr?spm=5176.8789780.J_3207526240.31.55af45b51P6ERcDocker应用,从0到0.8_第57张图片

②进入控制台-镜像

Docker应用,从0到0.8_第58张图片Docker应用,从0到0.8_第59张图片 

③选择个人实例(这里就用于测试)

Docker应用,从0到0.8_第60张图片

 ④创建一个命名空间

Docker应用,从0到0.8_第61张图片

Docker应用,从0到0.8_第62张图片

⑤创建镜像仓库名称

Docker应用,从0到0.8_第63张图片

Docker应用,从0到0.8_第64张图片

 ⑥进入镜像获取上传镜像的脚本 Docker应用,从0到0.8_第65张图片

Docker应用,从0到0.8_第66张图片

 ⑦根据脚本上传自己的镜像到阿里云镜像仓库

Docker应用,从0到0.8_第67张图片

Docker应用,从0到0.8_第68张图片 ⑧从阿里云镜像库拉取镜像

2,发布到私有镜像库

如果不太希望把自己的镜像存在别人的服务器上,那可以在自己的服务器上构建一个私有的镜像库。

 Docker提供了一个叫registry的镜像,供我们构建私有镜像库,相当于本地有了个私有的Docker hub。

①新建并运行Registry容器

docker run -d -p 5000:5000  -v /mydir/myregistry/:/tmp/registry --privileged=true registry

Docker应用,从0到0.8_第69张图片

② commit要提交的容器(将容器转化为镜像)

docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]

 ③查看本地私有库的镜像

curl -XGET 192.168.72.136:5000/v2/_catalog

④将待上传的镜像修改为符合私服规范的tag

docker tag 镜像:Tag Host:Port/Repository:Tag

Docker应用,从0到0.8_第70张图片

⑤ 修改配置文件使Docker支持http

 docker默认不允许使用http的方式推送镜像,通过配置选型关闭这个限制。修改完重启docker。

Docker应用,从0到0.8_第71张图片

⑥推送镜像到私服 

docker push 192.168.72.136:5000/myubuntu:1.0

Docker应用,从0到0.8_第72张图片

⑦从私服库拉去镜像

docker pull 192.168.72.136:5000/myubuntu:1.0

九,compose容器编排

前面我们说,当一个容器需要添加多个功能时,比如ifconfig、vim、java,需要我们输入多条命令,于是诞生了Dockerfile;

这里,我们需要构建多个容器呢,比如一个项目往往有多个微服务、而且还需要其他组件mysql、redis、kafka等,我们总不能一个一个容器的构建吧?而且,为微服务往往依赖于mysql、redis,启动也要有一定的顺序,于是诞生了Compose。

1,简要介绍

Docker-Compose是Docker官网的开源项目。负责实现对Docker容器集群的快速编排。

Compose是一个用于定义和运行多容器Docker应用程序的工具。使用Compose,您可以使用一个YAML文件来配置应用程序的服务。

参考官网:

Use Docker Compose | Docker Documentationhttps://docs.docker.com/get-started/08_using_compose/Overview of Docker Compose | Docker Documentationhttps://docs.docker.com/compose/

2,安装

 前面在安装Docker Engine的时候,已经安装过docker-compose-plugin,但当执行docker compose version时报找不到docker compose的问题,于是重新用yum install安装docker-compose-plugin,虽然提示“已安装并且是最新版本呢,无须任何处理”,但再次执行docker compose version就没啥问题了。

Docker应用,从0到0.8_第73张图片

3,使用Docker compose构建一个包含微服务、Redis、mysql容器的项目

①编写docker-compose.yml文件

version: "3"

services:
  microService:
    image: my_micorservie:1.6
    container_name: ms01
    ports:
      - "6001:6001"

    volumes:
      - /app/microService:/data

    networks: 
      - mynw

    depends_on: 
      - redis
      - mysql

  redis:
    image: redis:6.0.8
    ports:
      - "6379:6379"

    volumes:
      - /app/redis/redis.conf:/etc/redis/redis.conf
      - /app/redis/data:/data

    networks: 
      - mynw

    command: redis-server /etc/redis/redis.conf

  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: '123456'
      MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
      MYSQL_DATABASE: 'test'
      MYSQL_USER: 'user'
      MYSQL_PASSWORD: 'user123'
    ports:
       - "3306:3306"

    volumes:
       - /app/mysql/db:/var/lib/mysql
       - /app/mysql/conf/my.cnf:/etc/my.cnf
       - /app/mysql/init:/docker-entrypoint-initdb.d

    networks:
      - mynw

    command: --default-authentication-plugin=mysql_native_password #解决外部无法访问

networks: 
   mynw: 

②构建微服务项目

配置文件

server.port=6001

# ========================alibaba.druid相关配置=====================
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#spring.datasource.url=jdbc:mysql://192.168.111.169:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.url=jdbc:mysql://mysql:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.druid.test-while-idle=false

# ========================redis相关配置=====================
spring.redis.database=0
spring.redis.host=redis
spring.redis.port=6379
spring.redis.password=
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0

# ========================mybatis相关配置===================
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.atguigu.docker.entities

# ========================swagger=====================
spring.swagger2.enabled=true

 

 打jar包并上传服务器

编写Dockerfile

# 基础镜像使用java
FROM java:8

# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp

# 将jar包添加到容器中并更名为zzyy_docker.jar
ADD docker_boot-0.0.1-SNAPSHOT.jar test.jar

# 运行jar包
RUN bash -c 'touch /test.jar'
ENTRYPOINT ["java","-jar","/test.jar"]

#暴露6001端口作为微服务
EXPOSE 6001

构建镜像

docker build -t test:1.0

 ③启动docker-compose服务

docker-compose up

 Compose常用命令

  • docker-compose -h:查看帮助
  • docker-compose up:启动所有docker-compose服务
  • docker-compose up -d :启动所有docker-compose服务并后台运行
  • docker-compose down :停止并删除容器、网络、卷、镜像。
  • docker-compose exec  yml里面的服务id :进入容器实例内部  docker-compose exec docker-compose.yml文件中写的服务id /bin/bash
  • docker-compose ps :展示当前docker-compose编排过的运行的所有容器
  • docker-compose top :展示当前docker-compose编排过的容器进程
  • docker-compose logs  yml里面的服务id:查看容器输出日志
  • dokcer-compose config:检查配置
  • dokcer-compose config -q: 检查配置,有问题才有输出
  • docker-compose restart:重启服务
  • docker-compose start :启动服务
  • docker-compose stop:停止服务

④创建数据库和数据表

 十,容器监控

  • 轻量级可视化工具Portainer
  • 重量级容器监控CAdvisor+InfluxDB+Granfana

低花树映小妆楼,春入眉心两点愁。

斜倚栏杆背鹦鹉,思量何事不回头?

你可能感兴趣的:(Java技术栈,docker,容器,linux)