Docker镜像与容器
理解虚拟化
在实际生产环境中,虚拟化技术主要解决的是高性能的物理硬件性能过生和低性能硬件产能过低的重组重用,达到最大化的利用物理硬件,充分发挥其最大的作用
虚拟化技术的种类有很多,比如软件虚拟化,内存虚拟化,服务虚拟化,虚拟机等,比如VMware
理解Docker
Docker是实现轻量级的操作系统虚拟化解决方案,基于Linux容器
特别适用于微服务架构,我们也知道微服务架构是将一个应用拆成十几个微服务项目,Docker的容器就特别迎合这种部署架构;
一台宿主机可以创建多个Docker容器,每个容器互不影响,相互隔离,分别部署微服务架构的多个应用,尽可能的利用系统资源
虚拟化与Docker容器的比较
Docker容器是在操作系统层面上实现虚拟化,复用本地主机的操作系统,相当于调用一个应用一样,只要你有一个docker引擎,就能把本地操作系统复刻一个出来,当然系统还是只有一个系统
传统的虚拟机则是在硬件层面实现,在物理机上虚拟一个其他的系统,占用很多的内存,比如安装一个管理虚拟机的软件VMware,在Windows上通过虚拟机搭建Linux或者其他的环境,搭建的环境和本地操作系统是没有任何关系的
传统的虚拟机的启动和一个物理机的启动速度一致,比较慢且占大量内存,Docker容器技术并不是构建一个新的操作系统,而是调用本地的操作系统,所以启动速度比较快,且只占用小量的内存空间
Docker服务器与客户端
Docker是一个C/S架构程序(客服端-服务器),Docker客户端只需要向Docker服务器或守护线程发起请求,实现对Docker容器的管理,我们可以在一台机器上运行Docker的守护程序和客户端,也可以本地客户端连接远程Docker守护线程,实现远程管理
Docker镜像与容器
-
镜像
镜像是构建Docker的基石,用户基于镜像来运行自己的容器,镜像的体积很小,易于分享、储存、更新,我们这样理解或许会好很多,镜像就是一个面向Docker引擎的只读模版,包含了文件系统,比如我们在装Windows系统时,通过镜像来安装的话,这个镜像可以只是一个干净的只有操作系统的镜像,也可以是安装了360全家桶等程序的不干净镜像,它将特定的一系列文件按照一定的格式制作成单一的文件,便于下载和使用
-
Docker容器
一个Docker容器简单来说,包含三个东西:
一个镜像
一些列标准操作
一个执行环境
通过这张图,就能知晓容器的意义:
容器就像是一个轮船,上面装载了很多的软件,每一个软件看成一个集装箱,Docker使用Registry来保存用户构建的镜像,Registry分为公共和私有的两种,Docker公司运营的是Docker Hub,就像github一样的,我们可以在上面分享下载相关的镜像(速度超级慢!),私有的Registry需要我们自己构建
Docker的安装与启动
安装
-
环境CentOS7.X以上版本阿里云站点下载: http://mirrors.aliyun.com/centos/
-
然后再给一个CentOS7.X以上版本的网络环境配置指南:https://www.cnblogs.com/msi-chen/p/10922168.html
-
一般Docker都是挂载在CentOS7版本以上,6版本环境补全且很多补丁不支持更新
yum包更新到最新:sudo yum update
安装需要的软件包:sudo yum install -y yum-utils device-mapper-persistent-data lvm2
设置yum源:yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
查看Docker版本: yum list docker-ce --showduplicates | sort -r
默认安装最新免费版Docker: sudo yum install docker-ce
查看安装的docker版本:docker -v
设置镜像源
直接去国外获取镜像特别慢,我们需要设置国内的源,ustc是一个Linux镜像服务提供者,是一个不需要注册的公共服务
我这里出了一点小问题,没有默认的docker和daemon.json配置文件,touch daemon.json创建之
全自动方式执行:curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
手动方式:在文件中配置如下数据: vi /etc/docker/daemon.json
{"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]}
再给大家分享几个镜像源吧,有时候pull不下来,就换换试试
保存后重启即可:systemctl restart docker
Docker的启动相关命令
systemctl命令是系统服务管理指令
启动docker:systemctl start docker
停止docker:sysemctl stop docker
docker状态:systemctl status docker
重启docker:systemctl restart docker
开启启动docker:systemctl enable docker
docker概要信息: docker info
docker帮助文档:docker --help
如果运行报错,无法解决可以才去重新安装的方式:
查询安装过的包
yum list installed | grep docker
本机安装过旧版本
docker.x86_64,docker-client.x86_64,docker-common.x86_64
删除安装的软件包
yum -y remove docker.x86_64
yum -y remove docker-client.x86_64
yum -y remove docker-common.x86_64
Docker镜像相关命令
查看宿主机本地镜像:docker images
刚开始创建的Docker,本地是没有任何镜像的,所以下面没有数据
搜索镜像:docker search 镜像名称
拉取镜像:docker pull 镜像名称
查看本地镜像,就有tomcat的镜像了
删除镜像:docker rmi 镜像ID或者名称
之前我们拉取一个Tomcat镜像到本地,现在我们不想要它了,将其删除即可
docker rmi 365b0a528e2e 或者 docker rmi tomcat
Docker容器相关命令
-
查看容器
查看当前正在运行的容器:docker ps
查看所有的容器:docker ps -a
查看停止的容器:docker ps -f status=exited
-
容器的创建与启动
创建容器的常用参数说明:
创建容器的命令: docker create 或者docker run
-i:表示运行容器
-t:表示容器启动后会登录容器进去到其命令行,相当于一个伪终端
--name:为创建的容器命名
-v:表示目录映射关系(前者是宿主机目录,后者是映射到宿主机上的目录)
可以使用多个-v做多个目录或者文件映射,
注意:最好做目录映射,在宿主机上做修改共享到容器中
-d:在run后跟-d,就会创建一个守护式容器在后台运行(这样创建容器不会自动登录容器)
-p:表示端口映射,前者是宿主机端口,后者是容器内的映射端口,可以使用多个-p做多个端口映射
-e:表示设置该容器的环境变量,可以设置初始密码等
-
交互式方式 创建容器
创建:docker run -it --name=容器名称 镜像名称:标签 /bin/bash
如果镜像的标签是latest,可以不用标明,写一个镜像名称即可
下面我们创建一个包含了centos镜像的容器:
另开一个Linux连接终端,查看当前正在运行的容器:发现该容器
退出当前容器,容器也会关闭:exit
-
守护式方式创建容器
创建:docker run -di --name=容器名称 镜像名称:标签
登录:docker exec -it 容器名称(Name or ID) /bin/bash
退出还是:exit
只不过我们知识退出了那个伪终端,容器还是运行着的,效果自测
-
容器的启动与停止
启动: docker start 容器(Name or ID)
停止:docker stop 容器(Name or ID)
-
文件拷贝
有时候我们需要将文件拷贝到容器里去的需求,全程无需登录容器
docker cp 目标文件或文件夹 容器名称:容器目录
当然也可以从容器内拷贝数据出来
docker cp 容器名称:容器目录 指定资源存放路径
目录挂载
我们在创建容器的时候,将宿主机的目录与容器内的目录进行映射,这样我们就尅通过修改宿主机上某个目录的文件从而实现对容器内想映射的文件的数据
创建容器时创建文件/文件夹映射:docker run -di --name=mycentos3 -v /usr/my.txt:/usr/my.txt centos
登录容器观察变化docker exec -it mydentos3 /bin/bash
我们在宿主机上修改my.txt,即可实现对容器内my.txt数据的修改
注意事项:如果挂载的是多级目录,可能会有权限不足的警告
查看容器IP地址
我们可以通过下面的命令来查看容器运行的各种数据:docker inspect 容器(Name or ID)
当然上面的信息太多了,一般我们就提取一个ip最为常用:
docker inspect --format='{{.NetworkSettings.IPAddress}}' mycentos3
前面均为固定格式,最后指定那个容器即可
删除容器
删除容器:docker rm 容器(Name or ID)
删除镜像:docker rmi 镜像(Name or ID)
这里说一下,当我们的镜像正在被某个运行着的容器使用着的时候是不能删除的,需要关闭相关的容器才能删除该镜像
常用软件的部署
MySQL部署
拉取镜像:docker pull centos/mysql-57-centos7
创建容器:docker run -di --name=mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 centos/mysql-57-centos7
-p:端口映射,位于前面的是宿主机的端口,处于后面的是容器里的端口
-e:代表添加环境变量,设置Mysql的Root用户的登陆密码
进入到MySQL容器: docker exec -it mysql /bin/bash
登录到MySQL
bash-4.2$ mysql -uroot -p Enter password: (不用键入密码,回车即可)
SQLYog连接MySQL试试:
Tomcat部署
还是和上面一致,首先搜索Tomcat :docker search tomcat
拉取最上面的那个tomcat镜像到本地:docker pull tomcat
创建容器:docker run -di --name=myTomcat -p 8080:8080 -v /usr/local/wabapps:/usr/local/tomcat/webapps tomcat
这里做一个说明 -v是文件挂载,我们只需要将war包丢在宿主机下的/usr/local/wabapps目录即可对容器内的Tomcat起作用
/usr/local/tomcat/webapps:是Docker容器Tomcat的安装目录
为了方便测试,我们丢一个war包到宿主机的/usr/local/wabapps下
打开浏览器访问即可:OK
Nginx部署
到这里我相信大家闭着眼都知道怎么操作了吧?
首先对我们安装的环境进行搜索:docker search nginx
拉取镜像到本地 :docker pull nginx
创建运行容器对外提供服务 :docker run -di --name=myNginx -p 80:80 nginx
当然到这里还没完,不然我也不会写出来了,Nginx还有一些需要特别注意的事项
现在环境倒是安装好了,Ngin如何对我们的静态资源进行代理?CP拷贝?Nginx配置文件不配?
首先我们进入到Nginx容器:
看一下这个配置文件呢?
先赋值一个副本出来,以防万一。我们在副本中动手脚
到这里我们就可以动点脑壳了,如何才能对资源进行动态代理呢?将我们的资源拷贝到/usr/share/nginx/html/下?
我们通过cp拷贝一个index.页面到 /usr/share/nginx/html/试试?
Redis部署
按部就班,天黑请闭眼
首先对我们安装的环境进行搜索:docker search redis
拉取镜像到本地 :docker pull redis
创建运行容器对外提供服务 :docker run -di --name=myRedis -p 6379:6379 redis
就不做过测试了,这个没什么好说的,我们使用客户端连接一下即可:
Docker迁移与备份
容器保存为镜像
-
当我们将该容器保存为镜像的时候,该容器的数据还是一五一十的全部存在的
docker commit 容器(Name or Id) 生成的镜像Name
镜像备份
docker save -o mynginx.tar mynginx_i
镜像迁移与恢复
为了做测试,我们就想myNginx这个容器和与之相关的镜像都删掉,然后通过mynginx.tar 去创建新的镜像和容器
再补上一步,删除我们容器保存下来的镜像:docker rmi mynginx_i
然后我们通过之前备份的镜像文件 mynginx.tar试图恢复:docker load -i mynginx.tar
镜像已经恢复,我们创建容器用它创建容器,再次提供服务试试:
docker run -di --name=myNginx -p 888:80 mynginx_i
Dockerfile脚本
Dockerfile简单介绍
Dockerfile就是一系列命令和参数构成的脚本,在基础镜像创建新镜像的时候被运用,说起来可能有点抽象,下面我们演示一下,你就会尤其有深刻的印象
先把常用的命令记下来,后面在解释:
命令 | 解释 |
---|---|
FROM 镜像:tag | 定义了使用那个基础镜像构建新的镜像 |
MAINTAINER user_name | 声明镜像的创建者 |
ENV key value | 设置环境变量,可以写多条 |
RUN command | 是Dockerfile和核心部分,可以写多条,在容器内会被执行 |
ADD file file | 将宿主机上的文件复制到容器内,如果是压缩文件,会自动解压 |
COPY file file | 和ADD相似,区别在于如果是压缩文件,不会自动解压 |
WORKDIR pathDir | 设置工作目录 |
EXPOSE port1 port2 | 指定端口,使容器内的应用可以和外界进行交互 |
CMD argument | 在构建容器时,会被docker run 后的argument覆盖 |
ENTRYPOINT argument | 和CMD相似,但不会被docker run后指定的参数覆盖 |
VOLUME | 将本地文件夹或者其他容器的文件挂在到容器中 |
使用脚本创建镜像
首先我们上传我们的jdk8到Linux上,我把它上传到:/usr/local/jdk8/ 下
然后我们对其进行解压,获得它解压后的名称后即可删掉解压了得文件,留下压缩包即可
创建一个固定文件名的Dockerfile文件,作为脚本文件,并键入数据:
保存退出,执行以下命令,通过这个脚本创建
新的镜像: docker build -t='jdk1.8' .
docker build :构建命令
-t=' ' :给创建的新镜像命名
. :指定Dockerfile的路径, .表示在当前路径下
然后就报错了:没有这个文件或者文件夹?然后我又试着修改了一下
再次构建试试:构建成功了一个基于Centos环境基础的带有jdk的镜像
Docker私有仓库
私有仓库的搭建和配置
dockerhub用于托管一些共同的镜像,就想github一样,一般在企业中都是不会将代码托管到开放到公共的平台上,这个时候,我们都会搭建一个私服,用于存放我们自己自定义的一些数据,一方面是为了安全,另一方面是想完成小范围的共享;
在docker容器中运行原生的私有仓库:
docker pull registry
运行仓库:
docker run -di --name=regirstry -p 5000:5000 regirstry
私有仓库就算是搭建完成了,我们可以启动浏览器测试一番:看到这里私有仓库就算搭建完成了
修改daemon.json。让docker信任私有仓库地址
vi /etc/docker/daemon.json,上一条数据是我们的的镜像源地址
重启Docker服务即可完成
私库镜像的上传与下载
在本地镜像的上传之前,我们需要将registry服务开起来:
docker start registry
上传第一步:打标签,标记此镜像为私有仓库的镜像
docker tag jdk1.8 192.168.159.189:5000/jdk1.8
上传第二部:推送到私服
docker push 192.168.159.189:5000/jdk1.8
通过浏览器,查看:镜像推送成功
当我们想要下载该镜像的时候,记得修改daemon.json对该私服的信任,重启docker
docker pull 192.168.159.189:5000/jdk1.8即可完成下载