Docker安装应用
拉取已有镜像启动容器
以下以Redis的部署为例
获取Redis镜像
关于镜像的获取建议使用代理,因为有些镜像在国内仓库中没有回到外网节点中获取
1 |
|
上图表示拉取成功并完成,可用docker images
查看本地是否有镜像
注意:拉取速度会很慢,因为docker中央仓库在国外,中国虽然有镜像仓库,如阿里、网易蜂巢等,但速度也不理想。好在,docker文件可以反复拉取,拉取失败,重新拉取即可。
使用Redis镜像启动实例
启动docker容器以及内部的redis服务
1 |
|
- 参数说明:
- -d,则containter将会运行在后台模式(Detached mode)
- –name 实例名称
- -p 对外程序访问端口7000,宿主机映射的redis端口6379
- 最后的redis为镜像的名称
一些特殊参数
1 |
|
- –net=host:容器内暴露多少端口,宿主集器也暴露对应端口
- –restart=always:开启容器重启
- -e:设置容器环境变量
进入Docker内部
有必要则可以进入容器内部操作服务
1 |
|
进入redis客户端redis-cli
退出docker中的redis环境exit
端口映射关系
防火墙设置
systemctlstop firewalld.service
关闭防火墙服务
systemctldisable firewalld.service
禁止防火墙开启启动
systemctlrestart iptables.service
重启防火墙使配置生效
systemctlenable iptables.service
设置防火墙开机启动
测试单个Redis
1 |
|
以上案例中我们先获取了redis中的那么键值并打印,随后又为这个name设新的值,进入容器中的redis客户端查看这个值是否有变动
1 |
|
测试分片的Redis
启动多个redis,这里基于上一步的单个redis继续启动两个容器
以类似的方式启动,注意修改暴露的端口
1 |
|
上述java类是一个循环20次写值的过程,理论上分片后所有容器均会分担存储部分键值,查看结果如下
创建自定义镜像
Dockerfile
Dockerfile通过逐层layer叠加,使资源得到重复利用,同时变化无穷。
注意:FROM指定的镜像,本地如果有直接使用,无需网上下载。
关键字含义
序号 | 关键字 | 说明 |
---|---|---|
1 | FROM | 指定基础镜像的来源 |
2 | MAINTAINER | 作者 |
3 | ADD | 复制文件,会自动解压 |
4 | WORKDIR | 设置当前工作目录 cd |
5 | VOLUME | 设置数据卷,挂载主机目录 |
6 | EXPOSE | 指定对外暴漏的端口 |
7 | RUN | 执行命令 sh |
8 | CMD | 执行命令 exec,一个Dockerfile只能一个 |
9 | COPY | 复制文件 |
10 | ENTRYPOINT | docker run时参数可以覆盖,指定参数值 |
简单镜像操作
在你所选的目录下创建一个Dockerfile文件
配置Dockerfile
1 |
|
- tips:实际上如果只写FROM就相当于对镜像重命名
基于Dockerfile创建镜像
docker build -t 镜像名称 Dockerfile路径
参数-t标识TAG名称,注意最后有一个.代表当前路径。此命令会自动调用所选目录下的Dockerfile文件并执行其中的命令。
查看镜像
docker images
导出镜像
镜像导出会导出在当前目录下
- 按镜像名称导出
docker save -o 包名称.tar 镜像名称
- 按镜像ID导出(按镜像id导出,但导入时没名称)
docker save 镜像ID> 包名称.tar
删除镜像
- 根据镜像名称和版本号删除镜像
docker rmi 镜像名称:版本号
- 根据镜像ID删除(强制删除会删除父类镜像)
docker rmi -f 镜像ID
导入镜像
docker load -i 镜像tar包名称
- 如果导入完成时docker images
没有名称,没有版本。可是它会有imageId
配置含有JDK的镜像
以上可以看出一个目录只能有一个Dockerfile文件,而这个目录则是配置生成这个镜像文件的专属目录,资源包竟可能放到这个目录以便Dockerfile配置方便
创建目录
mkdir /usr/local/src/docker
创建目录vi Dockerfile
创建Dockerfile文件并编辑
编辑Dockerfile文件
1
2
3
4
5
6
7FROM 镜像名称
#解压并安装jdk
ADD jdk-8u211-linux-x64.tar.gz /usr/local/src
#设置环境变量
ENV JAVA_HOME=/usr/local/src/jdk1.8.0_211
ENV PATH=$JAVA_HOME/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar镜像制作
docker build --no-cache -t 镜像名称 Dockerfile目录
运行镜像
docker run -d -it
镜像名称:版本号docker ps
:查看是否启动成功
检查JDK是否安装成功
docker exec -it
:容器ID bash- java
java -version
exit
:退出容器
配置TOMCAT
在有jdk的基础上配置tomcat
重新编辑Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15FROM 镜像名称
#解压并安装jdk
ADD jdk-8u211-linux-x64.tar.gz /usr/local/src
#设置环境变量
ENV JAVA_HOME=/usr/local/src/jdk1.8.0_211
ENV PATH=$JAVA_HOME/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
# install 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
#对外访问的端口
EXPOSE 8080
#执行命令
CMD ["/usr/local/src/apache-tomcat-7.0.55/bin/catalina.sh","run"]创建镜像
docker build -t 镜像名称:镜像版本 Dockerfile目录
:创建镜像
启动镜像
- `docker run -d –name 容器别名 -p 8001:8080 镜像名称:镜像版本
访问tomcat
部署war包
重新编辑Dockerfile文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23FROM 镜像名称
#解压并安装jdk
ADD jdk-8u211-linux-x64.tar.gz /usr/local/src
#设置环境变量
ENV JAVA_HOME=/usr/local/src/jdk1.8.0_211
ENV PATH=$JAVA_HOME/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
# install 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
RUN rm -rf $CATALINA_HOME/webapps/*
#deploy the war
COPY ROOT.war $CATALINA_HOME/webapps/ROOT/ROOT.war
WORKDIR $CATALINA_HOME/webapps/ROOT
RUN jar xvf ROOT.war
RUN rm -rf ROOT.war
#对外访问的端口
EXPOSE 8080
#执行命令
CMD ["/usr/local/src/apache-tomcat-7.0.55/bin/catalina.sh","run"]上传文件到虚拟机中
1
2
3# 上传文件到虚拟机中/user/local/src/docker/EasyMall.war
# 修改文件名文ROOT.war
mv EasyMall.war ROOT.war制作镜像
docker build -t 镜像名称:镜像版本
启动镜像
docker run -d --name 镜像别名 -p 8000:8080 镜像名称:镜像版本
访问这个项目
Docker数据卷
有状态容器都有数据持久化需求。Docker 采用 AFUS 分层文件系统时,文件系统的改动都是发生在最上面的容器层。在容器的生命周期内,它是持续的,包括容器在被停止后。但是,当容器被删除后,该数据层也随之被删除了。因此,Docker 采用 volume (卷)的形式来向容器提供持久化存储。
docker run -p 53306:3306 -v $PWD/msyql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql5719 -d bf1219a0a00d
一个 data volume是容器中绕过文件系统的一个特定的目录。它被设计用来保存数据,而不管容器的生命周期。因此,当你删除一个容器时,Docker 肯定不会自动地删除一个volume。
注意,在容器被删除后,/var/lib/docker/volumes/xxx/_data目录及其中的内容都还会保留下来,但是,新启动的容器无法再使用这个目录,也就是说,已有的数据不能自动地被重复使用了。
配置具有mysql的镜像
下载镜像
docker pull mysql:5.7.19
启动并设置数据卷
docker run -p 53306:3306 -v $PWD/msyql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql_test -d bf1219a0a00d
- 参数说明:
-v $PWD/mysql:/var/lib/mysql
:将当前目录下的/mysql挂载到容器的/var/lib/mysql;当容器被关闭或删除时,/var/lib/mysql目录中的实例化文件会被记录到当前目录下新建的/mysql文件夹中-e MYSQL_ROOT_PASSWORD=root
:初始root账号的密码root
进入容器
docker exec -it mysql_test bash
进入mysql
mysql -u root -p
:root账号登录grant all privileges on *.* to root@"%" identified by "root" with grant option;
:赋予权限flush privileges;
:刷新权限配置
添加mysql数据
1
2
3
4
5
6
7
8
9
10
11
12DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`ID` INT(11) NOT NULL AUTO_INCREMENT,
`NAME` VARCHAR(30) DEFAULT NULL,
`BIRTHDAY` DATETIME DEFAULT NULL,
`ADDRESS` VARCHAR(200) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
#插入数据
insert into `user`(`ID`,`NAME`,`BIRTHDAY`,`ADDRESS`) values (1,'夏言','1573-01-01 00:00:00','桂州村'),(2,'严嵩','1587-01-01 00:00:00','分宜县城介桥村'),(3,'徐阶','1580-01-01 00:00:00','明松江府华亭县'),(4,'高拱','1566-01-01 00:00:00','河南省新郑市高老庄村'),(5,'张居正','1558-01-01 00:00:00','江陵');停止容器
1
2
3
4docker ps #查看开启的容器
docker stop 4f1dd82095c1 #停止指定的容器
docker ps
docker ps -a再次打开容器
1
2
3
4
5
6docker start 4f1dd82095c1 #开启停止的容器
docker ps #查看容器
docker exec -it 71621b64efc8 bash #进入容器
mysql -uroot –proot #登录
mysql> use test_db; #打开数据库
mysql> select * from user; #查看user表