Docker官网:https://www.docker.com/
Docker概述
Docker 是一种运行于 Linux 和 Windows 上的软件,用于创建、管理和编排容器。
Docker 是在 GitHub 上开发的 Moby 开源项目的一部分。
Docker 公司,位于旧金山,是整个 Moby 开源项目的维护者。Docker 公司还提供包含支持服务的商业版本的 Docker。
Docker公司
Docker 公司位于旧金山,由法裔美籍开发者和企业家 Solumon Hykes 创立,其标志如下图所示。
有意思的是,Docker 公司起初是一家名为 dotCloud 的平台即服务(Platform-as-a-Service, PaaS)提供商。
底层技术上,dotCloud 平台利用了 Linux 容器技术。为了方便创建和管理这些容器,dotCloud 开发了一套内部工具,之后被命名为“Docker”。Docker就是这样诞生的!
2013年,dotCloud 的 PaaS 业务并不景气,公司需要寻求新的突破。于是他们聘请了 Ben Golub 作为新的 CEO,将公司重命名为“Docker”,放弃dotCloud PaaS 平台,怀揣着“将 Docker 和容器技术推向全世界”的使命,开启了一段新的征程。
如今 Docker 公司被普遍认为是一家创新型科技公司,据说其市场价值约为 10 亿美元。Docker 公司已经通过多轮融资,吸纳了来自硅谷的几家风投公司的累计超过 2.4 亿美元的投资。
几乎所有的融资都发生在公司更名为“Docker”之后。
提示:“Docker”一词来自英国口语,意为码头工人(Dock Worker),即从船上装卸货物的人。
Docker是什么
以下言论为个人理解
Docker是基于容器技术的轻量级虚拟化解决方案。对于我们使用者来说,需要了解镜像和容器的概念。
镜像是需要封装的,操作系统的厂家封装了一个最简化的操作系统,它包含了一个系统运行的最关键的组件,然后开发者可以根据需要,在这个最简化的系统上配置代码运行环境,或者直接将软件服务也顺便打包进去,并再次封装镜像。Docker是分层的,每次打包都是给镜像又包上了一层封装。我们使用者将各种镜像下载到本地,通过命令运行起来一个容器,就得到了一个与宿主机隔离的运行环境。
镜像就像“王者荣耀”里的各种英雄,英雄的技能、数据,除了官方更新,它是不会有什么变化的。镜像也是一样,封装好了之后,我们把它整个下载下来,只要我们不再次打包,也不会有什么变化。而容器就像我们选择一个英雄开始了一局对战,无论我们在对战中升了多少级,购买了什么装备,结束游戏后,都不会带出来。容器也是一样,通过容器启动镜像后,无论我们在容器中做了什么,都不会对镜像产生影响,重新运行镜像,就又是一个全新的容器。
所以说,镜像就是一组只读的目录,或者叫只读的 Docker 容器模板,镜像中含有一个Docker 容器运行所需要的文件系统,所以我们说Docker 镜像是启动一个Docker 容器的基础。
可以将Docker 镜像看成是Docker 容器的静态时,也可将Docker 容器看成是Docker镜像的运行时。
从Docker 的官方文档来看,Docker 容器的定义和 Docker 镜像的定义几乎是相同,Docker 容器和Docker 镜像的区别主要在于docker 容器多出了一个可写层。
Docker运行时与编排引擎
多数技术人员在谈到 Docker 时,主要是指 Docker 引擎。
Docker 引擎是用于运行和编排容器的基础设施工具。有 VMware 管理经验的读者可以将其类比为 ESXi。
ESXi 是运行虚拟机的核心管理程序,而 Docker 引擎是运行容器的核心容器运行时。
其他 Docker 公司或第三方的产品都是围绕 Docker 引擎进行开发和集成的。
Docker 引擎可以从 Docker 网站下载,也可以基于 GitHub 上的源码进行构建。无论是开源版本还是商业版本,都有 Linux 和 Windows 版本。
Docker 引擎主要有两个版本:企业版(EE)和社区版(CE)。
每个季度,企业版和社区版都会发布一个稳定版本。社区版本会提供 4 个月的支持,而企业版本会提供 12 个月的支持。
社区版还会通过 Edge 方式发布月度版。
从 2017 年第一季度开始,Docker 版本号遵循 YY.MM-xx 格式,类似于 Ubuntu 等项目。例如,2018 年 6 月第一次发布的社区版本为 18.06.0-ce。
注:2017 年第一季度以前,Docker 版本号遵循大版本号.小版本号的格式。采用新格式前的最后一个版本是 Docker 1.13。
容器虚拟化的优点
主机虚拟化
- 应用程序运行环境强隔离
- 虚拟机操作系统与底层操作系统无关化
- 虚拟机内部操作不会影响到物理机
- 拥有操作系统会占用部署资源及存储
- 网络传输效率低
- 当应用程序需要调用硬件响应用户访问时间延迟大
容器虚拟化
- 可以实现应用程序的隔离
- 直接使用物理机的操作系统可以快速响应用户请求
- 不占用部署时间
- 占用少量磁盘空间
- 缺点:学习成本增加、操作控制麻烦、网络控制与主机虚拟化有所区别、服务治理。
Docker安装
Docker的安装方式有很多,可以自己添加yum源手动安装,也可以使用官方脚本安装。无论哪种方法,安装都非常简单。
方法1
添加yum源
这里添加的阿里云提供的yum仓库,比官方的要快
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache
安装
安装的步骤也非常简单,只有一步
yum install -y docker-ce
到这里就已经可以启动docker服务了,但是,我们还可以做一些配置。
配置
docker默认的数据存储目录是/var/lib/docker
,但是,如果我们使用的是云服务器,我们会购买少量的磁盘(一般40G)用来装系统,再单独购买一块磁盘作为数据盘,这样即使数据满了也不会影响到系统。所以,如果我们将Docker数据目录放到默认的位置,随着业务的增加,会占满系统盘,因此,建议把Docker的数据目录单拿出来,不要存到系统分区上。
创建配置文件目录
mkdir /etc/docker/cd /etc/docker/
创建配置文件
vim /etc/docker/daemon.json
参考配置文件如下:
{
"graph": "/data/docker",
"storage-driver": "",
"insecure-registries": ["registry.access.redhat.com","quay.io"],
"registry-mirrors": ["https://qdloedv0.mirror.aliyuncs.com"],
"bip": "172.7.5.0/16",
"exec-opts": ["native.cgroupdriver=systemd"],
"live-restore": true
}
释义
graph: 数据保存目录,如果根分区足够大,或者在开发环境,可以删掉该配置。
storage-driver: 存储驱动,Centos7早期版本的有用overlay的,现在基本都支持overlay2
insecure-registries: 指受信任的不安全仓库地址,把自己搭建的harbor仓库地址写到里面。
registry-mirrors: 镜像加速,每个人的阿里云账号都有免费的镜像加速地址。
bip: Docker的虚拟网卡IP,建议让容器的IP和宿主机的IP有一个对照关系,如果不知道怎么写,直接删掉该配置。
exec-opts: 启动时候的额外参数,默认cgroupfs,k8s官方推荐systemd,否则初始化出现Warning
live-restore: 当docker容器引擎死掉的时候,用docker已启动的容器还能保留。
启动
systemctl start docker
systemctl enable docker
后续工作
#安装compose
yum -y install docker-compose
#安装命令补全
yum -y install bash-completion
扩展:安装指定版本
首先查看可安装的版本
yum list docker-ce --show-duplicates
#或者查看简化版的
yum list docker-ce --show-duplicates | sort -r
根据输出,选择想要的版本,如:
yum -y install docker-ce-19.03.15
后续步骤参考前面。
方法2
使用Docker官方给的脚本直接安装,无需任何配置,但原理和方法1都是一样的。
docker安装脚本的地址:https://get.docker.com
保存到本地执行
curl -fsSL get.docker.com -o get-docker.sh
chmod +x get-docker.sh
./get-docker.sh
直接在线安装
#如果能连上国外的主机
curl -sSL https://get.docker.com | sh
#如果连不上国外的,可以使用国内地址
curl -sSL https://get.daocloud.io/docker | sh
基本操作
镜像的获取
我们作为使用者,尤其是初学者,大部分时候都是直接拉取官方封装好的镜像后使用,拉取镜像的方法也非常简单可以直接用docker pull
命令进行拉取。但是我们该拉取什么镜像呢?
获取镜像的途径很多
- 可以去官方仓库Dockerhub(地址:https://registry.hub.docker.com/)上去搜
比如我们想要个nginx,就可以直接搜索nginx,并找到对应的版本,不加版本就默认latest。
- 通过
docker search
命令查找镜像该命令也是去官方仓库查找,只是这种查找方式就无法看到镜像发布者写的说明了,会让我们不知道该如何使用该镜像。
- 各种第三方仓库,如阿里云、谷歌等都有自己的镜像仓库。我们自己也可以用Harbor搭建自己的镜像仓库。
下面以Dockerhub的上的拉取命令为例
docker pull nginx
上面那条拉取命令,没加任何后缀,会默认加上latest,相当于docker pull nginx:latest
,如果想要特定版本,可以到tags里去找
比如,我们想要1.20.2,那么拉取命令就是
docker pull nginx:1.20.2
docker search
命令虽然也能查到镜像,但是不太方便获取版本信息,也就不好拉取对应的版本,所以我推荐直接去Dockerhub上找。
镜像操作
列出所有镜像
docker images
#或者
docker image ls
完整展示镜像细节,包括镜像层数据和元数据(对于使用者来说用处不大)。
docker image inspect
删除镜像,如,刚才下载的nginx:1.20.2
docker rmi nginx:1.20.2
容器命令
启动
启动一个容器,启动容器需要用到run命令
docker run -it --name=nginx nginx:1.20.2 /bin/bash
-it: 带前台交互功能
--name: 为容器起个名字
nginx:1.20.2: 镜像名
/bin/bash: 解释器
此时我们不但启动了一个容器,而且还直接进入了容器中。由于这个容器封装的系统非常的小,很多Linux的命令都没有,当然我们可以给它安装各种工具来让这个系统越来越“完整”,但其实在实际生产中,没这个必要。它只需要能运行我们的项目就够了。
此时,我们如果直接输入exit
,就直接退出容器了,但是我们刚才运行的容器还在,并没有消失。
#查看正在运行的docker容器
docker ps
#查看所有容器,包括已经停止运行的
docker ps -a
删除容器
在docker ps中,可以看到容器的各种信息
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
298450e8b1c2 nginx:1.20.2 "/docker-entrypoint.…" 32 minutes ago Exited (0) 14 minutes ago nginx
# 容器ID 所用镜像 启动命令 创建时间 状态 端口开发和映射 容器名
可以直接用容器ID删除容器
docker rm 298450e8b1c2
#docker有个很智能的机制,你可以只输入ID的前两位
docker rm 29
也可以用容器名删除容器
docker rm nginx
后台启动
我们的业务在运行的时候,需要的是很多个在后台运行的容器,而不是进入容器里把容器运行在终端。
再次使用刚才的命令启动容器
docker run -it --name=nginx nginx:1.20.2 /bin/bash
此时,按下Ctrl + p
和Ctrl +q
,就会退出到系统,docker ps
查看,容器依然运行。
但实际工作中,我们是不可能这样启动容器的,需要一条命令直接后台启动
docker run -d --name=nginx nginx:1.20.2
加上-d
参数,就是让容器运行在后台,所以不再需要跟上shell解释器的参数/bin/bash
进入容器的命令
#/bin/bash可以简写为bash
docker exec -it nginx bash
查看容器具体信息
docker inspect nginx
停止容器,记住,一定是停止的容器,才能被删除(docker rm),否则会报错
#停止容器,这里同样可以使用容器ID
docker stop nginx
服务暴露
一个容器要想对外服务,那就必须把服务暴露出去。我们刚才启动的容器,都是和系统隔离的独立空间,只有宿主机才能访问。那么如何才能让外面的人访问服务呢?
容器网络
在介绍服务暴露之前,就不得不说容器网络。
容器在安装好之后,会创建一个docker 0
的虚拟网桥(可以使用ip a s
命令查看),该网卡桥接到了宿主机的物理网卡,容器的虚拟网卡用docker 0
作为网关,使得我们可以在宿主机上访问容器的IP,容器也能访问宿主机IP。
docker自带的网络模式有bridge,none,host,
docker network ls #查看docker网络
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
622ab32f5c96 bridge bridge local
134d543d8083 host host local
e1523c072ab0 none null local
bridge模式
docker的默认模式,docker进程第一次启动会创建一个docker0虚拟网桥,
此宿主机上启动的容器会默认连接到这个网桥上,容器通过这块网桥NAT访问外部网络,
当执行docker run 加入-p参数是,实际是在iptables中加入了对应的DNAT端口转发规则。使用 --net=bridge指定,默认设置,可不指定。
host模式
host模式的容器跟宿主机共用一个namespace,拥有一样的IP和路由,因此容器内的服务端口不能跟宿主机相同使用 --net=host 指定。
none模式
none模式创建的容器没有添加网卡,需要自行配置。使用 --net=none 指定。
container模式
container模式创建一个跟指定容器共用网络的新容器使用 --net=container:NAME_or_ID 指定。
我们可以用docker inspect $CONTAINER_NAME_OR_CONTAINER_ID
来查看对应容器的IP地址。
你也可以自己创建一个网络,创建的网络,并且自定义网段
docker network create --subnet=172.18.0.0/16 test
端口映射
端口映射的参数是-p
,启动命令如下:
docker run -d -p 80:80 --name=nginx nginx:1.20.2
该命令表示,将宿主机的80端口,映射到容器的80端口,容器启动后,系统会通过iptables配置一条转发规则。
我们可以启动很多个80端口的nginx容器,然后将宿主机的不同端口映射到每个容器的80端口。
如果我们可以确定,启动的每个容器都占用不同端口,那么就可以直接使用host模式,这对于跨宿主机的通信是非常方便的。
挂载
因为容器运行起来后,如果不算数据库的写入,是没有持久化的,意思就是,本次运行的数据,并不会在宿主机保留,随着容器的删除,本次运行时所产生的本地数据也就随风而去了。用专业的话来说,就是无状态服务。
那么,如果说我们需要保留一些文件,让容器下次启动时能够恢复之前的状态呢?比如MySQL
的data
目录,Nginx
的配置文件目录,只要有这些东西,就能保证每次启动的容器,都是之前的状态,用专业的话来说,就是有状态服务。
所以,这里就用到了Docker另外一个知识点,挂载,参数是-v
,格式为-v $LocalPath:$ContainerPath
,一定要写绝对路径。
挂载就是把宿主机的一个目录或文件,和容器中的某个目录或文件做个映射,容器可以操作被挂载的目录和文件,容器删除后,挂载目录会被保留。它直接挂载我们的项目代码,也可以挂载配置文件,看业务的需求。
举个例子,启动一个nginx镜像,并挂载html目录
仅凭一个nginx镜像,我们不知道它的html目录在哪,所以需要去DockerHub上看官方的说明。我们一定要学会看DockerHub,会看DockerHub,Docker就会了一半了。
Nginx官方很给力,第一个参考命令就告诉我们如何挂载html目录。参考官方给的命令,我们的命令如下
#首先,建一个本地目录,用来挂载
mkdir -p /data/html
#自己写个HelloWorld的html文件
echo "HelloWorld" > /data/html/index.html
#启动容器,挂载进去
docker run -d \
--name nginx \
-p 80:80 \
-v /data/html:/usr/share/nginx/html \
nginx:1.20.2
同样,也可以把自己写的配置文件,挂载到容器中,我们自己写一个server,开放8000端口,保存到文件/data/conf.d/nginx.conf
,将这个conf.d目录挂载到容器中
server {
listen 8000;
server_name localhost;
root /data/;
}
那么启动命令为
docker run -d \
--name nginx \
-p 8000:8000 \
-v /data/conf.d:/etc/nginx/conf.d \
-v /data/html:/data \
nginx:1.20.2
docker-compose
模板文件简介
定义
docker-compose是一种单机的多容器编排工具,在一个yaml文件中定义复杂的容器应用之间的关系,用一个命令即可执行。它和docker run
的启动命令是完全相通的,可以相互转化,只是表述方式不同。
Compose允许用户通过一个docker-compose.yml
模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。 Compose模板文件是一个定义服务、网络和卷的YAML文件。Compose模板文件默认路径是当前目录下的docker-compose.yml,可以使用.yml或.yaml作为文件扩展名。
Docker-Compose标准模板文件应该包含version、services、networks 三大部分,最关键的是services和networks两个部分。
version字段
version 字段是表明使用那个版本的compose ,compose 有如下的版本,目前的最新版是 3.7
- 1
- 2
- 2.x
- 3.x
不同版本的 compose 支持了不同的 docker 版本,COMPOSE 与 DOCKER 的版本对应关系如下表,下表显示了哪些Compose文件版本支持特定的Docker版本。
你可以这么写
version: "3.7"
或者简单写成
version: "3"
一般情况下,写3就能满足大部分需求。如果官方给出了版本,就按照官方的来。
举例
使用docker-compose启动一个nginx,位置为/data/compose/test/docker-compose.yaml
version: '3'
service:
nginx:
image: nginx:1.20.2
volumes:
- ./html:/usr/share/nginx/html
ports:
- "8080:80"
启动命令为:
docker-compose up -d
此时,会发生以下事情:
- 会创建一个名字是
test
的网络(因为文件目录为test
) nginx
这个容器会加入到test
网络中,并且在网络中的名称为nginx
。
假如说,我们在一个compose中启动了两个容器,那么,两个容器之间可以通过容器名相互找到对方,其实就相当于把容器名和容器IP做了个类似于DNS解析、host绑定,这样的话,假如我们启动了一个服务和一个数据库,就可以方便的让服务通过容器名来找到数据库地址,不用输入数据库的容器IP。
启动一个nacos
下面,以我们最熟悉的nacos为例,使用docker-compose启动一个nacos服务。
naco-docker官方的git地址为:https://github.com/nacos-group/nacos-docker
clone代码:
git clone git://github.com/nacos-group/nacos-docker.git
根据官方给出的example,nacos需要官方提供的init.d/custom.properties
文件,一个环境变量文件,还需要映射一个日志目录;MySQL需要一个环境变量文件,同时挂载数据目录。通过整理后,目录定位/data/nacos
结构和文件如下:
[root@localhost nacos]# tree
.
├── docker-compose.yaml
├── env
│ ├── mysql.env
│ └── nacos-standlone-mysql.env
└── init.d
└── custom.properties
2 directories, 4 files
因为我们映射的日志目录、MySQL数据目录本来就是空的,容器启动后会向里面写入数据,所以我们无需单独创建,容器启动的时候,会自行创建对应的目录。
各配置文件如下:
./env/mysql.env
,这里配置了MySQL的root密码、建立的数据库、拥有该数据库权限的用户、该用户的密码,具体细节可去MySQL的仓库查看。
MYSQL_ROOT_PASSWORD=root
MYSQL_DATABASE=nacos_devtest
MYSQL_USER=nacos
MYSQL_PASSWORD=nacos
./env/nacos-standlone-mysql.env
PREFER_HOST_MODE=hostname
MODE=standalone
SPRING_DATASOURCE_PLATFORM=mysql
MYSQL_SERVICE_HOST=mysql
MYSQL_SERVICE_DB_NAME=nacos_devtest
MYSQL_SERVICE_PORT=3306
MYSQL_SERVICE_USER=nacos
MYSQL_SERVICE_PASSWORD=nacos
MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false
./init.d/custom.properties
#spring.security.enabled=false
#management.security=false
#security.basic.enabled=false
#nacos.security.ignore.urls=/**
#management.metrics.export.elastic.host=http://localhost:9200
# metrics for prometheus
management.endpoints.web.exposure.include=*
# metrics for elastic search
#management.metrics.export.elastic.enabled=false
#management.metrics.export.elastic.host=http://localhost:9200
# metrics for influx
#management.metrics.export.influx.enabled=false
#management.metrics.export.influx.db=springboot
#management.metrics.export.influx.uri=http://localhost:8086
#management.metrics.export.influx.auto-create-db=true
#management.metrics.export.influx.consistency=one
#management.metrics.export.influx.compressed=true
docker-compose.yaml
version: "2"
services:
nacos:
image: nacos/nacos-server:${NACOS_VERSION}
container_name: nacos-standalone-mysql
env_file:
- ./env/nacos-standlone-mysql.env
volumes:
- ./standalone-logs/:/home/nacos/logs
- ./init.d/custom.properties:/home/nacos/init.d/custom.properties
ports:
- "8848:8848"
- "9848:9848"
- "9555:9555"
depends_on:
- mysql
restart: always
mysql:
container_name: mysql
image: nacos/nacos-mysql:8.0.16
env_file:
- ./env/mysql.env
volumes:
- ./mysql:/var/lib/mysql
启动
docker-compose up -d
参考命令
docker-compose up
用于部署一个 Compose 应用。
默认情况下该命令会读取名为 docker-compose.yml 或 docker-compose.yaml 的文件。
当然用户也可以使用 -f 指定其他文件名。通常情况下,会使用 -d 参数令应用在后台启动。
docker-compose stop
停止 Compose 应用相关的所有容器,但不会删除它们。
被停止的应用可以很容易地通过 docker-compose restart 命令重新启动。
docker-compose rm
用于删除已停止的 Compose 应用。
它会删除容器和网络,但是不会删除卷和镜像。
docker-compose restart
重启已停止的 Compose 应用。
如果用户在停止该应用后对其进行了变更,那么变更的内容不会反映在重启后的应用中,这时需要重新部署应用使变更生效。
docker-compose ps
用于列出 Compose 应用中的各个容器。
输出内容包括当前状态、容器运行的命令以及网络端口。
docker-compose down
停止并删除运行中的 Compose 应用。
它会删除容器和网络,但是不会删除卷和镜像。
Dockerfile
Dockfile原理
在Dockerfile定义所要执行的命令,使用docker build创建镜像,过程中会按照Dockerfile所定义的内容打开临时性容器(使用docker commit进行提交),把Dockerfile文件中的命令全部执行完成,就得到了一个容器应用镜像。执行命令越多,最终得到的容器应用镜像越大,所以要做优化。
Dockerfile关键字
FROM(指定基础image)
MAINTAINER(用来指定镜像创建者信息)
RUN (运行命令)
CMD(设置container启动时执行的操作)- 如果容器镜像中有此命令,启动容器时,不要手动让容器执行其它命令
ENTRYPOINT(设置container启动时执行的操作)
USER(设置container容器的用户)
EXPOSE(指定容器需要映射到宿主机器的端口)
ENV(用于设置环境变量)
COPY(从src复制文件到container的dest路径)
ADD(和COPY命令类似,区别是ADD可以解压tar包,还支持通过URL从远程服务器读取资源并复制到镜像中,但不支持认证)
VOLUME(指定挂载点)
WORKDIR(切换目录)
COPY指令和ADD指令的用法非常相似,具体注意事项如下:
- 源路径可以有多个
- 源路径是相对于执行build的相对路径
- 源路径如果是本地路径,必须是build上下文中的路径
- 源路径如果是一个目录,则该目录下的所有内容都将被加入到容器,但是该目录本身不会
- 目标路径必须是绝对路径,或相对于WORKDIR的相对路径
- 目标路径如果不存在,则会创建相应的完整路径
- 目标路径如果不是一个文件,则必须使用/结束
- 路径中可以使用通配符
下面以nginx打包一个"HelloWorld"为例,
还是之前的目录/data/html
,创建文件Dockerfile
FROM nginx:1.20.2
MAINTAINER daleo1987@163.com
COPY html /usr/share/nginx/html
这样就把我们的html项目给封装到了容器中,打包命令为:
docker build -t helloworld:latest .
其中,-t
表示为这个镜像打一个tag,后面有个.
,一定要注意,别丢了,这个点表示本地目录的Dockerfile
文件,如果想指定文件,需要加参数-f
,并带上文件名。
对于Dockerfile,我的建议还是多看别人写的,先模仿,模仿的多了也就会写了。
镜像仓库
镜像仓库分类
公有仓库
之前已经提到过了,共有仓库就是dockerhub,网址:https://hub.docker.com/
我们注册账号后,就能使用了。我们可以用docker软件登录公有仓库,然后把自己的镜像传上去。
登录命令
#直接登录,就表示登录docker官方仓库,后面会讲到登录私有仓库,之后会提示你输入账号密码,即我们在Dockerhub上注册的账号和密码。
docker login
上传镜像
上传镜像前,需要先给我们的镜像打上标记,标记由4部分组成:
仓库地址/项目名/镜像名:tag
第一位的“仓库地址”可以不写,默认会加上docker.io
,这是官方仓库,
第二位项目名,对于有官方认证的项目,也可以不写,比如Nginx、MySQL、Mongodb等等各种官方软件,都会在Dockerhub上获得官方认证,所以我们可以直接使用“镜像名:tag”的格式获得镜像。
第三位的镜像名是必写的,一个镜像怎能没有名字。
第四位如果不写,会默认给加上latest
。
还是以我们刚才build的“HelloWorld”为例,上传到我个人的仓库
docker tag helloworld:latest xcliao/helloworld:latest
docker push xcliao/helloworld:latest
然后镜像就传到了公有仓库。
私有仓库
私有仓库很多,每个云服务提供商那里都可以建立自己的私有仓库,包括我们自己也可以通过registry
镜像来搭建我们自己的私有仓库。但是registry
仓库使用起来不是那么的友好,管理起来不方便,所以,这里就不细说了,有兴趣的自己去查阅一下。
但是,有很多第三方公司在registry
的基础上做了二次开发,使用上更加简便。几乎所有云服务商提供的私有仓库,底层都是registry
仓库。
这里介绍一个可以自己方便搭建的私有仓库Harbor
Harbor
特点
- vmware公司开源
- 良好的中文界面
- web管理界面
- 使用广泛
官方GitHub地址:https://github.com/goharbor/harbor
下载页面:https://github.com/goharbor/harbor/releases
Harbor的启动需要docker-compos,我们之前已经装上了。
下载项目,这里最新的以1.10.10版本为例
cd /opt/src
wget https://github.com/goharbor/harbor/releases/download/v1.10.10/harbor-offline-installer-v1.10.10.tgz
mv harbor /opt/
如果没什么特殊需求,比如日志目录、数据目录、80端口被占用等问题,可以直接启动,有需求的话,在/opt/harbor/harbor.yml
中进行配置。建议harbor在一个单独的服务器上部署。
该配置文件需要修改几个地方
1.hostname配置的是域名,我们实验环境就不配置域名了,直接设置成宿主机的IP即可。比如我们这台IP为192.168.1.10
hostname: 192.168.1.10
2. 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
3. 数据目录可以自己修改下,比如放到/data/harbor,建议数据和代码分开放,这样方便你升级
data_volume: /data/harbor
4. 日志目录可根据自己喜好修改,不改也没事
location: /data/harbor/log
修改完成后,创建对应的目录
mkdir -p /data/harbor/log
启动
cd /opt/harbor
./install.sh
登录Harbor,默认账号密码admin/Harbor12345,新建一个项目
新建项目后,使用admin用户提交本地nginx镜像到Harbor仓库
docker login 192.168.1.10
Username: admin
Password:
但是此时是无法登录的,因为该地址不是安全仓库。
修改配置文件/usr/lib/systemd/system/docker.service
,ExecStart之后添加 –insecure-registry=http://192.168.1.10
还有个更省事的法子,ExecStart后面从 -H 开始都删掉。重启docker服务。
如果我们用的是域名,则可以在/etc/docker/daemon.json
中增加安全仓库,字段为:"insecure-registries"
再次登录即可。
之后打tag、推送的步骤和公有仓库一样。
docker tag helloworld:latest 192.168.1.10/harbor/helloworld:latest
docker push 192.168.1.10/harbor/helloworld:latest
然后到Harbor仓库中对应的项目中查看,看到镜像已经传上来了。