关键词
LXC Docker架构 仓库注册服务器 仓库 镜像 容器 UnionFS bootfs rootfs
为什么轻?
- 去掉了传统VM架构中Hypervisor(硬件资源虚拟化)这一层,Docker Engine 直接对宿主系统进行库调用,不关心具体硬件实现;
- 去掉庞大虚拟机操作系统(GuestOS),进程级别进行隔离,极大节省运行空间,扩容响应效率。
Docker架构
Docker使用C/S架构,Client 通过接口与Server进程通信实现容器的构建,运行和发布。client和server可以运行在同一台集群,也可以通过跨主机实现远程通信。
核心概念
仓库注册服务器 registry
为仓库提供托管的服务器,目前最大镜像仓库托管服务器 DockerHub,
还有提供加速服务的诸如阿里云镜像加速服务器、网易云加速服务器 等都属于这一类。
镜像仓库 repo
仓库注册服务器中镜像仓库往往以命名空间方式存在,可类比为linux服务器下众多文件目录。
镜像仓库下往往存在多个镜像。不同镜像依据 tag 划分为不同版本。
镜像 image
一堆类似于“花卷”的只读层,以java类模板类比,基于同一份镜像(类),可以创建不同容器(对象)。
容器 container
可读写的统一文件系统,加上隔离的进程空间,以及其中包含的进程。
可以理解运行时,在只读的镜像层上,套了一层可读写层,从而实现容器的个性化需求。
联合文件加载系统 UnionFS
1. 下载docker镜像的时候,每一层对应一个id,层是AUFS (Advanced UnionFS联合文件系统)中的重要概念;
2. 联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下;
3. 联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像;
4. 不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率;
5. Docker 目前支持的联合文件系统种类包括 AUFS, btrfs, vfs 和 DeviceMapper。
系统加载与Linux区别
传统Linux系统加载
典型的Linux文件系统由 bootfs 和 rootfs 两部分组成,bootfs (boot file system)主要包含 bootloader和kernel,bootloader主要是引导加载kernel,当kernel被加载到内存中后 bootfs就被umount了。 rootfs (root file system) 包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc等标准目录和文件。
传统的Linux加载bootfs时会先将rootfs设为read-only,然后在系统自检之后将rootfs从read-only改为read-write,然后我们就可以在rootfs上进行写和读的操作了。
Docker容器系统加载
Docker容器是建立在Aufs基础上的,Aufs(以前称之为Another Union FS,后来绝不不够高大上,更名为Advanced Union FS)是一种Union FS, 简单来说就是支持将不同的目录挂载到同一个虚拟文件系统下,并实现一种layer的概念。
Aufs将挂载到同一虚拟文件系统下的多个目录分别设置成read-only,read-write以及whiteout-able权限,对read-only目录只能读,而写操作只能实施在read-write目录中。重点在于,写操作是在read-only上的一种增量操作,不影响read-only目录。当挂载目录的时候要严格按照各目录之间的这种增量关系,将被增量操作的目录优先于在它基础上增量操作的目录挂载,待所有目录挂载结束了,继续挂载一个read-write目录,如此便形成了一种层次结构。
Docker的镜像运行时,在bootfs自检完毕之后并不会把rootfs的read-only改为read-write。而是利用union mount(UnionFS的一种挂载机制)将一个或多个read-only的rootfs加载到之前的read-only的rootfs层之上。在加载了这么多层的rootfs之后,仍然让它看起来只像是一个文件系统,在Docker的体系里把union mount的这些read-only的rootfs叫做Docker的镜像。但是,此时的每一层rootfs都是read-only的,我们此时还不能对其进行操作。当我们创建一个容器,也就是将Docker镜像进行实例化,系统会在一层或是多层read-only的rootfs之上分配一层空的read-write的rootfs。
常用命令
容器 container
【docker search】
#查看指定内容镜像
docker search centos
# NAME DESCRIPTION STARS # OFFICIAL AUTOMATED
# centos The official build of CentOS. 5387 [# OK]
# ansible/centos7-ansible Ansible on Centos7 # 121 [OK]
# jdeathe/centos-ssh CentOS-6 6.10 x86_64 / CentOS-7 7.5.1804 x86… 109
# stars>=100 centos 镜像
docker search --filter=stars=100 centos
# 查看明细
# docker search --no-trunc centos
# NAME DESCRIPTION STARS OFFICIAL AUTOMATED
# centos The official build of CentOS. 5387 [OK]
# ansible/centos7-ansible Ansible on Centos7 121 [OK]
# jdeathe/centos-ssh CentOS-6 6.10 x86_64 / CentOS-7 7.5.1804 x86_64 - SCL/EPEL/IUS Repos / Supervisor / OpenSSH. 109 [OK]
# 自动构建
docker search --filter=is-automated=true centos
# NAME DESCRIPTION STARS OFFICIAL AUTOMATED
# ansible/centos7-ansible Ansible on Centos7 121 [OK]
# jdeathe/centos-ssh CentOS-6 6.10 x86_64 / CentOS-7 7.5.1804 x86… 109 [OK]
# consol/centos-xfce-vnc Centos container with "headless" VNC session… 91 [OK]
【docker pull】
# 默认拉取最新镜像
docker pull centos
# 拉取指定版本镜像
docker pull centos:6.8
# 6.8: Pulling from library/centos
【docker run】
# 运行容器(-i 交互式, -t 模拟终端,-d 阻塞,--name 容器命名, /bin/sh -c ... 容器执行命名)
docker run -it -d --name mycentos centos:6.8 /bin/sh -c 'while true;do echo `date`; sleep 2 ;done'
# 8f6a378f18678889fb078c711d3120658e0c426ecbbe74a9f0bc1727615afc94
# 查看正在运行容器 (-a 全部容器 --no-trunc)
docker ps
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 8f6a378f1867 centos:6.8 "/bin/sh -c 'while t…" 3 minutes ago Up 3 minutes mycentos
# 查看容器日志 (-f 滚动监控)
docker logs -f mycentos
# Fri Jun 7 10:40:45 UTC 2019
# Fri Jun 7 10:40:47 UTC 2019
# Fri Jun 7 10:40:49 UTC 2019
# 停止容器
docker stop mycentos
# 删除容器
docker rm mycentos
# 杀死运行容器
docker kill mycentos
# 启动并直接进入bash
docker run -it --name mybash centos:6.8 bash
# [root@44a2f6008195 /]#
# exit 退出并关闭容器
Ctrl+P, Ctrl+Q 退出并在后台运行容器
# -d 启动并挂在后台运行(否则直接退出)
docker run -it --name mydeamon -d centos:6.8
# 7a1b7349c81e7ae51c32f6ae111c8f1d5380cb32ecd36fcf4e776e48bb94b45a
# docker ps
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 7a1b7349c81e centos:6.8 "/bin/bash" 10 seconds ago Up 9 seconds mydeamon
# (-p port1:port2) 启动将容器port2端口映射到宿主机port1端口
docker run -it -p 8080:8080 -d --name mycat tomcat
# docker ps (0.0.0.0:8080->8080/tcp 端口映射成功)
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# f76185505e3a tomcat "catalina.sh run" 3 seconds ago Up 2 seconds 0.0.0.0:8080->8080/tcp mycat
# docker logs -f mycat (tomcat 启动日志)
# 07-Jun-2019 11:39:05.646 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
# 07-Jun-2019 11:39:05.724 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
# 07-Jun-2019 11:39:05.731 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 1597 ms
# curl http://docker:8080/ 查看端口映射
# (-P)镜像EXPOSE端口随机映射到宿主机
docker run -d -it --name mycat2 -P tomcat
# d540c1620ecfa2734aa4ff2eee65e6b7ca58d6711d56cb7e08dde9e4c96b2f21
# docker ps
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# d540c1620ecf tomcat "catalina.sh run" 4 seconds ago Up 2 seconds 0.0.0.0:32768->8080/tcp mycat2
# f76185505e3a tomcat "catalina.sh run" 6 minutes ago Up 6 minutes 0.0.0.0:8080->8080/tcp mycat
mkdir /usr/tmp/test
cd /usr/tmp/test
touch 1.txt
# -v 挂在数据卷
docker run -it -d -v /usr/tmp/test:/usr/tmp/test --name myvol centos:6.8
# 登入容器(查看数据卷映射,读写权限)
docker attach mycat
# [root@4374114e4fd1 /]# ls /usr/tmp/test/
# 1.txt
# [root@4374114e4fd1 /]# echo 'hello' >> /usr/tmp/test/1.txt
# [root@4374114e4fd1 /]# cat /usr/tmp/test/1.txt
# hello
# 查看容器明细
docker inspect mycat
# {
# ....
# "Mounts": [
# {
# "Type": "bind",
# "Source": "/usr/tmp/test",
# "Destination": "/usr/tmp/test",
# "Mode": "",
# "RW": true,
# "Propagation": "rprivate"
# }
# ],
# ...
# }
# (-v dir1:dir2:ro) 挂在只读数据卷,默认为rw
docker run -v /usr/tmp/test:/usr/tmp/test:ro -it --name myvol1 centos:6.8 bash
# [root@7025dbea92a1 /]# ls /usr/tmp/test/
# 1.txt
# [root@7025dbea92a1 /]# echo 'hi' >> /usr/tmp/test/1.txt
# bash: /usr/tmp/test/1.txt: Read-only file system
docker inspect myvol1
# {
# ...
# "Mounts": [
# {
# "Type": "bind",
# "Source": "/usr/tmp/test",
# "Destination": "/usr/tmp/test",
# "Mode": "ro", <<<
# "RW": false,
# "Propagation": "rprivate"
# }
# ],
# ...
# }
# 重新启动容器
docker restart mycat
# 查看正在运行容器
docker ps
# 查看全部容器 (不截断信息)
docker ps -a --no-trunc
镜像 image
# 查找镜像
docker search tomcat
# 查找指定版本镜像
docker search tomcat:9.0
# NAME DESCRIPTION STARS OFFICIAL AUTOMATED
# iyayu/tomcat Java JDK:1.8.0_131 Tomcat:9.0.0.M22 0
# 查找评分在100以上镜像
docker search --filter=stars=100 tomcat
# NAME DESCRIPTION STARS OFFICIAL AUTOMATED
# tomcat Apache Tomcat is an open source implementati… 2410 [OK]
# 查找自动构建镜像
docker search --filter=is-automated=true tomcat
# NAME DESCRIPTION STARS OFFICIAL AUTOMATED
# dordoka/tomcat Ubuntu 14.04, Oracle JDK 8 and Tomcat 8 base… 53 [OK]
# 拉取指定版本镜像
docker pull tomcat:8.5
# 8.5: Pulling from library/tomcat
# Digest: sha256:d4a94787b1124f4269180e74e6c29ec9512bdb8c772c8aa1c7e7e822ce633618
# Status: Downloaded newer image for tomcat:8.5
# 将容器转换为本地镜像(-a author, -m message)
docker commit -a 'xx<xxx@xxx.com>' -m 'tomcat:9.0 in centos6.8' d540c1620ecf tomcat/centos6.8:v9.0
# sha256:1da2dff72b71c0cd45e652aa4be28e0e1510929708fb05962300d7b99aac12f7
# docker images
# REPOSITORY TAG IMAGE ID CREATED SIZE
# tomcat/centos6.8 v9.0 1da2dff72b71 3 seconds ago 522MB
# 容器提交为本地镜像(忘记打标签)
docker commit -a 'xx<xx@163.com>' -m 'tomcat:9.0 on centos6.8' d540c1620ecf
# sha256:66797a68a41b951c678f663443dccdf5033122aa2365677abc7cb7114995384c
# 查看全部镜像
docker images
# REPOSITORY TAG IMAGE ID CREATED SIZE
# <none> <none> 66797a68a41b 4 seconds ago 522MB
# 补标签
docker tag 66797a68a41b tomact/centos6.8:v9.0
# docker images
# REPOSITORY TAG IMAGE ID CREATED SIZE
# tomact/centos6.8 v9.0 66797a68a41b 33 seconds ago 522MB
mkdir /usr/tmp/dockerfile
# 创建DockerFile文件
vim /usr/tmp/dockerfile/DockerFile
# -----------------------------------
# # centos6.8 with hello-world
# FROM centos:6.8
# MAINTAINER xx<xx@xx.com>
# CMD echo 'hello world'
# -----------------------------------
# 基于DockerFile构建镜像
docker build -f /usr/tmp/dockerfile/DockerFile -t myhello/centos6.8:v1.0 /usr/tmp/dockerfile/
# Sending build context to Docker daemon 2.048kB
# Step 1/3 : FROM centos:6.8
# ---> 82f3b5f3c58f
# Step 2/3 : MAINTAINER xx<xx@xx.com>
# ---> Running in 1ce6df6a79e4
# Removing intermediate container 1ce6df6a79e4
# ---> 4300aac5726a
# Step 3/3 : CMD echo 'hello world'
# ---> Running in e2b443c58df4
# Removing intermediate container e2b443c58df4
# ---> 326e32a3cb3d
# Successfully built 326e32a3cb3d
# Successfully tagged myhello/centos6.8:v1.0
# docker images
# REPOSITORY TAG IMAGE ID CREATED SIZE
# myhello/centos6.8 v1.0 326e32a3cb3d 2 minutes ago 195MB
# 运行自定义镜像
docker run --name hello myhello/centos6.8:v1.0
# hello world
仓库 Repo
https://cr.console.aliyun.com/cn-hangzhou/instances/repositories
- 创建命名空间 centos68-registry
- 创建镜像仓库 tomcat [从本地镜像推送]
- 镜像仓库 > 管理
docker login --username=xxx registry.cn-hangzhou.aliyuncs.com
# 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
docker images
# REPOSITORY TAG IMAGE ID CREATED SIZE
# tomact/centos6.8 v9.0 66797a68a41b 37 minutes ago 522MB << 准备push的镜像
# 标注远程仓库tag
docker tag 66797a68a41b registry.cn-hangzhou.aliyuncs.com/centos68-registry/tomcat:v1.0
# docker images
# REPOSITORY TAG IMAGE ID CREATED SIZE
# registry.cn-hangzhou.aliyuncs.com/centos68-registry/tomcat v1.0 66797a68a41b 41 minutes ago 522MB
# tomact/centos6.8 v9.0 66797a68a41b About an hour ago 522MB
# 推送远程仓库
docker push registry.cn-hangzhou.aliyuncs.com/centos68-registry/tomcat:v1.0
# The push refers to repository [registry.cn-hangzhou.aliyuncs.com/centos68-registry/tomcat]
# 8ca06e1b99fd: Pushed
# .....
# 95c8d3f0ae82: Pushing [======================> ] 90.71MB/204.8MB
# a3e9c8cfc64e: Pushed
# v1.0: digest: sha256:f41aa4f8da6775d8030c70dbd2517bfa7311c0386a2bbdd346ba786b3bbe4fb3 size: 3051
# 删除标签 和 本地镜像
docker rmi registry.cn-hangzhou.aliyuncs.com/centos68-registry/tomcat:v1.0 tomact/centos6.8:v9.0
# 远程拉取镜像
docker pull registry.cn-hangzhou.aliyuncs.com/centos68-registry/tomcat:v1.0
# 查看指定仓库相关镜像
docker images docker images registry.cn-hangzhou.aliyuncs.com/centos68-registry/tomcat
# REPOSITORY TAG IMAGE ID CREATED SIZE
# registry.cn-hangzhou.aliyuncs.com/centos68-registry/tomcat v1.0 66797a68a41b About an hour ago 522MB
# 运行
docker run -d -it --name mycat2 registry.cn-hangzhou.aliyuncs.com/centos68-registry/tomcat:v1.0
# 查看正在运行容器ID
docker ps -q
# d949db870969
# 7025dbea92a1
# 4374114e4fd1
# 7a1b7349c81e
# 关闭所有正在运行容器
docker stop $(docker ps -q)
registry.cn-hangzhou.aliyuncs.com/centos68-registry/tomcat v1.0 66797a68a41b 41 minutes ago 522MB