Docker应用容器
1. 初识 Docker
我们写的代码会接触到好几个环境:开发环境、测试环境以及生产环境。
这期间可能出现不同环境下的 “水土不服” 导致正常的程序无法运行。这时就需要将我们的环境一起打包到容器发过去。解决:软件跨环境迁移的问题。
1.1 - Docker的概念
Docker是一个开源的应用容器引擎。Docker诞生于2013年, dotCloud 公司出品(后改名为Docker Inc)。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上。
容器是完全使用沙箱机制,相互隔离。
容器性能开销极低。
Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版) 。
1.2 安装Docker
# 1、yum 包更新到最新
yum update
# 2、安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
yum install -y yum-utils device-mapper-persistent-data lvm2
# 3、 设置yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 4、 安装docker,出现输入的界面都按 y
yum install -y docker-ce
# 5、 查看docker版本,验证是否验证成功
docker -v
1.3 Docker 的架构
镜像(Image) :Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和对象一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
仓库(Repository) :仓库可看成一个代码控制中心,用来保存镜像。
1.4 配置 Docker 镜像加速器
- 默认情况下,将来从docker hub(https://hub.docker.com/)上下载docker镜像,太慢。一般都会配置镜像加速器:
(1)USTC:中科大镜像加速器(https://docker.mirrors.ustc.edu.cn)
(2)阿里云
(3)网易云
(4)腾讯云
- 如何在CentOS7 中配置 Docker镜像加速器
切换到 docker目录下 :cd /etc/docker
创建并编辑文件 : vim daemon.json
编辑文件内容:
{
"registry-mirrors": ["https://ndirti7e.mirror.aliyuncs.com"]
}
重启docker服务 : systemctl restart docker
附加命令 (linux修改文件后缀):mv filename.js filename.json (因为我的后缀写错了一直没有反应,hahaha)
2. Docker 命令 *
2.1 Docker 服务相关命令
systemctl start docker : 启动服务
systemctl start docker : 查看Docker的状态
systemctl stop docker : 停止Docker服务
systemctl restart docker : 重启Docker服务
systemctl enable docker : 开机启动Docker
2.2 Docker 镜像相关命令
1. 查看镜像(本地):docker images
2. 搜索镜像:docker search '软件名称'
3. 拉取镜像:docker pusll redis :版本号
4. 删除镜像(本地):docker rmi 镜像id
5. 查看当前所有镜像的id: docker images -q
6. 删除当前所有镜像: docker rmi `docker images -q`
- 如何查找镜像的版本号 :https://hub.docker.com/
- 如果镜像中存在两个id相同的镜像:如何删除?
1. 可以通过 镜像名称加上版本号 删除 docker rmi redis:5.0
2.3 Docker 容器相关命令 **
- 容器是有镜像这个物理的文件运行出来的实例。命令主要是如何通过镜像创建出容器。并且去操作容器。
1. 查看容器:docker ps (查看正在运行的容器)docker ps -a(查看运行或没有运行的容器)
2. 创建容器:docker run -i(保持一致运行) -t (给容器一个终端)--name=名字(给容器起一个名字) centos:7 (指定根据哪个镜像) /bin/bash (进入容器的指令)
案例 docker run -i -t --name=cl centos:7 /bin/bash (通过这种方式创建的容器一旦退出就会关闭) 使用 exit 退出容器
docker run -i -d(后台运行容器,但是创建完之后不会自动进入容器) --name=ct centos:7
3. 进入容器: docker exec -it 容器名称 /bin/bash
4. 启动容器:docker stop 容器名称
5. 停止容器:docker start 容器名称
6. 删除容器:docker rm 容器id/容器名称 删除所有容器 docker rm `docker ps -aq` 开启的容器是不能被删除的。
7. 查看容器信息:docker inspect 容器名称
3. Docker的应用部署
- 在Docker上安装常见的软件。
3.1 MySQL部署
- 在Docker容器中部署MySQL,并通过外部mysql客户端操作MySQL Server。
- 外部如何访问到docker容器中的mysql服务?容器内的网络服务不能直接和外部直接通信。
- 外部机器和宿主机可以直接通信。
- 宿主机和容器可以直接通信。
- 当容器中的网络服务需要外部机器访问时,可以将容器中提供服务的端口映射到宿主机的端口上。外部机器访问宿主机的该端口,从而直接访问容器的服务。
3.1.1 实现步骤
- 搜索mysql镜像。
docker search mysql
- 拉取mysql镜像。
docker pull mysql:5.6
- 创建容器。
- 首先创建一个存放mysql数据的文件,并切换进去
# 在/root目录下创建mysql目录用于存储mysql数据信息
mkdir ~/mysql
cd ~/mysql
# 复制下面命令到终端执行 ,注意 \ 后面不能有空格之类的影响命令的执行
docker run -id \
-p 3307:3306 \
--name=c_mysql \
-v $PWD/conf:/etc/mysql/conf.d \
-v $PWD/logs:/logs \
-v $PWD/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.6
# 使用命令 进入到容器中 docker exec -it c_mysql /bin/bash
参数说明:
- -p 3307:3306:将容器的 3306 端口映射到宿主机的 3307 端口。
- -v $PWD/conf:/etc/mysql/conf.d:将主机当前目录下的 conf/my.cnf 挂载到容器的 /etc/mysql/my.cnf。配置目录
- -v $PWD/logs:/logs:将主机当前目录下的 logs 目录挂载到容器的 /logs。日志目录
- -v $PWD/data:/var/lib/mysql :将主机当前目录下的data目录挂载到容器的 /var/lib/mysql 。数据目录
- -e MYSQL_ROOT_PASSWORD=123456:初始化 root 用户的密码。
-
操作容器中的mysql。
3.2 Tomcat部署
- 需求:在Docker容器中部署Tomcat,并通过外部机器访问Tomcat部署的项目。
3.2.1 实现步骤
- 搜索Tomcat镜像
docker search tomcat
- 拉取Tomcat镜像
docker pull tomcat
- 创建容器
# 在/root目录下创建tomcat目录用于存储tomcat数据信息
mkdir ~/tomcat
cd ~/tomcat
docker run -id --name=c_tomcat \
-p 8080:8080 \
-v $PWD:/usr/local/tomcat/webapps \
tomcat
参数说明:
- -p 8080:8080:将容器的8080端口映射到主机的8080端口
- -v $PWD:/usr/local/tomcat/webapps:将主机中当前目录挂载到容器的webapps
- 部署项目
- 在宿主机之前创建的tomcat目录下新建一个项目文件夹 test
mkdir test
- 在test文件夹中创建一个 index.html文件
vim index.html
- 测试访问
-
使用远程主机IP进行访问。
3.3 Nginx部署
- 在Docker容器中部署Nginx,并通过外部机器访问Nginx。
3.3.1 实现步骤
- 搜索Nginx
docker search nginx
- 拉取Nginx,并编写配置文件
docker pull nginx
# 在/root目录下创建nginx目录用于存储nginx数据信息
mkdir ~/nginx
cd ~/nginx
mkdir conf
cd conf
# 在~/nginx/conf/下创建nginx.conf文件,粘贴下面内容
vim nginx.conf
# nginx.conf 配置文件内容
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
- 创建容器
# 切换到Nginx目录下执行如下命令创建Nginx的容器。
docker run -id --name=c_nginx \
-p 80:80 \
-v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf \
-v $PWD/logs:/var/log/nginx \
-v $PWD/html:/usr/share/nginx/html \
nginx
参数说明:
- -p 80:80:将容器的 80端口映射到宿主机的 80 端口。
- -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf:将主机当前目录下的 /conf/nginx.conf 挂载到容器的 :/etc/nginx/nginx.conf。配置目录
- -v $PWD/logs:/var/log/nginx:将主机当前目录下的 logs 目录挂载到容器的/var/log/nginx。日志目录
- 测试访问
切换到html 文件夹下创建一个index.html文件之后进行访问测试。
3.4 Redis部署
- 在Docker容器中部署Redis,并通过外部机器访问 Redis。
3.4.1 实现步骤
- 搜索Redis镜像。
docker search redis
- 拉取Redis镜像。
docker pull redis:5.0
- 创建容器。
docker run -id --name=c_redis -p 6379:6379 redis:5.0 //注意端口可能被绑定了,需要替换端口
- 测试访问。
redis-cli.exe -h 192.168.149.135 -p 6379
4. 备份与迁移
5. Dockerfile
5.1 Dockerfile的原理
linux文件系统由bootfs和rootfs两部分组成。
bootfs:包含bootloader(引导加载程序)和kernelkernel(内核)。
rootfs:root文件系统,包含的就是典型linux系统中的/devproc,/bin、 /etc等标准目录和文件
不同的linux发行版,bootfs基本是一样的,而rootfs不同,如ubuntu、centos等。
Docker镜像是由特殊的文件系统叠加而成
最底端是 bootfs,并使用宿主机的bootfs
第二层是 root文件系统rootfs,称为base image
然后再往上可以叠加其他的镜像文件
统一文件系统(Union File System) 技术能够将不同的层整合成一个文件系统,为这些层提供了一个。
统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。
一个镜像可以放在另一个镜像的上面。位于下面的镜像称为父镜像,最底部的镜像成为基础镜像。
当从一个镜像启动容器时,Docker会在最顶层加载一个读写文件系统作为容器
5.2 Dockerfile概念及作用
- Docker的本质是啥?
- 答:是一个分层文件系统
- Docker中一个centos镜像为什么只有200MB,而是一个centos操作系统的iso文件要几个G?
- 答:Centos的iso镜像文件包含bootfs和rootfs,而docker的centos镜像复用操作系统的bootfs,只有rootfs和其他镜像层
- Docker中一个tomcat镜像为什么有500mb而一个tomcat的 安装包只有70多mb?
- 答:Centos的iso镜像文件包含bootfs和rootfs,而docker的centos镜像复用操作系统的bootfs,只有rootfs和其他镜像
5.2.1 镜像制作
5.2.1.1 容器转为镜像的方式
docker commit 容器id 镜像名称:自定义版本号
通过commit的方式转化,以数据卷的方式挂载的文件是不会生效的。在root目录下创建的文件夹会打包到镜像中。会在重新加载的时候生效。
# 1. 打包一个镜像
docker commit 需要打包的容器id lyp_tomcat:1.0.0
# 2. 需要将镜像镜像压缩之后才能够进行传输
docker save -o 压缩文件名称.tar 镜像文件名称:1.0.0
3. 将镜像的压缩文件进行解压
docker load -i 压缩文件名称
5.2.1.2 Dockerfile的方式制作镜像
5.2.2 DockerFile的概念
- Dockerfile 是一个文本文件
- 包含了一条条的指令
- 每一条指令构建一层,基于基础镜像,最终构建出一个新的镜像
- 对于开发人员:可以为开发团队提供一个完全一致的开发环境
- 对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfile文件构建一个新的镜像开始工作了
-
对于运维人员:在部署时,可以实现应用的无缝移植
- Dochub网址:https://hub.docker.com
5.3 Dockerfile关键字
关键字 | 作用 | 备注 |
---|---|---|
FROM | 指定父镜像 | 指定dockerfile基于那个image构建 |
MAINTAINER | 作者信息 | 用来标明这个dockerfile谁写的 |
LABEL | 标签 | 用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看 |
RUN | 执行命令 | 执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN ["command" , "param1","param2"] |
CMD | 容器启动命令 | 提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD ["command" , "param1","param2"] |
ENTRYPOINT | 入口 | 一般在制作一些执行就关闭的容器中会使用 |
COPY | 复制文件 | build的时候复制文件到image中 |
ADD | 添加文件 | build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务 |
ENV | 环境变量 | 指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value |
ARG | 构建参数 | 构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数 |
VOLUME | 定义外部可以挂载的数据卷 | 指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME ["目录"] |
EXPOSE | 暴露端口 | 定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp |
WORKDIR | 工作目录 | 指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径 |
USER | 指定执行用户 | 指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户 |
HEALTHCHECK | 健康检查 | 指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制 |
ONBUILD | 触发器 | 当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大 |
STOPSIGNAL | 发送信号量到宿主机 | 该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。 |
SHELL | 指定执行脚本的shell | 指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell |
5.4 案例
5.4.1 自定义centos7镜像 。
- 默认登录路径为 :/usr.
- 可以使用vim
- 实现步骤 :
# 创建文件夹
mkdir dockerfile
# 创建一个文件
vim centos_dockerfile
# 编写下面的命令
# 定义父镜像
From centos:7
# 定义作者的信息
MAINTAINER lyp
# 执行安装 vim 的命令
RUN yum install -y vim
# 设置工作路径
WORKDIR / usr
# 定义容器启动执行的命令
CMD /bin/bash
# 将上面的命令 统一放到一个文件中 ,最后使用 命令执行该文件
docker build -f ./存放命令的路径及文件名 -t 创建的镜像的名称 : 版本 . (最后是一个点)
# 根据新创建的镜像创建容器
docker run -it --name=lyp_centos lyp_centos:1 /bin/bash
5.4.2 定义 dockerfile,发布springBoot项目
将事先准备好的jar文件上传到linux服务器上面 。
将jar添加到容器中去。
实现步骤 :
# 定义父镜像
FROM java:8
# 定义作者信息
MAINTAINER lyp
# 添加jar包到容器中
ADD 项目名称 .jar app.jar
# 执行命令 启动
CMD java -jar app.jar
# 使用build命令执行上面的命令文件
docker build -f ./存放命令的路径及文件名 -t 创建的镜像的名称 : 版本 . (最后是一个点)
6. Docker相关概念
7. 服务编排
服务编排: 按照一定的业务规则批量管理容器
7.1 服务编排的概念
微服务架构的应用系统中一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,维护的工作量会很大。
要从Dockerfile build image 或者去dockerhub拉取image
要创建多个container
要管理这些container(启动停止删除)
7.2 Docker Compose概述
Docker Compose是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止。使用步骤:
利用 Dockerfile 定义运行环境镜像
使用 docker-compose.yml 定义组成应用的各服务
运行 docker-compose up 启动应用
7.3 Docker Compose 安装使用
7.4 案例
8. Docker容器数据卷
- 数据卷:是宿主机中的一个文件或者目录 。
- 当数据卷目录和数据卷目录绑定后,对方的修改会立即同步。
- 一个数据卷可以被多个容器同时挂载。
8.1 数据卷的概念以及作用
- 思考:当Docker 删除后在容器中产生的数据还存在吗?
- 思考:Docker容器和外部机器可以直接交换文件吗?
- 思考:容器之间如何进行数据的交互?
8.1.1数据卷的作用
- 容器数据持久化。
- 外部机器和容器之间的间接通信。
- 容器之间数据交换。
8.2 配置数据卷
- 创建启动容器的时候使用-v设置数据卷 。
- 创建的目录必须是绝对路径。
- 路径之间使用 ‘:’ 分割不能有空格。
- 如果目录不存在会自动创建。
- 可以挂在多个数据卷。
docker run -it --name=cf -v /root/data:/root/data-container /centos:7 /bin/bash
8.2.1 操作
1. 创建容器并挂在数据卷 : docker run -it --name=cf -v /root/data:/root/data-container :centos:7 /bin/bash
2. 在容器中创建文件 : touch a.txt
3. 在宿主机中写入文件 : echo 123 > b.txt
-------------------------------------------
1. 创建一个守护模式的容器并挂载数据卷:docker run -id --name=ct -v /root/data:/root/data-container centos:7
2. 进入到容器中 : docker exec -it ct /bin/bash
-------------------------------------------
1. 创建容器并挂载两个以上数据卷 : docker run -it --name=cs -v ~/data:/root/data1\ -v ~/data:/root/data-container \ centos:7 /bin/bash 其中~代表 /root (但是只能将宿主机的路径写成这样) \ 代表没有写完命令 换行继续写。
8.2.2 两个容器同时挂载到一个数据卷上实现两个容器之间的数据交换
1. 创建第一个容器绑定到宿主机的data目录上 : docker run -it --name=cp -v /root/data:/root/data centos:7
2. 创建第二个容器也绑定到宿主机的data目录上:docker -it --name=cd -v /root/data:/root/data centos:7
3. 在第二个容器中写入内容到c.txt文件 : echo cd-container > c.txt
4. 查看该文件 : cat c.txt
8.3 配置数据卷容器
8.3.1 多容器进行数据交换
- 多个容器挂载同一个数据卷,但是工作其来比较麻烦。
-
数据卷容器。
8.3.2 操作
1. 创建c3数据卷容器,使用-v参数设置数据卷:docker run -it --name=c3 -v /volume centos:7 /bin/bash
2. 创建并启动c2 容器,使用 -volumes-from 参数设置数据卷 : docker run -it --name=c1 --volumes-from c3 centos:7 /bin/bash
3. 创建并启动c2容器 ,使用 -volumes-from 参数设置数据卷:docker run -it --name=c2 --volumes-from c3 centos:7 /bin/bash
4. 查看容器详情 : docker inspect 容器名称