Docker学习与使用

Docker容器

1:什么是容器

容器就是在隔离的环境运行的一个进程,如果进程停止,容器就会销毁。隔离的环境拥有自己的系统文件,ip地址,主机名等。

程序:代码,命令
进程:正在运行的程序
容器的系统文件就是宿主机的某一个目录

2:容器和虚拟化的区别

image-20221106231941897

Linux容器技术,容器虚拟化和kvm虚拟化的区别
kvm虚拟化:需要硬件的支持,需要模拟硬件,可以运行不同的操作系统,启动时间分钟级

Linux开机启动流程:
BIOS开机硬件自检
根据BIOS设置的优先启动项boot 网卡 硬盘 U盘 光驱
读取mbr引导 UEFI(gpt分区) mbr硬盘分区信息,内核加载路径
加载内核
启动第一个进程init systemd
系统初始化完成
运行服务
。。。

容器:共用宿主机内核,容器的第一个进程直接运行服务,损耗少,启动快,性能高
容器虚拟化:不需要硬件的支持,不需要模拟硬件,共用宿主机的内核,启动时间秒级(没有开机流程)

image-20221107001014175

  • 虚拟机(重量级)
    • 基础设施(Infrastructure):它可以是你的个人电脑,数据中心的服务器,或者是云主机。
    • 虚拟机管理系统(Hypervisor):利用Hypervisor,可以在主操作系统之上运行多个不同的从操作系统。类型1的Hypervisor有支持MacOS的HyperKit,支持Windows的Hyper-V、Xen以及KVM。类型2的Hypervisor有VirtualBox和VMWare workstation。
    • 客户机操作系统(Guest Operating System):假设你需要运行3个相互隔离的应用,则需要使用Hypervisor启动3个客户机操作系统,也就是3个虚拟机。这些虚拟机都非常大,也许有700MB,这就意味着它们将占用2.1GB的磁盘空间。更糟糕的是,它们还会消耗很多CPU和内存。
    • 各种依赖:每一个客户机操作系统都需要安装许多依赖。如果你的应用需要连接PostgreSQL的话,则需要安装libpq-dev;如果你使用Ruby的话,应该需要安装gems;如果使用其他编程语言,比如Python或者Node.js,都会需要安装对应的依赖库。
    • 应用:安装依赖之后,就可以在各个客户机操作系统分别运行应用了,这样各个应用就是相互隔离的
  • 容器(轻量级)
    • 基础设施(Infrastructure):它可以是你的个人电脑,数据中心的服务器,或者是云主机。
    • 主操作系统(Host Operating System):所有主流的Linux发行版都可以运行Docker。对于MacOS和Windows,也有一些办法”运行”Docker。
    • Docker守护进程(Docker Daemon):Docker守护进程取代了Hypervisor,它是运行在操作系统之上的后台进程,负责管理Docker容器。
    • 各种依赖:对于Docker,应用的所有依赖都打包在Docker镜像中,Docker容器是基于Docker镜像创建的。
    • 应用:应用的源代码与它的依赖都打包在Docker镜像中,不同的应用需要不同的Docker镜像。不同的应用运行在不同的Docker容器中,它们是相互隔离的。

总结:
(1) 与宿主机使用同一个内核,性能损耗小;
(2) 不需要指令集模拟;
(3) 容器可以在cpu核心的本地运行指令,不需要任何专门的解释机制;
(4) 避免了准虚拟化和系统调用替换中的复杂性;
(5) 轻量级隔离,在隔离的同时还提供共享机制,以实现容器与宿主机的资源共享

3:什么是 Docker

Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会,并成立推动 开放容器联盟(OCI)

Docker 自开源后受到广泛的关注和讨论,至今其 GitHub 项目已经超过 4 万 6 千个星标和一万多个 fork。甚至由于 Docker 项目的火爆,在 2013 年底,dotCloud 公司决定改名为 Docker。Docker 最初是在 Ubuntu 12.04 上开发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持;Google 也在其 PaaS 产品中广泛应用 Docker。

Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroupnamespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runCcontainerd

Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

chroot技术

新建一个子系统(拥有自己完整的系统文件)

参考资料:https://www.ibm.com/developerworks/cn/linux/l-cn-chroot/

4:为什么要使用 Docker

作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。

更高效的利用系统资源

由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。

更快速的启动时间

传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。

一致的运行环境

开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。

持续交付和部署

对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。

使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。

而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。

更轻松的迁移

由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。

更轻松的维护和扩展

Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。

对比传统虚拟机总结
特性容器虚拟机
启动秒级分钟级
运行形态直接运行于宿主机的内核上,不同容器共享同一个liunx内核运行于Hypervisior上
硬盘使用一般为 MB一般为 GB
性能接近原生弱于
系统支持量单机支持上千个容器一般几十个

5:docker不是完整的虚拟化

不是一个系统而是一个进程组,docker是一个进程(父进程),docker里有很多进程(子进程)。

注意:

千万不要误以为Docker就是虚拟机。其实Docker不是虚拟机!

docker是前台运行的需要hold住,也就是command是在前台停留的

docker没有systemd概念

6:docker容器

docker是通过进程虚拟化技术(namespaces及cgroups cpu、内存、磁盘io等)来提供容器的资源隔离与安全保障等。由于Docker通过操作系统层的虚拟化实现隔离,所以Docker容器在运行时,不需要类似虚拟机(VM)额外的操作系统开销,提高资源利用率。
namespace:资源隔离
cgroups:进程的资源限制
kvm:虚拟磁盘文件,资源隔离;资源限制
chroot:提供文件系统
docker:初期把lxc二次开发,libcontainer

docker的主要目标是"Build,Ship and Run any App,Angwhere",构建,运输,处处运行

Build once,Run anywhere 一次构建,处处运行

部署服务,环境问题

docker是一种软件的打包技术

构建:做一个docker镜像
运输:docker pull
运行:启动一个容器
每一个容器,他都有自己的系统文件rootfs

kvm解决了硬件和操作系统之间的依赖
kvm独立的虚拟磁盘,xml配置文件

docker解决了软件和操作系统环境之间的依赖,能够让独立服务或应用程序在不同环境中,得到相同的运行结果。
docker镜像有自己的文件系统。

容器启动运行流程

image-20221107002206437

7:Docker镜像

镜像原理(镜像文件系统原理)

Docker镜像是有文件系统叠加而成,最低端是一个引导文件系统,即bootfs。

Docker镜像的第二层是root文件系统rootfs,它位于引导文件系统bootfs之上。rootfs可以使一种或多种 操作系统,传统的Linux系统引导时root文件系统最先只读的方式加载,引导结束并完成完整性检查后会切换到读写模式,Docker中root文件系统永远只能是只读状态,并且Docker利用联合加载(unionmount)技术又会再root文件系统上加载更多的只读文件系统。

当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。

Docker将这种文件系统称为镜像,镜像可以叠加,在下方的镜像称为父镜像,最底层的镜像称为基础镜像,当使用一个镜像启动容器时,Docker会在该镜像的最顶层加载一个读写文件系统,在Docker中运行的程序就在这个读写层。

写时复制:Docker第一次启动一个容器时,初始的读写层是空的。当文件系统发生变化时,这些变化都会应用到这一层上,如果要修改一个文件,此文件会从下面的只读层复制到读写层,此文件的只读版本依然存在,但是会被读写层的副本隐藏。

img

联合加载:指一次同时加载多个文件系统(镜像),但是再外面只能看到一个文件系统,联合加载会将各层文件系统叠加到一起,这样最终文件系统会包含所有底层的文件和目录。

当一个容器启动后,容器会被移动到内存中,引导文件系统则会被卸载,以留出更多的内存公initrd磁盘镜像使用。

简单来说docker容器是由镜像的只读层(只读层以下的都归为只读层)和容器赋予的可读可写层组成的,如下图

8:镜像、容器、仓库

镜像

Docker的镜像是一个只读的模板,一个独立的文件系统,包括运行容器所需的数据,可以用来创建新的容器。

Docker的镜像相当于centos操作系统的iso安装包,ISO镜像的内容是固定的,不会发生改变,可以重复使用。

容器

Docker镜像生成出来的东西,我们就叫他它“容器”

仓库

仓库支持的操作类似git,当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。

类似于,将某项目模块打成jar包,然后上传到私有或者公有的maven仓库,然后在其他的所有支持maven环境的机器上,都可以拉取这个jar进行使用。

Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容器镜像,Docker工具默认从这个公共镜像库下载镜像。地址:https://hub.docker.com/explore

简单来说

镜像:启动容器的模板

仓库:保存镜像的地方

容器:对外提供服务的实例

实验环境

主机名IP地址备注
docker192.168.188.70

Docker安装

环境准备
[root@docker ~]# yum install -y wget
[root@docker ~]# cd /etc/yum.repos.d/
[root@docker yum.repos.d]# mkdir bak
[root@docker yum.repos.d]# mv ./* bak/
# 准备Base源
[root@docker yum.repos.d]# wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

[root@docker ~]# yum makecache
开始安装

打开阿里源的docker-ce源里面也有教程

# step 1: 安装必要的一些系统工具
[root@docker ~]# yum install -y yum-utils device-mapper-persistent-data lvm2

# Step 2: 添加软件源信息
[root@docker ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# Step 3
[root@docker ~]# sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo

# Step 4: 更新并安装Docker-CE
[root@docker ~]# yum makecache fast
[root@docker ~]# yum -y install docker-ce-18.06.3.ce-3.el7

# Step 4: 开启Docker服务
[root@docker ~]# service docker start
[root@docker ~]# systemctl enable docker

# 注意:
# 官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,您可以通过以下方式开启。同理可以开启各种测试版本等。
# vim /etc/yum.repos.d/docker-ce.repo
#   将[docker-ce-test]下方的enabled=0修改为enabled=1
#
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# yum list docker-ce.x86_64 --showduplicates | sort -r
#   Loading mirror speeds from cached hostfile
#   Loaded plugins: branch, fastestmirror, langpacks
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            docker-ce-stable
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            @docker-ce-stable
#   docker-ce.x86_64            17.03.0.ce-1.el7.centos            docker-ce-stable
#   Available Packages
# Step2: 安装指定版本的Docker-CE: (VERSION例如上面的17.03.0.ce.1-1.el7.centos)
# sudo yum -y install docker-ce-[VERSION]

镜像加速(可以指向个人仓库或企业仓库)

这里采用阿里云的镜像加速,https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://2l058lvr.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker

Docker基本操作

官网操作文档:https://docs.docker.com/engine/reference/commandline/docker/

查看docker版本号

[root@docker ~]# docker version   # 查看docker版本号

查看镜像信息 images

# 查看镜像信息 images
[root@docker ~]# docker images ls
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
[root@docker ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    feb5d9fea6a5   7 months ago   13.3kB


# 该表格包含了5列,含义如下:
1. REPOSITORY:镜像所属仓库名称。
2.TAG:镜像标签。默认是latest,表示最新。
3.IMAGE ID:镜像ID,表示镜像唯一标识。
4.CREATED:镜像创建时间。
5.SIZE:镜像大小。

查看容器 ps

# 查看当前启动的容器,二选一
[root@docker ~]# docker container ls
[root@docker ~]# docker ps(只列出运行的容器)
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

# 列出所有容器,包括未运行的容器
[root@docker ~]# docker ps -a


# 该表格包含了七列,含义如下:
1.CONTAINER_ID:表示容器ID。
2.IMAGE:表示镜像名称。
3.COMMAND:表示启动容器时运行的命令。运行的时候必须使用,不然可能起不来
4.CREATED:表示容器的创建时间。
5.STATUS:表示容器运行的状态。Up表示运行中,Exited表示已停止。
6.PORTS:表示容器对外的端口号。
7.NAMES:表示容器名称。该名称默认由Docker自动生成,也可使用docker run命令的–name选项自行指定。

镜像拉取centos和ubuntu

# pull命令可以从远程仓库拉取镜像,如果本地仓库已经存在该镜像,则会更新,默认源是Docker Hub,不指定版本时默认为latest版本
[root@docker ~]# docker pull centos:7   # 拉取指定版本的centos
[root@docker ~]# docker pull ubuntu     # 拉取ubuntu
[root@docker ~]# docker pull hello-world	#最小的例子,一般用来监测是否正常安装成功docker

容器运行镜像

[root@docker ~]# docker run hello-world

# 运行centos:7
[root@docker ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
ubuntu        latest    ba6acccedd29   7 months ago   72.8MB
hello-world   latest    feb5d9fea6a5   7 months ago   13.3kB
centos        7         eeb6ee3f44bd   8 months ago   204MB
[root@docker ~]# docker run eeb6ee3f44bd   # docker run 指定镜像ID  容器运行镜像,前台运行。(备注生产中调试用)
[root@docker ~]# docker ps   # 运行完上一条命令查看容器,发现没有
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@docker ~]# docker ps -a   # 要指定command,可以看到/bin/bash了一下,容器刷新一下就挂掉了
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS                      PORTS     NAMES
45861729009d   eeb6ee3f44bd   "/bin/bash"   22 seconds ago   Exited (0) 20 seconds ago             nifty_hermann
354e1fb5eb93   hello-world    "/hello"      36 hours ago     Exited (0) 36 hours ago               infallible_aryabhata

# 正确使用
[root@docker ~]# docker run -it eeb6ee3f44bd /bin/bash #分配伪终端启动容器。如果默认命令可以hold住退出容器,容器不消亡。如果hold 不住,则容器消亡。
[root@9954d6e3cb32 /]#     # 可以看到主机名变成了容器ID,证明成功进入
# 在容器内使用df -h 、free -h、lscpu等命令查看得到的都是宿主机的资源
# 可以使用ip a查看ip进行判断
[root@9954d6e3cb32 /]# yum -y install net-tools
[root@9954d6e3cb32 /]# ifconfig   # 会发现IP地址是172开头的,同时宿主机也有一张网卡容器的IP地址就是来源它;如果容器存活,宿主机还有一张对应的网卡,反之
[root@9954d6e3cb32 /]# exit   # 退出容器,不存活


# 错误后台使用
[root@docker ~]# docker run -d eeb6ee3f44bd /bin/bash   # 输出结果看起来启动了,实际并没有;有一些可以不接command,因为容器里面已经写好
68928d357d8bd801d4442df50d5c3f28c2a245c3e8864268c74055c8aafe1b74
[root@docker ~]# docker ps   # 因为后台运行/bin/bash就是刷新一下重新分配一个终端,所以容器就挂掉了
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

# 应挂载文件与开放端口
[root@docker ~]# docker run -d eeb6ee3f44bd   # 后台运行镜像容器,一般还需要开放端口和挂载文件等

删除容器

# 单一删除
[root@docker ~]# docker ps -a

[root@docker ~]# docker rm 354e1fb5eb93   # 通过容器id来删除容器
354e1fb5eb93

[root@docker ~]# docker rm awesome_dirac   # 通过容器名字来删除容器
awesome_dirac


# 批量删除
[root@docker ~]# docker ps -a -q   # 批量显示容器id
9954d6e3cb32
45861729009d
[root@docker ~]# docker rm `docker ps -q -a`   # 通过id批量删除容器
9954d6e3cb32
45861729009d

查看容器详细信息

[root@docker ~]# docker run -d eeb6ee3f44bd   # 返回容器ID
af0ba7c7c3a7086c0b3d9623e90acae36660f6ff2df467d14a59edbe3eefe96f
[root@docker ~]# docker inspect af0ba7   # 接容器ID前几位数即可,但并没有运行起来,所以没有网络信息,因为docker是前台运行的,前文有说到

镜像仓库

使用阿里云的镜像仓库,请自行创建好(容器镜像服务https://cr.console.aliyun.com/cn-hangzhou/instances)

# 举例
# 推送
docker login --username=注册的阿里云仓库账号或者默认dockerhub  registry.cn-shenzhen.aliyuncs.com(跟仓库域名)
docker tag 镜像id registry.cn-shenzhen.aliyuncs.com/adif0028(账号空间)/centos(账号仓库):[自定义镜像版本号]
docker push registry.cn-shenzhen.aliyuncs.com/adif0028/centos:[自定义镜像版本号]

# 通过docker ps查看会发现多了一个相当于软链接的镜像

# 拉取取决于是公开还是私有,在阿里云选择不同的网络拉取

image-20221107154026902

删除镜像

# 单一删除

# 删除hello-wold镜像
[root@docker ~]# docker images

[root@docker ~]# docker rmi feb5d9fea6a5   # docker rmi 镜像id/镜像名 (备注如果镜像间有父子镜像关系是不能被删除的,已经被容器运行起来的镜像也不允许删除)


# 批量删除
[root@docker ~]# docker images -q   # 显示所有镜像ID
ba6acccedd29
eeb6ee3f44bd
[root@docker ~]# docker rmi $(docker images -q)   # 通过镜像id批量删除镜像

搜索镜像

[root@docker ~]# docker search nginx
NAME      DESCRIPTION      STARS     OFFICIAL   AUTOMATED

# 表格包含五列,含义如下:
1.NAME:镜像仓库名称。
2.DESCRIPTION:镜像仓库描述。
3.STARS:镜像仓库收藏数,表示该镜像仓库的受欢迎程度,类似于GitHub的Stars。
4.OFFICAL:表示是否为官方仓库,该列标记为[OK]的镜像均由各软件的官方项目组创建和维护。由结果可知,java这个镜像仓库是官方仓库,而其他的仓库都不是镜像仓库。
5.AUTOMATED:表示是否是自动构建的镜像仓库。


# 选用镜像建议
1.优先考虑官方的
2.Stars数多的



# 运行一个nginx容器:
# pull一个nginx镜像注意选择合适版本
[root@docker ~]# docker pull nginx
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    605c77e624dd   4 months ago   141MB
ubuntu       latest    ba6acccedd29   7 months ago   72.8MB
centos       7         eeb6ee3f44bd   8 months ago   204MB

# 拉取一个最小系统镜像alpine
[root@docker ~]# docker pull alpine
[root@docker ~]# docker pull nginx:stable-alpine   # 拉取以alpine为底层镜像的nginx
[root@docker ~]# docker images
REPOSITORY   TAG             IMAGE ID       CREATED        SIZE
nginx        latest          605c77e624dd   4 months ago   141MB
alpine       latest          c059bfaa849c   5 months ago   5.59MB
nginx        stable-alpine   373f8d4d4c60   6 months ago   23.2MB
ubuntu       latest          ba6acccedd29   7 months ago   72.8MB
centos       7               eeb6ee3f44bd   8 months ago   204MB
[root@docker ~]# docker run -d -p 80:80 373f8d4d4c60   # 启动以alpine为底层镜像的nginx,-p端口映射,宿主机的80映射到容器里面的80
f8c67ad2a29bb87f45a2c5f7339e390efc72fd72c91959a440431e0768025f9d
[root@docker ~]# docker ps   # 检查
# 浏览器打开宿主机IP:80

进入已经运行的容器

[root@docker ~]# docker exec -it f8c67ad2a29b /bin/sh   # alpine没有bash的只有sh
/ # exit
[root@docker ~]#       # 退出后容器仍然存活 

[root@docker ~]# docker ps   # 检查发现command是容器里面写好的一个脚本




#进入容器:
#     进入容器(目的,调试,排错)
#     	docker exec  (会分配一个新的终端tty)
#		docker exec [OPTIONS] CONTAINER COMMAND [ARG...]		
#     docker exec -it  容器id或容器名字 /bin/bash(/bin/sh)

docker attach(使用同一个终端)

# attach是同时操作同步的
# docker attach :连接到正在运行中的容器

# 终端1
[root@docker ~]# docker images
REPOSITORY   TAG             IMAGE ID       CREATED        SIZE
nginx        latest          605c77e624dd   4 months ago   141MB
alpine       latest          c059bfaa849c   5 months ago   5.59MB
nginx        stable-alpine   373f8d4d4c60   6 months ago   23.2MB
ubuntu       latest          ba6acccedd29   7 months ago   72.8MB
centos       7               eeb6ee3f44bd   8 months ago   204MB

[root@docker ~]# docker run -it ba6acccedd29
root@5eb73951fddc:/#

# 终端2
[root@docker ~]# docker attach 5eb73951fddc   # 接容器ID


# exec是重新分配一个终端,attach是使用同一个终端

#     docker attach(使用同一个终端)
#           docker attach [OPTIONS] CONTAINER 
#     nsenter(安装yum install -y util-linux 弃用)

宿主机挂载文件进容器

# 拉去一个mysql5.7的容器
[root@docker ~]# docker pull mysql:5.7
[root@docker ~]# docker images   # 检查

[root@docker ~]# yum install -y lsof   # 安装lsof
[root@docker ~]# lsof -i :3306   # 检查3306端口是否被占用

# -e 传入一个环境变量,可以是字符串也可以是文件
[root@docker ~]# docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD="123456" c20987f18b13
[root@docker ~]# docker ps   # 验证
# 使用navicat连接验证

2022-05-21_104502

# 暴力结束所以运行中的容器(慎重)
[root@docker ~]# docker rm -f `docker ps -a -q`   # 使用-f参数

# 在宿主机创建挂载数据库文件目录
[root@docker ~]# mkdir /opt/mysql_data

# 使用-v参数,宿主机的挂载源挂到容器里面挂载点上;对应容器mysql就是/var/lib/mysql,这里是容器内生成数据的目录
[root@docker ~]# docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD="123456" -v /opt/mysql_data/:/var/lib/mysql c20987f18b13

[root@docker ~]# docker ps   # 验证

# 测试把容器删掉,宿主机上数据目录里面的数据是否还在
[root@docker ~]# cd /opt/mysql_data/
[root@docker mysql_data]# ls
[root@docker mysql_data]# docker stop e05cb1581c9d   # 停止容器
e05cb1581c9d
[root@docker mysql_data]# docker rm e05cb1581c9d
e05cb1581c9d
[root@docker mysql_data]# docker ps -a
[root@docker mysql_data]# ls   # 仍存在


# 所以当把数据目录放在宿主机上是可以做到防止重要数据丢失,可是生产上还是不建议使用容器数据库
# 数据库容器存货时,宿主机数据库目录会发现有一个临时文件ibtmp1,容器消亡后临时文件z不存在
# 进入容器新创库删掉看看是否会初始化覆盖掉造成数据丢失
[root@docker mysql_data]# docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD="123456" -v /opt/mysql_data/:/var/lib/mysql c20987f18b13
db2a557bb47c3dff4ef6f43d2beee7f784047c1ba1c37344f1eb9b6312276a5b

[root@docker mysql_data]# docker exec -it db2a557 /bin/bash

root@db2a557bb47c:/# mysql -uroot -p 
Enter password: 
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

mysql> create database shy charset utf8mb4;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| shy                |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> exit
Bye
root@db2a557bb47c:/# exit
exit


[root@docker mysql_data]# ls   # 发现刚新创的数据库文件

# 重新挂载验证是否有刚刚新创的库
[root@docker mysql_data]# docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD="123456" -v /opt/mysql_data/:/var/lib/mysql c20987f18b13

[root@docker mysql_data]# docker exec -it 1e13f80 /bin/bash
root@1e13f807e359:/# mysql -uroot -p123456 -e "show databases"   # 没有影响,新创的库还在;证明没有初始化
# 杀死容器
	docker kill container_name   # ps查看的任务码非0,非0是不正常退出,程序内部错误
# 查看容器列表
    docker ps
	docker ps –a 

导入导出镜像

# 导出
# 格式:docker save [OPTIONS] IMAGE [IMAGE...]
OPTIONS:可选参数
IMAGE:镜像
OPTIONS的常用值
-o string: 指定目标文件,和linux原生命令>有相同作用

# docker save 镜像id/镜像名 > /opt/alpine.tar   用镜像id导出来的是废镜像<none>
# docker save -o /opt/alpine.tar 镜像名 

# 导出镜像
	docker save -o 否则导入镜像没有镜像标签以及名字 
	例子:docker image save centos > docker-centos7.4.tar.gz
#导入镜像
	docker load  例子:docker image load -i docker-centos7.4.tar.gz
# load命令可以从指定文件中加载镜像,该文件需要是save命令保存的文件
# 将alpine镜像打包成alpine.tar
[root@docker ~]# docker images
REPOSITORY   TAG             IMAGE ID       CREATED        SIZE
nginx        latest          605c77e624dd   4 months ago   141MB
mysql        5.7             c20987f18b13   5 months ago   448MB
alpine       latest          c059bfaa849c   5 months ago   5.59MB
nginx        stable-alpine   373f8d4d4c60   6 months ago   23.2MB
ubuntu       latest          ba6acccedd29   7 months ago   72.8MB
centos       7               eeb6ee3f44bd   8 months ago   204MB

[root@docker ~]# docker save c059bfaa849c > /opt/alpine.tar   # 没有使用-o指定名字导出来的是废镜像


# 导入
# docker load < 文件来源 或者 docker load -i 文件来源

[root@docker ~]# docker rmi c059bfaa849c
[root@docker ~]# docker load < /opt/alpine.tar 
8d3ac3489996: Loading layer [==================================================>]  5.866MB/5.866MB
Loaded image ID: sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18
[root@docker ~]# docker images
REPOSITORY   TAG             IMAGE ID       CREATED        SIZE
nginx        latest          605c77e624dd   4 months ago   141MB
mysql        5.7             c20987f18b13   5 months ago   448MB
<none>       <none>          c059bfaa849c   5 months ago   5.59MB    # 没有指定名字识别不出来,是废镜像
nginx        stable-alpine   373f8d4d4c60   6 months ago   23.2MB
ubuntu       latest          ba6acccedd29   7 months ago   72.8MB
centos       7               eeb6ee3f44bd   8 months ago   204MB
[root@docker ~]# docker rmi c059bfaa849c
Deleted: sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18
Deleted: sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759
[root@docker ~]# docker load -i /opt/alpine.tar


# 正确导出与导入一
[root@docker ~]# docker save -o /opt/alpine.tar alpine:latest
[root@docker ~]# docker rmi c059bfaa849c
[root@docker ~]# docker load -i /opt/alpine.tar

导入导出容器

#export:将容器打包成一个文件
#export命令可以将容器打包到一个文件中,它和save命令比较容易混淆
#export和save的不同之处在于:export打包的是容器,save打包的是镜像
#export打包的是容器当时的快照,至于容器的历史记录和元数据信息都会丢失。还有,export的文件在被import成一个镜像时,可以重新指定镜像的名称和版本号


#格式:docker export [OPTIONS] CONTAINER
OPTIONS:可选参数
CONTAINER:容器
OPTIONS的常用值
-o string: 指定打包文件
export常用写法
将my-boot容器打包到my-boot.tar文件



# 由容器导出镜像:
        docker export -o 名字.tar.gz 容器名字/id
        docker import 名字.tar.gz 另外命名  (注意export模式会把默认命令取消掉。启动时要指定默认命令)
#        例如:
        docker run -d -p80:80 4ce44d891b27 /docker-entrypoint.sh nginx -g 'daemon off;'
        
# import可以从本地文件或远程文件中导入镜像到本地仓库;如果是从文件中导入,这个文件需要是export命令导出的文件
[root@docker ~]# docker rm -f `docker ps -a -q`
4250861b2dd5
1e13f807e359
[root@docker ~]# docker run -d -p 80:80 373f8d4d4c60
c5061caffa08793ae6b3afcb69c6032b4ffdce47c319fa3ab73ebeb7a5f54ccb
[root@docker ~]# docker ps

[root@docker ~]# docker exec -it c5061caffa08 /bin/sh
/ # vi /usr/share/nginx/html/index.html
# 更改如下
This is 70
/ # exit

[root@docker ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                               NAMES
c5061caffa08   373f8d4d4c60   "/docker-entrypoint.…"   4 minutes ago   Up 4 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp   relaxed_wescoff

[root@docker ~]# docker export -o /opt/seven.tar.gz c5061caffa08   # 导出


# 导入并启动
# 可以直接创建导入,也可以重新打标签和备注
# 从/opt/seven.tar.gz文件创建镜像,并指定镜像名称为seven、版本号为v1
[root@docker ~]# docker import /opt/seven.tar.gz seven:v1
sha256:b95540f0c1470c5969c64f4e842d477849d98141f5774aede97f943e97c51f83
[root@docker ~]# docker images
REPOSITORY   TAG             IMAGE ID       CREATED          SIZE
seven        v1              b95540f0c147   14 seconds ago   22.9MB
nginx        latest          605c77e624dd   4 months ago     141MB
mysql        5.7             c20987f18b13   5 months ago     448MB
alpine       latest          c059bfaa849c   5 months ago     5.59MB
nginx        stable-alpine   373f8d4d4c60   6 months ago     23.2MB
ubuntu       latest          ba6acccedd29   7 months ago     72.8MB
centos       7               eeb6ee3f44bd   8 months ago     204MB

# 启动,因为容器所有元信息都没有,所以启动需要/docker-entrypoint.sh nginx -g 'daemon off;'

[root@docker ~]# docker run -d -p 90:80 b95540f0c147 /docker-entrypoint.sh nginx -g 'daemon off;'
b1d6af7610591327697f23fc5771fa153ed9ce8508bf47921246c313e3841eb4
[root@docker ~]# docker ps
# 浏览器打开90

镜像与容器的导入导出总结

  1. save命令打包的是镜像,包含镜像的所有信息
  2. exprot命令打包的是容器,只是保存容器当时的快照,历史记录和元数据信息将会丢失
  3. export和save的不同之处在于:export打包的是容器,save打包的是镜像
  4. 保存镜像(保存镜像载入后获得跟原镜像id相同的镜像)
  5. 保存容器(保存容器载入后获得跟原镜像id不同的镜像)

Dockerfile

Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

1、FROM
格式:FROM <image>或 FROM <image>:<tag>
基础镜像来源,必须在第一行指令中指定,不指定标记则默认为latest。

2、LABEL
格式:LABEL <name>=<value>
指定添加元数据到镜像,可指定多个标签信息。

3、RUN
格式:RUN <command>
每条指令将在当前镜像基础上执行,并提交为新的镜像。

4、CMD
格式:CMD <command>
指定启动容器时执行的命令,每个Dockerfile只能有一条CMD指令,如果指定了多条CMD指令,则只会执行最后一条CMD指令。如果在启动镜像时指定了启动指令,则镜像预设的CMD指令不执行。一般用于执行容器时提供默认值。

5、EXPOSE
格式:EXPOSE <port>
指定镜像启动后暴露的端口,在容器启动时需要通过 -p 做端口映射

6、ENV
格式:ENV <key> <value>
指定环境变量,使用在构建阶段中的所有后续指令的环境。

7、ADD
格式:ADD  <src> <dest>
该指令会在<src>(本地文件系统或远程网络位置) 进行复制新文件,并将它们添加到容 路径上的文件系统中<dest>8、COPY
格式:COPY <src> <dest>
复制本地主机的 <src> (为 Dockerfile 所在目录的相对路径) 到容器中的 <dest>9、ENTRYPOINT
格式:ENTRYPOINT <command>
配置容器启动后执行的命令,并且不可被docker run提供的参数覆盖。如果指定了多条ENTRYPOINT指令,则只会执行最后一条ENTRYPOINT指令。

10、VOLUME
格式:VOLUME  <FileSystemMountPoint>
创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等

11USER
格式:USER <user>:<group> | USER <uid>:<gid>
指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。

12、WORKDIR
格式:WORKDIR <FileSystemPath>
为后续的 COPY、ADD、RUN、CMD、ENTRYPOINT 指令配置工作目录。(可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径, 则会基于之前命令指定的路径)

13、ARG
格式:ARG <varname>[=<value>]
该ARG指令定义了一个变量,用户可以docker build使用该--build-arg <varname>=<value> 标志在构建时将该变量传递给构建器。

14、ONBUILD 
格式:ONBUILD [INSTRUCTION]
配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令,就好像它已经FROM在下游指令之后立即插入一样 Dockerfile。

15、STOPSIGNAL
格式:STOPSIGNAL <signal>
设置将发送到容器的系统调用信号以退出。此信号可以是与内核的系统调用表中的位置匹配的有效无符号数,例如9,或SIGNAME格式的信号名,例如SIGKILL。

16、HEALTHCHECK heathcheck
格式:HEALTHCHECK [OPTIONS] CMD command
测试容器以检查它是否仍在工作。即使服务器进程仍在运行,这也可以检测到陷入无限循环且无法处理新连接的Web服务器等情况。当容器指定了运行状况检查时,除了正常状态外,它还具有运行状况。这个状态最初是starting。每当健康检查通过时,它就会变成healthy(以前所处的状态)。经过一定数量的连续失败后,它就变成了unhealthy。

17SHELL
格式:SHELL ["executable", "parameters"]SHELL指令允许覆盖用于shell命令形式的默认shell。Linux上的默认shell是["/bin/sh", "-c"],而在Windows上["cmd", "/S", "/C"]。该SHELL指令必须以JSON格式写入Dockerfile。
总结
FROM 开头必须是FROM注意一定是大写。后面跟镜像名字或者空(特殊写法)
MAINTAINER 声明作者是谁,可以省略。
ENV 声明环境变量,往镜像里注入需要的环境变量
COPY/ADD 都是把本地文件或者目录加入到镜像内,其中COPY可以覆盖文件,ADD与COPY区别在于有解压包的作用。
WORKDIR 声明工作目录在哪。构建镜像时会在容器内改目录一直操作,直到下一个WORKDIR出现或者RUN中出现cd命令。
RUN 执行主要命令和安装过程的关键字。注意RUN写的次数越少,镜像层就越少,建议所有操作只写一个RUN

dockerfile支持变量用,定义与引用与shell脚本相同

EXPOSE 暴露容器运行时默认的端口。
ENTRYPOINT/CMD 容器运行时默认运行的命令也就是pid 1进程命令。此命令在docker中要求必须hold住,容器才可以正常运行。这俩参数都可以生产pid 1运行命令,但是有区别,当两个关键字都存在时。ENTRYPOINT级别高于CMD,CMD运行内容会默认变成ENTRYPOINT的运行内容参数。从而两个参数形成一条运行命令。
centos-redis
[root@docker ~]# mkdir -p /docker/redis
[root@docker ~]# cd /docker/redis/
[root@docker redis]# wget http://download.redis.io/releases/redis-5.0.8.tar.gz
[root@docker redis]# ls
redis-5.0.8.tar.gz
[root@docker redis]# vim Dockerfile
FROM centos:7
WORKDIR /data
ADD redis-5.0.8.tar.gz /data
RUN yum install gcc gcc-c++ make -y && cd redis-5.0.8 && make && make install
EXPOSE 6379
CMD ["/data/redis-5.0.8/src/redis-server"]

[root@docker redis]# docker build -t redis:v1 .



# 验证
[root@docker redis]# docker images
REPOSITORY       TAG             IMAGE ID       CREATED         SIZE
redis            v1              9a8285dd6298   5 seconds ago   625MB

[root@docker redis]# docker run -d 9a8285dd6298
9eb3bcb1dacda4494aaa8d396bfc7a885ba6beda192cc6cf7a0b6937422a8633
[root@docker redis]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS      NAMES
9eb3bcb1dacd   9a8285dd6298   "/data/redis-5.0.8/s…"   5 seconds ago   Up 5 seconds   6379/tcp   naughty_rubin

[root@docker redis]# docker exec -it 9eb3bcb1dacd bash
[root@9eb3bcb1dacd data]# ls
redis-5.0.8

[root@9eb3bcb1dacd data]# ps -ef | grep redis
root          1      0  0 14:05 ?        00:00:00 /data/redis-5.0.8/src/redis-server *:6379
root         28     10  0 14:06 pts/0    00:00:00 grep --color=auto redis

[root@9eb3bcb1dacd data]# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> exit
不同启动方式,调用容器启动的第一个命令是不同的
[root@docker1 redis]# docker start 651cace10140
651cace10140
[root@docker1 redis]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
651cace10140        1fe9fbc1d6f5        "/bin/bash"         3 minutes ago       Up 2 seconds        6379/tcp            focused_allen


[root@docker1 redis]# docker run -d 1fe9fbc1d6f5 
15210e98c9ddb6098b815882e98606bc3607376899183d2612a131149f1889a4
[root@docker1 redis]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
15210e98c9dd        1fe9fbc1d6f5        "/data/redis-5.0.8/s…"   6 seconds ago       Up 5 seconds        6379/tcp            dreamy_borg

# 优化一
[root@docker redis]# vim Dockerfile
FROM centos:7
WORKDIR /data
ADD redis-5.0.8.tar.gz /data
RUN yum install gcc gcc-c++ make -y && cd redis-5.0.8 && make && make install \
    && cp /data/redis-5.0.8/src/redis-server /usr/local/bin && cp /data/redis-5.0.8/src/redis-cli /usr/local/bin \
    && cp /data/redis-5.0.8/redis.conf /etc/ && rm -rf /data/* && yum remove gcc gcc-c++ make -y && yum clean all
EXPOSE 6379
CMD ["redis-server"]


[root@docker redis]# docker build -t redis:v2 .
[root@docker redis]# docker images    # 可以看出v2经过优化比原来少了一半左右
REPOSITORY                                           TAG             IMAGE ID       CREATED          SIZE
redis                                                v2              18680627f22d   12 seconds ago   326MB
redis                                                v1              9a8285dd6298   20 minutes ago   625MB

# 验证
[root@docker redis]# docker run -d 18680627f22d
5a9d56c1caf2dee01c7070bd00904db47ec9281c45e5896db201e489798d71be
[root@docker redis]# docker ps
[root@docker redis]# docker exec -it 5a9d56c1caf2 bash
[root@5a9d56c1caf2 data]# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> exit
ubuntu_redis
[root@docker redis]# cp Dockerfile Dockerfile.bak
[root@docker redis]# vim Dockerfile
FROM ubuntu
WORKDIR /data
ADD redis-5.0.8.tar.gz /data
RUN sed  -i 's#archive.ubuntu.com#mirrors.aliyun.com#g' /etc/apt/sources.list && apt-get update \ 
    && apt-get install gcc  make -y && cd redis-5.0.8 && make && make install \
    && cp /data/redis-5.0.8/src/redis-server /usr/local/bin && cp /data/redis-5.0.8/src/redis-cli /usr/local/bin \
    && cp /data/redis-5.0.8/redis.conf /etc/
EXPOSE 6379
CMD ["redis-server"]

[root@docker redis]# docker build -t redis-ubuntu:v1 .

# 验证
[root@docker redis]# docker images
REPOSITORY                                           TAG             IMAGE ID       CREATED          SIZE
redis-ubuntu                                         v1              65ba35d38b5e   4 seconds ago    466MB

[root@docker redis]# docker ps   # 一般5s后不消亡都是成功的
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS      NAMES
de51550497e9   65ba35d38b5e   "redis-server"           11 seconds ago   Up 10 seconds   6379/tcp   dreamy_lewin

# 优化一
[root@docker redis]# vim Dockerfile
FROM ubuntu
WORKDIR /data
ADD redis-5.0.8.tar.gz /data
RUN sed  -i 's#archive.ubuntu.com#mirrors.aliyun.com#g' /etc/apt/sources.list && apt-get update \
    && apt-get install gcc  make -y && cd redis-5.0.8 && make && make install \
    && cp /data/redis-5.0.8/src/redis-server /usr/local/bin && cp /data/redis-5.0.8/src/redis-cli /usr/local/bin \
    && cp /data/redis-5.0.8/redis.conf /etc/ && rm -rf /data/* && apt-get remove gcc make -y && apt clean
EXPOSE 6379
CMD ["redis-server"]

[root@docker redis]# docker build -t redis-ubuntu:v2 .

# 验证
[root@docker redis]# docker images   # 可以看出v2经过优化比原来少了一半左右
REPOSITORY                                                  TAG             IMAGE ID       CREATED          SIZE
redis-ubuntu                                                v2              00880168900a   5 seconds ago    320MB
redis-ubuntu                                                v1              65ba35d38b5e   18 minutes ago   466MB

[root@docker redis]# docker ps 
CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS              PORTS      NAMES
99584cdb6957   00880168900a   "redis-server"           About a minute ago   Up About a minute   6379/tcp   cool_davinci
# 优化三  多阶段构建(可以不用别名用数字代替层数,也可以设置别名AS)

[root@docker redis]# vim Dockerfile
FROM ubuntu AS base
WORKDIR /data
ADD redis-5.0.8.tar.gz /data
RUN sed  -i 's#archive.ubuntu.com#mirrors.aliyun.com#g' /etc/apt/sources.list && apt-get update \
    && apt-get install gcc  make -y && cd redis-5.0.8 && make && make install

FROM ubuntu
COPY --from=base /data/redis-5.0.8/src/redis-server /usr/local/bin/
COPY --from=base /data/redis-5.0.8/src/redis-cli /usr/local/bin/
COPY --from=base /data/redis-5.0.8/redis.conf /etc/
EXPOSE 6379
CMD ["redis-server"]

[root@docker redis]# docker build -t redis-ubuntu:v3 .

# 验证
[root@docker redis]# docker images
REPOSITORY                                                  TAG             IMAGE ID       CREATED             SIZE
redis-ubuntu                                                v3              0c6f5f472e5a   3 minutes ago       90.8MB

[root@docker redis]# docker run -d 0c6f5f472e5a
24c64bd380f2c10b777515f322ddc488f59a375586f9cf6d1c30d756d90055de
[root@docker redis]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED             STATUS             PORTS      NAMES
24c64bd380f2   0c6f5f472e5a   "redis-server"           8 minutes ago       Up 8 minutes       6379/tcp   magical_spence
nginx-redis
[root@docker ~]# mkdir /docker/nginx-redis
[root@docker ~]# cd /docker/nginx-redis/
[root@docker nginx-redis]# ls
nginx-1.20.2.tar.gz  redis-5.0.8.tar.gz
[root@docker nginx-redis]# tar xf redis-5.0.8.tar.gz && cd redis-5.0.8
[root@docker redis-5.0.8]# sed -i "s/daemonize no/daemonize yes/g" redis.conf && cp redis.conf ../

[root@docker nginx-redis]# vim run.sh
[root@docker nginx-redis]# pwd
/docker/nginx-redis
[root@docker nginx-redis]# vim run.sh 
#!/bin/sh
echo "start nginx"
nginx
echo "start redis"
redis-server /etc/redis.conf
tail -f /dev/null


[root@docker nginx-redis]# vim Dockerfile
FROM centos:7
WORKDIR /data
ADD redis-5.0.8.tar.gz /data
ADD nginx-1.20.2.tar.gz /data
COPY redis.conf /etc/redis.conf
COPY run.sh /run.sh
RUN yum install gcc gcc-c++ make prce-devel openssl-devel -y && chmod a+x /run.sh \
    && cd redis-5.0.8 && make && make install \
    && cp /data/redis-5.0.8/src/redis-server /usr/local/bin && cp /data/redis-5.0.8/src/redis-cli /usr/local/bin \
    && cd /data/nginx-1.20.2 && useradd www -s /sbin/nologin \
    && CONFIG="\
       --prefix=/usr/local/nginx \
       --with-http_stub_status_module \
       --with-http_v2_module \
       --with-http_ssl_module  \
       --with-http_gzip_static_module \
       --with-http_realip_module  \
       --with-http_flv_module \
       --with-stream \
       --sbin-path=/usr/sbin/nginx \
       --modules-path=/usr/lib/nginx/modules \
       --conf-path=/usr/local/nginx/conf/nginx.conf \
       --user=www \
       --group=www \
      " \
    && ./configure $CONFIG && make && make install \
    && rm -rf /data/* && yum remove gcc gcc-c++ make -y && yum clean all
EXPOSE 6379
EXPOSE 80
ENTRYPOINT ["/bin/sh","-c"]
CMD ["/run.sh"]


[root@docker nginx-redis]# docker build -t nginx-redis:nr-v1 .

[root@docker nginx-redis]# docker images
REPOSITORY                                                  TAG       IMAGE ID       CREATED              SIZE
nginx-redis                                                 nr-v1     0a044c0707b0   About a minute ago   349MB

[root@docker nginx-redis]# docker run -d 0a044c0707b0
5e915a45e4c8b0dd115f8f4a8dd10a6ad1ae9a92e6bd0b06ca7abcd4da075d6c
[root@docker nginx-redis]# docker ps
CONTAINER ID   IMAGE          COMMAND                CREATED          STATUS          PORTS              NAMES
5e915a45e4c8   0a044c0707b0   "/bin/sh -c /run.sh"   5 seconds ago    Up 5 seconds    80/tcp, 6379/tcp   silly_germain

[root@docker nginx-redis]# docker exec -it 5e915a45e4c8 bash
[root@5e915a45e4c8 data]# ps -ef          
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 17:14 ?        00:00:00 /bin/sh /run.sh
root          7      1  0 17:14 ?        00:00:00 nginx: master process nginx
www           9      7  0 17:14 ?        00:00:00 nginx: worker process
root         10      1  0 17:14 ?        00:00:00 redis-server 127.0.0.1:6379
root         14      1  0 17:14 ?        00:00:00 tail -f /dev/null
root         15      0  0 17:14 pts/0    00:00:00 bash
root         33     15  0 17:15 pts/0    00:00:00 ps -ef
# 优化

[root@docker nginx-redis]# vim Dockerfile
FROM centos:7
WORKDIR /data
ADD redis-5.0.8.tar.gz /data
ADD nginx-1.20.2.tar.gz /data
RUN yum install gcc gcc-c++ make prce-devel openssl-devel -y \
    && cd redis-5.0.8 && make && make install \
    && cd /data/nginx-1.20.2 && useradd www -s /sbin/nologin \
    && CONFIG="\
       --prefix=/usr/local/nginx \
       --with-http_stub_status_module \
       --with-http_v2_module \
       --with-http_ssl_module  \
       --with-http_gzip_static_module \
       --with-http_realip_module  \
       --with-http_flv_module \
       --with-stream \
       --sbin-path=/usr/sbin/nginx \
       --modules-path=/usr/lib/nginx/modules \
       --conf-path=/usr/local/nginx/conf/nginx.conf \
       --user=www \
       --group=www \
      " \
    && ./configure $CONFIG && make && make install 
FROM centos:7
COPY redis.conf /etc/redis.conf
COPY run.sh /run.sh
COPY --from=0 /data/redis-5.0.8/src/redis-server /usr/local/bin/
COPY --from=0 /data/redis-5.0.8/src/redis-cli /usr/local/bin/
COPY --from=0 /data/redis-5.0.8/redis.conf /etc/
COPY --from=0 /usr/local/nginx /usr/local/nginx
COPY --from=0 /usr/sbin/nginx /usr/sbin/
COPY --from=0 /lib64 /lib64
RUN useradd www -s /sbin/nologin && chmod a+x /run.sh
EXPOSE 6379
EXPOSE 80
ENTRYPOINT ["/bin/sh","-c"]
CMD ["/run.sh"]


[root@docker nginx-redis]# docker build -t nginx-redis:nr-v2 .

[root@docker nginx-redis]# docker images
REPOSITORY                                                  TAG       IMAGE ID       CREATED             SIZE
nginx-redis                                                 nr-v2     79991815f3f0   42 seconds ago      306MB


[root@docker nginx-redis]# docker run -d 79991815f3f0
529d0163efdabc56db95195da1e90f2e5667d57bf0c121c1b07fc914cb100913
[root@docker nginx-redis]# docker ps
CONTAINER ID   IMAGE          COMMAND                CREATED          STATUS          PORTS              NAMES
529d0163efda   79991815f3f0   "/bin/sh -c /run.sh"   38 seconds ago   Up 37 seconds   80/tcp, 6379/tcp   laughing_mayer
[root@docker nginx-redis]# docker exec -it 529d0163efda bash
[root@529d0163efda /]# ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 17:56 ?        00:00:00 /bin/sh /run.sh
root          8      1  0 17:56 ?        00:00:00 nginx: master process nginx
root          9      1  0 17:56 ?        00:00:00 redis-server 127.0.0.1:6379
www          10      8  0 17:56 ?        00:00:00 nginx: worker process
root         14      0  0 17:56 pts/0    00:00:00 bash
root         28     14  0 17:56 pts/0    00:00:00 ps -ef
# 写法二
[root@docker nginx-redis]# vim Dockerfile 
FROM centos:7
WORKDIR /data
ADD redis-5.0.8.tar.gz /data
ADD nginx-1.20.2.tar.gz /data
RUN yum install gcc gcc-c++ make prce-devel openssl-devel -y \
    && cd redis-5.0.8 && make && make install \
    && cd /data/nginx-1.20.2 && useradd www -s /sbin/nologin \
    && CONFIG="\
       --prefix=/usr/local/nginx \
       --with-http_stub_status_module \
       --with-http_v2_module \
       --with-http_ssl_module  \
       --with-http_gzip_static_module \
       --with-http_realip_module  \
       --with-http_flv_module \
       --with-stream \
       --sbin-path=/usr/sbin/nginx \
       --modules-path=/usr/lib/nginx/modules \
       --conf-path=/usr/local/nginx/conf/nginx.conf \
       --user=www \
       --group=www \
      " \
    && ./configure $CONFIG && make && make install 
FROM centos:7
COPY run.sh /run.sh
COPY --from=0 /data/redis-5.0.8/src/redis-server /usr/local/bin/
COPY --from=0 /data/redis-5.0.8/src/redis-cli /usr/local/bin/
COPY --from=0 /data/redis-5.0.8/redis.conf /etc/
COPY --from=0 /usr/local/nginx /usr/local/nginx
COPY --from=0 /usr/sbin/nginx /usr/sbin/
COPY --from=0 /lib64 /lib64
RUN useradd www -s /sbin/nologin && chmod a+x /run.sh  && sed -i "s/daemonize no/daemonize yes/g" /etc/redis.conf
EXPOSE 6379
EXPOSE 80
ENTRYPOINT ["/bin/sh","-c"]
CMD ["/run.sh"]



[root@docker nginx-redis]# docker build -t nginx-redis:nr-v3 .

[root@docker nginx-redis]# docker images
REPOSITORY                                                  TAG       IMAGE ID       CREATED          SIZE
nginx-redis                                                 nr-v3     48b050033b9d   9 seconds ago    306MB

[root@docker nginx-redis]# docker run -d 48b050033b9d
dea9e5ef0b8ac70a52aa157f16eafaef35edd880546b69e8528c553bd8256c10
[root@docker nginx-redis]# docker ps
CONTAINER ID   IMAGE          COMMAND                CREATED          STATUS          PORTS              NAMES
dea9e5ef0b8a   48b050033b9d   "/bin/sh -c /run.sh"   53 seconds ago   Up 53 seconds   80/tcp, 6379/tcp   loving_lovelace
自写mysql镜像
[root@docker ~]# mkdir /docker/lnmp
[root@docker ~]# cd !$
[root@docker lnmp]# ls
mysql-5.7.30-linux-glibc2.12-x86_64.tar.gz  

[root@docker lnmp]# vim Dockerfile
FROM centos:7
WORKDIR /usr/local/
COPY my.cnf /etc/my.cnf
COPY run.sh /run.sh
ADD mysql-5.7.30-linux-glibc2.12-x86_64.tar.gz /usr/local/
RUN yum install -y libaio-devel numactl-devel && yum clean all \
    && mv mysql-5.7.30-linux-glibc2.12-x86_64 mysql \
    && useradd mysql -s /sbin/nologin \
    && mkdir -p /data/mysql \
    && mkdir -p /var/log/mysql \
    && mkdir -p /data/binlog/ \
    && chmod o+w /data/ \
    && chown mysql:mysql -R /usr/local/mysql /data/mysql /var/log/mysql /data/binlog/ /etc/my.cnf \
    && echo 'export PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile \
    && source /etc/profile \
    && echo 'source /etc/profile'>> /root/.bashrc \
    && chmod a+x /run.sh
EXPOSE 3306
ENTRYPOINT ["/bin/sh","-c"]
CMD ["/run.sh"] 

[root@docker lnmp]# cat my.cnf 
[mysqld]
user=mysql 
basedir=/usr/local/mysql        
datadir=/data/mysql             
server_id=1                         
port=3306                           
socket=/data/mysql/mysql.sock
log_bin=/data/binlog/mysql-bin
sync_binlog=1
binlog_format=row
        

[mysql]         
socket=/data/mysql/mysql.sock 

[mysqld_safe]
log-error=/var/log/mysql/mysql.log      
pid-file=/data/mysql/mysql.pid


[root@docker lnmp]# cat run.sh 
#!/bin/sh
#/usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf --user=mysql
#/usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql
/usr/local/mysql/bin/mysqld --initialize-insecure  --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql
/usr/local/mysql/support-files/mysql.server start

tail -f /dev/null


[root@docker lnmp]# docker build -t mysql:v1 .

复习

1、创建容器

docker run [参数] [镜像名称|ID] [CMD]

-d : 以守护进程运行
-e : 定义一个容器内部的环境变量
-i :打开标准输出
-t : 创建一个终端
-v : 挂载一个本地目录/文件到容器内部
--name : 指定容器的名称,将名称解析到Docker DNS 上
-P: 随机映射一个端口
-p :指定一个端口
--rm : 当容器的生命周期结束的时候立即自动删除容器
--link : 连接一个容器,单向链接
--restart=always 需要开机自启容器
--network

2、启动容器

docker start 容器名称|ID

3、停止容器

docker stop 容器名称|ID

4、查看容器列表

docker ps
-a : 查看所有的容器
-q : 仅查看容器ID

5、删除容器

docker rm [容器ID|名称]

-f : 强制删除

docker rm -f $(docker ps -a -q)

6、复制

# 由宿主主机复制到容器内部
docker cp [宿主主机路径]   [容器ID]:[容器内部的路径]

# 由容器内部复制到宿主主机
docker cp [容器ID]:[容器内部的路径] [宿主主机路径]   

7、进入容器

# exec : exec的设计目的实际上是在宿主主机外执行一个容器内部的命令
docker exec -it  [容器的ID|名称] [cmd]

# attach : 连接上容器内部PID=1的进程

# nsenter : 宿主主机的命令,

# ssh : 

数据卷

据卷的本质其实依然是宿主操作系统上的一个目录,只不过这个目录存放在 Docker 内部,接受 Docker 的管理。

数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:

  • 数据卷 可以在容器之间共享和重用
  • 对 数据卷 的修改会立马生效
  • 对 数据卷 的更新,不会影响镜像
  • 数据卷 默认会一直存在,即使容器被删除
[root@docker ~]# ls /   # 刚开始没有data目录
bin  boot  dev  docker  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

[root@docker ~]# docker run -d -v /data/web:/usr/share/nginx/html 605c77e624dd   # 选择挂载
7eb2ca32105517d58a5d012ce34366d9484ac974db42be2c7b24902e8acb1a44

[root@docker ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS     NAMES
7eb2ca321055   605c77e624dd   "/docker-entrypoint.…"   3 seconds ago   Up 2 seconds   80/tcp    suspicious_volhard

[root@docker ~]# ls /   # 可以看出尽管没有data目录,加了-v会自动创建
bin  boot  data  dev  docker  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

查看数据卷

[root@docker ~]# docker volume ls
DRIVER              VOLUME NAME
local               c608e204441ddf9e2d8bb66b655abde7f3ec44331d57947d965f1b5f1865e3d5
[root@docker1 volumes]# ll /var/lib/docker/volumes
总用量 24
drwxr-xr-x 3 root root    19 117 17:13 c608e204441ddf9e2d8bb66b655abde7f3ec44331d57947d965f1b5f1865e3d5
-rw------- 1 root root 32768 119 09:20 metadata.db

测试

当没有写明宿主机文件路径,会在哪里创建目录

[root@docker ~]# docker run -d -v uplooking:/usr/share/nginx/html 605c77e624dd
7c3611d9b12a47f5bf240ec024e3f0703eb4eae66e5f9abbd18ef124af40c17b

[root@docker ~]# docker volume ls   # 当不指定路径的时候就会生成一个卷
DRIVER    VOLUME NAME
local     uplooking

[root@docker ~]# docker volume inspect uplooking   # 查看卷的信息
[
    {
        "CreatedAt": "2022-05-28T23:05:16+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/uplooking/_data", #可以看到创建在这里,去到里面会发现nginx的一些文件也在里面
        "Name": "uplooking",
        "Options": null,
        "Scope": "local"
    }
]

创建卷

[root@docker ~]# docker volume create shy
shy
[root@docker ~]# docker volume create ls
ls
[root@docker ~]# docker volume ls
DRIVER    VOLUME NAME
local     ls
local     shy
local     uplooking


# 使用卷
[root@docker ~]# docker run -d -v ls:/usr/share/nginx/html 605c77e624dd
831316f118989ecb38e3bdaf9cb4a3fa4607b617f70331b7335e240091f6039d

[root@docker ~]# ll /var/lib/docker/volumes/ls/_data/   # 换了卷照样会在里面生成文件
50x.html    index.html

删除卷

# 正在使用的卷是不允许删除的
# docker volume rm 名字|ID

[root@docker ~]# docker volume rm shy
shy

docker修改存储位置

如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v 这个命令。

网络配置

bridge模式(默认)

  1. 当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
  2. 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。
  3. bridge模式是docker的默认网络模式,不写–net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。

host模式

  • 众所周知,Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
  • 例如,我们在10.10.101.105/24的机器上用host模式启动一个含有web应用的Docker容器,监听tcp80端口。当我们在容器中执行任何类似ifconfig命令查看网络环境时,看到的都是宿主机上的信息。而外界访问容器中的应用,则直接使用10.10.101.105:80即可,不用任何NAT转换,就如直接跑在宿主机中一样。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
[root@docker ~]# docker images
REPOSITORY                                            TAG              IMAGE ID       CREATED        SIZE
registry.cn-shenzhen.aliyuncs.com/xiaosu_shy/oldliu   nginx-php-74v3   38ec4b2456ca   2 weeks ago    564MB
nginx                                                 latest           605c77e624dd   5 months ago   141MB
mysql                                                 5.7              c20987f18b13   5 months ago   448MB
ubuntu                                                latest           ba6acccedd29   7 months ago   72.8MB
centos                                                7                eeb6ee3f44bd   8 months ago   204MB
# 使用host模式
[root@docker ~]# docker run -d --net=host 38ec4b2456ca
12217c0c6fb0411a763369ca7906ddd674ce75d5513154dc265593c122949ba3

# docker ps发现ports没有
[root@docker ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                CREATED         STATUS         PORTS     NAMES
12217c0c6fb0   38ec4b2456ca   "/run.sh /bin/sh -c"   9 seconds ago   Up 8 seconds             silly_ardinghelli


# 浏览器直接输入宿主机的IP地址

# 进入容器发现主机名没有变化而且目录变为根下
[root@docker ~]# docker exec -it 12217c0c6fb0 bash
[root@docker /]# yum install -y net-tools
[root@docker /]# ifconfig #可以看出容器内把宿主机的端口、网络等都映射进来;
坏处攻击这个容器的网络、端口其实就是攻击宿主机

[root@docker ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                CREATED         STATUS         PORTS     NAMES
12217c0c6fb0   38ec4b2456ca   "/run.sh /bin/sh -c"   7 minutes ago   Up 7 minutes             silly_ardinghelli

# 生产上不建议使用host模式
[root@docker ~]# docker inspect 12217c0c6fb0   # 发现host中IP地址是空的;因为用的是宿主机的


[root@docker ~]# docker rm -f 12217c0c6fb0
12217c0c6fb0

container模式

  • 在理解了host模式后,这个模式也就好理解了。这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
[root@docker ~]# docker images
REPOSITORY                                            TAG              IMAGE ID       CREATED        SIZE
registry.cn-shenzhen.aliyuncs.com/xiaosu_shy/oldliu   nginx-php-74v3   38ec4b2456ca   2 weeks ago    564MB
nginx                                                 latest           605c77e624dd   5 months ago   141MB
mysql                                                 5.7              c20987f18b13   5 months ago   448MB
ubuntu                                                latest           ba6acccedd29   7 months ago   72.8MB
centos                                                7                eeb6ee3f44bd   8 months ago   204MB
[root@docker ~]# docker run -d --name web nginx
bb9b6b9238f356ad9888a0a4bf2ffdff113e83874fb39415e1d6ff356119f4b3

[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
bb9b6b9238f3   nginx     "/docker-entrypoint.…"   7 seconds ago   Up 6 seconds   80/tcp    web

#格式:docker run -d --net=container:容器名或容器ID 镜像ID
[root@docker ~]# docker run -d --net=container:web 38ec4b2456ca   # 命名一个容器为web,采用container网络模式
8d730393288ecc660d6113a6810549c6bd1b65eee6c232649b99174d72d352c7

[root@docker ~]# docker ps   # 发现采用container网络模式的容器没有ports
CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS              PORTS     NAMES
8d730393288e   38ec4b2456ca   "/run.sh /bin/sh -c"     2 seconds ago        Up 1 second                   epic_lichterman
bb9b6b9238f3   nginx          "/docker-entrypoint.…"   About a minute ago   Up About a minute   80/tcp    web
# 进入container网络模式的容器
[root@docker ~]# docker exec -it 8d730393288e bash   # 进去发现主机名并不是这个容器的id,而是另外一个容器的id
[root@bb9b6b9238f3 /]# cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.2	bb9b6b9238f3
# 具体看图

[root@docker ~]# docker inspect 8d730393288e   # 详细信息里host也是无IP地址的

none模式(了解)

  • 这个模式和前两个不同。在这种模式下,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
[root@docker ~]# docker run -d --net=none 38ec4b2456ca
d5e9ec254eafc5c47cbad75de5e9fd8013597e62ae1ea9473d541821e4fcc9a3
[root@docker ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS     NAMES
d5e9ec254eaf   38ec4b2456ca   "/run.sh /bin/sh -c"     4 seconds ago    Up 3 seconds              sad_mccarthy
8d730393288e   38ec4b2456ca   "/run.sh /bin/sh -c"     10 minutes ago   Up 10 minutes             epic_lichterman
bb9b6b9238f3   nginx          "/docker-entrypoint.…"   11 minutes ago   Up 11 minutes   80/tcp    web

[root@docker ~]# docker inspect d5e9ec254eaf

# 这种模式容器里只有一张网卡lo

网络模式区别
bridge与宿主机共享网卡,会产生一张虚拟网卡
host直接与宿主机共用网卡,不会产生虚拟网卡
container与其它容器共用网卡,也不会产生虚拟网卡
none需要手动配置网卡配置

总结

None:不为容器配置任何网络功能,–net=none
Container:与另一个运行中的容器共享Network Namespace,–net=container:containerID(K8S)
Host:与宿主机共享Network Namespace,–net=host
Bridge:Docker设计的NAT网络模型

Docker compose

**Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。从功能上看,跟 OpenStack 中的 Heat 十分类似。**

其代码目前在 https://github.com/docker/compose 上开源。

Compose 定位是 「定义和运行多个 Docker 容器的应用(Defining and running multi-container Docker applications)」,其前身是开源项目 Fig。

Docker-Compose将所管理的容器分为三层,分别是工程(project),服务(service)以及容器(container)。Docker-Compose运行目录下的所有文件(docker-compose.yml,extends文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像,参数,依赖。一个服务当中可包括多个容器实例,Docker-Compose并没有解决负载均衡的问题,因此需要借助其它工具实现服务发现及负载均衡。

Docker-Compose的工程配置文件默认为docker-compose.yml,可通过环境变量COMPOSE_FILE或-f参数自定义配置文件,其定义了多个有依赖关系的服务及每个服务运行的容器。

使用一个Dockerfile模板文件,可以让用户很方便的定义一个单独的应用容器。在工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个Web项目,除了Web服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。

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

Docker-Compose项目由Python编写,调用Docker服务提供的API来对容器进行管理。因此,只要所操作的平台支持Docker API,就可以在其上利用Compose来进行编排管理。

Docker-compose模板文件简介

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

Compose模板文件是一个定义服务、网络和卷的YAML文件。Compose模板文件默认路径是当前目录下的docker-compose.yml,可以使用.yml或.yaml作为文件扩展名。

Docker-Compose标准模板文件应该包含version、services、networks 三大部分,最关键的是services和networks两个部分。Compose目前有三个版本分别为Version 1,Version 2,Version 3,Compose区分Version 1和Version 2(Compose 1.6.0+,Docker Engine 1.10.0+)。Version 2支持更多的指令。Version 1将来会被弃用。更详细看版本与协议的关系

image

image是指定服务的镜像名称或镜像ID。如果镜像在本地不存在,Compose将会尝试拉取镜像。

services:
    web:
        image: hello-world
build

服务除了可以基于指定的镜像,还可以基于一份Dockerfile,在使用up启动时执行构建任务,构建标签是build,可以指定Dockerfile所在文件夹的路径。Compose将会利用Dockerfile自动构建镜像,然后使用镜像启动服务容器。

build: /path/ to /build/dir

也可以是相对路径,只要上下文确定就可以读取到Dockerfile

build: ./dir

设定上下文根目录,然后以该目录为准指定Dockerfile

build:
  context: ../
  dockerfile: path/ of /Dockerfile

build都是一个目录,如果要指定Dockerfile文件需要在build标签的子级标签中使用dockerfile标签指定。

如果同时指定image和build两个标签,那么Compose会构建镜像并且把镜像命名为image值指定的名字

context

context选项可以是Dockerfile的文件路径,也可以是到链接到git仓库的url,当提供的值是相对路径时,被解析为相对于撰写文件的路径,此目录也是发送到Docker守护进程的context

build:
  context: ./dir
dockerfile

使用dockerfile文件来构建,必须指定构建路径

build:
  context: .
  dockerfile: Dockerfile-alternate
commond

使用command可以覆盖容器启动后默认执行的命令

command: bundle exec thin -p 3000
container_name

Compose的容器名称格式是:<项目名称><服务名称><序号>

可以自定义项目名称、服务名称,但如果想完全控制容器的命名,可以使用标签指定:

container_name: app
depends_on

在使用Compose时,最大的好处就是少打启动命令,但一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。例如在没启动数据库容器的时候启动应用容器,应用容器会因为找不到数据库而退出。depends_on标签用于解决容器的依赖、启动先后的问题

version: '2'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

上述YAML文件定义的容器会先启动redis和db两个服务,最后才启动web 服务

PID
pid: "host"

将PID模式设置为主机PID模式,跟主机系统共享进程命名空间。容器使用pid标签将能够访问和操纵其他容器和宿主机的名称空间

ports

ports用于映射端口的标签。

使用HOST:CONTAINER格式或者只是指定容器的端口,宿主机会随机映射端口

ports:
 - "3000"
 - "8000:8000"
 - "49100:22"
 - "127.0.0.1:8001:8001"

当使用HOST:CONTAINER格式来映射端口时,如果使用的容器端口小于60可能会得到错误得结果,因为YAML将会解析xx:yy这种数字格式为60进制。所以建议采用字符串格式。

extra_hosts

添加主机名的标签,会在/etc/hosts文件中添加一些记录

extra_hosts:
 - "somehost:162.242.195.82"
 - "otherhost:50.31.209.229"
volumes

挂载一个目录或者一个已存在的数据卷容器,可以直接使用 [HOST:CONTAINER]格式,或者使用[HOST:CONTAINER:ro]格式,后者对于容器来说,数据卷是只读的,可以有效保护宿主机的文件系统。

Compose的数据卷指定路径可以是相对路径,使用 . 或者 … 来指定相对目录。

数据卷的格式可以是下面多种形式

volumes:
  // 只是指定一个路径,Docker 会自动在创建一个数据卷(这个路径是容器内部的)。
  - /var/lib/mysql
  // 使用绝对路径挂载数据卷
  - /opt/data:/var/lib/mysql
  // 以 Compose 配置文件为中心的相对路径作为数据卷挂载到容器。
  - ./cache:/tmp/cache
  // 使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/)。
  - ~/configs:/etc/configs/:ro
  // 已经存在的命名的数据卷。
  - datavolume:/var/lib/mysql

如果不使用宿主机的路径,可以指定一个volume_driver。

volume_driver: mydriver
volumes_from

从另一个服务或容器挂载其数据卷:

volumes_from:
   - service_name   
     - container_name
dns

自定义DNS服务器。可以是一个值,也可以是一个列表

dns: 8.8.8.8
dns: 
    - 8.8.8.8   
    - 9.9.9.9
expose

暴露端口,但不映射到宿主机,只允许能被连接的服务访问。仅可以指定内部端口为参数,如下所示:

expose:
    - "3000"
    - "8000"
links

链接到其它服务中的容器。使用服务名称(同时作为别名),或者“服务名称:服务别名”(如 SERVICE:ALIAS),例如:

links:
    - db
    - db:database
    - redis
net

设置网络模式

net: "bridge"
net: "none"
net: "host"
net: "container"

Docker-compose模板文件示例

基于lnmp的禅道

作业:使用docker-compose搭建wordpress

1.安装

官网安装方式,这里我采用官网的安装方式,也就是方法一

下载地址:https://github.com/docker/compose/releases

方法一:

[root@docker ~]# DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}

[root@docker ~]# mkdir -p $DOCKER_CONFIG/cli-plugins

[root@docker ~]# curl -SL https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose

[root@docker ~]# chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose

方法二:

[root@docker ~]# mv docker-compose /usr/local/bin/docker-compose
[root@docker ~]# chmod a+x /usr/local/bin/docker-compose 

[root@docker ~]# docker-    # 用tab键是可以提示补全的
docker-compose  docker-init     docker-proxy    

[root@docker ~]# docker-compose version
Docker Compose version v2.5.0
2.编写模板文件
[root@docker ~]# mkdir -p /docker/script
[root@docker ~]# cd !$
cd /docker/script
[root@docker script]# mkdir compose
[root@docker script]# cd compose/
[root@docker compose]# vim docker-compose.yaml
version: '3'
services:
  db:
    image: mysql:5.7.36
    container_name: mysql
    restart: always
    tty: true
    environment:
      MYSQL_ROOT_PASSWORD: "123456"
    volumes:
      - /opt/data:/var/lib/mysql
    networks:					#其它容器都要同样的网络,但名字可以自定义
      - lnmp
  web:
    image: registry.cn-shenzhen.aliyuncs.com/adif0028/nginx_php:74v3
    container_name: web01
    restart: always
    tty: true
    depends_on:
      - db
    volumes:
      - /docker/wordpress:/usr/local/nginx/html
    ports:
      - 80:80
    networks:
      - lnmp
volumes:
  /opt/data:
  /docker/wordpress:
networks:
  lnmp:
# 上传禅道到/docker/script/compose下
[root@docker compose]# unzip ZenTaoPMS.12.3.2.zip 
[root@docker compose]# mv zentaopms/ zentao
3.启动
[root@docker compose]# docker compose up   # 前台启动,docker-compose up这条命令也可以


[root@docker compose]# docker compose up -d   # 后台启动

[root@docker compose]# docker ps

4.修改配置文件
[root@docker compose]# docker exec -it 882cee75d749 bash
[root@882cee75d749 /]# cd /usr/local/nginx/conf/
[root@882cee75d749 conf]# vi nginx.conf

改: 71      root /usr/local/nginx/html;
为: 71      root /usr/local/nginx/html/www;


[root@882cee75d749 conf]# vi /usr/local/php/etc/php.ini
改: 1312 ;session.save_handler = files
为: 1312 session.save_handler = files

改: 1341 ;session.save_path = "/tmp"
为: 1341 session.save_path = "/tmp"

[root@882cee75d749 conf]# nginx -s reload
[root@882cee75d749 conf]# /etc/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done


[root@882cee75d749 conf]# cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.21.0.3	882cee75d749


# 浏览器输入宿主机IP地址,到达数据库填写可以写db,因为compose里的yaml文件当时就已经定义好了,容器里面是有联系的

总结

注意compose文件需要特定的名字docker-compose.yaml
docker compose up -d (-d是后台启动,否则前台有输出启动)
关闭容器并且清理相关资源,清理容器,清理网络
docker compose down 也是在有yaml文件的目录下执行。

docker搭建registry仓库

镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。

一个 Docker Registry 中可以包含多个仓库Repository);每个仓库可以包含多个标签Tag);每个标签对应一个镜像。

通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。

Ubuntu 镜像 为例,ubuntu 是仓库的名字,其内包含有不同的版本标签,如,14.04, 16.04。我们可以通过 ubuntu:14.04,或者 ubuntu:16.04 来具体指定所需哪个版本的镜像。如果忽略了标签,比如 ubuntu,那将视为 ubuntu:latest

仓库名经常以 两段式路径 形式出现,比如 jwilder/nginx-proxy,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务。

Docker Registry 公开服务

Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。

最常使用的 Registry 公开服务是官方的 Docker Hub,这也是默认的 Registry,并拥有大量的高质量的官方镜像。除此以外,还有 CoreOSQuay.io,CoreOS 相关的镜像存储在这里;Google 的 Google Container RegistryKubernetes 的镜像使用的就是这个服务。

由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务(Registry Mirror),这些镜像服务被称为加速器。常见的有 阿里云加速器 一节中有详细的配置方法。

国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 时速云镜像仓库网易云镜像服务DaoCloud 镜像市场阿里云镜像库 等。

私有 Docker Registry

除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry。Docker 官方提供了 Docker Registry 一节中,会有进一步的搭建私有 Registry 服务的讲解。

开源的 Docker Registry 镜像只提供了 Docker Registry API 的服务端实现,足以支持 docker 命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。在官方的商业化版本 Docker Trusted Registry 中,提供了这些高级功能。

除了官方的 Docker Registry 外,还有第三方软件实现了 Docker Registry API,甚至提供了用户界面以及一些高级功能。比如,VMWare HarborSonatype Nexus

搭建私有的registry

1.拉取镜像
[root@docker ~]# docker pull registry
2.启动
[root@docker ~]# docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry registry
e1eb131be448e653a40f5eb742ae38bdc3b503c1f1e0d1316b30646e905e98e3

[root@docker ~]# docker ps
CONTAINER ID   IMAGE                                                                COMMAND                  CREATED         STATUS         PORTS                                       NAMES
e1eb131be448   registry                                                             "/entrypoint.sh /etc…"   5 seconds ago   Up 3 seconds   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   registry


# 浏览器输入宿主机IP地址:5000
# 在没有任何东西的时候打开是空白的

3.推送镜像

操作跟推送上阿里云一样的操作

# 打标签
[root@docker ~]# docker images
REPOSITORY                                            TAG              IMAGE ID       CREATED        SIZE
alpine                                                latest           c059bfaa849c   6 months ago   5.59MB

[root@docker ~]# docker tag c059bfaa849c 192.168.188.70:5000/alpine:v1



# 上传
[root@docker ~]# docker push 192.168.188.70:5000/alpine:v1
The push refers to repository [192.168.188.70:5000/alpine]
Get "https://192.168.188.70:5000/v2/": http: server gave HTTP response to HTTPS client
[root@docker ~]#


# 遇到报错The push refers to repository [192.168.188.70:5000/alpine] Get "https://192.168.188.70:5000/v2/": http: server gave HTTP response to HTTPS client

#为什么需要增加此配置呢?docker默认采用https的方式推送镜像,如果不进行此配置,则走https协议,此时我们安装的repositry并不支持https

# 解决方案
[root@docker ~]# vim /etc/docker/daemon.json 
# 增加这一项
"insecure-registries": ["192.168.188.70:5000"]

# 完整是
{
  "registry-mirrors": ["https://niphmo8u.mirror.aliyuncs.com"],
  "insecure-registries": ["192.168.188.70:5000"]
}


[root@docker ~]# systemctl restart docker
# 重新上传
[root@docker ~]# docker push 192.168.188.70:5000/alpine:v1

# 浏览器访问http://192.168.188.70:5000/v2/  ;根据前面提示信息里有,但是这里没有采用https,所以换成http

4.查看镜像列表
# 浏览器输入 http://192.168.188.70:5000/v2/_catalog 可以查看推送上的镜像

5.查看镜像标签
# 浏览器输入 http://192.168.188.70:5000/v2/alpine/tags/list


# 宿主机查看
[root@docker ~]# ls /opt/myregistry/docker/registry/v2/repositories/alpine/
_layers  _manifests  _uploads

6.带basic认证的registry

就是相当于阿里云镜像仓库的登陆

yum install httpd-tools -y
mkdir /opt/registry-var/auth/ -p
htpasswd  -Bbn shy 123456  >> /opt/registry-var/auth/htpasswd


docker rm -f registry

# 启动
docker run -d -p 5000:5000 -v /opt/registry-var/auth/:/auth/ -v /opt/myregistry:/var/lib/registry -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e  "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" registry 
docker login 192.168.188.70:5000
docker push 192.168.188.70:5000/alpine:v1
7.删除镜像
1)进入docker registry的容器中

docker exec -it registry /bin/sh

2) 删除repo

rm -fr /var/lib/registry/docker/registry/v2/repositories/nginx

3) 清除掉blob

registry garbage-collect /etc/docker/registry/config.yml

Docker跨主机容器之间的通信macvlan

默认一个物理网卡,只有一个物理地址,虚拟多个mac地址;基于二层

实验环境

主机名IP备注
docker192.168.188.70docker
docker-71192.168.188.71docker

目的:实现容器基于macvlan的单网段跨主机通信

1.创建网络

# 70的机子

[root@docker compose]# ifconfig   # 确认自己的网卡


# 创建macvlan网络,指定网段、网关等信息
[root@docker compose]# docker network create --driver macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.254 -o parent=ens33 macvlan_1

# 查看docker有什么网络
[root@docker compose]# docker network list   # container和macvlan、overlay是需要创建才会出现,其他都是默认有的
NETWORK ID     NAME           DRIVER    SCOPE
ff04f1f2a772   bridge         bridge    local
77e4bd1d47af   compose_lnmp   bridge    local
fe2a52aeaa07   host           host      local
d934bcc430b5   macvlan_1      macvlan   local
10f9ba31708a   none           null      local

# 开启ens33网卡的混杂模式,也就是开启网卡的多个虚拟interface(接口)
[root@docker compose]# ip link set ens33 promisc on
# 71的机子

[root@docker-71 compose]# ifconfig   # 确认自己的网卡


# 创建macvlan网络,指定网段、网关等信息
[root@docker-71 ~]# docker network create --driver macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.254 -o parent=ens33 macvlan_1


# 查看docker-71有什么网络
[root@docker-71 ~]# docker network list
NETWORK ID     NAME        DRIVER    SCOPE
1753cd6d5fcc   bridge      bridge    local
fe2a52aeaa07   host        host      local
20ea7618f39f   macvlan_1   macvlan   local
10f9ba31708a   none        null      local

# 开启ens33网卡的混杂模式,也就是开启网卡的多个虚拟interface(接口) 
[root@docker-71 ~]# ip link set ens33 promisc on

2.启动容器指定网络

# 70的机子

# 基于新创建的macvlan网络运行一个容器,并指定其IP
[root@docker compose]# docker run -it --network macvlan_1 --ip=10.0.0.200 centos:7
[root@7afc1f78d410 /]#    # 注意这里无法走外网
# 71的机子
# 基于新创建的macvlan网络运行一个容器,并指定其IP
[root@docker-71 ~]# docker run -it --network macvlan_1 --ip=10.0.0.201 centos:7
[root@b547ebdbb223 /]#

3.验证

# 互ping

# 70
[root@7afc1f78d410 /]# ping 10.0.0.201


# 71
[root@b547ebdbb223 /]# ping 10.0.0.200

Docker跨主机容器通信之overlay

http://www.cnblogs.com/CloudMan6/p/7270551.html

暂未实操,基于三层;在k8s中体现,使用网络插件flannel

1)准备工作
docker01上:
docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -bootstrap
设置容器的主机名

consul:kv类型的存储数据库(key:value)
docker01、02上:
vim  /etc/docker/daemon.json
{
  "hosts":["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"],
  "cluster-store": "consul://10.0.0.13:8500",
  "cluster-advertise": "10.0.0.11:2376"
}

vim /etc/docker/daemon.json 
vim /usr/lib/systemd/system/docker.service
systemctl daemon-reload 
systemctl restart docker

2)创建overlay网络
docker network create -d overlay --subnet 172.16.1.0/24 --gateway 172.16.1.254 ol1

3)启动容器测试
docker run -it --network ol1 --name oldboy01  busybox /bin/bash
每个容器有两块网卡,eth0实现容器间的通讯,eth1实现容器访问外网

总结

docker跨节点网络方案:端口映射、host模式、macvlan、overlay

Harbor

docker企业级镜像仓库harbor(vmware 中国团队)

Github地址https://github.com/goharbor/harbor

官方地址:https://github.com/goharbor/harbor/releases

我这里选择离线安装,把包下载下来

1.上传解压缩

[root@docker ~]# ls
anaconda-ks.cfg  harbor-offline-installer-v2.5.0.tgz
[root@docker ~]# tar xf harbor-offline-installer-v2.5.0.tgz
[root@docker ~]# ls
anaconda-ks.cfg  harbor  harbor-offline-installer-v2.5.0.tgz

2.修改文件

[root@docker ~]# cd harbor
[root@docker harbor]# ls
common.sh  harbor.v2.5.0.tar.gz  harbor.yml.tmpl  install.sh  LICENSE  prepare
[root@docker harbor]# cp harbor.yml.tmpl harbor.yml

[root@docker harbor]# vim harbor.yml
改: 5 hostname: reg.mydomain.com
为: 5 hostname: 192.168.188.70

改: 注释掉https(443)


改: 34 harbor_admin_password: Harbor12345
为: 34 harbor_admin_password: 123456


改: 数据库密码生产上需要改,这是dev就不改了


改: 47 data_volume: /data
为: 47 data_volume: /data/harbordata


[root@docker harbor]# mkdir -p /data/harbordata

3.安装

[root@docker harbor]# ./install.sh

4.验证

[root@docker harbor]# docker ps

# 浏览器输入宿主机的IP地址

操作与阿里云一样

注意:修改docker配置文件,增加如下内容

“insecure-registries”: [ “http://192.168.188.70”]

然后重启服务systemctl restart docker

为什么需要增加此配置呢?docker默认采用https的方式推送镜像,如果不进行此配置,则走https协议,此时我们安装的harbor并不支持https

`shell

互ping

70

[root@7afc1f78d410 /]# ping 10.0.0.201

71

[root@b547ebdbb223 /]# ping 10.0.0.200




## Docker跨主机容器通信之overlay

http://www.cnblogs.com/CloudMan6/p/7270551.html

暂未实操,基于三层;在k8s中体现,使用网络插件flannel

```shell
1)准备工作
docker01上:
docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -bootstrap
设置容器的主机名

consul:kv类型的存储数据库(key:value)
docker01、02上:
vim  /etc/docker/daemon.json
{
  "hosts":["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"],
  "cluster-store": "consul://10.0.0.13:8500",
  "cluster-advertise": "10.0.0.11:2376"
}

vim /etc/docker/daemon.json 
vim /usr/lib/systemd/system/docker.service
systemctl daemon-reload 
systemctl restart docker

2)创建overlay网络
docker network create -d overlay --subnet 172.16.1.0/24 --gateway 172.16.1.254 ol1

3)启动容器测试
docker run -it --network ol1 --name oldboy01  busybox /bin/bash
每个容器有两块网卡,eth0实现容器间的通讯,eth1实现容器访问外网

总结

docker跨节点网络方案:端口映射、host模式、macvlan、overlay

Harbor

docker企业级镜像仓库harbor(vmware 中国团队)

Github地址https://github.com/goharbor/harbor

官方地址:https://github.com/goharbor/harbor/releases

我这里选择离线安装,把包下载下来

1.上传解压缩

[root@docker ~]# ls
anaconda-ks.cfg  harbor-offline-installer-v2.5.0.tgz
[root@docker ~]# tar xf harbor-offline-installer-v2.5.0.tgz
[root@docker ~]# ls
anaconda-ks.cfg  harbor  harbor-offline-installer-v2.5.0.tgz

2.修改文件

[root@docker ~]# cd harbor
[root@docker harbor]# ls
common.sh  harbor.v2.5.0.tar.gz  harbor.yml.tmpl  install.sh  LICENSE  prepare
[root@docker harbor]# cp harbor.yml.tmpl harbor.yml

[root@docker harbor]# vim harbor.yml
改: 5 hostname: reg.mydomain.com
为: 5 hostname: 192.168.188.70

改: 注释掉https(443)


改: 34 harbor_admin_password: Harbor12345
为: 34 harbor_admin_password: 123456


改: 数据库密码生产上需要改,这是dev就不改了


改: 47 data_volume: /data
为: 47 data_volume: /data/harbordata


[root@docker harbor]# mkdir -p /data/harbordata

3.安装

[root@docker harbor]# ./install.sh

[外链图片转存中…(img-dtxw5pbd-1674898358081)]

4.验证

[root@docker harbor]# docker ps

# 浏览器输入宿主机的IP地址

[外链图片转存中…(img-9ANhXLsy-1674898358082)]

操作与阿里云一样

注意:修改docker配置文件,增加如下内容

“insecure-registries”: [ “http://192.168.188.70”]

然后重启服务systemctl restart docker

为什么需要增加此配置呢?docker默认采用https的方式推送镜像,如果不进行此配置,则走https协议,此时我们安装的harbor并不支持https

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值