Docker 概念
- Docker 是一个开源的应用容器引擎
- 诞生于 2013 年初,基于 Go 语言实现, dotCloud 公司出品(后改名为Docker Inc)
- Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上。
- 容器是完全使用沙箱机制,相互隔离
- 容器性能开销极低。
- Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版)
Docker安装
1、yum在线安装
# 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
2、其他安装方式
Docker安装
3、宝塔面板安装
Docker的架构
-
镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
-
容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和对象一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
例如,使用centos7的镜像,创建一个容器,就像是开启一个虚拟机,该虚拟机里,就是linux操作系统的环境
-
仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
配置镜像加速器
Docker会去中央仓库Docker Hub上下载一些镜像,这里我们使用阿里云的
- 打开阿里云的容器镜像服务
- 选择镜像加速器
- 复制到Linux下运行即可
目录下确实有该文件
Docker 命令
1、服务相关的命令
#启动 docker服务
systemctl start docker
#停止 docker服务
systemctl stop docker
#重启 docker服务
systemctl restart docker
#查看 docker服务状态
systemctl status docker
#开启自启动 docker
systemctl enable docker
2、镜像相关的命令
1、查看镜像: 查看本地所有的镜像
docker images
docker images –q # 查看所有镜像的id
2、搜索镜像: 从网络中查找需要的镜像
docker search 镜像名称
我们通常直接去Docker的中央仓库查看有无该镜像,以及该镜像的版本信息
3、拉取镜像: 从Docker仓库下载镜像到本地
镜像名称格式为 名称:版本号
docker pull 镜像名称:版本号
若不指定版本号,则为最新版本
4、删除镜像
# 删除指定本地镜像
docker rmi 镜像id #rmi:remove images
# 删除所有本地镜像
docker rmi `docker images -q` #注意是Tab键上面的 ·
3、容器相关的命令
容器的概念,有点像一个虚拟机;它根据镜像,在虚拟机中创建一套环境
1、查看容器
相当于查看所有的虚拟机
docker ps # 查看正在运行的容器
docker ps –a # 查看所有容器,包括关闭中的
2、创建并启动容器
相当于创建一个虚拟机,根据镜像搭建环境
docker run 参数 --name=容器名称 镜像名
可选操作 [/bin/bash] #进入容器时,使用黑窗口
参数说明:
- -i:保持容器运行。通常与 -t 同时使用。加入it这两个参数后,容器创建后自动进入容器中,退出容器后,容器自动关闭。
- -t:为容器重新分配一个伪输入终端,通常与 -i 同时使用。
- -d:以守护(后台)模式运行容器。创建一个容器在后台运行,需要使用docker exec 进入容器。退出后,容器不会关闭。
- -it 创建的容器一般称为交互式容器,-id 创建的容器一般称为守护式容器
- –name:为创建的容器命名。
1)使用 -it 创建交互式容器
当exit退出时,容器自动关闭
2)使用 -id 创建守护式容器
3、进入容器
docker exec 参数[-it] 容器名称 [/bin/bash] # 退出容器,容器不会关闭
4、停止容器
相当于关闭虚拟机
docker stop 容器名称
5、启动容器
相当于开启虚拟机,但并没有进入,后台运行
docker start 容器名称
6、删除容器
如果容器是运行状态则删除失败,需要停止容器才能删除
相当于删除虚拟机
docker rm 容器名称/容器ID
docker rm `docker ps -aq` 删除所有的虚拟机
7、查看容器信息
docker inspect 容器名称
数据卷
1、什么是数据卷
数据卷
- 是宿主机中的一个目录或文件
- 当容器目录和数据卷目录绑定后,双方的修改都会被同步
- 一个数据卷可以被多个容器同时挂载
- 一个容器也可以挂载多个数据卷
数据卷作用
- 容器数据持久化
- 外部机器和容器间接通信
- 容器之间数据交换
2、一个容器挂载一个数据卷
创建启动容器时,使用 –v 参数 设置数据卷
docker run ... –v 宿主机目录(文件):容器内目录(文件) ...
注意
1、目录必须是绝对路径,如果目录不存在,会自动创建
2、可以挂载多个数据卷
这两个文件就被双向绑定了(挂载)!
3、一个容器挂载多个数据卷
4、多个容器挂载同一个数据卷
这样就可以实现容器间的数据同步了!
5、数据卷容器
本质还是一个容器,只不过该容器中存放了数据卷信息
其他的容器,只需要继承数据卷容器即可!
不需要再手动关联到宿主机中的数据卷了!
即便数据卷容器挂了,其他的容器依然可以关联到宿主机中的数据卷
- 创建数据卷容器
- 其他容器继承数据卷容器
- 查看数据卷在宿主机中的位置
使用 docker inspect 容器名 命令
继承于数据卷容器的容器,他们的数据卷也在这个位置!
所以,即便数据卷容器挂掉,其他容器之间依然可以同步数据!
应用部署
1、Mysql部署
Docker容器中部署MySQL,并通过外部Sql yog操作MySQL Server。
- 外部机器与容器之间是无法直接通信的,但是可以和宿主机直接通信,宿主机和容器又可以直接通信;
- 可以将容器中提供服务的端口映射到宿主机的端口上,外部机器访问宿主机端口,从而间接访问容器的服务(端口映射)
1、搜索mysql镜像
docker search mysql
2、拉取镜像文件
docker pull mysql:5.7
3、创建容器,设置端口映射、数据卷
在宿主机中创建一个目录,用来存放数据卷(与容器中的配置文件、日志文件、数据文件进行挂载)
创建容器
[root@maki mysql] docker run -id \
> -p 3306:3306 \
> --name=c_mysql \
> -v /home/mysql/conf:/etc/mysql \
> -v /home/mysql/logs:/logs \
> -v /home/mysql/data:/var/lib/mysql \
> -e MYSQL_ROOT_PASSWORD=123456 \
> mysql:5.7
说明:
- docker run -id --》创建守护式容器
- -p 3306:3306 --》 将宿主机的3306端口,映射到容器的3306端口
- –name=c_mysql --》 容器名称为c_mysql
- -v /home/mysql/conf:/etc/mysql/conf.d --》将宿主机的conf目录挂载到容器的/etc/mysql。 配置目录
- -v /home/mysql/logs:/logs --》 将宿主机的logs目录挂载到容器的/logs目录。 日志目录
- -v /home/mysql/data:/var/lib/mysql --》 将宿主机的data目录挂载到容器的/var/lib/mysql。 数据目录
- -e MYSQL_ROOT_PASSWORD=123456 --》初始化root用户的密码
- mysql:5.7 镜像的名称+版本号
4、进入容器,操作mysql
5、外部机器使用sqlyog操作容器中的数据库
因为我们挂载了数据,所以要修改容器中的mysql配置时,直接对宿主机中的数据卷进行操作即可!
2、Tomcat部署
搜索tomcat镜像、拉取镜像…
1、在宿主机上创建tomcat目录,用于挂载容器中tomcat的数据信息
mkdir /home/tomcat
2、创建容器,设置端口映射、目录映射
[root@maki /] docker run -id --name=c_tomcat \
> -p 8080:8080 \
> -v /home/tomcat:/usr/local/tomcat/webapps \
> tomcat
3、在宿主机的tomcat目录下写一个html测试
[root@maki test] pwd
/home/tomcat/test
[root@maki test] vim index.html
注意:html文件要被放在webapps下的某一个文件夹中才行,否则访问不到;对应在宿主机中,即在tomcat目录下新建一个文件夹,将html文件放入
3、Nginx部署
搜索nginx镜像、拉取镜像…
1、在宿主机上提前准备好一个文件 nginx.conf,用于挂载容器中的文件
mkdir /home/nginx/conf
[root@maki conf] vim 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;
}
2、创建容器,设置端口映射、目录映射
[root@maki home] docker run -id --name=c_nginx \
> -p 80:80 \
> -v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
> -v /home/nginx/logs:/var/log/nginx \
> -v /home/nginx/html:/usr/share/nginx/html \
> nginx
注意:挂载文件时,宿主机中先提前准备好该文件
3、使用外部机器访问nginx
4、Redis部署
搜索redis镜像,拉取镜像…
1、创建容器,设置端口映射
[root@maki home] docker run -id --name=c_redis \
> -p 6379:6379 \
> redis
2、使用外部机器连接redis
Docker镜像原理
- Docker镜像本质是什么?
- 一个分层文件系统
- Docker中一个centos镜像为什么只有200mb,而一个centos操作系统的ios文件要几个GB?
- centos的ios镜像文件包含bootfs(Linux内核)和rootfs(root文件系统,包含的就是典型的 /dev,/home,/etc…等目录文件)
- centos的iso镜像文件包含bootfs和rootfs,而docker的centos镜像复用操作系统的bootfs,只有rootfs和其他镜像层
- Docker中一个tomcat镜像为什么有500mb,而一个tomcat安装包只有70多mb?
- 由于docker中镜像是分层的,tomcat虽然只有70多MB,但他需要依赖于父镜像和基础镜像,所有整个对外暴露的tomcat镜像大小500多
1、容器转为镜像
-
将容器转为镜像
docker commit 容器id 镜像名称:版本号
-
镜像转为压缩包(镜像文件不能直接传输)
docker save -o 压缩文件名称 镜像名称:版本号
-
压缩包解压缩后,就是一个镜像
docker load –i 压缩文件名称
注意:容器转为镜像时,容器中被挂载的文件不会被转入,其他的文件都会被转入
2、dockerfile制作镜像
- Dockerfile 是一个文本文件
- 包含了一条条的指令
- 每一条指令构建一层,基于基础镜像,最终构建出一个新的镜像
- 对于开发人员:可以为开发团队提供一个完全一致的开发环境
- 对于测试人员:可以直接拿开发时所构建的镜像开始测试了
- 对于运维人员:在部署时,可以实现应用的无缝移植
1、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 |
2、案例-自定义centos
需求:创建一个镜像,默认登录路径为/usr;可以使用vim指令
实现步骤:
-
定义父镜像:FROM centos:7
-
定义作者信息:MAINTAINER maki
-
执行安装vim命令: RUN yum install -y vim
-
定义默认的工作目录:WORKDIR /usr
-
定义容器启动执行的命令:CMD /bin/bash
-
通过dockerfile构建镜像:
docker bulid –f dockerfile的文件路径 –t 镜像名称:版本
演示:
[root@maki daichen] vim my_centos_dockfile
FROM centos:7 #该镜像基于centos:7
MAINTAINER maki #该镜像的作者信息
RUN yum install -y vim #创建镜像时,添加vim环境
WORKDIR /usr #通过该镜像创建的容器,默认登录路径为/usr
CMD /bin/bash #启动容器时,执行黑窗口
说明:
- -f : 指明dockfile文件的位置
- -t : 创建的镜像名称:版本号
- . : 告诉Docker到当前目录中去找dockerfile文件
根据我们自定义的centos镜像创建的容器,就可以使用vim指令了!
3、案例-部署springboot项目
需求:定义dockfile,发布springboot项目
实现步骤:
- 定义父镜像:FROM java:8
- 定义作者信息:MAINTAINER maki
- 将jar包添加到容器: ADD springboot.jar app.jar
- 定义容器启动执行的命令:CMD java –jar app.jar
- 通过dockerfile构建镜像:docker bulid –f dockerfile文件路径 –t 镜像名称:版本
演示:
-
先将springboot项目打包,放入服务器(宿主机)中
-
创建一个dockfile文件,写入参数
FROM java:8 MAINTAINER maki ADD springboot.jar app.jar CMD java -jar app.jar
-
将该文件转为镜像
-
创建容器,测试
Docker compose服务编排
docker compose用来按照一定的业务规则,批量管理容器!
Docker Compose是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止。使用步骤:
- 利用 dockerfile 创建镜像
- 使用 docker-compose.yml 设置容器的启动规则
- 运行 docker-compose up 按照定义好的规则,启动容器
1、docker compose安装与卸载
安装 docker compose
# Compose目前已经完全支持Linux、Mac OS和Windows,
#在我们安装Compose之前,需要先安装Docker。
#下面我们以编译好的二进制包方式安装在Linux系统中。
curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# 设置文件可执行权限
chmod +x /usr/local/bin/docker-compose
# 查看版本信息
docker-compose -version
卸载 docker compose
# 二进制包方式安装的,删除二进制文件即可
rm /usr/local/bin/docker-compose
2、docker compose编排nginx+springboot
-
创建docker-compose目录
-
提前准备好nginx的配置文件,用于挂载到容器中
数据卷在宿主机的 home/docker-compose/nginx/conf/nginx.confserver { listen 80; access_log off; location / { #c_springboot容器中的8080端口 proxy_pass http://c_springboot:8080; } }
-
编写docker-compose.yml文件(文件名固定)
该文件在宿主机的 /home/docker-compose目录下version: '3' services: c_nginx: #创建容器 image: nginx ports: - 80:80 #端口映射 links: - c_springboot #当前容器可以访问到c_springboot容器 volumes: #挂载数据卷 - ./nginx/conf:/etc/nginx/conf.d c_springboot: image: springboot expose: - "8080" #暴露端口
-
使用docker compose启动容器
在docker-compose.yml文件目录下执行
就会按照规则,批量创建容器
私有仓库
1、搭建私有仓库
# 1、拉取私有仓库镜像
docker pull registry
# 2、启动私有仓库容器
docker run -id --name=registry -p 5000:5000 registry
# 3、打开浏览器 输入地址http://私有仓库服务器ip:5000/v2/_catalog
# 看到{"repositories":[]} 表示私有仓库 搭建成功
# 4、修改Docker的daemon.json
vim /etc/docker/daemon.json
# 在上述文件中添加一个json数据 key:value,保存退出
# 此步用于让 docker 信任私有仓库地址
{"insecure-registries":["私有仓库服务器ip:5000"]}
# 5、重启docker 服务
systemctl restart docker
# 6、重启私有仓库容器
docker start registry
2、上传镜像到私有仓库
# 1、标记镜像为私有仓库的镜像
docker tag centos:7 私有仓库服务器IP:5000/centos:7
# 2、上传标记的镜像
docker push 私有仓库服务器IP:5000/centos:7
3、从私有仓库拉取镜像
#拉取镜像
docker pull 私有仓库服务器ip:5000/centos:7
Docker和虚拟机比较
其实docker能做的事情,虚拟机都能做!只不过docker更加轻量级!
容器就是将软件打包成标准化单元,以用于开发、交付和部署。
- 容器镜像是轻量的、可执行的独立软件包 ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。
- 容器化软件在任何环境中都能够始终如一地运行。
- 容器赋予了软件独立性,使其免受外在环境差异的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。
容器和宿主机共享的是操作系统,而虚拟机和宿主机共享的是硬件
即,容器只能运行同一类型操作系统,而虚拟机可以运行不同的操作系统