Docker 初识 1.0
一、初始 Docker
1. Docker 概念
- Docker 是一个开源的应用容器引擎
- 诞生于2013年初,基于
Go
语言实现,dotCloud公司出品(后改名Docker Inc) - Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布
到任何流行的Linux
机器上. - 容器是完全使用沙箱机制,相互隔离
- 容器性能开销极低
- Docker 从 17.03版本之后分为CE(Community Edition:社区版)和EE(Enterprise Edition:企业版)
小结:Docker 是一种容器技术,主要用于解决软件跨环境迁移部署问题
2. 安装 Docker
说明:Docker可以运行在MAC、Windows、CentOS、UBUNTU等操作系统上,以下学习全部基于CentOS7安装Docker.
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
3. 架构
说明:学习Docker架构能让我们知道Docker有哪些部分组成也就知道了我们应该怎样操作Docker
说明:上图共分为三个部分,客户端(Clients)、核心部分(Hosts),仓库(Registries)
核心部分又包括(镜像、容器)
- 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
- 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和对象的关系一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
- 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
4. 配置Docker镜像加速器
说明:默认情况下,都是从docker hub(https://hub.docker.com/) 上下载Docker镜像,但是太慢,所以一般都会配置国内的镜像加速器:USTC:中科大镜像加速器(https://docker.mirrors.ustc.edu.cn) 、阿里云、网易云、腾讯云
配置不同的加速器可能用到的方法也不尽相同,这里我们以阿里云加速器为例:
- 登录阿里云官网(https://www.aliyun.com/)
- 点击-控制台
- 搜索“镜像”
- 点击搜索到的“容器镜像服务”
- 点击“镜像加速器”
- 根据操作文档进行操作,将命令粘贴至命令行运行即可
- 查看是否配置成功
命令:cat /etc/docker/daemon.json
二、Docker 命令
说明:如下图,主要介绍三部分命令;第一部分介绍如何操作Hosts部分中Docker服务(daemon)即后台守护进程,第二部分介绍如何操作镜像(image),第三部分介绍如何操作容器(container)
1. Docker 服务相关命令
- 启动Docker服务
systemctl start docker
- 停止Docker服务
systemctl stop docker
- 重启Docker服务
systemctl restart docker
- 查看Docker服务状态
systemctl status docker
- 设置开机启动Docker服务
systemctl enable docker
2. Docker 镜像相关命令
- 查看镜像:查看本地所有的镜像
# 查看所有镜像 docker images # 查看所有镜像的id docker images -q
- 搜索镜像:从Docker Hub官网中查找需要的镜像
docker search 镜像名称
- 拉取镜像:从Docker仓库下载镜像到本地,镜像名称格式为 名称:版本号,如果不指定版本号则默认为最新版本。如果不知道镜像版本,可以去Docker hub搜索对应的镜像查看。
docker pull 镜像名称
- 删除镜像:删除本地镜像
# 根据id删除指定本地镜像 docker rmi 镜像id # 删除所有本地镜像 docker rmi `docker images -q`
3. 容器相关命令
说明:前面我们说过镜像与容器的关系;容器是通过运行镜像文件来创建的,容器是镜像运行时的实体。
- 查看容器
# 查看正在运行的容器 docker ps # 查看所有容器 docker ps -a
- 创建并启动容器
docker run -参数 --name=容器名称 镜像名称:镜像版本 进入容器的初始化指令 # 例1:创建完成后自动进入容器,并且退出容器后容器自动关闭 docker run -it --name=c1 centos:7 /bin/bash # 例2:创建完成后不会立即进入容器,需要通过键入命令的方式进入容器,并且退出容器后容器不会自动关闭,它会继续在后台运行 docker run -id --name=c2 centos:7 # 参数说明: # -i:保持容器运行。通常与 -t 同时使用。加入it这两个参数后,容器创建后自动进入容器中,退出容器后,容器自动关闭。 # -t:为容器重新分配一个伪输入终端,通常与-i同时使用。 # -d:以守护(后台)模式运行容器。创建一个容器在后台运行,需要使用docker exec进入容器。退出后,容器不会关闭。 # -it:创建的容器一般称为交互式容器,-id创建的容器一般称为守护式容器。 # --name:为创建的容器命名。 # 如若不写镜像版本号则默认为最新版本
- 进入容器
docker exec 参数 容器名称 初始化命令 例:docker exec -it c2 /bin/bash
- 退出容器
exit;
- 停止容器
docker stop 容器名称或者容器ID
- 启动容器
docker start 容器名称或者容器ID
- 删除容器
# 如果容器是运行状态则删除失败,需要先停止容器运行才能删除 docker rm 容器名称或者容器ID
- 查看容器信息
docker inspect 容器名称或者容器ID
三、Docker 容器的数据卷
1. 数据卷概念及作用
思考:
- Docker 容器删除后,在容器中产生的数据还在吗?
- Docker 容器和外部机器可以直接交换文件吗?
- 容器之间如何进行数据交互
数据卷:
- 数据卷是宿主机中的一个目录或文件
- 当容器目录和数据卷目录绑定后,双方不管谁发生变动都会立即同步至另一方
- 一个数据卷可以绑定多个容器
- 一个容器也可以绑定多个数据卷
数据卷作用:
- 容器数据持久化
- 外部机器和容器间接通信
- 容器之间数据交换
2. 配置数据卷
- 创建启动容器时,使用
-v
参数设置数据卷docker run -v 宿主机目录(文件):容器内目录(文件) //例1:绑定一个数据卷 docker run -it --name=c1 -v /root/data:/root/data_container centos:7 /bin/bash //例2:绑定多个数据卷 docker run -it --name=c2 -v /root/data2:/root/data_container2 -v /root/data3:/root/data_container3 centos:7 /bin
注意:
1.目录(文件)必须是绝对路径;
2.如果目录不存在,会自动创建;
3.可以绑定多个数据卷初学时可以自己在虚拟机内实践一下,将虚拟机作为宿主机,在宿主机内创建多个容器并绑定数据卷,看数据能否交换与持久化
3. 数据卷容器
描述:如上图,容器C1、C2、C3本质并没有不同,只是C3与宿主机中的数据卷绑定,C1、C2与C3绑定,这样一来,C1、C2相当于与数据卷绑定。
//1.首先创建C3容器
docker run -it --name=c3 -v /root/data:/root/volume centos:7
//2.创建C1、C2容器,并使用--volumes-from参数与C3绑定
docker run -it --name=c2 --volumes-from c3 centos:7
docker run -it --name=c1 --volumes-from c3 centos:7
实例:在c2 的/root/volume中创建文件c.txt,文件同时会出现在c1、c3与宿主机的/root/data目录中。可自行操作进行验证
四、Docker 应用部署
1. MySQL 部署
部署步骤:
- 搜索mysql镜像
- 拉取mysql镜像
- 创建容器
- 操作容器中的mysql
注意:因为容器内的网络服务和外部机器不能直接通信,但是,外部机器可以与容器的宿主机通信,所以,如果需要外部机器访问容器内服务时,需要将容器中提供服务的端口映射到宿主机的端口上,使外部机器访问宿主机的该端口,从而间接访问容器的服务。这种操作成为:端口映射。
- 搜索镜像
docker search mysql
- 拉去镜像
docker pull mysql:5.7
- 创建镜像
# 在/root目录下创建mysql目录用于存储mysql数据信息 mkdir /root/mysql
# 创建容器的命令 docker run -id -p 3307:3306 --name=mysql -v /root/mysql/conf:/etc/mysql/conf.d -v /root/mysql/logs:/logs -v /root/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
- 参数说明:
- -p 3307:3306:将容器的
3306
端口映射到宿主机的3307
端口(并非必须要映射到3307端口)。 - -v /root/mysql/conf:/etc/mysql/conf.d:将宿主机的
/root/mysql/conf
目录与容器的/etc/mysql/conf.d
进行绑定挂载,这是mysql
的配置目录。 - -v /root/mysql/logs:/logs:将宿主机的
/root/mysql/logs
的目录与容器的/logs
进行绑定挂在,用于存放日志。 - -v /root/mysql/data:/var/lib/mysql:将宿主机
/root/mysql/data
目录与容器/var/lib/mysql
进行绑定挂载,这是数据目录。 - -e MYSQL_ROOT_PASSWORD=123456:初始化
root
用户的密码
- -p 3307:3306:将容器的
- 进入容器,操作MySQL
# 进入容器的命令 docker exec -it mysql /bin/bash # 进入MySQL mysql -uroot -p123456 # 打印数据表 show databases;
- 外部机器连接容器中的MySQL
2. Tomcat 部署
- 搜索tomcat镜像
docker search tomcat
- 拉取tomcat镜像
docker pull tomcat
- 创建容器,设置端口映射、目录映射
# 在/root目录下创建tomcat目录用于存储tomcat数据信息 mkdir /root/tomcat cd /root/tomcat # 创建并运行容器 docker run -id --name=tomcat -p 8080:8080 -v /root/tomcat:/usr/local/tomcat/webapps tomcat
- 参数说明:
- -p 8080:8080:将容器的8080端口映射到主机的8080端口
- -v /root/tomcat:/usr/local/tomcat/webapps:将主机中Tomcat目录挂载到容器webapps目录
- 使用外部机器访问Tomcat:例
# 在宿主机的tomcat目录下创建文件 mkdir /root/tomcat/test # 创建index.html vim /root/tomcat/test/index.html
3. Nginx 部署
搜索nginx镜像
docker search nginx
拉取nginx镜像
docker pull nginx
创建容器,设置端口映射、目录映射
# 在/root目录下创建nginx目录用于存储nginx数据信息 mkdir /root/nginx mkdir /root/nginx/conf cd /root/nginx/conf # 在/root/nginx/conf/下创建nginx.conf文件,粘贴下面内容 vim nginx.conf
user nginx; # 设置nginx服务的系统使用用户 worker_processes 1; # 工作进程数 error_log /var/log/nginx/error.log warn; # nginx的错误日志 pid /var/run/nginx.pid; # nginx启动时候的pid events { worker_connections 1024; # 每个进程允许的最大连接数 } http { # http请求配置,一个http可以包含多个server #定义 Content-Type include /etc/nginx/mime.types; default_type application/octet-stream; # 日志格式 此处main与access_log中的main对应 # $remote_addr:客户端地址 # $remote_user:http客户端请求nginx认证的用户名,默认不开启认证模块,不会记录 # $timelocal:nginx的时间 # $request:请求method + 路由 + http协议版本 # status:http reponse 状态码 # body_bytes_sent:response body的大小 # $http_referer:referer头信息参数,表示上级页面 # $http_user_agent:user-agent头信息参数,客户端信息 # $http_x_forwarded_for:x-forwarded-for头信息参数 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; #访问日志,后面的main表示使用log_format中的main格式记录到access.log中 access_log /var/log/nginx/access.log main; #nginx的一大优势,高效率文件传输 sendfile on; #tcp_nopush on; #客户端与服务端的超时时间,单位秒 keepalive_timeout 65; #gzip on; server { #http服务,一个server可以配置多个location listen 80; #服务监听端口 server_name localhost; #主机名、域名 #charset koi8-r; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; #页面存放目录 index index.html index.htm; #默认页面 } #error_page 404 /404.html; # 将500 502 503 504的错误页面重定向到 /50x.html error_page 500 502 503 504 /50x.html; location = /50x.html { #匹配error_page指定的页面路径 root /usr/share/nginx/html; #页面存放的目录 } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } include /etc/nginx/conf.d/*.conf; }
# 创建并运行Nginx容器 docker run -id --name=nginx -p 80:80 -v /root/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /root/nginx/logs:/var/log/nginx -v /root/nginx/html:/usr/share/nginx/html nginx
- 参数说明:
- -p 80:80:将容器的
80
端口映射到宿主机的80
端口。 - -v /root/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:将主机下的
/root/nginx/conf/nginx.conf
挂载到容器的:/etc/nginx/nginx.conf
。配置目录 - -v /root/nginx/logs:/var/log/nginx:将主机下的
/root/nginx/logs
目录挂载到容器的/var/log/nginx
。日志目录
- -p 80:80:将容器的
- 使用外部机器访问Nginx服务:例
# 在宿主机的 /root/nginx/html/ 目录下创建index.html文件 cd /root/nginx/html vim index.html
4. Redis 部署
- 搜索redis镜像
docker search redis
- 拉取redis镜像
docker pull redis:5.0.9
- 创建容器,设置端口映射
docker run -id --name=redis -p 6379:6379 redis:5.0.9
- 使用外部机器连接redis
# 安装redis并运行 redis-cli.exe 连接宿主机上的redis容器 redis-cli.exe -h 宿主机IP地址 -p 绑定的宿主机端口
五、Dockerfile
Docker 镜像本质是一个分层文件系统。
1. 镜像制作
- 容器转为镜像
docker commit 容器ID 镜像名称:版本号
- 镜像转为压缩文件
# 因为镜像是不可以传输的,所以需要将镜像转为压缩文件 docker save -o 压缩文件名称 镜像名称:版本号
- 压缩文件转为镜像
# 将由镜像生产的压缩文件再转为镜像 docker load -i 压缩文件名称
2. Dockerfile
2.1 概述:
Dockerfile
是一个文本文件,它里面包含了一条条的指令,每一条指令构建一层。Dockerfile
基于基础镜像,最终构建出一个新的镜像来。对于开发人员来说,可以通过Dockerfile
为开发团队提供一个或多个完全一致的开发环境,便于项目的测试与运维。
2.2 关键字:
关键字 | 作用 | 备注 |
---|---|---|
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.3 案例1
自定义centos7镜像:
要求:1. 默认登录路径为/usr
;2. 可以使用vim
因为官方提供的centos7镜像创建容器后不能在容器内使用vim
,并且进入容器默认目录为/
实现步骤:
- 定义父镜像:
FROM centos:7
- 定义作者信息:
MAINTAINER itheima <itheima@itcast.cn>
- 执行安装vim命令:
RUN yum install -y vim
- 定义默认的工作目录:
WORKDIR /usr
- 定义容器启动执行的命令:
CMD /bin/bash
- 通过dockerfile构建镜像:
docker bulid –f dockerfile文件路径 –t 镜像名称:版本 .
# 在宿主机的/root目录下创建dockerfile文件夹用于存放dockerfile文件
mkdir /root/dockerfile
# 创建dockerfile
touch my_sentos7
# 将以下内容写入 my_sentos7 文件
FROM centos:7
MAINTAINER ws <18595476026@163.com>
RUN yum install -y vim
WORKDIR /usr
CMD /bin/bash
# 执行构建镜像的命令
docker build -f /root/dockerfile/my_sentos7 -t myself_centos7:1.0 .
# 查看本地镜像
docker images
# 通过 myself_centos7:1.0 镜像构建容器
docker run -id --name=myself_centos7 myself_centos7:1.0
# 进入容器
docker exec -it myself_centos7 /bin/bash
# 此时默认进入容器的 /usr 目录,并且可以使用 vim 命令
3. 服务编排
概述:按照一定的业务规则批量管理容器
3.1 Docker Compose 安装使用
Docker Compose
是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止。
使用步骤:
- 利用 Dockerfile 定义运行环境镜像
- 使用 docker-compose.yml 定义组成应用的各服务
- 运行 docker-compose up 启动应用
安装 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
六、Docker 私有仓库
1. 搭建 Docker 私有仓库
拉取私有仓库镜像
docker pull registry
启动私有仓库容器
docker run -id --name=registry -p 5000:5000 registry
验证是否搭建成功
# 打开浏览器 输入地址http://私有仓库服务器ip:5000/v2/_catalog,看到{"repositories":[]} 表示私有仓库 搭建成功
修改daemon.json
# 打开并编辑文件 vim /etc/docker/daemon.json # 将下面内容添加至文件中 {"insecure-registries":["私有仓库服务器ip:5000"]} # 例: { "registry-mirrors": ["https://r5w4t6kd.mirror.aliyuncs.com"],//原内容 "insecure-registries": ["192.168.118.130:5000"]//新增的内容 } # 作用:用于让 docker 信任私有仓库地址;注意将私有仓库服务器ip修改为自己私有仓库服务器真实ip
重启 docker 服务
systemctl restart docker docker start registry
2. Docker 私有仓库-上传镜像
1.标记镜像为私有仓库的镜像
# 命令:
docker tag 镜像名称:镜像版本号 私有仓库服务器IP:5000/镜像名称:镜像版本号
# 例:
docker tag centos:7 192.168.118.130:5000/centos:7
- 上传标记的镜像
# 命令: docker push 私有仓库服务器IP:5000/镜像名称:镜像版本号 # 例: docker push 192.168.118.130:5000/centos:7
3. Docker 私有仓库-拉取镜像
- 拉取镜像
# 命令: docker pull 私有仓库服务器ip:5000/centos:7 # 例: docker pull 192.168.118.130:5000/myself_centos7:1.0
本作品采用《CC 协议》,转载必须注明作者和本文链接