- Docker容器技术
- 需求场景
- 111,6.18电商狂欢节,特点是超高并发(处理方式:A.系统优化,nginx+tomcat、redis、rabbitMQ、mycat读写分离分库分表、主从复制、lucene+solr、dubbo。B.硬件优化,增加服务器,砸钱)。
- 斗鱼、熊猫、虎牙、全名、印客。。。直播,特点是高并发,数据流
这些案例有个特点,阶段性高并发,并不是持续,当软件层面优化做到极致之后只能增加硬件来支撑,但是成本不容易控制。一台刀片机2-15w。
小公司,租云服务器,大公司,出租云服务器。

一台云服务器不一定是一整台刀片机,可能是一小部分。
问题:
- 一台服务器如何部署多个系统,如何拆分资源?
- 如何快速部署成百上千太服务器?
解决办法:
虚拟机?Vmware?Vbox?--资源占用率太大。人工部署慢。
-
- Docker简介
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
-
- Docker与虚拟机对比

虚拟机:资源全部隔离,cpu、内存、磁盘相互独立,一台宿主机中可以安装的虚拟机数量是一定的,有限的,移植性不强(文件很大,拷贝传输困难)。
Docker:部分共享部分隔离,共享cpu,内存,磁盘甚至操作系统,极为轻量,可以有更多的个体对外提供服务,移植性强,共享仓库,移植时只需传输脚本文件。(类似maven,拿到pom文件就可以拿到所有的jar包)

由于以上提到的docker的特点,运行时资源共享宿主机,相当于在宿主机上边安装了一些应用,之后理想状态下享用宿主机的所有资源,所以性能与宿主机一样高,而虚拟机将资源完全划分出来并封闭不进行共享,所以他只能享用到自己分到的部分资源,也就是分多少用多少,并且还要被操作系统等资源占用很大一部分。
-
- Docker五大要素
- 沙箱:隔离,将应用之间的必要资源隔离开,防止互相影响
- 镜像:模板,centos+tomcat+mysql+redis,镜像可以拆分,传输用dockerfile
- 容器:镜像的实例,镜像只读,容器可写,容器中可以保存应用产生的零时文件,但是一旦关闭容器,数据清除。
- 数据卷:挂载到容器上,用于保存必要数据。比如容器中数据库的数据,但是不建议用,因为重启容器需要挂载同步数据,效率较慢,解决方式:数据库拆分
- 仓库:与maven仓库概念一致,应用都会保存在仓库中,创建容器是根据镜像的规定进行拉取,可以共享。
- Docker的缺点
1.资源隔离方面不如虚拟机,docker是利用cgroup实现资源限制的,只能限制资源消耗的最大值,而不能隔绝其他程序占用自己的资源。
2.安全性问题。docker目前并不能分辨具体执行指令的用户,只要一个用户拥有执行docker的权限,那么他就可以对docker的容器进行所有操作,不管该容器是否是由该用户创建。比如A和B都拥有执行docker的权限,由于docker的server端并不会具体判断docker cline是由哪个用户发起的,A可以删除B创建的容器,存在一定的安全风险。
3.docker目前还在版本的快速更新中,细节功能调整比较大。一些核心模块依赖于高版本内核,存在版本兼容问题
-
- Docker的版本及要求
Docker分为docker-ce(社区版-开源)和docker-ee(企业级-收费)
Docker基于linux3.8及以上版本64bit内核开发,所以在使用docker前需要确认linux内核版本,一般centos7以上。
查看linux版本命令:
uname -a

-
- Docker的安装
- 卸载老版本的 docker 及其相关依赖
- Docker的安装
sudo yum remove docker docker-common container-selinux docker-selinux docker-engine
-
-
- 安装 yum-utils,它提供了 yum-config-manager,可用来管理yum源
-
sudo yum install -y yum-utils
-
-
- 添加yum源
-
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
-
-
- 更新索引
-
sudo yum makecache fast
-
-
- 安装 docker-ce
-
sudo yum install docker-ce
-
-
- 启动 docker
-
sudo systemctl start docker
#
service docker start 启动
service docker stop 停止
service docker restart 重启
-
-
- 验证是否安装成功
-
sudo docker info
-
- docker命令
| 命令 | 用法 |
| yum -y install docker-ce | 下载最新版的docker |
| service docker start | 启动Docker服务 |
| service docker stop | 停止Docker服务 |
| service docker restart | 重新启动Docker服务 |
| docker version | 查看Docker的版本号 |
| docker pull 镜像地址:版本 | 从镜像仓库中下载 |
| docker save a2a69ca5184a > jt-centOS6.tar | 根据镜像id导出镜像 |
| docker save -o redis-3.2.8.tar redis:3.2.8 | 根据镜像名称导出镜像 |
| docker load -i docker-centos-6.5.tar | 指定jar包导入镜像文件 |
| docker rmi a2a69ca5184a | 根据Id号删除镜像文件 |
| docker rmi -f a2a69ca5184a | 强制删除镜像文件 删除镜像前需要先关闭容器 |
| docker images | 查询所有镜像文件 |
| docker inspect index.alauda.cn/tutum/centos:6.5 | 查看镜像文件细节信息 |
| docker tag 旧镜像名称和端口 redis-ali:0.0.1 | 修改镜像的名称 |
| docker build -t 镜像名称:版本号 | 根据dockerfile来创建镜像文件 |
| docker run -d --name 容器名 镜像名:版本号 | 根据镜像名称启动容器 |
| docker run -d --name 容器名(自定) 镜像id号 | 根据镜像id启动容器 |
| docker run -d -p 虚拟机端口:镜像端口 --name 容器名 镜像名:版本号 | 启动容器,并指定暴露端口 |
| docker ps | 查看活动的docker容器进程 |
| Docker ps -a/-all | 查看全部的容器 |
| docker exec -it 容器id bash | 进入指定的容器 |
| docker stop 容器Id号 | 停止指定容器 |
| docker start 容器Id号 | 启动创建好的容器 |
| docker stop $(docker ps -q) & docker rm $(docker ps -aq) | 关闭和删除所有的容器 |
| docker rm 容器Id | 删除指定的容器 |
-
- Redis案例
- 拉取redis镜像
- Redis案例
docker search redis #镜像库提供的多个镜像
docker pull redis #拉取最后版本的docker-redis镜像
docker pull redis:3.2.8 #拉取指定版本的redis镜像

阿里镜像加速
https://cr.console.aliyun.com/#/accelerator
注册账号拿到加速地址

- 修改docker镜像地址
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://XXXXXX "]
}
EOF
- 重启dockerDaemon
sudo systemctl daemon-reload
- 重启docker
sudo systemctl restart docker
本地导入镜像
由于网络限制,课堂使用导入镜像方式
进入/usr/local/src创建redis文件夹上传redis-3.2.8.tar包
执行

docker load -i redis-3.2.8.tar

-
-
- 查看镜像
-
docker images

-
-
- 创建容器
-
docker run -d --name redis7000 -p 7000:6379 redis:3.2.8
参数说明:
-d,则containter将会运行在后台模式(Detached mode)
--name 实例名称
-p 对外程序访问端口7000,宿主机映射的redis端口6379
最后的redis为镜像的名称
-
-
- 单个节点测试
-
@Test //完成单实例链接
public void jedis(){
Jedis jedis = new Jedis("192.168.163.30", 7000);
//jedis.auth("123456");
jedis.set("name", "tony"); //调用redis命令set
String s = jedis.get("name");
System.out.println(s);
jedis.close();
}
-
-
- 创建多个容器
-
docker run -d --name redis7001 -p 7001:6379 redis:3.2.8
docker run -d --name redis7002 -p 7002:6379 redis:3.2.8
-
-
- 测试分片
-
//redis测试分片
@Test
public void test02(){
//2.创建分片的连接池
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(500);
poolConfig.setMaxIdle(20);
//3.准备redis的分片
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo("192.168.65.110", 7000));
shards.add(new JedisShardInfo("192.168.65.110", 7001));
shards.add(new JedisShardInfo("192.168.65.110", 7002));
//1.创建分片的对象
ShardedJedisPool jedisPool =
new ShardedJedisPool(poolConfig, shards);
//获取jedis对象
ShardedJedis shardedJedis = jedisPool.getResource();
//5.redis的存取值操作
for (int i = 0; i < 9; i++) {
shardedJedis.set("n"+i,"我是分片操作"+i);
}
}
-
-
- 查看容器
-
docker ps #查看已经启动的容器
docker ps -a #查看所有容器
docker start b193fbe1e400 #开启实例,如重启可能实例被关闭
docker stop b193fbe1e400 #停止实例
docker rm 0cfc4932b9a0 #删除容器
docker rm –f 0cfc4932b9a0 #删除运行的容器,-f强制删除
docker rmi xcfc4932b9a0 #删除镜像
-
-
- 进入容器内部
-
docker exec -it 0cfc4932b9a0 bash #进入docker内部,-it输入输出,展示信息在控制台
root@a071867d6233:/data# ps -ef |grep redis
redis 1 0 1 08:45 ? 00:00:08 redis-server *:6379
root 26 20 0 08:58 ? 00:00:00 grep redis
redis-cli #根据最后映射的端口执行redis命令
exit #退出docker中的redis环境

-
- Dockerfile
Dockerfile是docker应用的核心,通过定义dockerfile来实现相同环境的自动部署,是docker实现快熟部署成百上千服务器的核心手段。
Dockerfile通过逐层layer叠加,使资源得到重复利用,同时变化无穷。
注意:FROM指定的镜像,本地如果有直接使用,无需网上下载。
-
-
- 关键字及含义
-
| 序号 | 关键字 | 说明 |
|
| FROM | 指定基础镜像的来源 |
|
| MAINTAINER | 作者 |
|
| ADD | 复制文件,会自动解压 |
|
| WORKDIR | 设置当前工作目录 cd |
|
| VOLUME | 设置数据卷,挂载主机目录 |
|
| EXPOSE | 指定对外暴露的端口 |
|
| RUN | 执行命令 sh |
|
| CMD | 执行命令 exec,一个Dockerfile只能一个 |
|
| COPY | 复制文件 |
|
| ENTRYPOINT | docker run时参数可以覆盖,指定参数值 |
-
-
- 制作CentOS6.5镜像
-
1.编辑dockerfile文件

2.创建镜像
docker exec 容器Id bash
3.检测容器启动是否正确 cd /usr/local/src

-
-
- 部署JDK
-
- 编辑dockerfile文件
#添加contos6.5文件
FROM a2a69ca5184a
#添加JDK1.8 centos+jdk
ADD jdk-8u51-linux-x64.tar.gz /usr/local/src
ENV JAVA_HOME=/usr/local/src/jdk1.8.0_51
ENV PATH=$JAVA_HOME/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
- 创建新的镜像文件
docker build -t jdk1.8:0.0.1 ./
3.启动容器
docker run -d --name jdk1.8 2a2efd0bf77b
4.检测jdk
docker exec -it b2cd27e069cd bash

-
- 添加tomcat镜像
- 编辑dockerfile文件
- 添加tomcat镜像
说明:添加tomcat
#添加tomcat
ADD apache-tomcat-7.0.55.tar.gz /usr/local/src
ENV CATALINA_HOME /usr/local/src/apache-tomcat-7.0.55
ENV PATH=$PATH:$CATALINA_HOME/bin
#进行项目发布
EXPOSE 8080
CMD ["/usr/local/src/apache-tomcat-7.0.55/bin/catalina.sh","run"]
-
-
- 制作镜像
-
docker build -t tomcat7:0.0.1 ./
-
-
- 启动容器
-
docker run -d -p 8080:8080 --name tomcat7-8080 ec8d94799976
-
-
- 效果查看
-

-
- EasyMall项目发布
- 修改数据库链接地址
- EasyMall项目发布
说明:将ROOT文件中的c3p0文件修改,修改数据库链接地址
路径:ROOT.war\WEB-INF\classes
-
-
- 导入数据库文件
-
说明:将easyMall中的sql文件导入到数据库中

-
-
- 添加dockerfile文件
-
#添加contos6.5文件
FROM a2a69ca5184a
#添加JDK1.8 centos+jdk
ADD jdk-8u51-linux-x64.tar.gz /usr/local/src
ENV JAVA_HOME=/usr/local/src/jdk1.8.0_51
ENV PATH=$JAVA_HOME/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
#centOS6.5+JDK1.8+tomcat7
ADD apache-tomcat-7.0.55.tar.gz /usr/local/src
ENV CATALINA_HOME /usr/local/src/apache-tomcat-7.0.55
ENV PATH=$PATH:$CATALINA_HOME/bin
#添加ROOT.war包文件
COPY ROOT.war $CATALINA_HOME/webapps/ROOT/ROOT.war
WORKDIR $CATALINA_HOME/webapps/ROOT
RUN jar xvf ROOT.war
RUN rm ROOT.war
#对外暴露的端口号
EXPOSE 8080
CMD ["/usr/local/src/apache-tomcat-7.0.55/bin/catalina.sh","run"]
-
-
- 创建镜像
-
docker build -t easymall:0.0.1 ./
-
-
- 启动容器
-
docker run -d -p 8080:8080 --name easymall-8080 ef1e93bb080c
-
-
- 效果展现
-

-
-
- 总结和拓展
-
Docker容器一般用于部署重复相同的服务,如:redis集群,tomcat集群Hadoop集群等。适用于快速高效集群扩展。其中Dockerfile是其核心,通过编写dockerfile来实现部署方式的快速传输(本质就是传输文本文件),各个节点通过拉取仓库中的镜像文件进行容器的快速创建。整个过程全自动,省去了运维成本。
拓展:
Devops:开发测试运维一体化,我们发现dockerfile能够实现所有机器环境及应用实现完全一致,而这正好能够解决一个我们日常开发中的一个非常麻烦的问题:开发,测试,生产环境的不一致导致开发人员完成任务后,到测试环节出现非bug问题,开发和测试调好后,也不能保证到生产环境没有问题,因为代码一样但是环境不一致导致很多不必要麻烦。而docker中的dockerfile通过统一调取一份镜像,从环境到代码甚至部署过程都是一致的,可以避免这样的问题。而docker的开发初衷就是开发测试运维一体化。
11万+

被折叠的 条评论
为什么被折叠?



