docker入门
在学一门新知识的时候,超哥喜欢提问,why?what?how?html
wiki资料python
什么是docker
Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,于 2013 年 3 月以 Apache 2.0 受权协议开源,主要项目代码在 GitHub 上进行维护。 Docker 使用 Google 公司推出的 Go 语言 进行开发实现。 docker是linux容器的一种封装,提供简单易用的容器使用接口。它是最流行的Linux容器解决方案。 docker的接口至关简单,用户能够方便的建立、销毁容器。 docker将应用程序与程序的依赖,打包在一个文件里面。运行这个文件就会生成一个虚拟容器。 程序运行在虚拟容器里,如同在真实物理机上运行同样,有了docker,就不用担忧环境问题了。
ocke用场景
web应用的自动化打包和发布 自动化测试和持续集成、发布 在服务型环境中部署和调整数据库或其余应用
为何要用docker?
咱们先看看好久好久之前,服务器是怎么部署应用的!mysql
因为物理机的诸多问题,后来出现了虚拟机linux
可是虚拟化也是有局限性的,每个虚拟机都是一个完整的操做系统,要分配系统资源,虚拟机多道必定程度时,操做系统自己资源也就消耗殆尽,或者说必须扩容
docker与虚拟机的区别
docker VS 传统虚拟机
特性nginx |
容器git |
虚拟机程序员 |
启动github |
秒级web |
分钟级sql |
硬盘使用 |
通常为 MB |
通常为 GB |
性能 |
接近原生 |
弱 |
系统支持量 |
单机支持上千个容器 |
通常几十个 |
环境配置的难题
让开发人员最头疼的麻烦事之一就是环境配置了,每台计算机的环境都不相同,应该如何确保本身的程序换一台机器能运行起来呢?
用户必须确保的是:
- 操做系统的相同
- 各类平台库和组件的安装
- 例如python依赖包,环境变量等
如何一些低版本的依赖模块和当前环境不兼容,那就头疼了。。。。。
若是环境配置这么痛苦的话,换一台机器,就得从新配置一下,那么在安装软件的时候,带着原始环境如出一辙的复制过来。
然而,开发和运维之间聊天通常是这样的
解决方案一 虚拟机
虚拟机也能够制做模板,基于模板建立虚拟机,保证环境问题一致
虚拟机(virtual machine)就是带环境安装的一种解决方案。它能够在一种操做系统里面运行另外一种操做系统,好比在 Windows 系统里面运行 Linux 系统。应用程序对此毫无感知,由于虚拟机看上去跟真实系统如出一辙,而对于底层系统来讲,虚拟机就是一个普通文件,不须要了就删掉,对其余部分毫无影响。
虽然用户能够经过虚拟机还原软件的原始环境。可是,这个方案有几个缺点。
(1)资源占用多
虚拟机会独占一部份内存和硬盘空间。它运行的时候,其余程序就不能使用这些资源了。哪怕虚拟机里面的应用程序,真正使用的内存只有 1MB,虚拟机依然须要几百 MB 的内存才能运行。
(2)冗余步骤多
虚拟机是完整的操做系统,一些系统级别的操做步骤,每每没法跳过,好比用户登陆。
(3)启动慢
启动操做系统须要多久,启动虚拟机就须要多久。可能要等几分钟,应用程序才能真正运行。
解决方案二 Linux容器
如今:自从用上docker容器后,能够实现开发、测试和生产环境的统一化和标准化。
镜像做为标准的交付件,可在开发、测试和生产环境上以容器来运行,最终实现三套环境上的应用以及运行所依赖内容的彻底一致。
因为虚拟机的诸多问题,Linux发展出了另外一种虚拟化技术:Linux容器(Linux Containers,缩写LXC)
Linux容器不是模拟一个完整的操做系统,而是对进程进行隔离。在正常进程的外面套了一个保护层,对于容器里面进程来讲,它接触的资源都是虚拟的,从而实现和底层系统的隔离。
(1)启动快
容器里面的应用,直接就是底层系统的一个进程,而不是虚拟机内部的进程。因此,启动容器至关于启动本机的一个进程,而不是启动一个操做系统,速度就快不少。
(2)资源占用少
容器只占用须要的资源,不占用那些没有用到的资源;虚拟机因为是完整的操做系统,不可避免要占用全部资源。另外,多个容器能够共享资源,虚拟机都是独享资源。
(3)体积小
容器只要包含用到的组件便可,而虚拟机是整个操做系统的打包,因此容器文件比虚拟机文件要小不少。
总之,容器有点像轻量级的虚拟机,可以提供虚拟化的环境,可是成本开销小得多。
docker容器的优点
更高效的利用系统资源 因为容器不须要进行硬件虚拟以及运行完整操做系统等额外开销,Docker 对系统 资源的利用率更高。
不管是应用执行速度、内存损耗或者文件存储速度,都要比传 统虚拟机技术更高效。所以,相比虚拟机技术,一个相同配置的主机,每每能够运 行更多数量的应用。
更快速的启动时间 传统的虚拟机技术启动应用服务每每须要数分钟,而 Docker 容器应用,因为直接 运行于宿主内核,无需启动完整的操做系统,所以能够作到秒级、甚至毫秒级的启 动时间。大大的节约了开发、测试、部署的时间。
一致的运行环境 开发过程当中一个常见的问题是环境一致性问题。因为开发环境、测试环境、生产环 境不一致,致使有些 bug 并未在开发过程当中被发现。
而 Docker 的镜像提供了除内 核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 “这段代码 在我机器上没问题啊” 这类问题。
持续交付和部署 对开发和运维(DevOps)人员来讲,最但愿的就是一次建立或配置,能够在任意 地方正常运行。 使用 Docker 能够经过定制应用镜像来实现持续集成、持续交付、部署。开发人员 能够经过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系 统进行集成测试,
而运维人员则能够直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。
并且使用 Dockerfile 使镜像构建透明化,不只仅开发团队能够理解应用运行环 境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。
更轻松的迁移 因为 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 能够在 不少平台上运行,不管是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运 行结果是一致的。
所以用户能够很轻易的将在一个平台上运行的应用,迁移到另外一 个平台上,而不用担忧运行环境的变化致使应用没法正常运行的状况。
工做中的虚拟化和容器
docker三大概念
容器三大基本概念 镜像 image 容器 container 仓库 repository
docker整个生命周期就是这三个概念。
docker镜像
Docker镜像就是一个只读的模板。 例如:一个镜像能够包含一个完整的CentOS操做系统环境,里面仅安装了Apache或用户须要的其余应用程序。 镜像能够用来建立Docker容器。 Docker提供了一个很简单的机制来建立镜像或者更新现有的镜像,用户甚至能够直接从其余人那里下载一个已经作好的镜像来直接使用。
image的分层存储
由于镜像包含完整的root文件系统,体积是很是庞大的,所以docker在设计时按照Union FS的技术,将其设计为分层存储的架构。
镜像不是ISO那种完整的打包文件,镜像只是一个虚拟的概念,他不是一个完整的文件,而是由一组文件组成,或者多组文件系统联合组成。
docker容器(container)
image和container的关系,就像面向对象程序设计中的 类和实例同样,镜像是静态的定义(class),容器是镜像运行时的实体(object)。 容器能够被建立、启动、中止、删除、暂停 Docker利用容器来运行应用。 容器是从镜像建立的运行实例。它能够被启动、开始、中止、删除。每一个容器都是相互隔离的,保证安全的平台。 能够把容器看作是一个简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。 注意:镜像是只读的,容器在启动的时候建立一层可写层做为最上层。
docker仓库(repository)
仓库是集中存放镜像文件的场所。有时候把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上每每存放着多个仓库,每一个仓库中又包含了多个镜像,每一个镜像有不一样的标签(tag)。 仓库分为公开仓库(Public)和私有仓库(Private)两种形式。 最大的公开仓库是Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括Docker Pool等,能够提供大陆用户更稳定快读的访问。 当用户建立了本身的镜像以后就可使用push命令将它上传到公有或者私有仓库,这样下载在另一台机器上使用这个镜像时候,只需须要从仓库上pull下来就能够了。 注意:Docker仓库的概念跟Git相似,注册服务器能够理解为GitHub这样的托管服务。
docker Registry
Docker Registry 公开服务是开放给用户使用、容许用户管理镜像的 Registry 服 务。通常这类公开服务容许用户免费上传、下载公开的镜像,并可能提供收费服务 供用户管理私有镜像。
最常使用的 Registry 公开服务是官方的 Docker Hub,这也是默认的 Registry,并 拥有大量的高质量的官方镜像。
除此之外,还有 CoreOS 的 Quay.io,CoreOS 相 关的镜像存储在这里;Google 的 Google Container Registry,Kubernetes 的镜像 使用的就是这个服务。 因为某些缘由,在国内访问这些服务可能会比较慢。
国内的一些云服务商提供了针 对 Docker Hub 的镜像服务(Registry Mirror),这些镜像服务被称为加速器。常见 的有 阿里云加速器、DaoCloud 加速器、灵雀云加速器等。
使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从官方网站下载速度会提升不少。在后 面的章节中会有进一步如何配置加速器的讲解。 国内也有一些云服务商提供相似于 Docker Hub 的公开服务。好比 时速云镜像仓 库、网易云镜像服务、DaoCloud 镜像市场、阿里云镜像库等。
CentOS安装docker
官方教程以下,最正确安装docker姿式
1.卸载旧版本 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-selinux \ docker-engine-selinux \ docker-engine 2.设置存储库 sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2 sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo 3.安装docker社区版 sudo yum install docker-ce 4.启动关闭docker systemctl start docker
docker版本
Docker 是一个开源的商业产品,有两个版本:社区版(Community Edition,缩写为 CE)和企业版(Enterprise Edition,缩写为 EE)。
企业版包含了一些收费服务,我的开发者通常用不到。本文的介绍都针对社区版。
系统环境准备
docker最低支持centos7且在64位平台上,内核版本在3.10以上
[root@oldboy_python ~ 10:48:11]#uname -r
3.10.0-693.el7.x86_64
Docker镜像加速器
https://www.daocloud.io/mirror#accelerator-doc
https://www.cnblogs.com/pyyu/p/6925606.html
#一条命令加速
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://95822026.m.daocloud.io
docker基础命令注释
[root@docker ~]# docker --help Usage: docker [OPTIONS] COMMAND [arg...] docker daemon [ --help | ... ] docker [ --help | -v | --version ] A self-sufficient runtime for containers. Options: --config=~/.docker Location of client config files #客户端配置文件的位置 -D, --debug=false Enable debug mode #启用Debug调试模式 -H, --host=[] Daemon socket(s) to connect to #守护进程的套接字(Socket)链接 -h, --help=false Print usage #打印使用 -l, --log-level=info Set the logging level #设置日志级别 --tls=false Use TLS; implied by--tlsverify # --tlscacert=~/.docker/ca.pem Trust certs signed only by this CA #信任证书签名CA --tlscert=~/.docker/cert.pem Path to TLS certificate file #TLS证书文件路径 --tlskey=~/.docker/key.pem Path to TLS key file #TLS密钥文件路径 --tlsverify=false Use TLS and verify the remote #使用TLS验证远程 -v, --version=false Print version information and quit #打印版本信息并退出 Commands: attach Attach to a running container #当前shell下attach链接指定运行镜像 build Build an image from a Dockerfile #经过Dockerfile定制镜像 commit Create a new image from a container's changes #提交当前容器为新的镜像 cp Copy files/folders from a container to a HOSTDIR or to STDOUT #从容器中拷贝指定文件或者目录到宿主机中 create Create a new container #建立一个新的容器,同run 但不启动容器 diff Inspect changes on a container's filesystem #查看docker容器变化 events Get real time events from the server#从docker服务获取容器实时事件 exec Run a command in a running container#在已存在的容器上运行命令 export Export a container's filesystem as a tar archive #导出容器的内容流做为一个tar归档文件(对应import) history Show the history of an image #展现一个镜像造成历史 images List images #列出系统当前镜像 import Import the contents from a tarball to create a filesystem image #从tar包中的内容建立一个新的文件系统映像(对应export) info Display system-wide information #显示系统相关信息 inspect Return low-level information on a container or image #查看容器详细信息 kill Kill a running container #kill指定docker容器 load Load an image from a tar archive or STDIN #从一个tar包中加载一个镜像(对应save) login Register or log in to a Docker registry#注册或者登录一个docker源服务器 logout Log out from a Docker registry #从当前Docker registry退出 logs Fetch the logs of a container #输出当前容器日志信息 pause Pause all processes within a container#暂停容器 port List port mappings or a specific mapping for the CONTAINER #查看映射端口对应的容器内部源端口 ps List containers #列出容器列表 pull Pull an image or a repository from a registry #从docker镜像源服务器拉取指定镜像或者库镜像 push Push an image or a repository to a registry #推送指定镜像或者库镜像至docker源服务器 rename Rename a container #重命名容器 restart Restart a running container #重启运行的容器 rm Remove one or more containers #移除一个或者多个容器 rmi Remove one or more images #移除一个或多个镜像(无容器使用该镜像才能够删除,不然须要删除相关容器才能够继续或者-f强制删除) run Run a command in a new container #建立一个新的容器并运行一个命令 save Save an image(s) to a tar archive#保存一个镜像为一个tar包(对应load) search Search the Docker Hub for images #在docker hub中搜索镜像 start Start one or more stopped containers#启动容器 stats Display a live stream of container(s) resource usage statistics #统计容器使用资源 stop Stop a running container #中止容器 tag Tag an image into a repository #给源中镜像打标签 top Display the running processes of a container #查看容器中运行的进程信息 unpause Unpause all processes within a container #取消暂停容器 version Show the Docker version information#查看容器版本号 wait Block until a container stops, then print its exit code #截取容器中止时的退出状态值 Run 'docker COMMAND --help' for more information on a command. #运行docker命令在帮助能够获取更多信息
使用docker镜像
从仓库获取镜像 管理本地主机的镜像
获取镜像
从docker registry获取镜像的命令是docker pull。命令格式是:
docker pull [选项][docker registry地址] 仓库名:标签
docker register地址:地址的格式通常是 域名:端口,默认地址是docker hub
仓库名:仓库名是两段格式,用户名/软件名,若是不写用户,默认docker hub用户名是library,也就是官方镜像
镜像文件
docker是把应用程序和其依赖打包在image文件里面,只有经过这个镜像文件才能生成docker容器。 一个image文件能够生成多个容器实例。
image文件是通用,能够共享的,为了节省时间,咱们尽可能
列出服务器全部镜像文件
#列出全部的image文件 docker image ls #删除image文件 docker image rm [imagename]
搜索docker镜像
[root@docker ~]# docker search centos #搜索全部centos的docker镜像 INDEX NAME(名称) DESCRIPTION(描述) STARS(下载次数)OFFICIAL(官方) AUTOMATED(自动化) docker.io docker.io/centos The official build of CentOS. 1781 [OK] docker.io docker.io/jdeathe/centos-ssh CentOS-6 6.7 x86_64 / 14 [OK] ……
获取docker镜像
可使用docker pull命令来从仓库获取所须要的镜像。下面的例子将从Docker Hub仓库下载一个Centos操做系统的镜像。 [root@docker ~]# docker pull centos #获取centos镜像 [root@docker ~]# docker run -it centos /bin/bash #完成后可使用该镜像建立一个容器
查看docker镜像
镜像的ID惟一标识了镜像,若是ID相同,说明是同一镜像。 TAG信息来区分不一样发行版本,若是不指定具体标记,默认使用latest标记信息。 [root@docker ~]# docker images #查看docker镜像 REPOSITORY(来自那个仓库) TAG(标签) IMAGE ID(惟一ID) CREATED(建立时间) VIRTUAL SIZE(大小) docker.io/centos latest 60e65a8e4030 5 days ago 196.6 MB docker.io/nginx latest 813e3731b203 13 days ago 133.8 MB
删除Docker镜像
若是要移除本地的镜像,可使用docker rmi命令(在删除镜像以前先用docker rm删除依赖于这个镜像的全部容器)。注意docker rm 命令是移除容器。 [root@docker ~]# docker rmi imageID #删除docker镜像
导出docker镜像
若是要导出镜像到本地文件,可使用docker save命令。 [root@docker ~]# docker save centos > /opt/centos.tar.gz #导出docker镜像至本地 [root@docker ~]# ll /opt/ -rw-r--r--.1 root root 204205056 12月 30 09:53 centos.tar.gz
导入docker镜像
可使用docker load从本地文件中导入到本地docker镜像库 [root@docker ~]# docker load < /opt/centos.tar.gz #导入本地镜像到docker镜像库 [root@docker~]# docker images #查看镜像导入状况 REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE docker.io/centos latest 60e65a8e4030 5 days ago 196.6 MB
启动docker容器的方式
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另一个是将在终止状态(stopped)的容器从新启动。 由于Docker的容器实在过轻量级了,不少时候用户都是随时删除和新建立容器。
新建容器而且启动
所须要的命令主要为docker run 例如,下面的命令输出一个hehe,以后终止容器。 [root@docker ~]# docker run centos /bin/echo "hehe" #这跟在本地直接执行 /bin/echo'hehe' hehe [root@docker ~]# docker run --name mydocker -it centos /bin/bash#启动一个bash终端,容许用户进行交互。 [root@1c6c3f38ea07 /]# pwd / [root@1c6c3f38ea07 /]# ls anaconda-post.log bindev etc homelib lib64 lost+foundmedia mnt optproc root runsbin srv systmp usr var --name:给容器定义一个名称 -i:则让容器的标准输入保持打开。 -t:让Docker分配一个伪终端,并绑定到容器的标准输入上 /bin/bash:执行一个命令
当利用docker run来建立容器时,Docker在后台运行的标准操做包括
检查本地是否存在指定的镜像,不存在就从公有仓库下载 利用镜像建立并启动一个容器 分配一个文件系统,并在只读的镜像层外面挂在一层可读写层 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去 从地址池配置一个ip地址给容器 执行用户指定的应用程序 执行完毕后容器被终止
docker与"hello docker"
hello world是程序员启蒙语言,咱们经过最简单的image文件“hello-world”,来感觉一下docker。
#获取镜像 hello-world docker pull hello-world #检查镜像 docker images #运行image文件,能够用容器id docker run hello-world
#检查docker容器进程
docker ps
#检查全部运行过的容器
docker ps -a
运行成功后,能够看到结果
表示你已经成功运行了容器,hello world运行的容器会在完成后,自动终止
运行一个ubuntu容器
我们要在cenots7操做系统下,以docker下载一个ubuntu image文件,而后以image启动容器
[root@oldboy_python ~ 11:52:22]#docker pull ubuntu:14.04
#如图,乌班图的镜像下载,是下载每一层的文件
Trying to pull repository docker.io/library/ubuntu ... 14.04: Pulling from docker.io/library/ubuntu 8284e13a281d: Pull complete 26e1916a9297: Pull complete 4102fc66d4ab: Pull complete 1cf2b01777b2: Pull complete 7f7a2d5e04ed: Pull complete Digest: sha256:4851d1986c90c60f3b19009824c417c4a0426e9cf38ecfeb28598457cefe3f56 Status: Downloaded newer image for docker.io/ubuntu:14.04
下载过程能够看出镜像是由多层存储构成的。下载也是一层一层,并不是单一的文件。 下载过程当中给出每一层的前12位ID。下载结束后会给出sha246的文件一致性校验值。
运行这个乌班图容器!
[root@oldboy_python ~ 12:18:53]#docker run -it --rm ubuntu:14.04 bash
#此时会进入交互式的shell界面,便可以使用乌班图操做系统 root@3efbb2749d7c:/# cat /etc/os-release NAME="Ubuntu" VERSION="14.04.5 LTS, Trusty Tahr" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 14.04.5 LTS" VERSION_ID="14.04" HOME_URL="http://www.ubuntu.com/" SUPPORT_URL="http://help.ubuntu.com/" BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
#使用exit退出容器
exit
docker run就是运行容器的命令。 参数 -it : -i 是交互式操做,-t是终端 -rm : 容器退出后将其删除。也能够不指定参数,手动docker rm,使用-rm能够避免浪费空间。
ubuntu:14.04 这指的是镜像文件
bash : 指定用交互式的shell,所以须要bash命令
Docker与CentOS
docker容许在容器内运行应用程序,使用docker run命令来在容器内运行应用程序。
#加速docker镜像下载 curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://95822026.m.daocloud.io
[root@oldboy_python ~ 15:14:31]#docker pull docker.io/centos Using default tag: latest Trying to pull repository docker.io/library/centos ... latest: Pulling from docker.io/library/centos 256b176beaff: Pull complete Digest: sha256:fc2476ccae2a5186313f2d1dadb4a969d6d2d4c6b23fa98b6c7b0a1faad67685 Status: Downloaded newer image for docker.io/centos:latest
运行一个交互式的容器
[root@oldboy_python ~ 15:15:07]#docker run -it centos /bin/bash
#此时进入docker容器 [root@c72e9c40cfe2 /]# cat /etc/redhat-release
参数解析:
-
-t:在新容器内指定一个伪终端或终端。
-
-i:容许你对容器内的标准输入 (STDIN) 进行交互。
此时就进入了centos系统 能够查看系统相关信息,内核版本信息 cat /proc/version
ls /
此时想要退出容器,使用exit命令
后台模式启动docker
-d参数:后台运行容器,返回容器ID
[root@oldboy_python ~ 15:58:14]#docker run -d centos /bin/sh -c "while true;do echo hello centos; sleep 1;done" c0283f1077d16a2bf2597e269d51a02815334f7390f18a62ed7a4ba07f351b65
#检查容器进程 [root@oldboy_python ~ 15:58:22]#docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c0283f1077d1 centos "/bin/sh -c 'while..." 6 seconds ago Up 5 seconds fervent_turing [root@oldboy_python ~ 15:58:28]#
查看容器内的标准输出
docker logs c02
中止容器
docker stop c02
#此时容器进程不存在
docker ps
启动容器
docker start c02
#检查容器进程
docker ps
删除容器 docker rm c02
Docker镜像经常使用命令
docker images #列出全部本级镜像 docker pull centos #获取新的centos镜像 docker search nginx #搜索nginx镜像
构建镜像
1.经过commit修改镜像 2.编写dockerfile
进入容器
使用-d参数时,容器启动后会进入后台。某些时候须要进入容器进行操做,有不少种方法,包括使用docker attach命令或nsenter工具等。
docker exec -it 容器id docker attach 容器id
提交建立自定义的镜像(docker container commit)
1.咱们进入交互式的centos容器中,发现没有vim命令 docker run -it centos 2.在当前容器中,安装一个vim yum install -y vim 3.安装好vim以后,exit退出容器 exit 4.查看刚才安装好vim的容器记录 docker container ls -a 5.提交这个容器,建立新的image docker commit 059fdea031ba chaoyu/centos-vim 6.查看镜像文件 [root@master /home]docker images REPOSITORY TAG IMAGE ID CREATED SIZE chaoyu/centos-vim latest fd2685ae25fe 5 minutes ago 348MB
外部访问容器
容器中能够运行网络应用,可是要让外部也能够访问这些应用,能够经过-p或-P参数指定端口映射。
-P 参数会随机映射端口到容器开放的网络端口
[root@oldboy_python ~ 16:31:37]#docker run -d -P training/webapp python app.py
检查映射的端口
#宿主机ip:32768 映射容器的5000端口
[root@oldboy_python ~ 16:34:02]#docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cfd632821d7a training/webapp "python app.py" 21 seconds ago Up 20 seconds 0.0.0.0:32768->5000/tcp brave_fermi
查看容器日志信息
#不间断显示log
docker logs -f cfd
也能够经过-p参数指定映射端口
#指定服务器的9000端口,映射到容器内的5000端口
[root@oldboy_python ~ 16:46:13]#docker run -d -p 9000:5000 training/webapp python app.py c0b5a6278d0f4f2e9b9eba8680451111d8b911b61de0c37ea64cb337aefb854e
访问服务器的9000端口
(若是访问失败的话,检查本身的防火墙,以及云服务器的安全组)
查看指定容器的端口映射
[root@oldboy_python ~ 16:49:01]#docker port c0b 5000/tcp -> 0.0.0.0:9000
查看容器内的进程
[root@oldboy_python ~ 16:49:05]#docker top c0b UID PID PPID C STIME TTY TIME CMD root 3926 3912 0 16:46 ? 00:00:00 python app.py
利用dockerfile定制镜像
镜像是容器的基础,每次执行docker run的时候都会指定哪一个镜像做为容器运行的基础。咱们以前的例子都是使用来自docker hub的镜像,直接使用这些镜像只能知足必定的需求,当镜像没法知足咱们的需求时,就得自定制这些镜像。
镜像的定制就是定制每一层所添加的配置、文件。若是能够吧每一层修改、安装、构建、操做的命令都写入到一个脚本,用脚原本构建、定制镜像,这个脚本就是dockerfile。
Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令 构建一层,所以每一条指令的内容,就是描述该层应当如何构建。
FROM scratch #制做base image 基础镜像,尽可能使用官方的image做为base image FROM centos #使用base image FROM ubuntu:14.04 #带有tag的base image LABEL version=“1.0” #容器元信息,帮助信息,Metadata,相似于代码注释 LABEL maintainer=“yc_uuu@163.com" #对于复杂的RUN命令,避免无用的分层,多条命令用反斜线换行,合成一条命令! RUN yum update && yum install -y vim \ Python-dev #反斜线换行 RUN /bin/bash -c "source $HOME/.bashrc;echo $HOME” WORKDIR /root #至关于linux的cd命令,改变目录,尽可能使用绝对路径!!!不要用RUN cd WORKDIR /test #若是没有就自动建立 WORKDIR demo #再进入demo文件夹 RUN pwd #打印结果应该是/test/demo ADD and COPY ADD hello / #把本地文件添加到镜像中,吧本地的hello可执行文件拷贝到镜像的/目录 ADD test.tar.gz / #添加到根目录并解压 WORKDIR /root ADD hello test/ #进入/root/ 添加hello可执行命令到test目录下,也就是/root/test/hello 一个绝对路径 COPY hello test/ #等同于上述ADD效果 ADD与COPY - 优先使用COPY命令 -ADD除了COPY功能还有解压功能 添加远程文件/目录使用curl或wget ENV #环境变量,尽量使用ENV增长可维护性 ENV MYSQL_VERSION 5.6 #设置一个mysql常量 RUN yum install -y mysql-server=“${MYSQL_VERSION}”
------这里须要稍微理解一下了-------中级知识---先不讲
VOLUME and EXPOSE 存储和网络 RUN and CMD and ENTRYPOINT RUN:执行命令并建立新的Image Layer CMD:设置容器启动后默认执行的命令和参数 ENTRYPOINT:设置容器启动时运行的命令 Shell格式和Exec格式 RUN yum install -y vim CMD echo ”hello docker” ENTRYPOINT echo “hello docker” Exec格式 RUN [“apt-get”,”install”,”-y”,”vim”] CMD [“/bin/echo”,”hello docker”] ENTRYPOINT [“/bin/echo”,”hello docker”] 经过shell格式去运行命令,会读取$name指令,而exec格式是仅仅的执行一个命令,而不是shell指令 cat Dockerfile FROM centos ENV name Docker ENTRYPOINT [“/bin/echo”,”hello $name”]#这个仅仅是执行echo命令,读取不了shell变量 ENTRYPOINT [“/bin/bash”,”-c”,”echo hello $name"] CMD 容器启动时默认执行的命令 若是docker run指定了其余命令(docker run -it [image] /bin/bash ),CMD命令被忽略 若是定义多个CMD,只有最后一个执行 ENTRYPOINT 让容器以应用程序或服务形式运行 不会被忽略,必定会执行 最佳实践:写一个shell脚本做为entrypoint COPY docker-entrypoint.sh /usr/local/bin ENTRYPOINT [“docker-entrypoint.sh] EXPOSE 27017 CMD [“mongod”] [root@master home]# more Dockerfile FROm centos ENV name Docker #CMD ["/bin/bash","-c","echo hello $name"] ENTRYPOINT ["/bin/bash","-c","echo hello $name”]
发布docker image到仓库
第一种,docker hub公有镜像发布
1.docker提供了一个相似于github的仓库dockerhub, 网址https://hub.docker.com/须要注册使用 2.注册docker id后,在linux中登陆dockerhub docker login
注意要保证image的tag是帐户名,若是镜像名字不对,须要改一下tag
docker tag chaoyu/centos-vim yuchao163/centos-vim
语法是: docker tag 仓库名 yuchao163/仓库名
3.推送docker image到dockerhub docker push yuchao163/centps-cmd-exec:latest 4.在dockerhub中检查镜像 https://hub.docker.com/ 5.删除本地镜像,测试下载pull 镜像文件 docker pull yuchao163/centos-entrypoint-exec
私有仓库
可是这种镜像仓库是公开的,其余人也是能够下载,并不安全,所以还可使用docker registry官方提供的私有仓库
1.官方提供的私有仓库docker registry用法 https://yeasy.gitbooks.io/docker_practice/repository/registry.html 2.一条命令下载registry镜像而且启动私有仓库容器 私有仓库会被建立在容器的/var/lib/registry下,所以经过-v参数将镜像文件存储到本地的/opt/data/registry下 端口映射容器中的5000端口到宿主机的5000端口 docker run -d \ -p 5000:5000 \ -v /opt/data/registry:/var/lib/registry \ registry 3.检查启动的registry容器 docker ps 4.测试链接容器 telnet 192.168.119.10 5000 5.修改镜像tag,以docker registry的地址端口开头 docker tag hello-world:latest 192.168.119.10:5000/hello-world:latest 6.查看docker镜像,找到registry的镜像 docker images 7.Docker 默认不容许非 HTTPS 方式推送镜像。咱们能够经过 Docker 的配置选项来取消这个限制,这里必须写正确json数据 [root@master /]# cat /etc/docker/daemon.json {"registry-mirrors": ["http://95822026.m.daocloud.io"], "insecure-registries":["192.168.119.10:5000"] }
写入到docker服务中,写入到[Service]配置块中,加载此配置文件 [root@master home]# grep 'EnvironmentFile=/etc/docker/daemon.json' /lib/systemd/system/docker.service EnvironmentFile=-/etc/docker/daemon.json 8.修改了docker配置文件,从新加载docker systemctl daemon-reload 9.重启docker systemctl restart docker 10.重启了docker,刚才的registry容器进程挂掉了,所以从新启动它
docker run --privileged=true -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry registry
--privileged=true docker容器的安全机制:设置特权级运行的容器 11.推送本地镜像 docker push 192.168.119.10:5000/hello-world
12.因为docker registry没有web节目,可是提供了API数据 官网教程:https://docs.docker.com/registry/spec/api/#listing-repositories curl http://192.168.119.10:5000/v2/_catalog
或者浏览器访问http://192.168.119.10:5000/v2/_catalog
13.删除本地镜像,从私有仓库中下载
docker pull 192.168.119.10:5000/hello-world
打包flask程序与dockerfile
超哥构建好的镜像,只要丢给武沛奇,说“小沛奇,拿去用吧,这个镜像你直接docker run就能用了,不须要你管环境问题了,有没有很崇拜我”,沛奇说,“超哥真牛逼”
确保app.py和dockerfile在同一个目录! 1.准备好app.py的flask程序 [root@master home]# cat app.py
#coding:utf8 from flask import Flask app=Flask(__name__) @app.route('/') def hello(): return "hello docker" if __name__=="__main__": app.run(host='0.0.0.0',port=8080) [root@master home]# ls app.py Dockerfile 2.编写dockerfile
FROM centos
COPY CentOS-Base.repo /etc/yum.repos.d/
COPY epel.repo /etc/yum.repos.d/
RUN yum clean all
RUN yum install python-setuptools -y
RUN easy_install flask
COPY s16-flask.py /opt/
WORKDIR /opt
EXPOSE 8080
CMD ["python","s16-flask.py"]
3.构建镜像image docker build -t yuchao163/flask-hello-docker . 4.查看建立好的images docker image ls 5.启动此flask-hello-docker容器,映射一个端口供外部访问 docker run -d -p 8080:8080 yuchao163/flask-hello-docker 6.检查运行的容器 docker container ls
一致的开发环境
docker网络
Docker 容许经过外部访问容器或容器互联的方式来提供网络服务。
- 端口映射容许外部访问容器
- --link 容器互联
- 容器桥接网络
1.经过--link容器通讯,给test2添加一个hosts解析记录 docker run -d --name test2 --link test1 busybox /bin/sh -c "while true;do sleep 3600;done" test2能够ping通test1,反之不能够
可是--link是不推荐使用的,而是更强大的自定义docker网络连接容器
1.新建一个docker网络 docker network create -d bridge my-net -d 参数指定 Docker 网络类型,有 bridge overlay 2.链接容器 运行一个容器并链接到新建的 my-net 网络 $ docker run -it --rm --name busybox1 --network my-net busybox sh 打开新的终端,再运行一个容器并加入到 my-net 网络 $ docker run -it --rm --name busybox2 --network my-net busybox sh 再打开一个新的终端查看容器信息 $ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b47060aca56b busybox "sh" 11 minutes ago Up 11 minutes busybox2 8720575823ec busybox "sh" 16 minutes ago Up 16 minutes busybox1 下面经过 ping 来证实 busybox1 容器和 busybox2 容器创建了互联关系。 在 busybox1 容器输入如下命令 / # ping busybox2 PING busybox2 (172.19.0.3): 56 data bytes 64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.072 ms 64 bytes from 172.19.0.3: seq=1 ttl=64 time=0.118 ms 用 ping 来测试链接 busybox2 容器,它会解析成 172.19.0.3。 同理在 busybox2 容器执行 ping busybox1,也会成功链接到。 / # ping busybox1 PING busybox1 (172.19.0.2): 56 data bytes 64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.064 ms 64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.143 ms 这样,busybox1 容器和 busybox2 容器创建了互联关系。
外部访问容器
容器中能够运行网络应用,可是要让外部也能够访问这些应用,能够经过-p或-P参数指定端口映射。
-P 参数会随机映射端口到容器开放的网络端口
[root@oldboy_python ~ 16:31:37]#docker run -d -P training/webapp python app.py
检查映射的端口
#宿主机ip:32768 映射容器的5000端口
[root@oldboy_python ~ 16:34:02]#docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cfd632821d7a training/webapp "python app.py" 21 seconds ago Up 20 seconds 0.0.0.0:32768->5000/tcp brave_fermi
查看容器日志信息
#不间断显示log
docker logs -f cfd
也能够经过-p参数指定映射端口
#指定服务器的9000端口,映射到容器内的5000端口
[root@oldboy_python ~ 16:46:13]#docker run -d -p 9000:5000 training/webapp python app.py c0b5a6278d0f4f2e9b9eba8680451111d8b911b61de0c37ea64cb337aefb854e
访问服务器的9000端口
(若是访问失败的话,检查本身的防火墙,以及云服务器的安全组)
查看指定容器的端口映射
[root@oldboy_python ~ 16:49:01]#docker port c0b 5000/tcp -> 0.0.0.0:9000
查看容器内的进程
[root@oldboy_python ~ 16:49:05]#docker top c0b UID PID PPID C STIME TTY TIME CMD root 3926 3912 0 16:46 ? 00:00:00 python app.py