DevOps

docker学习

2020-04-29  本文已影响0人  今年五年级

一 基本介绍

1. 什么是docker

Docker是一个开源的应用容器引擎,基于Go语言开发
Docker可以让开发者打包他们的应用与依赖到一个轻量级,可移植的容器中,然后发布到任何流星的Linux机器上,也可以实现虚拟化
容器完全使用沙箱机制,相互之间不会有任何接口且容器性能开销极低

传统虚拟机技术 VS Docker容器技术

特性 容器 虚拟机
启动速度 快,秒级 慢,分钟级
性能 接近原生 较弱
内存代价 很小 较多
磁盘使用 小,MB甚至KB 非常大,一般为GB
运行密度 单机支持上百个甚至上千个 一台宿主机上十几个,最多几十个
资源利用率

总结:Docker技术可以让我们更加高效轻松的将任何应用在Linux服务器部署

2. docker架构

3. docker容器文件挂载与端口映射

每docker run一下就会启动右边这样的一个容器,我们启动的容器是一个完整的运行环境,怎么体现完整性呢?因为mysql是安装在linux里面的,所以这个容器就是一个完整的linux

即:每一个docker容器都是一个完整的运行环境,是一个完整的linux,
那mysql安装到了这个linux里面,那mysql默认就有了一个端口3306,但是这个端口相当于是在2009870e21c3这个容器内部用的端口,如果我们想要使用mysql,需要将3306映射到linux

所谓的挂载就是容器内部的mysql运行,只要给/var/log/mysql产生了日志,那么我们就可以在linux下创建的文件夹下看到这个日志,有点像电脑的快捷方式,即相当于把我们容器内部的mysql的/var/log/mysql这个文件夹快捷方式放在我们linux外部的/mydata/mysql/log这个位置

所以我们在上面挂载了三个文件夹,第一个是容器内部mysql日志挂载到linux虚拟机外面创建了快捷方式
第二个是容器内部mysql相关配置信息/etc/mysql挂载到外部/mydata/mysql/conf目录下,相当于我们以后如果想要改mysql的配置,就进linux里面,来到/mydata/mysql/conf目录下,找我们配置,改了以后容器内部的/etc/mysql对应的配置也就跟着改了
第三个是把容器内部mysql运行期间的一些数据/var/lib/mysql(如mysql数据库运行期间需要持久化保存的一些数据都挂载到外部/mydata/mysql/data)

二 下载安装

Docker 是一个开源的商业产品,有两个版本:社区版(Community Edition,缩写为 CE)和企业版(Enterprise Edition,缩写为 EE)。企业版包含了一些收费服务,个人开发者一般用不到。下面的介绍都针对社区版

  1. Docker 要求 CentOS 系统的内核版本高于 3.10,通过 uname -r命令查看你当前的内核版本

  2. 使用 root 权限登录 Centos。确保 yum 包更新到最新
    yum -y update

  3. 卸载旧版本(如果安装过旧版本的话)
    yum remove docker docker-common docker-selinux docker-engine

  4. 安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
    yum install -y yum-utils device-mapper-persistent-data lvm2

  5. 设置yum源
    yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

  6. 查看所有仓库中所有docker版本,并选择特定版本安装
    yum list docker-ce --showduplicates | sort -r

  7. 安装docker(由于repo中默认只开启stable仓库,故这里安装的是最新稳定版20.10.8:2021-08-03)
    sudo yum install docker-ce-20.10.8-3.el7

  8. 启动并加入开机启动
    systemctl start docker.service启动docker
    systemctl enable docker.service设置docker开机自启动
    systemctl restart docker.service重启docker

  9. 验证安装是否成功(有client和service两部分表示docker安装启动都成功了)
    docker version

  10. 卸载docker
    yum -y remove docker-engine

三 基本概念

包含三大概念:镜像(image),容器(container),仓库(repository)
镜像相当于应用的安装包,在Docker部署的任何应用都需要先构建成为镜像,仓库是存放镜像的场所(容器是Docker镜像的载体,每个应用都分别运行在Docker的每个容器中)

1. 镜像

获取镜像的两种方式

  1. 通过dockerfile自行构建
  2. 通过docker pull拉取已有仓库镜像(docker pull从远程仓库拉取镜像到本地)

寻找镜像
docker search mysql
可能报如下错误
Error response from daemon: Get https://index.docker.io/v1/search?q=mysql&n=25: dial tcp 34.193.164.221:443: i/o timeout
【解决方式1】:
使用阿里云镜像加速器地址,登录阿里云(https://cr.console.aliyun.com/#/accelerator)


cd /etc/docker,查看有没有 daemon.json。这是docker默认的配置文件
如果没有新建,如果有,则修改。
vim daemon.json
{
"registry-mirrors": ["https://上面获取到的地址.mirror.aliyuncs.com"]
}
保存退出
重启docker服务

【解决方式2】:
如果上述方式无法成功,采用

  1. cat /etc/resolv.conf查看本机dns地址
  2. 通过dig @183.60.83.19 registry-1.docker.io找到可用IP,其中@后面的是本机的dns地址
  3. 尝试修改/etc/hosts强制docker.io相关的域名解析到其它可用IP52.55.198.220 registry-1.docker.io以后再次尝试

备注:\color{red}{如果以上方法还不行,如果为云服务器,检查流量出方向是否放行! }

下载镜像
使用命令docker pull命令即可从 Docker Registry上下载镜像,执行该命令后,Docker会从 Docker Hub中的 java仓库下载最新版本的java镜像。如果要下载指定版本则在java后面加冒号指定版本,例如:docker pull java:8
列举本地所有镜像
docker images


以上列表含义如下

删除镜像(rmi=remove image)
docker rmi -f 镜像名称/镜像ID

查看已下载的Docker镜像latest具体版本
docker image inspect nginx:latest|grep -i version

2. 容器

2.1 容器操作命令

-i:运行容器
-d:后台守护进程方式运行容器、
--name:给容器添加名称
-p:公开容器端口给当前宿主机(p是public)
-v:挂载目录
-p选项:公开容器端口给当前宿主机(p是public),指定端口映射,有以下四种格式

-- ip:hostPort:containerPort
-- ip::containerPort
-- hostPort:containerPort
-- containerPort

--net选项:指定网络模式,该选项有以下可选参数:

--net=bridge:默认选项,表示连接到默认的网桥
--net=host:容器使用宿主机的网络
--net=container:NAME-or-ID:告诉 Docker让新建的容器使用已有容器的网络配置
--net=none:不配置该容器的网络,用户可自定义网络配置

docker run -d -p 91:80 nginx这样就能启动一个 Nginx容器。在本例中,为 docker run添加了两个参数,含义如下:
-d 后台运行
-p 宿主机端口:容器端口 // 开放容器端口到宿主机端口

我们启动了tomcat容器,但是无法直接通过宿主机ip + 容器启动的端口访问,因为容器的端口并未开放给我们的宿主机来访问,我们需要在创建容器的那一刻开放一个端口才能在外部去访问这个容器冒号左边是公开给外界访问的端口,右边是容器的端口。将容器本身的端口公开给外面进行访问,外面是用91访问的容器的80端口*
访问 http://Docker宿主机 IP:91/,将会看到nginx的主界面

容器与宿主机之间的数据拷贝
Docker cp 命令 | 菜鸟教程 (runoob.com)

启动容器的两种方式

docker run和docker start的区别
一个是新建并启动 一个是启动已有的,docker run相当于执行了两步操作:将镜像放入容器中(docker create),然后将容器启动,使之变成运行时容器(docker start),即
docker run = docker create + docker start

2.2 容器的前台运行和后台运行

docker 容器默认会把容器内部第一个进程,也就是pid=1的程序作为docker容器是否正在运行的依据,如果docker 容器pid挂了,那么docker容器便会直接退出,也就是说Docker容器中必须有一个前台进程,否则认为容器已经挂掉。
因此你要在容器里运行的程序以前台进程的形式运行,当然,如果你的容器需要同时启动多个进程,那么也只需要,或者说只能将其中一个挂起到前台即可。
前台运行(可以通过停止命令行中断)
第一步:找到需要运行的镜像的名称和tag

第二步:执行如下命令
docker run -i 镜像名称:标签(如果是最新版,可以不加标签)

后台运行
docker run -di 镜像名称:标签(如果是最新版,可以不加标签)

3. 镜像与容器区别

镜像是文件,容器是进程
容器基于镜像创建,即容器进程依赖于镜像中的文件(如运行所需可执行文件,依赖软件),如tomcat进程依赖于运行所需的配置文件等等

四 将服务运行在docker上

4.1. 使用Dockerfile构建Docker镜像

Dockerfile是一个文本文件,其中包含了若干条指令,指令描述了构建镜像的细节
Dockerfile就是我们用来构建Docker镜像的源码,当然这不是所谓的编程源码,而是一些命令的组合,只要理解它的逻辑和语法格式,就可以编写Dockerfile了。
简单点说,Dockerfile的作用:它可以让用户个性化定制Docker镜像。因为工作环境中的需求各式各样,网络上的镜像很难满足实际的需求。

先来编写一个最简单的Dockerfile,以前文下载的Nginx镜像为例,来编写一个Dockerfile修改该Nginx镜像的首页

  1. 新建文件夹/app,在app目录下新建一个名为Dockerfile的文件,在里面增加如下内容:
FROM nginx
RUN echo '<h1>hello,this is dockerfile test on nginx</h1>'> /usr/share/nginx/html/index.html

该Dockerfile非常简单,其中的 FORM、 RUN都是 Dockerfile的指令。 FROM指令用于指定基础镜像, RUN指令用于执行命令

  1. 在Dockerfile所在路径执行以下命令构建镜像:
    docker build -t nginx:naughty-man ./
    其中,-t指定镜像名字,命令最后的点(.)表示Dockerfile文件所在路径
  2. 执行以下命令,即可使用该镜像启动一个 Docker容器
    docker run -d -p 92:80 nginx:naughty-man
  3. 访问 http://Docker宿主机IP:92/,可看到下图所示界面

Dockerfile常见命令

命令 作用
FROM image_name:tag 非常核心的基础镜像
MAINTAINER user_name 声明镜像作者
ENV key value 设置环境变量(可以写多条)
RUN command 编译镜像时运行的脚本(可以写多条)
CMD 设置容器的启动命令
ENTRYPOINT 设置容器的入口程序
ADD <src> <dest> 添加文件,从src目录复制文件到容器的dest,其中 src可以是 Dockerfile所在目录的相对路径,也可以是一个 URL,还可以是一个压缩包
COPY <src> <dest> 拷贝文件,和ADD命令类似,但不支持URL和压缩包
WORKDIR path_dir 设置工作目录
ARG 设置编译镜像时加入的参数
VOLUMN 设置容器的挂载卷
EXPOSE 声明容器在运行时对外提供的服务端口

注意:RUN命令在 image 文件的构建阶段执行,执行结果都会打包进入 image 文件;CMD命令则是在容器启动后执行。另外,一个 Dockerfile 可以包含多个RUN命令,但是只能有一个CMD命令。

注意,指定了CMD命令以后,docker container run命令就不能附加命令了(比如前面的/bin/bash),否则它会覆盖CMD命令。

注意:
docker -v 和Dockerfile 中VOLUME 区别
Dockerfile 中的 VOLUME 与 docker -v 区别

4.2 镜像构建示意图

4.3 使用Dockerfile构建服务镜像

下面我们通过几个步骤将我们所写的springboot项目jar包制作成镜像

  1. 上传我们需要部署的应用程序jar包到linux的/app/server目录,在jar包所在目录创建名为Dockerfile的文件
  2. 在Dockerfile中添加以下内容
# 基于哪个镜像,为java程序,因此依赖的基础镜像是java
FROM java:8  
# 将本地文件夹挂载到当前容器
VOLUME /tmp
# 文件的名字通过一个参数来传递,这里定义一个JAR_FILE的参数名,比如myTestServer.jar
ARG JAR_FILE
# 拷贝外面传进来的文件到镜像里面,然后命名为app.jar
ADD ${JAR_FILE} ./app.jar
# 声明需要暴露的端口
EXPOSE 8090
# 配置容器启动后执行的命令
ENTRYPOINT [“java”,"-jar","/app.jar"]
  1. 使用docker build命令构建镜像
    docker build --build-arg JAR_FILE=myTestServer.jar -t mytestserver:0.01 ./

使用-t选项指定了镜像的标签,mytestserver为镜像名称,0.01为标签(镜像名称必须为小写英文),最后的./表示到当前目录去查找Dockerfile文件
流程为先去下载基础镜像,然后在向下制作镜像

  1. 查看镜像是否构建成功 docker images
  2. 启动镜像,加-d可在后台启动
    docker run -p 9007:8090 mytestserver:0.01
  3. 访问http://Docker宿主机IP:9007/,可正常显示我们自己的服务首页
  4. 查看容器日志docker logs -f 容器id

4.4 使用Dockerfile编译、生成镜像

上面构建镜像我们需要手动敲命令,很不方便,插件 dockerfile-maven-plugin 可以帮助我们自动读取项目下的Dockerfile文件构建Docker镜像

(1)在项目根目录下创建Dockerfile文件
(2)在pom文件中添加如下配置

 <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <repository>${project.artifactId}</repository>
                    <buildArgs>
# 获取到当前项目打包后最终的jar包名字
                        <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                    </buildArgs>
                </configuration>
            </plugin>

(3)执行mvn clean package dockerfile:build,这样就能触发上面的插件执行来帮我们构建生成镜像

4.5 一些相关的命令

docker login
登录 Docker镜像仓库,默认是 Docker hub

上一篇下一篇

猜你喜欢

热点阅读