尚硅谷Docker基础篇和Dockerfile超详细整合笔记

Docker基础篇+DockerFile

Docker:您要如何确保应用能够在不同环境中运行和通过质量检测?并且在部署过程中不出现令人头疼的版本、配置问题,也无需重新编写代码和进行故障修复?而这个就是使用容器Docker解决了运行环境和配置问题的软件容器, 方便做持续集成并有助于整体发布的容器虚拟化技术。

基本概念:

  • 仓库(Repository)是存储Docker镜像的地方,可以理解为类似于代码仓库。Docker仓库分为公共仓库私有仓库两种类型。公共仓库可以免费获取大量的镜像;私有仓库则是企业或个人自己搭建的仓库,用于存储自己的专有镜像。 比如,我们可以使用Docker Hub来搜索并下载已经上传到Docker Hub的镜像,也可以使用Docker搭建私有仓库,将自己的镜像上传并进行管理

  • 镜像(Image):是Docker容器的模板,包含了一组文件系统及其上的应用程序,可以用来创建Docker容器。镜像是只读的,一旦创建就不可修改,可以通过构建、下载或者导入来获取。同一个镜像可以创建多个容器,每个容器都会独立运行。 例如,我们可以使用Docker从某个镜像仓库中下载一个运行Nginx的镜像,然后基于这个镜像创建多个Nginx容器运行不同的Web服务。

  • 容器(Container)是Docker中最基本的运行单位,可以将应用程序及其依赖项打包为一个独立的可执行文件,在任何环境中都可以运行。容器之间是相互隔离的,每个容器都拥有自己的文件系统、网络、进程空间等。容器可以被创建、启动、停止、删除等操作。 例如,我们可以使用Docker创建一个运行Web服务的容器,让这个容器在一个独立的环境中运行。

    1 从面向对象角度
    Docker 利用容器(Container)独立运行的一个或一组应用,应用程序或服务运行在容器里面,容器就类似于一个虚拟化的运行环境,容器是用镜像创建的运行实例。就像是Java中的类和实例对象一样,镜像是静态的定义,容器是镜像运行时的实体。容器为镜像提供了一个标准的和隔离的运行环境,它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台

    2 从镜像容器角度
    可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

  • 实例(Instance)是Docker容器运行时的实例每个Docker容器都是一个实例,它们有着不同的名称、ID和状态,可以进行启动、停止、删除等操作。 例如,我们通过Docker创建了一个名为"web"的容器,并启动该容器,那么这个"web"容器就是一个实例。

    大概流程就是:用户可以从仓库拉取下载需要的镜像,镜像可以用来创建 Docker 容器,然后再通过镜像这个容器模板运行启动容器。

    在这里插入图片描述

容器与虚拟机比较:比较了 Docker 和传统虚拟化方式的不同之处:

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。

CentOS7安装Docker:

Docker官方安装教程网站:link

1.确定你是CentOS7及以上版本

cat /etc/redhat-release

2.yum安装gcc相关

yum -y install gcc
yum -y install gcc-c++

3.安装需要的软件包

​ 3.1安装docker引擎库:

yum install -y yum-utils

!官网给的是这条命令:yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo。但是是国外的,下载很容易出问题,连接超时。

4.设置stable镜像仓库(用阿里云的)

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

5.更新yum软件包索引

yum makecache fast

6.安装DOCKER CE (开始安装docker引擎)

yum -y install docker-ce docker-ce-cli containerd.io

7.启动docker

systemctl start docker

第一次安装一定要启动docker,然后没返回消息就代表安装成功了。

8.测试

docker version
docker run hello-world

出现hello from docker!代表本机安装成功!

卸载docker命令: (补充知识点,请勿尝试)

1.停止docker

systemctl stop docker 

2.移除docker

yum remove docker-ce docker-ce-cli containerd.io

3.删掉docker的文件和第三方包

rm -rf /var/lib/docker
rm -rf /var/lib/containerd
mkdir -p /etc/docker
tee /etc/…………………………去阿里云粘贴自己的,这个只是模板
{
  "registry-mirrors": ["https://{自已的编码}.mirror.aliyuncs.com"]
}

4.重启服务器

systemctl daemon-reload
systemctl restart docker

5.启动Docker后台容器(测试运行 hello-world)

docker run hello-world

这个run命令做了啥:

在这里插入图片描述


Docker常用命令:

帮助启动类命令:

启动docker: systemctl start docker

停止docker: systemctl stop docker

重启docker: systemctl restart docker

查看docker状态: systemctl status docker

开机启动: systemctl enable docker

查看docker概要信息: docker info

查看docker总体帮助文档: docker --help

查看docker命令帮助文档: docker 具体命令 --help


镜像命令:

  • docker images: (为列出本地主机上的镜像

在这里插入图片描述

各个选项说明:
REPOSITORY:表示镜像的仓库源
TAG:镜像的标签版本号
IMAGE ID:镜像ID
CREATED:镜像创建时间
SIZE:镜像大小
同一仓库源可以有多个 TAG版本,代表这个仓库源的不同个版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。
如果你不指定一个镜像的版本标签,例如你只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像

OPTIONS说明:

​ -a :列出本地所有的镜像(含历史映像层)

​ -q :只显示镜像ID。

  • docker search 某个XXX镜像名字 (去远程库看有没有这个镜像)

命令:docker search [OPTIONS] 镜像名字 (一般下载最前面的那个组织的)

OPTIONS说明:

​ --limit : 只列出N个镜像,默认25个

​ docker search --limit 5 redis

docker pull 某个XXX镜像名字 (拉取下载镜像)

docker pull 镜像名字[:TAG]

docker pull 镜像名字

没有TAG就是最新版;等价与docker pull 镜像名字:latest ,例如:docker pull ubuntu

在这里插入图片描述

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

docker rmi 某个XXX镜像名字ID (删除镜像)

删除单个:docker rmi -f 镜像ID

删除多个docker rmi -f 镜像名1:TAG 镜像名2:TAG

删除全部:docker rmi -f $(docker images -qa)

该配图来自b站up主GeekHour:需要完整命令图可以关注他微信公众号

在这里插入图片描述

docker虚悬镜像是什么?

仓库名、标签都是< none >的镜像,俗称虚悬镜像dangling image


容器常用命令:

有镜像才能创建容器, 这是根本前提

先下载一个镜像:docker pull ubuntu

新建+启动容器 :docker run [OPTIONS] IMAGE [COMMAND] [ARG…]

OPTIONS说明(常用):有些是一个减号,有些是两个减号

–name=“容器新名字” 为容器指定一个名称;
-d: 后台运行容器并返回容器ID,也即启动守护式容器(后台运行);

-i:以交互模式运行容器,通常与 -t 同时使用;
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
也即启动交互式容器(前台有伪终端,等待交互);

-P: 随机端口映射,大写P

-p: 指定端口映射,小写p

启动交互式容器(前台命令行): (重点知识)

#使用镜像centos:latest以交互模式启动一个容器,在容器内执行/bin/bash命令。
docker run -it centos /bin/bash

参数说明:
-i: 交互式操作。
-t: 终端。
centos : centos 镜像。
/bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。
要退出终端,直接输入 exit:

列出当前所有正在运行的容器docker ps [OPTIONS]

OPTIONS说明(常用):

-a :列出当前所有正在运行的容器+历史上运行过的
-l :显示最近创建的容器。
-n:显示最近n个创建的容器。
-q :静默模式,只显示容器编号。

退出容器 :(两种退出方式)

exit:run进去容器,exit退出,容器停止

ctrl+p+q: run进去容器,ctrl+p+q退出,容器不停止

启动已停止运行的容器:docker start 容器ID或者容器名
重启容器:docker restart 容器ID或者容器名
停止容器:docker stop 容器ID或者容器名
强制停止容器:docker kill 容器ID或容器名
删除已停止的容器:docker rm 容器ID

一次性删除多个容器实例:docker rm -f $(docker ps -a -q) / docker ps -a -q | xargs docker rm

启动守护式容器(后台服务器):在大部分的场景下,我们希望 docker 的服务是在后台运行的, 我们可以过 -d 指定容器的后台运行模式。

docker run -d 容器名:#使用镜像centos:latest以后台模式启动一个容器
docker run -d centos

问题:然后docker ps -a 进行查看, 会发现容器已经退出
很重要的要说明的一点: Docker容器后台运行,就必须有一个前台进程.
容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的。

这个是docker的机制问题,比如你的web容器,我们以nginx为例,正常情况下,
我们配置启动服务只需要启动响应的service即可。例如service nginx start
但是,这样做,nginx为后台进程模式运行,就导致docker前台没有运行的应用,…

例如:前台交互式启动: docker run -it redis:6.0.8

​ 后台守护式启动: docker run -d redis:6.0.8

查看容器日志 : docker logs 容器ID
查看容器内运行的进程: docker top 容器ID
查看容器内部细节: docker inspect 容器ID

进入正在运行的容器并以命令行交互:

docker exec -it 容器ID bashShell

重新进入docker attach 容器ID

区别: attach 直接进入容器启动命令的终端,不会启动新的进程 用exit退出,会导致容器的停止

exec 是在容器中打开新的终端,并且可以启动新的进程 用exit退出,不会导致容器的停止

推荐使用 docker exec 命令,因为退出容器终端,不会导致容器的停止。

例如:进入redis服务

docker exec -it 容器ID /bin/bash
docker exec -it 容器ID redis-cli
一般用-d后台启动的程序,再用exec进入对应容器实例
从容器内拷贝文件到主机上(容器→主机): 注意这个是文件!
docker cp 容器ID:容器内路径 目的主机路径
导入和导出容器 : 这个是整个容器!
export 导出容器的内容留作为一个tar归档文件[对应import命令]
import 从tar包中的内容创建一个新的文件系统再导入为镜像[对应export]

例如:docker export 容器ID > 文件名.tar

cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号

在这里插入图片描述

在这里插入图片描述


Docker镜像**的加深理解:

镜像是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。

只有通过这个镜像文件才能生成Docker容器实例(类似Java中new出来一个对象)。

分层的镜像:

以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载

在这里插入图片描述

UnionFS(联合文件系统):

在这里插入图片描述

Docker镜像加载原理:

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。

rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

在这里插入图片描述

为什么 Docker 镜像要采用这种分层结构呢:

镜像分层最大的一个好处就是共享资源,方便复制迁移,就是为了复用

比如说有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;
同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享

重点理解:

Docker镜像层都是只读的,容器层是可写的

当容器启动时,一个新的可写层被加载到镜像的顶部

这一层通常被称作**“容器层”**,“容器层”之下的都叫“镜像层”。

在这里插入图片描述

Docker镜像commit操作案例:

docker commit提交容器副本使之成为一个新的镜像

docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]

例如: 原始的默认Ubuntu镜像是不带着vim命令的,这个时候我们就需要安装Vim:

docker容器内执行上述两条命令:

apt-get update
apt-get -y install vim

安装完成后,commit我们自己的新镜像即可

docker commit -m="add vim cmd" -a="z" 容器id z/myubuntu:1.1

本地镜像发布到阿里云

本地镜像发布到阿里云流程:

在这里插入图片描述

1.自己生成个要传的镜像

2.将本地镜像推送到阿里云:

​ 阿里云开发者平台:https://promotion.aliyun.com/ntms/act/kubernetes.html

2.1.创建仓库镜像:
2.1.1 选择控制台,进入容器镜像服务

 2.1.2 选择个人实例

​ 2.1.3 命名空间 创建命名空间

​ 2.1.4 仓库名称 创建镜像仓库

​ 2.1.5 进入管理界面获得脚本

2.2.将镜像推送到阿里云

​ 2.2.1 将镜像推送到阿里云registry 管理界面脚本

在这里插入图片描述

脚本实例:docker login --username=zzyybuy registry.cn-hangzhou.aliyuncs.com
docker tag cea1bb40441c registry.cn-hangzhou.aliyuncs.com/atguiguwh/myubuntu:1.1
docker push registry.cn-hangzhou.aliyuncs.com/atguiguwh/myubuntu:1.1
上面命令是案例,具体的去阿里云查看具体自己的命令。

3.将阿里云上的镜像下载到本地

在这里插入图片描述

例子:docker pull registry.cn-hangzhou.aliyuncs.com/atguiguwh/myubuntu:1.1

本地镜像发布到私有库

​ Dockerhub、阿里云这样的公共镜像仓库可能不太方便,涉及机密的公司不可能提供镜像给公网,所以需要创建一个本地私人仓库供给团队使用,基于公司内部项目构建镜像

Docker Registry是官方提供的工具,可以用于构建私有镜像仓库

将本地镜像推送到私有库流程

1.下载镜像Docker Registry

docker pull registry

2.运行私有库Registry,相当于本地有个私有Docker hub

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

默认情况,仓库被创建在容器的/var/lib/registry目录下,建议自行用容器卷映射,方便于宿主机联调

3.案例演示创建一个新镜像,ubuntu安装ifconfig命令

​ 3.1 从Hub上下载ubuntu镜像到本地并成功运行

​ 3.2 原始的Ubuntu镜像是不带着ifconfig命令的

​ 3.3 外网连通的情况下,安装ifconfig命令并测试通过

​ 3.4 安装完成后,commit我们自己的新镜像

docker commit -m="ifconfig cmd add" -a="z" be4779f8w112 zubuntu:1.2

​ 3.5 启动我们的新镜像并和原来的对比

4.curl验证私服库上有什么镜像

curl -XGET http://192.168.111.162:5000/v2/_catalog
 
可以看到,目前私服库没有任何镜像上传过。。。。。。

5.将新镜像zzyyubuntu:1.2修改符合私服规范的Tag

按照公式: docker   tag   镜像:Tag   Host:Port/Repository:Tag
自己host主机IP地址,填写你们自己的,不要粘贴错误,O(∩_∩)O
使用命令 docker tag 将zubuntu:1.2 这个镜像修改为192.168.111.162:5000/zubuntu:1.2
 
docker tag  zubuntu:1.2  192.168.111.162:5000/zzyyubuntu:1.2

6.修改配置文件使之支持http

别无脑照着复制,registry-mirrors 配置的是国内阿里提供的镜像加速地址,不用加速的话访问官网的会很慢。
2个配置中间有个逗号 ','别漏了,这个配置是json格式的。
2个配置中间有个逗号 ','别漏了,这个配置是json格式的。
2个配置中间有个逗号 ','别漏了,这个配置是json格式的。

vim命令新增如下红色内容:vim /etc/docker/daemon.json
{
“registry-mirrors”: [“https://aa25jngu.mirror.aliyuncs.com”],
“insecure-registries”: [“192.168.111.162:5000”]
}…

修改完后,建议重启docker

7.push推送到私服库

docker push 192.168.111.162:5000/zubuntu:1.2

8.curl验证私服库上有什么镜像

curl -XGET http://192.168.111.162:5000/v2/_catalog

9.pull到本地并运行

docker pull 192.168.111.162:5000/zzyyubuntu:1.2

docker run -it 镜像ID /bin/bash

Docker容器数据卷

坑:容器卷记得加入:–privileged=true

Docker挂载主机目录访问如果出现cannot open directory .: Permission denied
解决办法:在挂载目录后多加一个–privileged=true参数即可

如果是CentOS7安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行为,
在SELinux里面挂载目录被禁止掉了额,如果要开启,我们一般使用–privileged=true命令,扩大容器的权限解决挂载目录没有权限的问题,也即
使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。

概念:

卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷

就是将docker容器内的数据保存进宿主机的磁盘中

 docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录      镜像名

在这里插入图片描述

作用:

将运用与运行的环境打包镜像,run后形成容器实例运行 ,但是我们对数据的要求希望是持久化的

Docker容器产生的数据,如果不备份,那么当容器实例删除后,容器内的数据自然也就没有了。
为了能保存数据在docker中我们使用卷。

特点:
1:数据卷可在容器之间共享或重用数据
2:卷中的更改可以直接实时生效,爽
3:数据卷中的更改不会包含在镜像的更新中
4:数据卷的生命周期一直持续到没有容器使用它为止

案例:

宿主vs容器之间映射添加容器卷

直接命令添加:(将docker容器内的数据保存进宿主机的磁盘中)

 docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录      镜像名
 例如:
 docker run -it --privileged=true -v /tmp/host_data:/tmp/docker_data --name=u1 ubuntu 

宿主机下假如没这个目录,会自己帮你创建

查看数据卷是否挂载成功

docker inspect 容器ID

容器和宿主机之间数据共享

1 docker修改,主机同步获得
2 主机修改,docker同步获得
3 docker容器stop,主机修改,docker容器重启后依旧可以同步

读写规则映射添加说明

读写(默认) rw = read + write

 docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:rw      镜像名

只读 :容器实例内部被限制,只能读取不能写 ro = read only

此时如果宿主机写入内容,可以同步给容器内,容器可以读取到。

 docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:ro      镜像名

卷的继承和共享

容器1完成和宿主机的映射

docker run -it  --privileged=true -v /mydocker/u:/tmp --name u1 ubuntu

容器2继承容器1的卷规则

docker run -it  --privileged=true --volumes-from 父类  --name u2 ubuntu
例如: docker run -it  --privileged=true --volumes-from u1  --name u2 ubuntu

Docker常规安装简介

在这里插入图片描述

​ 以后做团队项目,只用去下载仓库或者官网打包好的镜像,直接运行镜像即可使用。步骤也就直接统一了

总体步骤

  1. 搜索镜像
  2. 拉取镜像
  3. 查看镜像
  4. 启动镜像 :服务端口映射
  5. 停止容器
  6. 移除容器

常见模拟案例:

安装tomcat

1.docker hub上面查找tomcat镜像

docker search tomcat

2.从docker hub上拉取tomcat镜像到本地

docker pull tomcat

3.docker images查看是否有拉取到的tomcat

4.使用tomcat镜像创建容器实例(也叫运行镜像)

docker run -it -p 8080:8080 tomcat
  • -p 小写,主机端口:docker容器端口
  • -P 大写,随机分配端口
  • i:交互
  • t:终端
  • d:后台

5.访问猫首页

出现问题:出现404,访问不到

解决:1.可能没有映射端口或者没有关闭防火墙

​ 2.先把webapps文件删了,再把webapps.dist目录换成webapps。因为真正有东西的在webapps.dist里面,所以把它进行改名

先把webapps文件删了:  rm -f webapps
把webapps.dist目录换成webapps  mv webapps.dist webapps

这样子运行最新版都要修改,太麻烦了。可以使用免修版:

免修改版说明

docker pull billygoo/tomcat8-jdk8
docker run -d -p 8080:8080 --name mytomcat8 billygoo/tomcat8-jdk8

安装mysql

1.docker hub上面查找mysql镜像

2.从docker hub上(阿里云加速器)拉取mysql镜像到本地标签为5.7

3.使用mysql5.7镜像创建容器(也叫运行镜像)

简单版:

使用mysql镜像

docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
docker ps
docker exec -it 容器ID /bin/bash
mysql -uroot -p

尝试建库建表插入数据:

show databases;
create database db01;
create table t1(id int,name varchar(20));
insert into t1 values(1,'z3');
select * from t1;

去使用本地的navicat看看能不能连接运行在dokcer上的mysql容器实例服务,发现是可以的,且刚刚新建的表和数据都存在。在navicat中插入数据发现也是互通的。

坑:但是插入中文数据时,出现了报错

说明docker上默认字符集编码隐患 ,于是乎在docker里面的mysql容器实例查看,输入命令内容如下:

 SHOW VARIABLES LIKE 'character%'

发现全是拉丁,这种得在docker的mysql实例修改!

且一不小心删除容器后,那里面的mysql数据如何办?

看下面的实战版↓:

实战版(解决乱码和备份问题):

1.新建mysql容器实例

docker run -d -p 3306:3306 --privileged=true 
-v /zzyyuse/mysql/log:/var/log/mysql 
-v /zzyyuse/mysql/data:/var/lib/mysql 
-v /zzyyuse/mysql/conf:/etc/mysql/conf.d 
-e MYSQL_ROOT_PASSWORD=123456  --name mysql mysql:5.7

2. 解决中文乱码问题:新建my.cnf 通过容器卷同步给mysql容器实例

[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = utf8

3.重新启动mysql容器实例再重新进入并查看字符编码

4.再新建库新建表再插入中文测试

5.结论:

之前的DB 无效

修改字符集操作+重启mysql容器实例

之后的DB 有效,需要新建

结论:docker安装完MySQL并run出容器后,建议请先修改完字符集编码后再新建mysql库-表-插数据

6.假如将当前容器实例删除,再重新来一次,之前建的db01实例还有,里面的数据也没有丢失

docker run -d -p 3306:3306 --privileged=true 
-v /zzyyuse/mysql/log:/var/log/mysql 
-v /zzyyuse/mysql/data:/var/lib/mysql 
-v /zzyyuse/mysql/conf:/etc/mysql/conf.d 
-e MYSQL_ROOT_PASSWORD=123456  --name mysql mysql:5.7

以后,务必要注意解决乱码和备份问题

安装redis

1.从docker hub上(阿里云加速器)拉取redis镜像到本地标签为6.0.8

2.命令提醒:容器卷记得加入–privileged=true

Docker挂载主机目录Docker访问出现cannot open directory .: Permission denied
解决办法:在挂载目录后多加一个--privileged=true参数即可

3.在CentOS宿主机下新建目录/app/redis

mkdir -p /app/redis

4.将一个redis.conf文件模板拷贝进/app/redis目录下

​ 4.1拷贝配置文件:
​ 将准备好的redis.conf文件放进/app/redis目录下

这个看之前的Linux安装redis的详细教程:

5./app/redis目录下修改redis.conf文件

在这里插入图片描述

​ 3.4开启redis数据持久化 appendonly yes 可选

6.使用redis6.0.8镜像创建容器(也叫运行镜像)

7.测试redis-cli连接上来

8.请证明docker启动使用了我们自己指定的配置文件

  • 修改前:我们用的配置文件,数据库默认是16个
  • 修改后:宿主机的修改会同步给docker容器里面的配置。 记得重启服务

9.测试redis-cli连接上来第2次



DockerFile解析

Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本

在这里插入图片描述

使用目的:使用基本命令很麻烦,每一次要变化的时候,都需要commit;假如有很多内容要提交,那要commit很多次,而DockerFile可以一次性搞定,它就像列了一个清单,你后续需要加入任何功能,直接在清单中写好,直接就相等于多次提交了。

构建三步骤:

1.编写Dockerfile文件

2.docker build命令构建镜像

3.docker run依镜像运行容器实例

Dockerfile内容基础知识:

1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数

2:指令按照从上到下,顺序执行

3:#表示注释

4:每条指令都会创建一个新的镜像层并对镜像进行提交

Docker执行Dockerfile的大致流程

(1)docker从基础镜像运行一个容器

(2)执行一条指令并对容器作出修改

(3)执行类似docker commit的操作提交一个新的镜像层

(4)docker再基于刚提交的镜像运行一个新容器

(5)执行dockerfile中的下一条指令直到所有指令都执行完成

在这里插入图片描述

DockerFile常用保留字指令

可以参考tomcat8的dockerfile入门:https://github.com/docker-library/tomcat

保留字:

FROM :基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是from

MAINTAINER:镜像维护者的姓名和邮箱地址

RUN:容器构建时需要运行的命令

两种格式:

shell格式: RUN yum -y install vim
exec格式:  RUN ["可执行文件","参数1","参数2"]
推荐使用shell格式,好理解和好用点

RUN是在 docker build时运行

EXPOSE:当前容器对外暴露出的端口

WORKDIR: 指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点

USER: 指定该镜像以什么样的用户去执行,如果都不指定,默认是root

ENV:用来在构建镜像过程中设置环境变量

ENV MY_PATH /usr/mytest
这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;
也可以在其它指令中直接使用这些环境变量,
 
比如:WORKDIR $MY_PATH

ADD:将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包

COPY:类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置
COPY src dest
COPY ["src", "dest"]
<src源路径>:源文件或者源目录
<dest目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

VOLUME: 容器数据卷,用于数据保存和持久化工作

CMD: 指定容器启动后的要干的事情

!注意:Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换

比如:在tomcat的dockerFile 最后一行是: CMD ["catalina.sh","run"]
但是你在docker run这个命令后面加一个/bin/bash ,虽然成功启动了,但是相当于在DockerFile后面又加了一个CMD ["/bin/bash","run"];会导致前面的CMD被覆盖了。这个时候去浏览器就看不到猫了。

它和前面RUN命令的区别:

  • CMD是在docker run 时运行。
  • RUN是在 docker build时运行。
ENTRYPOINT :类似于 CMD 指令,但是ENTRYPOINT不会被docker run后面的命令覆盖, 而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序

命令格式和案例说明:

命令格式:ENTRYPOINT ["<executeable>","<param1>","<param2>",...]

ENTRYPOINT可以和CMD一起用,一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参。
当指定了ENTRYPOINT后,CMD的含义就发生了变化,不再是直接运行其命令而是将CMD的内容作为参数传递给ENTRYPOINT指令,他两个组合会变成 <ENTRTPOINT>"<CMD>"
 
案例如下:假设已通过 Dockerfile 构建了 nginx:test 镜像:
FROM nginx
ENTRYPOINT ["nginx","-c"] # 定参
CMD ["etc/nginx/nginx.conf"] #变参
是否传参按照dockerfile编写执行传参运行
Docker命令docker run nginx:testdocker run nginx:test -c /etc/nginx/new.conf
衍生出的实际命令nginx -c /etc/nginx/nginx.confnginx -c /etc/nginx/new.conf

优点在执行docker run的时候可以指定 ENTRYPOINT 运行所需的参数。

注意如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

案例,加强理解:

自定义镜像mycentosjava8

1.要求: Centos7镜像具备 vim+ifconfig+jdk8 这三个功能

​ JDK的下载镜像地址:下载地址:https://www.oracle.com/java/technologies/downloads/#java8

2.编写 准备编写Dockerfile文件 大写字母D

FROM centos
MAINTAINER z
 
ENV MYPATH /usr/local
WORKDIR $MYPATH
 
#安装vim编辑器
RUN yum -y install vim
#安装ifconfig命令查看网络IP
RUN yum -y install net-tools...
#安装Java8及lib库
RUN yun -y install glibc.1686
RUN mkdir /usr/local/java
#ADD 是相对路径jar,把jdk-8u171-inux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置 自己复制自己所下载jdk的名字
ADD idk- 8u171- linux- x64.tar.gz /usr/local/java/ 
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib: $CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH

EXPOSE 80

CMD echo $MYPATH
CMD echo "success------------------------ok"
CMD /bin/bash

3.构建

docker build -t 新镜像名字:TAG .
如:docker build -t centosjava8:1.5 .

注意,上面TAG后面有个空格,有个点

4.运行

docker run -it 新镜像名字:TAG 
docker run -it centosjava8:1.5 /bin/bash
虚悬镜像

仓库名、标签都是的镜像,俗称dangling image

1.Dockerfile写一个:

1 vim Dockerfile
from ubuntu
CMD echo 'action is success'

2 docker build .

2.查看

docker image ls -f dangling=true

3.删除

docker image prune

虚悬镜像已经失去存在价值,有就可以删除


Docker微服务实战

通过dockerfile发布微服务部署到docker容器

1.IDEA工具里面搞定微服务jar包 : docker_boot-0.0.1-SNAPSHOT.jar

2.编写Dockerfile

# 基础镜像使用java
FROM java:8
# 作者
MAINTAINER z
# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为z_docker.jar
ADD docker_boot-0.0.1-SNAPSHOT.jar z_docker.jar
# 运行jar包
RUN bash -c 'touch /z_docker.jar'
ENTRYPOINT ["java","-jar","/z_docker.jar"]
#暴露6001端口作为微服务
EXPOSE 6001

记得将微服务jar包和Dockerfile文件上传到同一个目录下/mydocker:

jar传到/mydocker下面,在/mydocker下面vim Dockerfile

3.构建镜像

docker build -t z_docker:1.6 .

打包成镜像文件

4.运行容器 (注意:run后面也不要加内容了,以免命令覆盖)

docker run -d -p 6001:6001 z_docker:1.6

5.访问测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/124963.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Unity】简单案例脚本实现 | 鼠标观察/键盘控制移动飞行/行走/碰撞检测

《Unity5实战-使用C#和Unity开发多平台游戏》第二章-构建一个让你置身3D空间的演示 鼠标观察/键盘控制移动飞行/行走/碰撞检测 Unity版本&#xff1a;2019.4.23f1c1 注意脚本名称和组件添加&#xff0c;不在文章中一一强调场景模型都是在资源商店选择的免费下载&#xff08;选…

vue-router路由守卫进阶

vue-router路由守卫进阶 路由守卫&#xff0c;可以想象为古代御前侍卫&#xff0c;路由守卫&#xff0c;则是对路由进行权限控制 分类&#xff1a;全局守卫、独享守卫、组件内守卫 全局前置-路由守卫 作用&#xff1a;主要用来鉴权 用户点击导航区&#xff0c;随后引起路径的…

Flink ON Yarn 模式 --- per job mode 与application mode的区别

1、per job mode&#xff1a; 对于yarn-per-job模式调度的过程&#xff1a; 1、资源调度&#xff1a; 1、因为是yarn模式&#xff0c;所以客户端会向ResourceManager申请资源&#xff0c;申请容器负责来启动ApplicationManager 2、此时ResourceManager接受到客户端的请求&#…

文件上传 [GXYCTF2019]BabyUpload1

打开题目 传个是jpg文件后缀的一句话木马上去 代码如下 <script languagephp>eval($_POST[v]);</script> 发现上传成功 因此我们需要先上传 .htaccess 文件&#xff0c;然后再上传 2.jpg文件 .htaccess作用&#xff1a;文件将别的后缀名文件内容解析为php程序…

CSS特效001:鼠标放div上,实现旋转、放大、移动等效果

GPT能够很好的应用到我们的代码开发中&#xff0c;能够提高开发速度。你可以利用其代码&#xff0c;做出一定的更改&#xff0c;然后实现效能。 css实战中&#xff0c;经常会看到这样的场景&#xff0c;鼠标放到一个图片或者一个div块状时候&#xff0c;会出现旋转、放大、移动…

Linux 本地Yearning SQL审核平台远程访问

文章目录 前言1. Linux 部署Yearning2. 本地访问Yearning3. Linux 安装cpolar4. 配置Yearning公网访问地址5. 公网远程访问Yearning管理界面6. 固定Yearning公网地址 前言 Yearning 简单, 高效的MYSQL 审计平台 一款MYSQL SQL语句/查询审计工具&#xff0c;为DBA与开发人员使用…

如何设值固定ip地址

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 如何设值固定ip地址 一、找到网络和Internet选项二、选择更改适配器选项2.双击&#xff0c;选择属性3.选择ipv4&#xff0c;点击属性4.选择使用下面的IP地 总结 一、找到网络…

阿里云99元服务器40G ESSD Entry云盘、2核2G3M带宽配置

阿里云99元服务器新老用户均可以买&#xff0c;你没看错&#xff0c;老用户可以买&#xff0c;活动页面 aliyunfuwuqi.com/go/aliyun 配置为云服务器ECS经济型e实例、2核2G、3M固定带宽、40G ESSD Entry云盘&#xff0c;并且续费不涨价&#xff0c;原价99元即可续费&#xff0c…

基于轻量级卷积神经网络CNN开发构建打架斗殴识别分析系统

在很多公共场合中&#xff0c;因为一些不可控因素导致最终爆发打架斗殴或者大规则冲突事件的案例层出不穷&#xff0c;基于视频监控等技术手段智能自动化地识别出已有或者潜在的危险行为对于维护公共场合的安全稳定有着重要的意义。本文的核心目的就是想要基于CNN模型来尝试开发…

05-MySQL-进阶-存储引擎索引SQL优化

一、存储引擎 涉及资料 链接&#xff1a;https://pan.baidu.com/s/1M1oXN_pH3RGADx90ZFbfLQ?pwdCoke 提取码&#xff1a;Coke ①&#xff1a;MySQL体系结构 1.连接层 最上层是一些客户端和链接服务&#xff0c;包含本地sock 通信和大多数基于客户端/服务端工具实现的类似于 T…

Linux - 实现一个简单的 shell

前言 之前我们对进程的替换&#xff0c;进程地址空间等等的概念进行了说明&#xff0c;本篇博客会基于这些知识点来 实现一个简单的 shell &#xff0c;如有疑问&#xff0c;可以参考下述博客&#xff1a;Linux - 进程程序替换 - C/C 如何实现与各个语言之间的相互调用 - 替换…

STM32两轮平衡小车原理详解(开源)

一、引言 关于STM32两轮平衡车的设计&#xff0c;我想在读者阅读本文之前应该已经有所了解&#xff0c;所以本文的重点是代码的分享和分析。至于具体的原理&#xff0c;我觉得读者不必阅读长篇大论的文章&#xff0c;只需按照本文分享的代码自己亲手制作一辆平衡车&#xff0c…

【STM32】STM32的Cube和HAL生态

1.单片机软件开发的时代变化 1.单片机的演进过程 (1)第1代&#xff1a;4004、8008、Zilog那个年代&#xff08;大约1980年代之前&#xff09; (2)第2代&#xff1a;51、PIC8/16、AVR那个年代&#xff08;大约2005年前&#xff09; (3)第3代&#xff1a;51、PIC32、Cortex-M0、…

QT事件循环和事件队列的理解

Qt的事件循环机制_qt事件循环流程-CSDN博客 QT-事件循环机制_qt线程事件循环-CSDN博客 一、事件处理流程如图所示&#xff1a; 1.QCoreApplication::postEvent(QObject *receiver,QEvent *event)&#xff1a; QCoreApplication::postEvent()函数用于将事件异步地发送到目标对…

机器学习 vs. 数值天气预报,AI 如何改变现有的天气预报模式

数值天气预报是天气预报的主流方法。它通过数值积分&#xff0c;对地球系统的状态进行逐网格的求解&#xff0c;是一个演绎推理的过程。 然而&#xff0c;随着天气预报分辨率不断升高&#xff0c;预报时间逐渐延长&#xff0c;NWP 模式所需要的算力迅速增加&#xff0c;限制了…

CSS 外边距、填充、分组嵌套、尺寸

一、CSS 外边距&#xff1a; CSS margin&#xff08;外边距&#xff09;属性定义元素周期的空间。margin清除周围的&#xff08;外边框&#xff09;元素区域。margin没有背景颜色&#xff0c;是完全透明的。margin可以单独改变元素的上、下、左、右边距&#xff0c;也可以一次改…

什么叫做阻塞队列的有界和无界

&#xff08;mic老师面试题摘选&#xff09; 昨天一个 3 年 Java 经验的小伙伴私信我&#xff0c;他说现在面试怎么这么难啊&#xff01; 我只是面试一个业务开发&#xff0c;他们竟然问我&#xff1a; 什么叫阻塞队列的有界和无界。现在面试 也太卷了吧! 如果你也遇到过类似…

nanodet训练自己的数据集、NCNN部署到Android

nanodet训练自己的数据集、NCNN部署到Android 一、介绍二、训练自己的数据集1. 运行环境2. 数据集3. 配置文件4. 训练5. 训练可视化6. 测试 三、部署到android1. 使用官方权重文件部署1.1 下载权重文件1.2 使用Android Studio部署apk 2. 部署自己的模型【暂时存在问题】2.1 生成…

如何查看Android 包依赖关系

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、查看依赖关系3.1 方式一3.2 方式二…

安防监控系统视频融合平台EasyCVR页面地图功能细节详解

安防监控视频汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力&#xff…