Docker简介
Docker是一个开源的应用容器引擎,让开发者打包应用及依赖到镜像中,然后进行发布。由于开发环境和运维环境的不同会产生大量环境问题,且在集群搭建时每换一台机器就要重新搭建一次环境,费时费力。linux容器技术就解决了这一个问题,Docker就是在它的基础上发展过来的,使用Docker就能直接将环境一起打包就省去了许多麻烦工作
Docker理念
Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的应用及其运行环境能够做到一次封装,到处运行
虚拟机与虚拟化容器
- 虚拟机就是带环境安装的一种解决方案,它可以在一种操作系统里面运行另一种操作系统;但是区别在于虚拟机模拟了一个完成的操作系统,资源占用多、启动慢
- Linux虚拟化容器不是模拟一个完成的操作系统,而是对进程进行隔离。它只需要软件工作所需要的库和资源配置,容器内的应用进程直接运行与宿主的内核,容器内没有自己的内核,也没有硬件虚拟,所以容器要比传统虚拟机更轻便。
Docker容器 | 虚拟机(VM) | |
---|---|---|
操作系统 | 与宿主机共享OS | 宿主机的OS上运行虚拟机OS |
存储大小 | 镜像小,便于存储与传输 | 镜像庞大(vmdk、vdi等) |
运行性能 | 几乎无额外性能损失 | 操作系统额外的CPU、内存消耗 |
移植性 | 轻便、灵活、适应与linux | 笨重,与虚拟化技术耦合度高 |
硬件亲和性 | 面向然间开发者 | 面向硬件运维者 |
Docker架构图
- 镜像(Image):镜像就是一个只读的模板,用来创建容器,一个镜像可以创建多个容器,类似OOP种的类
- 容器(Container):独立运行的一个或一组应用。容器是用镜像创建的运行实例,类似OOP中的对象。可以把容器看作一个简易版的linux环境
- 仓库(Repository):集中存放镜像文件的场所,仓库和仓库注册服务器(Registry)不同,仓库注册服务器上往往存放着多个仓库。仓库分为公开仓库(public)和私有仓库(Private)两种形式,最大的公开仓库是Docker Hub;国内的公开仓库包括阿里云、网易云等
Docker底层运行原理
- docker工作流程:Docker是一个Client-Server结构的系统,Docker守护进程(daemon)运行在主机上,然后通过Socket连接客户端访问,守护进程从客户端接收命令并管理运行在主机上的容器
- 为什么docker比虚拟机快:
1.docker不需要实现硬件资源虚拟化
2.docker利用的是宿主机的内核,不用加载操作系统内核
Docker安装(CentOS7)
Docker仅支持CentOS6.5以上的版本
- 卸载老版本docker
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
- 设置Docker源
yum install -y yum-utils
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
- 安装docker,默认安装最新版
yum install docker-ce docker-ce-cli containerd.io
安装指定版本使用指令:yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
- 启动docker
systemctl start docker
- 测试,这一步会从docker hub上拉取hello-world镜像,并生成容器运行
docker run hello-world
阿里云镜像加速配置
- 注册阿里云账户
- 登录阿里云镜像平台,点击镜像工具->加速器
- 配置镜像加速器
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://rgha0dsr.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
- 查看docker信息
docker info
,可以看到阿里云的镜像地址
Client:
Context: default
Debug Mode: false
Plugins:
app: Docker App (Docker Inc., v0.9.1-beta3)
buildx: Build with BuildKit (Docker Inc., v0.6.1-docker)
scan: Docker Scan (Docker Inc., v0.8.0)
Server:
Containers: 2
Running: 0
Paused: 0
Stopped: 2
Images: 1
Server Version: 20.10.8
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc io.containerd.runc.v2 io.containerd.runtime.v1.linux
Default Runtime: runc
Init Binary: docker-init
containerd version: e25210fe30a0a703442421b0f60afac609f950a3
runc version: v1.0.1-0-g4144b63
init version: de40ad0
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-1160.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 972.3MiB
Name: 192.168.206.128
ID: PXZ7:AKT2:XDSO:PZWA:7KZ5:P5YY:RTJ5:6ZZK:AHK4:D5GE:PU7Q:5KKJ
Docker Root Dir: /var/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Registry Mirrors:
https://rgha0dsr.mirror.aliyuncs.com/
Live Restore Enabled: false
Docker常用命令
帮助命令
docker version
:查看docker基本信息docker info
:查看docker详细信息docker --help
:查看docker命令帮助信息
镜像命令
docker images [OPTION]
:查看本地所有镜像
repository:镜像名称
tag:镜像标签,表示镜像的版本,统一仓库可以有多个TAG,操作镜像时在镜像名称后接:TAG
来指定标签,不写则默认是latest最新版
image id:镜像ID,镜像的唯一标识符
created:镜像创建的时间
size:镜像的大小
OPTION:
-a:列出本地所有镜像(包括中间映像层)
-q:只显示镜像ID
–digests:显示镜像的摘要信息
–no-trunc:显示完整的镜像信息
docker search [OPTION] 镜像名
:从docker hub上查找镜像
name:镜像名
description:镜像描述
stars:镜像点赞数
official:是否是官方版
automated:是否自动构建
OPTION:
–no-trunc:显示完整的镜像描述
-f stars=x:列出点赞数不小于x的镜像
–automated:只列出automated build类型的镜像
docker pull 镜像名称[:tag]
:从远程仓库拉取镜像到本地docker push 镜像名称[:tag]
:从本地仓库推送镜像到远程- 从本地仓库删除镜像:
docker rmi -f 镜像名称1[:tag] 镜像名称2[:tag]
:删除多个
docker rmi -f 镜像ID
:删除单个
docker rmi -f $(docker images -qa)
:删除全部,$()命令级联执行
容器命令
docker run [OPTIONS] image [COMMAND] [ARG...]
:新建并运行一个容器
运行起来之后这里的fee91e0125e3是容器的id
OPTION:
--name 容器新名称
:为容器指定一个名称
-d:后台运行容器,并返回容器id,即启动守护式容器
-i:以交互模式运行容器,通常与-t同时使用
-t:为容器重新分配一个伪终端,通常与-i同时使用
-p:指定端口映射,有以下四种格式ip:hostPort:containerPort、ip::containerPort、hostPort:containerPort、containerPort。hostPort为主机暴露在外部的端口,containerPort为容器的端口,外部访问主机暴露的端口,再有docker映射到容器端口
-P:随机端口映射,随机分配一个主机暴露的端口
docker ps [OPTIONS]
:列出当前所有正在运行的容器
OPTION:
-a:列出当前所有正在运行的容器+历史上运行过的容器
-l:显示最近创建的容器
-n:显示最近n个创建的容器
-q:静默模式,只显示容器编号
–no-trunc:不截断输出
exit
:容器停止退出- CTRL+P+Q:容器不停止退出
docker start 容器ID或容器名
:启动已经存在的容器docker restart 容器ID或容器名
:重启容器docker stop 容器ID或容器名
:停止容器docker kill 容器ID或容器名
:强制停止容器,直接杀死容器进程docker rm 容器ID
:删除已停止的容器- 一次删除多个容器:
docker rm -f $(docker ps -a -q)
、docker ps -a -q | xargs docker rm
(-f表示强制删除force) - 查看容器日志:
docker logs -f -t --tail 容器ID
,-t是加入时间戳信息、-f跟随最新的日志打印、–tail+数字显示最后多少条 - 查看容器内的进程:
docker top 容器ID
- 查看容器内部的细节:
docker inspect 容器ID
- 重新进入运行中的容器并以命令行进行交互:
docker exec -it 容器ID bashShell
:在容器中打开新的终端,并且可以启动新的进程,bashShell是可以额外执行的shell脚本
docker attach 容器ID
:直接进入容器启动命令的终端,不会启动新的进程 - 容器内的文件拷贝到主机上:
docker cp 容器ID:容器内的路径 目的主机路径
容器的守护模式
使用docker run -d centos
可以后台启动一个容器,即守护式启动;但是使用docker ps -a
查看,会发现容器已经退出,这是因为Docker容器后台运行,就必须有一个前台进程;容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的;产生这个问题的根源是docker机制,如果容器后台启动而没有前台进程,这样的容器会立即自杀因为他觉得没事可做了
Docker镜像
概述
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码、运行时、库、环境变量、配置文件
UnionFS联合文件系统
Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同的目录挂载到同一个虚拟文件系统下。Union文件系统时Docker镜像的基础,镜像可以通过分层了来集成,基于基础镜像,可以制作各种具体应用的镜像
特性
一次同时加载多个文件系统,但从外面看起来,只看到一个文件系统,联合加载会把各层文件系统叠加卡里,这样最终的文件系统会包含所有底层文件和目录
Docker镜像分层
比如tomcat一定会有jdk环境,不然无法运行,jdk就在tomcat的下面,而最上面一层就是tomcat,我们从外面看起来就只是tomcat,但是能发现tomcat镜像比tomcat要大不少
镜像的特点
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载大镜像顶部,这一层通常被称作容器层,容器层之下都是镜像层
Docker镜像commit操作
docker commit -m="提交的描述信息" -a=作者 容器ID 要创建的目标镜像名:[标签名]
:提交容器副本使之成为一个新的镜像
打包tomcat镜像示例(Docker运行tomcat出现404错误的解决)
docker run -d -p 8080:8080 tomcat
:新建并运行tomcat容器
这里发现访问时出现404错误,通过docker exec -it 403e044660f2 /bin/bash
,ls
发现webapps在这里名为webapps.dist,使用mv webapps.dist/ webapps
将目录改名即可docker commit -m="解决webapps目录名造成的404错误" -a="laowa" 403e044660f2 my_tomcat:1.0
:提交容器副本创建镜像- 通过新的镜像创建容器,检查是否还有404问题:
docker run -d -p 8080:8080 my_tomcat:1.0
Docker容器数据卷
概述
Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据作为镜像的一部分保存下来,那么当容器删除后,数据自然就没有了。为了能保存容器中的数据,做容器中数据的持久化,我们使用容器数据卷。
容器数据卷的作用
- 容器的持久化
- 容器间继承+共享数据
容器内添加数据卷
直接命令添加
docker run -it -v /宿主机绝对路径目录:/容器内目录 image
:创建容器时将指定宿主机的目录与容器内指定目录绑定,两个目录的数据将共享- 查看数据卷是否挂载成功:通常在宿主机和容器中都创建一个新的目录,通过查看是否有新目录的产生就可以知道是否挂载成功
- 数据共享:宿主机或容器对绑定的目录下的内容进行操作时,双方的内容都会一致
- 容器退出后,数据共享会停止,但是容器一旦重新启动会立马同步数据
- 添加数据卷时加上权限:
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
,添加权限ro表示readonly,容器将无法对该目录进行写操作
DokcerFile添加
- 根目录下新建mydocker目录并进入
- 在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷
VOLUEM["容器内目录1","容器内目录2"...]
- dcoekrFile内容示例
FROM centos
VOLUME ["/dataVolumeContainer","/dataVolumeContainer2"]
CMD /bin/bash
docker build -f dockerfile文件路径 -t 镜像名称
,使用Dockerfile构建镜像- 默认宿主机的目录为/var/lib/docker/volumes/容器id/_data
数据卷容器
命名的容器挂载数据卷,其他容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器,类似redis的主从复制,数据卷容器为master,其他容器为salve
绑定数据卷容器
- 启动挂载了数据卷的父容器
- 创建容器时绑定父容器的数据卷:
docker run -it --name 子容器的名字 --volumes-from 父容器的名字 子容器的镜像
- 子容器和父容器都可以对数据卷的内容进行修改,内容都会共享
- 容器多重继承后,数据卷的生命周期一直持续到没有容器使用它位置,比如doc2继承自数据卷容器doc1,doc3继承doc2,当doc2删除后,doc3依然会继承自doc1
Dockerfile
概述
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本
Dockerfile构建操作步骤
- 编写Dockerfile文件
- docker build构建Docker镜像
- docker run创建容器
Dockerfile构建过程
Dockerfile基础
- 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
- 指令按照从上到下,顺序执行
- #表示注释
- 每条指令都会创建一个新的镜像层,并对镜像进行提交(前面所说的镜像分层就是通过依赖Dockerfile定义的规则进行)
Docker执行file的大概流程
- docker从基础镜像运行一个容器
- 执行一条指令并对容器做出修改
- 执行类似docker commit的操作提交一个新的镜像层
- docker再基于刚提交的镜像运行下一个容器
- 执行dockerfile中的下一条指令直到所有指令都执行完成
Dokcerfile、Docker镜像、Docker容器综述
- Dockerfile是软件的原材料
- Docker镜像是软件的交付品
- Docker容器是软件的运行态
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器用来部署于运维,三者合力充当Docker体系的基石
Dockerfile保留字指令
- FROM:导入基础镜像,即指定当前这个新镜像是要依赖于哪个镜像
- MAINTAINER:镜像维护者的姓名和邮箱地址
- RUN:容器构建时需要额外执行的命令
- EXPOSE:当前镜像创建的容器的端口
- WORKDIR:创建容器后,终端默认登录的工作目录,一个落脚点
- ENV:用来构建镜像过程中给生成环境变量,这个环境变量可以再后续的指令如RUN中使用,就如同在命令前面指定了环境变量前缀一样
- ADD:将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
- COPY:类似ADD,拷贝文件和目录到镜像中;但仅有拷贝功能。
COPY src dest
、COPY ["src","dest"]
- VOLUME:挂载容器数据卷,用于数据保存和持久化工作
- CMD:指定一个容器启动时要运行的命令,Dockerfile中可以有多个CMD命令,但只有最后一个生效,CMD会被docker run之后的参数替换
- ENTRYPOINT:指定一个容器启动时要运行的命令,Dockerfile中可以有多个ENTRYPOINT命令,但只有最后一个生效,ENTRYPOINT不会被docker run之后的参数替换
- ONBUILD:当构建一个被继承的Dockerfile时运行命令,父镜像被子继承后父镜像的onbuild被触发
Dockerfile实例——自定义tomcat镜像
- 创建目录/mydocker/tomcat9/usr/local
- 将tomcat和jdk压缩包拷贝到tomcat9目录下
- 在tomcat9目录下编写Dockerfile文件
FROM centos
MAINTAINER laowa<email>
# 将java于tomcat添加到容器中
ADD jdk-8u251-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.8.tar.gz /usr/local/
# 安装vim编辑器
RUN yum -y install vim
# 设置工作访问的落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 配置java和tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_251
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
# 容器运行时监听的端口
EXPOST 8080
# 启动时运行tomcat
ENTRYPOINT ["/usr/local/apache-tomcat-9.0.8/bin/startup.sh"]
CMD ["usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"]
- 构建Dockerfile:
docker build -t mytomcat9
Dockers常用安装
Docker安装tomcat
-
docker search -f stars=100 tomcat
-
docker pull tomcat
-
docker images
-
docker run -d -p 8080:8080 --name tomcat tomcat
docker安装mysql
-
docker search -f stars=100 mysql
-
docker pull mysql
-
docker images
-
docker run -d -p 8080:8080 --name mysql mysql
本地镜像发布到阿里云
- 登录阿里云镜像管理平台
- 创建仓库
- 登录到阿里云平台:
docker login --username=账号 registry.cn-hangzhou.aliyuncs.com
- 推送镜像:
docker tag ImageId registry.cn-hangzhou.aliyuncs.com/laowa/my_tomcat:[镜像版本号]
,docker push registry.cn-hangzhou.aliyuncs.com/laowa/my_tomcat:[镜像版本号]
中间的连接为镜像地址