一、Docker简介
Docker是基于Go语言实现的云开源项目
Docker的主要目标是“Build, Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次封装,到处运行”,解决了应用打包和发布这一困扰运维人员多年的技术难题
Docker的优势:
- 轻量、秒级的快速启动速度
- 简单、易用、活跃的社区
- 标准统一的打包/部署/运行方案
- 镜像支持增量分发,易于部署
- 易于构建,良好的REST API,也很适合自动化测试和持续集成
- 性能,尤其是内存和IO的开销
Docker三要素:镜像、容器、仓库
容器是用镜像创建的运行实例,它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序
仓库是集中存放镜像文件的场所
Docker架构图:
Docker中文手册:https://www.docker.org.cn/
Docker中文文档:http://www.dockerinfo.net/document
二、Docker常用命令
1、帮助命令
docker version:查看docker版本信息
dokcer info:查看docker详细信息
decker –help:查看docker帮助信息
2、镜像命令
2.1、docker images:列出本地主机上的镜像
REPOSITORY:表示镜像的仓库源
TAG:镜像的标签
IMAGE ID:镜像ID
CREATED:镜像创建时间
SIZE:镜像大小
同一仓库源可以有多个TAG,代表这个仓库源的不同版本,使用REPOSITORY:TAG来定义不同的镜像,如果不指定,默认使用最新的
options说明:
- a:列出本地所有的镜像(含中间映像层)
- q:只显示镜像ID
- –digests:显示镜像的摘要信息
- –no-trunc:显示完整的摘要信息
2.2、docker search 某个xxx镜像名字:查找镜像
options说明:
- –no-trunc:显示完整的镜像描述
- –limit:列出收藏数不小于指定值的镜像
- –automated:只列出automated build类型的镜像
2.3、docker pull 某个xxx镜像名字:拉取镜像
2.4、docker rmi 某个镜像名字ID:删除镜像
删除单个
docker rmi -f 镜像ID/镜像名称
删除多个
docker rmi -f 镜像名1:TAG 镜像名2:TAG
删除全部
docker rmi -f ${docker images -qa}
3、容器命令
3.1、新建并启动容器
docker run [OPTIONS] IMAGE [COMMAND][ARG]
options说明:
–name 容器新名字:为容器指定一个名称
-d:后台运行容器,并返回容器ID,也即启动守护式容器
-i:以交互模式运行容器,通常与-t同时使用
-t:为容器重新分配一个伪输入终端,通常与-i同时使用
-P:随机端口映射
-p:指定端口映射,有以下四种格式
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
3.2、列出当前所有正在运行的容器
docker ps
options说明:
- -a:列出当前所有正在运行的容器+历史上运行过的
- -l:显示最近创建的容器
- -n:显示最近n个创建的容器
- -q:静默模式,只显示容器编号
- –no-trunc:不截断输出
3.3、退出容器
容器停止退出
exit
容器不停止退出
ctrl+P+Q
3.4、启动容器
docker start 容器ID或者容器名
3.5、重启容器
docker restart 容器ID或者容器名
3.6、停止容器
docker stop 容器ID或者容器名
3.7、强制停止容器
docker kill 容器ID或者容器名
3.8、删除已停止的容器
删除单个容器
docker rm 容器ID
删除多个容器
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
3.9、启动守护式容器
docker run -d 容器名
3.10、查看容器日志
docker logs -f -t --tail 容器ID
options说明:
- -t:加入时间戳
- -f:跟随最新的日志打印
- –tail:数字显示最后多少条
3.11、查看容器内运行的进程
docker top 容器ID
3.12、查看容器内部细节
docker inspect 容器ID
3.13、进入正在运行的容器并以命令行交互
直接进入容器启动命令的终端,不会启动新的进程
docker attach 容器ID
是在容器中打开新的终端,并且可以启动新的进程
docker exec -it 容器ID /bin/bash
3.14、从容器内拷贝文件到主机上
docker cp 容器ID:容器内路径 目的主机路径
3.15、查看Docker服务状态
systemctl status docker
三、Docker镜像
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
1、docker镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
UnionFS(联合文件系统):是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后,整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs(root file system),在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu、CentOS等等
安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M?
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。
为什么Docker镜像要采用这种分层结构?
共享资源。比如:有多个镜像都从相同的base镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,同时内存也只需加载一份base镜像,就可以为所有容器服务了,而且镜像的每一层都可以共享。
2、docker镜像特点
docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称作“容器层”,容器层之下的都叫镜像层
3、commit操作
提交容器副本使之成为一个新的镜像
docker commit -m=提交的描述信息 -a=作者 容器ID 要创建的目标镜像名:标签名
四、Docker容器数据卷
1、数据卷概念
Docker的理念:将运用与运行的环境打包形成容器运行,运行可以伴随着容器,但是我们对数据的要求希望是持久化的,容器之间希望有可能共享数据
Docker容器产生的数据,如果不通过docker commit生成一个新的镜像,使得数据作为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了,为了能保存数据,在docker中我们使用卷。卷可以保持容器的持久化、容器间继承和共享数据
卷(volume)就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能过绕过联合文件系统提供一些用于持续存储或共享数据的特性
卷的设计目的就是数据的持久化,完全独立于容器的生命周期,因此docker不会在容器删除时删除其挂载的数据卷
2、数据卷特点
- 数据卷可在容器之间共享或重用数据
- 卷中的更改可以直接生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
3、容器内添加数据卷
3.1、直接命令添加
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
查看数据卷是否挂载成功
容器和宿主机之间数据可以共享
容器停止退出后,主机修改数据后,重新启动容器,数据自动同步
3.2、用Dockerfile文件添加
4、volumes-from
volumes-from:容器间信息传递
五、Dockerfile解析
1、docker执行Dockerfile的大致流程
- docker从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似docker commit的操作提交一个新的镜像层
- docker再基于刚提交的镜像运行一个新容器
- 执行dockerfile中的下一条指令直到所有指令都执行完成
2、Dockerfile保留字指令
FROM:基础镜像
MAINTAINER:镜像维护者的姓名和邮箱地址(例:xxxxxx@xxx.xxx)
RUN:容器构建时需要运行的命令
WORKDIR:创建容器后,终端默认登陆进来的工作目录
ENV:构建镜像过程中设置环境变量
ADD:拷贝文件和目录到镜像中+解压压缩包到镜像中
COPY:拷贝文件和目录到镜像中
VOLUME:容器数据卷,用于数据保存和持久化工作
CMD:指定容器启动时执行的命令,可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
shell格式:CMD <命令>
exec格式:CMD ["可执行文件", "参数1", "参数2"]
参数列表格式:CMD [“参数1”, “参数2”]
ENTRPOINT:指定容器启动时执行的命令
ONBUILD:当构建一个被继承的Docekrfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发
六、Docker打包Flask程序
1、拉取MySQL5.7镜像
sudo docker pull mysql:5.7
2、启动MySQL5.7容器
sudo docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7
-d:开启Daemon守护进程
-p:端口映射,格式为主机(宿主)端口:容器端口
-e:设置环境变量,MYSQL_ROOT_PASSWORD=123456 设置MySQL的密码为123456;
–name:为容器指定一个名称;
3、Navicat测试连接MySQL数据库
4、拉取OpenLdap镜像
docker pull osixia/openldap
5、启动OpenLdap容器
docker run -p 389:389 --name openldap --restart=always --env LDAP_ORGANISATION="admin" --env LDAP_DOMAIN="example.com" --env LDAP_ADMIN_PASSWORD="123456" --detach osixia/openldap
- 389端口:默认ldap服务是使用389端口
- LDAP_ORGANISATION 表示ldap的机构组织
- LDAP_DOMAIN 配置LDAP域
- LDAP_ADMIN_PASSWORD 配置LDAP管理员(admin)的密码
- 默认用登陆用户名admin
6、创建一个目录Docker_exercise
mkdir Docker_exercise
7、编写flask程序app.py,放在Docker_exercise里
from flask import Flask
import pymysql
from ldap3 import Server
from ldap3 import Connection
app = Flask(__name__)
@app.route('/')
def index():
print('index')
return 'index'
@app.route('/connect_mysql')
def connect_mysql():
conn = pymysql.connect(host='192.168.0.45',user='root',password='123456',port=8888)
print(conn)
if conn:
return 'connect_mysql_success'
else:
return 'connect_mysql_fail'
@app.route('/connect_ldap')
def connect_ldap():
LDAP_SERVER_HOST = '192.168.0.45'
LDAP_SERVER_PORT = 389
ADMIN_DN = 'cn=admin,dc=example,dc=com'
ADMIN_PWD = '123456'
# 查找user_dn
server = Server(LDAP_SERVER_HOST, LDAP_SERVER_PORT)
conn = Connection(server, ADMIN_DN, ADMIN_PWD)
res = conn.bind()
if res:
return 'connect_ldap_success'
else:
return 'connect_ldap_fail'
if __name__ == '__main__':
app.run(debug=False,port=5000,host='0.0.0.0')
8、生成requirements.txt文件,放在Docker_exercise里
pip freeze > requirements.txt
9、编写Dockerfile文件,放在Docker_exercise里
vim Dockerfile
内容如下:
# 指定所创建镜像的基础镜像
FROM python:3.7.5
WORKDIR /home/wmx/flask_demo
ADD . /home/wmx/flask_demo
# 安装依赖
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
# 声明镜像内服务监听的端口
EXPOSE 5000
CMD ["python", "app.py"]
10、在Docker_exercise目录中,创建名称为flask_demo的镜像,. 表示dockerfile文件所在目录
sudo docker build -t flask_dmeo .
11、启动镜像
sudo docker run -d -p 5000:5000 --name flask_demo flask_demo
参考链接:
- https://blog.csdn.net/weiwei200/article/details/88537111
- https://blog.csdn.net/sinat_34927324/article/details/80859616
七、安装Docker-compose
# 下载docker compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# github下载慢,尝试daocloud下载
sudo curl -L "https://get.daocloud.io/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 添加可执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 将文件copy到 /usr/bin/目录下
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# 查看版本
docker-compose --version
八、Docker-compose 常用命令
1、docker-compose命令格式
docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
选项如下:
-f,–file FILE 指定Compose模板文件,默认为docker-compose.yml,可以多次指定。
-p,–project-name NAME指定项目名称,默认将使用所在目录名称作为项目名。
-x-network-driver 使用Docker的可拔插网络后端特性(需要Docker 1.9+版本)
-x-network-driver DRIVER指定网络后端的驱动,默认为bridge(需要Docker 1.9+版本)
-verbose 出更多调试信息
-v,–version 打印版本并退出
2、docker-compose up
docker-compose up [options] [--scale SERVICE=NUM...] [SERVICE...]
选项包括:
-d 在后台运行服务容器
–no-color 不使用颜色来区分不同的服务的控制输出
–no-deps 不启动服务所链接的容器
–force-recreate 强制重新创建容器,不能与–no-recreate同时使用
–no-recreate 如果容器已经存在,则不重新创建,不能与–force-recreate同时使用
–no-build 不自动构建缺失的服务镜像
–build 在启动容器前构建服务镜像
–abort-on-container-exit 停止所有容器,如果任何一个容器被停止,不能与-d同时使用
-t, –timeout TIMEOUT 停止容器时候的超时(默认为10秒)
–remove-orphans 删除服务中没有在compose文件中定义的容器
–scale SERVICE=NUM 设置服务运行容器的个数,将覆盖在compose中通过scale指定的参数
示例:
#启动所有服务
docker-compose up
#在后台所有启动服务
docker-compose up -d
#-f 指定使用的Compose模板文件,默认为docker-compose.yml,可以多次指定。
docker-compose -f docker-compose.yml up -d
3、docker-compose ps
docker-compose ps [options] [SERVICE...]
示例:
#列出项目中目前的所有容器
docker-compose ps
4、docker-compose stop
docker-compose stop [options] [SERVICE...]
选项包括:
-t, –timeout TIMEOUT 停止容器时候的超时(默认为10秒)
示例
#停止正在运行的容器,可以通过docker-compose start 再次启动
docker-compose stop
5、docker-compose -h
#查看帮助
docker-compose -h
6、docker-compose down
#停止和删除容器、网络、卷、镜像。
docker-compose down [options]
选项包括:
–rmi type 删除镜像,类型必须是:all,删除compose文件中定义的所有镜像;local,删除镜像名为空的镜像
-v, –volumes 删除已经在compose文件中定义的和匿名的附在容器上的数据卷
–remove-orphans 删除服务中没有在compose中定义的容器
示例:
#停用移除所有容器以及网络相关
docker-compose down
7、docker-compose logs
#查看服务容器的输出。默认情况下,docker-compose将对不同的服务输出使用不同的颜色来区分。可以通过–no-color来关闭颜色
docker-compose logs [options] [SERVICE...]
8、docker-compose build
#构建(重新构建)项目中的服务容器
docker-compose build [options] [--build-arg key=val...] [SERVICE...]
选项包括:
–compress 通过gzip压缩构建上下环境
–force-rm 删除构建过程中的临时容器
–no-cache 构建镜像过程中不使用缓存
–pull 始终尝试通过拉取操作来获取更新版本的镜像
-m, –memory MEM 为构建的容器设置内存大小
–build-arg key=val 为服务设置build-time变量
服务容器一旦构建后,将会带上一个标记名。可以随时在项目目录下运行docker-compose build来重新构建服务
9、docker-compose pull
#拉取服务依赖的镜像
docker-compose pull [options] [SERVICE...]
选项包括:
–ignore-pull-failures 忽略拉取镜像过程中的错误
–parallel 多个镜像同时拉取
–quiet 拉取镜像过程中不打印进度信息
10、docker-compose restart
#重启项目中的服务
docker-compose restart [options] [SERVICE...]
选项包括:
-t, –timeout TIMEOUT 指定重启前停止容器的超时(默认为10秒)
11、docker-compose rm
#删除所有(停止状态的)服务容器,推荐先执行docker-compose stop命令来停止容器
docker-compose rm [options] [SERVICE...]
选项包括:
–f, –force,强制直接删除,包括非停止状态的容器
-v,删除容器所挂载的数据卷
12、docker-compose start
#启动已经存在的服务容器
docker-compose start
13、docker-compose run
#在指定服务上执行一个命令
docker-compose run [options] [-v VOLUME...] [-p PORT...] [-e KEY=VAL...] SERVICE [COMMAND] [ARGS...]
示例
#在指定容器上执行一个ping命令
docker-compose run ubuntu ping www.baidu.com
14、docker-compose scale
#设置指定服务运行的容器个数,通过service=num的参数来设置数量
docker-compose scale web=3 db=2
15、docker-compose pause
#暂停一个服务容器
docker-compose pause [SERVICE...]
16、docker-compose kill
#通过发送SIGKILL信号来强制停止服务容器
docker-compose kill [options] [SERVICE...]
示例
#支持通过-s参数来指定发送的信号,例如通过如下指令发送SIGINT信号:
docker-compose kill -s SIGINT
17、dokcer-compose config
#验证并查看compose文件配置
docker-compose config [options]
选项包括:
–resolve-image-digests 将镜像标签标记为摘要
-q, –quiet 只验证配置,不输出。 当配置正确时,不输出任何内容,当文件配置错误,输出错误信息
–services 打印服务名,一行一个
–volumes 打印数据卷名,一行一个
18、docker-compose create
#为服务创建容器
docker-compose create [options] [SERVICE...]
选项包括:
–force-recreate: 重新创建容器,即使配置和镜像没有改变,不兼容–no-recreate参数
–no-recreate: 如果容器已经存在,不需要重新创建,不兼容–force-recreate参数
–no-build: 不创建镜像,即使缺失
–build: 创建容器前,生成镜像
19、docker-compose exec
docker-compose exec [options] SERVICE COMMAND [ARGS...]
选项包括:
-d 分离模式,后台运行命令。
–privileged 获取特权。
–user USER 指定运行的用户。
-T 禁用分配TTY,默认docker-compose exec分配TTY。
–index=index 当一个服务拥有多个容器时,可通过该参数登陆到该服务下的任何服务,例如:docker-compose exec –index=1 web /bin/bash ,web服务中包含多个容器
20、docker-compose port
#显示某个容器端口所映射的公共端口
docker-compose port [options] SERVICE PRIVATE_PORT
选项包括:
–protocol=proto 指定端口协议,TCP(默认值)或者UDP
–index=index 如果同意服务存在多个容器,指定命令对象容器的序号(默认为1)
21、docker-compose push
#推送服务依的镜像
docker-compose push [options] [SERVICE...]
选项包括:
–ignore-push-failures 忽略推送镜像过程中的错误
22、docker-compose stop
#显示各个容器运行的进程情况
docker-compose stop [options] [SERVICE...]
23、docker-compose unpause
#恢复处于暂停状态中的服务
docker-compose unpause [SERVICE...]
24、docker-compose version
#打印版本信息
docker-compose version
九、Docker-Compose部署Flask程序(本机访问)
1、创建Docker-compose练习目录
mkdir docker-compose_exercise
2、将上文的app.py
、requirements.txt
、Dockerfile
放在docker_compose_exercise
中
3、在docker_compose_exercise
中创建docker-compose.yml
内容如下:
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
mysql:
image: "mysql:5.7"
ports:
- "8888:3306"
environment:
MYSQL_ROOT_PASSWORD: "123456"
openldap:
image: "osixia/openldap"
ports:
- "389:389"
environment:
LDAP_ORGANISATION: "admin"
LDAP_DOMAIN: "example.com"
LDAP_ADMIN_PASSWORD: "123456"
4、在docker-compose_exercise
中启动
sudo docker-compose up
十、上传镜像到DockerHub
1、在官网上注册账号
2、登录DockerHub账户
#登陆,根据提示输入用户名与密码
sudo docker login
3、查看本地镜像
将镜像的名称修改的更加规范
#docker tag 镜像ID 用户名称/镜像源名:新的标签名(tag)
docker tag flask_demo xxx/flask_demo:2.0
4、上传镜像
sudo docker push xxx/flask_demo:2.0
5、在docker-hub中可以查看我们上传的镜像
6、拉取上传的镜像
sudo docker pull xxx/flask_demo:2.0
7、可以修改之前的docker-compose.yml,引用上传的docker-hub镜像
内容如下:
version: '3'
services:
flask:
image: "xxx/flask_demo:2.0"
container_name: "flask_demo2.0"
ports:
- "5000:5000"
mysql:
image: "mysql:5.7"
container_name: "mysql5.7"
ports:
- "8888:3306"
environment:
MYSQL_ROOT_PASSWORD: "123456"
openldap:
image: "osixia/openldap"
ports:
- "389:389"
environment:
LDAP_ORGANISATION: "admin"
LDAP_DOMAIN: "example.com"
LDAP_ADMIN_PASSWORD: "123456"
注意:container_name是设置启动后容器的名称,这里的名称不要与存在的容器重名
8、重新启动程序
sudo docker-compose up -d
默认情况下,直接使用docker-compose up -d
命令启动即可。此时,docker-compose工具会在当前目录查找docker-compose.yml文件,并以目录名称作为工程名称。如果需要更改,则使用-f
来指定docker-compose文件,-p
指定工程名称。
十一、上传镜像到阿里云
1、在官网上注册账号
官网:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
2、创建自己的命名空间,设置访问凭证
3、登陆阿里云
sudo docker login -u userName [SERVER](登陆的服务器地址)
4、将镜像的名称修改规范(xxx为你创建的命名空间的名称)
sudo docker tag flask_demo registry.cn-hangzhou.aliyuncs.com/xxx/flask_demo
5、上传镜像
sudo docker push registry.cn-hangzhou.aliyuncs.com/xxx/flask_demo
上传到阿里云时需要加地址前缀registry.cn-hangzhou.aliyuncs.com
,docker-hub 默认前缀是docker.io
参考链接
- 尚硅谷周阳-Docker核心技术,百度云链接:https://pan.baidu.com/s/1NmBO3Ot5TbjhvETL7tWMkA
提取码:1007