docker最先基于LXC实现(LinuX Container)从0.7版本之后开始去除LXC转而使用自行开发的libcontainer,从1.11开始,演进为runC和containerd;docker是go语言开发,基于Linux内核的cgroup,namespace以及AUFS相似的Union FS(联合文件系统)等技术,对进程进行封装隔离,属于操做系统层面的虚拟化技术,因为隔离的进程独立于宿主机和其余的隔离进程,所以也称其为容器。
docker在容器的基础上进行了进一步的封装从文件系统,网络互联到进程隔离等,极大简化了容器的建立和维护管理。使得docker技术比虚拟机技术更为轻便,快捷。html
虚拟机与docker比较:
图片引用自网络前端
由上面的比较图能够看一样启动一个服务;虚拟机会多一层操做系统,而docker和宿主机共用内核系统;所以docker占用资源更少,资源利用率更高;
虚拟机与docker对比mysql
docker优势总结:
高效的资源利用率
快速的启动
一致的运行环境
持续将会和部署
更轻松的迁移
便捷的维护和扩展linux
系统要求:CentOS7.x_x64且安装Docker CE版本(社区版),不要使用epel仓库自带的docker docker从1.17后主要分docker-ce和docker-ee(企业版,你懂滴,就比如mysql企业版与社区版,若是还不明白当我没说)nginx
如下安装基于CentOS 7.4_x64 最小化安装git
[root@docker ~]# uname -r 3.10.0-693.21.1.el7.x86_64 [root@docker ~]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) #御载自带组件 yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine -y #安装依赖组件 [root@docker ~]# yum install -y yum-utils device-mapper-persistent-data lvm2 #添加国内源 yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo #添加官方源 [root@docker ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo #最新版的docker CE 使用如下命令 [root@docker ~]# yum-config-manager --enable docker-ce-edge #测试版docker ce 使用如下命令 (可选) [root@docker ~]# yum-config-manager --enable docker-ce-test #安装docker ce [root@docker ~]# yum makecache fast [root@docker ~]# yum install install docker-ce #注意官方docker-ce可能有点慢~ #或使用脚本自动安装 [root@docker ~] # curl -fsSL get.docker.com -o get-docker.sh [root@docker ~]# sh get-docker.sh --mirror Aliyun #安装完查看版本信息 [root@docker ~]# docker --version Docker version 18.04.0-ce, build 3d479c0 #启动docker [root@docker ~]# systemctl start docker
以上表示安装成功docker-ce版本,如下的示例测试均在此基础上进行;若是是ubuntu安装docker请参考这里ubuntu安装docker-cesql
从物理上讲client <--> docker daemon <--> Registry Server
逻辑上:
Images:
镜像只读,分层镜像机制,最后一层可读写,可共享,或理解为OS
Containers:容器:
是从镜像启动建立的,相似程序与进程的关系,而Images镜像就是程序文件,运行起来成为进程;镜像是静态定义,容器是镜像运行时的实体;容器能够被建立,启动,中止,删除,暂停;容器实质是进程;docker
Registry:Image Repositories (存放共享的镜像库,相似yum库)docker官方提供仓库地址hub.docker.comubuntu
容器的状态与指令:
经常使用状态如:
created:docker create(不经常使用),docker run 指令从镜像建立并运行
running:docker run 指令从镜像建立并运行
paused:docker paused 暂停容器
stopped:docker stop 中止运行某容器,或经过docker kill容器
状态间转化如图:centos
以上指令都可经过docker --help 或docker COMMAND --help获取子命令帮助
查看docker相关信息:
docker --version Docker version 18.03.0-ce, build 0520e24
获取docker daemon运行的信息
docker info
镜像相关操做
列出本机镜像:
docker images
拉取下载镜像:
docker pull 库/镜像名:版本 默认是docker.io/镜像名:lastest
删除镜像:
删除关确保没有容器使用
docker rmi 镜像名|镜像ID
查找镜像:
docker search 镜像名
[root@docker ~]# docker search busybox NAME DESCRIPTION STARS OFFICIAL AUTOMATED busybox Busybox base image. 1239 [OK] progrium/busybox 66 [OK] 说明:STARS可理解为获取的赞,OFFICIAL OK表示官方出的
示例:拉取busybox
[root@docker ~]# docker pull busybox Using default tag: latest
注意:没有指定仓库,默认从docker.io上获取最新latest版本
容器相关经常使用操做
docker run 选项 镜像:建立并运行一个容器
选项以下:
--rm 运行容器中止退出后删除容器
--it 交互式运行容器
-d 后台daemon运行(和--rm不可同时出现)
--name 指定容器名
-p [port:port] 把容器中的端口映射出来
docker ps :查看运行中的容器
docker ps -a:查看全部的容器(包括中止状态)
docker start :启动处于中止状态的容器
docker inspect 容器:查运行中容器信息
docker network ps :查看docker 网络接口
docker attach:附加至某运行状态的容器的终端设备;(运行在后台中的容)
docker exec:让运行中的容器运行一个额外的程序(容器中有程序前台占终端运行状况下,后面有实例)
docker logs:输出容器内部程序运行时输出到终端的信息
docker stats:动态方式显示容器的资源占用状态
docker top:显示容器运行的进程
docker kill :中止容器(容器牌前台运行时)
docker stop:中止容器
docker tag 镜像 新镜像:标记镜像
docker login -u 用户名: 登陆(默认docker.io须要注册)用户名
docker pull 镜像:默认从docker.io仓库获取最新版本镜像,如是私有仓库须要登陆
docker push 镜像:登陆后可push(默认docker.io)仓库
docker rename:重命名容器
docker restart: 重启容器
docker pause:暂停容器
docker unpause:从暂停状态恢复
docker rm :删除容器,须要注意的是容器只能是关闭状态才能删除
或运行进docker run --rm 表示运行中止后就删除容器
示例:从busybox镜像启动容器b1 前台运行
[root@docker ~]# docker run --rm -it --name b1 busybox # 按crtl + p +q 从终端拆除(转入后台) #查看容器 [root@docker ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 356979c81de8 busybox "sh" About a minute ago Up About a minute b1 说明:能够看到运行状态是up 容器名指定为b1 能够经过docker stop b1 中止 (因为 --rm选项)即容器删除 [root@docker ~]# docker stop b1 b1 [root@docker ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@docker ~]#
示例:后台启动容器 b1
[root@docker ~]# docker run -d -it --name b1 busybox b8548d53a69999b0c351dc779ebf18cdcfd40dc4d749bc7a6cec300d3ad958e5 [root@docker ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b8548d53a699 busybox "sh" 17 seconds ago Up 16 seconds b1 [root@docker ~]# docker stop b1 b1 [root@docker ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b8548d53a699 busybox "sh" 49 seconds ago Exited (137) 14 seconds ago b1
说明:经过后台启动模式,在中止运行后 容器处于退出中止状态,并不会删除,下次能够经过 docker start b1再次启动,--rm和-d不能同时存在。
镜像制做有两种方式,基于容器制做和基于(已有)镜像制做;
基于(运行中)容器制做
在容器中完成操做后制做
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]
示例:基于busybox 镜像启动容器b1并在容器里启动httpd服务 并以此运行的容器制做镜像
运行容器(进入容器操做) [root@docker ~]# docker run -it --name b1 busybox / # mkdir -pv /data/html created directory: '/data/' created directory: '/data/html' / # echo "<h1> Busybox httpd server</h1>" >/data/html/index.html / # cat /data/html/index.html <h1> Busybox httpd server</h1> / # httpd -h /data/html / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02 inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0 ....省略.... / # netstat -ntpul Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 :::80 :::* LISTEN 8/httpd 按ctrl +p +q 进入后台(拆除终端)
[root@docker ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 477cf5b3abca busybox "sh" 4 minutes ago Up 4 minutes b1
从以上能够看出在b1容器中启动了http 并侦听在80端口上;拆除终端进入了后台运行;
基于运行中的b1容器制做镜像并打上新的标签名"docker.io/dyc2005/bbox:v0.1.1-httpd"
[root@docker ~]# docker commit -p -a "san <san@san.com>" b1 docker.io/dyc2005/bbox:v0.1.1-httpd sha256:c4e8c59c4b577a568002789e7c266828a8e86dd9fdd825b05f91933a5e9710f0 [root@docker ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE dyc2005/bbox v0.1.1-httpd c4e8c59c4b57 6 seconds ago 1.15MB busybox latest 8ac48589692a 9 days ago 1.15MB
此时新的镜像ID和busybox(产生b1容器)镜像ID已经 不一样了,此时也可经过
docker push 推到镜像库中
验证:
基于新的镜像后台启动容器b2
补充:与上面效果相似
[root@docker ~]# docker commit -a "san" -c 'CMD ["/bindocke/httpd","-f","-h","/data/html"]' b1 docker.io/dyc2005/bbox:v0.1.2-httpd
#运行制做好的镜像:
[root@docker ~]# docker run --name h2 -it dyc2005/bbox:v0.1.2-httpd
[root@docker ~]# docker exec h2 ps
PID USER TIME COMMAND
1 root 0:00 /bin/httpd -f -h /data/html
8 root 0:00 ps
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7147cb559d9 dyc2005/bbox:v0.1.3-httpd "/bin/httpd -f -h /d…" 22 seconds ago Up 21 seconds h2
[root@docker ~]# docker run -it -d --name b2 docker.io/dyc2005/bbox:v0.1.1-httpd httpd -f -h /data/html b93754954d61b1a477ef361fcb348962b9b10004221263d9f4c69db193730a61 #查看b2的信息查看ip [root@docker ~]# docker inspect b2 |grep IPAddress "SecondaryIPAddresses": null, "IPAddress": "172.17.0.3", "IPAddress": "172.17.0.3", #访问b2 [root@docker ~]# curl http://172.17.0.3 <h1> Busybox httpd server</h1>
至此基于运行中的容器制做镜像完成!
此时产生一个问题,运行中的镜像进入是docker attach b2
但你发现终端卡在那里,因为httpd(容器中)前台运行,没法修改网页
解决方法:
[root@docker ~]# docker exec -it b2 /bin/sh / # netstat -ntpul Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 :::80 :::* LISTEN 1/httpd / #
经过 docker exec 就能够进行运行在容器前端的中修改容器中的内容!这也是attach与exec命令的区别所在!
另外本次运行镜像端口没有作映射,后面会提到!通常不推荐如此制做镜像;制做镜像推荐使用Dockerfile文件
基于镜像制做
编辑 Dockerfile,然后根据此文件制做;
详细说明参照这里
如下给出实例:
宿主机上建立bbox
[root@docker ~]# mkdir -pv bbox/data
[root@docker ~]# cat /data/html/index.html<h1>Busybox httpd server from Dockerfile.</h1>
[root@docker ~]#cat Dockerfiel
FROM busybox:latest MAINTAINER "san" "<san@san.com>" #COPY index.html /data/html/ COPY data /data/ VOLUME /data/html EXPOSE 80/tcp ENV epel_repo_file http://172.16.0.188/epel.repo ADD ${epel_repo_file} /etc/yum.repos.d/ RUN /bin/adduser -D myuser && \ /bin/mkdir /tmp/dir -pv
注意请自行模拟一个可访问的http能访问到的epel.repo
在bbox目录中运行
[root@docker bbox]# docker build -t docker.io/dyc2005/busybox/v.1.1-httpd ./ Sending build context to Docker daemon 4.096kB Step 1/8 : FROM busybox:latest ---> 8ac48589692a Step 2/8 : MAINTAINER "san" "<san@san.com>" ---> Using cache ---> 3105f31095b2 Step 3/8 : COPY data /data/ ---> Using cache ---> 355f7a29fd45 Step 4/8 : VOLUME /data/html ---> Using cache ---> 4111c015d683 Step 5/8 : EXPOSE 80/tcp ---> Using cache ---> 6f2ef2457118 Step 6/8 : ENV epel_repo_file http://172.16.0.188/epel.repo ---> Using cache ---> d1ac10e625c4 Step 7/8 : ADD ${epel_repo_file} /etc/yum.repos.d/ Downloading [==================================================>] 10B/10B ---> 943a7f280b6e Step 8/8 : RUN /bin/adduser -D myuser && /bin/mkdir /tmp/dir -pv ---> Running in 15bb73b0690d created directory: '/tmp/dir' Removing intermediate container 15bb73b0690d ---> e2ff30f1beb2 Successfully built e2ff30f1beb2 Successfully tagged dyc2005/busybox/v.1.1-httpd:latest ##查看新生成的镜像并运行 [root@docker bbox]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE dyc2005/busybox/v.1.1-httpd latest e2ff30f1beb2 52 seconds ago 1.15MB [root@docker bbox]# docker run -it --rm --name d1 dyc2005/busybox/v.1.1-httpd / # id myuser uid=1000(myuser) gid=1000(myuser) groups=1000(myuser) / # ls /tmp/dir/ / # ls /tmp/ dir / # 能够看出新生成的镜像已经完成了指定的操做
到此镜像制做的两咱方法已经小试牛刀的演示完,推荐用dockerfile文件生成镜像,Dockerfile中的每一行的命令都是一层
所以建议使用command && command && ...这种方式;
将镜像文件导出为tar文件
docker save #镜像保存成文件(在没有仓库的状况下)
Save one or more images to a tar archive (streamed to STDOUT by default)
docker save [OPTIONS] IMAGE [IMAGE...]
示例:docker save -o /root/nginx-v0.1.0.tar 4481eeccc973
从tar文件导入镜像
docker load ##从文件导入成镜像 Load an image from a tar archive or STDIN docker load [OPTIONS] --input, -i Read from tar archive file, instead of STDIN --quiet, -q false Suppress the load output 示例 # docker load -i nginx-v0.1.0.tar
从新打标签[root@docker ~]# docker tag 4481eeccc973 docker.io/dyc2005/nginx.v0.1.0
Bind mount volume :容器内和宿主机上都是用户指定 [root@docker ~]# run -it --name bbox1 -v /data/html busybox:v1.0 [root@docker ~]# cat /var/lib/docker/volumes/163a16717cb1d859869cdd7a87a3ad91b04e754ff26130d9145fe0c4ccf94e05/_data# cat index.html <h1>c1</h1> [root@docker ~]#docker inspect -f {{.Config.Volume}}{{.Mounts}} bbox1 Docker-managed volume :容器内用户指定,宿主机上的目录默认在/var/lib/docker/volumes 由docker指定 [root@docker ~]#docker run -it -v HOSTDIR:VOLUME --name bbox2 busybox:v1.0 [root@docker ~]# mkdir -pv /tmp/data(宿主机上) [root@docker ~]# echo "<h1> Test Page in App1</h1>" >/tmp/data/index.html [root@docker ~]# docker run --name h2 -d -it -v /tmp/data:/data/html dyc2005/bbox:v0.1.3-httpd [root@docker ~]# curl http://172.17.0.2 <h1> Test Page in App1</h1> [root@docker ~]# docker inspect -f {{.Mounts}} bbox2
列出volume卷:
[root@docker ~]#docker inspect -f {{.Mounts}} bbox2
docker volume list
DRIVER VOLUME NAME
local 163a16717cb1d859869cdd7a87a3ad91b04e754ff26130d9145fe0c4ccf94e05
查看详细信息
[root@docker ~]#docker inspect -f {{.Mounts}} bbox2 docker volume inspect 163a16717cb1d859869cdd7a87a3ad91b04e754ff26130d9145fe0c4ccf94e05 [ { "CreatedAt": "2018-04-09T18:10:46+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/163a16717cb1d859869cdd7a87a3ad91b04e754ff26130d9145fe0c4ccf94e05/_data", "Name": "163a16717cb1d859869cdd7a87a3ad91b04e754ff26130d9145fe0c4ccf94e05", "Options": {}, "Scope": "local" } ] 或 [root@docker ~]# inspect -f {{.Mounts}} bbox2 [{volume 163a16717cb1d859869cdd7a87a3ad91b04e754ff26130d9145fe0c4ccf94e05 /var/lib/docker/volumes/163a16717cb1d859869cdd7a87a3ad91b04e754ff26130d9145fe0c4ccf94e05/_data /data/html local true }]
注意问题:挂载volume到容器,若是容器中有内容则复制到宿主机目录,通常删除容器不会删除volume,若是要一并删除须要加--volumw|-v选项
单独删除 docker volume rm 命令
多个容器使用同一个宿主目录
[root@docker ~]# docker run --name h1 -d -it -v /tmp/data:/data/html dyc2005/bbox:v0.1.3-httpd [root@docker ~]# docker run --name h2 -d -it -v /tmp/data:/data/html dyc2005/bbox:v0.1.3-httpd 或复制其余主机使用的volume [root@docker ~]# docker run --name h1 -d -it -v /tmp/data:/data/html dyc2005/bbox:v0.1.3-httpd [root@docker ~]# docker run --name h3 -it --rm --volumes-from h1 dyc2005/bbox:v0.1.0 #cd /data/html/ /data/html # ls index.html
以上是docker学习中整理的笔记不免有错漏之处,欢迎指正!