Docker文档
一:docker简介1.1:什么是dockerDocker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目, 它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权 协议开源,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会, 并成立推动 开放
目录
6.1.2 harbor在线安装docker-compose
6.1.3 离线脚本安装docker-ce和docker-compose
一:Docker简介
1.1:什么是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 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作 系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容 器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd。
Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极 大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。
下面的图片比较了 Docker 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件 后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程 直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比 传统虚拟机更为轻便。
Chroot:该技术能在container里构造完整的Linux文件系统;
Veth:该技术能够在主机上虚拟出一张网卡与container里的eth0网卡进行桥接,实现容器与主机、容器之间的网络通信;
UnionFS:联合文件系统,Docker利用该技术“Copy on Write”的特点实现容器的快速启动和极少的资源占用,后面会专门介绍该文件系统;
Iptables/netfilter:通过这两个技术实现控制container网络访问策略;
TC:该技术主要用来做流量隔离,限制带宽;
Quota:该技术用来限制磁盘读写空间的大小;
Setrlimit:该技术用来限制container中打开的进程数,限制打开的文件个数等
1.2:docker和虚拟机的区别与对比
传统的虚拟化技术在虚拟机(VM)和硬件之间加了一个软件层Hypervisor,或者叫做虚拟机管理程序。Hypervisor的运行方式分为两类:
直接运行在物理硬件之上。如基于内核的KVM虚拟机,这种虚拟化需要CPU支持虚拟化技术;
运行在另一个操作系统。如VMWare和VitrualBox等虚拟机。
因为运行在虚拟机上的操作系统是通过Hypervisor来最终分享硬件,所以虚拟机Guest OS发出的指令都需要被Hypervisor捕获,然后翻译为物理硬件或宿主机操作系统能够识别的指令。VMWare和VirtualBox等虚拟机在性能方面远不如裸机,但基于硬件虚拟机的KVM约能发挥裸机80%的性能。这种虚拟化的优点是不同虚拟机之间实现了完全隔离,安全性很高,并且能够在一台物理机上运行多种内核的操作系统(如Linux和Window),但每个虚拟机都很笨重,占用资源多而且启动很慢。
Docker引擎运行在操作系统上,是基于内核的LXC、Chroot等技术实现容器的环境隔离和资源控制,在容器启动后,容器里的进程直接与内核交互,无需经过Docker引擎中转,因此几乎没有性能损耗,能发挥出裸机的全部性能。但由于Docker是基于Linux内核技术实现容器化的,因此使得容器内运行的应用只能运行在Linux内核的操作系统上。目前在Window上安装的docker引擎其实是利用了Window自带的Hyper-V虚拟化工具自动创建了一个Linux系统,容器内的操作实际上是间接使用这个虚拟系统实现的。
- 资源利用率更高:一台物理机可以运行数百个容器,但是一般只能运行数十个 虚拟机。
- 开销更小:不需要启动单独的虚拟机占用硬件资源。
- 启动速度更快:可以在数秒内完成启动。
对比传统虚拟机总结
特性
容器
虚拟机
启动
秒级
分钟级
硬盘使用
一般为
MB
一般为
GB
性能
接近原生
弱于
系统支持量
单机支持上千个容器
一般几十个
Docker 的优势:
- 快速部署:短时间内可以部署成百上千个应用,更快速交付到线上。
- 高效虚拟化:不需要额外的 hypervisor 支持,直接基于 linux 实现应用虚拟化, 相比虚拟机大幅提高性能和效率。
- 节省开支:提高服务器利用率,降低 IT 支出。
- 简化配置:将运行环境打包保存至容器,使用时直接启动即可。
- 快速迁移和扩展:可夸平台运行在物理机、虚拟机、公有云等环境,良好的兼 容性可以方便将应用从 A 宿主机迁移到 B 宿主机,甚至是 A 平台迁移到 B 平 台。
Docker 的缺点:
隔离性:各应用之间的隔离不如虚拟机彻底。
1.3:docker的几个基本概念
- 引擎:创建和管理容器的工具,通过读取镜像来生成容器,并负责从仓库拉取镜像或提交镜像到仓库中;
- 镜像:类似于虚拟机镜像,一般由一个基本操作系统环境和多个应用程序打包而成,是创建容器的模板;
- 容器:可看作一个简易版的Linxu系统环境(包括root用户权限、进程空间、用户空间和网络空间等)以及运行在其中的应用程序打包而成的盒子;
- 仓库:集中存放镜像文件的场所,分为公共仓库和私有仓库,目前最大的公共仓库是官方提供的Docker Hub,此外国内的阿里云、腾讯云等也提供了公共仓库;
- 宿主机:运行引擎的操作系统所在服务器。
1.4:Linux Namespace 技术
namespace 是 Linux 系统的底层概念,在内核层实现,即有一些不同类型的命名 空间被部署在核内,各个 docker 容器运行在同一个 docker 主进程并且共用同一 个宿主机系统内核,各 docker 容器运行在宿主机的用户空间,每个容器都要有 类似于虚拟机一样的相互隔离的运行空间,但是容器技术是在一个进程内实现 运行指定服务的运行环境,并且还可以保护宿主机内核不受其他进程的干扰和 影响,如文件系统空间、网络空间、进程空间等,目前主要通过以下技术实现 容器运行空间的相互隔离:
- MNT Namespace(mount):提供磁盘挂载点和文件系统的隔离能力CLONE_NEWNS
- IPC Namespace(Inter-Process Communication):提供进程间通信的隔离能力CLONE_NEWIPC
- UTS Namespace(UNIX Timesharing System):提供主机名隔离能力CLONE_NEWUTS
- PID Namespace(Process Identification):提供进程隔离能力CLONE_NEWPID
- Net Namespace(network):提供网络隔离能力CLONE_NEWNET
- User Namespace(user):提供用户隔离能力CLONE_NEWUSER
1.5:Linux control groups
在一个容器,如果不对其做任何资源限制,则宿主机会允许其占用无限大的内 存空间,有时候会因为代码 bug 程序会一直申请内存,直到把宿主机内存占 完,为了避免此类的问题出现,宿主机有必要对容器进行资源分配限制,比如 CPU、内存等,Linux Cgroups 的全称是 Linux Control Groups,它最主要的作用, 就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽 等等。此外,还能够对进程进行优先级设置,以及将进程挂起和恢复等操作。
cgroups 具体实现:
- blkio:块设备 IO 限制。
- cpu:使用调度程序为 cgroup 任务提供 cpu 的访问。
- cpuacct:产生 cgroup 任务的 cpu 资源报告。
- cpuset:如果是多核心的 cpu,这个子系统会为 cgroup 任务分配单独的 cpu 和内存。 devices:允许或拒绝 cgroup 任务对设备的访问。
- freezer:暂停和恢复 cgroup 任务。
- memory:设置每个 cgroup 的内存限制以及产生内存资源报告。
- net_cls:标记每个网络包以供 cgroup 方便使用。
- ns:命名空间子系统。
- perf_event:增加了对每 group 的监测跟踪的能力,可以监测属于某个特定的 group 的所有线程以及运行在特定 CPU 上的线程。
1.6:docker(容器)的依赖技术:
- 容器网络: docker 自带的网络 docker network 仅支持管理单机上的容器网络,当多主机运 行的时候需要使用第三方开源网络,例如 calico、flannel 等。
- 服务发现: 容器的动态扩容特性决定了容器 IP 也会随之变化,因此需要有一种机制可以 自动识别并将用户请求动态转发到新创建的容器上,kubernetes 自带服务发现功 能,需要结合 kube-dns 服务解析内部域名。
- 容器监控: 可以 通过 原生 命令 docker ps/top/stats 查看 容器运行状态, 另外也可以使 heapster/ Prometheus 等第三方监控工具监控容器的运行状态。
- 数据管理: 容器的动态迁移会导致其在不同的 Host 之间迁移,因此如何保证与容器相关 的数据也能随之迁移或随时访问,可以使用逻辑卷/存储挂载等方式解决。
- 日志收集:docker 原生的日志查看工具 docker logs,但是容器内部的日志需要通过 ELK 等专门的日志收集分析和展示工具进行处理。
1.7: Docker镜像文件系统
Docker镜像采用分层存储格式,每个镜像可依赖其他镜像进行构建,每一层的镜像可被多个镜像引用,上图的镜像依赖关系,K8S镜像其实是CentOS+GCC+GO+K8S这四个软件结合的镜像。这种分层结构能充分共享镜像层,能大大减少镜像仓库占用的空间,而对用户而言,他们所看到的容器,其实是Docker利用UnionFS(联合文件系统)把相关镜像层的目录“联合”到同一个挂载点呈现出来的一个整体,这里需要简单介绍一个UnionFS是什么:
UnionFS可以把多个物理位置独立的目录(也叫分支)内容联合挂载到同一个目录下,UnionFS允许控制这些目录的读写权限,此外对于只读的文件和目录,它具有“Copy on Write(写实复制)”的特点,即如果对一个只读的文件进行修改,在修改前会先把文件复制一份到可写层(可能是磁盘里的一个目录),所有的修改操作其实都是对这个文件副本进行修改,原来的只读文件并不会变化。其中一个使用UnionFS的例子是:Knoppix,一个用于Linux演示、光盘教学和商业产品演示的Linux发行版,它就是把一个CD/DVD和一个存在在可读写设备(例如U盘)联合挂载,这样在演示过程中任何对CD/DVD上文件的改动都会在被应用在U盘上,不改变原来的CD/DVD上的内容。
UnionFS有很多种,其中Docker中常用的是AUFS,这是UnionFS的升级版,除此之外还有DeviceMapper、Overlay2、ZFS和 VFS等。Docker镜像的每一层默认存放在/var/lib/docker/aufs/diff目录中,当用户启动一个容器时,Docker引擎首先在/var/lib/docker/aufs/diff中新建一个可读写层目录,然后使用UnionFS把该可读写层目录和指定镜像的各层目录联合挂载到/var/lib/docker/aufs/mnt里的一个目录中(其中指定镜像的各层目录都以只读方式挂载),通过LXC等技术进行环境隔离和资源控制,使容器里的应用仅依赖mnt目录中对应的挂载目录和文件运行起来。
利用UnionFS写实复制的特点,在启动一个容器时, Docker引擎实际上只是增加了一个可写层和构造了一个Linux容器,这两者都几乎不消耗系统资源,因此Docker容器能够做到秒级启动,一台服务器上能够启动上千个Docker容器,而传统虚拟机在一台服务器上启动几十个就已经非常吃力了,而且虚拟机启动很慢,这是Docker相比于传统虚拟机的两个巨大的优势。
当应用只是直接调用了内核功能来运作的情况下,应用本身就能直接作为最底层的层来构建镜像,但因为容器本身会隔绝环境,因此容器内部是无法访问宿主机里文件的(除非指定了某些目录或文件映射到容器内),这种情况下应用代码就只能使用内核的功能。但是Linux内核仅提供了进程管理、内存管理、文件系统管理等一些基础且底层的管理功能,在实际的场景中,几乎所有软件都是基于操作系统来开发的,因此往往都需要依赖操作系统的软件和运行库等,如果这些应用的下一层直接是内核,那么应用将无法运行。所以实际上应用镜像往往底层都是基于一个操作系统镜像来补足运行依赖的。
Docker中的操作系统镜像,与平常安装系统时用的ISO镜像不同。ISO镜像里包含了操作系统内核及该发行版系统包含的所有目录和软件,而Docker中的操作系统镜像,不包含系统内核,仅包含系统必备的一些目录(如/etc /proc等)和常用的软件和运行库等,可把操作系统镜像看作内核之上的一个应用,一个封装了内核功能,并为用户编写的应用提供运行环境的工具。应用基于这样的镜像构建,就能够利用上相应操作系统的各种软件的功能和运行库,此外,由于应用是基于操作系统镜像来构建的,就算换到另外的服务器,只要操作系统镜像中被应用使用到的功能能适配宿主机的内核,应用就能正常运行,这就是一次构建到处运行的原因。
1.8: Docker基础操作系统
BusyBox:一个极简版的Linux系统,集成了100多种常用Linux命令,大小不到2MB,被称为“Linux系统的瑞士军刀”,适用于简单测试场景;
Alpine:一个面向安全的轻型Linux发行版系统,比BusyBox功能更完善,大小不到5MB,是官网推荐的基础镜像,由于其包含了足够的基础功能和体积较小;
Debian/Ubuntu: Debian系列操作系统,功能完善;
CentOS/Fedora:都是基于Redhat的Linux发行版,企业级服务器常用操作系统,稳定性高;
1.9: 容器云平台CaaS
Docker的出现,使得很多云平台供应商开始提供容器云的服务,简称容器即服务CaaS,以下对比一下IaaS、PaaS和SaaS:
- IaaS(基础设施即服务):提供虚拟机或者其他基础资源作为服务提供给用户。用户可以从供应商那里获得虚拟机或者存储等资源来装载相关的应用,同时这些基础设施的繁琐的管理工作将由IaaS供应商来处理。其主要的用户是企业的系统管理员和运维人员;
- PaaS(平台即服务):把开发平台作为服务提供给用户。用户可以在一个包括SDK,文档和测试环境等在内的开发平台上非常方便地编写应用,而且不论是在部署,或者在运行的时候,用户都无需为服务器、操作系统、网络和存储等资源的管理操心,这些繁琐的工作都由PaaS供应商负责处理。其主要的用户是企业开发人员。
- SaaS(软件即服务):将应用作为服务提供给客户。用户只要接上网络,并通过浏览器,就能直接使用在云端上运行的应用,而不需要顾虑类似安装等琐事,并且免去初期高昂的软硬件投入。SaaS主要面对的是普通的用户。
- CaaS(容器即服务):完成IaaS和PaaS两个层级的功能。相对于传统的IaaS和PaaS服务,CaaS对底层的支持比PaaS更灵活,而对上层应用的操控又比IaaS更容易。同时因为Docker是比VM更细粒度的虚拟化服务,所以能够对计算资源做到更高效的利用。CaaS可以部署在任何物理机,虚拟机或IaaS云之上。
二:Docker 安装及基础命令介绍:
2.1:Debian/Ubuntu 用户
#如果你过去安装过 docker,先删掉:
apt-get remove docker docker-engine docker.io
#首先安装依赖:
apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common -y
#信任 Docker 的 GPG 公钥:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
#添加软件仓库:
add-apt-repository "deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian $(lsb_release -cs) stable"
#更新仓库
apt-get update
#查询安装版本
apt-cache madison docker-ce docker-ce-cli
#安装指定docker-ce和
apt-get install docker-ce=5:19.03.15~3-0~ubuntu-bionic docker-ce-cli=5:19.03.15~3-0~ubuntu-bionic -y
#设置开机启动
systemctl enable docker
2.2:Fedora/CentOS/RHEL用户
#如果你之前安装过 docker,请先删掉
sudo yum remove docker docker-common docker-selinux docker-engine
#安装一些依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
#根据你的发行版下载repo文件
wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo
#把软件仓库地址替换为清华源:
sudo sed -i 's+download.docker.com+mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo
#更新仓库
sudo yum makecache fast
#安装docker-ce
sudo yum install docker-ce
2.3:查看docker的版本
root@test-docker-150:~# docker version
Client: Docker Engine - Community
Version: 19.03.15
API version: 1.40
Go version: go1.13.15
Git commit: 99e3ed8919
Built: Sat Jan 30 03:16:51 2021
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.15
API version: 1.40 (minimum version 1.12)
Go version: go1.13.15
Git commit: 99e3ed8919
Built: Sat Jan 30 03:15:20 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.9
GitCommit: e25210fe30a0a703442421b0f60afac609f950a3
runc:
Version: 1.0.1
GitCommit: v1.0.1-0-g4144b63
docker-init:
Version: 0.18.0
GitCommit: fec3683
2.4:验证 docker 信息
root@test-docker-150:~# docker info
Client:
Debug Mode: false
Plugins:
scan: Docker Scan (Docker Inc., v0.8.0)
Server:
Containers: 0 #当前主机运行的容器总数
Running: 0 #有几个容器是正在运行的
Paused: 0 #有几个容器是暂停的
Stopped: 0 #有几个容器是停止的
Images: 0 #当前服务器的镜像数
Server Version: 19.03.15 #服务端版本
Storage Driver: overlay2 #正在使用的存储引擎
Backing Filesystem: xfs #后端文件系统,即服务器的磁盘文件系统
Supports d_type: true #是否支持 d_type
Native Overlay Diff: true #是否支持差异数据存储
Logging Driver: json-file #日志类型
Cgroup Driver: cgroupfs #Cgroups 类型
Plugins: #插件
Volume: local #卷
Network: bridge host ipvlan macvlan null overlay # overlay 跨主机通信
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog #日志类型
Swarm: inactive #是否支持 swarm
Runtimes: runc #已安装的容器运行时
Default Runtime: runc #默认使用的容器运行时
Init Binary: docker-init #初始化容器的守护进程,即 pid 为 1 的进程
containerd version: e25210fe30a0a703442421b0f60afac609f950a3 #版本
runc version: v1.0.1-0-g4144b63 # runc 版本
init version: fec3683 #init 版本
Security Options: #安全选项
apparmor #安全模块
seccomp #审计(操作)
Profile: default #默认的配置文件
Kernel Version: 4.15.0-112-generic #宿主机内核版本
Operating System: Ubuntu 18.04.5 LTS S #宿主机操作系统
OSType: linux #宿主机操作系统类型
Architecture: x86_64 #宿主机架构
CPUs: 2 #宿主机 CPU 数量
Total Memory: 3.412GiB #宿主机总内存
Name: test-docker-150 #宿主机 hostname
ID: UVUL:KOUV:TOGD:BSR3:Y2JO:SYCT:TELG:CWTV:WLIC:5XQV:JSTK:CKTV #宿主机 ID
Docker Root Dir: /var/lib/docker #宿主机数据保存目录
Debug Mode: false #是否开启 debug
Registry: https://index.docker.io/v1/ #镜像仓库
Labels: #其他标签
Experimental: false #是否测试版
Insecure Registries: #非安全的镜像仓库
127.0.0.0/8
Live Restore Enabled: false #是否开启活动重启(重启 docker-daemon 不关闭容器)
WARNING: No swap limit support #系统警告信息(没有开启 swap 资源限制)
解决不支持 swap #
root@test-docker-150:~# vim /etc/default/grub GRUB_DEFAULT=0 #GRUB_TIMEOUT_STYLE=hidden GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` #GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" GRUB_CMDLINE_LINUX_DEFAULT="" GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 cgroup_enable=memory swapaccount=1" root@test-docker-150:~# update-grub Sourcing file `/etc/default/grub' Generating grub configuration file ... Found linux image: /boot/vmlinuz-4.15.0-112-generic Found initrd image: /boot/initrd.img-4.15.0-112-generic done root@test-docker-150:~# reboot
此操作不会禁用swap 可以使用swapoff -a 或修改/etc/fstab文件,在swap分区这行前加 # 禁用掉,保存退出
2.4:容器的创建与管理过程
1.dockerd 通过 grpc 和 containerd 模块通信(runc)交换,dockerd 和 containerd 通信的 socket 文件:/run/containerd/containerd.sock。
2. containerd 在 dockerd 启动时被启动,然后 containerd 启动 grpc 请求监听, containerd 处理 grpc 请求,根据请求做相应动作。 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
3. 若是创建容器,containerd 拉起一个 container-shim 容器进程 , 并进行相应 的创建操作。
4. container-shim 被拉起后,start/exec/create 拉起 runC 进程,通过 exit、control 文件和 containerd 通信,通过父子进程关系和 SIGCHLD(信号)监控容器中进程状 态。
5. 在整个容器生命周期中,containerd 通过 epoll 监控容器文件,监控容器事件。
2.5:docker 镜像加速配置
国内下载国外的镜像有时候会很慢,因此可以更改 docker 配置文件添加一个加速器,可以通过加速器达到加速下载镜像的目的。
2.5.1:获取加速地址
浏览器打开 http://cr.console.aliyun.com,注册或登录阿里云账号,点击左侧的 镜像加速器,将会得到一个专属的加速地址,而且下面有使用配置说明:
2.5.2:生成配置文件
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://0pm2ubcs.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
#或 vim /lib/systemd/system/docker.service 中添加
2.5.3:修改docker存储目录
mkdir /data/docker
vim /usr/lib/systemd/system/docker.service
#在里面的EXECStart的后面增加后如下:
ExecStart=/usr/bin/dockerd --graph /data/docker
systemctl daemon-reload
systemctl restart docker
2.6:docker 镜像管理
Docker 镜像含有启动容器所需要的文件系统及所需要的内容,因此镜像主要 用于创建并启动 docker 容器。
Docker 镜像含里面是一层层文件系统,叫做 Union File System(Union FS 联合 文件系统),2004 年由纽约州立大学石溪分校开发,联合文件系统可以将多个 目录挂载到一起从而形成一整个虚拟文件系统,该虚拟文件系统的目录结构就 像普通 linux 的目录结构一样,docker 通过这些文件再加上宿主机的内核提供 了一个 linux 的虚拟环境,每一层文件系统我们叫做一层 layer,联合文件系统 可以对每一层文件系统设置三种权限,只读(readonly)、读写(readwrite)和 写出(whiteout-able),但是 docker 镜像中每一层文件系统都是只读的,构建镜 像的时候,从一个最基本的操作系统开始,每个构建的操作都相当于做一层的修 改,增加了一层文件系统,一层层往上叠加,上层的修改会覆盖底层该位置的可见 性,这也很容易理解,就像上层把底层遮住了一样,当使用镜像的时候,我们只 会看到一个完全的整体,不知道里面有几层也不需要知道里面有几层
2.6.1:搜索镜像
root@test-docker-150:~# docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 6731 [OK]
ansible/centos7-ansible Ansible on Centos7 134 [OK]
consol/centos-xfce-vnc Centos container with "headless" VNC session… 130 [OK]
jdeathe/centos-ssh OpenSSH / Supervisor / EPEL/IUS/SCL Repos - … 120 [OK]
centos/systemd systemd enabled base container. 101 [OK]
centos/mysql-57-centos7 MySQL 5.7 SQL database server 91
imagine10255/centos6-lnmp-php56 centos6-lnmp-php56 58 [OK]
tutum/centos Simple CentOS docker image with SSH access 48
centos/postgresql-96-centos7 PostgreSQL is an advanced Object-Relational … 45
kinogmt/centos-ssh CentOS with SSH 29 [OK]
guyton/centos6 From official centos6 container with full up… 10 [OK]
nathonfowlie/centos-jre Latest CentOS image with the JRE pre-install… 8 [OK]
centos/tools Docker image that has systems administration… 7 [OK]
centos/redis Redis built for CentOS 6 [OK]
drecom/centos-ruby centos ruby 6 [OK]
mamohr/centos-java Oracle Java 8 Docker image based on Centos 7 3 [OK]
darksheer/centos Base Centos Image -- Updated hourly 3 [OK]
dokken/centos-7 CentOS 7 image for kitchen-dokken 2
amd64/centos The official build of CentOS. 2
miko2u/centos6 CentOS6 日本語環境 2 [OK]
blacklabelops/centos CentOS Base Image! Built and Updates Daily! 1 [OK]
mcnaughton/centos-base centos base image 1 [OK]
smartentry/centos centos with smartentry 0 [OK]
jelastic/centosvps An image of the CentOS Elastic VPS maintaine… 0
starlabio/centos-native-build Our CentOS image for native builds 0 [OK]
2.6.2:下载镜像
root@test-docker-150:~# docker pull alpine
Using default tag: latest
latest: Pulling from library/alpine
a0d0a0d46f8b: Pull complete
Digest: sha256:e1c082e3d3c45cccac829840a25941e679c25d438cc8412c2fa221cf1a824e6a
Status: Downloaded newer image for alpine:latest
docker.io/library/alpine:latest
2.6.3:查看本地镜像
root@test-docker-150:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest 14119a10abf4 6 days ago 5.6MB
- REPOSITORY #镜像所属的仓库名称
- TAG #镜像版本号(标识符),默认为 latest
- IMAGE ID #镜像唯一 ID 标示
- CREATED #镜像创建时间
- VIRTUAL SIZE #镜像的大小
2.6.4:镜像导出
可以将镜像从本地导出问为一个压缩文件,然后复制到其他服务器进行导入使用。
root@test-docker-150:~# docker save alpine > /opt/alpine.tar.gz
root@test-docker-150:~# ll /opt/alpine.tar.gz
-rw-r--r-- 1 root root 5874688 Sep 3 14:22 /opt/alpine.tar.gz
root@test-docker-150:~# cd /opt/
root@test-docker-150:/opt# tar xvf alpine.tar.gz
14119a10abf4669e8cdbdff324a9f9605d99697215a0d21c360fe8dfa8471bab.json
746e646689cefccc4b07923569a7d658580ff9487482f59f80171f1bee5badbb/
746e646689cefccc4b07923569a7d658580ff9487482f59f80171f1bee5badbb/VERSION
746e646689cefccc4b07923569a7d658580ff9487482f59f80171f1bee5badbb/json
746e646689cefccc4b07923569a7d658580ff9487482f59f80171f1bee5badbb/layer.tar
manifest.json
repositories
root@test-docker-150:/opt# cat manifest.json
[{"Config":"14119a10abf4669e8cdbdff324a9f9605d99697215a0d21c360fe8dfa8471bab.json","RepoTags":["alpine:latest"],"Layers":["746e646689cefccc4b07923569a7d658580ff9487482f59f80171f1bee5badbb/layer.tar"]}]
2.6.4:镜像删除
root@test-docker-150:~# docker rmi alpine
Untagged: alpine:latest
Untagged: alpine@sha256:e1c082e3d3c45cccac829840a25941e679c25d438cc8412c2fa221cf1a824e6a
Deleted: sha256:14119a10abf4669e8cdbdff324a9f9605d99697215a0d21c360fe8dfa8471bab
Deleted: sha256:e2eb06d8af8218cfec8210147357a68b7e13f7c485b991c288c2d01dc228bb68
root@test-docker-150:~# docker images
REPOSITORY TAG
#当docker运行时 可使用docker rm 容器ID/容器名 -f 强制删除
2.6.4:镜像导入
root@test-docker-150:~# docker load < /opt/alpine.tar.gz
e2eb06d8af82: Loading layer [==================================================>] 5.865MB/5.865MB
Loaded image: alpine:latest
root@test-docker-150:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest 14119a10abf4 6 days ago 5.6MB
2.7:docker 容器的基本命令
2.7.1:启动一个容器
root@test-docker-150:~# docker run -it -d nginx
438206d042b6fbfb7be6e52e0867021ac6f234531fde769b0224ffd0ed6b9604
2.7.2:显示正在运行的容器
root@test-docker-150:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
438206d042b6 nginx "/docker-entrypoint.…" 6 seconds ago Up 4 seconds 80/tcp eager_fermat
2.7.3:显示所有容器
root@test-docker-150:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
438206d042b6 nginx "/docker-entrypoint.…" 40 seconds ago Up 39 seconds 80/tcp eager_fermat
6660815eebf7 nginx "/docker-entrypoint.…" 48 seconds ago Exited (127) 47 seconds ago charming_perlman
2.7.4:删除运行中的容器
root@test-docker-150:~# docker rm -f 438206d042b6
438206d042b6
2.7.5:随机映射端口
root@test-docker-150:~# docker run -it -d -P nginx
1985f4ea90562db85a44201c6e31a4ba6ed8110079a221bb253cb095b4c4e805
root@test-docker-150:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1985f4ea9056 nginx "/docker-entrypoint.…" 5 seconds ago Up 4 seconds 0.0.0.0:1025->80/tcp eloquent_wozniak
2.7.6:指定端口映射
root@test-docker-150:~# docker run -it -d -p 81:80 --name nginx-test nginx
13ce4ac4c562a5757bdc27dd6d0fb4da711b1d647464c381b9a6cd6b17c58fa2
root@test-docker-150:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
13ce4ac4c562 nginx "/docker-entrypoint.…" 5 seconds ago Up 4 seconds 0.0.0.0:81->80/tcp nginx-test
2.7.7:查询容器的日志
root@test-docker-150:~# docker logs -f nginx-test
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/09/03 07:38:38 [notice] 1#1: using the "epoll" event method
2021/09/03 07:38:38 [notice] 1#1: nginx/1.21.1
2021/09/03 07:38:38 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/09/03 07:38:38 [notice] 1#1: OS: Linux 4.15.0-112-generic
2021/09/03 07:38:38 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/09/03 07:38:38 [notice] 1#1: start worker processes
2021/09/03 07:38:38 [notice] 1#1: start worker process 30
2021/09/03 07:38:38 [notice] 1#1: start worker process 31
192.168.69.167 - - [03/Sep/2021:07:42:51 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15" "-"
2021/09/03 07:42:51 [error] 31#31: *2 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.69.167, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "172.18.1.150:81", referrer: "http://172.18.1.150:81/"
192.168.69.167 - - [03/Sep/2021:07:42:51 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "http://172.18.1.150:81/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15" "-"
2.7.8:查看容器已经映射的端口
root@test-docker-150:~# docker port nginx-test
80/tcp -> 0.0.0.0:81
2.7.9:自定义容器名称
#--name 指定容器名称
root@test-docker-150:~# docker run -it -d -p 81:80 --name nginx-test nginx
13ce4ac4c562a5757bdc27dd6d0fb4da711b1d647464c381b9a6cd6b17c58fa2
2.7.10:后台启动容器
# -d 后台启动容器
root@test-docker-150:~# docker run -it -d -p 81:80 --name nginx-test nginx
13ce4ac4c562a5757bdc27dd6d0fb4da711b1d647464c381b9a6cd6b17c58fa2
2.7.11:创建并进入容器
root@test-docker-150:~# docker run -it --name nginx-test3 nginx /bin/bash
root@58538413fa69:/# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
2.7.12:单次运行
root@test-docker-150:~# docker run -it --rm --name nginx-test4 nginx
2.7.13:容器的启动和关闭
root@test-docker-150:~# docker stop 13ce4ac4c562
13ce4ac4c562
root@test-docker-150:~# docker start 13ce4ac4c562
13ce4ac4c562
2.7.14:进入到正在运行的容器
root@test-docker-150:~# docker exec -it 13ce4ac4c562 bash
root@13ce4ac4c562:/#
2.7.15:批量关闭正在运行的容器
root@test-docker-150:~# docker stop $(docker ps -a -q )
58538413fa69
75faf770c581
13ce4ac4c562
1985f4ea9056
d9ee5af7e36d
6660815eebf7
afce6c594531
root@test-docker-150:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2.7.16:批量强制关闭正在运行的容器
root@test-docker-150:~# docker kill $(docker ps -a -q )
2.7.17:批量删除已退出容器
root@test-docker-150:~# docker rm -f `docker ps -sq -f status=exited`
58538413fa69
75faf770c581
13ce4ac4c562
1985f4ea9056
d9ee5af7e36d
6660815eebf7
afce6c594531
2.7.18:指定容器 DNS
root@test-docker-150:~# docker run -it --rm --dns 114.114.114.114 centos bash
[root@c9f67102d358 /]# cat /etc/resolv.conf
nameserver 114.114.114.114
2.7.19:查看容器的详细信息
root@test-docker-150:~# docker run -it -d nginx
529d0a7fab4894454426909e407fa8054d213ec888cf121e8889048580ee531e
root@test-docker-150:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
529d0a7fab48 nginx "/docker-entrypoint.…" 8 seconds ago Up 7 seconds 80/tcp dazzling_almeida
root@test-docker-150:~# docker inspect 529d0a7fab48
2.7.20:删除镜像
root@test-docker-150:~# docker rmi -f centos
2.7.21:给镜像打tag
root@test-docker-150:~# docker tag 3806d8b8ebb3 haproxy:2.2.11
2.7.22:删除所有未运行容器
root@test-docker-150:~# docker rm `docker ps -a -q`
2.7.23:删除所有镜像
root@test-docker-150:~# docker rmi `docker images -q`
2.7.24:按条件删除镜像
docker rmi -f `docker images | grep '<none>' | awk '{ print $3 }'`
三:Docker资源限制cgroups
在一个容器,如果不对其做任何资源限制,则宿主机会允许其占用无限大的内存空间,有时候会因为代码bug程序会一直申请内存,直到把宿主机内存占完,为了避免此类的问题出现,宿主机有必要对容器进行资源分配限制,比如CPU、内存等,Linux Cgroups 的全称是 Linux Control Groups,它最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。此外,还能够对进程进行优先级设置,以及将进程挂起和恢复等操作
3.1 查看系统cgroups
root@test-docker-150:~# ll /sys/fs/cgroup/
total 0
drwxr-xr-x 15 root root 380 Sep 3 13:50 ./
drwxr-xr-x 11 root root 0 Sep 3 13:50 ../
dr-xr-xr-x 5 root root 0 Sep 3 13:50 blkio/ 块设备 IO 限制
lrwxrwxrwx 1 root root 11 Sep 3 13:50 cpu -> cpu,cpuacct/ #使用调度程序为 cgroup 任务提供 cpu 的访问
lrwxrwxrwx 1 root root 11 Sep 3 13:50 cpuacct -> cpu,cpuacct/ #产生 cgroup 任务的 cpu 资源报告。
dr-xr-xr-x 5 root root 0 Sep 3 13:50 cpu,cpuacct/
dr-xr-xr-x 3 root root 0 Sep 3 13:50 cpuset/ #如果是多核心的 cpu,这个子系统会为 cgroup 任务分配单独的 cpu 和 内存。
dr-xr-xr-x 5 root root 0 Sep 3 13:50 devices/ #允许或拒绝 cgroup 任务对设备的访问。
dr-xr-xr-x 3 root root 0 Sep 3 13:50 freezer/ #暂停和恢复 cgroup 任务。
dr-xr-xr-x 3 root root 0 Sep 3 13:50 hugetlb/
dr-xr-xr-x 5 root root 0 Sep 3 13:50 memory/ #设置每个 cgroup 的内存限制以及产生内存资源报告。
lrwxrwxrwx 1 root root 16 Sep 3 13:50 net_cls -> net_cls,net_prio/ #标记每个网络包以供 cgroup 方便使用。
dr-xr-xr-x 3 root root 0 Sep 3 13:50 net_cls,net_prio/
lrwxrwxrwx 1 root root 16 Sep 3 13:50 net_prio -> net_cls,net_prio/
dr-xr-xr-x 3 root root 0 Sep 3 13:50 perf_event/ #增加了对每 group 的监测跟踪的能力
dr-xr-xr-x 5 root root 0 Sep 3 13:50 pids/
dr-xr-xr-x 2 root root 0 Sep 3 13:50 rdma/
dr-xr-xr-x 6 root root 0 Sep 3 13:50 systemd/
dr-xr-xr-x 5 root root 0 Sep 3 13:50 unified/
3.2查看容器的资源限制
目前 docker 已经几乎支持了所有的 cgroups 资源,可以限制容器对包括 network,device,cpu 和 memory 在内的资源的使用
默认情况下,Docker 启动一个容器后,会在 /sys/fs/cgroup 目录下的各个资源目录下生成以容器 ID 为名字的目录(group)
root@test-docker-150:/sys/fs/cgroup/memory/docker/32445eb54f4fb50309b7094f457706c08e052305b9ecc6203d4621c30e69f522#
root@test-docker-150:/sys/fs/cgroup# ls
blkio cpu cpuacct cpu,cpuacct cpuset devices freezer hugetlb memory net_cls net_cls,net_prio net_prio perf_event pids rdma systemd unified
root@test-docker-150:/sys/fs/cgroup# find ./* -iname 32445eb54f4fb50309b7094f457706c08e052305b9ecc6203d4621c30e69f522
./blkio/docker/32445eb54f4fb50309b7094f457706c08e052305b9ecc6203d4621c30e69f522
./cpu,cpuacct/docker/32445eb54f4fb50309b7094f457706c08e052305b9ecc6203d4621c30e69f522
./cpuset/docker/32445eb54f4fb50309b7094f457706c08e052305b9ecc6203d4621c30e69f522
./devices/docker/32445eb54f4fb50309b7094f457706c08e052305b9ecc6203d4621c30e69f522
./freezer/docker/32445eb54f4fb50309b7094f457706c08e052305b9ecc6203d4621c30e69f522
./hugetlb/docker/32445eb54f4fb50309b7094f457706c08e052305b9ecc6203d4621c30e69f522
./memory/docker/32445eb54f4fb50309b7094f457706c08e052305b9ecc6203d4621c30e69f522
./net_cls,net_prio/docker/32445eb54f4fb50309b7094f457706c08e052305b9ecc6203d4621c30e69f522
./perf_event/docker/32445eb54f4fb50309b7094f457706c08e052305b9ecc6203d4621c30e69f522
./pids/docker/32445eb54f4fb50309b7094f457706c08e052305b9ecc6203d4621c30e69f522
./systemd/docker/32445eb54f4fb50309b7094f457706c08e052305b9ecc6203d4621c30e69f522
root@test-docker-150:/sys/fs/cgroup#
3.3容器的内存限制
- 与操作系统类似,容器可使用的内存包括两部分:物理内存和swap
容器通过 -m或–memory设置内存的使用限额,例如:-m 300M;通过–memory-swap设置内存+swap的使用限额- 实例如下,允许容器最多使用256M的内存
root@test-docker-150:~# docker run -it --rm -m 256M --name test-mem1 lorel/docker-stress-ng --vm 2 --vm-bytes 256M
root@test-docker-150:/sys/fs/cgroup# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
4e43ee8a854e test-mem1 148.01% 254MiB / 256MiB 99.20% 0B / 0B 7.85GB / 44.6GB 5
root@test-docker-150:/sys/fs/cgroup# cat /sys/fs/cgroup/memory/docker/4e43ee8a854e6b9f6832ff89f2038e2ceca572fa7f2e6e2b219a2c72fcad2921/memory.limit_in_bytes
268435456
3.4容器的 CPU 限制
root@test-docker-150:~# docker run -it --rm --name test-cpu1 --cpus 1 lorel/docker-stress-ng --cpu 2 --vm 2
root@test-docker-150:/sys/fs/cgroup# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
2694de96b59d test-cpu1 101.62% 532.3MiB / 3.412GiB 15.24% 0B / 0B 0B / 0B 7
3.5容器的 CPU 切分
默认情况下,每个docker容器的cpu份额都是1024,单独一个容器的份额是没有意义的,只有在同时运行多个容器时,容器cpu的加权效果才能体现出现。
例如,两个容器A、B的cpu份额分别为1000和500,在cpu进行时间片分配的时候,容器A比容器B多一倍的机会获得cpu的时间片,但是分配的结果取决于当时主机和其他容器的运行状态,实际上也无法保证容器A一定能够获得cpu的时间片。比如容器A的进程一直是空闲的,那么容器B是可以获取比容器A更多的cpu时间片的,极端情况下,例如主机上只运行的一个容器,即使它的cpu份额只有50,它也可以独占整个主机的cpu资源
cgroups只在容器分配的资源紧缺时,即需要对容器使用的资源进行限制时,才会生效。因此,无法单纯的根据某个容器的份额的cpu份额来确定有多少cpu资源分配给它,可以通过cpu share参数可以设置容器使用cpu的优先级,比如启动了两个容器及运行查看cpu的cpu的使用百分比
四:Docker镜像制作
Docker 镜像有没有内核?
从镜像大小上面来说,一个比较小的镜像只有十几 MB,而内核文件需要一百 多兆, 因此镜像里面是没有内核的,镜像在被启动为容器后将直接使用宿主机 的内核,而镜像本身则只提供相应的 rootfs,即系统正常运行所必须的用户空间 的文件系统,比如/dev/,/proc,/bin,/etc 等目录,所以容器当中基本是没有/boot 目录的,而/boot 当中保存的就是与内核相关的文件和目录。
为什么没有内核? 由于容器启动和运行过程中是直接使用了宿主机的内核,所以没有直接调用过 物理硬件,所以也不会涉及到硬件驱动,因此也用不上内核和驱动,另外有内核 的那是虚拟机。
DockerFile 可以说是一种可以被 Docker 程序解释的脚本,DockerFile 是由 一条条的命令组成的,每条命令对应 linux 下面的一条命令,Docker 程序将这 些 DockerFile 指令再翻译成真正的 linux 命令,其有自己的书写方式和支持的 命令,Docker 程序读取 DockerFile 并根据指令生成 Docker 镜像,相比手动制 作镜像的方式,DockerFile 更能直观的展示镜像是怎么产生的,有了写好的各 种各样 DockerFile 文件,当后期某个镜像有额外的需求时,只要在之前的 DockerFile 添加或者修改相应的操作即可重新生成新的 Docke 镜像,避免了重 复手动制作镜像的麻烦,具体如下:
FROM 镜像基于另一个镜像,就是在另一个镜像的基础上再执行一些脚本构建出新的镜像
MAINTAINER xx.xxx xxx@qq.com 镜像维护者的信息
RUN 执行命令
WORKDIR 指定工作目录,相当于cd,一般在Dockerfile结尾会将工作目录切到常用的目录下,这样在docker exec进入容器时就会默认进入到此目录下,省去用户再cd目录的操作
COPY 复制当前目录的文件到镜像中,也可以从另一个镜像复制文件
ADD 添加当前目录的文件到镜像中,如果要添加的文件是*.tar.gz|tgz格式,则会自动解压到镜像的指定目录下
ENV 设置镜像中的环境变量
CMD 指定镜像在启动容器时执行的命令,在Dockerfile中CMD只能出现一次
ENTRYPOINT 指定镜像在启动容器时执行的命令或脚本,由于CMD只能出现一次,如果要在容器启动时执行多条命令就可以用entrypoint代替,可以在镜像中添加一个.sh文件,在.sh文件中写多条命令,要注意.sh文件需要有可执行权限,一般会RUN chmod u+x xxx.sh添加可执行权限。这里给出一条命令的写法["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/webapps/api.jar", "--spring.profiles.active=test"]
EXPOSE 说明暴露的端口,写不写都可以,但是写了之后,在docker inspect查看镜像时可以查看到镜像会暴露哪些端口
VOLUME 该指令可以指定一个或多个目录作为容器的数据卷。容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中。为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据
例如:将 /data 目录作为容器数据卷目录 /data 目录就会在运行时自动挂载为匿名卷,任何向 /data 中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。当然,运行时可以覆盖这个挂载设置。比如
docker run -d -v mydata:/data xxxx 命令中,就使用了 mydata 这个命名卷挂载到了 /data 这个位置,替代了 Dockerfile 中定义的匿名卷的挂载配置
4.1DockerFile 制作Nginx镜像
#把容器中的nginx.conf和页面拷贝到当前目录
root@test-docker-150:/data/ops/app/dockerfile/web/nginx# ls
code code.tar.gz Dockerfile nginx-1.16.1.tar.gz nginx.conf
#编辑Dockerfile
root@test-docker-150:/data/ops/app/dockerfile/web/nginx# vim Dockerfile
#My Dockerfile
From centos:7
#指定维护者的名字或者邮箱
MAINTAINER 765499757@qq.com
#安装软件
RUN yum install -y epel-release && yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop
#复制nginx包到目录
ADD nginx-1.16.1.tar.gz /usr/local/src/
#进入目录并编译安装
RUN cd /usr/local/src/nginx-1.16.1 && ./configure --prefix=/apps/nginx --with-http_sub_module && make && make install
#创建用户
RUN useradd nginx -u 2022
#复制本地nginx配置文件到容器中
ADD nginx.conf /apps/nginx/conf/nginx.conf
#复制本地页面到nginx中
ADD code.tar.gz /data/nginx/html
#暴露端口
EXPOSE 80 443
#运行命令
ENTRYPOINT ["/apps/nginx/sbin/nginx"]
#运行命令cmd作为ENTRYPOINT 的参数
CMD ["-g","daemon off;"]
#执行镜像构建
root@test-docker-150:/data/ops/app/dockerfile/web/nginx# docker build -t centos-nginx:1.16.1 .
#构建够会有指定的centos-nginx:1.16.1镜像
root@test-docker-150:/data/ops/app/dockerfile/web/nginx# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-nginx 1.16.1 bbe6250d9d17 9 seconds ago 570MB
centos 7 8652b9f0cb4c 9 months ago 204MB
lorel/docker-stress-ng latest 1ae56ccafe55 5 years ago 8.1MB
#指定此镜像运行容器
root@test-docker-150:/data/ops/app/dockerfile/web/nginx# docker run -itd -p 80:80 centos-nginx:1.16.1
#可以看到此容器已经运行
root@test-docker-150:/data/ops/app/dockerfile/web/nginx# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
46810e14a35f centos-nginx:1.16.1 "/apps/nginx/sbin/ng…" 5 seconds ago Up 5 seconds 0.0.0.0:80->80/tcp, 443/tcp crazy_turing
4.2自定义 Centos 基础镜像
先基于官方提供的基础镜像,制作出安装了常用命令的自定义基础镜像,然后 在基础镜像的基础之上,再制作 JDK 镜像、Tomcat 镜像等。
root@test-docker-150:/data/ops/app/dockerfile/system/centos# vim Dockerfile
FROM centos:7.8.2003
MAINTAINER 765499757@qq.com
RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
RUN yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop && groupadd www -g 2022 && useradd www -u 2022 -g www
root@test-docker-150:/data/ops/app/dockerfile/system/centos# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-base v1 6118ea51dca1 10 minutes ago 574MB
centos-nginx 1.16.1 bbe6250d9d17 43 minutes ago 570MB
4.3自定义构建 JDK 镜像
root@test-docker-150:/data/ops/app/dockerfile/web/jdk# ls
Dockerfile jdk-8u212-linux-x64.tar.gz profile
root@test-docker-150:/data/ops/app/dockerfile/web/jdk# vim Dockerfile
FROM centos-base:v1
MAINTAINER zixuan "765499757@qq.com"
ADD jdk-8u212-linux-x64.tar.gz /usr/local/src
RUN ln -sv /usr/local/src/jdk1.8.0_212 /usr/local/jdk
ADD profile /etc/profile
ENV name zixuan
ENV JAVA_HOME /usr/local/jdk
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/:$JRE_HOME/lib/
ENV PATH $PATH:$JAVA_HOME/bin
RUN rm -rf /etc/localtime && ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
root@test-docker-150:/data/ops/app/dockerfile/web/jdk# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jdk-base v8.212 1172747ee551 6 seconds ago 981MB
centos-base v1 6118ea51dca1 20 minutes ago 574MB
centos-nginx 1.16.1 bbe6250d9d17 52 minutes ago 570MB
#创建容器测试
root@test-docker-150:/data/ops/app/dockerfile/web/jdk# docker run -it jdk-base:v8.212 bash
[root@0c4a80362716 /]# java -version
java version "1.8.0_212"
Java(TM) SE Runtime Environment (build 1.8.0_212-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.212-b10, mixed mode)
4.4自定义构建tomcat镜像
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat# ls
apache-tomcat-8.5.65.tar.gz Dockerfile
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat# vim Dockerfile
#tomcat base image
FROM jdk-base:v8.212
MAINTAINER zixuan "765499757@qq.com"
ADD apache-tomcat-8.5.65.tar.gz /apps
RUN ln -sv /apps/apache-tomcat-8.5.65 /apps/tomcat
4.5基于tomcat镜像制作业务镜像
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat/tomcat-app1# ls
Dockerfile myapp myapp.tar.gz run_tomcat.sh server.xml
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat/tomcat-app1# vim Dockerfile
FROM tomcat-base:v8.5.65
MAINTAINER zixuan "765499757@qq.com"
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh
ADD server.xml /apps/tomcat/conf/server.xml
ADD myapp.tar.gz /data/tomcat/webapps
RUN chown www.www /data /apps -R
EXPOSE 8080 8443
CMD ["/apps/tomcat/bin/run_tomcat.sh"]
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat/tomcat-app1# vim myapp/index.jsp
<h1>zixuan tomcat app1 web page</h1>
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat/tomcat-app1# tar zcvf myapp.tar.gz myapp
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat/tomcat-app1# vim run_tomcat.sh
#!/bin/bash
su - www -c "/apps/tomcat/bin/catalina.sh start"
tail -f /etc/hosts
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat/tomcat-app1# docker build -t tomcat-web:app1 .
docker run -itd -p 8080:8080 tomcat-web:app1
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat/tomcat-app2# ls
Dockerfile myapp myapp.tar.gz run_tomcat.sh server.xml
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat/tomcat-app2# vim Dockerfile
FROM tomcat-base:v8.5.65
MAINTAINER zixuan "765499757@qq.com"
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh
ADD server.xml /apps/tomcat/conf/server.xml
ADD myapp.tar.gz /data/tomcat/webapps
RUN chown www.www /data /apps -R
EXPOSE 8080 8443
CMD ["/apps/tomcat/bin/run_tomcat.sh"]
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat/tomcat-app2# vim myapp/index.jsp
<h1>zixuan tomcat app1 web page</h1>
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat/tomcat-app2# tar zcvf myapp.tar.gz myapp
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat/tomcat-app2# vim run_tomcat.sh
#!/bin/bash
su - www -c "/apps/tomcat/bin/catalina.sh start"
tail -f /etc/hosts
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat/tomcat-app2# docker build -t tomcat-web:app2 .
docker run -itd -p 8081:8080 tomcat-web:app2
root@test-docker-150:/data/ops/app/dockerfile/web/tomcat# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat-web app2 3806d8b8ebb3 4 minutes ago 1.01GB
tomcat-web app1 a11515defd46 11 minutes ago 1.01GB
tomcat-base v8.5.65 e8c8e59af6c8 35 minutes ago 995MB
jdk-base v8.212 1172747ee551 About an hour ago 981MB
centos-base v1 6118ea51dca1 2 hours ago 574MB
centos-nginx 1.16.1 bbe6250d9d17 2 hours ago 570MB
4.6构建 haproxy 镜像:
root@test-docker-150:/data/ops/app/dockerfile/web/haproxy# ls
Dockerfile haproxy-2.2.11.tar.gz haproxy.cfg run_haproxy.sh tomcat-web-app2.tar
root@test-docker-150:/data/ops/app/dockerfile/web/haproxy# vim Dockerfile
#haproxy image
FROM centos-base:v1
MAINTAINER 765499757@qq.com
RUN yum install libtermcap-devel ncurses-devel libevent-devel readline-devel gcc gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel net-tools vim iotop bc zip unzip zlib-devel lrzsz tree screen lsof tcpdump wget ntpdate -y
ADD haproxy-2.2.11.tar.gz /usr/local/src
RUN cd /usr/local/src/haproxy-2.2.11 && make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_CPU_AFFINITY=1 PREFIX=/apps/haproxy && make install PREFIX=/apps/haproxy && cp haproxy /usr/sbin/ && mkdir /apps/haproxy/run -p
ADD run_haproxy.sh /apps/haproxy/bin/run_haproxy.sh
ADD haproxy.cfg /etc/haproxy/haproxy.cfg
EXPOSE 80 9999
CMD ["/apps/haproxy/bin/run_haproxy.sh"]
root@test-docker-150:/data/ops/app/dockerfile/web/haproxy# vim haproxy.cfg
global
chroot /apps/haproxy
#stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
uid 99
gid 99
daemon
nbproc 1
pidfile /apps/haproxy/run/haproxy.pid
log 127.0.0.1 local3 info
defaults
option http-keep-alive
option forwardfor
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:123456
listen web_port
bind 0.0.0.0:80
mode http
log global
balance roundrobin
server web1 172.18.1.150:8080 check inter 3000 fall 2 rise 5
server web2 172.18.1.151:8080 check inter 3000 fall 2 rise 5
root@test-docker-150:/data/ops/app/dockerfile/web/haproxy# vim run_haproxy.sh
#!/bin/bash
/apps/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg
tail -f /etc/hosts
#将app2镜像打包拷贝到172.38.1.151上
root@test-docker-150:/data/ops/app/dockerfile/web/haproxy# docker save 3806d8b8ebb3 > tomcat-web-app2.tar
root@test-docker-150:/data/ops/app/dockerfile/web/haproxy# scp tomcat-web-app2.tar 172.18.1.151:/data/ops/app/dockerfile
root@test-docker-151:/data/ops/app/dockerfile# ls
tomcat-web-app2.tar
root@test-docker-151:/data/ops/app/dockerfile# docker load < tomcat-web-app2.tar
root@test-docker-151:/data/ops/app/dockerfile# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 3806d8b8ebb3 53 minutes ago 1.01GB
root@test-docker-151:/data/ops/app/dockerfile# docker tag 3806d8b8ebb3 haproxy:2.2.11
root@test-docker-151:/data/ops/app/dockerfile# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
haproxy 2.2.11 3806d8b8ebb3 53 minutes ago 1.01GB
root@test-docker-151:/data/ops/app/dockerfile# docker run -itd -p 8080:8080 haproxy:2.2.11
五:Docker镜像管理
Docker 的镜像是分层设计的,镜像层是只读的,通过镜像启动的容器添加了一层可读写的文件系统,用户写入的数据都保存在这一层当中。 如果要将写入到容器的数据永久保存,则需要将容器中的数据保存到宿主机的指定目录,目前 Docker 的数据类型分为两种:
一是数据卷(data volume),数据卷类似于挂载的一块磁盘,数据容器是将数据保存在一个容器上.
二是数据卷容器(Data volume container), 数据卷容器是将宿主机的目录挂载至一个专门的数据卷容器,然后让其他容器通过数据卷容器读写宿主机的数据。
5.1 查看指定 PID 的容器信息
#查看指定 PID 的容器信息
root@test-docker-150:~# docker inspect 2a694d7a4256
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/8c9e6a790288ff08a53822c7ad235a0353a21ec8a0a685347d5b1f0bde89a87b-init/diff:/var/lib/docker/overlay2/fabfe9e33be6fffa4855b534deec0f750f5ef3aa31d50b28ba150f544d3dde8f/diff:/var/lib/docker/overlay2/dfb84608d77af2398df1ef5d92fa1ed2d044c9d49a318a4a27aaa82ac993d078/diff:/var/lib/docker/overlay2/3ce74febd4c5e5f7aea0bbf39505a124b6391a833920afa083a0f58253769c1b/diff",
"MergedDir": "/var/lib/docker/overlay2/8c9e6a790288ff08a53822c7ad235a0353a21ec8a0a685347d5b1f0bde89a87b/merged",
"UpperDir": "/var/lib/docker/overlay2/8c9e6a790288ff08a53822c7ad235a0353a21ec8a0a685347d5b1f0bde89a87b/diff",
"WorkDir": "/var/lib/docker/overlay2/8c9e6a790288ff08a53822c7ad235a0353a21ec8a0a685347d5b1f0bde89a87b/work"
},
Lower Dir:image 镜像层(镜像本身,只读)
Upper Dir:容器的上层(读写)
Merged Dir:容器的文件系统,使用 Union FS(联合文件系统)将 lowerdir 和 upper Dir:合并给容器使用。
Work Dir:容器在 宿主机的工作目录
5.2 启动测试容器验证
root@test-docker-150:~# cd /tmp/
root@test-docker-150:/tmp# touch test.txt
root@test-docker-150:~# docker run -itd --name test1 -v /tmp:/tmp reg.local.com/library/centos-base:v1
#test2的ro标识该目录只读,默认是可读写的:
root@test-docker-150:~# docker run -itd --name test2 -v /tmp:/tmp:ro reg.local.com/library/centos-base:v1
#在test2中是不可删除的
root@test-docker-150:~# docker exec -it 5b0b022e86a2 bash
[root@5b0b022e86a2 /]# ll /tmp/
total 0
-rw-r--r-- 1 root root 0 Sep 9 02:48 test.txt
[root@5b0b022e86a2 /]# rm /tmp/test.txt
rm: remove regular empty file '/tmp/test.txt'? y
rm: cannot remove '/tmp/test.txt': Read-only file system
#在test1是可以删除的
[root@c52b70006243 /]# ll /tmp/
total 0
-rw-r--r-- 1 root root 0 Sep 9 02:48 test.txt
[root@c52b70006243 /]# rm /tmp/test.txt
rm: remove regular empty file '/tmp/test.txt'? y
5.3 数据卷的特点和使用场景
- 数据卷是宿主机的目录或者文件,并且可以在多个容器之间共同使用。
- 在宿主机对数据卷更改数据后会在所有容器里面会立即更新。
- 数据卷的数据可以持久保存,即使删除使用使用该容器卷的容器也不影响。
- 在容器里面的写入数据不会影响到镜像本身。
- 日志输出
- 静态 web 页面
- 应用配置文件
- 多容器间目录或文件共
5.4 镜像的磁盘管理
#通过docker system df -v查看更详细的数据,包括每个镜像占用的空间,每个容器占用的空间等
root@test-docker-150:~# docker system df -v
Images space usage:
REPOSITORY TAG IMAGE ID CREATED SIZE SHARED SIZE UNIQUE SIZE CONTAINERS
haproxy 2.2.11 89072b85cd53 41 hours ago 874.8MB 574.2MB 300.6MB 1
tomcat-web app2 3806d8b8ebb3 42 hours ago 1.01GB 995.3MB 14.68MB 0
tomcat-web app1 a11515defd46 42 hours ago 1.01GB 995.3MB 14.68MB 1
tomcat-base v8.5.65 e8c8e59af6c8 42 hours ago 995.3MB 995.3MB 0B 0
jdk-base v8.212 1172747ee551 43 hours ago 980.6MB 980.6MB 0B 0
centos-base v1 6118ea51dca1 43 hours ago 574.2MB 574.2MB 0B 2
centos-nginx 1.16.1 bbe6250d9d17 44 hours ago 570.3MB 0B 570.3MB 0
Containers space usage:
CONTAINER ID IMAGE COMMAND LOCAL VOLUMES SIZE CREATED STATUS NAMES
21dd41c99acf reg.local.com/library/centos-base:v1 "/bin/bash" 0 32B 8 minutes ago Up 8 minutes test2
c52b70006243 reg.local.com/library/centos-base:v1 "bash" 0 65B 13 minutes ago Up 13 minutes test1
625945e2344a haproxy:2.2.11 "/apps/haproxy/bin/r…" 0 2B 41 hours ago Exited (137) 18 hours ago laughing_noyce
a1a862e6db3d tomcat-web:app1 "/apps/tomcat/bin/ru…" 0 643kB 42 hours ago Exited (137) 18 hours ago compassionate_taussig
Local Volumes space usage:
VOLUME NAME LINKS SIZE
Build cache usage: 0B
CACHE ID CACHE TYPE SIZE CREATED LAST USED USAGE SHARED
#通过docker ps --size查看运行中的容器占用的空间
root@test-docker-150:~# docker ps --size
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
21dd41c99acf reg.local.com/library/centos-base:v1 "/bin/bash" 8 minutes ago Up 8 minutes test2 32B (virtual 574MB)
c52b70006243 reg.local.com/library/centos-base:v1 "bash" 14 minutes ago Up 14 minutes test1 65B (virtual 574MB)
root@test-docker-150:~#
如果docker根目录所在的硬盘确实腾不出空间了,可以挂一个新的硬盘,
service docker stop
关闭docker服务,将当前docker根目录下的文件移动到新的硬盘(默认docker的根目录是/var/lib/docker
),修改/etc/docker/daemon.json
添加或修改data-root
到新的硬盘上,再service docker start
启动docker服务,这样就完成了docker目录的迁移
六:Harbor 仓库使用
Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,由vmware开源,其通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源 Docker Distribution。作为一个企业级私有 Registry 服务器,Harbor 提供了更好的性能和安全。提升用户使用 Registry 构建和运行环境传输镜像的效率。Harbor 支持安装在多个 Registry 节点的镜像资源复制,镜像全部保存在私有 Registry 中,确保数据和知识产权在公司内部网络中管控,另外,Harbor 也提供了高级的安全特性,诸如用户管理,访问控制和活动审计等。
vmware 官方开源服务列表地址:https://vmware.github.io/harbor/cn/,
harbor 官方 github 地址:GitHub - goharbor/harbor: An open source trusted cloud native registry project that stores, signs, and scans content.
harbor 官方网址:Harbor
下载地址:Releases · goharbor/harbor · GitHub
安装文档:Harbor docs | Harbor Installation and Configuration
harbor组件:
- nginx:harbor 的一个反向代理组件,代理 registry、ui、token 等服务。这个代 理会转发 harbor web 和 docker client 的各种请求到后端服务上。
- harbor-adminserver:harbor 系统管理接口,可以修改系统配置以及获取系统信 息。 harbor-db:存储项目的元数据、用户、规则、复制策略等信息。
- harbor-jobservice:harbor 里面主要是为了镜像仓库之前同步使用的。
- harbor-log:收集其他 harbor 的日志信息。 harbor-ui:一个用户界面模块,用来管理 registry。
- registry:存储 docker images 的服务,并且提供 pull/push 服务。
- redis:存储缓存信息
- webhook:当 registry 中的 image 状态发生变化的时候去记录更新日志、复制等 操作。
- token service:在 docker client 进行 pull/push 的时候负责 token 的发放。
6.1 harbor的基础配置
6.1.1harbor的安装需求
- Docker engine:Version 17.06.0-ce+
- Docker Compose:Version 1.18.0+
6.1.2harbor在线安装docker-compose
Ubuntu:
# apt update
# apt install -y python-pip
# pip install docker-compose
Centos:
# yum install epel-release
# yum install -y python-pip
# pip install --upgrade pip
# pip install docker-compose
6.1.3离线脚本安装docker-ce和docker-compose
tar xvf docker-19.03.15-binary-install.tar.gz
bash docker-install.sh
[root@test-harbor-153 ~]# docker-compose --version
docker-compose version 1.24.1, build 4667896b
6.1.4通过离线完整安装包安装harbor
#下载harbor
wget https://github.com/goharbor/harbor/releases/download/v2.1.2/harbor-offline-installer-v2.1.2.tgz
#将下载的安装包解压到指定目录
tar zxf harbor-offline-installer-v2.1.2.tgz -C /usr/local
6.2 harbor的配置
#切换至解压后的目录中
cd /usr/local/harbor/
#编辑这个配置文件
cp harbor.yml.tmpl harbor.yml
#里面注释很多,主要修改几个参数
vim harbor.yml
#这个是指定harbor的ip地址
hostname: 172.18.1.152
#使用80端口
http:
port: 80
#如果使用80就将此禁用反之亦然
https:
port: 443
certificate: /your/certificate/path
private_key: /your/private/key/path
#harbor的登陆密码
harbor_admin_password: Harbor12345
#harbor的存储路径
data_volume: /data/ops/app/harbor/
6.3harbor安装
#执行自带的安装脚本,安装完毕,浏览器即可访问
./install.sh
...
[Step 5]: starting Harbor ...
Creating network "harbor_harbor" with the default driver
Creating harbor-log ... done
Creating harbor-db ... done
Creating registry ... done
Creating registryctl ... done
Creating redis ... done
Creating harbor-portal ... done
Creating harbor-core ... done
Creating nginx ... done
Creating harbor-jobservice ... done
✔ ----Harbor has been installed and started successfully.----
6.4harbor验证
默认的账户密码 admin/Harbor12345
6.5 使用node节点添加私有仓库
root@test-docker-150:~# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://0pm2ubcs.mirror.aliyuncs.com"],
"insecure-registries": ["http://reg.local.com","172.18.1.153"]
}
root@test-docker-150:~# docker login http://reg.local.com --username=admin --password=Harbor12345
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
# 镜像打tag
root@test-docker-150:~# docker tag centos-base:v1 reg.local.com/library/centos-base:v1
# 推送到harbor
root@test-docker-150:~# docker push reg.local.com/library/centos-base:v1
可以在harbor页面中看到此上传的镜像
6.6 实现 harbor 双向同步
Harbor 支持基于策略的 Docker 镜像复制功能,这类似于 MySQL 的主从同步, 其可以实现不同的数据中心、不同的运行环境之间同步镜像
6.6.1准备基础环境
test-harbor-152 172.18.1.152 docker-ce docker-compose harbor
test-harbor-153 172.18.1.152 docker-ce docker-compose harbor
6.6.2添加仓库和复制规则
#172.18.1.152
#1 系统管理-仓库管理-新建目标
目标名称:153
目标url:http://172.18.1.153
访问ID:admin
访问密码:Harbor12345
#2 系统管理-复制管理-新建目录
名称:push-153
复制模式:push-based
源资源过滤器:全部
目标仓库:153-http://172.18.1.153
触发模式:事件驱动
#172.18.1.153
#1 系统管理-仓库管理-新建目标
目标名称:152
目标url:http://172.18.1.152
访问ID:admin
访问密码:Harbor12345
#2 系统管理-复制管理-新建目录
名称:push-152
复制模式:push-based
源资源过滤器:全部
目标仓库:152-http://172.18.1.152
触发模式:事件驱动
6.6.3 验证复制是否成功
test-docker-150登陆 harbor 172.18.1.152
test-docker-151登陆 harbor 172.18.1.153
在test-docker-150上传镜像
root@test-docker-150:~# docker tag centos-base:v1 reg.local.com/library/centos-base:v1
root@test-docker-150:~# docker push reg.local.com/library/centos-base:v1
在test-docker-151可以下载镜像
root@test-docker-151:~# docker pull 172.18.1.153/library/centos-base:v1
6.7harbor的高可用
虽然通过harbor同步可以实现备份,但是node节点指向通常都是一个,无法切换,此时需要使用keepalived+haproxy实现高可用
6.7.1安装keepalived和haproxy
[root@test-harbor-152 ~]# yum install -y keepalived haproxy
[root@test-harbor-153 ~]# yum install -y keepalived haproxy
6.7.2 配置keepalived
[root@test-harbor-152 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 1
priority 100
advert_int 3
unicast_src_ip 172.18.1.152
unicast_peer {
172.18.1.153
}
authentication {
auth_type PASS
auth_pass 123abc
}
virtual_ipaddress {
172.18.1.160 dev eth0 label eth0:1
}
}
[root@test-harbor-152 ~]# systemctl restart keepalived.service
[root@test-harbor-153 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state SLAVE
interface eth0
virtual_router_id 1
priority 100
advert_int 3
unicast_src_ip 172.18.1.153
unicast_peer {
172.18.1.152
}
authentication {
auth_type PASS
auth_pass 123abc
}
virtual_ipaddress {
172.18.1.160 dev eth0 label eth0:1
}
}
[root@test-harbor-153 ~]# systemctl restart keepalived.service
#可以看到vip已经有了
[root@test-harbor-152 ~]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:cf:2c:96 brd ff:ff:ff:ff:ff:ff
inet 172.18.1.152/24 brd 172.18.1.255 scope global eth0
valid_lft forever preferred_lft forever
inet 172.18.1.160/32 scope global eth0:1
valid_lft forever preferred_lft forever
6.7.3 配置haproxy
#两台harbor分别追加一下内容并重启
[root@test-harbor-152 ~]# vim /etc/haproxy/haproxy.cfg
listen harbor_80
bind 172.18.1.160:8180
mode tcp
balance source
server 172.18.1.152 172.18.1.152:80 check inter 2000 fall 3 rise 5
server 172.18.1.153 172.18.1.153:80 check inter 2000 fall 3 rise 5
[root@test-harbor-152 ~]# systemctl restart haproxy.service
[root@test-harbor-153 ~]# vim /etc/haproxy/haproxy.cfg
listen harbor_80
bind 172.18.1.160:8180
mode tcp
balance source
server 172.18.1.152 172.18.1.152:80 check inter 2000 fall 3 rise 5
server 172.18.1.153 172.18.1.153:80 check inter 2000 fall 3 rise 5
[root@test-harbor-153 ~]# systemctl restart haproxy.service
#可以看到172.18.1.160:8180 端口已经打开 (没有vip的那个机器是不打开的)
[root@test-harbor-152 ~]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 3000 *:5000 *:*
LISTEN 0 65535 127.0.0.1:1514 *:*
LISTEN 0 3000 172.18.1.160:8180 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 65535 :::80 :::*
LISTEN 0 128 :::22 :::*
6.7.4 在daemon.json设置信任
root@test-docker-150:~# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://0pm2ubcs.mirror.aliyuncs.com"],
"insecure-registries": ["http://reg.local.com","172.18.1.153","http://172.18.1.160:8180"]
}
root@test-docker-150:~# systemctl restart docker
root@test-docker-151:~# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://0pm2ubcs.mirror.aliyuncs.com"],
"insecure-registries": ["http://reg.local.com","172.18.1.153","http://172.18.1.160:8180"]
}
root@test-docker-151:~# systemctl restart docker
6.7.5登录harbor并测试
root@test-docker-150:~# docker login 172.18.1.160:8180 --username=admin --password=Harbor12345
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
root@test-docker-151:~# docker login 172.18.1.160:8180 --username=admin --password=Harbor12345
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
#可以成功下载镜像
root@test-docker-151:~# docker pull 172.18.1.160:8180/library/centos-base:v1
v1: Pulling from library/centos-base
9b4ebb48de8d: Already exists
a2628f37c275: Already exists
6719a855b39b: Already exists
Digest: sha256:3639036a5dbe0faa4dea5ddb8e1f8a449a523ce0d87224168f6082b0a2e43853
Status: Downloaded newer image for 172.18.1.160:8180/library/centos-base:v1
172.18.1.160:8180/library/centos-base:v1
root@test-docker-151:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
haproxy 2.2.11 3806d8b8ebb3 45 hours ago 1.01GB
172.18.1.160:8180/library/centos-base v1 6118ea51dca1 46 hours ago 574MB
#通过浏览器测试可以访问vip,当其中一个harbor停止服务后,另外一个也不受到影响
更多推荐
所有评论(0)