Docker:Docker思想&解决问题&Docker优势&Docker基本概念&Docker安装&基本设置&常用命令&网络管理&数据卷&构建自定义镜像&多容器管理

什么是Docker?

Docker是一个用来装应用的容器,就好比杯子用来装水,笔筒用来装笔,书包用来装书一样,你可以把hello world放到Docker里,你可以把网站放到Docker里,你可以把你想的到的任何程序放到Docker里。

Docker的思想

Docker的思想来源于集装箱

下图为运输行业没有集装箱之前的货物处理:

在这里插入图片描述

上面的处理异常麻烦,而且还有下面三个问题:

1.货物的运输效率非常慢并且需要非常大的人力资源

2.货物直接与外界接触,不安全

3.每种类型的货物都需要专门的车辆或者轮船来运输

在这里插入图片描述

Docker 的思想来源于集装箱,集装箱最大的作用在于能够将货品标准化,在运输的过程中,不需要直接装载和卸载各种各样的商品,而是统一标准的集装箱,这样装载和卸载的环节就可以实现流水线和自动化了,并且商品封装在集装箱中,没有暴露在外面,提高安全性,集装箱与集装箱之间也是互相隔离,不会有任何相互影响的问题。我们也不再需要专门的船去运输专门的货品,只要货品在集装箱内好好封存着,那就可以使用一艘大船将他们都运走。并且你可以很方便的将集装箱装载到飞机、轮船、货车、火车,大大的提高了运输的便利性。

对于我们来说,Docker 也担任了集装箱类似的角色,我们的应用或者所依赖的第三方服务可以理解为货品,而 Docker 则是将我们的货品规范化管理起来,从而可以轻易的完成产品交付,环境转移等等诸多问题。还有我们的货品由Docker这个集中箱封装,对外隔离,提高安全性。并且 Docker 对于主机资源的消耗非常小,可以实现对服务器资源的最大利用。

重点:就是借鉴集装箱的全球统一标准的思想,因为是全球统一标准,就能够实现流水线式来处理流水线上的货物

Docker为我们解决了哪些问题?

首先目前软件业遇到的问题:

1.大量的重复部署的工作

在这里插入图片描述

在这里插入图片描述

2.应用上线的安全性问题:

没有容器之前,应用由于是直接部署在系统上,安全性问题不是一点半点
在这里插入图片描述
而Docker解决安全性的问题:是采取容器与外界系统的隔离
在这里插入图片描述

3.环境冲突带来的资源浪费问题

在这里插入图片描述

有了Docker之后环境冲突可以这样解决环境冲突的问题

在这里插入图片描述

简单总结为:

  • 便携性

    另一问题是,以传统的方式部署你的应用,如果我们的应用如果后期需要迁移(这里的迁移包括相同操作系统和不同操作系统的迁移),还是需要做大规模的集群,都是一件工作量非常大的操作。而容器化了的应用,对这些操作都是非常方便的。

  • 安全性

    最后一个不得不提的问题就是安全,以传统的方式部署你的应用,如果该应用被攻击者攻击,或者因为程序自身的bug,又或是运行环境多个应用间混乱的依赖关系导致的问题,这样的话,你的服务器系统安全危险级别会很高,因为这些问题将直接影响你的系统安全。但如果你的应用是运行在Docker容器中,那么一切的危害都会被隔离在容器内,因为容器的资源跟系统是隔离的,危害将被降到最低。

  • 组织有序性

    以传统的方式部署你的应用,可能出现由于多个应用程序的依赖不用,导致应用之间的依赖变得非常混乱,若此时出现两个应用依赖同一个程序但却依赖不同版本,便会出现让人比较头痛的问题,使用Docker便可以很方便的帮我们管理各个应用的依赖,并以容器为基础将应用的运行环境独立开来,从而不会互相影响,还能提高资源利用率。

Docker VS VM

Docker 的核心是 基于 LXC(Liunx container) 技术的实现,可以理解为一个轻量级的虚拟机(实际上是容器的概念,Docker 不是虚拟机),Docker 使用 Linux 的 namespace 和 cgroups 技术实现容器隔离资源限制

Docker的容器隔离的技术是依赖于Linux的技术,与VM完全虚拟出计算机隔离主机的原理根本不同

具体上的不同

在这里插入图片描述

在这里插入图片描述

应用场景

面向产品:

产品的交付模式改变

之前需要的是:要开发人员到现场部署,现在有了Docker之后,直接发个镜像过去就OK了

面向开发:

个人开发环境发生改变

比如之前在开发环境没有任何问题,但是在测试环境有问题

有了Docker之后,可以在镜像上运行环境,开发/测试的时候

直接在容器上测试就不会有上面的问题了

面向运维:

获得比虚拟机性能损失更小的解决方案

可以更快的进行自动化扩容(VM 是分钟级扩容,Docker 是秒级)

Docker 适用于微服务架构

面向测试:

同一环境下多版本测试

自动化、微服务、大规模集群(微博红包案例)百度的 Paas 平台、等等…

应用场景扩展:http://www.docker.org.cn/docker/151.html
docker中文学习网:http://www.docker.org.cn

Docker带来的挑战:DevOps

基本概念

Docker 有三大重要的概念:仓库、镜像、容器    

仓库(Repository):

仓库是用于存放镜像的地方,类似于 Maven 仓库、Git 仓库、yum仓库等用途,仓库之上还有仓库注册服务器(Registry)的概念,上面存放着多个仓库,每个仓库中又有多个镜像,而每个镜像又可以有多个标签(tag)。目前最大的公开仓库是 Docker Hub,我们可以使用类似 Git 命令的方式去 pull/push 镜像

镜像(Image):

可以理解为一个只读的模板,镜像可以用来创建容器,一个镜像可以创建多个容器,你可以直接从官方仓库(docker hub)或者其他私服仓库拉取(pull)想要的镜像,或通过 Dockerfile 来构建属于你自己的镜像,这一切操作都非常的简单

容器(Container):

容器是由镜像创建的实例,他可以被启动、停止、运行、删除(生命周期)。每个容器之间是互相隔离的、保证安全的平台。可以把容器看做为一个简单的 Linux 环境

安装Docker

安装Docker的大前提:Linux内核必须是3.1 不然无法安装

Docker 的安装相对来说也算比较简单, Docker 官方要求 CentOS 操作系统内核必须在 3.10 以上,所以我们这边使用 CentOS7 来安装;

PS:可以使用 uname -r 来查看当前系统的内核版本

在这里插入图片描述

  1. 更新 yum 仓库,确保 yum 包都是最新版本
yum update

提示:假如不是阿里云ECS而是本地搭建的虚拟机,该命令慎用,因为会耗费大量的时间

  1. 查看是否有安装 docker,若有则将其删除
yum list installed | grep docker
yum remove docker...... # 如果有的话则删除对应的包
  1. 安装需要的软件包,yum-util 提供 yum-config-manager 功能,另外两个是 devicemapper 驱动依赖的(一共要安装3个程序)

utils:yum库的管理,后面两个是提供docker驱动的映射

yum install -y yum-utils device-mapper-persistent-data lvm2
  1. 设置 yum 源(阿里源)

这里设置阿里的yum库,是因为官方的docker库并没有提供docker-ce(引擎)的下载
而我们的docker,是必须要依赖docker-ce来运行的

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  1. 查看yum库中有无docker-ce
yum list | grep docker-ce

在这里插入图片描述

  1. 安装 docker
yum install -y docker-ce
  1. 设置 docker 开机自动启动
systemctl start docker # 启动 docker 服务端
systemctl enable docker # 启用 docker 服务开机自启
  1. 校验 docker 是否启动成功
docker version

在这里插入图片描述

最后启动 + 设置开机启动

在这里插入图片描述

在这里插入图片描述

常见问题

在这里插入图片描述

普通用户运行 docker param 命令会报错:

由于 docker daemon 需要绑定到主机的 Unix socket 而不是普通的 TCP 端口, 而 Unix socket 的属主为 root 用户, 所以其他用户只有在命令前添加 sudo 选项才能执行相关操作. 如果不想每次使用 docker 命令的时候还额外敲一个 sudo, 可以按照下面的方法进行配置.

  1. 切换到root用户

  2. 添加普通用户到 docker 组
    在这里插入图片描述

  3. 重新切换到<普通用户>

  4. 验证 docker 命令是否可以运行

常用命令

search # 查找仓库中是否有指定镜像
格式:docker search [镜像名]
演示:docker search centos
在这里插入图片描述

pull # 从仓库中下载某一个镜像
格式:docker pull [镜像名]
演示:docker pull centos
阿里云的docker镜像地址:dev.aliyun.com

可以看到这里centos镜像确实很小,几乎都是包含的CentOS核心组件
在这里插入图片描述

images # 查看本地镜像列表
格式:docker images
在这里插入图片描述
tag # 修改镜像名字和标签
格式:docker tag [镜像名]:[镜像标签] [新镜像名]:[新镜像标签]
演示:docker tag registry.cn-shanghai.aliyuncs.com/sa_dockerhub/centos:latest centos:1.0
在这里插入图片描述
这里可以看到tag修改其实是复制
在这里插入图片描述

rmi # 删除某个镜像
格式:docker rmi [镜像名]:[镜像标签] | [镜像ID]
-f 强制删除镜像
演示:docker rmi -f centos:1.0 或者 docker rmi -f 3fa822599e10

在这里插入图片描述
在这里插入图片描述

run #命令解释:

  1. 命令会检测当前要运行的镜像在本地存不存在,若不存在他会自动 pull 下来再运行

在这里插入图片描述

  1. 运行后会启动一个容器, 并且开启一个文件系统, 你可以直接在容器内创建文件夹. 运行一个指定的程序, 当程序退出后, 容器也就退出了

  2. 运行时的容器无法删除, 只能停止后删除, 或者加上 -f 参数强制删除
    格式:docker run [参数] [镜像id] | [镜像名]:[镜像标签] [命令]

    -i 表示容器的输入终端保持打开,不直接关闭

    -t 表示开启一个虚拟终端, 绑定到标准输入上

    -d 表示让该容器在后台运行

    –name 给该容器起一个容器名,如果没有此参数,则有一个默认的容器名

    –rm 停止该容器时,把容器删除掉

    #多个参数可以连着一起写,比如:-it

演示:

docker run -it --name centos7 centos7:1.0
在这里插入图片描述
注意:此时已经调到了容器之中了

切换回原虚拟机

在这里插入图片描述
查看当前是否有容器在运行
在这里插入图片描述

docker run -it --rm --name centos2 centos7:1.0 /bin/echo ‘Hello world’
在这里插入图片描述
docker run -d --rm --name centos2 centos:1.0
在这里插入图片描述
docker run -itd --rm --name centos2 centos:1.0
在这里插入图片描述

ps # 查看容器列表
格式:docker ps #查看正在运行中的容器
-a 查看所有容器
-l 查看最后一个运行的容器
在这里插入图片描述
docker ps -l 列出最后启动的容器
在这里插入图片描述
stop #停止某个指定的容器
格式:docker stop [容器id]
演示:docker stop 055ca075244f
在这里插入图片描述

容器的重启
1)第一种方式:先停止后start
在这里插入图片描述
在这里插入图片描述
2)重启容器
在这里插入图片描述

rm #删除容器
格式:docker rm [容器id][容器名]
演示:docker rm 54ada6028aa9
#批量删除没有运行的容器:docker rm $(docker ps -qf status=exited)
在这里插入图片描述
PS:-f 强制删除正在运行的容器

stats #查看docker的所有容器运行状态
格式:docker stats
在这里插入图片描述

在这里插入图片描述
inspect # 获取容器的详细信息

格式: docker inspect [参数] [容器id][容器名]
在这里插入图片描述

-f 格式化(go 语言的格式化语法如:{{.State.Pid}})

演示:docker inspect -f {{.State.Pid}} 54ada6028aa9
在这里插入图片描述
应用:这里拿到Pid之后就可以执行kill命令,杀死对应容器

exec #进入容器里面
格式: docker exec [参数] [容器id] | [容器名] [命令]
在这里插入图片描述
-i 表示容器的输入终端保持打开,不直接关闭
-t 表示开启一个虚拟终端, 绑定到标准输入上
-d 表示让该容器在后台运行
演示:docker exec -it 54ada6028aa9 /bin/bash 或者 docker exec -it centos1 /bin/bash

PS: 使用 Ctrl + P + Q 可以退出容器,不停止容器

Docker的网络管理

docker的网络模式:
docker有四种网络模式,
分别是:

bridge模式、
host模式、
container模式、
none模式。

在运行容器时,添加以下参数:
–net [bridge | host | container | none] 即可选择一种网络模式运行容器。

bridge模式(默认模式):

在这里插入图片描述

当docker进程启动时,会在主机上创建一个名为docker0虚拟网卡,此主机上启动的Docker容器会连接到这个虚拟网卡上,从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网卡中。该模式是docker默认的网络模式。

简单的来说就是:内部通讯的原理就是那个网卡对veth pair,eth0连接容器内部,

veth*连接外部docker0,然后docker0的eth0网卡从外界获取数据或者向外界传输数据

在这里插入图片描述
为了研究docker的网络,我们下载tomcat,并运行该tomcat容器
在这里插入图片描述
启动之后有另一个问题,如何访问该tomcat应用?

这里就涉及到端口映射

端口映射:bridge

端口映射原理(桥接模式):

在这里插入图片描述

容器中的环境与宿主机隔离,那么此时容器内与外部进行网络通信就会有些问题,外部不能直接访问容器内的IP地址和端口。
docker 为我们提供了宿主机的端口与容器内的端口映射来解决此问题,方式有两种,一种是随机映射,一种是指定映射。
在运行容器时,添加以下参数:
随机映射
-P 会将容器中暴露的端口随机映射到宿主机的某一个端口上
演示:docker run --name tomcat1 -d --rm -P tomcat
在这里插入图片描述
之后就能看到随机映射了一个端口
在这里插入图片描述
指定映射:
-p hostPort:containerPort
-p ip:hostPort:containerPort
-p 参数可以指定多次, 如: -p 91:80 -p 92:443…
演示:docker run --name tomcat2 -d --rm -p 8080:8080 tomcat
在这里插入图片描述

host模式

如果启动容器的时候使用host模式,那么容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

缺点:没有对网络进行隔离,安全性堪忧

在这里插入图片描述

container模式

这个模式指定新创建的容器不会创建自己的网卡配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。

在这里插入图片描述

none模式

使用none模式,Docker容器不会进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。

这种模式存在的意义:
这种模式就是专门用作做数据/文件共享用的,因为这种模式没必要共享网络

数据卷(volume)

绕过 docker 的 vfs (virtual File System), 直接将数据存储在宿主机中。

简单来说就是docker的文件共享系统,是为了解决dockert与宿主机隔离导致的文件不能访问的问题

在运行容器时,添加以下参数:

格式:

	-v [**物理机磁盘**:**容器磁盘**]
	
	演示:

    # 指定映射目录
    # -h 表示指定主机名,与数据卷无关的参数
    # 可以通过该参数生成指定的主机名

在这里插入图片描述
# -v /opt:/opt 表示将物理机的 /opt 目录映射到 容器中的 /opt 目录
# -v /opt:/opt:ro 表示该目录在容器内只读, 不能写
docker run -itd --rm --name volume-test -h host -v /opt:/opt centos
在这里插入图片描述
查看映射目录
在这里插入图片描述
回到宿主机,查看生成的文件
在这里插入图片描述

在启动一个容器的时候,指定数据卷容器
在这里插入图片描述
现在验证一下,是否有test.txt?
在这里插入图片描述
数据卷容器关闭也不影响
在这里插入图片描述

    # 查看容器的 volume 映射在物理机的什么位置
    # 老版本应使用 -f '{{.Volumes}}'
    # 该物理目录会与容器内挂载的目录共享
    docker inspect -f '{{index .Mounts 0}}' volume-test

    docker run -itd --rm --name volume-test1 -h host1 -v /opt:/opt centos

用法:
将代码存放到指定目录. 如 /data/code, /data/logs, /data/conf 用来统一管理每一个环境的代码, 日志, 配置等, 那么此时将所有容器构建好, 在每个环境下面启动容器时按照此规则映射即可. 若要跑多种版本的业务, 又可以以 code 目录再去细分某些业务, 当然这只是一种解决方案, 可以根据这种思路进行拓展.

构建Docker镜像

为什么要构建镜像?

因为从网上下载的镜像都是通用的,我们部署项目必然要会构建自己的镜像

Dockerfile

Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。它们简化了从头到尾的流程并极大的简化了部署工作。Dockerfile从FROM命令开始,紧接着跟随者各种方法,命令和参数。其产出为一个新的可以用于创建容器的镜像。

Dockerfile构建镜像:

    ● 基础镜像信息
    ● 维护者信息
    ● 镜像操作指令
    ● 容器启动时执行指令

构建步骤:

  1. 创建专门管理 dockerfile 的文件夹
  2. 创建文件 dockerfile(名字必须按照该风格)
  3. dockerfile文件内容包含的配置信息(docker官网文档:

http://www.docker.org.cn/dockerppt/114.html)

       FROM base_image 基础镜像
       
       MAINTAINER author 维护者信息
       
       COPY file to_path 拷贝主机文件到容器中
       
       ADD file to_path 拷贝主机文件到容器中
       (更高级的文件拷贝,如果是压缩文件会自动解压,如果是URL路径会自动下载)
       
       WORKDIR path 实际上就是 cd 到指定目录
       
       VOLUME ["path"] 数据挂载
       
       EXPOSE port 暴露端口
       
       ENV key value 创建环境变量
       
       RUN command 运行指定命令
       (构建镜像的时候执行命令,一个dockerfile文件不建议用太多该指令,
       因为每用一个该指令就会创建一个镜像层,这会导致镜像臃肿)
       
       CMD command 执行命令(运行容器的时候执行命令)

下面就是即将会用到的dockerfile示例

由于我们下一步将会做dubbo-admin(监控中心)的镜像

所以我们需要的是:tomcat,jdk1.7 和 monitor.war的解压包

在这里插入图片描述
而由于我们已经清楚了dockerfile的格式后,写入dockerfile如下

#基础镜像
FROM registry.cn-shanghai.aliyuncs.com/sa_dockerhub/centos

#镜像维护者的信息
MAINTAINER wuming "[email protected]"

#进入工作目录,后面就不用一次次指定/usr/local了
WORKDIR /usr/local

#安装JDK 这里是指当前目录  解压到容器的哪个目录
ADD jdk-7u80-linux-x64.gz ./

#配置JDK的环境变量
ENV JAVA_HOME /usr/local/jdk1.7.0_80
ENV PATH $PATH:$JAVA_HOME/bin

#安装TOMCAT
ADD apache-tomcat-7.0.78.tar.gz ./

#发布网络端口
EXPOSE 9090

#部署应用
COPY monitor ./apache-tomcat-7.0.78/webapps/monitor

#启动Tomcat
CMD ./apache-tomcat-7.0.78/bin/startup.sh && tail -f apache-tomcat-7.0.78/logs/catalina.out 

以上的OK,将该文件夹打成zip包,通过:Linux的ftp工具发送到linux端

(本人是用本地虚拟机做的,如果你是ECS,建议先从网上下载对应的组件再进行对应的组装)

在这里插入图片描述

  1. 构建镜像

有了对应的组件集合之后就可以利用这些组件来构建镜像了

格式:docker build -t [镜像名]:[镜像标签] [存放dockerfile的目录]

语法格式演示:docker build -t wolfcode/monitor:1.0 /soft/dockerfiledir/build_monitor_image

在这里插入图片描述
之后查看生成的镜像
在这里插入图片描述
启动自定义的镜像
在这里插入图片描述
能启动到此步就说明成功了
在这里插入图片描述

常见的问题:一直卡在Starting ZkClient event thread

注意如果你的monitor是拷贝过来的,就一定要注意了,在webapps/WEB-INF/dubbo.properties文件中记得修改zookeeper的地址

第二个很常见的问题就是没有启动zookeeper进程,导致这边应用程序一直在尝试连接

多容器管理(docker-compose)

为什么需要多容器管理?

假如服务器遇到意外,N个容器被强制关闭了,那么此时是不是需要一个个去启动呢?

对,一个个搞会非常非常麻烦,所以需要 docker-compose 统一管理这些容器

docker-compose 是一个用于统一管理多个Docker容器的工具,它通过一个 yml 模板文件来配置,我们可以使用它来配置容器启动的参数

如:网络、数据卷、执行指令、环境变量、资源限制等等。除此之外,它还可以一键重启、关闭、删除、监控所有的 docker 容器。只需要一次配置,则可以对容器进行统一管理,那么此时我们则不必为了每次要运行一堆容器时写大量的命令而头疼。

  1. 安装 docker-compose:

方式一(不推荐,慢,且经常出问题):
(1)下载并安装docker程序:
curl -L “https://github.com/docker/compose/releases/download/1.9.0/docker-compose- ( u n a m e s ) (uname -s)- (uname -m)” -o /usr/local/bin/docker-compose # 安装 1.9.0 版本

(2)给docker-compose文件添加执行权限
chmod +x /usr/local/bin/docker-compose
docker-compose version # 查看版本号,测试是否安装成功

方式二:

(1)安装python-pip
yum -y install epel-release
yum -y install python-pip

(2)安装docker-compose
pip install docker-compose
待安装完成后,执行查询版本的命令确认安装成功
docker-compose version
在这里插入图片描述

  1. 配置 docker-compose.yml 文件

docker-compose.yml的作用是统一配置需要启动的容器,且docker-compose有个特点就是:一定要在docker-compose.yml所在的文件夹下启动docker-compose,docker-compose才会去使用对应的配置文件(可以实现分类配置启动,非常方便)

细节问题(关于语法):
以version: '2’为例,version:后面一定要接一个英文空格,这个是yml的语法规定,不然会出现解析错误,下面的各个xx:也是同样的道理

具体语法规则:

    version: '2' # docker 的版本
    services: # 配置的容器列表
        CONTAINER_NAME: # 容器的名称
            image: BASE_IMAGE # 这个一个容器的基础镜像
            ports: # 你的容器需不需要做端口映射
                - "host_port:container_port"
            volumes: # 数据卷配置
                - “host_dir:container_dir”
            environment: # 环境变量(map 的配置方式 key: value)
                PARAM: VALUE
            environments: # 环境变量(数组的配置方式 - key=value)
                - PARAM=VALUE
            restart: always # 容器的重启策略
            dns: # dns 的配置
                - "8.8.8.8"
------------------------------------------------------------------
            restart 容器的重启策略:
                no:默认策略,在容器退出时不重启容器
                on-failure:在容器非正常退出时(退出状态非0),才会重启容器
                on-failure:3:在容器非正常退出时重启容器,最多重启3次
                always:在容器退出时总是重启容器

现在我们根据上面的语法规则写一个最简单的yml配置:如下
在这里插入图片描述

  1. 常用命令

docker-compose up -d # 启动所有服务并在后台运行

在这里插入图片描述
docker-compose ps # 查看服务运行状态
在这里插入图片描述
docker-compose restart # 重启所有服务
在这里插入图片描述

docker-compose restart myApp # 重启 myApp(指定) 服务
在这里插入图片描述

docker-compose start # 启动所有服务

docker-compose start myApp # 启动 myApp(指定) 服务

docker-compose stop # 停止所有服务
在这里插入图片描述
docker-compose stop myApp # 停止 myApp (指定)服务

docker-compose rm # 删除所有服务
在这里插入图片描述

docker-compose rm myApp # 删除 myApp(指定)服务

猜你喜欢

转载自blog.csdn.net/fenghuoliuxing990124/article/details/85039350
今日推荐