最近要使用Docker将开发微服务进行打包,来记录一下常用的操作以及命令,博文内容随着Docker的使用逐渐进行补充。
文章目录
1、Docker安装
这里我主要介绍Windows下的Docker安装;windows10企业版以下的系统,要是用docker toolbox 来安装,国内可以使用阿里云的镜像来下载,下载地址:http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/
docker toolbox 是一个工具集,它主要包含以下一些内容:
Docker CLI 客户端,用来运行docker引擎创建镜像和容器
Docker Machine. 可以让你在windows的命令行中运行docker引擎命令
Docker Compose. 用来运行docker-compose命令
Kitematic. 这是Docker的GUI版本
Docker QuickStart shell. 这是一个已经配置好Docker的命令行环境
Oracle VM Virtualbox. 虚拟机
下载以后直接安装即可。
windows10企业版的用户安装时需要首先在 "启用或关闭windows功能 " 里边首先开启 “Hyper-V” 然后安装最新版的Docker toolbox即可。官网下载地址: https://www.docker.com/get-docker
2、Docker配置国内镜像加速
在Docker的命令行输入环境中进行如下配置即可
docker-machine ssh default
sudo sed -i "s|EXTRA_ARGS='|EXTRA_ARGS='--registry-mirror=[镜像地址]|g" /var/lib/boot2docker/profile
exit
docker-machine restart default
docker-machine env default
完成以上的操作以后,输入 docker info 命令,就可以看到刚才配置的镜像。
3、Docker常用命令
首先要介绍一下镜像(image)和容器的概念;形象的说image就相当于一个类,而容器就是对应的实例。
docker --help # docker帮助
docker version # 查询docker的版本
docker pull [选项] [仓库名]:[标签名] # 获取镜像
docker image ls # 列出镜像列表
docker port 容器ID或容器name # 查看容器的端口映射情况
docker logs [容器ID或容器name] # 查看容器日志
docker ps # 查看正在运行的容器
docker ps -a # 列出容器列表,包括未运行的
docker system df # 查看镜像、容器、数据卷所占用的空间
docker image [选项] <镜像> # 其中<镜像> 可以是 镜像短 ID、镜像长 ID、镜像名 或者 镜像摘要,也可以是<仓库名>:<标签>
docker image rm $(docker image ls -q A) # 删除仓库名为A的所有仓库
docker start [选项] <容器名称,id> # 开启容器
docker restart [选项] <容器名称,id> # 重启容器
docker stop [选项] <容器名称,id> # 停止容器;-t、--time=10 设置终止容器前的等待时间,单位为秒
docker-machine env # 查询虚拟机相关信息
docker top [容器名称] [ps OPTIONS] # 容器运行时不一定有/bin/bash终端来交互执行top命令,而且容器还不一定有top命令,可以使用docker top来实现查看container中正在运行的进程
docker查看日志命令:
docker logs [OPTIONS] CONTAINER
Options:
--details 显示更多的信息
-f, --follow 跟踪实时日志
--since string 显示自某个timestamp之后的日志,或相对时间,如42m(即42分钟)
--tail string 从日志末尾显示多少行日志, 默认是all
-t, --timestamps 显示时间戳
--until string 显示自某个timestamp之前的日志,或相对时间,如42m(即42分钟)
# 指定时间后查看显示10行日志记录【要用标准时间】
docker logs -f -t --since="年-月-日T时:分:秒" --tail=10 containerID
# 显示最近10分钟的日志
docker logs -f --since=10m containerID
# 查询某个时间之后的日志
docker logs -t --since="2020-11-18T01:23:37" containerID
# 查询某个时间段内的日志
docker logs -t --since="2019-11-05T13:23:37" --until "2019-11-05T12:23:37" containerID
docker镜像的导入、导出
docker pull [选项] [仓库名]:[标签名] # 获取镜像
docker save [仓库名]:[标签名] > [指定的目录] # 导出镜像到指定地址
eg: docker save es:7.12.0 > images/es.tar # 将镜像es以压缩文件的形式导入到images/目录下,并命名为es.tar
docker load [可选参数,如:-i] [压缩文件格式镜像存在路径,如:/root/es/es.tar] # 将从指定位置镜像导入
docker run --name [容器名称N] -d -p 8080:8089 [仓库名]:[标签名] # 镜像使用
# 以上的步骤可以实现镜像在服务器之间的传递,也可以使用另外的方式来传递,将镜像发送到公共镜像仓库,使用的时候再pull下来
常见命令参考博客:
https://segmentfault.com/a/1190000008876540#articleHeader32
http://seanlook.com/2014/10/31/docker-command-best-use-1/
http://seanlook.com/2014/11/05/docker-command-best-use-2/
使用Dockerfile来定制一个镜像:
# 首先使用命令来创建一个Dockerfile文件
mkdir A # 创建一个名为A的文件夹
cd A # 进入到文件夹A
touch Dockerfile # 创建名为Dockerfile的文件,如果已经有该文件的话时间标签更新为系统当前的时间(默认方式),它们的数据将原封不动地保留下来;
docker build -t [仓库名]:[标签名] . # 构建仓库,标签名如果不设置的话,默认为latest,后边的"."表示Dockerfile的路径为当前路径下;"-t"表示设置镜像名称
docker run --name [容器名称N] -d -p 8080:8089 [仓库名A]:[标签名] # 用A镜像启动一个容器,命名为N;并映射了8089端口。"-d" 设置为守护进程模式,容器以后台方式运行;"-p" 将连接到主机的容器的特定端口暴露在外,可以有多个-p,来暴露多个端口,前一个8080为浏览器访问的端口,8089为容器内工程本身的端口。
设置一个最简单的 Dockerfile文件:
FROM openjdk #指定在openjdk 镜像的基础上来创建镜像
COPY testdocker-0.0.1-SNAPSHOT.jar app.jar #核心功能:必须要有,将生成的jar包拷贝到镜像中并更改命名
ENTRYPOINT ["java","-jar","app.jar"] # 执行启动jar包的操作
在进行docker镜像的生成时,可以将Dockerfile和jar包放到同一个文件夹中。
参考文章:https://yeasy.gitbooks.io/docker_practice/content/image/
4、遇到的问题
问题1: 在windows下对自己写的服务在docker中进行了部署以后,只能在当前主机上进行访问,局域网内别的主机均无法进行访问。
解决办法: 由于在windows下,docker是运行在虚拟机下的,需要进行一下虚拟机的相关配置,具体操作如下:
完成以上配置以后,局域网内的其他电脑就可以访问了。
5、Docker安装Mysql
遇到的问题: 最开始,我使用mysql的最新版的镜像,部署到Docker以后,只能在宿主机上进行访问,局域网内的其他电脑访问不到,最后将mysql的版本更改为5.7以后,解决了问题。
主要操作命令如下:
docker pull mysql:5.7 #获取mysql镜像
docker run --name mysql57 -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 # 启动mysql,设置密码为“123456”
docker exec -it mysql57 bash # 登录到mysql,
mysql -u root -p
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION; # 授予权限
flush privileges; # 刷新权限
************************************************************************************************
#登录到mysql 以后,也可以单独新建一个专门的远程账户
CREATE USER '用户名'@'%' IDENTIFIED WITH mysql_native_password BY '密码'; #创建账户
GRANT ALL PRIVILEGES ON *.* TO '用户名'@'%' IDENTIFIED BY '密码' WITH GRANT OPTION;#授予远程权限
完成以上配置以后就可以在宿主机和局域网的机器中进行测试了,如果在windows下也需要在VirtualBox中进行路由转发的配置,否则局域网其他电脑访问不到。
6、Docker Volume
docker 镜像是以 layer 概念存在的,一层一层的叠加,最终成为我们需要的镜像。但该镜像的每一层都是 ReadOnly 只读的。只有在我们运行容器的时候才会创建读写层。文件系统的隔离使得:
- 容器不再运行时,数据将不会持续存在,数据很难从容器中取出。
- 无法在不同主机之间很好的进行数据迁移。
- 数据写入容器的读写层需要内核提供联合文件系统,这会额外的降低性能。
Note:
1、数据卷就是宿主机上的一个文件或目录,当容器目录和数据卷目录绑定以后,双方修改会立即同步操作,一个数据卷可以被多个容器同时挂载
。
2、数据卷的作用:
- 容器数据的持久化
- 外部机器和容器间接通信
- 容器之间数据交换
在docker中引入了Volume,即为了实现将数据进行持久化,以下来介绍下容器卷的使用以及常用的命令:
docker volume create [卷name] # 创建卷
docker volume ls # 查询卷列表
docker volume inspect [卷name] # 获取卷的详细信息
docker volume rm [卷name] # 删除卷
******************************************************************
# 使用卷进行数据持久化
docker run -d -v v1:/var/lib/mysql -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7 #使用卷来创建一个名称为mysql的容器
# 如果接下来对mysql中的数据进行操作,然后删除容器,接下来重新以卷v1来创建一个容器
docker run -d -v v1:/var/lib/mysql -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql1 mysql:5.7
# 可以发现mysql1中会保留mysql数据库中对于数据的改变。
7、使用Docker来构建微服务
该部分内容可以参考博文:使用Docker来构建微服务
7.1、Docker Compose
在前边的内容中,已经简要的介绍了Dockerfile的配置以及使用,Dockerfile的使用可以让一个用户来单独的管理一个容器,而Compose则允许用户在一个模板(YAML 格式)中定义一组相关联的应用容器,例如在一个项目中加上Redis和Mysql对应的容器等。
接下来就简单介绍一下Compose在项目中的使用:
1、先创建一个项目(省略)
2、可以在src/main/resources下创建docker文件夹,即结构为:src/main/resources/docker
3、在docker文件夹下创建Dockerfile文件,名字不在固定为Dockerfile;
FROM openjdk
COPY reddot-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]
4、在src/main/resources下创建docker-compose.yml文件,配置内容如下:
version: '3' # 如果不配置的话,默认就使用1.0
# 服务列表
services:
# 服务1,名为:dot
dot:
build: # 用于配置Dockerfile
context: ./docker #用于注明Dockerfile文件所在的文件夹的路径,‘.’表示当前路径
dockerfile: dot.dockerfile # 所配置的Dockerfile文件的名称
container_name: my-web-container # 自定义容器的名称
ports: # 对容器进行端口映射,相当于“-p”
- "8080:8080"
volumes: # 使用卷来启动容器,相当于“-v”
- .:/code
depends_on: # 配置所依赖的容器,在启动容器时,会先启动依赖的容器
- redis
network_mode: host # 设置容器的网络模式,相当于--net,例如:设置为host模式
# 如果有多个服务需要通信时,可以每个服务或者外部访问入口服务均设置为host模式,这样在访问入口服务内就可以使用localhost作为主机名来访问其他的服务了,如;服务A访问服务B,可以将服务A设置为host模式
# 服务2,名为redis
redis:
image: redis # 启动指定容器的镜像,如果还配置有build,那么它将使用指定的build选项构建它,并使用image指定的名字和标记对其进行标记。
5、在进行运行部署的时候,可以在docker-compose.yml文件所在的文件夹下执行命令:“docker-compose up -d” 即可;加"-d"是为了让容器在后端执行,不加的话会一直处于容器的启动页面。
# docker-compose常用命令如下:
docker-compose up -d # 命令用于构建、启动、重新启动配置中包含的服务,同时会将yaml配置中的更新用于服务。
docker-compose stop # 停止运行容器而不删除
docker-compose down [options] # 停止容器并删除由up命令创建的容器,网络,卷和镜像,默认是只删除网络,如果需要删除其他的则需要添加[options]参数
docker-compose rm # 删除停止的服务容器
docker-compose start # 启动已经停止的服务器,与stop命令相对
注意:Dockerfile文件要与jar包放在一起。
使用docker-compose遇到的一个问题:更新完代码以后,执行docker-compose down
和docker-compose up -d
命令,部署完访问时仍然显示旧版的代码内容,这是因为docker-compose没有使用Dockerfile进行镜像的编译,这是需要使用docker-compose up --force-recreate --build -d
命令,–build参数必不可少。
--force-recreate
:强制Compose停止并重新创建所有容器
--build
:开启容器之前进行镜像的重新构建
8、使用Docker部署tomcat并搭建文件服务系统
使用docker部署一个tomcat服务非常的简单,使用如下的命令即可:
docker pull tomcat:[版本号,如:8.5] # 下载对应的tomcat镜像,这里选择8.5版本的
docker run -d -p 8080:8080 --name tomcat tomcat:8.5 # 这样即完成了容器的创建,tomcat的安装部署就完成了
但是通过浏览器访问tomcat的时候【http://xxxx:8080】会发现报如下的错误:
进入容器内部两种方式:
1、docker exec -it [容器名称或者ID,如:tomcat] /bin/bash # 进入名称为tomcat的容器内部
2、docker exec -it [容器名称或者ID,如:tomcat] sh
可以发现容器内部有webapps和webapps.dist两个文件夹,而webapps中为空,webapps.dist中存放的却是我们常见的内容,ROOT、index.jsp等等;所以只需要将webapps.dist中的内容拷贝到webapps中即可。这样再次访问就可以看到熟悉的小猫咪了。到这使用docker部署tomcat的操作就结束了。
退出容器的两种方式:
1、exit
2、ctrl+P+Q
8.1、修改tomcat的配置文件
由于我们使用docker容器来部署的tomcat服务,而在容器的内部是不允许使用’vi’、'vim’这些修改文件的命令的,所以我们在宿主机上进行配置文件的修改,然后在覆盖容器中的配置文件,再重启容器即可。
# 1、先将容器中中tomcat的配置文件拷贝到宿主机的/home/new目录下
docker cp [容器名称或ID,如:tomcat]:/usr/local/tomcat/conf/server.xml /home/new
# 2、在/home/new下修改配置文件
# 3、用修改后的配置文件覆盖容器中的tomcat的配置文件
docker cp /home/new/server.xml tomcat:/usr/local/tomcat/conf
# 4、重启容器
docker restart tomcat
8.2、使用tomcat搭建一个简单的文件系统
使用tomcat搭建文件系统一般在server.xml中添加如下配置即可:
<Context path="/videos" reloadable="true" docBase="/data"></Context>
但是使用docker部署的tomcat则需要将容器中的目录与宿主机的目录进行一下挂载操作,可以理解为我们上一步的操作相当于把容器中的data目录作为了文件系统的根目录,但是我们在宿主机上是无法操作容器内的data目录,如上述命令我们设置的docBase=“/data”,则启动tomcat容器时需要如下:
# 将宿主机的/home/vv/目录与容器中的data目录进行挂载
docker run -d -p 8080:8080 -v /home/vv/:/data/ --name tomcat tomcat:8.5
这是进入到容器内部,就会看到一个data文件夹:
我们在宿主机上的/home/vv目录中添加a.html1和index.jsp文件,然后查看容器中的data目录: