1.介绍
上述情况会出现软件跨环境迁移的问题,Docker作为一个容器技术,为了解决上述问题。
Docker
-
开源的应用容器引擎。
-
诞生于2013年初,基于Go语言
-
可以让开发者打包他们的应用以及依赖包到一个轻量级,可移植的容器中,然后发布到任何流行的Linux机器上
-
容器使用沙箱机制,相互隔离
-
容器性能开销极低。
-
从17.03分为CE社区板,EE企业版
-
Package Software into Standardized Units for Development, Shipment and Deployment
A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. A Docker container image is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings.
Container images become containers at runtime and in the case of Docker containers - images become containers when they run on Docker Engine. Available for both Linux and Windows-based applications, containerized software will always run the same, regardless of the infrastructure. Containers isolate software from its environment and ensure that it works uniformly despite differences for instance between development and staging.
Docker containers that run on Docker Engine:
- Standard: Docker created the industry standard for containers, so they could be portable anywhere
- Lightweight: Containers share the machine’s OS system kernel and therefore do not require an OS per application, driving higher server efficiencies and reducing server and licensing costs
- Secure: Applications are safer in containers and Docker provides the strongest default isolation capabilities in the industry
-
Container images become containers at runtime and in the case of Docker containers - images become containers when they run on Docker Engine. Available for both Linux and Windows-based applications, containerized software will always run the same, regardless of the infrastructure. Containers isolate software from its environment and ensure that it works uniformly despite differences for instance between development and staging.
Docker containers that run on Docker Engine:
- Standard: Docker created the industry standard for containers, so they could be portable anywhere
- Lightweight: Containers share the machine’s OS system kernel and therefore do not require an OS per application, driving higher server efficiencies and reducing server and licensing costs
- Secure: Applications are safer in containers and Docker provides the strongest default isolation capabilities in the industry
Docker Containers Are Everywhere: Linux, Windows, Data center, Cloud, Server-less , etc.
Docker container technology was launched in 2013 as an open source Docker Engine.
It leveraged existing computing concepts around containers and specifically in the Linux world, primitives known as cgroups and namespaces. Docker’s technology is unique because it focuses on the requirements of developers and systems operators to separate application dependencies from infrastructure.
Success in the Linux world drove a partnership with Microsoft that brought Docker containers and its functionality to Windows Server (sometimes referred to as Docker Windows containers).
Technology available from Docker and its open source project, Moby has been leveraged by all major data center vendors and cloud providers. Many of these providers are leveraging Docker for their container-native IaaS offerings. Additionally, the leading open source serverless frameworks utilize Docker container technology.
2.安装
sudo curl https://get.docker.com/ > ./docker_install.sh sudo sh docker_install.sh –mirror Aliyun
配置加速器:
阿里云等等。https://cr.console.aliyun.com/
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://rp0hjyg7.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
3.架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r1vTUYws-1584002477866)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311104613297.png)]
- image:镜像。相当于一个root文件系统
- daemon:守护进程
- container:容器。根据镜像所创建出来的实例。类似面向对象的类(镜像)和对象(容器)。
- registries:仓库。代码控制中心,保存镜像。
4. Docker命令
4.1进程相关命令
sudo systemctl start docker
开启docker服务sudo systemctl status docker
查看docker服务状态(active/dead)sudo systemctl stop docker
关闭docker服务sudo systemctl restart docker
重启docker服务sudo systemctl enable docker
开启docker开机启动
4.2镜像相关命令
-
docker images
查看本地镜像[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tje6Q1wE-1584002477867)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311161022220.png)]- -a: 查看本地所有镜像
- -q: 查看id
-
docker search 镜像名
搜索镜像[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P7vLatGx-1584002477868)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311161121403.png)] -
docker pull 镜像名
安装镜像,默认最新[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xE8713hI-1584002477869)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311160747062.png)]- 强制版本
docker pull redis:5.0
版本号去官网查询
- 强制版本
-
docker rmi 镜像id
删除镜像,id通过查看本地镜像看到-
docker rmi 镜像名字
删除镜像 -
docker rmi `docker images -q`
删除所有镜像
-
4.3容器相关命令
-
docker run -it --name=容器名 /bin/bash
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VraeyNmJ-1584002477870)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311161331980.png)]-
-i:一直运行,否则无客户端连接会断开连接
-
-t:给容器分配一个终端,exit退出后就关闭了
-
-d: 以守护(后台)模式运行,exit退出后不会关闭
-
–name: 给容器取名字
-
-it 创建的容器叫交互式容器,-id创建的叫守护式容器
-
/bin/bash 会直接进入容器的终端,需要exit退出
-
-
exit
退出容器 -
docker start 容器名
:启动容器 -
docker ps
查看正在运行的容器。- -a 查看所有。包括已经删除的
- -q查id
-
docker exec -it 容器名 /bin/bash
进入容器 -
docker stop 容器名
关闭容器[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-87Rf0qRB-1584002477870)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311160650293.png)] -
docker rm 容器名
删除容器-
docker rm `docker ps -aq`
删除所有容器
-
开启的容器不能删。要先停。
-
-
docker inspect 容器名
- 部分截图如下:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JYTenNmu-1584002477871)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311162214073.png)]
- “Mounts”显示宿主机的数据卷目录
- “binds”显示容器的数据卷目录
-
以上的容器名均可换成ID
5. Docker容器的数据卷
5.1数据卷的概念及作用
容器存在以下问题:
- Docker容器删除后,在容器中产生的数据会丢失。(数据的持久化问题)
- Docker容器和宿主机(外部机器)不能直接交换文件
- 容器之间不能数据交互
数据卷:
- 宿主机中的一个目录或文件
- 当容器目录和数据卷目录绑定后,二者的修改会立即同步
- 一个容器可以挂载多个数据卷
- 一个数据卷可以被多个容器挂载
数据卷作用:(即前述问题)
- 容器数据持久化
- 外部机器和容器简介通信
- 容器之间数据交换
5.2数据卷配置
-
创建启动容器时,使用-v参数设置数据卷
docker run ... -v 宿主机目录(文件):容器内目录文件 容器
docker run -it --name=cwd -v /home/pi/data:/root/data_container ubuntu
- 目录必须是绝对路径
- 如果不存在会自动创建
- 容器出现目录[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kbhCrTPP-1584002477872)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311175052542.png)]
- 宿主机出现目录[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vL9sa28U-1584002477873)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311175217612.png)]
- 两边目录本来都是空的,在一边创建一个新文件后,会自动同步到另一边。文件内容也会同步。
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ig7CXVDG-1584002477874)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311175525388.png)]
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gn2pE6lx-1584002477875)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311175732148.png)]
- 其他同步均可实验
5.3数据卷容器
处理多容器数据交换问题:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ARXzgZic-1584002477876)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311185929035.png)]
配置数据卷容器:
-
创建启动C3数据卷容器,使用-v参数设置数据卷
docker run -it --name=c3 -v /volume ubuntu
-
创建启动C1,C2容器,使用–volumes-from参数设置数据卷
docker run -it --name=c1 --volumes-from c3 ubuntu
docker run -it --name=c2 --volumes-from c3 ubuntu
-
达到数据共享等目的。
6. Docker应用部署
6.1 MySQL部署
(树莓派4b架构是armv7,Mysql暂时还不支持)
在Docker容器中部署MySQL,并通过外部MySQL客户端操作
-
搜索镜像
-
拉取镜像
-
创建容器,设置端口映射,目录映射
#在/root目录下创建mysql目录用于储存mysql数据信息 mkdir ~/mysql \ docker run -id \ #以守护式方式运行 -p 3307:3306 \ #端口映射 --name=c_mysql \ #pwd命令为查看本机路径。下面是三个数据卷配置 -v $PWD/conf:/etc/mysql/conf.d \ -v $PWD/logs:/logs \ -v $PWD/data:/var/lib/mysql \ #设置mysql服务root用户密码 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.6
说明:
-p 3307:3306
: 将容器的3306端口映射到宿主机的3307端口-v $PWD/conf:/etc/mysql/conf.d
:将主机当前目录下的conf/my.conf目录挂载到容器的/etc/mysql/conf.d。配置目录-v $PWD/logs:/logs
:将主机当前目录下的logs目录挂载到容器的/logs。日志目录-v $PWD/data:/var/lib/mysql
:将主机当前目录下的data目录挂载到容器的/var/lib/mysql。数据目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cHNknYT4-1584002477876)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311194603633.png)]
6.2 Tomcat部署
在Docker容器中部署Tomcat,并通过外部Tomcat部署的项目
-
搜索Tomcat镜像
-
拉取Tomcat镜像
docker pull tomcat:jdk11-adoptopenjdk-hotspot
官网找了一个支持arm/v7的版本。 -
创建容器
#在/home/pi/目录下创建tomcat目录用于储存tomcat数据信息 mkdir ~/home/pi/tomcat \ cd ~/home/pi/tomcat docker run -id --name=c_tomcat \ -p 8080:8080 \ -v $PWD:/usr/local/tomcat/webapps \ tomcat:jdk11-adoptopenjdk-hotspot
参数说明:
-p 8080:8080
: 将容器的8080端口映射到主机的8080端口-v $PWD:/usr/local/tomcat/webapps
:将主机中当前目录挂载到容器的webapps
-
部署项目
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AteBTKGr-1584002477877)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311215330693.png)]
index.html中编写简单脚本
<h1> hello world <h1>
-
测试访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rybvMLdD-1584002477878)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200311215521040.png)]
6.3 Nginx部署
-
搜索镜像
-
拉取镜像
-
创建容器,设置端口映射,目录映射
docker run --name nginx-test -p 3000:80 -d nginx
参数说明:
-p 3000:80
: 将容器的80端口映射到宿主机的3000端口
-
运行结果如下:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pJAa1I6D-1584002477879)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200312104754899.png)]
7.Dockerfile
7.1镜像原理
为什么?
- Docker中ubuntu镜像只有几百M,而一个iso却要几个G?
- ubuntu的iso镜像文件包含bootfs和rootfs,而docker的Ubuntu镜像复用操作系统的bootfs,只有rootfs和其他镜像层
- Tomcat镜像有385MB,安装包却只有70多M?
- docker的镜像分层的,tomcat虽然只有70多MB,但是需要依赖的父镜像和基础镜像占用空间,而对外暴露的只有tomcat一个
- Docker的镜像本质是什么?
- 一个分层的文件系统
操作系统组成部分:
- 进程调度子系统
- 进程通信子系统
- 内存管理子系统
- 设备管理子系统
- 文件管理子系统
- 网络通信子系统
- 作业控制子系统
Linux文件系统:由bootfs和rootfs两部分构成:
- bootfs:包含bootloader(引导加载程序)和kernel(内核)
- rootfs:root文件系统,包含的就是linux系统中的/dev,/proc,/bin,/ect等标准目录和文件
- 不同的linux发行版,bootfs基本一样,而rootfs不同
Docker镜像原理:
- Docker镜像是由特殊的文件系统叠加而成
- 最低端是bootfs,并使用宿主机的bootfs
- 第二层是root文件系统rootfs,成为base image
- 再往上叠加其他镜像文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SwCkDDhN-1584002477879)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200312112729201.png)] - 统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统
- 一个镜像可以叠加在另一个上面,位于下面的镜像叫父镜像,最底部的叫基础镜像
7.2镜像制作
- 容器转为镜像
docker commit 容器id 镜像名称:版本号
docker save -o 压缩文件名称 镜像名称:版本号
docker load -i 压缩文件名称
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UAEYvM4c-1584002477880)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200312122336689.png)]- 通过数据卷挂载的文件在生成镜像后内容不会在里面
7.3Dockerfile概念及作用
概念:
- Dockfile是一个文本文件
- 包含了一条条指令
- 每一条指令构建一层,基于基础镜像,最终构建出一个新的镜像(即每一行一层)
- 对于开发人员:可以为开发团队提供一个完全一致的开发环境
- 对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfile文件构建一个新的镜像开始工作
- 对于运维人员:在部署时,可以实现应有的无缝移植
- ubuntu Dockerfile
7.4Dockerfile关键字
关键字 | 作用 | 备注 |
---|---|---|
FROM | 指定基础镜像 | 指定dockerfile基于那个image构建,建议格式写全 registry/namespace/project:tag 或者 registry/namespace/project:tag as aliasName |
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 | 入口 | 一般在制作一些执行就关闭的容器中会使用 配合CMD 使用更好 下面会专门说这个东西 |
COPY | 复制文件 | build的时候复制文件到image中 可以使用通配符 只要复合go的filepath.Match规则就行 COPY source target 如果是从标准输出流构建 无法使用这个关键字 |
ADD | 添加文件 | build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务 ADD source target 注意: target如果带/ 那么会把target当成文件夹 内部文件名称自动推断 如果没有带/那么可能蒋target当成一个文件 |
ENV | 环境变量 | 指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value … |
ARG | 构建参数 | 构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数 |
VOLUME | 定义外部可以挂载的数据卷 | 指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME [“目录”] |
EXPOSE | 暴露端口 | 定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp 如果不指定监听tcp还是udp 那么默认为tcp |
WORKDIR | 工作目录 | 指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径 |
USER | 指定执行用户 | 指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户 |
HEALTHCHECK | 健康检查 | 指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制 |
ONBUILD | 触发器 | 当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大 |
STOPSIGNAL | 发送信号量到宿主机 | 该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。此信号可以是与内核的系统调用表中的位置匹配的有效无符号数,例如9,或SIGNAME格式的信号名,例如SIGKILL。 这个不太明白干啥的 看起来是和宿主机通过信号量交互的 |
SHELL | 指定执行脚本的shell | 指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell 例如 sh bash zsh powershell 等 格式 SHELL zsh |
7.5案例
实现步骤:
- 定义父镜像: FROM centous:7
- 定义作者信息: MAINTAINER cwd
- 其他安装,比如vim : RUN yum install -y vim
- 定义默认工作目录: WORKDIR/usr
- 定义容器启动执行命令: CMD/bin/bash
FROM centous:7
MAINTAINER cwd
RUN yum install -y vim
WORKDIR/usr
CMD/bin/bash
vim centous_dockerfile
:在vim编辑器内复制上面这一段
docker build -f ./centos_dockerfile -t 新镜像名称
运行成功后docker images
就可以看到image了
8.Docker服务编排
服务编排:按照一定的业务规则批量管理容器
微服务架构的应用系统中一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,维护的工作量会很大。
- 要从Dockerfile build image 或者Dockerhub 拉取image
- 要创建多个container
- 要管理这些container
ocker Compose**:是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止。使用步骤:
- 利用Dockerfiles定义运行环境镜像
- 使用docker-compose.yml定义组成应用的各服务
- 运行docker-compose up 启动应用
安装应用等:菜鸟教程
9.Docker私有仓库
1搭建私有仓库:
#1.拉取私有仓库镜像
docker pull registry
#2.启动私有仓库容器
docker run -id --name=registry -p 5000:5000 registry
#3.打开浏览器 输入地址http://私有仓库服务器ip:5000/v2/_catalog,看到{"repositories":[]} 表示私有仓库搭建成功
#4. 修改daemon.json
sudo vim /etc/docker/daemon.json
#在上述文件中添加一个key,保存退出。此步用于让docker新人私有仓库地址
{"insecure-registries":["192.168.167.15:5000"]}
#5.重启docker服务
systemctl restart docker
docker start registry
2将镜像传至私有仓库:
#1.标记镜像为私有仓库的镜像
docker tag ubuntu 私有仓库服务器ip:5000/ubuntu
#2.上传标记的镜像
docker push 私有仓库服务器ip:5000/ubuntu
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rAN5XSYr-1584002477881)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200312161519557.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jUT4Ks1z-1584002477882)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200312161626798.png)]
此时再打开浏览器 输入地址http://私有仓库服务器ip:5000/v2/_catalog,看到{“repositories”:[“ubuntu”]} ,表示上传成功
3从私有仓库拉取镜像到本地:
#拉取镜像
docker pull 私有仓库服务器IP:5000/ubuntu
10.docker
容器就是将软件打包成标准化单元,以用于开发,交付和部署。
- 容器镜像是轻量的、可执行的独立软件包,包含软件运行所需的所有内容:代码,运行时环境,系统工具,系统库和设置
- 容器化软件在任何环境中都能够实则如一的运行
- 容器赋予软件独立性,使其免受外在环境差异的影响,从而有助于减少团队间
容器和虚拟机的架构区别:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-infWX7o6-1584002477882)(C:\Users\U2016\AppData\Roaming\Typora\typora-user-images\image-20200312163353311.png)]
相同:
- 容器和虚拟机具有相似的资源隔离和分配优势
不同:
- 容器虚拟化的是操作系统,虚拟机虚拟化的是硬件
- 容器与宿主机共享操作系统底层。虚拟机与主机共享硬件
- 虚拟机可以运行不同操作系统,容器只能运行同一类型的操作系统
特性 | 容器 | 虚拟机 |
---|---|---|
硬盘使用 | MB | GB |
性能 | 接近原生 | 弱于原生 |
系统支持量 | 上千个 | 几个 |
启动时间 | 秒级 | 分钟级 |