码迷,mamicode.com
首页 > 其他好文 > 详细

部署Docker容器虚拟化平台

时间:2021-02-01 13:01:20      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:网络模式   enabled   创新   F12   创建者   sign   缓存   bash命令   版本号   

1.Docker概述

 1.1Docker概述

  Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用及依赖包到一个可移植的容器中,然后发布到任何流行的linux机器上,也可以实现虚拟化。容器是完全使用沙盒机制,相互之间不会有任何接口(类似iphone的app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架或包装系统。

  扩展:沙盒

  沙盒也叫沙箱,英文sandbox。在计算机领域指一种虚拟技术,且多用于计算机安全技术。安全软件可以先让它在沙盒中运行,如果含有恶意行为,则禁止程序进一步运行,而不会对系统造成任何危害。

  Docker是docColud公司开源的一个基于LXC的高级容器引擎,源代码托管在Github上,基于go语言开发并遵从Apache2.0协议开源。

  Docker让开发者可以打包他们的应用及依赖包到一个可移植的container中,然后发布到任何流行的linux机器上。

  Docker的创新:Docker镜像一次构建,到处运行。(我们经常遇到一些软件在一个系统平台上可以使用在另一个平台系统上不能使用的情况,如office2016在XP系统上不能使用,在win7或更高版本的windows系统上可以正常使用,又如googe浏览器以后4.9版本就只能在win7或更高版本的windows系统上可以正常使用。mk.rpm在redhat系列的Linux上运行,但是不能在其他的linux版本上运行等)

  扩展:

  LXC为Linux Container的简写。Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。

  LXC主要通过来自kernel的namespace实现每个用户实例之间的相互隔离,通过cgroup实现对资源的配额和度量。

  Docker的官网:https://www.docker.com

技术图片

  理解:docker服务相当于鲸鱼,container容器就是集装箱。

  container:集装箱,容器

  docker:码头工人

  docker源代码:https://github.com/moby/moby

  扩展:

  集装箱是海上运货的一个创新

技术图片

 

 1.2 Docker容器技术与虚拟机对比

  相同点:docker容器技术和虚拟机技术,都是虚拟化技术。

技术图片

  总结:相对于VM虚拟机,docker少了虚拟机操作系统这一层,所以docker效率比虚拟机高,docker在上启动一个实例一般只要几秒钟

 1.3 Docker架构

技术图片

  工作流程:服务器A上运行docker Engine服务,在docker Engine上启动很多容器container,从外网Docker Hub上把image操作系统镜像下载下来,放到container容器运行。这样一个容器的实例就运行起来了。

  最后,通过Docker client对docker容器虚拟化平台进行控制。

  dockerhub:dockerhub是docker官方的镜像存储站点,其中提供了很常见的镜像供用户下载,如ubuntu,centos等系统镜像。通过dockerhub用户也可以发布自己的docker镜像,为些用户需要注册一个dockerhub的账号,在网站上创建一个docker仓库。

  Docker核心技术

  1.Namespace 实现Container的进程、网络、消息、文件系统和主机名的隔离。

  2.Cgroup 实现对资源的配额和度量。

  注:Cgroup的配额,可以指定实例使用的CPU的个数,内存大小等,就如下图,vmware虚拟机中的硬件配置参数。

技术图片

 

 1.4 Docker特性

  文件系统隔离:每个进程容器运行在一个完全独立的根文件系统里。

  资源隔离:系统资源,像CPU和内存等可以分配到不同的容器中,使用cgroup。

  网络隔离:每个进程容器运行在自己的网络空间,虚拟接口和IP地址。

  日志记录:Docker将会收集和记录每个进程容器的标准流(stdout/stderr/stdin),用于实时检索和批量检索。

  变更管理:容器文件系统的变更可以提交到新的镜像中,并可重复使用以创建更多的容器。无需使用模板或手动配置。

  交互式shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上,例如运行一个一次性交互shell。

  Docker的优点:

  1.一些优势各VM一样,但是不是所有都一样。

  比VM小,比VM快,Docker容器的尺寸减小相比整个虚拟机大大简化了分布到云和从云分发时间和开销。Docker启动一个容器实例的时间很短,一两秒就可以启动一个实例。

   2.对于在笔记本电脑,数据中心的虚拟机,以及任何的云上,运行相同的没有变化的应用程序,IT的发布速度更快。

  Docker是一个开放的平台,构建,发布和运行分布式应用程序。

  Docker使应用程序能够从组件组装和避免开发与生产环境之间的摩擦。

  3.可以在部署在公司局域网和云或虚拟机上使用它。

  4.开发人员并不关心具体哪个Linux操作系统。

  使用Docker,开发人员可以根据所有的依赖关系构建相应的软件,针对他们所选择的操作系统。

  然后,在部署时一切是完全一样的,因为一切都在DockerImage的容器上运行。

  开发人员负责并且能够确保所有的相关性得到满足。

  5.Google、微软、亚马逊,IBM等都支持Docker。

  6.Docker支持Unix/Linux操作系统,也支持Windows或Mac

技术图片

 

   Docker的缺点局限性:

  1.Docker用于应用程序是最有用的,但并不包含数据。日志,跟踪和数据库等通常应放在Docker容器外。一个容器的镜像通常很小,不适合存大量数据,存储可以通过外部挂载的方式使用。比如使用:NFS,ipsan,MFS等,-v映射磁盘分区。

  一句话:docker只用于计算,存储交给别人

  oracle 不适合使用 docker来运行,太大了,存储的数据太多。

 1.5 Docker版本的简单介绍

  docker有以下3种安装方式:

  yum install docker

  yum install docker-engine

  yum install docker-ce

  说明:

  Docker最早的版本名是docker和docker-engine,现在的名字是docker-ce和docker-ee

  2017年年初,docker公司将原先的docker开源项目改名为moby。

  moby是继承了原先的docker的项目,是社区维护的开源项目,谁都可以在moby的基础上打造自己的容器产品。

  docker-ce是docker公司维护的开源项目,是一个基于moby项目的免费的容器产品。

  docker-ee是docker公司维护的闭源产品,是docker公司的商业产品。

  注:moby是源代码,docker-ce和docker-ee是容器产品,是rpm包。

  所以现在我们经常使用到的是版本是docker-ce版本。

2. 部署docker容器虚拟化平台并配置docker镜像加速地址

 2.1 实验环境准备

  实验1:部署docker容器虚拟化平台

  实验环境:CentOS7.6   64位  IP:172.20.77.201

  安装docker环境依赖

  [root@server ~]# yum install -y yum-utils device-mapper-persistent-data lvm2

  配置国内docker的yum源(阿里云)

  [root@server ~]# wget -O /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

  安装docker-ce

  [root@server ~]# yum install -y docker-ce docker-cli containerd.io

  注:docker-ce-cli 作用是docker命令行工具包。

  containerd.io作用是容器接口相关包。

  yum info软件包的命令,可以查看一个包的具体作用。

  启动docker并加入开机启动项

  [root@server ~]# systemctl start docker&&systemctl enable docker

  [root@server ~]# docker version  #显示docker版本信息

  [root@server ~]# docker info  #查看docker信息(确认服务运行)显示docker系统信息,包括镜像和容器数。  

  Server:
  Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
  Images: 0
  Server Version: 19.03.12
  Storage Driver: overlay2
  Backing Filesystem: xfs

  .......

  Name: server.com
  ID: SSLG:MZG6:THPP:GWBN:7BYC:33KD:PS2G:NGWL:NMN7:S4UL:7LSN:GTQW
  Docker Root Dir: /var/lib/docker  #默认的docker的家目录,后期镜像也在这个目录下
  Debug Mode: false
  Registry: https://index.docker.io/v1/  #默认去这个index.docker.io/v1/网站找docker镜像

 2.2下载docker镜像

  技术图片

 

 

   搜索镜像images

  [root@server ~]# docker search centos  #从Docker Hub中搜索符合条件的镜像。

  技术图片

 

   星数反映受欢迎的程度,如果OFFICIAL为【OK】,说明为官方提供可以放心使用。

  下载镜像方法:

  方法1.从公网docker hub拉取(下载)image  pull:拉 

  [root@server ~]# docker pull centos
  Using default tag: latest
  latest: Pulling from library/centos
  6910e5a164f7: Pull complete
  Digest: sha256:4062bbdd1bb0801b0aa38e0f83dece70fb7a5e9bce223423a68de2d8b784b43b
  Status: Downloaded newer image for centos:latest
  docker.io/library/centos:latest

  #如果因为网络问题下载报错了,可以选择换一个dokcer镜像下载地址

  方法2:使用阿里云docker镜像加速器,提升pull的速度:

  你只需要登录容器Hub服务 https://cr.console.aliyun.com的控制台,使用你注册的阿里云账号,第一次登录时,需要设置一个独立的密码,左侧的加速器帮助页面就会显示为你独立分配的加速地址。  

  技术图片

 

 

   网易镜像:

  https://c.163.com/hub#/m/home/  #需要先注册登录上,才能打开此站点

技术图片

 

 

   创建配置文件daemon.json

  [root@server ~]# vi /etc/docker/daemon.json  #需要手动创建daemon.json文件。

写入以下内容:  

  {
  "registry-mirrors":["https://hab0i5dh.mirror.aliyuncs.com"]
  }

  镜像源可以添加多个,根据自己的网络环境选择速度快的。

  [root@server ~]# vi /etc/docker/daemon.json  #在文件中插入 

  {
  "registry-mirrors":["https://dockerhub.azk8s.cn","http://hub-mirror.c.163.com""https://hab0i5dh.mirror.aliyuncs.com"]
  }

  说明:azk8s.cn 这域名是上海蓝云网络科技有限公司的。

  上海蓝云网络科技有限公司成立于2013年3月,由世纪互联专门为在中国境内提供Windows Azure和Office365服务而成立,为世纪互联的全资子公司  

  [root@server ~]# systemctl daemon-reload
  [root@server ~]# systemctl restart docker

  [root@server ~]# docker info

  ......

  Registry Mirrors:
  https://dockerhub.azk8s.cn/      #上海蓝云镜像源
  http://hub-mirror.c.163.com/      #网易镜像源
  https://hab0i5dh.mirror.aliyuncs.com/  #阿里云镜像源
  Live Restore Enabled: false

  方法3:把以前下载好的image镜像导入image:

  把docker-centos-httpd.tar 镜像上传到linux上

  参数: -i docker-centos-httpd.tar 指定载入的镜像归档。

  [root@server ~]# docker load -i /root/docker-centos-httpd-image.tar

  方法4:直接下载其它站点镜像

  [root@server ~]# docker pull hub.c.163.com/library/tomcat:latest

  总结:下载docker镜像的4种方法

  1、docker pull  直接下载

  2、配置成阿里、网易、蓝云的docker加速地址

  3、直接导入本地的docker镜像

  4、直接下载其它站点的镜像  

       

  查看到下载到本地的镜像images列表

  [root@server ~]# docker images  #列出本地所有镜像。其中[name]对镜像名称进行关键词查询。
  REPOSITORY            TAG      IMAGE ID       CREATED       SIZE
  cent                              httpd-v2    79d4dad2805d        7 days ago      317MB
  centos              latest      831691599b88     5 weeks ago    215MB
  hub.c.163.com/library/tomcat    latest      72d2be374029      2 years ago       292MB

  注:docker镜像相当于对程序+程序依赖的库打了一个包

  软件是依赖操作系统中的库或二进制文件。如果我把软件所依赖的库和二进制文件打包在一起发布,不用物理机系统上的文件,也就不依赖操作系统了。

 2.3 开启网络转发功能

  开户网络转发功能,默认会自动开启。

  手动开启:

  [root@server ~]# vi /etc/sysctl.conf  #插入以下内容

  net.ipv4.ip_forward = 1

  [root@server ~]# sysctl -p  #生效

  net.ipv4.ip_forward = 1

  [root@server ~]# cat /proc/sys/net/ipv4/ip_forward

  1

  否则,docker启动实例时,会报错以下警告:

  [root@server ~]# docker run -it centos:latest /bin/bash
  WARNING: IPv4 forwarding is disabled. Networking will not work.

  [root@server ~]# systemctl stop firewalld && systemctl disable firewalld  #关闭防火墙

  [root@server ~]# systemctl restart docker  #关了防火墙,要把docker服务重启一下,不然docker的ip包转发功能无法使用。即使防火墙关了,docker依然会调用内核模块netfilte增加规则,所以有防火墙规则。

 2.4 docker平台的基本使用方法

   1.运行一个container并加载镜像centos,运行起来这个实例后,在实例中执行/bin/bash命令

  docker 常用参数:

  run  运行

  -i  以交互模式运行容器,通常与-t同时使用;

  -t  为容器重新分配一个伪终端,通常与-i同时使用;

  [root@server ~]# docker images  
  REPOSITORY            TAG      IMAGE ID       CREATED       SIZE
  centos              latest      831691599b88     5 weeks ago    215MB 

  [root@server ~]# docker run -it centos:latest bash  #启动一个实例,也就2秒左右
  [root@44087d4632cf /]# ls  #查看实例环境
  bin etc lib lost+found mnt proc run srv tmp var
  dev home lib64 media opt root sbin sys usr
  [root@44087d4632cf /]# cat /etc/redhat-release  #查看实例centos的版本
  CentOS Linux release 8.2.2004 (Core)
  [root@44087d4632cf /]# exit  #退出容器

  2.在container中启动一个长久运行的进程,不断向stdin输出hello world。模拟一个后台运行服务

  docker常用参数:

  -d  后台运行容器,并返回容器ID

  -c  后面跟待完成的命令  

  [root@server ~]# docker run -d centos:latest /bin/bash -c "while true;do echo hello world;sleep 1;done"
  5735dd82dc879fecd653acabaee40bd6df129c58dc16b77e9625d680f13eb2de  #容器的ID

  从一个容器中取日志,查看输出的内容,可用于后期检查docker实例在标准输出中弹出的错误信息或正常的信息。

  命令语法: docker logs 容器实例的Name/ID

  [root@server ~]# docker logs 5735dd82dc879  #容器的ID可以写全,也可以不写全,只要唯一就行
  hello world
  hello world
  hello world
  hello world

  查看正在运行的容器:

  [root@server ~]# docker ps  #列出所有正在运行中的容器

  技术图片

 

   也可以使用短ID或docker实例的名字查看日志输出:

  [root@server ~]# docker logs 5735dd82dc87

  或

  [root@server ~]# docker logs eager_hellman

  [root@server ~]# docker ps -a  #-a列出所有容器(包含沉睡/退出状态的容器)

  技术图片

 

   3.杀死一个容器。比如:杀死一个正在后台运行的容器

  查看要杀死的容器的ID:

  [root@server ~]# docker ps -a  技术图片

  杀死ID为5735dd82dc87的容器

  [root@server ~]# docker kill 5735dd82dc87

  5735dd82dc87

  查看结果:

  [root@server ~]# docker ps

  CONTAINER ID    IMAGE    COMMAND    CREATED    STATUS    PORTS    NAMES

  4.启动、停止、重启container容器实例

  [root@server ~]# docker run -d centos:latest /bin/bash -c "while true;do echo hello world;sleep 1;done"

  0d3ef5eb705f676da32090dfa8ac0aad6e88a67d9200b3c1c4469d84bbb93dda

  [root@server ~]# docker ps  #查看容器

  CONTAINER ID   IMAGE      COMMAND        CREATED      STATUS        PORTS NAMES
  0d3ef5eb705f    centos:latest   "/bin/bash -c ‘while…"   27 seconds ago    Up 26 seconds     affectionate_cori

  [root@server ~]# docker stop 0d3ef5eb705f  #关闭容器

  0d3ef5eb705f

  [root@server ~]# docker ps  #查看容器
  CONTAINER ID   IMAGE   COMMAND    CREATED   STATUS    PORTS NAMES

  [root@server ~]# docker start 0d3ef5eb705f  #启动容器

  0d3ef5eb705f

  [root@server ~]# docker restart 0d3ef5eb705f  #重启容器

  0d3ef5eb705f

  删除指定容器container:rm  

  [root@server ~]# docker rm 0d3ef5eb705f
  Error response from daemon: You cannot remove a running container 0d3ef5eb705f676da32090dfa8ac0aad6e88a67d9200b3c1c4469d84bbb93dda. Stop the container before attempting removal or force remove

  解决办法:先把容器0d3ef5eb705f关闭然后再删除,或者加-f强制删除  

  [root@server ~]# docker rm -f 0d3ef5eb705f
  0d3ef5eb705f

 2.5 docker 镜像的制作方法

  Docker Image的制作方法:

  方法1:docker commit  #保存container的当前状态到image后,然后生成对应的image

  方法2:docker build  #使用Dockerfile文件自动化制作image

 2.5.1 方法1:docker commit 创建一个安装好apache web服务器的容器镜像

  [root@server ~]# docker run -it centos:latest /bin/bash

  [root@3dcd9a9b467c /]# yum -y install httpd  #在container中安装apache软件包

  [root@3dcd9a9b467c /]# exit

  [root@server ~]# docker images

  REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE  

  centos           latest     831691599b88  5 weeks ago    215MB  #当前中有一个image centos

  根据容器当前状态做一个image镜像:创建一个安装了apache的centos镜像

  语法:docker commit <container的ID>  <新的image_name>

  例:

  查看容器ID:

  [root@server ~]# docker ps -a

  CONTAINER ID    IMAGE      COMMAND    CREATED

  3dcd9a9b467c    centos:latest   "/bin/bash"    11 minutes ago

  [root@server ~]# docker commit 3dcd9a9b467c centos:httpd

  sha256:a460b81d2b70c9c72bae6fce8b93baaa70743130d86477d45ffa691b4668126f

   [root@server ~]# docker images

  REPOSITORY                   TAG                 IMAGE ID            CREATED              SIZE

  centos                           httpd               a460b81d2b70        About a minute ago   255MB

  centos                           latest              831691599b88        5 weeks ago              215MB

  使用新创建centos:httpd镜像,生成一台容器实例:

  [root@server ~]# docker run -it centos:httpd /bin/bash

  [root@eaf8b8fda890 /]# rpm -qa httpd  #查看是否己经安装好httpd命令
  httpd-2.4.37-21.module_el8.2.0+382+15b0afa8.x86_64  #说明是基于centos:httpd镜像创建的容器成功

 2.5.2 使用docker build创建镜像

  通过docker build创建一个基于centos的httpd web服务器镜像。

  使用docker bulid创建镜像时,需要使用Dockerfile文件自动化制作image镜像

  注:Dockerfile有点像源码编译时的./configure后生成的Makefile

  1.创建工作目录

  [root@server ~]# mkdir /docker-build
  [root@server ~]# cd /docker-build/
  [root@server docker-build]# touch Dockerfile  #make自动化编译时需要Makefile文件,自动化创建docker镜像时,需要Dockerfile

  2.编辑Dockerfile

  Dockerfile用来创建一个自定义的image,包含了用户指定的软件依赖等。 

  FROM centos:7.6.1810  #FROM基于哪个镜像
  MAINTAINER <root@server.com>  #MAINTAINER 镜像创建者
  RUN yum install -y httpd  #RUN 安装软件用
  ADD start.sh /usr/local/bin/start.sh  #ADD将文件<src>拷贝到新产生的镜像的文件系统对应的路径。所有拷贝到新镜像中的文件和文件夹权限为0755,uid和gid为0
  ADD template /var/www/html
  CMD /usr/local/bin/start.sh  #当docker实例启动成功后,会执行CMD后面的命令。所以CMD后面一般跟需要开机启动的服务或脚本。一个Dockerfile中只能有一条CMD命令,多条则只执行最后一条CMD

  3.创建start.sh脚本启动httpd服务和apache默认首页index.html文件

  [root@server docker-build]# echo "/usr/sbin/httpd -DFOREGROUND" > start.sh
  [root@server docker-build]# chmod a+x start.sh

   上传站点模板

  [root@server ~]# rz

  技术图片

 

  #解压模板

  [root@server ~]# unzip -d /docker-build/ /root/template.zip

  4.使用命令build来创建新的image

  语法:docker build -t 父镜像名:镜像的tag  Dockerfile文件所在的路径  

  -t:表示tage,镜像名

  使用命令docker build来创建新的image,并命名为centos:httpd

  [root@server ~]# cd /docker-build/

  [root@server docker-build]# docker build -t centos:httpd-v1 ./

  注:./表示当前目录。另外你的当前目录下要包含Dockerfile

  Sending build context to Docker daemon 1.198MB

  Step 1/6 : FROM centos:7.6.1810
  ---> f1cb7c7d58b7
  Step 2/6 : MAINTAINER <root@server.com>
  ---> Running in e5027216fba2
  Removing intermediate container e5027216fba2
  ---> 5d74c4e1d4d6
  Step 3/6 : RUN yum install -y httpd
  ---> Running in 84f1dd43cf82
  Loaded plugins: fastestmirror, ovl

  ........

  Step 4/6 : ADD start.sh /usr/local/bin/start.sh

  ---> d668532981bb
  Step 5/6 : ADD template /var/www/html
  ---> 6d61a775761d
  Step 6/6 : CMD /usr/local/bin/start.sh
  ---> Running in 28ce42ce8449
  Removing intermediate container 28ce42ce8449
  ---> 84875768c29a
  Successfully built 84875768c29a
  Successfully tagged centos:httpd-v1

  查看image列表

  [root@server docker-build]# docker images
  REPOSITORY   TAG           MAGE ID      CREATED     SIZE
  centos         httpd-v1   84875768c29a    7 minutes ago    321MB

  注:docker镜像主要包含的内容有:应用/程序+库/依赖关系包

 2.5.3 Docker Image的发布:

  方法1:save image to  TarBall

  保存Image到tar包

  语法:docker save -o 导出的镜像名.tar  本地镜像名:镜像标签  

  [root@server docker-build]# docker save -o docker-centos-httpd-image.tar centos:httpd-v1
  [root@server docker-build]# ll -h docker-centos-httpd-image.tar
  -rw-------. 1 root root 315M Aug 3 03:07 docker-centos-httpd-image.tar 

  测试:删除镜像centos:httpd-v1并导入刚刚创建的本地镜像docker-centos-httpd-image.tar

  [root@server ~]# docker rmi centos:httpd-v1

  [root@server ~]# docker images  #查看镜像发现己删除

  [root@server ~]# cd /docker-build/

  [root@server docker-build]# docker load -i docker-centos-httpd-image.tar  #导入本地镜像

  [root@server ~]# docker images  #查看镜像发现前删除centos:httpd-v1又回来了

  方法2:Push Image To Docker Hub  发布到外网

  1、Signup on docker hub&create repo  注册一个账号

  http://hub.docker.com/

  2、Login to docker hub  登录Docker hub网站

  #docker login -u username -p password username@gmail.com

  3、Push image to  docker hub  #上传镜像

  #docker push centos:httpd

  4、Pull image from docker hub  #下载镜像

  #docker pull username/centos:httpd-v1  #用户名/镜像名

 2.6 Container容器端口映射

  [root@server ~]# iptables -F
  [root@server ~]# systemctl restart docker
  [root@server ~]# docker run -d -p 80:80 centos:httpd-v1
  1e3d001cf922442001181d989a8821629decbb4cd1f743a04d7885cc17071d6b

  注:-p 物理机的80端口:容器实例的80端口,把容器中的80端口映射到物理机上的80端口

  在物理机上查看容器状态:

  [root@server ~]# docker ps

  CONTAINER ID    IMAGE      COMMAND        CREATED       STATUS       PORTS       NAMES
  1e3d001cf922      centos:httpd-v1    "/bin/sh -c /usr/loc…"   4 minutes ago   Up 4 minutes    0.0.0.0:80->80/tcp   sleepy_meninsky

  查看物理机上开启的80代理端口

  [root@server ~]# netstat -atunp|grep 80

  tcp6       0      0 :::80                   :::*                    LISTEN      24782/docker-proxy

   测试网站:http://172.20.77.201

技术图片

   注:现在docker实例运行的网络模式类似于VMware的NAT模式。

  访问正在运行的container容器实例

  语法:docker exec -it <containerid|name> /bin/bash

  查看正在运行的容器ID:

  [root@server ~]# docker ps

  CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES

  1e3d001cf922        centos:httpd-v1     "/bin/sh -c /usr/loc…"   17 minutes ago      Up 17 minutes       0.0.0.0:80->80/tcp   sleepy_meninsky  

  [root@server ~]# docker exec -it 1e3d001cf922 /bin/bash  #进入容器
  [root@1e3d001cf922 /]# echo "hello world" > /var/www/html/test.html  #创建test.html文件
  [root@1e3d001cf922 /]# exit
  exit
  [root@server ~]# curl http://172.20.77.201/test.html  #物理机上测试查看新添加的test.html文件
  hello world

  查看物理机和容器的网络:

  查看容器的IP:

  [root@server ~]# docker exec -it 1e3d001cf922 /bin/bash

  [root@1e3d001cf922 /]# yum install -y net-tools

  [root@1e3d001cf922 /]# ifconfig

  eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
    inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255    

  物理机的IP: 

  [root@server ~]# ifconfig
  docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
    inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
  注:相当于虚拟机NAT网络模式

  测试网络:  

  [root@server ~]# ping 172.17.0.2
  PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
  64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.111 ms

  单台docker的网络结构如下:

 技术图片

3.docker容器命名和资源配额控制

 3.1 docker容器命名和重命名

  容器命名语法:docker run -d --name 容器实例名 容器镜像名 要执行的命令

  容器重命名语法:docker rename 旧容器名 新容器名

  例1:运行一个名字为docker1 的容器

  [root@server ~]# docker run -itd --name docker1 centos:7.6.1810 /bin/bash

  9a9f745b5f8c0e5d25584754345ab3b65953aed2453cf5c58613b79e1409842a

  注:如本地无 centos:7.6.1810的镜你,会自动下载

  [root@server ~]# docker ps  #查看运行的docker镜像

  CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

  9a9f745b5f8c        centos:7.6.1810     "/bin/bash"         3 minutes ago       Up 3 minutes                                docker1

     例2:将docker1重命名为docker2

  [root@server ~]# docker rename docker1 docker2
  [root@server ~]# docker ps

  CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

  9a9f745b5f8c        centos:7.6.1810     "/bin/bash"         6 minutes ago       Up 6 minutes                               docker2

 3.2 创建docker容器实例时指定容器的主机名

  语法:docker run -it --name 容器名 -h 指定主机名 镜像 /bin/bash

  例1:  

  [root@server ~]# docker run -it --name docker3 -h docker66.com centos /bin/bash

  注:centos镜像代表centos:latest,没有指定tag标签,默认为latest
  [root@docker66 /]# hostname  #查看主机名
  docker66.com

  [root@docker66 /]# exit

  设置docker容器开机自动启动

  语法:docker run --restart=always -itd --name 容器名 镜像 /bin/bash

  参数:--restart=always  #在容器退出时总是重启容器。

  例:

  [root@server ~]# docker run --restart=always -itd --name test1 centos /bin/bash

  c3f1c501b664518bc321be85ba7ef39dd1823a1aeeee8bdbc3fa8754ea4928b8

  [root@server ~]# systemctl restart docker

  [root@server ~]# docker ps

  CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

  c3f1c501b664          centos                "/bin/bash"            23 minutes ago      Up About a minute                       test1

  扩展:

  Docker容器的重启策略如下:

  no,默认策略,在容器退出时不重启容器

  on-failure,在容器非正常退出时(退出时状态非0),才会重启容器

  on-failure:3,在容器非正常退出时重启容器,最多重启3次

  always,在容器退出时总是重启容器

  unless-stopped,在容器退出时总是重启容器,但是不考虑在docker守护进程启动时就己经停止了的容器。

  

  如果创建时未指定--always,可通过update命令来更新设置

  语法:docker update --restart=always 容器ID或名字

  [root@server ~]# docker run -itd --name test8 centos /bin/bash

  411b1e52afde2f784ae27c5cd89f461904e6470cbe5f46978ecdc31c0958280f
  [root@server ~]# docker update --restart=always test8
  test8
  [root@server ~]# systemctl restart docker  #重启docker服务
  [root@server ~]# docker ps|grep test8  #设置了开机启动的docker实例会启动,说更新设置成功了

  411b1e52afde        centos              "/bin/bash"         About a minute ago   Up 39 seconds

 3.3 docker容器资源配额控制之CPU

  Docker通过cgroup来控制容器使用的资源配额,包括CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制。

  cgroup概述:

  cgroup是Control Groups的缩写,是Linux内核提供的一种可限制、记录、隔离进程给所使用的物理资源(如CPU、内存、磁盘IO等等)的机制,被LXC、docker等很多项目用于实现进程资源控制。cgroup将任意进程进行分组化管理的Linux内核功能。cgroup本身是提供将进程进行分组化管理的功能和接口基础结构,IO或内存的分配控制等具体的资源管理功能是通过这个功能来实现的。

  为什么要进行硬件配额?

  当多个容器运行时,防止某容器把所有的有一硬件资源都占用了。(比如一台被黑的容器,有可能把所有的资源都占用)

 3.3.1 指定docker容器可以使用的cpu配额

  例:给容器实例分配512权重的cpu配额

  [root@server ~]# docker run --help|grep cpu-shares

   CPU配额参数:-c, --cpu-shares int                 CPU shares (relative weight) 在创建容器时指定容器所使用的CPU配额值。cpu-shares的值不能保证可以获得1个vcpu或者多少GHz的CPU资源,仅仅只是一个弹性的加权值。

  默认每个docker容器的cpu配额值都是1024.在同一个CPU核心上,同时运行多个容器时,容器的CPU加权效果才能体现出来。

  例:两个容器A、B的CPU配额分别为1000和500,结果会怎么样?

  情况1:A和B正常运行,在cpu进行时间片分配的时候,容器A比容器B多一倍的机会获得CPU的时间片。

  

  情况2:分配的结果取决于当时其它容器的运行状态。比如容器A的进程一直是空闲的,那么容器B是可以获取比容器A更多的CPU时间片的;比如主机上只运行了一个容器,即使它的CPU配额只有50,它也可以独占整个主机的CPU资源。

  cgroups只在多个容器同时争抢同一个CPU资源时,CPU配额才会生效。因此,无法单纯根据某个容器的CPU配额来确定有多少CPU资源分配给它,资源的分配结果取决于同时运行的其他容器的CPU分配和容器中进程运行情况

  例:给容器实例分配512权重的CPU使用配额

  参数:  --cpu-shares 512

  [root@server ~]# docker run -it --cpu-shares 512 centos:7.6.1810 /bin/bash

  [root@9f2faed531ae /]# cat /sys/fs/cgroup/cpu/cpu.shares  #查看容器CPU权重配额
  512

  注:后面我们启动多个容器实例,测试一下是不是只能使用512权重配额的CPU资源。单独一个容器,看不出来使用的CPU的比例。因为没有其它docker实例跟此docker实例竞争。

 3.3.2 CPU core核心控制

   参数:--cpuset可以绑定CPU

  对多核CPU的服务器,docker还可以控制容器运行限定使用哪些cpu内核和内存节点,即使用--cpuset-cpus和--cpuset-mems参数。对具有有NUMA拓扑(具有多CPU、多内存节点)的服务器尤其有用,可以对需要高性能计算的容器进行性能最优的配置。如果服务器只有一个内存节点,则--cpuset-mems的配置基本上不会有明显效果。

  扩展:

  服务器架构一般分为:SMP、NUMA、MPP体系结构介绍

  从系统架构来看,目前的商用服务器大体可以分为三类:

  1、对称多处理器结构(SMP :Symmetric Multi-Processor)例:x86服务器,双路服务器。主板上有两个物理CPU

  2、非一致存储访问结构(NUMA:Non-Uniform Memory Access)例:IBM小型机 pSeries690

  3、海量并行处理结构(MPP:Massive ParallelProcessing)例:IBM大型机 Z14

  为什么要把进程绑定到CPU上?

  注:当CPU数量很多时,确实需要绑定进程到CPU上,这样可以减少CPU上下文切换的开销,节约时间。

 3.3.3  扩展技术taskset命令

  taskset设定CPU亲和力,taskset能够将一个或多个进程绑定到一个或多个处理器上运行。

  参数:

  -c,--cpu-list  以列表格式显示或指定CPU

  -p,--pid    在己经存在的pid上操作

  如:设置只在cpuID是1和2的cpu上运行sshd进程程序。注:第一个cpu的ID是0

  [root@server ~]# ps aux|grep sshd

  root       6628  0.0  0.2 112756  4316 ?        Ss   02:59   0:00 /usr/sbin/sshd -D  

  [root@server ~]# taskset --cpu-list --pid 1,2 6628
  pid 6628‘s current affinity list: 0-3
  pid 6628‘s new affinity list: 1,2

  如:如何查看某个进程在那个cpuID上运行,例如查看的是PID为1的进程

  [root@server ~]# taskset -cp 1
  pid 1‘s current affinity list: 0-3

  例:物理机一共有4个核心,创建的容器只能用0、1、2这3个核心

  [root@server cpuset]# docker run -it --name cpu1 --cpuset-cpus 0-2 centos:7.6.1810 /bin/bash

  [root@345dc56e4239 /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
  0-2
  [root@345dc56e4239 /]# taskset -cp 1
  pid 1‘s current affinity list: 0-2
  [root@345dc56e4239 /]# ps -aux

  USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

  root          1  1.1  0.1  11820  1916 pts/0    Ss   20:33   0:00 /bin/bash

  3.3.4  CPU配额的控制参数的混合使用

  cpu-shares的控制只发生在容器竞争同一个cpu的时间片时有效。

  如果通过cpuset-cpus指定容器A的使用cpu0,容器B只是用cpu1,在主机上只有这两个容器使用对应的内核情况,它们各自占用全部的内核资源,cpu-shares没有明显效果。

    如果要看到cpu-shares的效果,就将容器A和容器B配上cpuset-cpus值并绑定到同一个cpu上,然后同时抢占cpu资源,就可以看出效果

  说明:要测试cpu-shares和cpuset-cpus混合使用运行效果,就需要用到压力测试工具stress来让容器实例把cpu跑满

    如果要把4核心的cpu中的第一和第三核心跑满,可以运行stress然后使用taskset绑定stress到CPU ID为0和2上就可以了

  扩展:stress命令

  概述:linux系统压力测试软件stress。stress可以测试Linux系统cpu/memory/IO/disk的负载。

  stress参数说明:

  -?  显示帮助信息

  -v  显示版本号

  -q  不显示运行信息 

  -n  显示己完成的指令情况

  -t  --timeout  N 指定运行N秒后停止

      --backoff  N 等待N微秒后开始运行

  -c  产生n个进程 每个进程反复不停的计算随机数的平方根,测试cpu

  -i  产生n个进程 每个进程反复调用sync(),sync()用于将内存上的内容写到硬盘上,测试磁盘

  -m  --vm n产生n个进程,每个进程不断调用内存分配malloc()和内存释放free()函数,测试内存

        --vm-bytes B 指定malloc时内存字节数(默认256MB)

        --vm-hang N  指定在free栈的秒数

  -d  --hadd n 产生n个执行write和unlink函数的进程

     --hadd-bytes B指定写的字节数

     --hadd-noclean 不unlink

  注:时间单位可以为秒 s,分 m,小时 h,天 d,年 y,文件大小单位可以为K,M,G 

  安装yum扩展源

  [root@server ~]# yum install -y epel-release

  [root@server ~]# yum install -y stress

   例1:产生2个cpu进程,2个io进程,20秒后停止运行

  [root@server ~]# stress -c 2 -i 2 --verbose --timeout 20s

  技术图片

 

 

   例2:测试cpuset-cpus和cpu-shares混合使用运行效果,通过压力测试工具stress来让容器实例把cpu跑满,当跑满后,观察stress进程会不会跑到其他cpu上运行,如果没有其他cpu上运行,说明cgroup资源限制成功。

  创建两个容器实例:docker10和docker20。让docker10和docker20只运行在cpu0t和cpu1上,最终测试一下docker10和docker20使用的百分。实验拓扑图如下图

  技术图片   

  [root@server ~]# docker run -itd --name docker10 --cpuset-cpus 0-1 --cpu-shares 512 centos:7.6.1810 /bin/bash
  f8b7817baaf44d181eaaff7551eb74287fcb32b7f64082e14647edebb403e188
  [root@server ~]# docker run -itd --name docker20 --cpuset-cpus 0-1 --cpu-shares 1024 centos:7.6.1810 /bin/bash
  282da3cd0534f3804f4a136e962e83ce60960f65fafcf39a214a6411828dadd 

  测试1:进入docker10,使用stress测试进程是不是只在cpu0,1上运行

  [root@server ~]# docker exec -it docker10 /bin/bash
  [root@f8b7817baaf4 /]# yum install -y epel-release  #安装epel扩展yum源

  [root@f8b7817baaf4 /]# yum install -y stress  #安装stress命令

  [root@f8b7817baaf4 /]# stress -c 2 -v -t 10m  #运行2个进程,把两个cpu点满

  在物理机另外一个虚拟终端上运行top命令,按数字1键,查看每个cpu使用情况,如下图所示

技术图片

  测试2:进入docker20,使用stress测试进程是不是只在cpu0,1上运行并且docker20上运行的stress使用cpu的百分比是docker10的2倍

  [root@server ~]# docker exec -it docker20 /bin/bash

  [root@282da3cd0534 /]# yum install -y epel-release

  [root@282da3cd0534 /]# yum install -y stress

  [root@282da3cd0534 /]# stress -c 2 -v -t 10m

  在物理机另外一个虚拟终端上运行top命令,按数字1键,查看每个cpu使用情况,如下图所示,

技术图片

   注:两个容器只在cpu0,1上运行,说明cpu绑定限制成功,而且docker20占用的cpu使用率是docker10的2倍,说明--cpu-shares限制资源成功

 3.3.4  CPU周期的控制

  docker提供了--cpu-period(周期)、--cpu-quota两个参数控制容器可以分配到的CPU时钟周期。

  --cpu-period是用来指定容器对CPU的使用,要在多长时间内做一次秤分配。 指定周期

  --cpu-quota是用来指它在这个周期内,最多可以有多少时间片断来跑这个容器。 指定在这个周期中使用多少的时间片

  跟--cpu-shares不同的,--cpu-period 和--cpu-quotat是指定一个绝对值,而且没有弹性在里面,容器对CPU资源的使用绝对不会超过配置的值。

  cpu-period和cpu-quota的单位为微秒。cpu-period的最小值为1000微秒,最大值为1秒,默认值为0.1秒,cpu-quota的值默认为-1,表示不做控制。

  时间换算单位:1秒=1000毫秒;1毫秒=1000微秒

  例1 .设置docker实例每1秒只能使用单个CPU的0.2秒时间,可以将cpu-period设置为1000000(即1秒),cpu-quota设置为200000(0.2秒)  

  [root@server ~]# docker run -it --cpu-period 1000000 --cpu-quota 200000 centos:latest /bin/bash
  [root@897131ecd3c8 /]# cat /sys/fs/cgroup/cpu
  cpu/ cpu,cpuacct/ cpuacct/ cpuset/
  [root@897131ecd3c8 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_period_us
  1000000
  [root@897131ecd3c8 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
  200000

 3.3.4  docker容器实例运行结束后自动释放资源

  [root@server ~]# docker run --help|grep rm

  参数: -rm  Automatically remove the container when it exits

  作用:当容器命令运行结束后,自动删除容器,自动释放资源

  应用场景:在某些环境下,可能需要大量的新建docker实例,然后仅仅运行几秒钟或几分钟,然后就彻底删除。如运行单元测试或测试弹性云计算。

  例:阿里云,要模拟双11的压力,需要快速创建1万docker实例,每个docker容器实例中都运行ab命令,拼命的访问tmall.com首页,运行1个小时,1小时后自动删除

  [root@server ~]# docker run -it --rm --name rm centos:7.6.1810 sleep 5

  物理机上查看docker进程

  [root@server ~]# docker ps|grep rm

  34529b6e0619        centos:7.6.1810     "sleep 5"           2 seconds ago       Up 4 second                             rm

  等5秒后再查看

  [root@server ~]# docker ps|grep rm   #己经自动删除了

 3.4 docker容器资源配额控制之内存

  Docker提供参数-m,--memory =‘‘限制容器的内存使用量。

  例1.允许容器使用的内存上限为128M  

  [root@server ~]# docker run -it -m 128m centos:7.6.1810
  [root@b68b2418f5cf /]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes
  134217728

  注:也可以使用stress进行测试

  例2:创建一个docker,只使用2个cpu核心,只能使用128M内存

  [root@server ~]# docker run -it --cpuset-cpus 0-1 -m 128m centos:7.6.1810 /bin/bash 

  [root@7a9427e01966 /]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes
  134217728  

  [root@7a9427e01966 /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
  0-1 

 3.5 docker容器资源配额控制之IO

  为什么阿里云平台上,普通的云盘的IO为1000 IOPS,为什么这么小?

  假如一台存储为20000T,每个云主机20G,给2000台云主机使用,需要控制一下,防止某台云主机吃光存储的I/O资源 

  情景:防止某个Docker容器吃光你的磁盘I/O资源

  例1:限制容器实例对硬盘的最高写入速度为1MB/s

  --device参数:将主机的设备添加到容器 

  --device-write-bps value  #限制此设备上的写速度(bytes per second),单位可以是kb、mb、gb

  --device-read-bps value  #限制此设备上的读速度(bytes per second),单位可以是kb、mb、gb

  例1:启动一个docker,限制此设备上的写速度为1MB/s

  [root@server ~]# docker run -it -v /var/www/html:/var/www/html --device /dev/sda:/dev/sda --device-write-bps /dev/sda:1mb centos:7.6.1810 /bin/bash
  [root@c01b5315f8c9 /]# time dd if=/dev/sda of=/var/www/html/test.out bs=1M count=30 oflag=direct,nonblock  #测试IO限制是否有效

  30+0 records in
  30+0 records out
  31457280 bytes (31 MB) copied, 30.1154 s, 1.0 MB/s

  real 0m30.123s
  user 0m0.000s
  sys 0m0.359s

  注:dd 参数

  direct:读定数据采用IO方式,不走缓存,直接从内存写到硬盘上。

  nonblock:读写数据采用非阻塞IO方式,优先写dd命令的数据

 3.6 docker数据映射(数据的长期存储)

  docker用来做计算,数据存储通过外挂目录的方式来实现

  语法:docker run -itd -v /src:/dst centos:7.6.1810 /bin/bash

  -v 用来指定挂载目录,冒号:前面的/src为物理机本地目录,冒号:后面的/dst为容器里的目录

  例1:把物理机上的/var/www/html映射到docker实例的/var/www/html

  docker run -itd -v /var/www/html:/var/www/html centos:7.6.1810 /bin/bash

  优点:当docker损坏了,数据还在物理机上,再使用apache镜像启动一个docker实例,并将物理机的目录映射到新的docker就可以了,数据不会丢失 

4.配置docker静态IP地址-配置私有仓库

 4.1创建docker静态化IP

  4.1.1 Docker的4种网络模式:

  1.Docker有以下4种网络模式:

  host模式,使用--net=host指定

  container模式,使用--net=container:NAME_or_ID指定。

  none模式,使用--net=none指定。

  bridge模式,使用--net=bridge指定,默认就是bridge模式

  4.1.2配置桥接网络

  桥接本在物理网网络的目的,是为了局域网内用户方便访问docker实例中服务,不需要各种商品映射即可访问服务。但这样做,又违背容器安全隔离的原则,工作中根据实际情况,合理选择

  创建桥设备br0:

  [root@server ~]# rpm -ivh /mnt/cdrom/Packages/bridge-utils-1.5-9.el7.x86_64.rpm  #桥设备安装包

  [root@server network-scripts]# cp ifcfg-ens33 /opt
  [root@server network-scripts]# vi ifcfg-ens33
  TYPE=Ethernet
  PROXY_METHOD=none
  BROWSER_ONLY=no
  BOOTPROTO=none
  DEFROUTE=yes
  IPV4_FAILURE_FATAL=no
  IPV6INIT=yes
  IPV6_AUTOCONF=yes
  IPV6_DEFROUTE=yes
  IPV6_FAILURE_FATAL=no
  IPV6_ADDR_GEN_MODE=stable-privacy
  NAME=ens33
  UUID=69532d74-5b91-48c9-953b-131b2ecd980a
  DEVICE=ens33
  ONBOOT=yes
  IPADDR=172.20.77.201
  PREFIX=24
  GATEWAY=172.20.77.98
  DNS1=172.20.77.98

  BRIDGE=‘br0‘  #在文件最后插入这一行,表示把ens33桥接到br0上

  生成桥设备br0的配置文件:  

  [root@server network-scripts]# vi ifcfg-br0  #创建ifcfg-br0文件,并写入以下内容
  DEVICE=‘br0‘
  NM_CONTROLLED=‘yes‘
  ONBOOT=‘yes‘
  TYPE=‘Bridge‘
  BOOTPROTO=none
  IPADDR=172.20.77.201
  PREFIX=24
  GATEWAY=172.20.77.98
  DNS1=114.114.114.114

  [root@server network-scripts]# systemctl restart network

  测试br0:  

  [root@server ~]# ifconfig  

  [root@server ~]# ping baidu.com
  PING baidu.com (39.156.69.79) 56(84) bytes of data.
  64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=52 time=43.2 ms
  

部署Docker容器虚拟化平台

标签:网络模式   enabled   创新   F12   创建者   sign   缓存   bash命令   版本号   

原文地址:https://www.cnblogs.com/happysnowy/p/13358339.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!