Docker
一、安装
Ubuntu
首先,更新软件包索引,并且安装必要的依赖软件,来添加一个新的 HTTPS 软件源:
1 | sudo apt update |
使用下面的 curl
导入源仓库的 GPG key:
1 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - |
将 Docker APT 软件源添加到你的系统:
1 | sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" |
现在,Docker 软件源被启用了,你可以安装软件源中任何可用的 Docker 版本。
安装最新版本
想要安装 Docker 最新版本,运行下面的命令。
1 | sudo apt update |
安装指定版本
想要安装指定版本,首先列出 Docker 软件源中所有可用的版本:
1 | sudo apt update |
后回列出很多版本
5:20.10.23~3-0~ubuntu-bionic
这种就是版本
通过在软件包名后面添加版本=<VERSION>
来安装指定版本:
1 | sudo apt install docker-ce=<VERSION> docker-ce-cli=<VERSION> containerd.io |
安装完成后
一旦安装完成,Docker 服务将会自动启动。你可以输入下面的命令,验证它:
1 | sudo systemctl status docker |
输出将会类似下面这样:
1 | ● docker.service - Docker Application Container Engine |
安装后续升级/禁止升级
当一个新的 Docker 发布时,你可以使用标准的sudo apt update && sudo apt upgrade
流程来升级 Docker 软件包。
如果你想阻止 Docker 自动更新,锁住它的版本:
1 | sudo apt-mark hold docker-ce |
以非 Root 用户身份执行 Docker
默认情况下,只有 root 或者 有 sudo 权限的用户可以执行 Docker 命令。
想要以非 root 用户执行 Docker 命令,你需要将你的用户添加到 Docker 用户组,该用户组在 Docker CE 软件包安装过程中被创建。想要这么做,输入:
1 | sudo usermod -aG docker $USER |
$USER
是一个环境变量,代表当前用户名。
登出,并且重新登录,以便用户组会员信息刷新。
验证安装过程
想要验证 Docker 是否已经成功被安装,你可以执行docker
命令,前面不需要加`sudo, 我们将会运行一个测试容器:
1 | docker container run hello-world |
如果本地没有该镜像,这个命令将会下载测试镜像,在容器中运行它,打印出 “Hello from Docker”,并且退出。
输出看起来应该像这样:
这个容器将会在打印消息后停止运行,因为它没有任何长期运行的进程。
默认情况下,Docker 从 Docker Hub 拉取镜像。它是一个云端服务,主要用来储存 公有和私有源中的 Docker 镜像。
卸载 Docker
在卸载 Docker 之前,你最好 移除所有的容器,镜像,卷和网络。
运行下面的命令停止所有正在运行的容器,并且移除所有的 docker 对象:
1 | docker container stop $(docker container ls -aq) |
现在你可以使用apt
像卸载其他软件包一样来卸载 Docker:
1 | sudo apt purge docker-ce |
配置加速器
Docker Hub 镜像加速器 - 腾讯云开发者社区-腾讯云 (tencent.com)
二、基本使用
配置开机启动docker:
systemctl enable docker
Docker镜像命令
- 查看已有镜像:
docker images
- 查看远程库的镜像:
docker search xxx
- 拉取远程镜像:
docker pull xxx
- 默认latest(最新版本)
- 指定镜像版本:
docker pull xxx:xxx
- 具体使用版本前往Docker Hub Container Image Library | App Containerization搜索所需产品现已支持的版本
- 删除现有镜像:
docker rmi xxx:xxx
- 若删除镜像名而不是ID,且删除该镜像名后仍有相同ID存在,则没有Sha码提示(实际上并没删除)
- 若想删除全部镜像可以采用
docker rmi 'docker images -q'
- 查看所有镜像ID:
docker images -q
Docker容器命令
创建并进入容器:
docker run -it --name=c1 centos:7 /bin/bash
i
:使得容器持续运行t
:给容器分配一个伪终端可以接受命令name
:给容器取名字(可以空格或者等号centos:7
:指定容器与版本号/bin/bash
:打开脚本初始化
进入容器内部:可以发现@后面的名称变了,此时为容器的ID
ls后不难得出,我们又打开了一个Linux系统
- 退出容器:
exit
- 查看容器:
docker ps
- 查看历史容器:
docker ps -a
- container id:容器ID
- image:镜像ID
- command:进入容器初始化命令,默认/bin/bash
- created:创建时间
- status:现在处于什么状态
- 查看历史容器:
- 创建后台容器:
docker run -id --name=c2 centos:7
- d为以守护(后台)模式运行容器命令,注意使用此命令创建后,并未立刻进入容器
- 进入容器:
docker exec -it c2 /bin/bash
注:如果想要启动已经退出的容器,需要先
docker start xxx(容器名)
启动容器
开启镜像:
docker start c2
关闭容器:
docker stop c2
- 开启的容器不能被rm删除
- 且可以使用
docker stop c1 c2 c3
这样的方式来同时删除多个容器
删除容器:
docker rm xx
查看容器信息:
docker inspect xxx
三、容器的数据卷
基本常识
引入:
Docker 容器删除后,在容器中产生的数据也会随之销毁
Docker 容器和外部机器可以直接交换文件吗?
容器之间想要进行数据交互?
概念:
数据卷是宿主机中的一个目录或文件
当容器目录和数据卷目录绑定后,对方的修改会立即同步
一个数据卷可以被多个容器同时挂载
一个容器也可以被挂载多个数据卷
作用:
容器数据持久化
外部机器和容器间接通信
容器之间数据交换
配置数据卷
配置host的/root/data
目录为数据卷,桥接c1
的/root/data/data_container
目录:
docker run -it --name=c1 -v /root/data:/root/data_container centos:7 /bin/bash
容器:
宿主机:
换言之:宿主机为容器提供持久化功能
- 同时添加多个数据卷的方式也简单粗暴,即添加多个
-v
即可
展示如何利用数据卷在容器之间传递数据
C3容器中:
C1容器中:
数据卷容器
多容器进行数据交换,除了上述创建数据卷的方式,更有效的办法是使用数据卷容器
这个容器数据卷的意义就在于:如果我们把c1和c2直接挂在到数据卷上,那么当我们更改数据卷地址时候,我们需要更改c1挂载,还需要更改c2挂载,而如果通过容器数据卷,我们只需要一个更改一个挂载就可以了。
- 创建启动c3数据卷容器,使用 –v 参数 设置数据卷
docker run –it --name=c3 –v /volume centos:7 /bin/bash
- 创建启动 c1 c2 容器,使用 –-volumes-from 参数 设置数据卷
docker run –it --name=c1 --volumes-from c3 centos:7 /bin/bash
docker run –it --name=c2 --volumes-from c3 centos:7 /bin/bash
我们使用docker inspect c3
查看host和c3中的数据卷位置(且c1和c2中该数据卷位置一致)
C3:
C1:
C2:
四、Docker部署
一、部署MySQL
- 搜索mysql镜像
1 | docker search mysql |
- 拉取mysql镜像
1 | docker pull mysql:5.6 |
- 创建容器,设置端口映射、目录映射
1 | 在/root目录下创建mysql目录用于存储mysql数据信息 |
1 | docker run -id \ |
- 参数说明:
- -p 3307:3306:将容器的 3306 端口映射到宿主机的 3307 端口。
- 可直接3306:3306,因为第一次,演示一下可以这样玩
- -v $PWD/conf:/etc/mysql/conf.d:将主机当前目录下的 conf/my.cnf 挂载到容器的 /etc/mysql/my.cnf。配置目录
- -v $PWD/logs:/logs:将主机当前目录下的 logs 目录挂载到容器的 /logs。日志目录
- -v $PWD/data:/var/lib/mysql :将主机当前目录下的data目录挂载到容器的 /var/lib/mysql 。数据目录
- -e MYSQL_ROOT_PASSWORD=123456:初始化 root 用户的密码。
- -p 3307:3306:将容器的 3306 端口映射到宿主机的 3307 端口。
- 进入容器,操作mysql
1 | docker exec –it c_mysql /bin/bash |
- 使用外部机器连接容器中的mysql
二、部署Tomcat
均大同小异
- 搜索tomcat镜像
1 | docker search tomcat |
- 拉取tomcat镜像
1 | docker pull tomcat |
- 创建容器,设置端口映射、目录映射
1 | 在/root目录下创建tomcat目录用于存储tomcat数据信息 |
1 | docker run -id --name=c_tomcat \ |
- 参数说明:
-p 8080:8080:将容器的8080端口映射到主机的8080端口
-v $PWD:/usr/local/tomcat/webapps:将主机中当前目录挂载到容器的webapps
- 使用外部机器访问tomcat
创建测试:
1 | mkdir test |
index.html:
1 | <h1> |
后本地浏览器访问xxx.xxx.xxx.xxx:8080/test
可得到
三、部署Nginx
- 搜索nginx镜像
1 | docker search nginx |
- 拉取nginx镜像
1 | docker pull nginx |
- 创建容器,设置端口映射、目录映射
1 | 在/root目录下创建nginx目录用于存储nginx数据信息 |
1 |
|
到nginx目录执行操作,具体来说就是
cd ..
1 | docker run -id --name=c_nginx \ |
- 参数说明:
- -p 80:80:将容器的 80端口映射到宿主机的 80 端口。
- -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf:将主机当前目录下的 /conf/nginx.conf 挂载到容器的 :/etc/nginx/nginx.conf。配置目录
- -v $PWD/logs:/var/log/nginx:将主机当前目录下的 logs 目录挂载到容器的/var/log/nginx。日志目录
- 使用外部机器访问nginx
使用cd html
进入html文件夹,后vim index.html
,输入
1 | <h1> |
可在本地打开浏览器访问Docker宿主机IP直接查看效果
四、部署Redis
- 搜索redis镜像
1 | docker search redis |
- 拉取redis镜像
1 | docker pull redis:5.0 |
- 创建容器,设置端口映射
1 | docker run -id --name=c_redis -p 6379:6379 redis:5.0 |
- 使用外部机器连接redis
1 | ./redis-cli.exe -h 192.168.149.135 -p 6379 |
五、Dockerfile
Docker镜像原理
思考:
Docker 镜像本质是什么?
Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G?
Docker 中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB?
Linux文件系统由bootfs和rootfs两部分组成
bootfs:包含bootloader(引导加载程序)和 kernel(内核)
rootfs: root文件系统,包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc等标准目录和文件
不同的linux发行版,bootfs基本一样,而rootfs不同,如ubuntu,centos等
• Docker镜像是由特殊的文件系统叠加而成
• 最底端是 bootfs,并使用宿主机的bootfs
• 第二层是 root文件系统rootfs,称为base image
• 然后再往上可以叠加其他的镜像文件
• 统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。
• 一个镜像可以放在另一个镜像的上面。位于下面的镜像称为父镜像,最底部的镜像成为基础镜像。
• 当从一个镜像启动容器时,Docker会在最顶层加载一个读写文件系统作为容器
Docker 镜像本质是什么?
- 是一个分层文件系统
Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G?
- Centos的iso镜像文件包含bootfs和rootfs,而docker的centos镜像复用操作系统的bootfs,只有rootfs和其他镜像层(前提是你的系统是centos的,如果你是Ubuntu系统,那这对于Ubuntu镜像也是同理)
Docker 中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB?
- 由于docker中镜像是分层的,tomcat虽然只有70多MB,但他需要依赖于父镜像和基础镜像,所有整个对外暴露的tomcat镜像大小500多MB
具体要了解某某有多少层叠加起来,可以使用命令docker inspect xxx:xxx(tomcat:latest)
,查看详细信息
Docker容器转镜像
一共分为三步:
docker commit 容器id 镜像名称:版本号
docker save -o 压缩文件名称 镜像名称:版本号
docker load –i 压缩文件名称
PS:镜像的名称必须小写
一般来说这种命令不常用,了解即可,要注意数据卷的数据不会被保存在创建的镜像内
Dockerfile关键字
关键字 | 作用 | 备注 |
---|---|---|
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 |
Dockerfile自定义
需求一,自定义centos7镜像。要求:
默认登录路径为 /usr
可以使用vim(镜像默认没安装vim,只能用vi)
首先本地创建一个dockerfile文件,这里我取得是centos_dockerfile
为文件名
1 | FROM centos:7 |
后输入指令docker build -f ./centos_dockerfile -t jjyaoao_centos:1 .
即可创建自己的镜像
具体步骤如下:
① 定义父镜像:FROM centos:7
② 定义作者信息:MAINTAINER jjyaoao jjyaoao@126.com
③ 执行安装vim命令: RUN yum install -y vim
④ 定义默认的工作目录:WORKDIR /usr
⑤ 定义容器启动执行的命令:CMD /bin/bash
⑥ 通过dockerfile构建镜像:docker bulid –f dockerfile文件路径 –t 镜像名称:版本
需求二:将JAVA8环境的SpringBoot项目,利用Dockerfile部署
首先本地创建一个dockerfile文件,这里我取得是springboot_dockerfile
为文件名
1 | FROM java:8 |
后输入指令docker build -f ./springboot_dockerfile -t app .
即可创建自己的镜像
① 定义父镜像:FROM java:8
② 定义作者信息:MAINTAINER jjyaoao jjyaoao@126.com
③ 将jar包添加到容器: ADD springboot.jar app.jar
④ 定义容器启动执行的命令:CMD java -jar app.jar
⑤ 通过dockerfile构建镜像:docker bulid –f dockerfile文件路径 –t 镜像名称:版本
最后创建容器,映射外部端口docker run -id -p 9000:8080 app
即可直接输入IP地址访问
若遇到端口冲突请在docker容器内使用命令java -jar -Dspring.config.location=application.properties -Dserver.port=8898 app.jar &
更换成任意端口,这里采用的是8898,同时提前修改上述外部端口映射
六、DockerCompose
服务编排: 按照一定的业务规则批量管理容器
微服务架构的应用系统中一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,维护的工作量会很大。
要从Dockerfile build image 或者去dockerhub拉取image
要创建多个container
要管理这些container(启动停止删除)
Docker Compose是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止。使用步骤:
利用 Dockerfile 定义运行环境镜像
使用 docker-compose.yml 定义组成应用的各服务
运行 docker-compose up 启动应用
一、安装Docker Compose
1 | Compose目前已经完全支持Linux、Mac OS和Windows,在我们安装Compose之前,需要先安装Docker。下面我们以编译好的二进制包方式安装在Linux系统中。 |
二、卸载Docker Compose
1 | 二进制包方式安装的,删除二进制文件即可 |
三、 使用docker compose编排nginx+springboot项目
- 创建docker-compose目录
1 | mkdir ~/docker-compose |
- 编写 docker-compose.yml 文件
1 | version: '3' |
- 创建./nginx/conf.d目录
1 | mkdir -p ./nginx/conf.d |
- 在./nginx/conf.d目录下 编写itheima.conf文件
1 | server { |
- 在~/docker-compose 目录下使用docker-compose 启动容器
1 | docker-compose up |
- 测试访问(默认端口为80)
1 | http://xxx.xxx.xxx.xxx/hello |
七、Docker 私有仓库
一、私有仓库搭建
1 | 1、拉取私有仓库镜像 |
二、将镜像上传至私有仓库
1 | 1、标记镜像为私有仓库的镜像 |
三、 从私有仓库拉取镜像
1 | 拉取镜像 |