2021-10-13Docker
一、简介
1.技术前提
了解linux
修改虚拟机ip为静态:
- vim /etc/sysconfig/network-scripts/ifcfg-ens33
- BOOTPROTO=“static”
- IPADDR=“192.168.188.107”
- NETMASK=255.255.255.0
- GATEWAY=192.168.188.2
- DNSI=192.168.188.2
- 重启网络服务:systemctl restart network
2.应用背景
软件在windows上开发完成后,把jar或war包交给运维,运维部署到linux或云服务器上时,可能会因为环境不同或配置不同,而导致不能正常工作。用docker就可能方便的解决该问题。
3. 工作原理
如果到宠物店只买回一条鱼,回家后可能因为环境不适应而死亡,而从宠物店买回的是带鱼缸和鱼这一整套环境就不会出问题。也就是从系统底层至上层整体打包成镜像文件,从而达到完全跨平台的到处运行。
4.Docker与虚拟机的区别
Docker是一个精简版的虚拟机,只是少了对操作系统和硬件的虚拟,所以启动速度是秒级的,而虚拟机的启动则是分钟级的
5.Docker的组成
-
镜像:相当于java中的类,如Person。应用程序和配置及依赖打包成一个可运行的环境,这个包就是镜像文件。
-
容器:相当于new Person产生对象,容器是以镜像为模板产生,可把容器看成镜像一个简化版的linux环境和若干运行在其中的应用程序。
-
仓库:是集中存放镜像的地方,docker三要素:镜像、容器、仓库
-
仓库注册服务器:放着多个仓库。
二、安装
1.下载Dcoker的依赖环境
yum install -y yum-utils device-mapper-persistent-data lvm2
2.指定Docker镜像源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3. 安装Docker
yum makecache fast #为加快安装速度,对缓存加速 yum -y install docker-ce
4.查看版本
docker version
5.启动Docker并测试
- 启动docker: systemctl start docker
- 重启: systemctl restart docker
- 卸载docker: yum remove docker
- 设置开机启动: systemctl enable docker
6. 云镜像仓库
是一个代理仓库,放了一些镜像,因为中央仓库https://hub.docker.com是国外网站,非常慢,有两个云可用,网易云和阿里云,推荐使用阿里云,更全面,其镜像地址:https://www.aliyun.com/product/acr
获取加速器地址的方法如下:
-
注册–>可使用淘宝帐号注册,搜索容器镜像服务
-
获取加速器地址:通过网址https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors获取
-
配置加速器
-
mkdir /etc/docker
-
vim /etc/docker/daemon.json
-
内容如下:每个帐号都不同,使用下面一个也可以。
{ "registry-mirrors": ["https://f1z25q5p.mirror.aliyuncs.com"] } -
使配置生效:
- systemctl daemon-reload
- systemctl restart docker
-
-
helloworld镜像生成容器:docker run hello-world,默认先从本地的镜像中找,没找到就从阿里云中找其镜像并拉取。
三、docker常用命令
1. 帮助命令
-
docker info—查看docker的总体信息
-
docker help—查看docker有哪些命令
2. 镜像操作
- 查看镜像
- docker images—查看有哪些镜像,repository表示镜像的仓库源,tag是版本,image id是镜像的唯一ID,created是创建时间,size是镜像大小。
- docker images -a—查看镜像及中间映像层,也就是一个表面镜像内部还包含了哪些镜像。
- docker images -q—只显示镜像ID
- 下载镜像 docker pull xxx
- docker pull nginx,相当于docker pull nginx:latest下载最新版本。
- docker pull tomcat:8.5.32
- 删除镜像 docker rmi xxx
- docker rmi hello-world—失败,因为提示说该镜像的容器正在运行,
- docker rmi -f hello-world—强制删除
3. 容器操作
3.1 创建并启动容器
以centos镜像为例演示
- docker pull centos—从阿里上拉取centos镜像
- docker run -it centos—创建容器,i为交换模式,t为使用终端,it常常一起使用表示使用终端进入交互模式,exit退出
- docker run -it --name mycts centos–启动并指定容器名称,上面没指定都会随机给个名字
3.2 查看有哪些容器
- docker ps ** 查看正在运行**的容器
- docker ps -q —只显示容器id
- docker ps -qa 查看所有,包括没有运行的容器
3.3 停止和启动容器
- exit—从终端退出并可能停止容器,ctrl+p+q退出但容器仍然运行。
- docker stop aea7a56b0c7d或容器名—停止容器
- docker start 容器名或容器id 重新启动被停止的容器
3.4 删除容器
不是停止,停止后容器还在,只是不运行了
- docker rm 容器id或名称—注意,必须先关闭容器才能删除,rmi是删除镜像
- docker rm -f $(docker ps -aq)—批量删除
3.5 进入容器的内部进行操作
docker exec -it 容器id bash
3.6 容器与宿主机间拷贝文件
-
从容器中拷贝到宿主机
docker run -it centos-->cd /tmp–>vi hello.txt—>ctrl+p+q–>docker ps–>docker cp 容器id:/tmp/hello.txt /opt
-
从宿主机拷贝到容器
docker cp /opt/a.txt 容器id:/tmp
四. 数据卷/目录挂载
1. 有什么用
-
目录映射:
为方便宿主机与容器间传递数据,产生目录映射,使两者共享同一目录。使用数据卷可将宿主机上的一个目录映射到容器的一个目录中。
-
持久化容器数据
容器运行中所产生的数据,如果不通过commit生成新镜像,当容器被删除后数据就丢失了。使用数据卷可在不产生新镜像的前提下保存数据在磁盘上,有点像redis中的持久化。
-
部署项目方便
为了部署项目,需要使用到cp命令将宿主机内的war包复制到容器内部。
使用数据卷可以在宿主机中操作目录中内容,那么容器内部映射的文件,也会跟着一起改变
2. 特点
- 数据卷可在容器之间共享
- 修改卷中数据可以直接生效,并且对卷的修改不会引起镜像的更新。
- 卷的生命周期一直持续到没有容器使用它为止。
3. 产生数据卷
docker run -di -v /myData:/myContainerData --name myc1 centos
参数说明:
- -di:产生交互式后台进程
- -v:目录挂载,myData是宿主机中目录,myContainerData是容器中目录
- –name:给容器启一名称为myc1
4. 测试
- vim /myData/a.txt
- docker exec -it myc1 bash
- cat /myContainerData/a.txt
五. docker应用部署
1. MYSQL部署
a. 拉取镜像
-
搜索mysql镜像:docker search mysql
-
拉取镜像:docker pull centos/mysql-57-centos7 ,镜像选择的是centos/mysql-57-centos7
b. 创建mysql容器
docker run -di --name=mysql5.7 -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123 centos/mysql-57-centos7 注意:如果宿言主机上已经安装mysql,则这里宿主机就不能还使用3306
参数说明:
- -di: 以守护进程交互式启动容器
- –name: 给容器启名为mysql5.7
- -p: 端口映射,格式为:宿主机端口:容器端口,为什么要映射?因为容器的ip地址跟windows的ip不在一个网段,无法通信。从win7访问容器就只能通过win7访问宿主机(虚拟机)的ip+映射的端口。
- -e: 当从win7远程连接容器mysql时,要设置root帐号的密码,这里设置远程连接密码为root,但要注意:在进入容器内访问时,密码是空的。
- 最后一个参数:是上面下载的镜像名.
c. 连接mysql
1. 容器本地连接
-
docker exec -it -u root mysql5.7 bash
-u root:表示以root身份进入容器
-
mysql -uroot -p ,密码为空,回车
2. win7远程连接
mysql -uroot -p123 -h192.168.188.107,默认连接的是3306,如果映射的宿主机不是3306,则后面添加 -P3306
2. tomcat部署
2.1 拷贝war包
从宿主机上拷贝war包到容器中
-
运行tomcat8.5.32镜像
docker run -d --name mytom1 -p 9000:8080 tomcat:8.5.32
参数说明:
- -p是端口映射,9000为宿主机端口,8080为容器中tomcat端口,没办法直接访问容器的8080,就直接访问宿主机的9000,映射到容器的8080
- -d是后台启动,换成-it则是前台启动tomcat
- 测试tomcat:192.168.188.107:9000
-
直接拷贝war包到容器
docker cp /opt/data/day1.war 容器id:/usr/local/tomcat/webapps/
-
测试:192.168.188.107:9000/day1/showSuc
2.2 使用目录挂载
-
挂载命令
docker run -di -p 8888:8080 -v /opt/data:/usr/local/tomcat/webapps/ --name mytom2 tomcat:8.5.32
-
向/opt/data中放入day1.war
-
测试:192.168.188.107:8888/day1/showSuc
3. nginx部署
3.1 拉取镜像
docker pull nginx
3.2 创建容器
-
docker run -it --name mynginx1 -p 80:80 nginx bash
-
配置文件在/etc/nginx/nginx.conf,默认没有vi命令
-
拷贝nginx目录到宿主机:
- ctr+p+q
- docker ps
- docker cp mynginx1:/etc/nginx /opt/data
-
删除容器:docker rm -f mynginx1
-
启动容器并添加数据卷:
docker run -v /opt/data/nginx:/etc/nginx -di --name mynginx2 -p 80:80 nginx
3.3 测试
192.168.188.107/
4. redis部署
4.1. 拉取redis
docker pull redis
4.2 创建容器
以aof方式持久化,如果用rdb则不加–appendony yes
docker run -d --name myredis -p 6379:6379 redis --appendonly yes
4.3 进入redis容器
-
进入容器
docker exec -it myredis bash
-
启动客户端
- cd /usr/local/bin
- redis-cli
六、自定义镜像
##1.Dockerfile方式
###a. Dockerfile介绍
-
有什么用?
使用Dockerfile可以根据需求开发一个自定义的镜像,其实就是一个文本文件,由一系列命令和参数构成,Docker可读取这个文件构建一个镜像。
-
dockerfile常用指令
from 基于哪个镜像 MAINTAINER 作者 COPY 复制文件进入镜像(只能用相对路径,不能用绝对路径) ADD 复制文件进入镜像(压缩包会解压) WORKDIR 指定工作目录,不存在会创建路径 ENV 设置环境变量 EXPOSE 暴露容器端口 ENTRYPOINT 在容器启动的后执行,作用于容器层,dockerfile里有多条时只执行最后一条 RUN 构建镜像的时候执行其后的命令,作用于镜像层面,命令格式: shell命令格式:RUN yum install -y net-tools exec命令格式:RUN [“yum”,“install”,"-y",“net-tools” ###b. 创建jdk镜像 + 向/opt/data/jdk目录添加jdk压缩文件 + 在/opt/data/jdk目录中创建并编辑Dockerfile文件, vim Dockerfile ,添加下面内容: ```dockerfile FROM centos:7 MAINTAINER lly WORKDIR /usr RUN mkdir /usr/local/java ADD jdk1.8.0_144.tar.gz /usr/local/java/ ENV JAVA_HOME /usr/local/java/jdk1.8.0_144 ENV JRE_HOME $JAVA_HOME/jre ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JAR_HOME/lib:$CLASSPATH ENV PATH $JAVA_HOME/bin:$PATH
-
编译并构建镜像,镜像名为jdk1.8
docker build -t=‘jdk1.8’ ./
-
查看镜像
docker images
-
通过镜像jdk1.8创建容器myjdk
docker run -it --name myjdk jdk1.8 bash
###c. 微服务部署
-
上传jar包
在/opt/data/eureka目录中添加eureka_7001.jar
-
查找jdk镜像
docker search jdk 得到ascdc/jdk8镜像,也可使用前面创建的镜像jdk1.8
-
编辑Dockerfile
-
在/opt/data/eureka中创建并编辑Dockerfile文件
#基于哪个镜像 #FROM ascdc/jdk8 FROM jdk1.8 #目录挂载,将本地文件夹挂载到当前容器,这里用不着,了解 VOLUME /tmp #将文件复制到容器指定目录 ADD eureka_7001.jar /usr/local/java/ #暴露服务的端口 EXPOSE 7001 #设置容器启动后要自动执行的命令 ENTRYPOINT ["java","-jar","/usr/local/java/eureka_7001.jar"]
-
-
生成镜像并测试
-
编译并创建镜像
docker build -t=‘eureka-server’ ./
-
查看生成的镜像:docker images
-
启动容器:
- 前台启动:docker run -p 7001:7001 eureka-server
- 后台启动:docker run -di -p 7001:7001 eureka-server
-
192.168.188.107:7001
-
2. commit方式
a. 创建使用redis的微服务
-
static 的js子目录下添加vue.js和axios.js
-
在static目录下添加下面两个前端页面,注意给每个页面导入vue和axios
-
login.html
<div id="d"> <input name="username" v-model='name'><br> <button @click="f">登录</button> </div> <script> new Vue({ el:"#d", data:{ name:"" }, methods:{ f:function () { axios.get('http://localhost/login',{ params:{ username:this.name } }).then(ret=> { location.href='http://localhost/main.html' }); } } }); </script> -
main.html
<div id="d"> <h1>欢迎你:{{name}}</h1> </div> <script> new Vue({ el:"#d", data:{ name:"" }, mounted: function(){ axios.get( '/getuserName' ).then(rs => { if(rs.data){ this.name=rs.data; } }); } }); </script>
-
-
导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>2.0.4.RELEASE</version> </dependency> -
配置类上添加redisSession的注解
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 300) -
添加控制器类
@RestController public class UserCtl { @RequestMapping("/login") public String login(HttpSession session, String username){ session.setAttribute("username",username); System.out.println("name:"+username+",sessionID:"+session.getId()); return "success"; } @RequestMapping("/getuserName") public String getName(HttpSession session){ return (String)session.getAttribute("username"); } }
b. 把容器生成新镜像
docker commit -a "lly" -m "注释" 容器id 镜像名:版本号,如 docker commit -a "lly" -m "这是运行了redis服务,tmp目录下存放微服务" myredis redis:1.0
posted on 2021-10-13 08:43 JavaCoderPan 阅读(10) 评论(0) 编辑 收藏 举报 来源
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库