Docker基础教程(1)-基础概念

343 阅读12分钟

Docker基础教程(1)

自从2013年Docker问世后,短短几年时间已经成为了火爆全球的容器化解决方案,被认为可能会改变软件行业的发展,时至今日,可能还有许多开发者不知道,不了解Docker是什么,解决了什么问题,我们为什么要用Docker,此系列文章将会详细解释,帮助大家理解他,并且加入一些实例来更好的使用.

什么是docker

Docker 是世界领先的软件容器平台。开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用 Docker 可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用 Docker 可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为 Linux 和 Windows Server 应用发布新功能。

Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。

总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会,并成立推动 开放容器联盟(OCI)。

Docker 自开源后受到广泛的关注和讨论,至今其 GitHub 项目已经超过 4 万 6 千个星标和一万多个 fork。甚至由于 Docker 项目的火爆,在 2013 年底,dotCloud 公司决定改名为 Docker。Docker 最初是在 Ubuntu 12.04 上开发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持;Google 也在其 PaaS 产品中广泛应用 Docker。

Docker解决了什么问题

环境配置的问题

软件开发中,经历的最麻烦也是大家最不喜欢的一件事就是环境的配置,每一次公司新换服务器或者自己新购买了一台服务器,环境配置永远首要工作,并且安装一个服务还会涉及到一系列的依赖服务

而且如果两台服务器的环境配置或者内核不相同,就会出现一台机器可以跑,另一台机器由于各种奇葩或者无法解决的问题导致跑不起来的尴尬情况

环境配置如此麻烦,换一台机器,就要重来一次,旷日费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。

资源使用的问题

大部分个人服务器和小公司的服务器中,很多情况下都是好多服务部署在同一台服务器中,即便是大型的分布式项目,也有可能两个服务的某个节点在同一台服务器中,这种使用情况导致如果某一服务发现异常导致cpu跑满,则在此台服务器中所有的服务都将挂掉,这不是我们所期望的

那么有人可能会提到虚拟机技术,虚拟机技术占用的资源过于夸张,可能我实际运行的服务只占用几MB内存,但是还是需要占用宿主机几百MB内存才能使用,而且虚拟机的管理方式比较麻烦,并且启动和退出都是十分慢的

容器化

那么基于以上这些问题,linux提供给用户容器化的技术,首先要明确一个概念,容器并不是docker率先提出的,甚至不是linux,容器化的概念早在2000年就已经被提出了

而Linux容器不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。

Docker是什么

Docker 属于 Linux 容器的一种封装 ,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷,提供简单易用的容器使用接口(Docker Client 即docker命令行)。它是目前最流行的 Linux 容器解决方案。

Docker是CS架构主要有两个概念

  • Docker deamon: 运行在宿主机上,Docker守护进程,用户在宿主机中使用Docker Client(docker 命令行)来与Docker deamon 进行交互
  • Docker client: 是用户使用Docker的主要方式,Docker client与Docker daemon通信并将结果返回给用户,Docker client也可以通过socket或者RESTful api访问远程的Docker daemon

Docker的安装

Ubuntu Docker 安装

CentOS Docker 安装

Windows Docker 安装

MacOS Docker 安装

Docker的重要概念

镜像(Image)

  • Docker的镜像类似虚拟机的快照,不过更轻量,不过image只是一个静态的文件,并没有运行任何程序,只占用磁盘资源
  • Docker把应用程序及其依赖打包在一个image文件里面,可以理解为一个容器的使用. 通过这个image文件可以生成容器的实例.同一个image文件可以生成同时运行的多个实例

容器(Container)

  • 等同于从快照中创建出的虚拟机,也是服务实际运行的地方
  • 容器是从镜像创建的运行实例,它可以被启动、开始、停止、删除.每个容器都是相互隔离的,保证安全的平台
  • 可以把容器看作一个简易的Linux环境和运行在其中的应用程序
  • 容器中的端口可以与宿主机共享,也可以使用端口映射的方式来映射到宿主机中详见Docker中的网络和端口

仓库(Registry)

  • Docker仓库可以理解为git仓库或者maven仓库一样的远程存储中心,仓库中存储的是image数据,仓库可以选择公共的DockerHub(类似github),也可以选择在自己的服务器上搭建属于自己的Docker仓库(类似gitlab,gogs等私人仓库)

Docker中容器,镜像和仓库的概念,类似于LOL中英雄商店(仓库),你拥有的英雄(镜像),你在游戏中游玩的英雄(容器),比如想玩一个快乐风男(运行一个Apache服务),首先你要先从商店中购买英雄(从仓库中下载镜像),然后在开启游戏选择快乐风男(使用镜像启动容器)

数据卷(volumes)

  • 数据卷是一个可供一个容器或多个容器使用的特殊目录
  • 进程和数据的分离
  • 实际保存在容器之外,从而允许你在不影响数据的情况下对容器进行销毁、重建、修改、丢弃
  • 可用于数据持久化
  • 数据卷的共享, 可以在多个容器中共享数据

链接(links)

  • 容器的连接系统是除了端口的映射外,另一种跟容器中应用交互的方式
  • 在源和容器之间创建一个隧道,接收容器可以看到源容器指定的信息
  • Docker在两个互联的容器之间创建了一个安全隧道,而且不用映射他们的端口到宿主机上,从而避免了暴露关键系统(如数据库)端口到外部网络上

Docker简单实践

Docker的基础概念已经整理的差不多了,接下来我们来动手实践一下运行一个Docker的CentOS容器

运行命令docker search centos搜索镜像

[root@iZbp1cwfb0i1aften1twtvZ ~]# docker search centos
INDEX       NAME                                         DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
docker.io   docker.io/centos                             The official build of CentOS.                   5615      [OK]       
docker.io   docker.io/ansible/centos7-ansible            Ansible on Centos7                              124                  [OK]
docker.io   docker.io/jdeathe/centos-ssh                 OpenSSH / Supervisor / EPEL/IUS/SCL Repos ...   113                  [OK]
docker.io   docker.io/consol/centos-xfce-vnc             Centos container with "headless" VNC sessi...   99                   [OK]
docker.io   docker.io/centos/mysql-57-centos7            MySQL 5.7 SQL database server                   63                   
docker.io   docker.io/imagine10255/centos6-lnmp-php56    centos6-lnmp-php56                              57                   [OK]
docker.io   docker.io/tutum/centos                       Simple CentOS docker image with SSH access      44                   
docker.io   docker.io/centos/postgresql-96-centos7       PostgreSQL is an advanced Object-Relationa...   39                   
docker.io   docker.io/kinogmt/centos-ssh                 CentOS with SSH                                 29                   [OK]
docker.io   docker.io/pivotaldata/centos-gpdb-dev        CentOS image for GPDB development. Tag nam...   10                   
docker.io   docker.io/guyton/centos6                     From official centos6 container with full ...   9                    [OK]
docker.io   docker.io/drecom/centos-ruby                 centos ruby                                     6                    [OK]
docker.io   docker.io/centos/tools                       Docker image that has systems administrati...   4                    [OK]
docker.io   docker.io/darksheer/centos                   Base Centos Image -- Updated hourly             3                    [OK]
docker.io   docker.io/mamohr/centos-java                 Oracle Java 8 Docker image based on Centos 7    3                    [OK]
docker.io   docker.io/pivotaldata/centos                 Base centos, freshened up a little with a ...   3                    
docker.io   docker.io/miko2u/centos6                     CentOS6 日本語環境                                   2                    [OK]
docker.io   docker.io/pivotaldata/centos-gcc-toolchain   CentOS with a toolchain, but unaffiliated ...   2                    
docker.io   docker.io/pivotaldata/centos-mingw           Using the mingw toolchain to cross-compile...   2                    
docker.io   docker.io/blacklabelops/centos               CentOS Base Image! Built and Updates Daily!     1                    [OK]
docker.io   docker.io/indigo/centos-maven                Vanilla CentOS 7 with Oracle Java Developm...   1                    [OK]
docker.io   docker.io/mcnaughton/centos-base             centos base image                               1                    [OK]
docker.io   docker.io/pivotaldata/centos6.8-dev          CentosOS 6.8 image for GPDB development         0                    
docker.io   docker.io/pivotaldata/centos7-dev            CentosOS 7 image for GPDB development           0                    
docker.io   docker.io/smartentry/centos                  centos with smartentry                          0                    [OK]

选择star数最高的第一个镜像,NAME字段就是镜像的名称,下载的时候可以省略docker.io

运行docker pull centos 下载centos镜像,可以在镜像后面加入:版本号来下载对应的版本,默认选择latest版本

[root@iZbp1cwfb0i1aften1twtvZ ~]# docker pull centos
Using default tag: latest
Trying to pull repository docker.io/library/centos ... 
latest: Pulling from docker.io/library/centos
729ec3a6ada3: Pull complete 
Digest: sha256:f94c1d992c193b3dc09e297ffd54d8a4f1dc946c37cbeceb26d35ce1647f88d9
Status: Downloaded newer image for docker.io/centos:latest

运行docker images查看已经下载的镜像

[root@iZbp1cwfb0i1aften1twtvZ ~]# docker images
REPOSITORY                           TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos                     latest              0f3e07c0138f        2 weeks ago         220 MB

运行docker run -it --name mycentos -v /tmp/centos/:/tmp/ -e IMAGENAME=testcentos centos /bin/bash将镜像运行呈容器

命令解读

  • run命令将镜像运行成容器
  • -it 以命令行的形式打开
  • --name 指定运行容器的名称,如果不指定则默认分配一个名称
  • -v 数据卷的指定,将容器中的/tmp/目录映射到/tmp/centos/下
  • -e 环境变量的设定
  • centos 镜像名称的指定(如果有标签,还需要提供标签,默认是 latest 标签)。
  • /bin/bash 容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell。

如果以上命令执行成功就会返回一个命令提示符

[root@iZbp1cwfb0i1aften1twtvZ ~]# docker run -it --name mycentos -v /tmp/centos/:/tmp/ -e IMAGENAME=testcentos  centos bash
[root@a90b77adefcf /]#  

可以看到我们目前实际已经进入了容器中,试着运行echo $IMAGENAME输出一下我们制定的环境变量

[root@a90b77adefcf /]# echo $IMAGENAME
testcentos

接下来测试一下数据卷的使用,我们进入/tmp文件夹并创建一个文件并且输入一些内容

[root@a90b77adefcf tmp]# cd /tmp/
[root@a90b77adefcf tmp]# touch test.txt
[root@a90b77adefcf tmp]# echo test > test.txt 

接下来我们退出容器,注意退出容器有两种方式exit命令(Ctrl+D也可)和Ctrl+P+Q,第一种退出方式会关闭当前bash对话框,第二种则是bash后台运行直接返回宿主机,由于我们的docker容器需要一个主线程来支撑,如果容器觉得没有任何线程或者bash在运行,则会觉得自己没事情做选择自己退出容器,各位小伙伴在以后的使用中如果出现容器刚刚启动就退出的情况,有可能是这个问题

因为我们目前只有这一个bash在运行,如果是用exit的话容器就会关闭,所以我们选择Ctrl+P+Q退出容器

[root@a90b77adefcf tmp]# [root@iZbp1cwfb0i1aften1twtvZ ~]# 

可以看到我们已经回到宿主机中了,运行docker ps查看正在运行的容器

[root@iZbp1cwfb0i1aften1twtvZ ~]# docker ps
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                                              NAMES
a90b77adefcf        centos               "bash"                   16 minutes ago      Up 16 minutes                                                          mycentos

我们的centos服务还在后台默默地运行,那么我们来看看刚刚在容器中创建的文件是否能在宿主机中正常查看呢

[root@iZbp1cwfb0i1aften1twtvZ ~]# cd /tmp/centos/
[root@iZbp1cwfb0i1aften1twtvZ centos]# cat test.txt 
test
[root@iZbp1cwfb0i1aften1twtvZ centos]#

可以看到我们在容器中创建的这个文件依旧可以在宿主机中查看

接下来我们运行docker stop mycentos来停止掉这个容器(此处可以使用容器的名称,也可以使用容器的id)

[root@iZbp1cwfb0i1aften1twtvZ centos]# docker stop mycentos
mycentos

运行docker ps -a查看所有的容器

[root@iZbp1cwfb0i1aften1twtvZ centos]# docker ps -a
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS                      PORTS                                              NAMES
a90b77adefcf        centos               "bash"                   20 minutes ago      Exited (0) 58 seconds ago                                                      mycentos

该容器的STATUS已经变成了Exited,说明该容器已经停止了,但是停止的容器也会占用我们服务器的磁盘资源,所以运行docker rm mycetnos 删除该容器

[root@iZbp1cwfb0i1aften1twtvZ centos]# docker rm mycentos
mycentos

有兴趣的同学可以回去看一下刚刚我们创建的text.txt文件,依旧存在宿主机中,这就是数据卷的持久化保存

接下来我们删除掉使用的镜像 运行docker rmi centos删除镜像

[root@iZbp1cwfb0i1aften1twtvZ centos]# docker rmi centos
Untagged: centos:latest
Untagged: docker.io/centos@sha256:f94c1d992c193b3dc09e297ffd54d8a4f1dc946c37cbeceb26d35ce1647f88d9
Deleted: sha256:0f3e07c0138fbe05abcb7a9cc7d63d9bd4c980c3f61fea5efa32e7c4217ef4da
Deleted: sha256:9e607bb861a7d58bece26dd2c02874beedd6a097c1b6eca5255d5eb0d2236983

这样整个docker运行容器的实例就进行完成啦~

想观看更多教程可以移步我的个人博客 小阿宅的个人博客

感谢观看