docker笔记 -使用方法

效果如下图:docker安装

docker官网:https://docs.docker.com/

准备

  • 一台linux系统的服务器。选的是CentOS7版本系统

docker官网

其实docker官网中对于安装docker的步骤介绍很详细了,下面参考官网的安装步骤进行安装docker;
在这里插入图片描述

进入官网的界面如上图;

Product manuals—>Docker Engine—>Installation per distro—>Install on CentOS
在这里插入图片描述

按照这个路径进入centos镜像的安装介绍:

安装

按照官网的步骤,首先卸载旧版容器版本;

1.卸载旧版

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

执行结果如图:

在这里插入图片描述

2.安装依赖包和设置仓库

安装依赖包
sudo yum install -y yum-utils

在这里插入图片描述

设置仓库

仓库地址,官网是国外的仓库配置,类似maven中央仓库一样,我们需要改成阿里云国内地址;
阿里云地址:http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

配置阿里云地址:

sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

在这里插入图片描述

3.更新依赖(可选)

sudo yum update

注意:这个更新依赖过多,时间太长,更新过程中大家可以使用kill -9 PID杀死进程;否则需要等待更新进程一直在阻塞者,下面的安装进程无法操作;

4.正式安装docker

目前安装的是最新版,如果想安装其他版本可以按照官网命令安装:

sudo yum -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin
  • 其他版本
yum list docker-ce --showduplicates | sort -r

安装:sudo yum -y install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io docker-compose-plugin

执行完毕如下:
在这里插入图片描述

5.启动docker

sudo systemctl start docker

6.验证是否成功

docker version

执行如下:

在这里插入图片描述

7.hello world

sudo docker run hello-world

执行以上命令如下:

在这里插入图片描述

万般语言hello world起,从日志中可以看到本地仓库中没有helloworld镜像,从阿里云仓库中下载最新版镜像,使用docker images确定是否下载成功;

在这里插入图片描述

8.阿里云镜像加速

  1. 注册阿里云账户(淘宝账户就可以)

在这里插入图片描述

  1. 获得加速器地址连接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在这里插入图片描述

  1. 粘贴脚本直接运行

在这里插入图片描述

  1. 重启服务器

在这里插入图片描述

docker命令

(一)docker 基础命令

启动docker systemctl start docker

关闭docker systemctl stop docker

重启docker systemctl restart docker

docker自启动 systemctl enable docker

查看docker 运行状态 systemctl status docker

查看docker 版本号信息 docker version docker info

查看docker镜像/容器/数据卷所占空间 docker system df

docker 帮助命令 docker --help

比如 咱忘记了 拉取命令 不知道可以带哪些参数 咱可以这样使用 docker pull --help

(二)docker 镜像命令

**查看自己服务器中docker 镜像列表 **

docker images

搜索镜像

docker search 镜像名
docker search --filter=STARS=9000 mysql    #搜索 STARS >9000的 mysql 镜像

拉取镜像 不加tag(版本号) 即拉取docker仓库中 该镜像的最新版本latest , 加:tag 则是拉取指定版本

docker pull 镜像名 
docker pull 镜像名:tag

运行镜像 ----咱拉取一个tomcat 跑起来试一试

docker run 镜像名
docker run 镜像名:Tag

示例:

docker pull tomcat
docker run tomcat

发现咱运行后 出现tomcat 默认占用的8080 端口 说明该镜像已经是启动了 ,但是 咱好像鼠标没有回到咱服务器上了 ,这怎么办呢 ?

使用 Ctrl+C (注:此方式虽然可以退出容器,但此种命令操作方式却是错误的,详细缘由请见下文的容器命令)

docker中 run 命令是十分复杂的 有什么持久运行 映射端口 设置容器别名 数据卷挂载等

一通测试,发现我们拉了好多镜像了,但我们现在根本用不着,这些无用镜像怎么删除呢?

删除镜像 ------当前镜像没有被任何容器使用才可以删除

#删除一个
docker rmi 镜像名/镜像ID

#删除多个 其镜像ID或镜像用空格隔开即可 
docker rmi 镜像名/镜像ID 镜像名/镜像ID 镜像名/镜像ID

#删除全部镜像  -a 意思为显示全部, -q 意思为只显示ID
docker rmi $(docker images -aq)

强制删除镜像

#删除一个
docker rmi -f 镜像名/镜像ID

#删除多个 其镜像ID或镜像用空格隔开即可 
docker rmi -f 镜像名/镜像ID 镜像名/镜像ID 镜像名/镜像ID

#删除全部镜像  -a 意思为显示全部, -q 意思为只显示ID
docker rmi -f $(docker images -aq)

删除虚悬镜像 (镜像名称和标签为的镜像)

docker image prune

保存镜像

将我们的镜像 保存为tar 压缩文件 这样方便镜像转移和保存 ,然后 可以在任何一台安装了docker的服务器上 加载这个镜像

docker save 镜像名/镜像ID -o 镜像保存在哪个位置与名字

exmaple:

docker save tomcat -o /myimg.tar

在这里插入图片描述

加载镜像
任何装 docker 的地方加载镜像保存文件,使其恢复为一个镜像

docker load -i 镜像保存文件位置

在这里插入图片描述

查看镜像 测试镜像功能是否正常

我们来把解压的镜像 run一下。

在这里插入图片描述

镜像标签
有的时候呢,我们需要对一个镜像进行分类或者版本迭代操作,比如我们一个微服务已经打为docker镜像,但是想根据环境进行区分为develop环境与alpha环境,这个时候呢,我们就可以使用Tag,来进对镜像做一个标签添加,从而行进区分;版本迭代逻辑也是一样,根据不同的tag进行区分

app:1.0.0 基础镜像
# 分离为开发环境
app:develop-1.0.0   
# 分离为alpha环境
app:alpha-1.0.0   
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

docker tag 源镜像名:TAG 想要生成新的镜像名:新的TAG

# 如果省略TAG 则会为镜像默认打上latest TAG
docker tag aaa bbb
# 上方操作等于 docker tag aaa:latest bbb:test

示例:

# 我们根据镜像 quay.io/minio/minio 添加一个新的镜像 名为 aaa 标签Tag设置为1.2.3
docker tag quay.io/minio/minio:1.2.3 aaa:1.2.3

# 我们根据镜像 app-user:1.0.0 添加一个新的镜像 名为 app-user 标签Tag设置为alpha-1.0.0
docker tag app-user:1.0.0 app-user:alpha-1.0.0

在这里插入图片描述

(三)docker 容器命令

前言已经说了 docker 容器 就好比 咱java中的new出来对象(docker run 镜像 产生一个该镜像具体容器实例),docker 容器的启动需要 镜像的支持

查看正在运行容器列表

docker ps

查看所有容器 -----包含正在运行 和已停止的

docker ps -a

容器怎么来呢 可以通过run 镜像 来构建 自己的容器实例

运行一个容器

-it 表示与容器进行交互式启动(如centos,mysql,redis等) -d 表示可后台运行容器(守护式运行)  --name 给要运行的容器起的名字  /bin/bash  shell交互路径
docker run -it -d --name 要取的别名 镜像名:Tag /bin/bash 

例如我们要启动一个redis 把它的别名取为redis001 并交互式运行 需要的命令 —我这里指定版本号为5.0.5

#1. 拉取redis 镜像
docker pull redis:5.0.5
#2.命令启动
docker run -it -d --name redis001 redis:5.0.5 /bin/bash

在这里插入图片描述

#3.查看已运行容器
docker ps

在这里插入图片描述

发现看到了 redis 使用了6379 端口 那么我们在关闭防火墙或开启了安全组的情况下 是否可以进行访问呢?

为了区分, 咱们使用linux 命令查看一下

# netstat是控制台命令,是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息
netstat -untlp

在这里插入图片描述

惊讶的发现,我们redis容器启动占用的 6379端口netstat 没有显示出来?什么情况?赶紧使用 redis desktop manger 连接测试一下

在这里插入图片描述

为什么不行呢 已经确定了 docker 中 redis 容器已经是在运行中 且占有端口 6379啊?

因为:占用的6379端口 仅仅是在容器中内部本身的端口,与宿主机的6379端口并无联系,我们通过宿主机Ip:6379访问此redis示例,那自然是找不到的哟!


这里,来补充一点Docker容器的知识!

每一个 Docker容器都是独立和安全的应用平台(我们可以理解为,每一个docker容器都相当于在我们的服务器上占用资源然后开辟了属于自己的一个空间(也可以理解为服务器))

在这里插入图片描述

这是Docker 一大特点,每个容器之间环境都是隔离的!!!

我们甚至可以在一个服务器上,使用docker镜像,来跑出N个 mysql实例(尽管,他们的默认端口都是一样的,但还是那句话,容器间,环境是隔离的。A容器中的3306 与B容器的3306毫无关系,因为其不在一个世界呀!)

默认情况下,我们是无法通过宿主机(安装docker的服务器)端口来直接访问容器的 ,因为docker容器自己开辟空间的端口与宿主机端口没有联系…

如果外部想要访问容器,那必须得让容器中的端口与宿主机的端口建立联系绑定起来,这个正式的概念叫做 容器端口映射

有了端口映射,我们就可以将宿主机端口与 容器端口绑定起来,比如 我们建立宿主机的6379端口与容器redis6379端口绑定起来,那么再访问宿主机Ip:6379 就可以访问到对应容器了!

接下来 进行容器端口映射演示

首先停止容器

# 先停止咱之前运行的 redis 容器 
docker stop 容器名/容器ID

在这里插入图片描述

然后删除容器 -----不经意间 咱发现已经运行过这么多容器了 咱进行清理一下
在这里插入图片描述

#删除一个容器
docker rm -f 容器名/容器ID
#删除多个容器 空格隔开要删除的容器名或容器ID
docker rm -f 容器名/容器ID 容器名/容器ID 容器名/容器ID
#删除全部容器
docker rm -f $(docker ps -aq)

在这里插入图片描述

这样 容器就已经删除完毕了, 咱们接着弄 前边说的 端口映射

容器端口与服务器端口映射

命令:

-p 宿主机端口:容器端口

还是使用前方的 redis 镜像 尝试 将6379端口 映射到服务器的8888 如果成功了的话 那么咱们访问服务器的8888端口就会访问到咱们的 docker 中的容器 redis002

-p 8888:6379 解析 将容器内部的 6379端口与docker 宿主机(docker装在哪台服务器 哪台服务器就是宿主机)8888 端口进行映射 那通过外部访问宿主机8888端口 即可访问到 docker 容器 6379 端口了

docker run -itd --name redis002 -p 8888:6379 redis:5.0.5 /bin/bash

在这里插入图片描述

在运行后 发现服务器的 8888 端口显示已被docker-proxy 所占用了 那么此时咱再用工具进行连接测试呢?

image-20200521161729868

**那么容器端口映射有没有什么限制呢? **

有的,虽说每个容器之间,环境都是隔离的,但是宿主机每个端口都是一个,8888端口被redis002容器绑定了,那么其他所有的容器都不可以使用8888这个端口了!!!


有时候,我们需要进入容器内部,修改其配置文件,那么如何才能进入容器内呢?

进入容器方式一 这里咱就进入 前面的 redis001容器

docker exec -it 容器名/容器ID /bin/bash

#进入 前面的 redis001容器   
docker exec -it redis001 /bin/bash

在这里插入图片描述

可以看到 我已经从主机alibyleilei 跳到了容器ID 对应下的 /data 已经是进入到容器内部了

进入容器方式二 —推荐使用 exec 方式

docker attach 容器名/容器ID

那怎么退出容器呢 ?

从容器内 退出到自己服务器中 需注意 两个退出命令的区别

#-----直接退出  未添加 -d(持久化运行容器) 时 执行此参数 容器会被关闭  
exit
# 优雅提出 --- 无论是否添加-d 参数 执行此命令容器都不会被关闭
Ctrl + p + q

停止容器

docker stop 容器ID/容器名

重启容器

docker restart 容器ID/容器名

启动容器

docker start 容器ID/容器名

kill 容器

docker kill 容器ID/容器名

容器文件拷贝 —无论容器是否开启 都可以进行拷贝

#docker cp 容器ID/名称:文件路径  要拷贝到外部的路径   |     要拷贝到外部的路径  容器ID/名称:文件路径
#从容器内 拷出
docker cp 容器ID/名称: 容器内路径  容器外路径
#从外部 拷贝文件到容器内
docker  cp 容器外路径 容器ID/名称: 容器内路径

查看容器日志

docker logs -f --tail=要查看末尾多少行 默认all 容器ID

在这里插入图片描述

设置容器自启动

我们在运维的时候,通常给一些软件喜欢设置开机自启动,例如 mysql、redis,这样测试环境服务器重启时可节省不少运维时间成本,那么我们如果是docker容器 是否也可以设置开机自启动容器呢?

答案是 OKKKKK!

启动容器时,使用docker run命令时 添加参数--restart=always 便表示,该容器随docker服务启动而自动启动

ex:

docker run -itd --name redis002 -p 8888:6379 --restart=always  redis:5.0.5 /bin/bash

这个时候有小伙伴着急了,我都已经启动一个容器好久了,跑了很多数据了,现在才告诉我可以设置自启动?我把容器删了再启动,我数据咋办???

哎!小伙汁,这个时候不要慌,我告诉你两个办法!

我是红色

**方法一:担心数据丢了,这说明你在跑容器的时候没有进行数据挂载吧??? **

什么是数据挂载?

简单来讲,就是将容器内的数据与外部宿主机文件绑定起来,类似一个双持久化,当容器删除时,宿主机文件数据目录仍在,下次启动容器只要将数据目录指向宿主机数据所在位置即可恢复!

具体请参考:docker 文件分层与数据卷挂载

命令:

-v 宿主机文件存储位置(绝对路径):容器内文件位置

如此操作,就将 容器内指定文件挂载到了宿主机对应位置,-v命令可以多次使用,即一个容器可以同时挂载多个文件

-v 宿主机文件存储位置:容器内文件位置 -v 宿主机文件存储位置:容器内文件位置 -v 宿主机文件存储位置:容器内文件位置
-v 宿主机文件存储位置(绝对路径):容器内文件位置:只读(ro)/可写(rw)

容器中对应文件权限操作:ro: 只读,rw: 可读可写

示例:

# 运行一个docker redis容器进行端口映射 两个数据卷挂载(目录会自动创建) 设置开机自启动--restart=always  扩充权限--privileged=true redis密码(没有则不加)--requirepass "password" 

docker run -d -p 6379:6379 --name redis505 --restart=always --privileged=true -v /var/lib/redis/data/:/data -v /var/lib/redis/conf/:/usr/local/etc/redis/redis.conf  redis:5.0.5 --requirepass "password"

此方法完了你很无语?那还不是得删容器?是呀!没错!那么为什么你有数据恢复需求而没有想到数据持久化,数据恢复备份,数据卷挂载?自己DEMO的吃亏,是为了平时开发少扣脑壳多摸鱼!

方法二:不想删容器,又想让这个容器设置开机自启动,那么我们修改其启动配置即可!

命令:

docker  update --restart=always 容器Id 或者 容器名
或
docker container update --restart=always 容器Id 或者 容器名

如上,虽然不删容器就设置了自启动需求满足了,但是,危不危险,这个容器有没有需要数据恢复的情况?自己考量吧!!!

更换容器名

想给容器换个霸气炫酷吊炸天的名字?

docker rename 容器ID/容器名 新容器名

ex:

在这里插入图片描述

容器数据卷的继承

volumes-from: 表示继承父级容器的数据挂载方式

docker run -it --privileged=true --volumes-from 父级容器ID或名称 --name 当前容器名称 镜像名称:TAG

导出和导入容器

导出容器

如果要导出本地某个容器,可以使用 docker export 命令。

docker export 1e560fca3906 > ubuntu.tar

导出容器 1e560fca3906 快照到本地文件 ubuntu.tar。

在这里插入图片描述

这样将导出容器快照到本地文件。

导入容器快照

可以使用 docker import 从容器快照文件中再导入为镜像,以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1

 cat docker/ubuntu.tar | docker import - test/ubuntu:v1

在这里插入图片描述

此外,也可以通过指定 URL 或者某个目录来导入,例如:

docker import http://example.com/exampleimage.tgz example/imagerepo

检查 WEB 应用程序

使用 docker inspect 来查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。

docker inspect 容器ID或容器名
[
    {
        "Id": "bf08b7f2cd897b5964943134aa6d373e355c286db9b9885b1f60b6e8f82b2b85",
        "Created": "2018-09-17T01:41:26.174228707Z",
        "Path": "python",
        "Args": [
            "app.py"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 23245,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2018-09-17T01:41:26.494185806Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
......

(四)自己提交一个镜像

我们运行的容器可能在镜像的基础上做了一些修改,有时候我们希望保存起来,封装成一个更新的镜像,这时候我们就需要使用 commit 命令来构建一个新的镜像

docker commit -m="提交信息" -a="作者信息" 容器名/容器ID 提交后的镜像名:Tag

我们拉取一个tomcat镜像 并持久化运行 且设置与宿主机进行端口映射

docker pull tomcat

docker run -itd -p8080:8080 --name tom tomcat /bin/bash

访问 咱的端口 发现访问404 这是因为咱配置了阿里云镜像后 所拉取得镜像都是最基础班的 仅仅包含其容器必要数据 例如 容器中 vim vi ll 命令都没有
在这里插入图片描述

在这里插入图片描述

咱们的webapps 下一个文件都没有 ,访问肯定404罗

不断查看 发现咱 webapps.dist 下是有文件的 我们把它拷贝到webapps 下 然后打包成一个新的镜像 后 访问查看是否进入到首页 不进入404页面

在这里插入图片描述

exit 退出容器

使用 提交命令 将在运行的tomcat 容器 打包为一个全新的镜像 名字为tom Tag为1.0

docker commit -a="leilei" -m="第一次打包镜像,打包后直接访问还会404吗" 231f2eae6896 tom:1.0

在这里插入图片描述

为了区分 咱停止并删除之前tomcat 的容器
在这里插入图片描述

接下来 运行咱自己打包的镜像 tom:1.0

设置容器名字为lei 映射端口为6500:8080

docker run -d -it  -p6500:8080 --name lei tom:1.0 /bin/bash

在这里插入图片描述

在这里插入图片描述

访问6500 端口进入到了 tomcat 首页 说明 咱commit 镜像成功了

(五)docker搭建私服仓库

概述:
看到这里可能会有人觉得以为不是有类似dockerhub,啊里云等公共镜像仓库吗,为啥还有构建私有仓库,因为在企业开发当中有些会涉及机密问题所以很有必要构建一个私服仓库提供企业项目的开发团队共同使用,我们可以用docker register官方提供的工具搭建私有镜像仓库

**1.**下载docker registry镜像,如果本地没有可以使用docker pull registry命令进行下载

在这里插入图片描述

**2.**运行registry镜像相当于本地拥有一个dockerhub仓库,具体的命令解释可参考上一篇的docker基础命令详解文章,这里我就不解释了

docker run -d -p 5000:5000 -v /root/hyx/myregistry/:/tmp/registry --privileged=true registry

在这里插入图片描述

**3.**运行registry之后,我们可以查看一下刚才搭建的私服仓库中有什么镜像。

curl -XGET http://192.168.79.129:5000/v2/_catalog
 
//【虚拟机】ip就是仓库所在机器的ip,端口5000就是上面运行registry镜像容器暴露的端口

在这里插入图片描述

**4.**尝试将本地镜像发布到registry

本次我们选择mydockerpro:1.1这个镜像进行演示发布,在将本地镜像发布到registry之前,我们先把镜像修改为符合私服仓库的规范Host:Port/Repository:Tag,修改命令如下

docker tag mydockerpro:1.1  192.168.79.129:5000/mydockerpro:1.1

在这里插入图片描述

**5.**改为/etc/docker/daemon.json配置文件,加入如下内容使其支持http,因为docker默认不支持http方式推送镜像,我们可以加入改配置让docker取消这个限制,配置完然后重启docker服务。

"insecure-registries":["192.168.79.129:5000"]

在这里插入图片描述

**6.**推送本地镜像mydockerpro到私服仓库当中

docker push 192.168.79.129:5000/mydockerpro:1.1
//格式
docker push 镜像名称:Tag

在这里插入图片描述

**7.**使用curl -XGET http://192.168.79.129:5000/v2/_catalog查看私服仓库是否有我们刚才推送的mydockerpro镜像

在这里插入图片描述

**8.**删除之前留下的mydockerpro镜像然后重新去私服仓库pull ,看下是否可以pull成功

在这里插入图片描述

在这里插入图片描述

**9.**尝试运行刚从私服仓库pull的镜像
在这里插入图片描述

经过漫长的九个步骤搭建,私服仓库算是基本完成了,从私服仓库的搭建,推送本地镜像到私服仓库,从私服仓库拉取镜像,总体而言搭建起来还是比较简单!!!

docker常见问题及解决方式

Docker挂载主机目录访问如果出现cannot open directory: Permission denied

**解决办法:**在挂载目录后多加一个–privileged=true参数即可


docker安装mysql8

1、创建容器数据挂载目录,使mysql数据持久化

#docker部署mysql8全部步骤;
#1. 拉取镜像
docker pull mysql:8.0.27
#2. 创建临时容器(名称为mysql)
docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.27
#3. 创建mysql容器的数据挂载目录(数据持久化)
mkdir -p /data/docker/mysql8/data
mkdir -p /data/docker/mysql8/logs
#4. 复制mysql容器的配置到本地,并修改目录名
cd /data/docker/mysql8
docker cp mysql:/etc/mysql ./
mv mysql conf
#5. 删除临时镜像(名称为mysql,也可指定镜像ID)
docker rm -f mysql

2、创建正式mysql8容器

#6. 创建正式mysql8.0容器
docker run -d -p 3306:3306 --name mysql8 -v /data/docker/mysql8/conf:/etc/mysql -v /data/docker/mysql8/logs:/var/log/mysql -v /data/docker/mysql8/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --privileged=true --restart=always mysql:8.0.27

#命令解释
-d  以守护进程方式启动(后台启动)
-p 端口映射, 宿主机端口:docker容器端口
--privileged=true  挂载文件权限设置
--restart=always  设置开机后自动重启容器
-v /data/docker/mysql8/conf:/etc/mysql      挂载mysql配置文件
-v /data/docker/mysql8/logs:/var/log/mysql      挂载日志
-v /data/docker/mysql8/data:/var/lib/mysql   挂载数据文件,持久化到主机,
-v /etc/localtime:/etc/localtime    容器时间与宿主机同步
-e MYSQL_ROOT_PASSWORD=123456    设置mysql密码

3、设置容器中mysql参数配置

设置root用户外网可访问权限(此步骤可跳过),docker中mysql的root用户默认可访问外网

#7. 进入容器
docker exec -it mysql8 /bin/bash
#8. 进入mysql终端
mysql -uroot -p123456
#9. 设置root账户外网可访问或修改root用户密码
use mysql;    # 切换到mysql数据库
select host,user from user;   # 查看用户及其可访问主机, root对应host
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';  #修改root用户访问权限及密码
flush privileges;  # 刷新权限
select host,user from user;  # 再次查看用户及其可访问主机,root对应host应为‘%’
#10. 退出
exit
exit

设置mysql配置参数

修改挂载到本地的日志目录的权限

chown -R 999:999 /data/docker/mysql8/logs
#11. 编辑mysql.cnf
vi /data/docker/mysql8/conf/conf.d/mysql.cnf
#12. mysql.cnf文件插入utf-8编码内容
[client]
default-character-set=utf8mb4    

[mysql]
default-character-set=utf8mb4    
 
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci

skip-character-set-client-handshake
skip-name-resolve    #禁用dns解析,避免网络DNS解析服务引发访问MYSQL的错误,一般应当启用。

#skip_log_bin   # 注释日志文件,关闭日志功能,不记录日志
binlog_expire_logs_seconds=2592000 #默认保留30天,超过30天的binlog删除
log-error=/var/log/mysql/error.log    #错误日志路径
slow_query_log=1    # 启动慢查询
long_query_time=3   #慢查询时间 超过3秒则为慢查询
slow_query_log_file=/var/log/mysql/mysql-slow.log
log-queries-not-using-indexes

#13. 保存退出
esc
:wq!
#14. 再次查看mysql字符编码(进入mysql容器,并通过mysql交互式窗口使用该命令)
show variables like 'character%';
# 如果挂载成功,所有的字符都会变为utf8

docker配置mysql主从复制(一主一从)

1.新建主服务器容器实例3307(一主)

docker run -d -p 3307:3306 --name mysql-master -e MYSQL_ROOT_PASSWORD=123456 --privileged=true --restart=always -v /data/docker/mysql-master/conf:/etc/mysql -v /data/docker/mysql-master/logs:/var/log/mysql -v /data/docker/mysql-master/data:/var/lib/mysql -v /data/docker/mysql-master/mysql-files:/var/lib/mysql-files/ mysql:8.0.27

2.进入/data/docker/mysql-master/conf目录下新建my.cnf文件

touch /data/docker/mysql-master/conf/my.cnf

3.在my.cnf文件中添加如下参数信息:

[client]
default-character-set=utf8mb4    

[mysql]
default-character-set=utf8mb4    

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci

server-id=101    #表示是主服务器server-id,必须保持唯一
binlog-ignore-db=mysql     # 不需要主从同步的数据库名称
log-bin=mysql-bin       # 开启二进制日志功能
log-error=/var/log/mysql/error.log    #错误日志路径
binlog_cache_size=1M    # 设置二进制日志使用内存大小。默认binlog_cache_size大小32K
binlog_format=mixed    # 设置使用的二进制日志格式(mixed,statement,row)
binlog_expire_logs_seconds=2592000 #超过30天的binlog删除
# 跳过主从复制遇到的所有错误或指定类型的错误,避免slave端复制中断,如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
replica_skip_errors=1062

修改挂载到本地的日志目录的权限

chown -R 999:999 /data/docker/mysql-master/logs

4.修改完配置后,重启master实例

docker restart mysql-master

5.进入master容器实例,通过交互式客户端登录

docker exec -it mysql-master /bin/bash

登录root用户,(第一次登录密码为空,不需要输入,直接按回车就行)

mysql -uroot -p123456

**注意:**若未启动,请使用docker logs -f mysql-master查看mysql-master启动日志,查找报错原因

6.修改root用户密码和更新权限(若第一次则需要,否则可跳过)

grant all privileges on *.* to 'root'@'%' with grant option;      //root用户授权
ALTER USER 'root'@'%' IDENTIFIED BY '123456' PASSWORD EXPIRE NEVER;    //更新加密规则:
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';   //更新root用户密码:
flush privileges;

7.再次登录,使用新密码即可

8.创建slaver用户,并授予权限

create user 'slaver'@'%' identified with mysql_native_password by '123456';
grant replication slave, replication client on *.* to 'slaver'@'%' with grant option;
flush privileges;

replication client:授予此权限,复制用户可以使用 SHOW MASTER STATUS, SHOW SLAVE STATUS和 SHOW BINARY LOGS来确定复制状态。

replication slave:授予此权限,复制才能真正工作。

一般复制账号需要以上两个权限。

14.进入主数据库master,查看主mysql服务状态

show master status;

在这里插入图片描述

记录上图中MASTER_LOG_FILE 和 MASTER_LOG_POS

退出mysql客户端和mysql-mater容器

exit
exit

9.创建从服务器容器实例3308(一从)

docker run -d -p 3308:3306 --name mysql-slaver -e MYSQL_ROOT_PASSWORD=123456 --privileged=true --restart=always -v /data/docker/mysql-slaver/conf:/etc/mysql -v /data/docker/mysql-slaver/logs:/var/log/mysql -v /data/docker/mysql-slaver/data:/var/lib/mysql -v /data/docker/mysql-slaver/mysql-files:/var/lib/mysql-files/ mysql:8.0.27

10.进入/data/docker/mysql-slaver/conf目录下新建my.cnf文件

touch /data/docker/mysql-slaver/conf/my.cnf

11.在my.cnf文件中添加如下参数信息:

[client]
default-character-set=utf8mb4    

[mysql]
default-character-set=utf8mb4    

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci

server-id=102    #表示是从服务器server-id,同一局域网中必须保持唯一
binlog-ignore-db=mysql     # 不需要主从同步的数据库名称
log-bin=mysql-slave-bin       # 开启二进制日志功能,热备:当master挂掉后,可能作为新的master时使用
log-error=/var/log/mysql/error.log    #错误日志路径
binlog_cache_size=1M    # 设置二进制日志使用内存大小。默认binlog_cache_size大小32K
binlog_format=mixed    # 设置使用的二进制日志格式(mixed,statement,row)
binlog_expire_logs_seconds=2592000 #超过30天的binlog删除
# 跳过主从复制遇到的所有错误或指定类型的错误,避免slave端复制中断,如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
replica_skip_errors=1062
#relay_log配置中继日志
relay_log=mysql-relay-bin
# log_slave_updates表示slave将复制事件写进自己的二进制日志中
log_slave_updates=1
# slave设置为只读(具有super权限的用户除外)
read_only=1

修改挂载到本地的日志目录的权限

chown -R 999:999 /data/docker/mysql-slaver/logs

12.修改完配置后,重启master实例

docker restart mysql-slaver

13.进入slaver容器实例,通过交互式客户端登录

docker exec -it mysql-slaver /bin/bash

登录root用户,

mysql -uroot -p123456

15.进入从数据库slaver,在从数据库中配置主从复制

change master to
MASTER_HOST='192.168.10.145',       
MASTER_PORT=3307,
MASTER_USER='slaver',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=156;

MASTER_HOST: 主服务器ip

MASTER_PORT: 主服务端口号

MASTER_USER:主从用户名

MASTER_PASSWORD:主服务密码

MASTER_LOG_FILE:主服务日志文件

MASTER_LOG_POS:主服务日志开始位置

16.开启主从同步

start slave;

17.查看从机状态

show slave status\G   # (G后面不要加分号)

docker安装redis

一、拉取镜像

//拉取最新版本
docker pull redis
//拉取指定版本
docker pull redis:6.0.8

查看镜像

docker images

在这里插入图片描述

二、准备redis的配置文件

因为需要redis的配置文件,这里最好还是去redis的官方去下载一个redis使用里面的配置文件即可

redis中文官方网站:http://www.redis.cn/download.html

在这里插入图片描述

下载后解压出来:

在这里插入图片描述

这个redis.conf文件就是咱们需要的,为了保险,还是拷贝一下,做个备份。

三、配置redis.conf配置文件

修改redis.conf配置文件:
主要配置的如下:

#bind 127.0.0.1 #注释掉这部分,使redis可以外部访问

protected-mode no #关闭protected-mode模式,此时外部网络可以直接访问,默认为yes

daemonize no #用守护线程的方式启动
appendonly yes #redis持久化  默认是no

requirepass 密码 #给redis设置密码(可不设置此参数,默认无密码)

redis.conf中需要修改的参数如下:

# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
#bind 127.0.0.1

protected-mode no	
daemonize no
requirepass 密码   # 可不设置,默认无密码
appendonly yes

若需要修改其他参数(如port等),请参考redis.conf参数配置

四、创建本地与docker映射的目录,即本地存放的位置

创建本地存放redis的位置;

# 创建目录
mkdir -p /data/docker/redis/conf

配置文件redis.conf拷贝到刚才创建好的目录里

如果本身就是Linux操作系统,可以直接拷贝过去,如果是windows的话,可能需要使用ftp等工具拷贝过去,或者直接复制内容,然后粘贴过去。

五、启动docker redis

docker run -d -p 6379:6379 --name redis --privileged=true --restart always -v /data/docker/redis/conf/redis.conf:/etc/redis/redis.conf  -v /data/docker/redis/data:/data  redis:6.0.8 redis-server /etc/redis/redis.conf 

参数解释:

-p 6379:6379:把容器内的6379端口映射到宿主机6379端口
-v /data/redis/redis.conf:/etc/redis/redis.conf:把宿主机配置好的redis.conf放到容器内的这个位置中
-v /data/redis/data:/data:把redis持久化的数据在宿主机内显示,做数据备份
redis-server /etc/redis/redis.conf:这个是关键配置,让redis不是无配置启动,而是按照这个redis.conf的配置启动
–appendonly yes:redis启动后数据持久化

--requirepass "123456" 设置密码为"123456"

查看是否运行成功

docker ps

在这里插入图片描述

可以查看一下日志: docker logs -f redis

六、进入有密码的Redis控制台

# 进入Redis容器
docker exec -it redis /bin/bash
 
# 通过密码进入Redis控制台, (如无密码,则不使用该参数 -a 密码)
redis-cli -h 127.0.0.1 -p 6379 -a 123456

在这里插入图片描述

docker配置redis集群(三主三从)

一、3主3从集群配置步骤

1、关闭防火墙+启动docker后台服务

systemctl start docker

2、新建6个docker容器redis实例

docker run -d --name redis-node-1 --net host  --privileged=true  -v /data/redis/share/redis-node-1:/data  redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381

docker run -d --name redis-node-2 --net host --privileged=true  -v /data/redis/share/redis-node-2:/data  redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382 

docker run -d --name redis-node-3 --net host  --privileged=true  -v /data/redis/share/redis-node-3:/data  redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383

docker run -d --name redis-node-4 --net host --privileged=true  -v /data/redis/share/redis-node-4:/data  redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384 

docker run -d --name redis-node-5 --net host --privileged=true  -v /data/redis/share/redis-node-5:/data  redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385 

docker run -d --name redis-node-6 --net host --privileged=true  -v /data/redis/share/redis-node-6:/data  redis:6.0.8 --cluster-enabled yes --appendonly yes  --port 6386

参数解释:
docker run 创建并运行docker容器实例
–name redis-node-1 容器名字
–net host 使用宿主机的IP和端口,默认
–privileged=true 获取宿主机root用户权限
-v /data/redis/share/redis-node-1:/data 容器卷,宿主机地址:docker内部地址
redis:6.0.8 redis镜像和版本号
–cluster-enabled yes 开启redis集群
–appendonly yes 开启持久化
–port 6381 redis端口号

如果运行成功,效果如下:

在这里插入图片描述

3、进入容器redis-node-1并为6台机器构建集群关系

进入容器:

docker exec -it redis-node-1 /bin/bash

构建主从关系:

redis-cli --cluster create 192.168.10.147:6381 192.168.10.147:6382 192.168.10.147:6383 192.168.10.147:6384 192.168.10.147:6385 192.168.10.147:6386 --cluster-replicas 1

#参数解释:
#192.168.10.147  当前宿主机ip
#--cluster-replicas 1 表示为每个master创建一个slave节点

如果运行成功,效果如下图:

在这里插入图片描述

在这里插入图片描述

4、链接进入6381作为切入点,查看集群状态

# 查看集群状态
redis-cli --cluster check 192.168.203.128:6381
# 连接6381 redis服务
redis-cli -p 6381

查看集群状态:

cluster info     # 查看集群状态
cluster nodes    # 查看节点

效果如下图:

在这里插入图片描述

在这里插入图片描述

二、主从容错切换迁移案例

1、数据读写存储,启动6机构成的集群

由于数据存储在hash槽中,而每个节点的hash槽范围不同(即每个节点只能与存储hash槽对应的数据)

因此在进入集群时,需要加上参数-c,表示启动集群

注意:这里不能使用访问节点的命令,而应该是访问集群,因此需要加上参数-c

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

查看集群状态:

redis-cli --cluster check 192.168.203.128:6381

效果如下图:

在这里插入图片描述

2、容错切换迁移

主6381和从机切换,先停止主机6381,对应的真实从机上位,成为master节点,效果如下图:

在这里插入图片描述

在这里插入图片描述

还原三主三从,查看集群状态,恢复的节点会以从节点的形势存在集群中,效果如下图

在这里插入图片描述

三、主从扩容案例

1、新建6387、6388两个节点

docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6387

docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388
docker ps    # 查看当前容器实例

效果如下图:

在这里插入图片描述

2、进入6387容器实例内部

docker exec -it redis-node-7 /bin/bash

3、将新增的6387节点(空槽号)作为master节点加入原集群

redis-cli --cluster add-node 192.168.203.128:6387 192.168.203.128:6381

效果如下图:

在这里插入图片描述

进入容器,查看集群状态

docker exec -it redis-node-1 /bin/bash     # 进去6381容器
redis-cli --cluster check 192.168.203.128:6381    # 查看集群状态

在这里插入图片描述

4、重新分派槽号

进入容器

docker exec -it redis-node-1 /bin/bash     

重新分配槽号

redis-cli --cluster reshard 192.168.203.128:6381

执行上面命令有三个地方需要输入:

  • how many slots do you want to move (from 1 to 16384)? 4096 (这个值是通过 16384 / 4 = 4096 得到的)16384表示所有hash槽数量,4表示master节点数量
  • what is the receiving node ID? 6387的ID
  • Source node #1: all
  • 输入yes

在这里插入图片描述

查看集群状态

redis-cli --cluster check 192.168.203.128:6381

在这里插入图片描述

注意:为什么6387是3个新的区间,以前的还是连续?
重新分配成本太高,所以前3家各自匀出来一部分,从6381/6382/6383三个旧节点分别匀出1364个坑位给新节点6387

5、为主节点6387分配从节点6388

redis-cli --cluster add-node 192.168.203.128:6388 192.168.203.128:6387 --cluster-slave --cluster-master-id 3edde5ba512ac753688e990d283fbb4cf0ed389b
cluster-master-id值是6387的ID,按照自己实际情况

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

四、主从缩容案例(目的让6387和6388下线)

1、检查集群情况1获得6388的节点ID

在这里插入图片描述

2、从集群中将4号从节点6388删除

redis-cli --cluster del-node 192.168.203.128:6388 ef935c6357e8f1cf024204bac3860e1928fe9dcb

效果如图下:

在这里插入图片描述

检查集群:

redis-cli --cluster check 192.168.203.128:6381

在这里插入图片描述

3、将6387的槽号清空,重新分配,本例将清出来的槽号都给6381

redis-cli --cluster reshard 192.168.203.128:6381

在这里插入图片描述

在这里插入图片描述

4、检查集群情况

在这里插入图片描述

5、将6387删除

redis-cli --cluster del-node 192.168.203.128:6387 3edde5ba512ac753688e990d283fbb4cf0ed389b

在这里插入图片描述

6、查看集群情况

在这里插入图片描述

至此docker环境下配置redis3主3从集群配置,实现主从容错、主从扩容、主从缩容已完结。

Dockerfile编写和使用

Dockerfile是用来构建docker镜像的文件,是一个命令参数脚本。DockerFile是面向开发的,发布项目的时候需要做镜像,就要编写dockerfile文件。如果对docker还不太了解的小伙伴,请先移步浅谈Docker

构建步骤:

  1. 编写一个dockerfile文件
  2. docker build 构建一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub、阿里云从仓库等)

Dockerfile基础知识

1、每个指令都必须是大写字母;

2、执行顺序从上到下;

3、#表示注释;

4、每一个指令都会提交一个新的镜像层,并提交。

# DockerFile常用指令 
FROM # 基础镜像,一切从这里开始构建,如果本地不存在基础镜像,则首先从DockerHub拉去下来。
MAINTAINER # 镜像的作者姓名+邮箱 
RUN # 镜像构建的时候需要运行的命令 
ADD # 拷贝文件(支持正则表达式)到镜像,并自动解压(如果是压缩包) 
WORKDIR # 默认的镜像工作目录 
VOLUME # 挂载的目录 运行时会在会随机在宿主机的目录下生成一个卷目录,该命令只能定义docker管理的卷。如果要实现指定路径形式的挂载,需要在创建好镜像以后用 docker run -v aaa:bbb 的方式指定。
EXPOSE # 保留端口配置,为容器打开指定的要监听的端口以实现与外部通信,但通过这种方式,宿主机每次与容器映射的端口是随机的,也可以在 docker run -p 8888:80 进行端口的映射绑定。
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。 
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令,用法和 CMD 相似,但是我们可以在 docker run 后面追加参数,会作为 ENTRYPOINT 的参数,即不会被覆盖。如果 docker run 后面没有额外的东西,但是 CMD 有,那么cmd的全部内容会作为 entrypoint 的参数。
COPY # 类似ADD,将我们文件拷贝到镜像中 
ENV # 构建的时候设置环境变量!并可以被Dockerfile中位于其后面的其他命令调用

示例

1.准备

首先是先有一个可执行的jar包,然后再创建一个Dockerfile文件,目录结构为下:

在这里插入图片描述

2.编写Dockerfile

在Dockerfile按自己需求编写内容,我的web-ssh程序的Dockerfile文件内容如下:

FROM openjdk:8-jdk
 
MAINTAINER username: lijunpeng, email: 1635975742@qq.com
 
RUN mkdir -p /usr/local/web-ssh
 
COPY ./lib/web-ssh-1.0.5.jar /usr/local/web-ssh
 
WORKDIR /usr/local/web-ssh
 
EXPOSE 8080
 
CMD ["java", "-jar", "web-ssh-1.0.5.jar"]

3.执行Dockerfile,构建镜像

进入到含有Dockerfile的目录下,执行下面的命令进行镜像的构建:

# -f 指定Dockerfile文件,可省略,默认寻找当前目录下的Dockerfile文件
# -t 指定镜像名和版本
# .  指定运行时根目录,意思是Dockerfile内的绝对目录都是以这里为基本
docker build -f Dockerfile -t web-ssh:1.0.5 .

命令执行完不报错就说明完成啦。

4.运行镜像,创建容器实例

# 查看构建的镜像
docker images
 
# 运行镜像
docker run -d -t --name ssh -p 8080:8080 web-ssh:1.0.5
 
# 查看已运行的容器
docker ps

docker network使用

使用docker network 很方便的维护和管理docker网络,方便容器之间ip和端口交互。

1、docker network 相关命令

使用network网络配置,使得各容器之间可以相互通信

docker network --help    # 查看docker network相关命令
  • connect 将某个容器连接到一个docker网络
  • create 创建一个docker局域网络
  • disconnect 将某个容器退出某个局域网络
  • inspect 显示某个局域网络信息
  • ls 显示所有docker局域网络
  • prune 删除所有未引用的docker局域网络
  • rm 删除docker网络

2、创建自定义docker局域网络

docker network create mynet    # 创建自定义docker网络 mynet

然后pull两个镜像使用新创建的网络

3、pull镜像和运行镜像

拉取镜像

docker pull redis
docker pull nginx
#运行redis容器
docker run -d --name redis --network mynet --privileged=true -p 6379:6379 redis
#运行nginx容器
docker run -d --name nginx -p 80:80 --network mynet --privileged=true -v /home/wwwroot:/home/wwwroot -v /home/wwwlogs:/home/wwwlogs  nginx

注意:docker容器内部的ip可能会发生变化,因此使用network名称进行映射

–network mynet:容器运行在名称为mynet的网络中,保证同一网络下的容器之间可以通信

4、docker 查询网络信息

#查看mynet的详细信息,发现redis和nginx已在Containers容器内,属于当前mynet网络
[root@localhost /]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "8453b7b1d246f1ad54e27033928bbb8e7842ca96b4315fad720688af206b69c6",
        "Created": "2020-12-13T22:50:55.566207522-08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {
            "87ff63bb819a823578bed89a67527009d9fee31a92de9d50e5d635b97cc18664": {
                "Name": "redis",
                "EndpointID": "19a04279300025dc936d206a287b1e31d04b339298b445694452a5f4326f7051",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "c75ff4ac770fd04a1c6daa05a82533555038e3b0f8e15c3b1ee29e26c14a0131": {
                "Name": "nginx",
                "EndpointID": "4ccc014edcfd7be443c75491cc32aa0745561cfd45903e204e8d3e7afa94a4fe",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

5、验证ping命令是否容器之间网络交互

#进入redis命令行,使用ping nginx命令验证能够连接成功
#使用ping命令之前,需要给docker安装ping,请自行百度
docker exec -it redis bash
ping nginx

同样也可以不指定网络,直接启动容器,然后使用docker network connect接入网络。

#将容器删掉重新创建
docker stop nginx
docker rm -f nginx
docker stop redis
docker rm -f redis

6、使用docker network connect接入网络

#运行nginx和docker容器
docker run -itd --name redis -p 6379:6379 redis
docker run -d --name nginx -p 80:80 --privileged=true -v /home/wwwroot:/home/wwwroot -v /home/wwwlogs:/home/wwwlogs nginx    

使用docker network connect命令连接网络

docker network connect 网络名 容器名
#加入nginx到mynet网络
docker network connect mynet nginx
#加入redis到mynet网络
docker network connect mynet redis
#查看mynet网络包含的容器,会发现两个容器都加入当前网络了,后面使用ping命令是能够ping通容器名称的。
docker network inspect mynet

7、将容器移除network网络

#将nginx移除mynet局域网络
docker network disconnect mynet nginx

docker Compose容器编排

1、docker Compose概述

现有 docker 进行项目部署存在的问题

1、为了完成一个完整项目势必用到N多个容器(一个容器只运行一个进程)配合完成项目中业务开发,一旦引入N多个容器,容器之间就会形成某种依赖,也就意味某个容器或某些容器的运行需要其他容器优先启动之后才能正常运行。容器的编排显得至关重要,容器的运行一定要有先后顺序。

2、现在这种方式使用容器,没有办法站在项目的角度将一个项目用到的一组容器划分到一起,日后难点在于项目的多服务器部署。比如项目在当前服务器上运行成功,需要将项目再部署到另一台服务器上,但我们不清楚哪组容器是项目引用的,哪组容器是别的引用的。

Docker Compose 简介

负责对docker 容器集群的快速编排,可以管理多个docker容器组成一个应用。因此,需要定一个YAML格式的配置文件docker-compose.yml, 写好多个容器之间的调用顺序。然后,只要一个命令,就能同时启动/关闭这些容器。

Compose 使用的三个步骤

1、使用 Dockerfile 定义应用程序的环境。

2、使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。

docker-compose.yml 的配置案例如下:

#第一层 版本号
version: "3.8"  #代表使用docker-compose项目的版本号
#第二层:services 服务配置
services:
  web:
    build: .
    ports:  #宿主机和容器的端口映射
      - "5000:5000"
    volumes:
      - .:/code
  redis:
     image: "redis:alpine"
# 第三层 其他配置 网络、卷、全局规划
volumes:
  logvolume01: {}

3、最后,执行 docker-compose up 命令来启动并运行整个应用程序。

Compose 允许用户通过一个单独的 docker-compose.yml 模板文件(YAML格式)来定义一组相关联的容器为一个项目(project)。

2、Docker Compose 安装与卸载

注意:compose版本需要与docker版本对应 (推荐使用3.x版本)

docker-compose 版本和 docker 版本的对应关系:

docker-compose 版本docker 版本
3.819.03.0+
3.718.06.0+
3.618.02.0+
3.517.12.0+
3.417.09.0+
3.317.06.0+
3.217.04.0+
3.11.13.1+
3.01.13.0+
2.417.12.0+
2.317.06.0+
2.21.13.0+
2.11.12.0+
2.01.10.0+

2.1、安装

注意:只有 Linux 平台上在安装docker时没有安装docker-compose,windows、macos平台安装docker时会自动安装docker-compose。

Linux 在线安装 docker-compose

1、下载 docker-compose文件:

国内镜像加速下载地址——快:

sudo curl -L "https://get.daocloud.io/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

在这里插入图片描述

2、赋予执行权限:

sudo chmod +x /usr/local/bin/docker-compose

3、查看docker compose版本

docker-compose --version

Linux 离线安装 docker-compose

1、下载 docker-compose安装包

2、放入 /usr/local/bin 目录下

3、赋予执行权限:

sudo chmod +x /usr/local/bin/docker-compose

3、查看docker compose版本

docker-compose --version

2.2、卸载

rm /usr/local/bin/docker-compose

3、Compose 模板文件指令

模板文件是使用 Docker Compose 的核心,涉及到的指令关键字也比较多。默认的模板文件名称为 docker-compose.yml ,格式为YAML 格式。一个 docker-compose.yml 文件可以分为三层:

#第一层 版本号
version: "3.8"  #代表使用docker-compose项目的版本号
#第二层:services 服务配置
services:
  web:        # 容器名称
    build: .
    ports:  #宿主机和容器的端口映射
      - "5000:5000"
    volumes:   # 数据卷,将容器中的指定目录映射到宿主机指定目录,实现数据持久化
      - .:/code
    networks:      # 指定网络
      - dev-network
  redis:      # 容器名称
     image: "redis:alpine"    # 使用的镜像
     networks:      # 指定网络
      - dev-network
  mysql:
    image: mysql:latest
    restart: always   # 重启策略
    command: --default-authentication-plugin=mysql_native_password # 解决外部无法访问的问题
    networks:      # 指定网络
      - dev-network
    ports:
      - "3306:3306"
    environment:       # 环境变量
      MYSQL_ROOT_PASSWORD: abc123
      MYSQL_USER: 'test'
      MYSQL_PASS: 'test'
    volumes:       # 数据卷,将容器中的指定目录映射到宿主机目录,实现数据持久化
      - mysql_data:/var/lib/mysql 
# 第三层 其他配置 网络、卷、全局规划
volumes:
  logvolume01: {}
networks:   #创建网络
  dev-network:

build 指令

指定 Dockerfile 所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像。

version: "3.8" 
services:
  web:
    build: .  #指定Dockerfile的上下文目录为当前目录

你也可以使用 context 指令指定 Dockerfile 所在文件夹的路径。

使用 dockerfile 指令指定 Dockerfile 文件名。

使用 arg 指令指定构建镜像时的变量。

version: '3'
services:
  webapp:
    build:
      context: ./dir    #定义Dockerfile的上下文目录为当前目录的dir目录下
      dockerfile: Dockerfile-alternate
      args: 
        buildno: 1

command 指令

覆盖容器启动后默认执行的命令,类似于docker run image 命令

以下面的Dockerfile文件为例,容器启动后执行的是 java -jar apps.jar

FROM openjdk:8-jre
EXPOSE 8081
ENV APP_PATH=/apps
WORKDIR $APP_PATH
COPY apps.jar $APP_PATH
ENTRYPOINT ["java","-jar"]
CMD ["apps.jar"]

如果我们想要容器启动后执行的是 java -jar test.jar,在docker-compose.yml文件中使用指令 command: [“test.jar”]

version: '3'
services:
  webapp:
    build:
      context: ./dir #定Dockerfile的上下文目录为当前目录的dir目录下
      dockerfile: Dockerfile-alternate
      args: 
        buildno: 1
    command: ["test.jar"]

container_name 指令(不推荐使用)

指定容器名称。默认将会使用 项目名称_服务名称_序号 这样的格式。

container_name: docker-web-container

注意: 指定容器名称后,该服务将无法进行扩展(scale),因为 Docker 不允许多个容器具有相同的名称。

depends_on 指令

解决容器的依赖、启动先后的问题。以下例子中会先启动 redisdb 再启动 web

version: '3'

services:
  web:
    build: .
    depends_on: # web服务依赖于db和web服务
      - db
      - redis

  redis:
    image: redis

  db:
    image: postgres

注意:在启动web服务时,并不会等待 redisdb 服务进入ready状态,而只是等到它们被启动状态(running状态)了。

environment 指令

设置环境变量,相当于 docker run -e。你可以使用数组或字典两种格式。

只给定名称的变量会自动获取运行 Compose 主机上对应变量的值,可以用来防止泄露不必要的数据。

version: '3'

services:
  mysql:
    image: mysql:5.7
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root  #字典格式
    command: --default-authentication-plugin=mysql_native_password #这行代码解决无法访问的问题
#====================================================
    environment:
      - "MYSQL_ROOT_PASSWORD=root"  #数组格式
      - "SESSION_SECRET"

env_file 指令

从文件中获取环境变量,可以为单独的文件路径或列表。

如果通过 docker-compose -f FILE 方式来指定 Compose 模板文件,则 env_file 中变量的路径会基于模板文件路径。

如果有变量名称与 environment 指令冲突,则按照惯例,以 environment 为准。

env_file: .env

env_file: #指定多个环境变量文件
  - ./common.env
  - ./.env
  - /opt/secrets.env

环境变量文件中每一行必须符合格式,支持 # 开头的注释行。

环境变量文件 .env:推荐使用这种命名,因为在Linux下,这种方式命名的文件属于隐藏文件,一定程度上防止泄露不必要的数据。

MYSQL_ROOT_PASSWORD=root

expose 指令

用来指定镜像构建过程中容器暴露的端口号,但不映射到宿主机,只被连接的服务访问。

该指令compose配置文件中一般不用,都在Dockerfile文件中使用EXPOSE指定。

image 指令

指定为镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉取这个镜像,相当于 docker run image(镜像名)。

ports 指令

指定宿主机和容器端口映射,或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。

注意:当使用 HOST:CONTAINER格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为YAML会自动解析xx:yy这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。例如:“3306:3306”

networks 指令

指定启动容器时使用的网络,相当于 docker run --network

version: "3"
services:

  some-service:
    networks:
     - some-network  #指定使用的网络
     - other-network

networks:   #创建网络
  some-network:
  other-network:

volumes 指令

用来指定宿主机目录和容器目录映射

version: "3"

services:
  my_src:
    image: mysql:8.0
    volumes:  #数据卷名称挂载
      - mysql_data:/var/lib/mysql

volumes:  #定义数据卷名称
  mysql_data:

restart 指令

指定容器退出后的重启策略为始终重启。该命令对保持服务始终运行十分有效。

restart: always

4、Docker-Compose 常用命令

4.1、命令对象与格式

对于 Compose 来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的服务或者容器。如果没有特别的说明,命令对象将是项目,这意味着项目中所有的服务都会受到命令影响。

执行 docker-compose [COMMAND] --help 或者 docker-compose help [COMMAND] 可以查看具体某个命令的使用格式。

docker-compose 命令的基本的使用格式是

docker-compose [-f=<arg>...] [options] [COMMAND] [ARGS...]

命令选项说明:

-f, --file FILE 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定。

-p, --project-name NAME 指定项目名称,默认将使用所在目录名称作为项目名。

--verbose 输出更多调试信息。

-v, --version 打印版本并退出。

4.2、命令使用说明

up

  • 该命令十分强大,它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。
  • 链接的服务都将会被自动启动,除非已经处于运行状态。
  • 可以说,大部分时候都可以直接通过该命令来启动一个项目。
  • 默认情况,docker-compose up 启动的容器都在前台,控制台将会同时打印所有容器的输出信息,可以很方便进行调试。
  • 当通过 Ctrl-C 停止命令时,所有容器将会停止。
  • 如果使用 docker-compose up -d,将会在后台启动并运行所有的容器。一般推荐生产环境下使用该选项。
  • 如果服务容器已经存在,docker-compose up 将会尝试停止容器,然后重新创建(保持使用 volumes-from 挂载的卷),以保证新启动的服务匹配 docker-compose.yml 文件的最新内容。
  • 当使用 docker-compose up 服务id,就是对当前项目中的容器服务进行操作

命令格式为 :

docker-compose up [options] [SERVICE...]

选项说明:

  • -d 在后台运行服务容器。
  • --no-color 不使用颜色来区分不同的服务的控制台输出。
  • --no-deps 不启动服务所链接的容器。
  • --force-recreate 强制重新创建容器,不能与 --no-recreate 同时使用。
  • --no-recreate 如果容器已经存在了,则不重新创建,不能与 --force-recreate 同时使用。
  • --no-build 不自动构建缺失的服务镜像。
  • -t, --timeout TIMEOUT 停止容器时候的超时(默认为 10 秒)。

down

docker-compose down

此命令将会停止 up 命令所启动的容器,并移除网络,但不会移除数据卷。

docker-compose down 服务id

停止某个服务。

exec

docker-compose exec 服务id /bin/bash

ps

列出项目中目前的所有容器。

docker-compose ps [options] [SERVICE...]

选项说明:

  • -q 只打印容器的 ID 信息。

restart

重新启动所有已停止并正在运行的服务。

docker-compose restart [options] [SERVICE...]

选项:

  • -t, --timeout TIMEOUT 指定重启前停止容器的超时(默认为 10 秒)。

rm

删除所有(停止状态的)服务容器。推荐先执行 docker-compose stop 命令来停止容器。

docker-compose rm [options] [SERVICE...]

选项:

  • -f, --force 强制直接删除,包括非停止状态的容器。一般尽量不要使用该选项。
  • -v 删除容器所挂载的数据卷。

top

查看项目中各个服务容器内运行的进程。

如果加上服务id,就是查看项目中指定服务容器的进程。

unpause 和 pause

pause:暂停一个服务容器。

docker-compose pause [SERVICE...]

unpause :恢复处于暂停状态中的服务。

docker-compose unpause [SERVICE...]

logs

查看服务容器的输出。默认情况下,docker-compose 将对不同的服务输出使用不同的颜色来区分。可以通过 --no-color 来关闭颜色。

查看项目中指定服务的日志:

docker-compose logs 服务id

help [COMMAND] `可以查看具体某个命令的使用格式。

docker-compose 命令的基本的使用格式是

docker-compose [-f=<arg>...] [options] [COMMAND] [ARGS...]

命令选项说明:

-f, --file FILE 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定。

-p, --project-name NAME 指定项目名称,默认将使用所在目录名称作为项目名。

--verbose 输出更多调试信息。

-v, --version 打印版本并退出。

4.2、命令使用说明

up

  • 该命令十分强大,它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。
  • 链接的服务都将会被自动启动,除非已经处于运行状态。
  • 可以说,大部分时候都可以直接通过该命令来启动一个项目。
  • 默认情况,docker-compose up 启动的容器都在前台,控制台将会同时打印所有容器的输出信息,可以很方便进行调试。
  • 当通过 Ctrl-C 停止命令时,所有容器将会停止。
  • 如果使用 docker-compose up -d,将会在后台启动并运行所有的容器。一般推荐生产环境下使用该选项。
  • 如果服务容器已经存在,docker-compose up 将会尝试停止容器,然后重新创建(保持使用 volumes-from 挂载的卷),以保证新启动的服务匹配 docker-compose.yml 文件的最新内容。
  • 当使用 docker-compose up 服务id,就是对当前项目中的容器服务进行操作

命令格式为 :

docker-compose up [options] [SERVICE...]

选项说明:

  • -d 在后台运行服务容器。
  • --no-color 不使用颜色来区分不同的服务的控制台输出。
  • --no-deps 不启动服务所链接的容器。
  • --force-recreate 强制重新创建容器,不能与 --no-recreate 同时使用。
  • --no-recreate 如果容器已经存在了,则不重新创建,不能与 --force-recreate 同时使用。
  • --no-build 不自动构建缺失的服务镜像。
  • -t, --timeout TIMEOUT 停止容器时候的超时(默认为 10 秒)。

down

docker-compose down

此命令将会停止 up 命令所启动的容器,并移除网络,但不会移除数据卷。

docker-compose down 服务id

停止某个服务。

exec

docker-compose exec 服务id /bin/bash

ps

列出项目中目前的所有容器。

docker-compose ps [options] [SERVICE...]

选项说明:

  • -q 只打印容器的 ID 信息。

restart

重新启动所有已停止并正在运行的服务。

docker-compose restart [options] [SERVICE...]

选项:

  • -t, --timeout TIMEOUT 指定重启前停止容器的超时(默认为 10 秒)。

rm

删除所有(停止状态的)服务容器。推荐先执行 docker-compose stop 命令来停止容器。

docker-compose rm [options] [SERVICE...]

选项:

  • -f, --force 强制直接删除,包括非停止状态的容器。一般尽量不要使用该选项。
  • -v 删除容器所挂载的数据卷。

top

查看项目中各个服务容器内运行的进程。

如果加上服务id,就是查看项目中指定服务容器的进程。

unpause 和 pause

pause:暂停一个服务容器。

docker-compose pause [SERVICE...]

unpause :恢复处于暂停状态中的服务。

docker-compose unpause [SERVICE...]

logs

查看服务容器的输出。默认情况下,docker-compose 将对不同的服务输出使用不同的颜色来区分。可以通过 --no-color 来关闭颜色。

查看项目中指定服务的日志:

docker-compose logs 服务id

注:上面的 服务id 代表 docker-compose.yml 文件中的服务名

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值