容器化技术的发展主要分为三个阶段。 物理机时代->虚拟化技术->容器化技术
物理机时代:其实就是类似我们常见的机房,是真实纯在的机器。
缺点
虚拟化时代: 在一台机器上,分出其他系统,比如vmware,我们在自己的win10系统的中,分配中一部分cpu,内存 给虚拟机
优点
缺点
容器化时代:可以简单的理解为,不用安装操作系统的虚拟化技术
从上面的图我们可以知道,容器化技术,他把HostOS作为底层,每个APP使用的HostOs操作系统都是共享。而虚拟化技术,则是必须每个APP都需要安装他们对应的操作系统。
提问:有了容器化技术啦,是不是就不需要虚拟化技术啦
容器化虽然有虚拟化技术没有优点,但是我们还是不能放弃虚拟化技术。
因为容器化技术他注重的是APP之间的隔离,比如 打包依赖环境,比如们我项目中,给生产发版需要教运维,怎么配置config,配置环境。稍微有一个失败,就可能导致全局失败。而如果用了docker,就类似把这些以来全部压缩到一个文件,运维只需要拿到镜像,发布即可。
而虚拟化技术是物理资源层面的隔离,他可以随便分配cpu和内存之类的资源。两者注重的层面是不一致的。
由于docker 不需要hypervisor(虚拟机)实现硬件资源虚拟化
,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源. 因此在cpu,内存利用率上docker会更有明显优势安装参考官方链接:https://docs.docker.com/engine/install/centos/
安装环境要求:需要一个CentOS 7或8的维护版本
安装环节
1. 安装组件
yum -y install gcc
yum -y install gcc-c++
yum -y install yum-utils
2. 设置yum安装源头
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3. 优先使用较快的yum
yum makecache hostfile ## 适用于centos 7
dnf makecache ## 适用于centos 8
4. 安装docker
sudo yum install docker-ce docker-ce-cli containerd.io
##docker-ce 代表的是开源的社区版本
5. 启动docker
service docker start
6. 查看版本号
docker version
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://9ih5llc0.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
安装过程中遇到的汇总
1: Failed to start Docker Application Container Engine.
把刚配置的daemon.json上传到本地文件,检查下空格前是否有类似 ---- 的特俗字符
2:color=“blue”>inotify_add_watch(7, /dev/dm-3, 10) failed: No such file or directo
原因:是因为 xfsprogs 版本太低了。 解决方案:yum update xfsprogs
我们提到了诸如像镜像容器这样的专业名词。可能此时你有点一头雾水。 那么本节课咱们就来介绍这些基本的概念。让你对docker 首先有一个全面的了解。
首先作为docker,他被称为是一个容器化平台
。注意我的用词,它是一个平台
,所有的应用程序。都是基于这个平台来运行的,作为docker 这个平台提供了一个标准化的打包与运行程序的方式。通过下面这个图,我们可以清晰的了解到。
比如我们采购了一台物理机,或者采购了一台阿里云,腾讯云的虚拟机。这些能看得见,摸得着的,都被称之为可用资源
,其中包含了c p u 硬盘、内存等等。但是我们的应用程序。并不是像以前一样去直接操作这些合用资源,而取而代之是应用程序面向docker 引擎,也就是英文。docker engine 来尝试获取这些可用资源。大家看到这个中间层docker 引擎像什么吗?如果你对java 稍微熟悉一点,你会发现这其实和我们java 中的j v m 虚拟机非常的像,其中最关键的也就是。无论是docker 平台上的应用程序,还是我们java 中的应用程序,都不再直接面向底层的资源,而是通过一个中间层来进行操作。那么对于这个docker 引擎的部分,它又包含了三个子组件。咱们来看一下。
在这个docker 体系结构中,我们把关注点先放在左侧这个圆中。
docker 引擎呢它包含了三个部分,分别是
最核心的docker服务器,我们也称为docker demon 守护进程。
Rest Api 的通信层:在外侧。有一个基于rest api 的通信层以及最外层。
Docker 的客户端: 这个大圆代表了我们docker 的客户端。
镜像
作为docker 中最基础的文件呢是镜像文件,镜像文件是只读的。
他提供了完整。运行程序的软硬件资源是应用程序的集装箱。
这里有两个关键词,首先镜像它是一个文件。
其次,文件包含了所有的软硬件资源。
容器
容器是镜像的实例,由docker 负责创建。
容器之间是彼此隔离的。
每一个容器和容器之间独立管理资源呢也互不冲突。
通俗解释:
帮助启动类命令
启动docker : systemctl start docker
停止docker: systemctl stop docker
重启docker: systemctl restart docker
查看docker状态: systemctl status docker
开机启动: systemctl enable docker
查看docker概要信息: docker info
查看docker总体帮助文档: docker --help
查看docker命令帮助文档: docker 具体命令 --help
镜像命令
列出本地主机上的镜像 :docker images
-a :列出本地所有的镜像(含历史映像层)
-q :只显示镜像ID。
搜索镜像: docker search 镜像的名称
–limit : 只列出N个镜像,默认25个
docker search --limit 5 redis
拉取镜像: docker pull 镜像的名称[:TAG]
每没有Tag就是最新版
查看镜像/容器/数据库占用的空间: docker system df
删除镜像 docker rmi 某个镜像的名字Id
删除单个 docker rmi -f 镜像ID
删除多个 docker rmi -f 镜像名1:TAG 镜像名2:TAG
删除全部 docker rmi -f $(docker images -qa)
容器命令
新建+启动容器: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
OPTIONS说明(常用)
-name=“容器新名字” 为容器指定一个名称;
-d: 后台运行容器并返回容器ID,也即启动守护式容器(后台运行);
-i:以交互模式运行容器,通常与 -t 同时使用;
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
也即启动交互式容器(前台有伪终端,等待交互);
-P: 随机端口映射,大写P
-p: 指定端口映射,小写p
docker run -p(端口映射) 8000(宿主机端口):8080(docker容器端口号) -d(后台启动) tomcat
列出当前所有正在运行的容器:docker ps [OPTIONS]
OPTIONS说明(常用):
-a :列出当前所有正在运行的容器+历史上运行过的
-l :显示最近创建的容器。
-n:显示最近n个创建的容器。
-q :静默模式,只显示容器编号。
退出容器: exit or ctrl+p+q
run进去容器,exit退出,容器停止
run进去容器,ctrl+p+q退出,容器不停止
启动已停止运行的容器:docker start 容器ID或者容器名
重启容器:docker restart 容器ID或者容器名
启动已停止运行的容器:docker start 容器ID或者容器名
停止容器:docker stop 容器ID或者容器名
强制停止容器:docker kill 容器ID或容器名
删除已停止的容器:docker rm 容器ID
一次性删除多个容器实例
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
重要命令
启动守护式容器(后台服务器):docker run -d 容器名
1: docker run -it redis:6.0.8 前台交互式启动
2: docker run -d redis:6.0.8 后台守护式启动
查看容器日志 docker logs 容器ID
查看容器内运行的进程: docker top 容器ID
查看容器内部细节:docker inspect 容器ID
进入正在运行的容器并以命令行交互:docker exec -it 容器ID bashShell
1.重新进入docker attach 容器ID
2:attach 直接进入容器启动命令的终端,不会启动新的进程
3:用exit退出,会导致容器的停止。exec 是在容器中打开新的终端,并且可以启动新的进程
4:推荐大家使用 docker exec 命令,因为退出容器终端,不会导致容器的停止。
5: 案例 docker exec -it 容器ID /bin/bash
从容器内拷贝文件到主机上:docker cp 容器ID:容器内路径 目的主机路径
导入和导出容器
1: export 导出容器的内容留作为一个tar归档文件[对应import命令]
2: import 从tar包中的内容创建一个新的文件系统再导入为镜像[对应export]
3: 案例: docker export 容器ID > 文件名.tar
4: cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
将修改后的容器,制作为一个新的容器:
docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
比如你安装了一个ubuntu 镜像,但是不支持vim , 你在exec 容器内部,安装了vim, 想让这个安装vim的容器成为一个新的镜像
这个官方的docker仓库,可以理解为咱们常用的Maven仓库,在以后的开发中,我们会经常用到。在这里做个简单的了解和使用
在进行我们docker拉取镜像的试试,我们可以从上面的图,可以看出来。拉取的镜像主要分为Linux操作系统,JDK,Tomcat。所以我们也可以同样式使用linux命令,对容器内部进行操作。那么如何进入到容器内部呢?
格式 :docker -it 0728852zscsd535 /bin/bash
写成 docker -it 0728852zscsd535 bash
也行
参数解释
从这里也能看出,容器是镜像文件运行所产生的实例
查看容器版本
cat /proc/version
我们再来看看容器他给我们安装的jdk的版本
拉取的镜像和容器都存在了宿主机的那个位置呢?—> /var/lib/docker
Dockerfile的作用
前面的讲解,都是如何对 获取,删除镜像的讲解,那么如何自己创建一个镜像呢?此时 Dockerfile的意义就是创建镜像
什么是 Dockerfile
1、 Dockerfile是一个包含用于组合镜像的命令的文本文档
2、 Docker 通过读取Dockerfile中的指令按步自动生成镜像
案例需求:
之前我么拉取了一个tomcat镜像,现在我们想创建一个页面,把这个页面放到tomcat镜像中。并且能够正常访问
创建编辑Dockerfile文件。
FROM tomcat:lates
MAINTAINER tvunet.com
WORKDIR /usr/local/tomcat/webapps
ADD docker-web ./docker-web
构建镜像命令格式
docker build -t {机构名/镜像名称:版本号} {dockerfile路径, 下面的案例中.代表当前路径}
docker build -t tvunet.com/mywebapp:1.0 .
FROM
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210605174838155.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdG
LABEL & MAINTAINER
WORKDIR
ADD & COPY
ENV
在docker中,提供了三个命令,分别是RUN & CMD & ENTRYPYPOINT, 他们书写格式分别有Shell格式
和Exec格式(推荐)
Shell格式
RUN yum install -y vim
Exec命令格式
RUNN ["yum","install","-y","vim"]
格式案例 CMD[“ps”,“ef”] # 推荐使用exec格式
综上知道了两者的特点我们可以吧ENTRYPOINT和CMD综合使用
此时进行buit->run 结果为
如果我们想ps -aux ,可以在不进行修改dockerfile ENTRYPOINT的属性的情况下,直接传入参数 -aux,两者使用更加灵活。
总结:run 可以无限次,CMD 和 ENTRYPOINT 只能生效一次,但是cmd可以替换参数,而ENTRYPOINT 只能自己作为定值
为什么docker 会为run 提供2种方式,这里解释下
Shell 格式:
FROM centos:7
#定义路径的环境变量
ENV REDIS_HOME /usr/local
#安装YUM源
RUN yum -y update && yum -y install epel-release && yum -y install redis
#安装清理缓存文件
RUN yum clean all
#设置密码
RUN echo "requirepass 6jXL95Iv2BFisJNB" >> /etc/redis.conf
#设置端口
EXPOSE 6379
#启动
ENTRYPOINT [ "/usr/bin/redis-server","/etc/redis.conf"]
CMD []
. 代表,执行的命令为当前的dockerfile所在的路径。
docker build -t redis .
docker run -p 6379:6379 -d --restart always 61589feb102d
我们一直是在单个容器间进行操作,如果我们想要2个容器进行通信,如何操作呢?
在进行通信的时候,推荐使用给容器进行命名,而不是ip进行通信。
记这个 --name 是2个杠
docker run -d --name web tomcat
(此时一个名为web的tomcat 容器,就已经创建好啦)
docker run -d --name database -it centos /bin/bash
(centos 创建完后,就默认进行退出了状态,所以为了让容器保持运行,就需要 -it 进行交互模式,访问bin/bash 让他在后台运行)
查看容器的原数据,每个容器都有属于自己的ip
docker inspect 容器id
此时我们进入到另一个容器的内部,进行ping 刚刚看到容器的ip
那么我们如果进行名称的,ping的访问呢?
docker run -d --nam web --link database tomcat
此时我们在进行ping,就可以成功啦。 所以–name 的命名 也并不是没有意义的
如果发现ping 命令,没法使用的话进行如下的操作
1) apt-get update,这个命令的作用是:同步 /etc/apt/sources.list 和 /etc/apt/sources.list.d 中列出的源的索引,这样才能获取到最新的软件包。
2)等更新完毕以后再敲命令:apt-get install iputils-ping命令即可。
总结:
1. 一个容器 开启 -it /bin/bash 和 --name 准备和另一个容器进行配对
2. 另一个容器 开启 --link 连接容器的别名 进行通信
web容器绑定网桥 , database 同上
5. 当两者绑定成功之后,则进行对方容器进行ping 测试即可。
总结:
1.首先创建一个网桥
2. 双方容器都绑定网桥即可。
为什么要进行数据共享呢?-- > 如果我们自定义了镜像, 会在每个容器中有相同的副本, 在这个副本在不同的容器中是相同,加入此时我们对107.1.31.22 进行更新了页面,此时107.1.31.28,或者其他3000台以上机器也需要同步更新,就是件麻烦的事情啦。
解决方案 :在宿主机开辟一个空间,我们把文件放到开辟的共享空间即可。
数据共享的两种办法
通过设置-v挂载宿主机目录
其实也就是 我修改了我宿主机的webapps。 那么 也会同步 容器里面的webapps文件
实战:
比如说我们在这里dist文件夹,创建一个文件。然后进行挂载,如果这里面文件修改了,和他挂载的容器的路径对应的文件 也会进行修改
然后我们进入到容器,发现什么文件也没有。
现在我们在/opt/dist下创建一个文件,并且添加内容为123
缺点:进行挂载的时候,如果中间输错了一个字母,就会让挂载失败,所以我们来看下第二种方式。
通过 --volumes-from 共享容器内挂载点
这里其实就相当于给 挂载的路径设置了一个名称,共享容器 以后引用挂载点的别名就可以啦。修改挂载点的时候,修改共享容器的路径即可。
第二种方式和第一种类似,这里就不再演示啦。
总结:进行容器的挂载,当修改宿主机文件的时候,也会同步修改容器里面的文件。 其中挂载一共有2种方法,第二种类似创建一个全局变量,进行一个全局管理。
docker compose 帮我们解决多容器部署的麻烦事,比如你部署一个java服务,你还给运行 配置nginx ,mysql 。烦不烦。 docker compose 就是解决这个问题
具体的操作,参考官方文档 https://docs.docker.com/get-started/08_using_compose/
获取并且自动安装docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
进行授权
sudo chmod +x /usr/local/bin/docker-compose
输入如下命令,出现出图一致,则为安装成功
docker-compose -version
1:官方链接:https://docs.docker.com/compose/
将如下内容进行粘贴到 docker-compose,yml 中
这里内容,我就不给代码,自己去官方复制下。至于参数的含义,我们这里暂时先不了解。
docker-compose up -d
我们ps 一下,发现他已经帮我们run 并且帮我们映射了额端口,我们直接访问 下
经过了简单的初始话,我们来到了主页面
在这里我们准备一下 初始化的SQL脚本
在这个文件夹内,我们加入了配置文件和启动的jar
然后我们吧资源上传到linux 服务器,然后创建一个Dockerfile文件
构建结果如下
但是我们启动docker run 的时候发现数据,无法连接 ,因为没有数据库容器呀。。。
我们吧之前的初始化脚本进行上传,然后创建一个DockerFile文件, 进行编辑如下
在这里注意下WORKDIR:写的目的是官方说明的,初始化目录,如果
sh和sql的文件,放到这里的时候,此时mysql的启动的时候会自动进行执行脚本。
现在们项目和mysql 的都已经弄好啦, 那如何利用docker-compose 进行操作呢?
我们直接在app 和 db的两个父类文件夹路径 创建一个docker-compose.yml文件
利用dcker-compose up -d他会自动读取yml文件,并且后台运行,。
docker-compose logs 用于查看 后台运行的日志
docker-compose down
此时他自动创建了2个容器。