深入理解Docker

1 Docker理论

1.1 背景知识

​ **传统软件开发与运维痛点:**一款产品从开发到上线,从操作系统到运行环境,再到应用配置。作为开发+运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对的问题,特别是各种版本的迭代之后,不同版本环境的兼容,对运维人员都是考验。Docker之所以发展如此迅速,也是因为它对此给出了一个标准化的解决方案。环境配置如此麻烦,换一台机器,就要重来一次,费力费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装? 也就是说,安装的时候,把原始环境一模一样地复制过来,消除协作编码时“在我的机器上可正常工作,在他人机器上不能运行”的问题。
从而打破之前开发人员只提供代码(代码即应用)的方式,改为提交Docker镜像包括(运行文档、配置环境、运行环境、运行依赖包、操作系统发行环境),即镜像即应用。

1.2 是什么

​ Docker是基于Go语言实现的云开源项目。Docker的主要目标是"Build,Ship and Run Any App,Anywhere",也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP (可以是一个WEB应用或数据库应用等)及其运行环境能够做到“一次封装,到处运行”。

​ Linux容器技术的出现就解决了这样一个问题,而Docker就是在它的基础上发展过来的。将应用运行在Docker容器上面,而Docker容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,换到别的机子上就可以一键部署,大大简化了操作。

在这里插入图片描述

与虚拟机的区别?
虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,比如在Windows系统里面运行Linux系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。这类虚拟机完美的运行了另一套系统,能够使应用程序,操作系统和硬件三者之间的逻辑不变。

虚拟机的缺点:
1、资源占用多 2、冗余步骤多 3、启动慢(分钟级别)

在这里插入图片描述

1.3 Docker基本三要素

仓库Repository + 镜像Image + 容器Container

在这里插入图片描述

仓库Repository—>镜像Image(类Person)–>容器Container(对象p1、p2)

  1. 仓库Repository是存放镜像文件的场所,仓库Repository与仓库注册器Registry是有区别的,仓库注册服务器上往往存放多个仓库,每个仓库有多个镜像,每个镜像有不同的标签tag(仓库分为公开仓库public和私有库private,最大的仓库Docker Hub,但由于其服务器在国外,从中拉去镜像速度很慢,国内一般使用的是阿里云、网易云。)
  2. 镜像Image就是从docker Hub仓库拉取到本地的一个只读的模版,镜像Image用来创建容器Container,一个镜像可以创建多个容器
    镜像Image(类)—>容器Container(对象)
  3. Docker本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就似乎image镜像文件。只有通过这个镜像文件才能生成Docker容器(集装箱)。

1.4 镜像原理

在这里插入图片描述

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时库、环境变量和配置文件。

​ UnionFS (联合文件系统) : Union文件系统(UnionFS) 是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

	特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

1.5 安装教程

1. Docker官网:https://www.docker.com
2. Docker Hub官网:https://hub.docker.com
3. MAC安装教程:https://docs.docker.com/desktop/install/mac-install/
4. LinuxC安装教程
# 1.移除以前docker相关包
	yum remove docker* 															
# 2.配置yum源
    sudo yum install -y yum-utils
    sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 

# 3.安装docker并启动
    sudo yum install -y docker-ce docker-ce-cli containerd.io  					# 安装docker及其组件
    yum install -y docker-ce-20.10.7 docker-ce-cli-20.10.7  containerd.io-1.4.6 # 以下是在安装k8s的时候使用,暂时不安装
    systemctl enable docker --now		# 启动docker,并设置开机自启动,首次优先使用该命令
    service docker status				# 查看状态
    service docker start        		# 启动
    service docker stop					# 停止

# 4.配置加速
    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://82m9ar63.mirror.aliyuncs.com"],
      "exec-opts": ["native.cgroupdriver=systemd"],
      "log-driver": "json-file",
      "log-opts": {
        "max-size": "100m"
      },
      "storage-driver": "overlay2"
    }
    EOF

    sudo systemctl daemon-reload
    sudo systemctl restart docker

2 Docker常用命令

2.0 防火墙相关命令

sudo firewall-cmd --list-all --zone=public                         # 查看防火墙对外提供访问的接口
sudo firewall-cmd --zone=public --add-port=80/tcp --permanent      # 开放TCP端口80(HTTP)
sudo firewall-cmd --zone=public --remove-port=80/tcp --permanent   # 关闭TCP端口80(HTTP
sudo firewall-cmd --permanent --query-port=80/tcp                  # 查看端口是否开启
service firewalld status
service firewalld stop
service firewalld start
service firewalld restart

2.1 镜像命令

1 帮助命令:
	docker version
	docker info
	docker --help

2 镜像命令:
	1、列出本地镜像:docker images [-options]
		-a:列出本地所有镜像
		-q:只显示镜像ID
		--digests:显示镜像的摘要信息
		--no-trunc:显示完整的镜像信息
		docker images -a
		docker images -q
	2、查询DockerHub镜像:docker search [-options] 镜像名
		docker search tomcat:列出tomcat的镜像
		docker search --no-trunc tomcat:显示完整的镜像描述
	3、下载镜像到本机:docker pull 镜像名
        docker pull tomcat   		下载最新镜像tomcat,等同于docker pull tomcat:latest
        docker pull redis:6.2.4 	下载指定版本镜像
	4、删除本机镜像:docker rmi -f 镜像名/镜像id
		docker rmi [-f] tomcat

在这里插入图片描述

2.2 容器命令

容器命令:有镜像才能实例化容器(提前下载一个centos镜像仅有200MB)
	1、新建并启动一个容器:docker run [-options] 具体镜像名称:版本号 /bin/bash:
		--name:容器的新别名
		-i:以交互方式启动容器,通常与-t同时使用
		-t:为容器分配一个伪输入终端
		-d:以守护进程方式启动容器

以交互方式启动容器(为主):前台启动
		docker run –it --name my-centos centos:7 /bin/bash
以守护进程方式启动容器:运行在后台
		docker run -d --name=mynginx --restart=always -p 88:80 nginx

	2、列出所有正在运行的容器: docker ps [-options] 
        -l:显示最近创建的容器
        -n 2:显示最近2个创建的容器
        -a:显示当前多元的正在运行的容器+历史上运行过的
        -q:静默模式,只显示容器编号
        --no-trunc:不截断输出显示
    
    3、退出容器
        exit:			在容器内,关闭该容器并推出
        ctrl+P+Q: 在容器内,关闭该容器但是不推出
	
    4、停止容器				docker stop 容器名称或容器id
    5、强制停止容器		   docker kill容器名称或容器id
    6、重启容器	 			docker restart 容器名称或容器id
    7、删除容器				docker rm 容器名称或容器id
    8、查看容器日志		   docker logs [-options] 容器名称或容器id
    	docker logs -f 3063af3e3f86    

2.3 进阶命令

1、进容器内部
	docker exec -it 容器id  /bin/bash  # 在新的容器中打开新的命令终端,可以启动新的进程
2、挂载数据到外部修改
	docker run --name=mynginx \ 
	-d --restart=always \
	-p  88:80 \
	-v /data/html:/usr/share/nginx/html:ro \ # 修改页面只需要去主机的 /data/html
	nginx:latest 
3、镜像分享方案一
    docker save -o mynginx.tar nginx # 将镜像保存成压缩包
    docker load -i abc.tar 			 # 别的机器将压缩包加载为镜像
4、镜像分享方案二【需要docker hub账号】
	docker commit -m "首页变化" 341d81f7504f guignginx:v1.0  # 将自己修改好的镜像提交
	在docker hub 注册仓库
	docker tag guignginx:v1.0 leifengyang/guignginx:v1.0 	# 把旧镜像的名字,改成仓库要求的新版名字
	docker login  							# 登录到docker hub
	docker push leifengyang/guignginx:v1.0  # 推送
	docker logout 							# 推送完成镜像后退出
	docker pull leifengyang/guignginx:v1.0  # 别的机器下载
5、查看容器运行情况
	docker top 容器名称或容器id   # 查看容器内运行的进程
	docker inspect 容器名称或容器id # 查看容器内部细节
	docker attach 容器名称或容器id # 进入正在运行的容器并以命令行交互, 不会启动新的进程
6、从容器内拷贝文件到主机上:		
	docker cp 容器id: 容器路径 目的主机路径

在这里插入图片描述

3. 实战之Docker部署springboot项目

需求:

  1. 手动部署:本地IDE打包成jar,在docker环境中创建java环境容器,将jar包使用命令行拷贝至docker容器中,启动。
  2. 自动部署:通过Maven插件配置参数自动部署。(优先选这个)

步骤一:Springboot项目配置

1.1 添加docker的maven依赖

		<plugins>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.2.2</version>
                <configuration>
                    <imageName>docker/${project.artifactId}</imageName> <!-- 镜像名称  -->
                    <dockerDirectory>src/main/docker</dockerDirectory>  <!-- Dockerfile文件存放目录:后续改为项目根目录,后续Dockfile文件一定要放在这 -->
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>

            <!--这个插件,可以将应用打包成一个可执行的jar包-->
  					<!--千万不能丢掉,不然web项目没有main入口-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.5.2</version>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>

1.2 新建Dockfile构建镜像

# 基于openjdk 镜像,如果镜像不是本地的会从 DockerHub 进行下载
FROM openjdk:8

# VOLUME 指向了一个/tmp的目录,由于 SpringBoot使用内置的Tomcat容器,Tomcat 默认使用/tmp作为工作目录。
# 这个命令的效果是:在宿主机的/var/lib/docker目录下创建一个临时文件并把它链接到容器中的/tmp目录
VOLUME /tmp

# 作者
MAINTAINER zhupeng

# 将本地JAR包打包到容器中,并重命名
ADD springboot-1.0-SNAPSHOT.jar app.jar

# 声明需要暴露的端口 在Dockerfile中声明了那些端口是需要开放的,在构建容器时通过-p可以随机映射端口,如果EXPOSE没有指定端口,那么使用-p参数无效。本配置只是声明,一般我们需要在构建docker容器时使用-p(小写的p)指定开放的端口。
EXPOSE 8080

# 配置容器启动后执行的命令
ENTRYPOINT ["java","-jar","app.jar"]

1.3 执行构建命令

mvn clean package -Dmaven.test.skip=true docker:build # 前提要有docker环境

PS:如果还win执行mvn指令:mvn clean package ‘-Dmaven.test.skip=true’

在这里插入图片描述

步骤二 启动docker镜像

 docker images -a
 docker run -d --name my-springboot -p 8080:8080 docker/springboot-multipart [务必指定暴露端口]
 
 docker ps -a
 docker logs -f 976e5ee13513ed3

在这里插入图片描述

步骤三:访问测试

http://10.1.42.71:8080/test/show

在这里插入图片描述

坑:镜像无法启动

如果没连接数据库的话,是可以正常启动的,但是如果application.yml连接了数据库,那就会无法启动。

Host '10.1.42.71' is not allowed to connect to this MySQL server" MySQL不允许远程登录

解决方案:
1. update user set host = '%' where user = 'root'; 会警告报错
2. UPDATE `mysql`.`user` SET `Host` = '%' WHERE (`Host` = 'localhost') and (`User` = 'root');
   或者手动改

use mysql;
Select user from mysql.user; MySQL 服务器中所有用户的列表
mysql -u root -h 10.1.42.71 -p: MySQL远程登录

4. 实战之Dockerfile编写指南

https://zhuanlan.zhihu.com/p/143109114

Dockerfile中文名叫镜像描述文件,是一个包含用于组合镜像目录的文本文档,也可以叫“脚本”。他通过读取Dockerfile中的指令安装步骤自动生成镜像。

补充:文件名称必须是:Dockerfile

基础命令

# 1. FROM
# 制作基础镜像:基于openjdk 镜像
FROM openjdk:8

# 2. MAINTAINER
# 谁创造了它(作者信息)
MAINTAINER zhupeng

# 3. WORKDIR
# 类似于Linux中的cd命令:cd高级的地方在于,若发现没有这个目录,就自动创建出来,建议使用绝对路径
WORKDIR /usr/local/testdir

# 4.COPY
# 文件拷贝
# 案例一:将1.txt拷贝到根目录下。它不仅仅能拷贝单个文件,还支持Go语言风格的通配符,比如如下:
COPY 1.txt /
# 案例二:拷贝所有 abc 开头的文件到testdir目录下
COPY abc* /testdir/
# 案例三:? 是单个字符的占位符,比如匹配文件 abc1.log
COPY abc?.log /testdir/

# 5.ADD
# 往它肚子里放点文件(会自动解压)
ADD springboot-1.0-SNAPSHOT.jar app.jar
# 案例一:将1.txt拷贝到根目录的abc目录下。若/abc不存在,则会自动创建
ADD 1.txt /abc
# 案例二:将test.tar.gz解压缩然后将解压缩的内容拷贝到/home/work/test
ADD test.tar.gz /home/work/test
# docker官方建议当要从远程复制文件时,尽量用curl/wget命令来代替ADD。因为用ADD的时候会创建更多的镜像层。镜像层的size也大。

# ADD/COPY对比
# 1.二者都是只复制目录中的文件,而不包含目录本身。
# 2.COPY能干的事ADD都能干,甚至还有附加功能。
# 3.ADD可以支持拷贝的时候顺带解压缩文件,以及添加远程文件(不在本宿主机上的文件)
# 4.只是文件拷贝的话可以用COPY,有额外操作可以用ADD代替。


# 6.ENV
# 设置环境常量,方便下文引用
ENV JAVA_HOME /usr/local/jdk1.8
RUN ${JAVA_HOME}/bin/java -jar xxx.jar

# 7.RUN
# RUN指令是在构建镜像时运行,在构建时能修改镜像内部的文件[docker::build]
# SHELL命令格式:RUN yum -y install vim
# EXEC命令格式:	RUN ["yum","-y","install","vim"]

# SHELL:当前shell是父进程,生成一个子shell进程去执行脚本,脚本执行完后退出子shell进程,回到当前父进程。
# EXEC:用EXEC进程替换当前进程,并且保持PID不变,执行完毕后直接退出,不会退回原来的进程。
# 总结:也就是说shell会创建子进程执行,EXEC不会创建子进程。推荐EXEC命令格式

# 8.CMD
# 1.容器启动时执行,而不是镜像构建时执行[docker run]
# 2.Dockerfile中只有最后一个ENTRYPOINT会被执行,推荐用EXEC格式。
# 3.重点在于如果容器启动的时候有其他额外的附加指令,则CMD指令不生效。

# 9.ENTRYPOINT
# 容器创建时执行,而不是镜像构建时执行。
# Dockerfile中只有最后一个ENTRYPOINT会被执行,推荐用EXEC格式。
ENTRYPOINT ["java","-jar","app.jar"]

# 给我一个存放行李的地方(目录挂载):将本地文件夹挂载到当前容器
VOLUME /tmp

# 声明需要暴露的端口
EXPOSE 8080
  • 23
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr朱墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值