虚拟化:是一种资源管理技术,是将计算机的各种实体资源(如内存、硬盘、网络、服务器等)予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比远不的组态更好的方式来应用资源。即 不同应用之间可以将物理资源(内存、硬盘、网络)共享,按需分配,充分利用。常见的虚拟化技术有:虚拟机、Docker等。
Hypervisor: 是一种运行在物理服务器和操作系统之间的中间件层,可允许多个操作系统和应用共享一套基础物理硬件,因此也可以看做是虚拟环境中的元操作系统,它可以协调访问服务器上的所有物理设备和虚拟机,也叫虚拟机监视器(Virtual Machine Monitor, 简称VMM),Hypervisor是所有虚拟化技术的核心,当服务器启动Hypervisor时会给每一台虚拟机分配适量的内存、CPU、网络和磁盘,并加载所有虚拟机的客户操作系统。Hypervisor是所有虚拟化技术的核心,常见的产品有VMware workstation。
虚拟机可以拆分物理资源,但每启动一个虚拟机就会分配部分物理资源,当这些物理资源闲置时也不能释放出来供其它虚拟机使用,所以虚拟机可以拆分物理资源,但不能最大化合理使用资源,一台电脑可能启动不了多少虚拟机。而Docker可以最大化充分利用资源,Docker比虚拟机能启动的更多。
一:Docker简介
Docker是对VM虚拟机进行大刀阔斧的精简,去掉没用的部分,只留下必须的部分,精简后的虚拟机更加轻量、资源占用非常少、启动非常快(几秒之内就能启动完成),在精简后的基础上又提供了一套命令,使得运维非常方便的搭建环境和部署程序,这就是Docker。
Docker相关概念
- Docker client: Docker命令行工具,用于执行docker命令行(如 docker pull、docker build、docker run等)
- Docker daemon: Docker守护进程, Docker client 与 Docker daemon进行交互
- Docker Host: Docker宿主机,就是Docker安装所在的系统
- Docker image(镜像): 应用程序 + Docker配置文件(Dockerfile + docker-compose.yml), 镜像包含的属性:repository(仓库)、tag(标签/版本 latest表示最新的版本)、image id(镜像id)、created(镜像创建时间)、size(镜像大小), docker的镜像名的命名规则一般是:前缀/项目名称,前缀用于区分该镜像所属者,防止命名冲突,常见的前缀有library、docker.io。可以将自己制作的镜像推送到Docker Hub或者阿里云镜像仓库。
- Docker container(容器) : 用于运行镜像,一般一个容器运行一个镜像
- Docker hub/registry(仓库): 镜像所在的地方(类似于maven中央仓库的概念或者GitHub), 镜像仓库地址:https://hub.docker.com/
二:CentOS7安装Docker
# 安装Docker
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
$ sudo yum install -y yum-utils
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
$ sudo yum install docker-ce docker-ce-cli containerd.io
$ yum install docker
# 启动Docker 服务
$ service docker start
# 设置开机启动
$ chkconfig docker on
#LCTT 译注:此处采用了旧式的 sysv 语法,如采用CentOS 7中支持的新式 systemd 语法,如下:
systemctl start docker.service
systemctl enable docker.service
# 配置Docker中国加速器(默认daemon.json是空的)
$ vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"live-restore": true
}
$ systemctl daemon-reload
$ systemctl restart docker
$ docker version
配置阿里云镜像加速器:产品 -》 弹性计算 -》容器服务ACK -》管理控制台 -》市场(容器镜像服务) -》镜像工具(镜像加速器)
查看docker是否启动
systemctl status docker
systemctl start docker
systemctl restart docker
三:Docker常用命令
# 查看docker的所有命令
docker
# 查看docker本身的信息
docker info
# 查看docker版本
docker version
# 查看docker支持的命令
docker --help
# 查看build命令的帮助文档
docker build --help
# 在仓库中搜索镜像
docker search <image_name>
# 拉取某个镜像,如果省略tag默认拉取latest
docker pull <image_name[:tag]>
# 查看所有镜像
docker images
# 查看某个镜像
docker images <image_name>
# 删除镜像
docker rmi image_name/image_id
# 创建并运行镜像
# -i: 创建一个交互式容器
# -t: --tty tty终端(分配一个终端来操作容器)
# -d: --detach 后台运行
# --name: 容器名称(需要唯一,不允许重复)
# -p: 主机端口映射的容器端口
# 如果省略tag默认为latest,如果拉取的镜像是指定版本的,这里要显式指定版本号
# 创建交互式容器
docker run -it --name <container name> /bin/bash
# 创建守护式容器
docker run -itd --name <container name> -p 端口:端口 <image name[:tag]>
# 目录挂载,修改宿主机中映射目录的内容同时也会修改对应的容器下的内容
# 目录挂载便于修改配置文件,不用登录到容器直接在宿主机上修改配置文件即可同步到容器中
# 挂载的作用:防止容器停止时丢失持久化数据,一般情况下各个软件的配置文件需要挂载(如 redis.conf),一些持久化数据需要挂载,如 redis持久化时保存的目录等
# 注意:如果镜像不存在会先pull镜像,即启动镜像可以省略docker pull, 直接run镜像就会自动下载
docker run -itd --name <container name> -v 宿主机目录:容器目录 镜像名
# 进入镜像
docker exec -it <image_name> /bin/bash
docker exec -it <image_name> bash
# 交互式容器:exit会停止运行容器
# 守护式容器:exit会退出容器,并不会停止运行容器
exit
# 查看已启动的容器
docker ps
# 查看所有容器
docker ps -a
# 查看最后一次运行的容器
docker ps -l
# 查看容器的CONTAINER ID
docker ps -q
# 启动、停止、重启容器
docker start container_name/container_id
docker stop container_name/container_id
docker restart container_name/container_id
# 后台启动一个容器后,使用该命令进入这个容器
docker attach container_name/container_id
# 查看容器的详细信息
docker inspect container_name/container_id
# 查看容器的ip地址属性,docker的ip为172.17.0.1,其它容器的依次是172.17.0.2递增
docker inspect -f='{{.NetworkSettings.IPAddress}}' container_name/container_id
# 查看容器的进程信息
docker top <container_name/container_id>
docker top <container_name/container_id> -eo pid,comm
# 删除已停止的容器
docker rm container_name/container_id
# 删除所有停止的容器
# -a: all 显示所有容器
# -q: quiet 只显式容器id这列的值
docker rm $(docker ps -a -q)
# 查看容器日志
docker logs container_name/container_id
# 将宿主机中的文件拷贝到某个容器的某个目录下
docker cp 文件名 容器名:/目录
# 将某个容器中的某个文件拷贝到宿主机中
docker cp 容器名:/文件 目录
# 登录Docker仓库
docker login -u <用户名> -p <密码>
# 编译镜像
# -f = --file Dockerfile的路径
# -t = --tag 'name:tag'格式, 标签就是版本号,可以为数字如1.0.0也可以是字母如latest
# build-content-path Dockerfile所在的目录 . 表示当前目录
docker build -t <name:tag> <build-content-path>
# 打标签
docker tag <image_name:tag> <仓库地址/仓库名:版本号>
docker push <imagename:tag>
# 网络列表,默认的是桥接方式bridge可以和宿主机和外网通信
docker network ls
# 查看使用bridge的容器
docker network inspect bridge
docker pull centos
docker pull ubuntu
# 拉取java 8镜像,tag可以省略默认是latest,前缀可以省略默认是library
docker pull library/java:8
docker pull elasticsearch:6.5.1
docker pull library/jetty
docker pull redis
docker pull hello-world
查看Docker的IP
yum install net-tools -y
ifconfig
四:常用的官方镜像
镜像仓库地址:https://hub.docker.com/ 可以在该地址中搜索某个具体的镜像信息,如Dockerfile示例及docker-compose.yml示例
- nginx、haproxy
- openjdk/java
- maven/gradle
- jenkins
- mysql
- redis/memcached/mongo/elasticsearch/kibana/logstash/cassandra/neo4j
- tomcat/jetty
- httpd
- ubuntu/centos/debian/fedora
- node/php/python/golang/swift
- 等等
openjdk:8-jdk-alpine
java:8
maven:3.6-jdk-8
nginx docker-compose.yml 示例
搭建私有仓库
搭建Docker私有仓库需要使用官方提供的registry镜像。搭建私有仓库可以使用安全认证用户名密码登录。
# 先下载registry镜像,然后再创建容器
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /mnt/registry:/var/lib/registry \
registry:2
docker tag hello-world:latest localhost:5000/helloworld
docker push localhost:5000/helloworld
# 访问私有仓库地址
localhost:5000/
五: Dockerfile 指令
Dockerfile文件的语法为DSL语法。可以通过docker build进行构建镜像。
- FROM 指定基础镜像
基础镜像一般是操作系统(如centos, ubuntu等),FROM指令必是Dockerfile文件中的首条命令,启动构建流程后,Docker将会基于该镜像构建新镜像
# FROM语法格式, tag和digest省略会使用latest版本
# FROM的内容可以从镜像仓库中https://hub.docker.com/查找
FROM <image-name>[:<tag>]
FROM <image-name>[:<digest>]
- MAINTAINER
维护者信息 后面可以根姓名和邮箱等信息
MAINTAINER mengday "mengday.zhang@gmail.com"
- ENV 设置环境变量
设置环境变量而已,无论是后面的其它指令,如RUN,还是运行时的应用,都可以直接使用这里定义的环境变量。
# 方式一
ENV <key> <value>
# 方式二:如果要换行使用反斜杠
ENV <key1>=<value1> \
<key2>=<value2>...
- ARG 变量
ARG用于指定传递给构建运行时的变量, 在使用docker build构建镜像时,可以通过 --build-arg = 参数来指定或重设置这些变量的值。
ARG <name>[=<default value>]
ARG site
ARG build_user=mengday
- RUN 执行命令
在镜像的构建过程中执行特定的命令,并生成一个中间镜像
# shell格式
RUN <command>
# exec格式
RUN ["executable", "param1", "param2"]
RUN echo 'Hello Docker!'
- CMD
在容器启动时所要执行的命令
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2
- VOLUME 定义匿名卷
VOLUME用于创建挂载点,可以将源代码、数据或其它内容添加到镜像中,而又不会提交到镜像中,并使我们可以多个容器间共享这些内容。
VOLUME ["/data"]
- COPY 和 ADD 复制文件
COPY和ADD功能都是将构建上下文中源文件复制到镜像内的目标路径,ADD与COPY不同的是ADD支持源文件是一个URL,所以直接用ADD就可以了
ADD <源文件>... <目标路径>
ADD springboot-docker-1.0.jar app.jar
- RUN 执行命令
在镜像的构建过程中执行特定的命令,并生成一个中间镜像
#shell格式
RUN <command>
#exec格式
RUN ["executable", "param1", "param2"]
- EXPOSE 设置监听端口
为构建的镜像设置监听端口,使容器在运行时监听
EXPOSE <port> [<port>...]
EXPOSE 80
EXPOSE 8080
- ENTRYPOINT
给容器配置一个可执行程序.也就是说,每次使用镜像创建容器时,通过ENTRYPOINT指定的程序都会被设置为默认程序。
Dockerfile 中只允许有一个 ENTRYPOINT 命令,多指定时会覆盖前面的设置,而只执行最后的 ENTRYPOINT 指令。
ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖 ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给 ENTRYPOINT。
也可以通过docker run --entrypoint重写 ENTRYPOINT入口点
# 格式一
ENTRYPOINT ["executable", "param1", "param2"]
# 格式二
ENTRYPOINT command param1 param2
# 启动项目 java -jar /app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
- WORKDIR 指定工作目录
用于在容器内设置一个工作目录, 通过WORKDIR设置工作目录后,Dockerfile 中其后的命令 RUN、CMD、ENTRYPOINT、ADD、COPY 等命令都会在该目录下执行。 在使用 docker run 运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。
WORKDIR /path/to/workdir
- USER 指定当前用户
- LABEL 为镜像添加元数据
- ONBUILD 设置镜像触发器
- STOPSIGNAL 设置停止容器所要发送的系统调用信号
- SHELL 设置shell类型
六 Docker Compose
1. 简介
Dockerfile 可以让用户管理一个单独的应用容器;而 Compose 则允许用户在一个模板(YAML 格式)中定义一组相关联的应用容器(被称为一个 project,即项目),例如一个 Web 服务容器再加上后端的数据库服务容器等。通过 Docker-Compose 用户可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。
Compose 中有两个重要的概念:
- 服务 (service) :一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
- 项目 (project) :由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。
一个项目可以由多个服务(容器)关联而成,Compose 面向项目进行管理,通过子命令对项目中的一组容器进行便捷地生命周期管理。如一个微服务可能会用到nginx服务、mysql服务、redis服务等
2. Docker Compose 安装
Docker Compose 是 Docker 的独立产品,因此需要安装 Docker 之后在单独安装 Docker Compose
2.1 Docker Compose安装
#下载
sudo curl -L https://github.com/docker/compose/releases/download/1.20.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
#安装
chmod +x /usr/local/bin/docker-compose
#查看版本
docker-compose version
2.2 安装补全工具(可选)
为了方便我们输入命令,也可以安装 Docker 的补全提示工具帮忙我们快速输入命令
#安装
yum install bash-completion
#下载docker-compose脚本
curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
2.3 docker-compose常用命令
# 拉取服务依赖的镜像
docker-compose pull
#构建(重新构建)项目中的服务容器。服务容器一旦构建后,将会带上一个标记名
# 启动应用
docker-compose up
# 后台启动应用
docker-compose up -d
# -f指定使用的 Compose 模板文件,默认为 docker-compose.yml
docker-compose up -d -f docker-compose.yml
# 停用移除所有容器以及网络相关
docker-compose down
# 查看服务容器的输出
docker-compose logs
# 查看启动的服务
docker-compose ps
# 启动已经存在的服务容器。
docker-compose start
# 停止已经处于运行状态的容器,但不删除它。通过 docker-compose start 可以再次启动这些容器。
docker-compose stop
# 重启项目中的服务
docker-compose restart