Docker是通过内核虚拟化技术来提供容器的资源隔离与安全保障等,由于docker通过操作系统层的虚拟化实现隔离,所以docker容器在运行时,不需要类似虚拟机额外的操作系统开销,提高资源利用率。
Docker 扩展了 Linux 容器(Linux Containers),或着说 LXC,通过一个高层次的 API 为进程单独提供了一个轻量级的虚拟环境。Docker 利用了 LXC,cgroups 和 Linux 自己的内核。和传统的虚拟机不同的是,一个 Docker 容器并不包含一个单独的操作系统,而是基于已有的基础设施中操作系统提供的功能来运行的。
Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd。
较老版本的Docker被称为docker或docker-engine,2017年的3月1号之后,Docker的版本命名开始发生变化,同时将CE版本和EE版本进行分开。
Docker Engine改为Docker CE(社区版)
Docker Data Center改为Docker EE(企业版)
镜像(Image)
操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 root文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root 文件系统。
docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
容器(Container)
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。
docker容器可以理解为在沙盒中运行的进程。这个沙盒包含了该进程运行所必须的资源,包括文件系统、系统类库、shell 环境等等。但这个沙盒默认是不会运行任何程序的。你需要在沙盒中运行一个进程来启动某一个容器。这个进程是该容器的唯一进程,所以当该进程结束的时候,容器也会完全的停止。
仓库(Repository)
镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。
一个 Docker Registry中可以包含多个仓库(Repository );每个仓库可以包含多个标签(Tag)每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
仓库名经常以两段式路径形式出现,比如 jwilder/nginx-proxy ,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
特性 | 容器 | 虚拟机 |
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为MB | 一般为GB |
性能 | 接近原生 | 弱于原生 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
基本环境
主机名 | 系统版本 | IP地址 |
docker | CentOS 7.2 | 10.0.0.12 |
# yum -y install yum-utils device-mapper-persistent-data lvm2 #安装依赖包
# yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo #安装docker yum源
# yum makecache fast #更新yum软件源缓存
# yum -y install docker-ce #安装CE社区版的docker
# systemctl start docker
# systemctl enable docker
默认的docker官方register连接不上,所以改为Docker官方提供的中国registry mirror,就是所谓的镜像加速器
# cat /etc/docker/daemon.json #如果没有该文件,则自己创建
"registry-mirrors": [
"https://registry.docker-cn.com"
]
}
# systemctl daemon-reload
# systemctl restart docker
# docker pull hello-world #下载个hello-world镜像测试是否成功
# docker images #查看本地仓库里的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/hello-world latest f2a91732366c 3 weeks ago 1.848 kB
/etc/docker/daemon.json
/var/lib/docker
docker运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,docker会从镜像仓库下载该镜像。
从docker镜像仓库获取镜像的命令是docker pull,其命令格式为:
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
具体的选项可以通过 docker pull --help 命令看到,这里我们说一下镜像名称的格式。
Docker 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号] 。默认地址是 Docker Hub。
仓库名:如之前所说,这里的仓库名是两段式名称,即 <用户名>/<软件名> 。对于 Docker
Hub,如果不给出用户名,则默认为 library ,也就是官方镜像。
[root@docker ~]# docker pull centos #下载centos镜像,不指定版本号,默认下载最新的latest
Using default tag: latest
latest: Pulling from library/centos
85432449fd0f: Pull complete
Digest: sha256:3b1a65e9a05f0a77b5e8a698d3359459904c2a354dc3b25ae2e2f5c95f0b3667
Status: Downloaded newer image for centos:latest
[root@docker ~]# docker image ls #查看下载好的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 3fa822599e10 2 weeks ago 204MB
[root@docker ~]# docker search centos #搜索所有的centos镜像
[root@docker ~]# docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 3893 [OK] ansible/centos7-ansible Ansible on Centos7 103 [OK]
jdeathe/centos-ssh CentOS-6 6.9 x86_64 / CentOS-7 7.4.1708 x8... 90 [OK]
consol/centos-xfce-vnc Centos container with "headless" VNC sessi... 37 [OK]
imagine10255/centos6-lnmp-php56 centos6-lnmp-php56 35 [OK]
……省略
[root@docker ~]# docker search -s 90 centos #搜索被收藏90次及以上centos镜像
[root@docker ~]# docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 3893 [OK] ansible/centos7-ansible Ansible on Centos7 103 [OK]
jdeathe/centos-ssh CentOS-6 6.9 x86_64 / CentOS-7 7.4.1708 x8... 90 [OK]
# docker image ls或者# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 16.04 00fd29ccc6f1 2 days ago 111MB
centos latest fa822599e10 2 weeks ago 204MB
hello-world latest f2a91732366c 3 weeks ago 1.85kB
镜像 ID 则是镜像的唯一标识,一个镜像可以对应多个标签
# docker image ls centos #列出centos镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 3fa822599e10 2 weeks ago 204MB
# docker image ls ubuntu:16.04 #列出特定镜像,指出仓库名和标签
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 16.04 00fd29ccc6f1 2 days ago
docker image ls -f since=centos #列出在centos之后下载的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 16.04 00fd29ccc6f1 2 days ago 111MB
docker system df #查看镜像、容器、数据卷所占用的空间
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 2 2 203.5MB 0B (0%)
Containers 2 0 46B 46B (100%)
Local Volumes 0 0 0B 0B
Build Cache 0B 0B
# docker image ls -q #列出所有镜像的id
00fd29ccc6f1
3fa822599e10
f2a91732366c
# docker image ls --format "{{.ID}}: {{.Repository}}" #列出镜像ID和仓库名
00fd29ccc6f1: ubuntu
3fa822599e10: centos
f2a91732366c: hello-world
# docker run --name webserver -d -p 80:80 nginx #第一个80是操作系统的端口,第二个是容器里的端口
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
e7bb522d92ff: Pull complete
0f4d7753723e: Pull complete
91470a14d63f: Pull complete
Digest: sha256:2ffc60a51c9d658594b63ef5acfac9d92f4e1550f633a3a16d898925c4e7f5a7
Status: Downloaded newer image for nginx:latest
1237c47dade0837e82f6cf28f232c2a6aabe4eb36370a806a4c9b5d8d095210d
用nginx镜像启动了一个容器(如果本地仓库里没用nginx镜像会自动下载),命名为webserver,并且映射了80端口,这样就可以用浏览器去访问这个nginx服务器了。访问地址为:10.0.0.12
# docker exec -it webserver bash #以交互式终端方式进入webserver容器并执行bash命令
修改nginx的index.html文件内容
[root@1237c47dade0:/]# echo '<h1>Hello ,Docker!</h1>' >/usr/share/nginx/html/index.html
[root@1237c47dade0:/]# exit
[root@docker ~]#
当我们运行一个容器的时候(如果不使用卷的话),我们做的任何文件修改都会被记录于容器存储层里。而Docker提供了一个docker commit命令,可以将容器的存储层保存下来成为镜像。换句话说,就是在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜像。以后我们运行这个新镜像的时候,就会拥有原有容器最后的文件变化。
docker commit 的语法格式为:
docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
[root@docker ~]# docker commit --author "wangning <1198143315@qq.com>" --message "修改了默认网页" webserver nginx:v2
--author是指定修改的作者
--message是记录本次修改的内容,这点和git版本控制相似,这里这些信息可以省略留空
webserver是启动的容器名称
nginx:v2是自定义的版本号
[root@docker ~]# docker image ls nginx #查看新定制镜像,×××的是新定制的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v2 811c1f4cfdeb 8 minutes ago 108MB
nginx latest f895b3fb9e30 4 days ago 108MB
用新定制的镜像启动一个容器webserver2,浏览器里输入http://10.0.0.12:81就可以访问了
[root@docker ~]# docker run --name webserver2 -d -p 81:80 nginx:v2
使用docker commit命令可以比较直观的帮助理解镜像分层存储的概念,但是实际环境中并不会这样使用。使用docker commit意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为黑箱镜像,换句话说,就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像,别人根本无从得知。
镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
[root@docker ~]# mkdir /opt/nginx
[root@docker ~]# touch /opt/nginx/Dockerfile
[root@docker ~]# cat /opt/nginx/Dockerfile
FROM nginx
RUN echo '<h1>Hello,Docker is a container!</h1>' >/usr/share/nginx/html/index.html
FROM 指定基础镜像
RUN用来执行shell命令,shell命令要尽量写成一行,这样可以避免镜像臃肿
[root@docker ~]# cd /opt/nginx/
[root@docker nginx]# docker build -t nginx:v3 . #一定要在Dockerfile所在目录执行,注意后面有个点
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM nginx
---> f895b3fb9e30
Step 2/2 : RUN echo '<h1>Hello,Docker is a container!</h1>' >/usr/share/nginx/html/index.html
---> Running in e9a34a37ab7a
<h1>Hello,Docker is a container!</h1> /usr/share/nginx/html/index.html
---> ad0e0e8cb74f
Removing intermediate container e9a34a37ab7a
Successfully built ad0e0e8cb74f
Successfully tagged nginx:v3
[root@docker nginx]# docker image ls nginx #此时已经构建好了镜像
REPOSITORY TAG MAGE ID CREATED SIZE
nginx v3 ad0e0e8cb74f 2 minutes ago 108MB
nginx v2 811c1f4cfdeb 3 hours ago 108MB
nginx latest f895b3fb9e30 5 days ago 108MB
# docker run --name webserver3 -d -p 82:80 nginx:v3 #用镜像nginx:v3启动一个容器webserver3
浏览器里输入http://10.0.0.12:82即可访问
这些命令不区分大小写
FROM 后加基础镜像
MAINTAINER 后加维护者信息
RUN 后加shell命令
ADD 将Dockerfile所在目录里的指定的文件放入相应的目录
WORKDIR 相当于cd的意思
VOLUME 目录挂载
EXPOSE 后加指定服务启用的端口号
CMD后加要启动的服务
下面以centos:2镜像为基础镜像,安装一个nginx服务,并启动它。
Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样去启动后台服务,容器内没有后台服务的概念。
[root@docker nginx]# cat /opt/nginx/Dockerfile
#This docker file
#Version 4
#Author: wangning
FROM centos:2
MAINTAINER wangning 1198143315@qq.com
# daemon off;表示以前台方式启动
RUN yum install -y nginx && echo "daemon off;" >>/etc/nginx/nginx.conf
ADD index.html /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["nginx"]
[root@docker nginx]# cat /opt/nginx/index.html
<h1>the docker is a good container!</h1>
[root@docker nginx]# tree
.
├── Dockerfile
└── index.html
0 directories, 2 files
[root@docker nginx]# docker build -t nginx:v4 . #构建镜像nginx:v4
Sending build context to Docker daemon 3.072kB
Step 1/6 : FROM centos:2
---> 2377ded06842
Step 2/6 : MAINTAINER wangning 1198143315@qq.com
---> Running in 058ad0745355
---> c5b43803658b
Removing intermediate container 058ad0745355
Step 3/6 : RUN yum install -y nginx && echo "daemon off;" >>/etc/nginx/nginx.conf
---> Running in 6a28e9f696ca
Loaded plugins: fastestmirror, ovl
……
# docker run --name webserver4 -d -p 83:80 nginx:v4 #用镜像nginx:v4启动一个容器webserver4
[root@docker ~]# docker image ls #列出镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v4 cc79e9595141 About an hour ago 395MB
centos 2 2377ded06842 3 hours ago 290MB
nginx v3 dc8d7882a686 6 hours ago 108MB
nginx v2 811c1f4cfdeb 10 hours ago 108MB
ubuntu 16.04 00fd29ccc6f1 2 days ago 111MB
nginx latest f895b3fb9e30 5 days ago 108MB
centos latest 3fa822599e10 2 weeks ago 204MB
[root@docker ~]# docker save nginx:v4 >/opt/nginx_v4.tar #导出镜像
[root@docker ~]# # docker load </opt/nginx_v4.tar #导入镜像
镜像的唯一标识是其 ID 和摘要,而一个镜像可以有多个标签。因此当我们删除了所指定的标签后,可能还有别的标签指向了这个镜像,如果是这种情况,那么 Delete 行为就不会发生。所以并非所有的 docker rm 都会产生删除镜像的行为,有可能仅仅是取消了某个标签而已。
镜像是多层存储结构,因此在删除的时候也是从上层向基础层方向依次进行判断删除。镜像的多层结构让镜像复用变动非常容易,因此很有可能某个其它镜像正依赖于当前镜像的某一层。这种情况,依旧不会触发删除该层的行为。直到没有任何层依赖当前层时,才会真实的删除当前层。
除了镜像依赖以外,还需要注意的是容器对镜像的依赖。如果有用这个镜像启动的容器存在(即使容器没有运行),那么同样不可以删除这个镜像。容器是以镜像为基础,再加一层容器存储层,组成这样的多层存储结构去运行的。因此该镜像如果被这个容器所依赖的,那么删除必然会导致故障。如果这些容器是不需要的,应该先将它们删除,然后再来删除镜像。
用镜像名(仓库名加tag标签)的方式删除
[root@docker ~]# docker image rm nginx:v4
用镜像id方式删除
[root@docker ~]# docker image rm cc79e9595141
简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。
[root@docker ~]# docker container ls #查看运行中的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e994d092dff1 nginx:v2 "nginx -g 'daemon ..." 12 hours ago Up 38 seconds 0.0.0.0:81->80/tcp webserver2
1237c47dade0 nginx "nginx -g 'daemon ..." 15 hours ago Up 5 minutes 0.0.0.0:80->80/tcp webserver
[root@docker ~]# docker container ls -a 或[root@docker ~]# docker ps -a #查看所有容器,包括停止状态的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ed23f12df3ba nginx:v3 "nginx -g 'daemon ..." 8 hours ago Exited (0) 5 minutes ago webserver3
e994d092dff1 nginx:v2 "nginx -g 'daemon ..." 12 hours ago Up 6 minutes 0.0.0.0:81->80/tcp webserver2
1237c47dade0 nginx "nginx -g 'daemon ..." 15 hours ago Up 11 minutes 0.0.0.0:80->80/tcp webserver
[root@docker ~]# docker inspect nginx #查看nginx容器的详细信息
进入容器命令 docker exec
进入webserver容器里,可以执行shell命令进行操作,-i交互式 -t伪终端
[root@docker nginx]# docker exec -it webserver bash
root@1237c47dade0:/# cat /etc/issue
Debian GNU/Linux 9 \n \l #从公有仓库下载的nginx镜像,用的操作系统是Debian
root@1237c47dade0:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@1237c47dade0:/# exit 退出容器
exit
[root@docker nginx]#
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。
# docker run --name webserver4 -d -p 83:80 nginx:v4 #第一个83是操作系统的端口,第二个80是容器里的端口
用nginx:v4镜像启动了一个容器,命名为webserver4,并且映射了83端口,-d表示后台运行
这样就可以用浏览器去访问这个nginx服务器了。访问地址为:http://10.0.0.12:83
小结:
当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:
检查本地是否存在指定的镜像,不存在就从公有仓库下载
1.利用镜像创建并启动一个容器
2.分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
3.从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
4.从地址池配置一个 ip 地址给容器
5.执行用户指定的应用程序
6.执行完毕后容器被终止
[root@docker ~]# docker container start webserver3 #启动webserver3容器
[root@docker ~]# docker container stop webserver3 #停止webserver3容器
[root@docker ~]# docker kill $(docker ps -q) #停止所有正在运行的容器
删除终止的容器
[root@docker ~]# docker container rm webserver4
删除运行中的容器
[root@docker ~]# docker container rm -f webserver3
删除所有停止状态的容器
root@docker ~]# docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
e994d092dff1501bc62ed26f43a7ecbb478014f21cc0949236b8a73fc6f62577
1237c47dade0837e82f6cf28f232c2a6aabe4eb36370a806a4c9b5d8d095210d
仓库(Repository)是集中存放镜像的地方。
一个容易混淆的概念是注册服务器(Registry)。实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。例如对于仓库地址 dl.dockerpool.com/ubuntu 来说,dl.dockerpool.com 是注册服务器地址,ubuntu 是仓库名。
目前 Docker 官方维护了一个公共仓库 Docker Hub,其中已经包括了数量超过 15,000 的镜像。大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。
注册
你可以在 https://cloud.docker.com 免费注册一个 Docker 账号。
登录
可以通过执行 docker login 命令交互式的输入用户名及密码来完成在命令行界面登录Docker Hub。
你可以通过 docker logout 退出登录。
拉取镜像
你可以通过 docker search 命令来查找官方仓库中的镜像,并利用 docker pull 命令来将它下载到本地。
[root@docker ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: 1198143315
Password: *******
Login Succeeded
[root@docker ~]# docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 3886 [OK]
ansible/centos7-ansible Ansible on Centos7 103 [OK]
jdeathe/centos-ssh CentOS-6 6.9 x86_64 / CentOS-7 7.4.1708 x8... 90 [OK]
consol/centos-xfce-vnc Centos container with "headless" VNC sessi... 37 [OK]
tutum/centos Simple CentOS docker image with SSH access 34
……省略
根据是否是官方提供,可将镜像资源分为两类。
一种是类似 centos 这样的镜像,被称为基础镜像或根镜像。这些基础镜像由 Docker 公司创建、验证、支持、提供。这样的镜像往往使用单个单词作为名字。
还有一种类型,比如 tutum/centos 镜像,它是由 Docker 的用户创建并维护的,往往带有用户名称前缀。可以通过前缀 username/ 来指定使用某个用户提供的镜像,比如 tutum用户。
小结:
官方的公共仓库网速很慢,经常登录不上,可改用docker在中国的镜像站,详见7更改默认register。
有时候使用Docker Hub这样的公共仓库不方便,用户可以创建一个本地仓库供私人使用,个人感觉类似于centos的本地yum源。
可以选择用yum方式安装docker-registry包,也可以通过获取官方registry镜像来运行,这里选择第二种方式。
[root@docker ~]# docker pull registry #下载registry镜像
[root@docker ~]# docker run --name registry -d -p 5000:5000 --restart=always -v /opt/registry:/var/lib/registry registry
用registry镜像创建一个容器,命名为registry,默认情况下,仓库会被创建在容器的/var/lib/registry目录下,此处的选项-v表示将容器里的/var/lib/registry挂载到本地的/opt/registry目录下,类似于Linux中mount命令。
[root@docker ~]# docker container ls #查看registry容器是否正常运行
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8a7d1d95dc54 registry "/entrypoint.sh /e..." 3 minutes ago Up 3 minutes 0.0.0.0:5000->5000/tcp registry
[root@docker ~]# docker image ls #先查看本地有哪些镜像
[root@docker system]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f895b3fb9e30 6 days ago 108MB
registry latest 177391bcf802 2 weeks ago 33.3MB
使用docker tag 将nginx:latest这个镜像标记为10.0.0.12:5000/nginx:latest
格式为 docker tag IMAGE[:TAG] [REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]
root@docker ~]# docker tag nginx:latest 10.0.0.12:5000/nginx:latest
[root@docker ~]# docker image ls 查看标记好的镜像
[root@docker ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f895b3fb9e30 6 days ago 108MB
10.0.0.12:5000/nginx latest f895b3fb9e30 6 days ago 108MB
registry latest 177391bcf802 2 weeks ago 33.3MB
[root@docker ~]# docker push 10.0.0.12:5000/nginx:v4 #开始向私有仓库上传镜像
The push refers to a repository [10.0.0.12:5000/nginx]
Get https://10.0.0.12:5000/v2/: http: server gave HTTP response to HTTPS client
此时上面红色报错是https问题,因为Docker从1.3.X之后,与docker registry交互默认使用的是https,然而此处搭建的私有仓库只提供http服务,所以当与私有仓库交互时就会报上面的错误。为了解决这个问题需要在启动docker server时增加启动参数为默认使用http访问。
修改etc/docker/daemon.json这个文件,×××部分为添加的内容
[root@docker ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": [
"https://registry.docker-cn.com"
],
"insecure-registry": [
"10.0.0.12:5000"
]
}
再次上传镜像
[root@docker ~]# docker push 10.0.0.12:5000/nginx:latest
The push refers to a repository [10.0.0.12:5000/nginx]
995f02eaa054: Pushed
938981ec0340: Pushed
2ec5c0a4cb57: Pushed
latest: digest: sha256:3eff18554e47c4177a09cea5d460526cbb4d3aff9fd1917d7b1372da1539694a size: 948
用curl查看私有仓库中的镜像
[root@docker ~]# curl 10.0.0.12:5000/v2/_catalog
{"repositories":["nginx"]}
先从本地删除这个镜像
[root@docker ~]# docker image rm 10.0.0.12:5000/nginx:latest
[root@docker ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f895b3fb9e30 6 days ago 108MB
registry latest 177391bcf802 2 weeks ago 33.3MB
然后再从私有仓库中下载这个镜像
[root@docker ~]# docker pull 10.0.0.12:5000/nginx:latest
latest: Pulling from nginx
Digest: sha256:3eff18554e47c4177a09cea5d460526cbb4d3aff9fd1917d7b1372da1539694a
Status: Downloaded newer image for 10.0.0.12:5000/nginx:latest
[root@docker ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
10.0.0.12:5000/nginx latest f895b3fb9e30 6 days ago 108MB
nginx latest f895b3fb9e30 6 days ago 108MB
registry latest 177391bcf802 2 weeks ago 33.3MB
在容器中管理数据主要有两种方式:
数据卷(Volumes)
挂载主机目录(Bind mounts)
1. 可以在容器之间共享和重用
2. 对数据卷的修改会立马生效
3. 对数据的更新,不会影响镜像
4. 数据卷默认会一直存在,即使容器被删除
[root@docker ~]# docker volume create my-vol #创建数据卷
[root@docker ~]# docker volume ls #查看所有数据卷
DRIVER VOLUME NAME
local my-vol
[root@docker ~]# docker volume inspect my-vol #查看指定数据卷的信息
[
{
"CreatedAt": "2017-12-18T20:21:13-05:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}
]
[root@docker ~]# docker run --name nginx -d -p 80:80 -v my-vol:/nginx_data nginx
用nginx镜像创建一个容器nginx,将数据卷my-vol挂载到容器nginx里的nginx_data(如果容器里没有此目录,则会自动创建)目录下,当nginx_data有数据写入时,本地的卷my-vol里也会相应的写入数据,当容器nginx被删除时,卷my-vol里的数据不会被删除。
[root@docker ~]# docker inspect nginx #查看nginx容器有关卷的详细信息
……省略
"Mounts": [
{
"Type": "volume",
"Name": "my-vol",
"Source": "/var/lib/docker/volumes/my-vol/_data",
"Destination": "/nginx_data",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
…..省略
[root@docker ~]# docker volume rm my-vol #删除数据卷my-vol,如果该卷正在被容器使用,则会报错无法删除
[root@docker ~]# docker volume prune #删除所有没有被使用的数据卷,即无主的数据卷
数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker不会在容器被删除后自动删除数据卷 ,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用docker rm -v这个命令。
容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。
当使用 -P 标记时,Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口。
当使用-p标记时,可以自己指定映射端口
[root@docker ~]# docker run --name nginx -d -P nginx
[root@docker ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a8d681612934 nginx "nginx -g 'daemon ..." 9 seconds ago Up 9 seconds 0.0.0.0:32768->80/tcp nginx
当使用-P时,系统随机分配了一个端口32768对应容器nginx里的80端口
原文地址:http://blog.51cto.com/wn2100/2052224