为了能很好的了解k8s,这里小编写大体的将docker的基础作一些介绍,这里小编将会以2篇博文的形式,详细的介绍一下docker的基础部分,这一篇是docker的概念以及docker的基本使用,后续会在发布一篇关于docker的官网上的quick-start的实战案例,让你们能更好的了解docker。html
Docker是一个开源的引擎,能够轻松的为任何应用建立一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试经过的容器能够批量地在生产环境中部署,包括VMs(虚拟机)、bare metal、OpenStack 集群和其余的基础应用平台。mysql
Docker经过容器来打包应用,意味着迁移只须要在新的服务器上启动须要的容器就能够,下降部署过程出现的问题的风险。
更高的资源利用,docker容器的运行不须要额外的虚拟化管理程序支持,它是内核级的虚拟化,能够实现更高的性能。
更轻松的更新管理。使用dockerfile只须要小小的配置,就能够代替以往大量的更新工做。
nginx
工做流程:服务器A运行docker engine 服务,在docker engine 上启动不少容器container,从外网Docker Hub把image操做系统镜像pull下来,放到container容器运行。最后经过docker client对docker容器虚拟化平台进行控制。
Image 和 Container 的关系:image 能够理解为一个系统镜像,Container 是 Image 在运行时的 一个状态。
dockerhub:dockerhub 是 docker 官方的镜像存储站点,其中提供了不少经常使用的镜像供用户下载, 如 ubuntu, centos 等系统镜像。(这里还有私有镜像库harbor,小编在以前的博文中也介绍过:http://www.javashuo.com/article/p-haetltkg-cw.html)
Docker的核心技术:web
Docker依赖于Linux内核的特性:namespace和cgroups(控制组)。
Namespace实现资源隔离,其中docker有五种命名空间:
- PID:进程隔离
- NET:管理网络接口
- IPC:管理夸进程通讯的访问
- MNT:管理挂载点
- UTS:隔离内核已经版本标识
Cgroups实现这个五种命名空间的管理:
- 资源限制:内存、网络、磁盘、CPU
- 优先级设定:设定哪些进程组使用更大的资源。
- 资源计量:计算资源组使用了多少资源。
- 资源的控制:将进程组执行和挂起。
Docker容器的能力:
- 文件系统的隔离:每一个容器有本身的root文件系统
- 进程隔离:每一个容器都运行在本身的进程环境中
- 网络隔离:容器间的虚拟网络接口和IP地址都是分开的
- 资源隔离和分组:使用cogroup将CPU和内存之类的资源独立分配给每个Docker容器sql
因为docker的安装比较容易这里小编就不在给出,可是这里须要注意:docker对centos7的支持比较好,centos6可能有有些小问题(升级kernel...):
http://www.javashuo.com/article/p-xlupdqno-gc.htmldocker
咱们在安装好Docker CE后,使用docker pull官方镜像的时候速度很是慢,因此须要使用加速器进行加速,配置好加速器后能够很是快速的pull(拉取)Docker官方的镜像。
第一步:注册阿里云帐号:
阿里云帐号注册网址:
https://account.aliyun.com/register/register.htm?spm=5176.166170.765261.21.7150217fkh2EMl&oauth_callback=https%3A%2F%2Fwww.aliyun.com%2Fproduct%2Facr%3Fspm%3D5176.54417.765261.263.db5924592lOt4j
第二步:进入容器镜像服务的管理控制台:
第三步:配置镜像加速器:
例如我如今的操做系统是ubuntu16.04,我须要在/etc/docker文件夹下新建一个名为daemon.json的文件,并将配置信息写进去
当前Docker CE的版本是18.03:
建立daemon.json,并编辑它
将你的专属加速器网址写进去,保存退出:
而后重启docker服务
好了,如今你就能够经过加速器愉快的下载Docker官方镜像了。数据库
有时候使用 Docker Hub 这样的公共仓库可能丌方便(有时候没法访问),用户能够建立一个本地仓库供私人使用,这里使用官方提供的工具 docker-registry 来配置私有库。
docker-registry 是官方提供的工具,能够用于构建私有的镜像仓库。
实战搭建json
#下载registry镜像 [root@xuegod63 ~]# docker pull registry [root@xuegod63 ~]# docker pull busybox #启动registry容器 docker run -d -p 5000:5000 -v /docker/images_repo:/var/lib/registry --name private_registry registry #修改配置 echo '{ "insecure-registries":["192.168.130.101:5000"] }' > /etc/docker/daemon.json #重启docker systemctl restart docker #给busyboxdabianqian打标签 docker tag busybox:latest 192.168.130.101:5000/busybox:latest #将busybox镜像推送到远端 docker push 192.168.130.101:5000/busybox #删除本地全部的busybox镜像 docker rmi 192.168.130.101:5000/busybox docker rmi busybox #从私有仓库中下载busybox镜像 docker pull 192.168.130.101:5000/busybox
若是搭建成功,以上操做都会执行成功。
观察私有库的结构:ubuntu
[root@zy system]# tree /opt/registry/docker/registry/v2/
补充:这里介绍一下,若是是想配置私有库,而且也想配置外部的公共仓库:
编辑/etc/docker/daemon.json:centos
{ "registry-mirrors": [ "https://2lqq34jg.mirror.aliyuncs.com", "https://pee6w651.mirror.aliyuncs.com", "https://registry.docker-cn.com", "http://hub-mirror.c.163.com" ], "dns": ["8.8.8.8","8.8.4.4"], "insecure-registries":["192.168.172.128:5000"] }
根据以上的模板进行修改,小编尝试过编辑/etc/deaful/docker:
DOCKER_OPTS="--insecure-registries 192.168.130.130:5000"
可是好像不起做用!
#镜像操做
在docker Hub 官方仓库中搜索镜像
[root@test ~]# docker search image_name(mysql)
注意:
获取镜像
[root@test ~]# docker pull busybox
获取特定版本的镜像
[root@test ~]# docker pull ubuntu:14.04
查看本地镜像信息
[root@test ~]# docker images
给已有镜像打标签
[root@test ~]# docker tag busybox busybox:latests
删除镜像
[root@test ~]# docker rmi image/tag
注意:若是有镜像是经过此镜像打标签的,则只是删除了这个标签而已,不影响镜像自己。固然,若是本地这个镜像只有一个标签的话,执行删除操做,将会删除此镜像文件。
若是这里有镜像已经在运行容器,强制删除
[root@test ~]# docker rim -f image_name
建立镜像之基于已有的镜像容器建立(接下来是一组操做)
[root@test ~]# docker run -ti test /bin/sh #运行并进入容器 sh-4.2$ touch test.txt #在容器中进行修改操 sh-4.2$ exit #退出容器 [root@test ~]# docker ps -a #查看全部容器
记住此容器的ID
[root@test ~]# docker commit -m "add a new file " -a "zy" 容器ID 镜像名 #提交镜像
建立镜像之导入本地模板
[root@test ~]# cat ubuntu-14.04-x86_64-minimal.tar.gz |docker import - ubuntu:14.04
存出和载入镜像
[root@test ~]# docker save -o test.tar image_name #将镜像存出到本地 [root@test ~]# docker load --input test.tar #将存出的镜像导入docker仓库
上传镜像(将镜像上传到远端仓库)
[root@test ~]# docker push image_name #注意这里须要实现登陆镜像仓库,若是有本身的私有仓库,可使用 [root@test ~]#docker push ip:port/仓库路径/image:tag
建立容器
[root@test ~]# docker create -it 镜像名
查看容器
[root@test ~]#docker ps -a
新建并启动容器
[root@test ~]# docker run 镜像名 /bin/echo ‘hello world’ 上一句命令会执行的操做: 检查本地是否存在指定的镜像,不存在就从共享仓库下载 利用镜像建立并启动一个容器 分配一个文件系统,并在只读的镜像层外挂载一层可读可写层 从宿主机配置的网桥接口中桥接一个虚拟接口到容器 从地址池配置一个IP给容器 执行用户指定的程序 执行完毕后容器被终止
启动一个容器并执行终端
[root@test ~]# docker run -it centos /bin/bash -t 选项是让docker分配一个伪终端并绑定到容器,-i 则是让容器的标准输入保持打开。
守护态运行
[root@test ~]# docker run -d -h hostname centos /bin/bash -c "exec command"
查看容器日志
[root@test ~]# docker log 容器ID #获取容器的输出信息
终止容器
[root@test ~]# docker stop -t 100 容器ID # -t 是多久后终止容器
启动容器
[root@test ~]# docker start 容器ID
启动并进入一个容器
[root@test data]# docker start -it 容器ID
进入容器
[root@test ~]# docker run -t -i -h hostname 镜像名 /bin/bash #方法一(建立并进入容器) [root@test ~]#docker attach 容器名 #方法二 (attach,进入已启动的容器) [root@test ~]# docker exec -ti 容器ID/容器名 /bin/bash #方法三 (exec进入已启动的容器)
删除容器
[root@test ~]# docker rm [option] container [root@test ~]#docker rm 容器ID #删除一个终止的容器 [root@test ~]#docker rm -f 容器ID #删除一个正在运行的容器
注意:
导出容器
[root@test ~]# docker export 容器ID > centos_for_run.tar
导入容器
[root@test ~]# cat centos_for_run.tar |docker import - centos:v1.0
docker容器的生命周期:
从官方仓库中查找镜像
[root@test ~]# docker search centos
从官方仓库中下载镜像当本地仓库
[root@test ~]# docker pull centos
建立和使用私有仓库
安装docker后,能够经过官方提供的registry镜像来简单搭建一套本地私有仓库环境 [root@test ~]# docker pull registry [root@test ~]#docker run -d -p 5000:5000 registry 注意:上述命令,会后台启动一个registry容器,建立本地的私有仓库服务。 默认状况下,仓库将会放入/tmp/registry目录下,这样容器容易被删除。因此经过-v参数,指定镜像存放的目录。 [root@test ~]#docker run -d -p 5000:5000 -v /docker/images_repo registry #此时在本地将启动一个私有仓库服务,监听端口为5000 [root@test ~]#curl 127.0.0.1:5000/v1/search #访问私有仓库
小编这里只是简单的将registry私有仓库搭建完成,并无测试,若是你们有疑问能够查看https://blog.csdn.net/tellmewhyto/article/details/80822188 这个大神写的博客。固然若是以为registry简单的私人仓库知足不了需求,可使用harbor企业级的私人仓库,这里小编也有介绍:http://www.javashuo.com/article/p-haetltkg-cw.html
固然最后介绍一下搭建私人仓库的好处:
- 节约带宽
- 能够本身定制系统
- 对于微服务的发布和使用,也就是对运维部署,提供了便捷。
用户在使用docker的过程当中,每每须要能查看容器内应用产生的数据,或者须要把容器内的数据进行备份,甚至多个容器之间进行数据的共享,这必然涉及容器的数据管理操做:数据卷、数据卷容器。
数据卷的使用,相似于Linux下对目录或者文件进行mount操做。数据卷是一个可供容器使用的特殊目录,他绕过文件系统,能够提供不少的有用特性:
- 数据卷能够在容器之间共享数据和重用
- 对数据卷的修改会马上生效
- 对数据卷的更新,不会影响镜像
- 数据卷会一直存在,直到没有容器为止
对数据卷的操做
[root@test ~]#docker run -d --name web -v /data centos #在容器中建立一个数据卷 [root@test ~]# docker run -d --name web1 -v /docker/data:/webapp centos #挂载一个主机目录做为数据卷 注意: - 本地目录的路径必须是绝对路径,若是目录不存在docker会自动建立。 - ‘-v’后面的参数为:宿主机文件/目录:容器里对应的文件/目录 [root@test ~]# docker run -d --name web1 -v /docker/data:/webapp:or centos 上面的/docker/data:/webapp:'or' 默认状况下是rw,加了ro以后容器内挂载的数据卷的数据就没法修改了。
若是用户须要在容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。数据卷容器其实就是一个普通的容器,专门用他提供数据卷供其余容器挂载使用。
容器卷容器的操做(实现多个容器之间的数据共享)
#首先,建立一个数据卷容器dbdata ,并在其中建立一个数据卷挂载到/dbdata: [root@test data]# docker run -it -v /dbdata --name dbdata centos #此时在这个容器中就会出现一个/dbdata目录。 #在其余容器中使用--volumes-from 来挂载dbdata容器中的数据卷: [root@test data]# docker run -it --volumes-from dbdata --name db1 centos [root@test data]# docker run -it --volumes-from dbdata --name db2 centos #此时容器db1和db2都挂载同一个数据卷到相同的/dbdata目录下,三个容器任何一个该目录下的写入,其余的容器均可以看到。 '注意': - 使用--volumes-from参数,所挂载数据卷的容器自身'不须要保持运行状态' - 若是删除了挂载的容器(包括dbdata、db一、db二、)数据卷不会自动删除,若是想删除数据卷,必须在删除最后一个挂载他的容器时,-v指定同时删除关联的容器
能够用数据卷容器对其中的数据卷进行备份,恢复,以实现数据的迁移。
数据备份
[root@test data]# docker run --volumes-from dbdata -v $(pwd):/backup --name worker centos tar cvf /backup/backup.tar /dbdata 解释:首先利用centos镜像建立一个容器worker,使用--volumes-from dbdata 参数来让worker容器挂载dbdata容器中的数据卷; 使用-v $(pwd):/backup 参数来挂载本地的当前目录到worker容器中的/backup目录; 最后worker启动后,使用tar cvf /backup/backup.tar /dbdata将其内容备份到/backup下,既宿主机的当前目录下。
数据恢复
#先建立一个带有数据卷的容器dbdata2 [root@test data]# docker run -v /dbdata --name dbdata2 centos #而后建立另外一个新的容器,挂载dbdata2的容器,并使用tar命令解压备份文件到所挂载的容器目录中: [root@test data]# docker run --volumes-from dbdata2 -v $(pwd):/backup centos tar xvf /backup/backup.tar -C /dbdata
大量的互联网应用服务包括多个服务组件,这每每须要多个容器之间经过网络通讯。Docker目前提供了映射容器端口到宿主机和容器互联机制来将容器内引用服务提供外部网络,以及经过容器互联系统让多个容器之间进行快捷的网络通讯。
在启动容器的时候,若是不指定对应的参数,在容器外部是没法经过网络来访问容器内的服务的。当容器中运行一些服务时,要让外部访问这些应用时,经过-p或者-P 参数指定端口映射,-P参数docker会随机映射一个49000~49900的端口至容器内部开发的网络端口。
以registry 服务为例:
#为服务指定端口
[root@test data]# docker run -d -P registry
#指定具体的端口映射
[root@test data]# docker run -d -p 5000:5000 registry #其中的两个5000,表示:hostPort:containerPort
[root@test data]# docker run -d -p 127.0.0.1:5000:5000 registry #映射到指定地址的指定端口
[root@test data]# docker run -d -p 127.0.0.1:5000:5000/(tcp|udp) registry #指定具体的协议
#查看端口映射 [root@test data]# docker ps [root@test data]# docker logs -f 容器名称 [root@test data]#docker port 容器名
容器将的相互通讯,它会在源和接受容器之间建立一个隧道,接受容器能够看到源容器指定的信息。在链接系统时依据容器的名称来执行,因此在建立容器的时候,使用--name 指定好容器的名称。
实现容器互联
#先建立一个新的数据库容器:
[root@test data]# docker run -d --name db training/postgres
#而后建立一个web容器,并将它链接到db容器:
[root@test data]# docker run -d -P --name web --link db:db trainng/webapp
注意:'--link db:db' :表示'链接容器的名字:此链接的别名'
[root@test data]# docker ps
这样docker就在两个容器之间建立了一个安全隧道,并且不用映射他们的端口到宿主机上。
环境变量
[root@test data]# docker run --rm --name web 2 -link db:db training/webapp env
其中以DB_开头的环境变量hi提供web容器链接掉db容器使用。
更新/etc/hosts
[root@test data]# docker run -t -i --rm --link db:db training/webapp /bin/bash
其中有两个hosts信息,第一个是web,它用本身的容器ID做为主机名
第二个就是db容器的IP和主机名。
DockerFile是由一行行命令语句组成,并支持#开头的注释行。通常而言,DockerFile分为四个部分:基础镜像信息,维护者信息,镜像操做指令,和容器执行指令。
#一个简单的dockerfile #This is DockerFile users the centos image #Version 2 -EDITION 1 #Author zy #Command format: Instruction [argunents/command].. #第一行必须指定基础的镜像信息 FROM centos #维护者信息 MAINTANER docker_user zy@email.com #镜像的操做指令 RUN echo "deb http://archive.centos.com/centos raring main universe ">> /etc /apt/sources.list RUN install -y nginx RUN echo "\n daemon off;">>/etc/nginx/nginx.conf #容器启动的执行指令 CMD /usr/sbin/nginx
#注意:RUN 命令是在image构建时运行的,而CMD是在容器运行时运行的命令 #若是在运行容器是指定了运行的命令 CMD命令则会被覆盖 FROM ubuntu:14.04 MAINTAINER zy 'm18726234267@163.com' RUN echo "Hell World!" RUN apt-get update RUN apt-get install -y nginx #ENTRYPOINT指令 和CMD的不一样就是,若是docker run 不指定 --entrypoint 及时后面有命令,也不会覆盖 ENTRYPOINT [ "/usr/sbin/nginx" ] #ADD src dest 将文件和目录复制到docker镜像中 ,ADD提供了解压缩功能,能够直接解压 .tar 的压缩包 #COPY src dest 单纯的复制文件使用 COPY #VOLUME 为容器添加卷 #WORKDIR 在建立容器时为容器添加工做目录 #ENV key=value 用于设置环境变量 #USER 容器基于什么用户身份运行(默认是root用户) USER nginx #USER uid #USER user:group #USER uid:gid #USER user:gid #EXPOSE 容器的暴露的端口 EXPOSE 80 #ONBUILD 容器触发器,当一个镜像被其余的镜像做为基础镜像建立时执行,会在构建过程当中插入指令 #ONBUILD 的命令,不会再基础镜像中运行,哪个以他做为基础镜像,就在哪个镜像被构建时执行
当编译好dockerfile时,咱们使用dockerfile去构建镜像
[root@test data]# docker build -t build_repo/first_image /tmp/docker_builder 注意:-t是指定镜像的标签,后面是DockerFile所在的路径
具体步骤:
- 从基础镜像运行一个容器
- 执行一条指令(RUN),对容器作出修改
- 执行相似docker commit的操做,提交一个新的镜像层
- 在基于刚刚提交的镜像运行一个新容器
- 在执行dockerfile的下一条指令
- 重复以上的步骤,直至全部指令执行完毕
- 在最后的结尾处,返回最后一个镜像的ID
注意:在使用dockerfile构建镜像时,只会删除中间的构建时运行的容器,不会删除中间层镜像,咱们能够经过中间层镜像的ID,查看每个步骤具体构建的内容。这里每个步骤都使用一个中间镜像的好处时,此时会给这个中间镜像添加缓存,咱们在下次重复构建时,速度很是快。固然咱们也能够不使用之间缓存:docker build --no-cache。或者在dockerfile中设置环境变量:
ENV REFRESH_DATE 2019-4-13,设置缓存的刷新时间。
#查看构建过程:
docker history image。
Docker 经过 cgroup 来控制容器使用的资源配额,包括 CPU、内存、磁盘三大方面,基本覆盖了常 见的资源配额和使用量控制。
cgroup 是 Control Groups 的缩写,是 Linux 内核提供的一种能够限制、记录、隔离过程组所使用 的物理资源(如 cpu、memory、磁盘 IO 等等) 的机制,被 LXC、docker 等不少项目用于实现过程资源 控制。cgroup 将任意过程过行分组化管理的 Linux 内核功能。cgroup 自己是提供将过程过行分组化管 理的功能和接口的基础结构,I/O 或内存的分配控制等具体的资源管理功能是经过这个功能来实现的。
[root@test data]# docker run --help |grep cpu-shares
-c, --cpu-shares int CPU shares (relative weight) 在建立容器时指定容器所使用的 CPU 份额 值。cpu-shares 的值不能保证能够得到 1 个 vcpu 或者多少 GHz 的 CPU 资源,仅仅只是一个弹性的加权值。
默认状况下,每一个docker容器的CPU份额都是1024.单独一个容器的份额是没有意义的,只有在同时运行多个容器时,容器的 cpu 加权的效果才能体现出来。
举例:
两个容器 A、B 的 cpu 份额分别为 1000 和 500。
状况一:A 和 B 正常运行,在 cpu 过行时间片分配的时候,容器 A 比容器 B 多一倍的机会得到 CPU 的时间片。
状况二:分配的结果取决于当时主机和其余容器的运行状态,实际上也没法保证容器 A必定能得到 CPU 时间片。好比容器 A 的过程一直是空闲的,那么容器 B 是能够得到比容器 A 更多的 CPU 时间片的。
总结:cgroups 只在容器分配的资源紧缺时,也就是说在须要对容器使用的资源过行限制时,才会生效。所以,没法单纯根据某个容器的 cpu 份额来肯定有多少 cpu 资源分配给它,资源分配结果取决于同时运行的其余容器的 cpu 分配和容器中过程运行状况。
#分配命令 [root@test data]# docker run -it --cpu-shares 512 centos /bin/bash
CPU的周期控制
docker 提供了--cpu-period(周期)、--cpu-quota 两个参数控制容器能够分配到的 CPU 时钟周期。
--cpu-period:是用来指定容器对 CPU 的使用要在多长时间内作一次从新分配。(指定周期)
--cpu-quota:是用来指定在这个周期内,最多能够有多少时间片段用来跑这个容器。 (指定在这个周期中使用多少时间片)
注意:--cpu-period:默认是0.1s,最大是1s。--cpu-quota:默认是-1,不作控制。
#命令容器过程须要每 1 秒使用单个 CPU 的 0.2 秒时间
[root@test data]#docker run -it --cpu-period 1000000 --cpu-quota 200000 centos /bin/bash
Docker 提供参数-m, --memory=""限制容器的内存使用量。
[root@xuegod63 ~]# docker run -it -m 128m centos
#容器对硬盘的最高写入速度设定为 1MB/s [root@test data]#docker run -it -v /var/www/html/:/var/www/html --device /dev/sda:/dev/sda --device-write-bps /dev/sda:1mb centos /bin/bash