docker学习与使用(概念、镜像、容器、数据卷、dockerfile等)
文章目录
- 前言
- 引入
- docker 简介
- docker的应用场景
- docker的虚拟化技术VS虚拟机
- docker的优点
- docker架构
- Docker仓库
- Docker镜像
- linux操作系统的大致组成部分
- Docker容器
- docker安装与启动
- 校验版本
- 移除旧的版本
- 安装依赖工具
- 设置软件源
- 安装docker
- 验证
- 配置镜像加速器
- docker服务相关命令
- docker镜像相关命令
- docker容器相关命令
- 数据卷
- 数据卷配置
- 数据卷容器
- docker应用部署
- mysql部署
- tomcat
- 制作镜像
- dockerfile 制作镜像
- dockerfile 常用命令
- 通过dockerfile制作镜像
- docker compose
- 安装
- 示例
- docker 私有仓库(未完成)
- docker swarm集群搭建(未完成)
- 参考目录
前言
阅读本文前请注意最后编辑时间,文章内容可能与目前最新的技术发展情况相去甚远。欢迎各位评论与私信,指出错误或是进行交流等。
引入
问题1:
某IT部门要上线一个项目。常规操作,直接去线上服务器,拷贝一个tomcat,然后改端口号,然后部署应用到webapps文件
夹下,重启就好。
一个服务器上可能会部署多个应用服务。如果某个应用出现问题,CPU占用达到100%,可能这个服务器上的其他应用也会出现问题。
对于一个大型应用拆分为几十个微服务,分别交由不同的团队开发,不同团队之间水平参差不齐。如果还采用这种部署方式,
你的应用可能会因为另一个团队的应用发生意外。因部署在了同一台服务器上,导致全部出现问题。
问题2:
开发和线上代码(同一套代码)问题。开发阶段部署一套软件环境,测试人员在开发中测试没有问题,运维进行部署。但是正
式部署到服务器时,发生了问题(启动参数、环境问题、漏配了参数)等意外。
问题3:
随着微服务技术的兴起,一个大的应用需要拆分成多个微服务。多个微服务的生成,就会面临庞大系统的部署效率,开发协同
效率问题。然后通过服务的拆分,数据的读写分离、分库分表等方式重新架构,而且这种方式如果要做的彻底,需要花费大量人力
物力。可能需要部署很多个服务器。
问题4:
持续的软件版本发布/测试项目。到线上环境的集成
以上问题可以由docker解决。
docker 简介
Docker 是一个开源的应用容器引擎,可以让开发者打包应用及其依赖到一个轻量级、可移植的容器中。
容器是一种标准化的软件单元,可以在任何支持 Docker 的环境中快速部署和运行。容器性能开销极低。
容器是完全使用沙箱机制,相互隔离。
docker的应用场景
- 应用的自动化打包和发布。
- 自动化测试和持续集成、发布。
- 微服务架构:每个微服务独立打包成容器,灵活扩展
docker的虚拟化技术VS虚拟机
名词解释:
infrastructure(基础服务)硬件
Host OS 主机操作系统
VM 虚拟机
Hypervisor 虚拟层程序
1.实现原理技术不同
虚拟机是用来进行硬件资源划分的完美解决方案,利用的是硬件虚拟化技术,如VT-x、AMD-V会通
过一个hypervisor层来实现对资源的彻底隔离。
而容器则是操作系统级别的虚拟化,利用的是内核的Cgroup和Namespace特性,此功能通过软件
来实现,仅仅是进程本身就可以实现互相隔离,不需要任何辅助。
2.使用资源方面不同
Docker容器与主机共享操作系统内核,不同的容器之间可以共享部分系统资源,因此更加轻量级,
消耗的资源更少。
虚拟机会独占分配给自己的资源,不存在资源共享,各个虚拟机之间近乎完全隔离,会消耗更多的资源。
3.应用场景不同
若需要资源的完全隔离并且不考虑资源的消耗,可以使用虚拟机。
若是想隔离进程并且需要运行大量进程实例,应该选择Docker容器。
特性 | 容器 | 虚拟机 |
---|---|---|
启动速度 | 秒级 | 分钟级 |
硬盘使用 | 一般为MB | 一般为GB |
性能 | 接近原生 | 弱于原生 |
系统支持量 | 单机一般支持上千个容器 | 单机一般支持几十个虚拟机 |
docker的优点
- Docker能够自动执行重复性任务,例如搭建和配置开发环境,从而解放了开发人员以便他们专注在真正重要的
事情上:构建杰出的软件。 - 用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就
像管理普通的代码一样。 - Docker的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现“这段代码在
我机器上没问题啊”这类问题; - 可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。–更快速的启动时间
- 避免公用的服务器,资源会容易受到其他用户的影响。–隔离性
- 善于处理集中爆发的服务器使用压力;–弹性伸缩,快速扩展
- 可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正
常运行的情况。–迁移方便 - 用Docker可以通过定制应用镜像来实现持续集成、持续交付、部署。-持续交付和部署
docker架构
Docker使用客户端-服务器(C/S)架构模式,使用远程API来管理和创建Docker容器。
组件 | 说明 |
---|---|
Docker Machine | 是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker |
Docker客户端(Client) | Docker客户端通过命令行或者其他工具使用DockerAPI与Docker的守护进程(daemon)通信。 |
Docker主机(Host) | 一个物理或者虚拟的机器用于执行Docker守护进程和容器。 |
Docker镜像(Images) | Docker镜像是用于创建Docker容器的模板。 |
Docker容器(Container) | 容器是独立运行的一个或一组应用。 |
Docker仓库(Registry) | Docker仓库用来保存镜像,可以理解为代码控制中的代码仓库。DockerHub提供了庞大的镜像集合供用户使用。 |
Docker仓库
是一个存储镜像的仓库。通常被部署在互联网服务器或者云端。
Docker Hub(https://hub.docker.com)提供了庞大的镜像集合供使用。
Docker镜像
Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些
为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也
不会被改变。
经观察发现,
问题1:Docker中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个G?
问题2:Docker中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB?
在说明上述两个问题之前,先了解一下linux操作系统的大致组成部分
linux操作系统的大致组成部分
操作系统组成部分:
- 进程调度子系统
- 进程通信子系统
- 内存管理子系统
- 设备管理子系统
- 文件管理子系统
- 网络通信子系统
- 作业控制子系统
其中Linux文件系统由bootfs和rootfs两部分组成
- bootfs:包含bootloader(引导加载程序)和kernel(内核)
- rootfs:root文件系统,包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件
- 不同的linux发行版,bootfs基本一样,而rootfs不同,如ubuntu、centos等
Docker镜像是由特殊的文件系统叠加而成
- 最底端是bootfs,并使用宿主机的bootfs
- 第二层是root文件系统rootfs,称为base image
- 然后再往上可以叠加其他的镜像文件
- 统一文件系统(UnionFileSystem)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角
这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。 - 一个镜像可以放在另一个镜像的上面。位于下面的镜像称为父镜像,最底部的镜像成为基础镜像。
答问题1:Docker使用了宿主机中的bootfs,所以docker中的centos镜像只需要下载对应的rootfs文件系统即可。而一个centos操作系统的iso文件是包含了bootfs和rootfs两部分。
答问题2:Docker中一个tomcat镜像将jdk和tomcat整合成一个文件,隐藏了多层的存在,在用户的角度看来,只存在一个tomcat。tomcat安装包仅有tomcat部分的文件。
iso镜像包含操作系统完整的root文件系统,其体积往往是庞大的。因此在Docker设计时,就充分利用统一文件系统(UnionFileSystem)的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个ISO那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。
分层存储的特征还使得镜像的复用、定制变的更为容易。当从一个镜像启动容器时,docker会加载一个可读写文件系统作为容器。可以用之前构建好的镜像作为基础层,然后在此基础上修改或进一步添加新的层,以定制自己所需的内容,构建新的镜像。
Docker容器
Docker容器通过Docker镜像来创建。容器与镜像的关系类似于面向对象编程中的对象与类。镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间,甚至自己的用户ID空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。也因为这种隔离的特性,很多人初学Docker时常常会混淆容器和虚拟机。
前面讲过镜像使用的是分层存储,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层(也就是上文提到的可读写容器)。
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
按照Docker最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume)、或者绑定宿主目录。这样读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据不会丢失。
docker安装与启动
docker命令参考大全:https://www.runoob.com/docker/docker-tutorial.html
docker官方文档:https://docs.docker.com/
本文基于安装了centos7的虚拟机进行介绍。
因此,安装docker容器需要先配置好一台centos虚拟机,并配置好网络连接,以及挂载完iso镜像文件。确保yum可以正常使用
目前,CentOS发行版本中的内核支持Docker。Docker运行在CentOS7上,要求系统为64位、系统内核版本为3.10以上。
校验版本
命令: uname -r 校验Linux内核版本(3.10以上版本)
从2017年3月开始docker在原来的基础上分为两个分支版本:Docker CE和Docker EE。
Docker CE 即社区免费版, Docker EE 即企业版,强调安全,但需付费使用。
移除旧的版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common\
docker-latest \
docker-latest-logrotate\
docker-logrotate\
docker-selinux \
docker-engine-selinux \
docker-engine
如果yum报告未安装这些软件包,则可以。
安装依赖工具
yum install -y yum-utils device-mapper-persistent-data lvm2
设置软件源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo# 也可以使用阿里云的源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装docker
yum install -y docker-ce docker-ce-cli containerd.io
# 或者使用以下命令
sudo yum -y install docker-ce
验证
docker --version
配置镜像加速器
使用Docker的时候,默认从官方获取镜像。鉴于国内网络问题,从仓库拉取Docker镜像十分缓慢,我们可以配置镜像加速器来解决。
Docker官方和国内很多云服务商都提供了国内加速器服务,例如:阿里云镜像加速器
-
注册阿里云账号(已有账号可跳过)
-
获取专属加速器地址
- 登录阿里云控制台
- 搜索进入 容器镜像服务 → 镜像工具 → 镜像加速器
根据官网提示的命令进行操作
sudo mkdir -p /etc/docker
# 写入阿里云加速器配置(替换成你的实际地址)
sudo tee /etc/docker/daemon.json <<-'EOF'
{"registry-mirrors": ["https://xxxxxx.mirror.aliyuncs.com"]
}
EOF
# 重启 Docker 生效
sudo systemctl daemon-reload
sudo systemctl restart docker
docker服务相关命令
# 启动docker
systemctl start docker# 停止docker
systemctl stop docker# 重启docker
systemctl restart docker# 查看docker状态:
systemctl status docker# 设置docker开机启动:
systemctl enable docker# 查看docker概要信息:
docker info# 查看docker总体帮助文档:
docker --help# 查看docker命令帮助文档:
docker 具体命令 --help
docker镜像相关命令
#列出当前环境中已下载的镜像
docker images docker search 某个xxx镜像名字
# 去公共仓库中查找某个镜像 例如:docker search redis
加上 --limit : 只列出N个镜像 例如:docker search --limit 5 redis docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
# Docker 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号]。默认地址是 Docker Hub。
# 仓库名:如之前所说,这里的仓库名是两段式名称,即 <用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像。
#简略版
docker pull 某个xxx镜像名字[:TAG]
# 没有TAG就是拉取最新版
例如 docker pull mysqldocker pull redis:6.0.8docker rmi -f 某个xxx镜像名字ID
删除单个 docker rmi -f 镜像ID
删除多个 docker rmi -f 镜像名1:TAG镜像2
删除全部 docker rmi -f $(docker images -qa)
docker容器相关命令
1.新建和启动容器实例
docker run [options] image [command]
options说明(常用):
–name= “容器新名字” 为容器指定一个名称
-d 后台运行容器并返回容器ID,也即启动守护式容器(后台运行)
-i 以交互模式运行容器,通常与-t 同时使用
-t 为容器重新分配一个伪输入终端,通常与-i 同时使用
-P 随机端口映射,大写P
-p 指定端口映射,小写p
docker run -it --name=c1 centos:7 /bin/bash启动一个有交互命令的centos7系统
参数说明:
i:交互式操作。
t:终端。
centos:7:centos:7镜像。
bin/bash:放在镜像名后的是命令,这里我们希望有个交互式Shell,因此用的是bin/bash。一经创建就会进入容器
要退出容器,直接输入exit
2.查看容器状态
docker ps
-a 列出当前所有正在运行的容器+历史上运行过的
-l 显示最近创建的容器
-n 显示最近n个创建的容器
-q 静默模式,只显示容器编号
如果使用docker ps则看不到这一条记录。因为我们使用docker run -it创建的容器在输入exit命令退出后,该容器就不再运行了。因为该容器没有使用 -d参数设置为后台运行。
# 创建守护式容器(后台运行)
docker run -id redis:6.0.8 /bin/bash
3.退出容器
进入容器,exit退出,容器停止(守护式容器不会停止)
exit进入容器,ctrl+p+q 退出,容器不停止
ctrl+p+q
4.进入容器、查看容器信息
进入容器
docker exec -it 容器id/容器名称 bashShell
例 docker exec -it c1 bin/bash查看容器运行日志
docker logs 容器id查看容器运行的进程
docker top 容器id 查看内部细节
docker inspect 容器id
5.重启、停止、强制停止容器,启动、删除已停止的容器
重启容器
docker restart 容器ID或者容器名停止容器
docker stop 容器ID或者容器名强制停止容器
docker kill 容器ID或容器名启动已经停止运行的容器
docker start 容器ID或者容器名删除已经停止的容器
docker rm 容器ID或容器名一次删除多个容器
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
6.在宿主机和容器之间交换文件
在宿主机和容器之间相互COPY文件cp的用法如下docker cp [OPTIONS] LOCALPATHI CONTAINER:PATH #宿主机复制到容器中
docker cp [OPTIONS] CONTAINER:PATH LOCALPATH #容器中复制到宿主机宿主机复制一个图片到容器中:将png图片复制到了容器指定目录下
docker cp guoweixin.png tomcat2:/usr/local/tomcat/webapps/ROOT将容器内的index.jsp复制到root下
docker cp tomcat2:/usr/local/tomcat/webapps/ROOT/index.jsp /root
数据卷
问题一:通过镜像创建一个容器。Docker容器删除后,在容器中产生的数据也会随之销毁。容器中的数据不是持久化状态的。
问题二:Docker容器和外部机器如何交换文件
问题三:容器与容器之间如何进行数据交互
那有没有一种独立于容器、提供持久化并能服务于多个容器的东西呢?
数据卷:是宿主机中的一个目录或文件(可供一个或多个容器使用的特殊目录),当容器目录和数据卷目录绑定后,对方的修改会立即同步。一个数据卷可以被多个容器同时挂载,一个容器也可以被挂载多个数据卷
特性:
- 数据卷可以在容器之间共享和重用
- 对数据卷的修改会立马生效
- 对数据卷的更新,不会影响镜像
- 数据卷默认会一直存在,即使容器被删除
数据卷配置
创建启动容器时,使用-V参数设置数据卷
# 方式一
docker run...-v 宿主机目录(文件):容器内目录(文件)...
注意事项:
1.目录必须是绝对路径
2.如果目录不存在,会自动创建
3.一个容器可以挂载多个数据卷
将两个容器挂载同一数据卷,则可实现容器之间的数据交换。
# 方式二
#1 创建数据卷
docker volume create 数据卷名称
#创建数据卷之后,默认会存放到目录:/var/lib/docker/volume/数据卷名称/_data目录下
#2 查看数据卷
docker volume inspect 数据卷名称
#3 查看全部数据卷信息
docker volume 1s
#4 删除数据卷
docker volume rm 数据卷名称
#5 应用数据卷
#5.1 当你映射数据卷时,如果数据卷不存在,Docker会帮你自动创建
docker run -v...数据卷名称:容器内路径...
数据卷容器
当多个容器挂在同一个数据卷,我们可以将一个容器挂载到数据卷上(作为数据卷容器)。其余容器挂载在 这个 数据卷容器上,这样就相当于所有容器都挂载在这一数据卷上。(即使c3容器出问题了, c1和c2仍然可以和数据卷进行数据交换)
#1 创建数据卷
docker volume create 数据卷名称
#创建数据卷之后,默认会存放到目录:/var/lib/docker/volume/数据卷名称/_data目录下
#2 创建数据卷容器(name=c3 仅作演示)
docker run -it --name=c3 -v /var/lib/docker/volume/数据卷名称/_data目录下:/volume centos:7 bin/bash
#3 将其他容器挂载到该数据据容器上
docker run -it --name=c1 --volumes-from c3 centos:7
docker应用部署
总体步骤:
搜索镜像 (docker search xx) 或者在 dockerhub上查看镜像
拉取镜像 (docker pull xx)
查看镜像 (docker images xx)
启动镜像 (docker run -it -p 8080:8080 tomcat)
停止容器 (docker stop xx)
移除容器 (docker rmi -f xx)
mysql部署
- 容器内的网络服务和外部机器不能直接通信
- 外部机器和宿主机可以直接通信
- 宿主机和容器可以直接通信
- 当容器中的网络服务需要被外部机器访问时,可以将容器中提供服务的端口映射到宿主机的端口上。外部机器访问宿主机的该端口,从而间接访问容器的服务。
- 这种操作称为:端口映射
# 搜索mysql 镜像
docker search mysql
# 拉取mysql 镜像
docker pull mysql:5.6
# 在/root目录下创建mysql目录用于存储数据
mkdir /root/mysql
cd /root/mysql
# 使用mysql镜像创建容器c_mysql 以3307端口打开 并设置数据卷 并配置mysql的root密码为123456
docker run -id \
-p 3307:3306 \
--name=c_mysql\
-v/root/mysql/conf:/etc/mysql/conf.d\
-v $PWD/logs:/logs\
-v $PWD/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456
mysql:5.6参数说明:
-p 3307:3306:将容器的3306端口映射到宿主机的3307端口。也可以都为3306
$PWD 是当前目录 /root/mysql
-v $PWD/conf:/etc/mysql/conf.d:将主机当前目录下的conf/my.cnf 与容器的/etc/mysql/my.cnf 挂载# 进入该容器
docker exec -it c_mysql /bin/bash# 运行mysql 输入密码后进入mysql操作端
mysql -u -root -p123456
就和正常Linux系统下操作mysql一样了。
通过SQLyog访问宿主机IP和映射的端口,可以访问到容器中的Mysql服务。
tomcat
拉取tomcat 镜像
docker pull tomact运行该容器至8080端口
docker run -d -p 8080:8080 --name t1 tomcat
访问首页 看看有没有成功 发现出现404页面
- 可能没有映射端口或者没有关闭防火墙 (很小可能)
- 把webapps.dist 目录换成webapps (因为新版的tomcat换掉了访问的目录)
# 重新进入tomcat终端 以此来排查问题
docker exec -it t1 /bin/bash进入目录
cd webapps查看当前目录下文件 发现没有任何文件
ls -l切换到上层目录
cd ../删除目录 因为这个目录没有想要的文件
rm -r webapps将有内容的文件改名为 webapps 让tomcat找到对应的文件
mv webapps.dist webapps
再次访问 发现可以正常访问
制作镜像
当我们从docker镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。
- 将已经创建的容器中制作成镜像,并且提交这个镜像
- 使用 Dockerfile 指令来创建一个新的镜像
- 对于开发人员,可以为开发团队提供一个完全一致的开发环境
- 对于测试人员,可以直接拿开发时所构建的镜像测试。
- 对于运维人员,在部署时,可以实现快速部署、移值。
命令
# 将已经创建的容器转换成镜像
docker commit 容器id 镜像名称:版本号# 将镜像文件压缩 (用于传输给他人)
docker save -o 压缩文件名称 镜像名称:版本号# 将镜像压缩文件解压
docker load -i 压缩文件名称
dockerfile 制作镜像
dockerfile制作镜像实际上就是确定镜像每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、制作镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
Dockerfile是一个文本文件,其内包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
dockerfile 常用命令
FROM :指定基础镜像
基础镜像不存在会在Docker Hub上拉去(一般会是文件的第一个指令)
使用格式:
FROM<镜像>:[tag]
FROM <镜像>@digest[校验码]
当前主机没有此镜像时,会自动去官网HUB下载
如果不以任何镜像为基础,那么写法为:FROM scratch。
MAINTAINER:提供Dockerfile制作者提供本人信息 [逐渐废弃]
LABLE-替代MAINTANIER
使用格式:
MAINTANIER “作者信息”
MAINTANIER “guoweixin guoweixin@aliyun.com”
LABLE maintainer=“作者信息”
LABEL maintainer=“guoweixin@aliyun.com”
ENV:用于为docker容器设置环境变量,ENV设置的环境变量,可以使用 docker inspect命令来查看。
同时还可以使用docker run -env =来修改环境变量。
具体用法:
ENV JAVA_HOME /usr/local/jdk
ENV JRE HOME SJAVA HOME/jre
ENV CLASSPATH SJAVA_HOME/lib/:$JRE_HOME/lib/
ENV PATH SPATH:SJAVA_HOME/bin/
USER:用来切换运行属主身份的。Docker默认是使用root,但若不需要,建议切换使用者身份,毕竟root权限太大
了,使用上有安全的风险。
WORKDIR:WORKDIR用来切换工作目录的。
Docker默认的工作目录是/,只有RUN能执行cd命令切换目录,而且还只作用在当下的RUN,也就是说每一个RUN都是独立进行的。
如果想让其他指令在指定的目录下执行,就得靠WORKDIR。WORKDIR动作的目录改变是持久的,不用每个指令前都使用一次WORKDIR。
WORKDIR /usr/local/tomcat/
EXPOSE:暴露容器运行时的监听端口给外部,以实现与外部通信。想使得容器与主机的端口有映射关系,必须在容器启动的时候加上 -P参数。如果不设定,会随机映射端口。
具体写法:
EXPOSE 端口号
EXPOSE 端口号/协议
不加协议默认为tcp
例如
EXPOSE 80/tcp
EXPOSE 80/udp
RUN:RUN指令是用来执行命令行命令的。其格式有两种:
shell格式:RUN<命令>,就像直接在命令行中输入的命令一样。
exec格式:RUN[”可执行文件",“参数1”,“参数2”】,这更像是函数调用中的格式。
使用格式:
RUN
RUN [‘’‘’‘’‘’‘’]
注意:多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层,多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。
RUN书写时的换行符是\
CMD:功能为容器启动时要运行的命令
语法有三种写法:
- CMD [“executable”,“param1”,“param2”]
- CMD [“param1”,“param2”]
- CMD command param1 param2
第三种比较好理解了,就是shell执行方式和写法
第一种和第二种其实都是可执行文件加上参数的形式
注意:RUN是构件容器时就运行的命令以及提交运行结果
CMD是容器启动时执行的命令,在构建时并不运行。
ADD: 一个复制命令,把文件复制到镜像中。
语法如下:
- ADD …
- ADD [“”,… “”]
路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径
可以是一个本地文件或者是一个本地压缩文件,还可以是一个url
如果把写成一个url,那么ADD就类似于wget命令
尽量不要把写成一个文件夹,如果是一个文件夹了,会复制整个目录的内容,包括文件系统元数据
COPY:看这个名字就知道,又是一个复制命令。将宿主机的文件拷贝到容器中
语法如下:
- COPY …
- COPY [“”,… “”]
与ADD的区别
COPY的只能是本地文件,其他用法一致
ENTRYPOINT:功能是启动时的默认命令
语法如下:
- ENTRYPOINT [“executable”, “param1”, “param2”]
- ENTRYPOINT command param1 param2
第二种就是shell写法
第一种就是可执行文件加参数
与CMD比较说明:
- 相同点:
- 只能写一条,如果写了多条,那么只有最后一条生效
- 容器启动时才运行,运行时机相同
- 不同点:
- ENTRYPOINT不会被运行的command覆盖,而CMD则会被覆盖
- 如果我们在Dockerfile种同时写了ENTRYPOINT和CMD,并且CMD指令不是一个完整的可执行命令,那么CMD指定的内容将会作为ENTRYPOINT的参数
通过dockerfile制作镜像
docker build -f dockerfile文件路径 -t 镜像名称:版本号
docker compose
前面我们使用 Docker的时候,定义 Dockerfile文件,然后使用 docker build、docker run-d–name-p等命令操作容器。然而微服务架构的应用系统一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,那么效率之低,维护量之大可想而知
使用 Docker Compose可以轻松、高效的管理容器,它是一个用于定义和运行多容器 Docker的应用程序工具
Docker Compose 是Docker官方编排(Orchestration)项目之一,负责快速的部署分布式应用。
其代码目前在https://github.com/docker/compose上开源
Compose 定位是「定义和运行多个Docker容器的应用(Defining and running multi-container Dockerapplications)。
我们知道使用一个 Dockerfile模板文件,可以让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个Web项目,除了Web服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。Compose恰好满足了这样的需求。它允许用户通过一个单独的docker-compose.yml模板文件(YAML格式)来定义一组相关联的应用容器为一个项目(project)。
Compose中有两个重要的概念:
- 服务(service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
- 项目(project):由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml文件中定义。
Compose的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。
Compose项目由Python编写,实现上调用了Docker服务提供的API来对容器进行管理。因此,只要所操作的平台支持 Docker API,就可以在其上利用 Compose来进行编排管理。
安装
# 官方安装
#1 github官方网站 搜索Docker compose
https://github.com/docker/compose/releases/download/1.25.5/docker-compose-Linux-x86_64
#2将下载好的文件拖入Linux并剪切到/usr/local目录下
mv docker-compose-Linux-x86_64/usr/local
#3 修改名称(为后面方便调用)并修改其为可执行文件
mv docker-compose-Linux-x8664 docker-compose
chmod 777 docker-compose
mv docker-compose /usr/local/bin/
示例
用compose的方式管理一个Tomcat容器和MySQL
- 管理文件夹,创建相应的目录
mkdir -p /opt/docker_mysql_tomcat/ - 在如上目录中编写创建docker-compose.yml配置文件
编写 docker-compose.yml文件,这个是Compose使用的模板文件。
vergion:'3.1'
services:mysql: #服务的名称restart: always # 只要docker启动,容器会随着启动image: daocloud.io/library/mysq1:5.7.6 #指定镜像路径信息(默认官方镜像地址)container_name:mysq1-3306 #指定容器名称--nameports:- 3306:3306 #指定端口号映射environment:MYSQL_ROOT_PASSWORD:root #指定MYSQL ROOT用户的密码TZ: Asiz/Shanghai #指定时区volumes:- /opt/docker_mysql_tomcat/mysql/data:/var/lib/mysql #映射mysq1的数据目录到宿主机,保存数据- /opt/docker_mysql_tomcat/mysql/conf/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf#把mysq1的配置文件映射到容器的相应目录tomcat:restart: alwaysimage: daocloud.io/library/tomcat:8.5.15-jre8container_name:tomcat-8080ports:- 8080:8080environment:TZ: Asiz/Shanghaivolumes:- /opt/docker_mysql_tomcat/tomcat/webapps:/usr/local/tomcat/webapps- /opt/docker_mysql_tomcat/tomcat/logs:/usr/local/tomcat/logs
- 启动
# 执行该docker-compose.yml文件
# 只有当该文件的名称是docker-compose.yml的时候 且在当前文件路径下能运行
docker-compose up -d# 如果文件名是其他的 需要指定该yml文件的名称 且在当前文件路径下
docker-compose -f 文件名.后缀 up -d
docker 私有仓库(未完成)
docker swarm集群搭建(未完成)
参考目录
https://www.bilibili.com/video/BV1CJ411T7BK
https://www.bilibili.com/video/BV1ug411j71W
https://www.bilibili.com/video/BV1CJ411T7BK
https://www.bilibili.com/video/BV1CJ411T7BK
https://www.bilibili.com/video/BV1gr4y1U7CY
https://www.bilibili.com/video/BV1Zn4y1X7AZ
https://blog.csdn.net/weixin_67102357/article/details/129399578
https://blog.csdn.net/weixin_67102357/article/details/129399578
https://blog.csdn.net/qq_45297578/article/details/117926769
https://blog.csdn.net/qq_37132495/article/details/118739692