From 3bcd84d005873979ba7ed94cf7cbcf83a1100d3f Mon Sep 17 00:00:00 2001 From: wxin <15253413025@163.com> Date: Fri, 4 Apr 2025 17:31:23 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E8=87=B3?= =?UTF-8?q?=20/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.md | 153 +++++++++++++++++ docker-harbor.md | 252 +++++++++++++++++++++++++++ docker-基础.md | 420 +++++++++++++++++++++++++++++++++++++++++++++ docker-进阶.md | 294 +++++++++++++++++++++++++++++++ docker-镜像构建.md | 314 +++++++++++++++++++++++++++++++++ 5 files changed, 1433 insertions(+) create mode 100644 docker-compose.md create mode 100644 docker-harbor.md create mode 100644 docker-基础.md create mode 100644 docker-进阶.md create mode 100644 docker-镜像构建.md diff --git a/docker-compose.md b/docker-compose.md new file mode 100644 index 0000000..e883065 --- /dev/null +++ b/docker-compose.md @@ -0,0 +1,153 @@ +

Docker-compose

+ +------ + +## 一:Docker-compose 概述 + +​ Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。使用 Compose,您可以使用 YAML 文件来配置应用程序的服务。然后,使用一个命令,您可以从您的配置中创建并启动所有服务。 + +​ Compose 适用于所有环境:生产、登台、开发、测试以及 CI 工作流程。 + +**使用 Compose 基本上是一个三步过程:** + +- 使用定义您的应用程序的环境,`Dockerfile`以便可以在任何地方复制它 +- 定义构成您的应用程序的服务,`docker-compose.yml` 以便它们可以在隔离环境中一起运行 +- 运行`docker compose up`,Docker compose 命令启动并运行您的整个应用程序 + +## 二:Docker-compose 安装 + +### 1. 下载 + +```bash +[root@docker ~]# curl -SL https://github.com/docker/compose/releases/download/v2.6.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose +``` + +### 2. 创建软连接 + +```bash +[root@docker ~]# ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose +``` + +### 3. 添加执行权限 + +```bash +[root@docker ~]# chmod +x /usr/bin/docker-compose +``` + +### 4. 查看版本 + +```bash +[root@docker ~]# docker-compose --version +Docker Compose version v2.6.0 +``` + +## 三:使用 + +### 1. 创建项目目录结构 + +```bash +[root@docker ~]# mkdir nginx +[root@docker ~]# cd nginx +[root@docker nginx]# mkdir conf html +``` + +### 2. 编写`Nginx`配置文件 + +```bash +[root@docker nginx]# vim conf/nginx.conf +server { + listen 80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } +} +``` + +### 3. 创建静态文件 + +在`html/index.html`中写入测试内容: + +```bash +[root@docker nginx]# vim html/index.html + + + + Nginx in Docker + + +

Hello from Docker + Nginx!

+ + +``` + +### 4. 编写`docker-compose.yml` + +```bash +[root@docker nginx]# vim docker-compose.yml +version: '3.8' + +services: + nginx: + image: nginx:latest + container_name: nginx-v1 + ports: + - "80:80" + volumes: + - ./conf/nginx.conf:/etc/nginx/conf.d/default.conf + - ./html:/usr/share/nginx/html + restart: unless-stopped + +参数说明: +ports: 映射宿主机 80 端口到容器的 80 端口 +restart: 容器意外退出时自动重启。 +``` + +### 5. 启动服务 + +```bash +# 启动容器(后台运行) +[root@docker nginx]# docker-compose up -d +[+] Running 2/2 + ⠿ Network nginx_default Created 0.1s + ⠿ Container nginx-v1 Started 0.3s + +# 查看运行状态 +[root@docker nginx]# docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +f289f37ccc44 nginx:latest "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp nginx-v1 + +# 查看日志 +[root@docker nginx]# docker-compose logs nginx +``` + +### 6. 验证 + +```bash +[root@docker nginx]# curl http://localhost + + + + Nginx in Docker + + +

Hello from Docker + Nginx!

+ + +``` + +### 7. 其他命令 + +```bash +[root@docker nginx]# docker-compose up -d //后台运行 +[root@docker nginx]# docker-compose ps //列出容器 +[root@docker nginx]# docker-compose pause //暂停服务 +[root@docker nginx]# docker-compose unpause //取消暂停服务 +[root@docker nginx]# docker-compose down //停止并移除容器、网络 +[root@docker nginx]# docker-compose logs //查看容器的输出 +[root@docker nginx]# docker-compose start //启动服务 +[root@docker nginx]# docker-compose stop //停止服务 +``` + diff --git a/docker-harbor.md b/docker-harbor.md new file mode 100644 index 0000000..ea02d78 --- /dev/null +++ b/docker-harbor.md @@ -0,0 +1,252 @@ +

Docker-harbor

+ +------ + +## 一:harbor + +### 1. harbor 概念 + +​ Harbor 是一个企业级的云原生容器镜像仓库,由`VMware`主导开发并贡献给`Cloud Native Computing Foundation(CNCF)`。它通过为`Docker`镜像提供安全、高效的管理能力,帮助企业简化容器应用程序的交付流程。相比于传统的`Docker Registry`,`Harbor`提供了更多的企业级特性,如容器镜像仓库之间的镜像复制、用户管理、访问控制、漏洞扫描和镜像签名等功能。 + +### 2. 特性 + +​ `Harbor`的主要作用是为容器化应用程序提供集中式的镜像存储管理。它允许企业通过集中的仓库存储、分发和保护容器镜像,确保开发、测试和生产环境中使用的镜像都符合安全和合规要求。 + +`Harbor`有以下特性: + +- **基于云原生场景:**`Harbor`支持容器镜像和`Helm Chart`,可用作容器`Runtime`和编排平台等云原生环境的镜像仓库。 +- **镜像管理:**`Harbor`作为一个企业级的镜像仓库,支持`Docker`和`OCI`格式镜像的存储和管理。 +- **细粒度的访问控制:**通过基于角色的访问控制`(RBAC)`,`Harbor`能够确保不同用户在仓库中的操作权限得到精确控制。 +- **镜像复制:**支持跨多个`Harbor`实例进行镜像复制,帮助实现多数据中心或混合云环境下的高效镜像分发。 +- **漏洞扫描**: 集成了`Clair`或`Trivy`等安全工具,`Harbor`可以自动扫描镜像中的安全漏洞,确保部署的镜像安全。 +- **镜像签名和内容信任:**通过`Notary`集成,`Harbor`支持镜像的签名和验证,确保镜像的完整性和可信度。 +- **日志与审计:**提供详细的操作日志和审计功能,帮助企业了解镜像的使用和管理情况。 +- **多租户支持:**`Harbor`支持项目隔离,帮助企业实现多租户环境下的镜像管理。 +- **LDAP/AD 支持:**`Harbor`与现有的企业`LDAP/AD`集成以进行用户身份验证和管理,并支持将`LDAP`组导入`Harbor`,然后可以授予特定项目的权限。 +- **镜像删除和垃圾收集:**系统管理员可以运行垃圾回收作业,以便可以删除**镜像**(悬挂的`manifests`和未引用的`blobs`),并且可以定期释放这些空间。 +- **审核:**对存储库的所有操作都通过日志进行跟踪。 +- **RESTful API:**提供`RESTful API`以方便管理操作,并且易于使用以与外部系统集成。嵌入式`Swagger UI`可用于探索和测试`API`。 + +### 3. harbor 的架构 + +​ `Harbor`的架构设计遵循微服务原则,由多个松耦合的组件组成,每个组件负责不同的功能模块。在`V2.0`版本,已经完全符合`OCI`标准。 + +下图是`Harbor`的整体架构。 + +![](accents\image-202504040003.png) + +### 4. harbor 的组件介绍 + +如上图所示,Harbor 由放置在 3 层中的以下组件组成: + +#### 1. 数据访问层(Data Access Layer) + +​ 数据访问层主要负责存储和管理容器镜像以及相关的元数据,是整个 Harbor 系统的基础。它包括以下几个核心组件: + +- **k-v 存储:** 由 Redis 组成,提供数据缓存功能,并支持临时持久化 Job 服务的 Job 元数据。 +- **Registry(镜像仓库)**: 基于 Docker Registry 扩展的核心组件,负责存储容器镜像及其标签(tags)。它支持 Docker 和 OCI 格式的镜像,并允许通过 HTTP API 进行镜像的上传、下载和管理。 +- **Database(数据库)**: Harbor 使用 PostgreSQL 数据库存储元数据,包括用户信息、项目、镜像标签、访问控制策略等。数据库是 Harbor 中各个功能模块元数据管理的核心。 +- **Object Storage**: Harbor 也支持将镜像存储在对象存储中,支持的存储后端包括文件系统、S3、Ceph 等。对象存储用于存储实际的镜像层(layers)和其他大文件数据。 + +#### 2. 基础服务(Fundamental Services) + +​ 基础服务,即是核心层,负责处理业务逻辑,是系统的心脏。这个层次负责管理用户、权限控制、镜像的生命周期、任务调度等操作。 + +- **Proxy:** 由 Nginx Server 组成的反向代理,提供 API 路由能力。Harbor 的组件,如核心、注册中心、Web 门户和 Token 服务等,都位于这个反向代理的后面。代理将来自浏览器和 Docker 客户端的请求转发到各种后端服务。 + +**核心:** Harbor 的核心服务,主要提供以下功能: + +- **API Service:**该组件是`Harbor`的核心服务,处理所有`API`请求。它负责用户身份验证、项目和镜像的管理,以及与其他微服务的交互。它还管理系统中的访问控制`(RBAC)`以及任务调度。 +- **Job Service:**负责异步任务的处理,比如镜像的复制、漏洞扫描等。它通过消息队列来调度任务,并监控任务的执行状态。 +- **Notary:**该组件用于提供镜像的签名与验证服务,确保镜像的来源可信。`Notary`通过实现`Docker Content Trust (DCT)`来保护镜像的完整性。 +- **Clair/Trivy:**这是`Harbor`的漏洞扫描服务,负责对上传的镜像进行安全漏洞扫描。通过定期扫描镜像中的已知漏洞`(CVE)`,帮助管理员发现并修复潜在的安全问题。 +- **Replication Controller**(**复制控制器**):管理复制策略和第三方容器仓库的适配器,触发和监控并发复制进程。实现了许多第三方容器仓库适配器,包括不限于`docker registry`、`Docker Hub`、`Huawei SWR`、阿里 `ACR`等。 +- **k (通知管理器)**:在`Harbor`中配置的一种机制,以便可以将`Harbor`中的工件状态更改事件触发`Harbor`中配置的`Webhook`端点。而第三方应用可以通过侦听相关的`webhook`事件来触发一些后续操作。现在,支持两种方式: + 1. `HTTP Post`请求 + 2. `Slack channel` +- **Log collector(日志收集器):** 日志收集器,负责将其他模块的日志收集到一个地方。 + +#### 3. 消费者(Consumers) + +- **外部客户端**:作为标准的云原生容器仓库,自然会支持相关客户端,如`docker CLI`、`notary`客户端、`OCI`兼容客户端`(如 Oras)`和`Helm`。除了这些客户端。 +- **Web 门户:** 一个图形用户界面,可帮助用户管理`Registry`上的映像。 + +## 二:harbor 部署 + +环境:安装`docker`、`docker-compose` + +### 1. 下载 + +安装包下载地址:[Tags · goharbor/harbor · GitHub](https://github.com/goharbor/harbor/tags) + +```bash +[root@harbor ~]# wget https://github.com/goharbor/harbor/releases/download/v2.12.2/harbor-offline-installer-v2.12.2.tgz + +解压 +[root@harbor ~]# tar xf harbor-offline-installer-v2.12.2.tgz -C /usr/local/ +``` + +### 2. 配置 + +修改配置文件 + +```bash +[root@harbor ~]# cd /usr/local/harbor/ +[root@harbor harbor]# mv harbor.yml.tmpl harbor.yml +[root@harbor harbor]# vim harbor.yml +修改主机IP +hostname: 192.168.159.132 + +注释https +# https related config +# https: + # https port for harbor, default is 443 + # port: 443 + # The path of cert and key files for nginx + # certificate: /your/certificate/path + # private_key: /your/private/key/path + +修改密码 +harbor_admin_password: Harbor12345 +``` + +### 3. 导入镜像 + +```bash +[root@harbor harbor]# docker load -i harbor.v2.12.2.tar.gz + +# 查看镜像 +[root@harbor harbor]# docker images +REPOSITORY TAG IMAGE ID CREATED SIZE +goharbor/harbor-exporter v2.8.2 63341a78f287 22 months ago 98.1MB +goharbor/redis-photon v2.8.2 6f4498a430ca 22 months ago 121MB +goharbor/trivy-adapter-photon v2.8.2 06de9f1c733d 22 months ago 460MB +goharbor/notary-server-photon v2.8.2 ef7c8ea2dc49 22 months ago 114MB +goharbor/notary-signer-photon v2.8.2 4e5b1746a124 22 months ago 111MB +goharbor/harbor-registryctl v2.8.2 fa61a236a6d6 22 months ago 142MB +goharbor/registry-photon v2.8.2 f80e71363231 22 months ago 79.3MB +goharbor/nginx-photon v2.8.2 3d009028f260 22 months ago 120MB +goharbor/harbor-log v2.8.2 2914d282d9bf 22 months ago 127MB +goharbor/harbor-jobservice v2.8.2 40118f1568a8 22 months ago 141MB +goharbor/harbor-core v2.8.2 0bbbd1f379fc 22 months ago 165MB +goharbor/harbor-portal v2.8.2 3e74e0758aa4 22 months ago 127MB +goharbor/harbor-db v2.8.2 5126635ae9f0 22 months ago 174MB +goharbor/prepare v2.8.2 eb3cf3cdd17a 22 months ago 163MB +``` + +### 4. 初始化与安装 + +```bash +# 初始化 +[root@harbor harbor]# ./prepare + +# 安装 +[root@harbor harbor]# ./install.sh +``` + +### 5. 查看 harbor 状态 + +```bash +[root@harbor harbor]# docker-compose ps +NAME COMMAND SERVICE STATUS PORTS +harbor-core "/harbor/entrypoint.…" core running (healthy) +harbor-db "/docker-entrypoint.…" postgresql running (healthy) +harbor-jobservice "/harbor/entrypoint.…" jobservice running (healthy) +harbor-log "/bin/sh -c /usr/loc…" log running (healthy) 127.0.0.1:1514->10514/tcp +harbor-portal "nginx -g 'daemon of…" portal running (healthy) +nginx "nginx -g 'daemon of…" proxy running (healthy) 0.0.0.0:80->8080/tcp, :::80->8080/tcp +redis "redis-server /etc/r…" redis running (healthy) +registry "/home/harbor/entryp…" registry running (healthy) +registryctl "/home/harbor/start.…" registryctl running (healthy) +``` + +### 6. 操作 + +关闭`harbor` + +```bash +[root@harbor harbor]# docker-compose stop +``` + +启动`harbor` + +```bash +[root@harbor harbor]# docker-compose start +``` + +创建`harbor` + +```bash +[root@harbor harbor]# docker-compose up -d +``` + +删除`harbor` + +```bash +[root@harbor harbor]# docker-compose down +``` + +### 7. 推送镜像到 harbor + +登录页面:http://ip:80 + +![](accents\image-202504040004.png) + +密码:配置文件中 + +docker 添加 harbor 仓库 + +```bash +[root@docker ~]# vim /etc/docker/daemon.json +{"insecure-registries":["http://192.168.159.132"]} +``` + +重启 docker + +```bash +[root@docker ~]# systemctl daemon-reload +[root@docker ~]# systemctl restart docker +``` + +查看dcoker是否配置成功 + +```bash +[root@docker ~]# docker info + Insecure Registries: + 192.168.159.132 + 127.0.0.0/8 + Live Restore Enabled: false +``` + +docker 客户端登录 harbor + +```bash +[root@docker ~]# docker login 192.168.159.132 +Username: admin +Password: +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 + +```bash +[root@docker ~]# docker tag centos:7 192.168.159.132/library/centos:7 +``` + +推送镜像 + +```bash +[root@docker ~]# docker push 192.168.159.132/library/centos:7 +The push refers to repository [192.168.159.132/library/centos] +174f56854903: Pushed +7: digest: sha256:dead07b4d8ed7e29e98de0f4504d87e8880d4347859d839686a31da35a3b532f size: 529 +``` + +查看页面 + +![](accents\image-202504040005.png) + diff --git a/docker-基础.md b/docker-基础.md new file mode 100644 index 0000000..79c333c --- /dev/null +++ b/docker-基础.md @@ -0,0 +1,420 @@ +

Docker

+ +------ + +## 一:容器 + +### 1. 容器介绍 + +![](accents\image-202503310001.png) + +​ 容器(container)其实是一种沙盒技术。顾名思义,沙盒就是能够像一个集装箱一样,把你的应用"装"起来的技术。这样,应用与应用之间,就因为有了边界而不至于相互干扰;而被装进集装箱的应用,也可以被方便地搬来搬去,这其实是 PaaS 最理想的状态。 + +### 2. Docker VS 传统 + +**部署方式** + +- 传统的部署模式: 安装(包管理工具或者源码包编译)->配置->运行 +- Docker部署模式: 复制->运行 + +**容器和虚拟机** + +1. 容器提供了基于进程的隔离,而虚拟机提供了资源的完全隔离。 +2. 虚拟机可能需要一分钟来启动,而容器只需要一秒钟或更短。 + +3. 容器使用宿主操作系统的内核,而虚拟机使用独立的内核 + +4. 容器只是一个进程,而虚拟机不是 + +![](C:\Users\wxin\Desktop\docker\accents\image-202503310002.png) + +​ 容器是应用程序层的抽象,将代码和依赖项打包在一起。多个容器可以在同一台计算机上运行,并与其他容器共享`OS`内核,每个容器在用户空间中作为隔离的进程运行。容器占用的空间少于`VM`,可以处理更多的应用程序,并且需要的`VM`和操作系统更少。 + + **Docker对服务器端开发/部署带来的变化:** + +- 实现更轻量级的虚拟化,方便快速部署 +- 对于部署来说可以极大的减少部署的时间成本和人力成本 + +​ `Docker`支持将应用打包进一个可以移植的容器中,重新定义了应用开发,测试,部署上线的过程,核心理念就是 Build once, Run anywhere + +1. 标准化应用发布,`docker`容器包含了运行环境和可执行程序,可以跨平台和主机使用; +2. 节约时间,快速部署和启动,`VM`启动一般是分钟级,`docker`容器启动是秒级; +3. 方便构建基于`SOA`架构或微服务架构的系统,通过服务编排,更好的松耦合; +4. 节约成本,以前一个虚拟机至少需要几个`G`的磁盘空间,`docker`容器可以减少到`MB`级; +5. 方便持续集成,通过与代码进行关联使持续集成非常方便; +6. 可以作为集群系统的轻量主机或节点,在`IaaS`平台上,已经出现了`CaaS`,通过容器替代原来的主机。 + +### 3. 云计算服务类型 + +- 基础设施即服务`IaaS` +- 平台即服务`PaaS` +- 软件即服务`SaaS` + +**注意:** + +**IAAS:**指把IT基础设施作为一种服务通过网络对外提供,并根据用户对资源的实际使用量或占用量进行计费的一种服务模式。 + +**PaaS:**为开发人员提供了一个框架,使他们可以基于它创建自定义应用程序。所有服务器,存储和网络都可以由企业或第三方提供商进行管理,而开发人员可以负责应用程序的管理。 + +**SaaS:**提供商为企业搭建信息化所需要的所有网络基础设施及软件、硬件运作平台,并负责所有前期的实施、后期的维护等一系列服务,企业无需购买软硬件、建设机房、招聘IT人员,即可通过互联网使用信息系统。就像打开自来水龙头就能用水一样,企业根据实际需要,向`SaaS`提供商租赁软件服务。 + +### 4. Docker 的优势 + +**交付物标准化** + +​ `Docker`是软件工程领域的"标准化"交付组件,最恰到好处的类比是"集装箱";集装箱将零散、不易搬运的大量物品封装成一个整体,集装箱更重要的意义在于它提供了一种通用的封装货物的标准,卡车、火车、货轮、桥吊等运输或搬运工具采用此标准,隧道、桥梁等也采用此标准。以集装箱为中心的标准化设计大大提高了物流体系的运行效率。 + +注意: + +​ 传统的软件交付物包括:应用程序、依赖软件安装包、配置说明文档、安装文档、上线文档等非标准化组件。 + +​ `Docker`的标准化交付物称为"镜像",它包含了应用程序及其所依赖的运行环境,大大简化了应用交付的模式。 + +**一次构建,多次交付** + +​ 类似于集装箱的"一次装箱,多次运输",`Docker`镜像可以做到"一次构建,多次交付"。当涉及到应用程序多副本部署或者应用程序迁移时,更能体现`Docker`的价值。 + +**应用隔离** + +​ 集装箱可以有效做到货物之间的隔离,使化学物品和食品可以堆砌在一起运输。`Docker`可以隔离不同应用程序之间的相互影响,但是比虚拟机开销更小。 + +​ 总之,容器技术部署速度快,开发、测试更敏捷;提高系统利用率,降低资源成本。 + +### 5. Docker 的度量 + +​ `Docker`是利用容器来实现的一种轻量级的虚拟技术,从而在保证隔离性的同时达到节省资源的目的。`Docker`的可移植性可以让它一次建立,到处运行。`Docker`的度量可以从以下四个方面进行: + +1. **隔离性** + - `Docker`采用`libcontainer`作为默认容器,代替了以前的`LXC`。libcontainer的隔离性主要是通过内核的命名空间来实现 的,有`pid`、`net`、`ipc`、`mnt`、`uts`命令空间,将容器的进程、网络、消息、文件系统和主机名进行隔离。 +2. **可度量性** + - `Docker`主要通过`cgroups`控制组来控制资源的度量和分配。 +3. **移植性** + - `Docker`利用`AUFS`来实现对容器的快速更新。 + - `AUFS`是一种支持将不同目录挂载到同一个虚拟文件系统下的文件系统,支持对每个目录的读写权限管理。`AUFS`具有层的概念,每一次修改都是在已有的只写层进行增量修改,修改的内容将形成新的文件层,不影响原有的层。 +4. **安全性** + - 安全性可以分为容器内部之间的安全性;容器与托管主机之间的安全性。 + - 容器内部之间的安全性主要是通过命名空间和`cgroups`来保证的。 + - 容器与托管主机之间的安全性主要是通过内核能力机制的控制,可以防止`Docker`非法入侵托管主机。 + +**Docker容器使用AUFS作为文件系统,有如下优势** + +1. **节省存储空间:**多个容器可以共享同一个基础镜像存储。 +2. **快速部署:**如果部署多个来自同一个基础镜像的容器时,可以避免多次复制操作。 +3. **升级方便:**升级一个基础镜像即可影响到所有基于它的容器。 +4. **增量修改:**可以在不改变基础镜像的同时修改其目录的文件,所有的更高都发生在最上层的写操作层,增加了基础镜像的可共享内容。 + +## 二:Docker 核心概念 + +### 1. Docker 系统 + +`Docker`系统有两个程序:`docker`服务端和`docker`客户端 + +- `Docker`服务端:是一个服务进程,管理着所有的容器 +- `Docker`客户端:是`docker`服务端的远程控制器,可以用来控制`docker`的服务端进程 + +### 2. Docker 核心组件 + +- Docker 镜像 - Docker images +- Docker 仓库 - Docker registeries +- Docker 容器 - Docker containers + +**容器组成要素** + +- 命名空间 namespace +- 资源限制 cgroups +- 文件系统 overlay2(UnionFS) + +#### 2.1 Docker 仓库 + +​ 用来保存镜像,可以理解为代码控制中的代码仓库。同样的,Docker 仓库也有公有和私有的概念。 + +​ 公有的 Docker 仓库名字是 Docker Hub + +**库:registry** + +- 公有库:Docker-hub Daocloud ali 网易蜂巢 +- 私有库:公司内部使用(自己部署) + +**分类:** + +- 操作系统名称 centos ubuntu +- 应用名称 nginx tomcat mysql + +**Tag:** + +- 表示镜像版本 + +#### 2.2 Docker 镜像 + +​ Docker 镜像是 Docker 容器运行时的只读模板,每一个镜像由一系列的层 (layers) 组成。 + +​ 每一个镜像都可能依赖于由一个或多个下层的组成的另一个镜像,下层那个镜像是上层镜像的父镜像。 + +**镜像名称:** + +```shell +registry/repo:tag +``` + +**基础镜像** + +​ 一个没有任何父镜像的镜像,谓之基础镜像 + +**镜像ID** + +​ 所有镜像都是通过一个 64 位十六进制字符串 (内部是一个 256 bit 的值)来标识的。 为简化使用,前 12 个字符可以组成一个短ID,可以在命令行中使用。短ID还是有一定的碰撞机率,所以服务器总是返回长ID。 + +**镜像名称** + +​ 镜像是`Docker`最核心的技术之一,也是应用发布的标准格式。无论你是用`docker pull image`,或者是在`Dockerfile`里面写`FROM image`,下载镜像应该是`Docker`操作里面最频繁的动作之一。 + +下面是在本地机器运行`docker images`的输出结果: + +```bash +[root@docker ~]# docker images +REPOSITORY TAG IMAGE ID CREATED SIZE +wxin/centos v1 fe13d78ff413 34 minutes ago 231MB +mysql 5.7 5107333e08a8 15 months ago 501MB +centos latest 5d0da3dc9764 3 years ago 231MB +centos v7 5d0da3dc9764 3 years ago 231MB +``` + +​ 常说的`centos`镜像其实不是一个镜像名称,而是代表了一个名为`centos`的`Repository`,同时在这个`Repository`下面有一系列打了`tag`的`Image`,`Image`的标记是一个`GUID`,为了方便也可以通过`Repository:tag`来引用。 + +​ 那么`Registry`又是什么呢?`Registry`存储镜像数据,并且提供拉取和上传镜像的功能。 + +​ `Registry`中镜像是通过`Repository`来组织的,而每个`Repository`又包含了若干个`Image`。 + +- `Registry`包含一个或多个`Repository` +- `Repository`包含一个或多个`Image` +- `Image`用`GUID`表示,有一个或多个`Tag`与之关联 + +**注意:** + +​ 当一个镜像的名称不足以分辨这个镜像所代表的含义时,你可以通过tag将版本信息添加到`run`命令中,以执行特定版本的镜像。 + +```bash +docker run ubuntu:14.04 +``` + + + +#### 2.3 Docker 容器 + +​ Docker 容器和文件夹很类似,一个Docker容器包含了所有的某个应用运行所需要的环境。 + +​ 每一个 Docker 容器都是从 Docker 镜像创建的。Docker 容器可以运行、开始、停止、移动和删除。 + +​ 每一个 Docker 容器都是独立和安全的应用平台,Docker 容器是 Docker 的运行部分。 + +Docker容器可以使用命令创建: + +```bash +docker run imagename +``` + +​ 它会在所有的镜像层之上增加一个可写层。这个可写层有运行在CPU上的进程,而且有两个不同的状态: + +- 运行态(Running) +- 退出态 (Exited) + +​ 这就是Docker容器。当我们使用docker run启动容器,Docker容器就进入运行态,当我们停止Docker容器时,它就进入退出态。当我们有一个正在运行的Docker容器时,从运行态到停止态,我们对它所做的一切变更都会永久地写到容器的文件系统中。要切记,对容器的变更是写入到容器的文件系统的,而不是写入到Docker镜像中的。我们可以用同一个镜像启动多个Docker容器,这些容器启动后都是活动的,彼此还是相互隔离的。我们对其中一个容器所做的变更只会局限于那个容器本身。如果对容器的底层镜像进行修改,那么当前正在运行的容器是不受影响的,不会发生自动更新现象。 + +​ 64字符的十六进制的字符串来定义容器ID,它是容器的唯一标识符。容器之间的交互是依靠容器ID识别的,由于容器ID的字符太长,我们通常只需键入容器ID的前4个字符即可。当然,我们还可以使用容器名。 + +**容器名称** + +​ --name= Assign a name to the container + +​ --为容器分配一个名字,如果没有指定,会自动分配一个随机名称 + +​ --docker run子命令的参数 + +**容器命名方式** + +​ 使用`UUID`长命名`("f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778")` + +​ 使用`UUID`短命令`("f78375b1c487")` + +​ 使用`Name("centos") ` + +**注意:** + +- 这个`UUID`标识是由`Docker deamon`生成的 +- 如果你在执行`docker run`时没有指定`--name`,那么`deamon`会自动生成一个随机字符串`UUID` +- 但是对于一个容器来说有个`name`会非常方便,当你需要连接其它容器时或者类似需要区分其它容器时,使用容器名称可以简化操作。无论容器运行在前台或者后台,这个名字都是有效的 +- 如果在使用`Docker`时有自动化的需求,你可以将`containerID`输出到指定的文件中`(PIDfile)`类似于某些应用程序将自身`ID`输出到文件中,方便后续脚本操作 + +```bash +--cidfile="": Write the container ID to the file +``` + +### 3. 命名空间 + +​ 命名空间是 Linux 内核一个强大的特性。每个容器都有自己单独的命名空间,运行在其中的应用都像是在独立的操作系统中运行一样。命名空间保证了容器之间彼此互不影响。 + +1. **`pid`命名空间** + + 不同用户的进程就是通过`pid`名字空间隔离开的,且不同名字空间中可以有相同`pid`。所有的`LXC`进程在`Docker`中的父进程为`Docker`进程,每个 `LXC`进程具有不同的名字空间。同时由于允许嵌套,因此可以很方便的实现嵌套的`Docker`容器。 + +2. **`net`命名空间** + + 有 了`pid`名字空间, 每个名字空间中的`pid`能够相互隔离,但是网络端口还是共享`host`的端口。网络隔离是通过`net`名字空间实现的,每个`net` 名字空间有独立的 网络设备,`IP`地址, 路由表,`/proc/net`目录。这样每个容器的网络就能隔离开来。`Docker`默认采用`veth`的方式,将容器中的虚拟网卡同`host`上的一 个`Docker`网桥`docker0`连接在一起。 + +3. **`ipc`命名空间** + + 容器中进程交互还是采用了`Linux`常见的进程间交互方法(`interprocess communication - IPC`),包括信号量、消息队列和共享内存、`socket`、管道等。然而同`VM`不同的是,容器的进程间交互实际上还是`host`上具有相同`pid`名字空间中的进程间交互,因此需要在`IPC`资源申请时加入名字空间信息,每个`IPC`资源有一个唯一的 32 位`id`。 + +4. **`mnt`命名空间** + + 类似`change root`,将一个进程放到一个特定的目录执行。`mnt`名字空间允许不同名字空间的进程看到的文件结构不同,这样每个名字空间 中的进程所看到的文件目录就被隔离开了。同`chroot`不同,每个名字空间中的容器在`/proc/mounts`的信息只包含所在名字空间的`mount point`。 + +5. **`uts`命名空间** + + `UTS`("UNIX Time-sharing System") 名字空间允许每个容器拥有独立的 `hostname`和`domain name`,使其在网络上可以被视作一个独立的节点而非主机上的一个进程。 + +6. **`user`命名空间** + + 每个容器可以有不同的用户和组`id`,也就是说可以在容器内用容器内部的用户执行程序而非主机上的用户。 + +## 三:Docker 安装 + +### 1. Docker 版本 + +- **Docker-ce:**是docker公司维护的开源项目,是一个基于moby项目的免费的容器产品 +- **Docker-ee:**是docker公司维护的闭源产品,是docker公司的商业产品。 + +### 2. Docker 安装 + +```bash +[root@docker ~]# yum install -y yum-utils +[root@docker ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo +[root@docker ~]# yum -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin +``` + +### 3. 配置docker加速器 + +**配置DNS** + +```bash +vim /etc/resolv.conf +; generated by /usr/sbin/dhclient-script +nameserver 114.114.114.114. +nameserver 8.8.8.8 +options edns0 trust-ad +search localdomain +``` + +**配置加速器** + +```bash +[root@docker ~]# vim /etc/docker/daemon.json +{ + "max-concurrent-downloads": 10, + "max-concurrent-uploads": 5, + "default-shm-size": "1G", + "debug": true, + "experimental": false, + "registry-mirrors":[ + "https://x9r52uz5.mirror.aliyuncs.com", + "https://dockerhub.icu", + "https://docker.chenby.cn", + "https://docker.1panel.live", + "https://docker.awsl9527.cn", + "https://docker.anyhub.us.kg", + "https://dhub.kubesre.xyz" + ] +} +[root@docker ~]# systemctl daemon-reload +``` + +### 4. 启动服务 + +```bash +[root@docker ~]# systemctl start docker +[root@docker ~]# systemctl enable docker +``` + +### 5. Docker 查看 + +**查看安装版本** + +```bash +[root@docker ~]# docker -v +Docker version 26.1.4, build 5650f9b +``` + +**查看docker运行状态** + +```bash +[root@docker ~]# docker info +Client: Docker Engine - Community + Version: 26.1.4 + Context: default + Debug Mode: false + Plugins: + buildx: Docker Buildx (Docker Inc.) + Version: v0.14.1 + Path: /usr/libexec/docker/cli-plugins/docker-buildx + compose: Docker Compose (Docker Inc.) + Version: v2.27.1 + Path: /usr/libexec/docker/cli-plugins/docker-compose + +Server: + Containers: 0 + Running: 0 + Paused: 0 + Stopped: 0 + Images: 0 + Server Version: 26.1.4 + Storage Driver: overlay2 + Backing Filesystem: xfs + Supports d_type: true + Using metacopy: false + Native Overlay Diff: true + userxattr: false + Logging Driver: json-file + Cgroup Driver: cgroupfs + Cgroup Version: 1 + Plugins: + Volume: local + Network: bridge host ipvlan macvlan null overlay + Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog + Swarm: inactive + Runtimes: io.containerd.runc.v2 runc + Default Runtime: runc + Init Binary: docker-init + containerd version: d2d58213f83a351ca8f528a95fbd145f5654e957 + runc version: v1.1.12-0-g51d5e94 + init version: de40ad0 + Security Options: + seccomp + Profile: builtin + Kernel Version: 3.10.0-1160.el7.x86_64 + Operating System: CentOS Linux 7 (Core) + OSType: linux + Architecture: x86_64 + CPUs: 4 + Total Memory: 1.934GiB + Name: docker + ID: 8d6f9241-c1b7-4371-bc14-eaf68f0c3760 + Docker Root Dir: /var/lib/docker + Debug Mode: true + File Descriptors: 25 + Goroutines: 43 + System Time: 2025-03-31T18:15:55.298009462+08:00 + EventsListeners: 0 + Experimental: false + Insecure Registries: + 127.0.0.0/8 + Registry Mirrors: + https://x9r52uz5.mirror.aliyuncs.com/ + https://dockerhub.icu/ + https://docker.chenby.cn/ + https://docker.1panel.live/ + https://docker.awsl9527.cn/ + https://docker.anyhub.us.kg/ + https://dhub.kubesre.xyz/ + Live Restore Enabled: false +``` + diff --git a/docker-进阶.md b/docker-进阶.md new file mode 100644 index 0000000..061c817 --- /dev/null +++ b/docker-进阶.md @@ -0,0 +1,294 @@ +

Docker 进阶

+ +------ + +## 一:端口转发 + +使用端口转发解决容器端口访问问题 + +- -p 手工指定 +- -P 随机端口 + +### 1. MySQL 应用端口转发 + +`-p`: + +​ 创建应用容器的时候,一般会做端口映射,这样是为了让外部能够访问这些容器里的应用。可以用多个-p指定多个端口映射关系 + +`mysql`应用端口转发: + +```bash +查看本地地址: +[root@docker ~]# ip a +inet 192.168.159.131/24 brd 192.168.159.255 scope global noprefixroute ens33 +``` + +​ 运行容器:使用`-p`作端口转发,把本地`3307`转发到容器的`3306`,其他参数需要查看发布容器的页面提示。 + +```bash +[root@docker ~]# docker run -it -d --name="mysql-v1" -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_ROOT_HOST='%' mysql:5.7 + +查看容器ip +[root@docker ~]# docker inspect mysql-v1 | grep IPAddress + "SecondaryIPAddresses": null, + "IPAddress": "172.17.0.2", + "IPAddress": "172.17.0.2", +``` + +登入容器mysql + +```bash +[root@docker ~]# docker exec -it mysql-v1 mysql -uroot -p +... +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +mysql> +``` + +远程登入 + +```bash +[root@docker ~]# mysql -uroot -P 3307 -h 192.168.159.131 -p +... +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +mysql> +``` + +### 2. Redis 应用端口转发 + +`-P` + +​ Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口。 + +`redis`应用端口转发: + +```bash +查看本地地址: +[root@docker ~]# ip a +inet 192.168.159.131/24 brd 192.168.159.255 scope global noprefixroute ens33 +``` + +运行容器:使用`-p`作端口转发,把本地`6380`转发到容器的`6379`,其他参数需要查看发布容器的页面提示 + +```bash +[root@docker ~]# docker run -it --name="redis-v1" -p 6380:6379 redis:latest --bind 0.0.0.0 +``` + +登入容器 + +```bash +[root@docker ~]# docker exec -it redis-v1 redis-cli +127.0.0.1:6379>set name wxin +OK +``` + +远程登入 + +```bash +[root@docker ~]# redis-cli -h 192.168.159.131 -p 6380 +192.168.159.131:6380> get name +"wxin" +``` + +## 二:Docker 私有仓库 + +### 1. 仓库镜像 + +​ `Docker hub`官方已提供容器镜像`registry`,用于搭建私有仓库 + +**拉取镜像** + +```bash +# docker pull daocloud.io/library/registry:latest +``` + +### 2. 运行容器 + +```bash +# docker run --name "pri_registry" --restart=always -d -p 5000:5000 daocloud.io/library/registry +``` + + 注:如果创建容器不成功,报错防火墙,解决方案如下 + +```bash +# systemctl stop firewalld +# yum install iptables +# systemctl start iptables +# iptables -F +# systemctl restart docker +``` + +### 3. 查看容器 + +```bash +# docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +1f444285bed8 daocloud.io/library/registry "/entrypoint.sh /etc/" 23 seconds ago Up 21 seconds 0.0.0.0:5000->5000/tcp elegant_rosalind +``` + +### 4. 连接容器查看端口状态 + +```bash +# docker exec -it 1f444285bed8 /bin/sh //这里是sh 不是bash + /# netstat -lnp //查看5000端口是否开启 + Active Internet connections (only servers) + Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name + tcp 0 0 :::5000 :::* LISTEN 1/registry + Active UNIX domain sockets (only servers) + Proto RefCnt Flags Type State I-Node PID/Program name Path +``` + +在本机查看能否访问该私有仓库, 看看状态码是不是200: + +```bash +# curl -I 127.0.0.1:5000 //参数是大写的i +HTTP/1.1 200 OK +Cache-Control: no-cache +Date: Thu, 08 Oct 2020 05:34:32 GMT +``` + +### 5. 仓库功能测试 + +为了方便,下载1个比较小的镜像,buysbox + +```bash +# docker pull busybox +``` + +上传前必须给镜像打tag 注明ip和端口: + +```bash +# docker tag busybox  本机IP:端口/busybox +``` + +这是直接从官方拉的镜像,很慢: + +```bash +# docker tag busybox 192.168.245.136:5000/busybox +``` + +下面这个Mysql是我测试的第二个镜像,从daocloud拉取的: + +```bash +# docker tag daocloud.io/library/mysql 192.168.245.136:5000/daocloud.io/library/mysql +``` + +注意: + +​ `tag`后面可以使用镜像名称也可以使用`id`,我这里使用的镜像名称,如果使用官方的镜像,不需要加前缀,但是`daocloud.io`的得加前缀。 + +修改请求方式为`http`: + +```bash +默认为https,不改会报以下错误: +Get https://master.up.com:5000/v1/_ping: http: server gave HTTP response to HTTPS client +# vim /etc/docker/daemon.json +{ "insecure-registries":["192.168.245.136:5000"] } + +重启docker: +# systemctl restart docker +``` + +上传镜像到私有仓库 + +```bash +# docker push 192.168.245.136:5000/busybox +# docker push 192.168.245.136:5000/daocloud.io/library/mysql +``` + +查看私有仓库里的所有镜像: + +```bash +# curl 192.168.245.130:5000/v2/_catalog +{"repositories":["busybox"]} +``` + +查看私有仓库里的镜像版本: + +```bash +# curl 10.11.67.110:5000/v2/busybox/tags/list +{"name":"busybox","tags":["v1","v2"]} + +# curl -XGET http://10.11.67.110:3000/v2/busybox/tags/list +{"name":"busybox","tags":["v1","v2"]} +查询镜像digest_hash,删除命令里边要填写的 镜像digest_hash 就是 查询结果里边 Docker-Content-Digest: 后边的内容 +# curl --header "Accept:application/vnd.docker.distribution.manifest.v2+json" -I -XGET http://10.11.67.110:3000/v2/busybox/manifests/v1 +HTTP/1.1 200 OK +Content-Length: 527 +Content-Type: application/vnd.docker.distribution.manifest.v2+json +Docker-Content-Digest: sha256:c9249fdf56138f0d929e2080ae98ee9cb2946f71498fc1484288e6a935b5e5bc +Docker-Distribution-Api-Version: registry/2.0 +Etag: "sha256:c9249fdf56138f0d929e2080ae98ee9cb2946f71498fc1484288e6a935b5e5bc" +X-Content-Type-Options: nosniff +Date: Thu, 12 Nov 2020 07:29:46 GMT +删除私有库镜像 +进入/etc/docker/registry/config.yml添加,在stroage后面加 +delete + enabled: true + +修改完后重新启动容器 +# curl -I -XDELETE http://10.11.67.110:3000/v2/busybox/manifests/sha256:c9249fdf56138f0d929e2080ae98ee9cb2946f71498fc1484288e6a935b5e5bc +HTTP/1.1 202 Accepted +Docker-Distribution-Api-Version: registry/2.0 +X-Content-Type-Options: nosniff +Date: Thu, 12 Nov 2020 07:30:22 GMT +Content-Length: 0 + +查看镜像信息可以看到镜像的标签显示为空 null +# curl -XGET http://10.11.67.110:3000/v2/busybox/tags/list +{"name":"busybox","tags":null} +``` + +## 三:Docker 网络 + +### 1. 容器网络 + +​ `docker`安装后,默认会创建三种网络类型,`bridge`、`host`和`none` + +**显示当前网络:** + +```bash +[root@docker ~]# docker network list +NETWORK ID NAME DRIVER SCOPE +3857f7cc9806 bridge bridge local +eb0052691d0f host host local +46decb5eed2f none null local +``` + +**bridge:网络桥接** + +​ 默认情况下启动、创建容器都是用该模式,所以每次`docker`容器重启时会按照顺序获取对应`ip`地址,这就导致容器每次重启,`ip`都发生变化。 + +**none:无指定网络** + +​ 启动容器时,可以通过`network=none`,`docker`容器不会分配局域网`ip`。 + +**host:主机网络** + +​ `docker`容器的网络会附属在主机上,两者是互通的。 + +### 2. 创建固定`ip`容器 + +创建自定义网络类型,并且指定网段: + +```bash +[root@docker ~]# docker network create --subnet=192.168.0.0/16 staticnet + +[root@docker ~]# docker network list +NETWORK ID NAME DRIVER SCOPE +3857f7cc9806 bridge bridge local +eb0052691d0f host host local +46decb5eed2f none null local +ab85da59edc7 staticnet bridge local +``` + +​ 通过`docker network ls`可以查看到网络类型中多了一个`staticnet` + +使用新的网络类型创建并启动容器: + +```bash +[root@docker ~]# docker run -it -d --name="mysql-v2" --net staticnet --ip 192.168.0.2 mysql:5.7 /bin/bash +``` + +​ 通过`docker inspect`可以查看容器`ip`为`192.168.0.2`,关闭容器并重启,发现容器`ip`并未发生改变。 diff --git a/docker-镜像构建.md b/docker-镜像构建.md new file mode 100644 index 0000000..e8faa20 --- /dev/null +++ b/docker-镜像构建.md @@ -0,0 +1,314 @@ +

Docker 镜像构建

+ +------ + +## 一:创建镜像 + +### 1. 容器文件系统打包 + +​ 将容器的文件系统打包成tar文件,也就是把正在运行的容器直接导出为tar包的镜像文件。 + +**导出** + +```bash +export + Export a container's filesystem as a tar archive +有两种方式(elated_lovelace为容器名): +第一种: +[root@docker ~]# docker export -o elated_lovelace.tar elated_lovelace +第二种: +[root@docker ~]# docker export 容器名称 > 镜像.tar +``` + +**导入** + +```bash +导入镜像归档文件到其他宿主机: +import + Import the contents from a tarball to create a filesystem image +[root@docker ~]# docker import elated_lovelace.tar elated_lovelace:v1 +``` + +**注意:** + +​ 如果导入镜像时没有起名字,随后可以单独起名字(没有名字和tag),可以手动加tag。 + +```bash +[root@docker ~]# docker tag 镜像ID mycentos:7 +``` + +### 2. 通过容器创建本地镜像 + +​ 容器运行起来后,又在里面做了一些操作,并且要把操作结果保存到镜像里。 + +**方案:** + +​ 使用`docker commit`指令,把一个正在运行的容器,直接提交为一个镜像。`commit`是提交的意思,类似告诉`svn`服务器我要生成一个新的版本。 + +例:在容器内部新建了一个文件 + +```bash +[root@docker ~]# docker exec -it 4ddf4638572d /bin/sh +[root@4ddf4638572d \]# touch test.txt +[root@4ddf4638572d \]# exit +将这个新建的文件提交到镜像中保存 +[root@docker ~]# docker commit 4ddf4638572d wing/helloworld:v2 +``` + +例: + +```bash +[root@docker ~]# docker commit -m "my images version1" -a "wing" 108a85b1ed99 daocloud.io/ubuntu:v2 + sha256:ffa8a185ee526a9b0d8772740231448a25855031f25c61c1b63077220469b057 + -m 添加注释 + -a 作者author + 108a85b1ed99 容器环境id + daocloud.io/ubuntu:v2 镜像名称:hub的名称/镜像名称:tag + -p,–pause=true 提交时暂停容器运行 +``` + +​ `Init`层的存在,是为了避免执行`docker commit 时`,把`Docker`自己对 `/etc/hosts`等文件做的修改,也一起提交掉。 + +### 3. 镜像迁移 + +​ 保存一台宿主机上的镜像为`tar`文件,然后可以导入到其他的宿主机上。 + +```bash +save + Save an image(s) to a tar archive +将镜像打包,与下面的load命令相对应 +[root@docker ~]# docker save -o nginx.tar nginx +load + Load an image from a tar archive or STDIN +与上面的save命令相对应,将上面sava命令打包的镜像通过load命令导入 +[root@docker ~]# docker load < nginx.tar +``` + +**注意:** + +- `tar`文件的名称和保存的镜像名称没有关系 +- 导入的镜像如果没有名称,自己打`tag`起名字 + +**扩展:**export和save的区别 + +- **export:**相当于容器快照,容器快照文件将丢弃所有的历史记录和元数据信息。 +- **save:**没有这个现象,就是完整的。 + +## 二:利用 Dockerfile 创建镜像 + +​ `docker build`命令用于根据给定的`Dockerfile`和上下文以构建`Docker`镜像。 + +**docker build语法:** + +```bash +docker build [OPTIONS] +``` + +### 1. 常用选项 + +```shell +--build-arg:设置构建时的变量 +--no-cache:默认false。设置该选项,将不使用Build Cache构建镜像 +--pull:默认false。设置该选项,总是尝试pull镜像的最新版本 +--compress:默认false。设置该选项,将使用gzip压缩构建的上下文 +--disable-content-trust:默认true。设置该选项,将对镜像进行验证 +--file, -f:Dockerfile的完整路径,默认值为‘PATH/Dockerfile’ +--isolation:默认--isolation="default",即Linux命名空间;其他还有process或hyperv +--label:为生成的镜像设置metadata +--squash:默认false。设置该选项,将新构建出的多个层压缩为一个新层,但是将无法在多个镜像之间共享新层;设置该选项,实际上是创建了新image,同时保留原有image。 +--tag, -t:镜像的名字及tag,通常name:tag或者name格式;可以在一次构建中为一个镜像设置多个tag +--network:默认default。设置该选项,Set the networking mode for the RUN instructions during build +--quiet, -q:默认false。设置该选项,Suppress the build output and print image ID on success +--force-rm:默认false。设置该选项,总是删除掉中间环节的容器 +--rm:默认--rm=true,即整个构建过程成功后删除中间环节的容器 +``` + +### 2. PATH | URL | - 说明 + +​ 给出命令执行的上下文。 + +​ `docker build`需要的各种文件必须放到上下文目录中 + +​ 上下文可以是构建执行所在的本地路径,也可以是远程`URL`,如`Git`库、tar包或文本文件等。如果是Git库,如https://github.com/docker/rootfs.git#container:docker,则隐含先执行`git clone --depth 1 --recursive`,到本地临时目录;然后再将该临时目录发送给构建进程。 + +​ 构建镜像的进程中,可以通过`ADD`命令将上下文中的任何文件加入到镜像中。 + +​ `-`表示通过`STDIN`给出`Dockerfile`或上下文。 + +**示例:** + +```shell +docker build - < Dockerfile +``` + +**说明:**该构建过程只有`Dockerfile`,没有上下文 + +```shell +docker build - < context.tar.gz +``` + +**说明:**其中Dockerfile位于context.tar.gz的根路径 + +```bash +[root@docker ~]# docker build -t champagne/bbauto:latest -t champagne/bbauto:v2.1 . +[root@docker ~]# docker build -f dockerfiles/Dockerfile.debug -t myapp_debug . +``` + +### 3. 创建镜像所在的文件夹和 Dockerfile 文件 + +```shell +[root@docker ~]# mkdir dockerfile-test +[root@docker ~]# cd dockerfile-test +[root@docker dockerfile-test]# touch Dockerfile +``` + +在Dockerfile文件中写入指令,每一条指令都会更新镜像的信息例如: + +```bash +[root@docker dockerfile-test]# vim Dockerfile +# This is a comment +FROM daocloud.io/library/centos:7 +MAINTAINER wing wing@qfedu.com +RUN 命令1;命令2;命令3 +RUN 命令 +``` + +**格式说明:** + +- 每行命令都是以`INSTRUCTION statement`形式,就是命令`+`清单的模式。命令要大写,`#`是注解 +- `FROM`命令是告诉`docker`我们的镜像什么 +- `MAINTAINER`是描述 镜像的创建人 +- `RUN`命令是在镜像内部执行。就是说他后面的命令应该是针对镜像可以运行的命令 + +### 4. 创建镜像 + +**命令:** + +```shell +[root@docker ~]# docker build -t centos:v2 . + +docker build 是docker创建镜像的命令 +-t 是标识新建的镜像 +centos 仓库名称 +:v2 tag +. 上下文目录,如果不用-f指定Dockerfile文件的位置和名称,默认会从上下文目录也就是这里指定的当前目录查找 +``` + +**详细执行过程:** + +```bash +[root@docker dockerfile-test]# docker build -t wxin/centos:v1 . +[+] Building 0.4s (6/6) FINISHED docker:default + => [internal] load build definition from Dockerfile 0.0s + => => transferring dockerfile: 201B 0.0s + => [internal] load metadata for docker.io/library/centos:latest 0.0s + => [internal] load .dockerignore 0.0s + => => transferring context: 2B 0.0s + => [1/2] FROM docker.io/library/centos:latest 0.0s + => [2/2] RUN touch test.txt && echo 1234567890 > test.txt 0.3s + => exporting to image 0.0s + => => exporting layers 0.0s + => => writing image sha256:fe13d78ff4131453ad82cec521f82ee79ba44fda5e 0.0s + => => naming to docker.io/wxin/centos:v1 +``` + +### 5. 创建完成后,从镜像创建容器 + +```bash +[root@docker dockerfile-test]# docker run -it -d --name="centos-v1" wxin/centos:v1 /bin/bash +``` + +## 三:Dockerfile文件构建容器 + +### 1. Dockerfile 文件构建 nginx + +```bash +[root@docker ~]# vim Dockerfile +FROM centos:7.2.1511 +ENV TZ=Asia/Shanghai +ENV LANG=en_US.UTF-8 +ENV LANGUAGE=en_US:en +ENV LC_ALL=en_US.UTF-8 +RUN yum -y install gcc openssl openssl-devel pcre-devel zlib-devel make +ADD nginx-1.14.0.tar.gz /opt/ +WORKDIR /opt/nginx-1.14.0 +RUN ./configure --prefix=/opt/nginx +RUN make && make install +WORKDIR /opt/nginx +RUN rm -rf /opt/nginx-1.14.0 +ENV NGINX_HOME=/opt/nginx +ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/nginx/sbin +EXPOSE 80 443 +CMD ["nginx", "-g", "daemon off;"] + +注意: +Nginx的docker仓库原文说明如下: +If you add a custom CMD in the Dockerfile, be sure to include -g daemon off; in the CMD in order fornginx to stay in the foreground, so that Docker can track the process properly (otherwise your container will stop immediately after starting)! +Running nginx in debug mode +Images since version 1.9.8 come with nginx-debug binary that produces verbose output when using higher log levels. It can be used with simple CMD substitution: +$ docker run --name my-nginx -v /host/path/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx nginx -g 'daemon off;' +Similar configuration in docker-compose.yml may look like this: + +web: + image: nginx + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf:ro + command: [nginx, '-g', 'daemon off;'] +``` + +### 2. Dockerfile 文件构建 redis + +```bash +[root@docker ~]# vim Dockerfile +FROM centos:7.2.1511 +MAINTAINER qf +ENV TZ=Asia/Shanghai +ENV LANG=en_US.UTF-8 +ENV LANGUAGE=en_US:en +ENV LC_ALL=en_US.UTF-8 +RUN yum -y install gcc make +ADD redis-4.0.9.tar.gz /opt/ +RUN cd /opt/ && mv redis-4.0.9 redis && cd /opt/redis && make && make install +RUN mkdir -p /opt/redis/logs && mkdir -p /opt/redis/data && mkdir -p /opt/redis/conf && cp /opt/redis/redis.conf /opt/redis/conf/ && cp /opt/redis/src/redis-trib.rb /usr/local/bin/ +EXPOSE 6379 +CMD ["redis-server","/opt/redis/conf/redis.conf"] +基于哨兵模式的redis镜像 +FROM centos:7.2.1511 +MAINTAINER redis4 jichujingxiang +ENV TZ=Asia/Shanghai +ENV LANG=en_US.UTF-8 +ENV LANGUAGE=en_US:en +ENV LC_ALL=en_US.UTF-8 +RUN yum -y install gcc make +ADD redis-4.0.9.tar.gz /opt/ +ADD run.sh / +RUN cd /opt/ && mv redis-4.0.9 redis && cd /opt/redis && make && make install +RUN mkdir -p /opt/redis/logs && mkdir -p /opt/redis/data && mkdir -p /opt/redis/conf && cp /opt/redis/redis.conf /opt/redis/conf/ && cp /opt/redis/src/redis-trib.rb /usr/local/bin/ && cp /opt/redis/sentinel.conf /opt/redis/conf/ && chmod 777 /run.sh +EXPOSE 6379 +CMD ["./run.sh"] + +[root@docker ~]# vim run.sh +#!/usr/bin/bash +cd /opt/redis/src/ +./redis-server /opt/redis/conf/redis.conf & #这一个要放在后台运行,不然下面的启动不了 +./redis-sentinel /opt/redis/conf/sentinel.conf +``` + +3.Dockerfile 文件构建 jenkins + +```bash +[root@docker ~]# vim Dockerfile +FROM local/c7-systemd +ADD jdk-9.0.1_linux-x64_bin.tar.gz /usr/local/ +ADD apache-tomcat-9.0.14.tar.gz /usr/local/ +WORKDIR /usr/local/ +ENV JAVA_HOME=/usr/local/java +ENV PATH=$JAVA_HOME/bin:$PATH +ENV CATALINA_HOME=/usr/local/tomcat +ENV export JAVA_HOME CATALINA_HOME PATH +RUN mv jdk-9.0.1 java && mv apache-tomcat-9.0.14 tomcat +COPY jenkins.war /usr/local/tomcat/webapps/ +EXPOSE 8080 +CMD ["/usr/local/tomcat/bin/catalina.sh","run"] +``` +