前言
1、背景:
在真实项目中,往往有多个环境,而且项目在迁移到一个新的服务器上时,往往都需要安装新的环境,redis,mysql,jdk等等,而docker使用镜像打包的形式将项目所需的环境也带上,这样在部署项目的时候就不需要再去部署新的环境,极大降低了部署和运维的成本,同时极大的提升了工作效率。
个人理解:将我们我的项目打包成一个镜像(自己创建,或者配置从仓库中下载),直接通过镜像可以启动多个容器(应用),容器(应用)的配置文件通过宿主机映射(外挂)的方式实现,再通过镜像创建容器实例时指定不同的外挂文件可以创建不同的应用实例
2、docker介绍:docker是一个开源的,基于go语言开发的应用容器引擎
,docker可以让开发者们打包他们的项目以及依赖包到一个轻量级、可移植的容器中
,然后发布到任何linux系统上,容器采用沙箱机制,相互隔离
3、docker于虚拟机:docker与传统的虚拟机还是有区别的, 想vmware是虚拟一个完成的操作系统,内核,磁盘,网络等等,而docker则是虚拟的是一个能够提供功能的一个最小化的容器,没有其他硬件信息和内核,依赖于宿主机的内核
4、docker的特征:镜像(类似java中的类),容器(类似java中的由类创建的对象),仓库(存储docker镜像的地方,类似maven,git,里面有各种常用数据库,环境的镜像,不用自己在服务器手动下载安装然后make,make install等操作,使用docker安装即可,和maven一样,也有公共库和私有库,可以公司内部搭建,使用dockerhub国外的网站比较慢,可以使用国内的阿里云库
)
5、docker架构:cs架构,类似myslq,后天守护进程运行服务端,客户端接收命令对docker服务端进行一系列的操作
一、docker安装
1、yum安装、测试
直接使用这个命令应该也是可以的:yum -y install docker
启动:systemctl start docker / sevice docker start
2、宝塔安装
3、配置阿里云镜像加速器
二、常用软件安装
2.1、nginx
1、第一次安装需直接启动docker run nginx,然后进入容器中拷贝配置文件,最后退出删除,再启动自己的nginx
docker run --name nginx -d nginx #直接启动nginx
docker cp nginx:/etc/nginx/nginx.conf /home/docker/volumes/nginx/conf/nginx.conf #从容器中复制配置文件
docker cp nginx:/etc/nginx/conf.d /home/docker/volumes/nginx/conf/ #从容器中复制配置文件夹
docker cp nginx:/usr/share/nginx/html /home/docker/volumes/nginx/ #从容器中复制html文件
docker cp nginx:/var/log/nginx /home/docker/volumes/nginx/log #从容器中复制日志文件
2、带外挂文件启动(镜像名字再需要在最后面,命令顺序,域名映射也是?????)
chmod 777 /home/docker/volumes/nginx/conf/nginx.conf #给予权限
docker run -d -p 7777:80 -p 9999:9999 --name nginx \
-v /home/docker/volumes/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /home/docker/volumes/nginx/conf/conf.d:/etc/nginx/conf.d \
-v /home/docker/volumes/nginx/html:/usr/share/nginx/html \
-v /home/docker/volumes/nginx/log:/var/log/nginx \
-e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 \ #解决中文乱码
--privileged=true \ #给容器内root权限
--restart=always nginx \ #随着docker的启动而启动
3、nginx监听多个端口的话,每个端口都需要映射(实测不行,直接暴力多个 -p 即可)
$ docker run -d --name nginx --restart always --net host -v ~/docker_root/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v ~/docker_root/nginx/html:/usr/share/nginx/html -v ~/docker_root/nginx/logs:/var/log/nginx -v ~/docker_root/nginx/conf.d:/etc/nginx/conf.d nginx
2.2、mysql
2.3、redis
三、手动创建镜像
1、需要提交创建Dockerfile文件,文件中大致分为三个步骤:
①、备注:作者名,使用的基础镜像:linux,windows,开发语言镜像,应用镜像
②、命令:
例如基础镜像为Linux,通过最基本linux命令安装一些基础工具,然后根据自己想要的(安装软件)通过命令操作,容器内部创建文件夹,将外部/下载的项目拷入到文件
准备条件做好之后,进入到对应创建好的工作目录,启动项目
③、打印日志,流程解读
# 注释版
# 所有的指令都是全部大写的
# FROM表示你的镜像所依托的基础镜像是什么,我们就依托centos系统了
# 第一句话就代表我们这个镜像是centos系统了
FROM centos:latest
# 写一下作者的信息
MAINTAINER Yunfei Hu@89713373@qq.com
# 使用ENV定义一个MYPATH路径
ENV MYPATH /usr/local/project
# 设置WORKDIR为我们刚刚定义的MYPATH路径
# 设置WORKDIR的目的是让我们进入容器的时候,当前的路径。 (不设置默认进入根目录)
# 比如设置/usr/local/project,进入容器就会直接进入到这个目录下
WORKDIR $MYPATH
# 执行一些指令,需要特别强调,现在我们这个镜像已经有一个centos了,它是前后安装的
# 那么下面这些就相当于在这个空壳子centos上,去建立一些我们需要的东西
# 第一句话是更新yum工具
RUN yum -y update \
# 通过yum下载vim,此时我们的精简centos系统,有了vim这个工具
&& yum -y install vim \
# 通过yum下载vim,此时我们的精简centos系统,有了git这个工具
&& yum -y install git \
# 通过yum下载vim,此时我们的精简centos系统,有了gcc这个工具
&& yum install -y gcc-c++ \
# 通过yum下载vim,此时我们的精简centos系统,有了wget这个工具。
# 为什么要下载wget呢? 因为下面要下载go的编译器,它是一个安装包,需要用wget来下载
# yum是直接下载并安装,wget只是一个下载工具,类似于迅雷
&& yum -y install wget \
# 通过wget来下载这个安装包
&& wget -P /root/ https://dl.google.com/go/go1.14.1.linux-amd64.tar.gz \
# 用tar指令来解压缩这个安装包到/usr/local
&& tar -zxvf /root/go1.14.1.linux-amd64.tar.gz -C /usr/local \
# 添加go环境在系统环境变量中
&& echo export PATH=$PATH:/usr/local/go/bin >> /etc/profile \
# 重新编译一下/etc/profile文件(环境变量生效),并且查看一下go版本
&& source /etc/profile && go version \
# 在bash每次启动的时候,都会加载.bashrc文件中的内容,也就是每次打开bash(终端)
# 的时候,都会编译一下/etc/profile文件(环境配置文件)
&& echo "source /etc/profile" >> /root/.bashrc \
# 设置我们刚刚下载的go编译工具的代理地址(下载速度会变快)
&& go env -w GOPROXY=https://goproxy.cn,direct \
# 在Go11.1版本之后,go采用go module来代替之前的依赖管理,如果我们想要启用
# go module的功能,需要设置GO111MODULE,它有三个值,on,off,auto,默认为auto
# on开启,off关闭,auto则会寻找项目根目录有没有go.mod文件来决定是否开启。
&& go env -w GO111MODULE=on \
# 打印------end-------代表完成
CMD echo "-----end-----"
2、安装镜像
# 通过以下命令来构建镜像
# -f后面指定我们的Dockerfile文件的路径,如果是在当前目录,而且是Dockerfile的话
# -f也可以不写,因为Dockerfile这个名字是官方指定的,它会自动去找
# -t是用来设置名字和Tag(版本),比如我写centos_go:0.1,表示这是一个centos带go
# 环境的系统,版本是0.1。
# 需要特别注意的是,这条命令的最后有一个点,不能去掉,它指的是上下文路径,是指docker在
# 构建镜像的时候,有时候需要用到本机的文件(比如复制),docker build命令得知这个路径
# 后,会将路径下的所有内容打包。 如果不说明这个参数,默认的上下文路径就是Dockerfile所在的位置
docker build -f Dockerfile -t centos_go:0.1 .
3、创建容器:指定端口,外部映射文件,交互式操作(终端命令进入容器操作)
#如果外挂配置文件不存在,那么会启动失败,但是会创建这个文件夹,再次使用该命令会提示容器已存在,可知这个命令是根据镜像创建容器并且启动,所以第二会失败
docker run -it -v /root/project:/usr/local/project --name centos_test01 centos_go:0.1 /bin/bash
四、后端项目jar包镜像部署
4.1、基本流程
1、打包好jar包
2、创建指定目录,将jar上传到该目录,同事创建Dockerfile配置文件
FROM java:8
# 将demo-0.0.1-SNAPSHOT.jar 复制 到容器中并重命名为 app.jar
COPY demo-0.0.1-SNAPSHOT.jar app.jar
#这样并不能修改程序的端口号,应该项目原因,项目启动没有带arg参数
#CMD ["--server.port=8080"]
# 这样也并不能修改端口号,应该是项目原因,项目启动没有带arg参数
#ENTRYPOINT ["java","-jar","app.jar","--server.port=1111"]
#暴露服务端口,和项目端口一致
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
3、构建镜像
docker build -t 镜像名:1.0 .
4、创建容器并且启动
docker -it -p 8080:8080 --name 容器名 镜像名:版本号(不写默认是latest) -d(后端进程启动,不会打印日志) /bash/bin
4.2、域名配置
1、在制作镜像时配置域名,这样创建的每一个容器都有配置,但增加了镜像文件大小(建议使用这种,就后端而言,分为开发环境和正式环境,开发环境直接通过jar启动就可以,正式环境一般也不会随便更改域名,直接在镜像中使用最方便,即使有修改,我们也可以使用第三种方法,但是我试过这一种方法不可行
)
RUN echo 10.121.55.96 whdsj096.sunment >> /etc/hosts
2、容器启动,进入容器修改(对于我们的后端程序,是创建容器直接启动,应该会报错,所以不可行,没有验证,理论上是这样)
docker exec -it 容器名 bash
3、在使用镜像创建容器时配置,而且必须在–name 的前面,不然也会找不到域名
# 注意域名在前,ip在后
--add-host=host:ip
--add-host=test2.docker.com:192.168.1.10
4.3、读取配置文件
4.3.1、在创建镜像时配置到容器中(这样如果配置文件变更,需求重新修改镜像)
将配置文件和jar一样拷贝到容器中,并且配置和jar在同一目录下(还有其他三种方式,见springboot读取外部配置文件)
#Dockerfile文件配置
copy xxx.jar app.jar
copy application.yml application.yml
copy application.properties application.properties
4.3.2、外挂配置(修改配置配置文件,重启容器即可)
Dockerfile
# Dockerfile
ENTRYPOINT ["java","-jar","app.jar","--spring.config.location=容器内部配置文件路径/application.yml"]
创建容器命令(可以不上文件
)
docker run -it -v 宿主机配置文件目录/:容器内容配置文件路径/
4.3.2、两种都采用(综合以上方法,容器有默认配置值,也可以通过外部挂载)
# Dockerfile
copy xxx.jar app.jar
copy application.yml application.yml
copy application.properties application.properties
ENTRYPOINT ["java","-jar","app.jar","--spring.config.location=容器内部配置文件路径/application.yml"]
docker run -it -v 宿主机配置文件目录/:容器内容配置文件路径/
4.4、容器启动成功后,快速迁移,不需要制作镜像,启动配置复杂操作
4.5、dockerfile解读
①每一个命令都是一层,没多一层就会增加镜像的大小,所以命令尽量简洁并且放在一行中执行,而且在构建镜像时,如果在仓库有相同的层信息,那么在推送,构建的时候可能会使用缓存中的层信息,这样镜像很可能还是原来的,建议直接删除源镜像,但是这样也是删除不干净的,docker并没有提供可以直接删除层信息缓存的命令,但是可以试一试,或者给镜像换一个名字
②dockerfile:volume(如果dockerfile中有,但是run时没有指定目录,那么会有一个默认的目录映射),expose、ENV都是不必要声明,在run的时候指定都可以,只不过在dockerfile中声明方便一些,就和注释一个道理
ENV:容器内环境变量
ADD:将宿主机文件添加到容器中,会自动解压tar文件,zip不可以
copy:将宿主机文件添加到容器中,不会解压
EXPOSE:暴露端口
RUN:在镜像构建时执行命令,通常是下载安装应用
CMD:创建容器时执行命令,如果和ENTRYPOINT同时存在,那么添加在ENTRYPOINT后面,在docker run 后面可以修改CMD后面参数
ENTRYPOINT:创建容器时执行命令,ENTRYPOINT后面参追加docker run 后面的参数,多个ENTRYPOINT只会执行最后一条
五、常用命令
5.1、镜像命令
# 删除镜像
docker image rm 镜像名
5.2、容器命令
docker start 容器名/容器ID # 启动容器
docker exec -it container_name bash #新增一个后台进程进入容器,不影响的,最优解,也可以在docker新建sshd,直接连接docker容器操作,但是不建议
docker attach container_name bash #如果多个窗口进入容器,施工用一个进程的,一个界面操作,其他界面会返回相同结果,而且窗口阻塞时,其他窗口不可用
docker stop 容器名 #停止容器
docker ps #查看运行中的容器
-a 查看容器
六、其他
6.1、容器
1、容器日志
2、如果根据容器得到创建容器时的执行信息
6.2、镜像
1、如何根据镜像获取创建镜像dockerfile文件内容,比如:直接下载的nginx镜像中配置文件的位置
6.3、端口冲突
端口问题需要重启docker