Docker

Docker

Docker_第1张图片

(1)从VM与Docker框架中,直观上VM多了一层Guest OS,同时Hypervisor会对硬件资源进行虚拟化,docker直接使用硬件资源,所以资源利用率相对docker低。

(2)openstack能够以10台/min的速度创建虚拟机,在docker面前就弱爆了,因为docker是利用宿主机的系统内核,所以可以做到在几秒钟之内创建大量容器,它们的启动速度是在数量级上的差距。Docker的每个隔离环境是进程级的,每个守护进程共用操作系统内核,在隔离环境中打包运行服务必要的依赖。因此每个容器启动非常快,且占用的资源非常少,非常适合用在服务器上部署后台服务。

(3)Docker有着小巧、迁移部署快速、运行高效等特点,但隔离性比服务器虚拟化差;

(4)虚拟机更擅长于彻底隔离整个运行环境。例如,云服务提供商通常采用虚拟机技术隔离不同的用户。而Docker通常用于隔离不同的应用,例如前端,后端以及数据库。

服务器虚拟化解决的核心问题是资源调配,而容器解决的核心问题是应用开发、测试和部署。

(5)VM在宿主机器、宿主机器操作系统的基础上创建虚拟层、虚拟化的操作系统、虚拟化的仓库,再安装应用;Docker容器在宿主机器的操作系统上创建Docker引擎,直接在宿主主机的操作系统上调用硬件资源。

(6)虚拟机虽然可以隔离出很多「子电脑」,但占用空间更大,启动更慢。虚拟机软件可能还要花钱,例如 VMWare。容器技术不需要虚拟出整个操作系统,只需要虚拟一个小规模的环境,类似「沙箱」。运行空间,虚拟机一般要几 GB 到 几十 GB 的空间,而容器只需要 MB 级甚至 KB 级。

Docker_第2张图片

(7)虚拟机的 Hypervisor 创建了一个非常牢固的边界,以防止应用程序突破它,而容器的边界不那么强大。

1.初识 Docker

1.1 docker概念

1、Docker 是一个开源的应用容器引擎
2、诞生于 2013 年初,基于 Go 语言实现, dotCloud 公司出品(后改名为Docker Inc)
3、Docker 是一个可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器引擎(好比汽车发动机),然后发布到任何流行的 Linux 机器上。
4、容器是完全使用沙箱机制,相互隔离
5、容器性能开销极低。
6、Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版)

Docker_第3张图片

docker扮演的是图中鲸鱼的角色,而鲸鱼之上的集装箱就是一个个容器,容器中是我们开发的应用程序(不仅限于web应用),每个容器都有自己独立的环境(环境设置、网络、文件系统…),互不干扰。而每个箱子,又可以打包成一个新的镜像,放到其它服务器的docker环境中直接运行,不再需要重复安装程序运行环境

1.2 docker应用场景

案例一:

前几天,公司一批服务器就要到期了,由于服务器是15年购买的,硬件的性能远比现在新出的云主机低,因此决定把所有服务器都换成新一代服务器,但是张三正准备动手迁移服务器时,内心一阵阵崩溃感涌上心头,仔细一算,每台服务器都要做同样的事情。

1、装jdk、Tomcat、nginx
2、配置jdk环境变量和系统变量
3、配置Tomcat
4、配置nginx
5、安装项目所需的视频解码组件
6、导入项目所需的一些特殊字体

后来决定用docker部署的办法,在每台服务器都把docker安装之后,只需要在其中一台服务器中把Tomcat镜像从镜像仓库拉取下来,把这些配置都设置好,做成一个自己的镜像上传到镜像仓库中,之后在其他几台服务器都下载自己做的镜像,运行于docker中,把代码上传,就万事大吉了。

案例二

前不久的圣诞活动中,公司临时的活动方案在程序员的加班加点中终于上线,但是一上线之后发现推广海报中的中文名字乱码,领导问责测试人员怎么没做好测试,测试很委屈的说我已经测试无数遍并且测试报告都提交了,解决了所有问题才上线的;没办法只能让服务器同事查看正式服务器中的tomcat配置,发现原来 tomcat用了默认编码方式:iso8859-1,而测试环境中是UTF-8。针对这个问题,项目组决定把开发环境迁移到docker中,在测试环境中测试无误后,把镜像打包发布到正式环境中,解决了环境不同导致的问题

1.3 安装docker

Docker可以运行在MAC、Windows、CentOS、UBUNTU等操作系统上,本课程基于CentOS 7 安装Docker。
官网:https://www.docker.com

#yum 包更新到最新
yum update -y

#安装需要的软件包
yum install -y yum-utils device-mapper-persistent-data lvm2

#设置yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 安装docker
yum install -y docker-ce

#查看docker版本,验证是否验证成功
docker -v

考虑到从 docker 官方的仓库下载 docker-ce 有时会比较慢,可以使用下述命令将下载网址改为华为的镜像服务器:
sudo sed -i ‘s+download.docker.com+repo.huaweicloud.com/docker-ce+’ /etc/yum.repos.d/docker-ce.repo

1.4 docker相关概念

  • 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
  • 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和对象一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
  • 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。

1.5 配置 Docker 镜像加速器

默认情况下,将来从docker hub(https://hub.docker.com/)上下载docker镜像,太慢。一般都会配置镜像加速器:

  • USTC:中科大镜像加速器(https://docker.mirrors.ustc.edu.cn)
  • 阿里云
  • 网易云
  • 腾讯云

阿里云镜像加速器配置

首先登陆阿里云,点击控制台,然后再点击左边的像三字一样的图标,再点击产品与服务,在输入关键字地方搜索“镜像”,会显示容器镜像服务,点击“容器镜像服务”,在左侧的最下方有镜像中心(镜像加速器),点击镜像加速器,复制如下代码到linux执行即可

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://88y9upwp.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

2.Docker命令

2.1 进程相关命令

systemctl start docker    #启动docker服务
systemctl stop docker     #停止docker服务 
systemctl restart docker  #重启docker服务 
systemctl status docker   #查看docker服务状态
systemctl enable docker   #开机启动docker服务

2.2 镜像相关命令

1、查看镜像: 查看本地所有的镜像

docker images   
# 查看所有镜像的id
docker images –q

2、搜索镜像:从网络中查找需要的镜像

#docker search 镜像名称
docker search  redis

3、拉取镜像:从Docker仓库下载镜像到本地,镜像名称格式为 名称:版本号,如果版本号不指定则是最新的版本,如果不知道镜像版本,可以去docker hub 搜索对应镜像查看。 https://hub.docker.com/_/docker

#docker pull 镜像名称:版本号
docker pull redis:5.0 
docker pull centos:7
docker pull mysql:5.6  |  docker pull mysql:8.0.25 
docker pull tomcat:8
docker pull nginx

4、删除镜像: 删除本地镜像

#docker rmi 镜像id
docker rmi `docker images -q`

2.3 容器相关命令

1、查看容器

docker ps       # 查看正在运行的容器
docker ps –a    # 查看所有容器 (包括没有运行的容器)

2、创建并启动容器

#docker run -it | -id --name=容器名称 镜像名称:版本 /bin/bash
docker run -it --name=c1 centos:7 /bin/bash   #创建并自动进入容器,当输入exit 退出容器并回到宿主机
docker -id --name=c2 centos:7				 #创建容器 但不进入容器

参数说明:

-i:保持容器运行。通常与 -t 同时使用。加入it这两个参数后,容器创建后自动进入容器中,退出容器后(执行命令exit),容器自动关闭

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

-d:以守护(后台)模式运行容器。创建一个容器在后台运行,需要使用docker exec 进入容器。退出后,容器不会关闭

/bin/bash 这是表示载入容器后运行bash ,docker中必须要保持一个进程的运行,要不然整个容器就会退出。这个就表示启动容器后启动bash。默认会启动一个bash,可以忽略不写

3、进入容器

#docker exec 参数  /bin/bash      #进入容器  注意 此处的/bin/bash不能省略
docker -id --name=c2 centos:7
docker exec -it c2 /bin/bash
exit         #此时容器还是在运行着的

4、启动容器

#docker start 容器名称
docker start c1

5、停止容器运行

docker stop 容器名

6、删除容器

#docker rm 容器名称       #如果容器是运行状态则删除失败,需要停止容器才能删除
docker rm c1

7、查看容器信息

#docker inspect 容器名称
docker inspect  c1

8、查看docker日志

#docker logs --tail 行数 -f  容器名   #查看某个容器末尾300行的日志内容
docker logs --tail  300 -f app-jar  

9、docker容器安装命令

apt-get  update
apt-get  -y install net-tools  | yum .....

10、用于容器与主机之间的数据拷贝

#将主机/root/123.war文件拷贝到容器96f7f14e99ab的/root目录下
docker cp /root/123.war 96f7f14e99ab:/root/

#将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中
docker cp  96f7f14e99ab:/root /tmp/

4.Docker应用部署

Nginx部署

1、搜索nginx镜像

docker search nginx

2、拉取nginx镜像

docker pull nginx

3、创建目录

mkdir nginx
cd nginx
mkdir conf
cd conf
vim nginx.conf

4、编写nginx.conf配置文件

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on; 
    keepalive_timeout  65;
    include /etc/nginx/conf.d/*.conf;  

}

说明:

第四步其实可以省略,默认创建一个nginx容器,会在/etc/nginx/目录下生成一个叫nginx.conf的配置文件,nginx容器启动会去加载该文件,该文件的内容和第四步配置文件的内容相同。这个文件的末尾有include /etc/nginx/conf.d/*.conf;这句话,也就说在conf.d目录下并且以conf结尾的文件都会被加载,而这个目录下只有一个配置文件就是default.conf,default.conf文件的内容配置了一个server节点,以及默认访问nginx的目录和首页(/html/index.html)

5、创建nginx容器、端口映射、目录挂载

docker run -id --name=c_nginx \
-p 80:80 \    #左边是对外开放的端口,右边是JAR端口
-v /root/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \  #不挂载这个配置文件也是可以的
-v /root/nginx/logs:/var/log/nginx \                    #nginx容器默认的日志文件保存到/var/log/nginx目录下
-v /root/nginx/html:/usr/share/nginx/html \             #nginx默认会去访问/usr/share/nginx/html下的index.html
nginx
docker run -id --name=c_nginx -p 80:80 nginx

如果你不想挂载,所有的都可以不挂载,如果所有的都不挂载,默认情况,当创建nginx容器时,在/etc/nginx/目录下有nginx.conf这个文件,这个文件是nginx的配置文件,nginx容器启动的时候会去读这个配置文件

在宿主机的/root/nginx/html目录下新建 index.html,让其同步到/usr/share/nginx/html目录下

测试访问:http://192.168.128.130/

5.Docker镜像制作

5.1 Linux文件系统组成

Linux文件系统组成由bootfs和rootfs两部分

  • bootfs:包含bootloader(引导加载程序)和 kernel(内核)
  • rootfs: root文件系统,包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc等标准目录和文件不同的linux发行版,bootfs基本一样,而rootfs不同,如ubuntu,centos等

思考:

  • Docker 镜像本质是什么?
  • Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G?
  • Docker 中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB?

5.2 Docker 镜像原理

  • Docker镜像是由一层一层的文件系统叠加而成,最底端是 bootfs,并使用宿主机的bootfs ,第二层是 root文件系统rootfs,称为base image,然后再往上可以叠加其他的镜像文件,这种层级的文件系统被称之为UnionFS,统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统
  • 一个镜像可以放在另一个镜像的上面。位于下面的镜像称为父镜像,最底部的镜像成为基础镜像,当从一个镜像启动容器时,Docker会在最顶层加载一个读写文件系统作为容器

Docker_第4张图片

1.Docker 镜像本质是一个分层文件系统

2.我们下载tomcat镜像大小是600+MB,是因为里面还包含了jdk和centos这两个镜像层,所以很大,另外需要注意一点的是,这个tomcat镜像里面包含了jdk镜像和centos基础镜像,为什么基础镜像是centos而不是ubuntu呢?这是有做这个tomcat镜像的发行商决定的。

3.我们下载centos镜像很小,是因为而centos镜像层复用了宿主机的bootfs,下载的只有rootfs,所以centos是很小的

说明:docker内核和宿主机共内核,也就是bootfs,至于rootfs发行版本,可以使和宿主机一样是centos、也可以是ubuntu或者其他的,如:docker pull centos,然后做一个容器,那么docker的发行版本是centos,进入docker容器,通过输入命令: cat /etc/redhat-release 可以查看; docker pull ubuntu,然后做一个容器,则发行版本是ubuntu,进入docker容器

5.3 Docker镜像制作

Docker_第5张图片

5.3.1 普通方式

我们可以在容器去部署应用,然后把容器转为镜像给测试人员用,由于镜像是不能直接传输的,所以我们将新的镜像转成压缩文件,给测试人员。测试人员把我们的压缩文件还原成一个新的镜像

docker commit 容器id 镜像名称:版本号     #把容器做成镜像
docker save -o 压缩文件名称 镜像名称:版本号  #把镜像做成压缩包,放到宿主机的某个位置
docker load –i 压缩文件名称     #别人(测试人员)加载镜像(压缩包)

注意事项:容器转为镜像,如果容器有挂载的内容,做成新镜像的时候,挂载的内容是不会载入到镜像里面的

案例一:制作centos-java镜像

1、首先创建一个centos容器

docker pull centos:7.9.2009
docker run -it --name=centos centos:7.9.2009  /bin/bash

2、安装JDK

2.1下载jdk-8u151-linux-x64.tar.gz到容器的home目录里面

wget http://192.168.0.222:9000/%e5%b7%a5%e5%85%b7/CentOS%e5%b8%b8%e7%94%a8%e8%bd%af%e4%bb%b6/jdk-8u151-linux-x64.tar.gz

2.2配置JDK环境变量

tar -xzvf jdk-8u151-linux-x64.tar.gz

2.3配置profile:

vi  /etc/profile

2.4在最下面加上:

export JAVA_HOME=/home/jdk1.8.0_151
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin

2.5使配置生效:

source /etc/profile

2.6检查jdk:

java -version

2.7重启后环境变量仍生效在/etc/bashrc最下面加上:

export JAVA_HOME=/home/jdk1.8.0_151
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin

由于每次启动终端的时候,都会执行 /etc/bashrc ,所以可以把source /etc/profile 命令** 写入到 /etc/bashrc 文件中,实现环境变量立刻全面生效的效果。

2.8退出容器

[root@cce867bb4e32 /]# exit

2.9重启容器

docker start cce867bb4e32

2.10进行容器验证JDK是否有效

docker exec -it cce867bb4e32 /bin/bash

2.11检查jdk:

java -version

3、把centos7容器做成镜像

docker commit 6598a89db5f6 centos7-java8:1.0
docker images   #可以查看到centos7-java8:1.0镜像

4、把镜像做成压缩包 放到宿主机的某个位置

docker save -o woniu_tomcat.tar centos7-java8:1.0    #-o:output 压缩文件保存到/root目录下

5、把压缩文件载入镜像(第三方载入该压缩包)

docker load -i centos7-java8.tar  #镜像加载 -i  (input)
docker images

6、用centos7-java8:1.0镜像做容器

docker run -id --name=centos7-java8 centos7-java8:1.0
docker exec -it centos7-java8 /bin/bash  #进入容器
#或者启动并进入容器
docker run -it --name=centos7-java8 centos7-java8:1.0 /bin/bash

5.3.2 dockerfile方式

它是用来制作docker镜像的一个文本文件,文件包含了一条条的指令,每一条指令构建一层,基于基础镜像,最终构建出一个新的镜像,对于开发人员:可以为开发团队提供一个完全一致的开发环境,对于测试人员:可以直接拿开发时所构建的镜像或者用Dockerfile文件构建一个新的镜像开始工作了,对于运维人员:在部署时,可以实现应用的无缝移植
Dochub网址:https://hub.docker.com

Dockerfile关键字

关键字 作用 备注
FROM 指定父镜像 指定dockerfile基于那个image构建
MAINTAINER 作者信息 用来标明这个dockerfile谁写的
LABEL 标签 用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看
RUN 执行命令 执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN [“command” , “param1”,“param2”]
CMD 容器启动命令 提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD [“command” , “param1”,“param2”]
ENTRYPOINT 入口 一般在制作一些执行就关闭的容器中会使用
COPY 复制文件 build的时候复制文件到image中
ADD 添加文件 build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务, ADD 源路径 目标路径
ENV 环境变量 指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value
ARG 构建参数 构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数
VOLUME 定义外部可以挂载的数据卷 指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME [“目录”]
EXPOSE 暴露端口 定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp
WORKDIR 工作目录 指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径
USER 指定执行用户 指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户
HEALTHCHECK 健康检查 指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制
ONBUILD 触发器 当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大
STOPSIGNAL 发送信号量到宿主机 该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。
SHELL 指定执行脚本的shell 指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell

案例1:需求自定义centos7镜像。要求如下:

1、默认登录路径为 /usr
2、可以使用vim

步骤1:创建centos-dockerfile文件

mkdir docker-file
cd docker-file
[root@localhost docker-file]# vim centos-dockerfile

步骤2:文件内容如下

FROM centos:7  #原镜像
MAINTAINER  woniu .cn>
RUN yum install -y vim
WORKDIR /usr
CMD /bin/bash

说明:

定义父镜像:FROM centos:7
定义作者信息:MAINTAINER woniu [email protected]
执行安装vim命令: RUN yum install -y vim
定义默认的工作目录:WORKDIR /usr
定义容器启动执行的命令:CMD /bin/bash

步骤3:通过dockerfile文件构建镜像

语法:docker build –f dockerfile的文件路径 –t 镜像名称:版本 .

[root@localhost docker-file]# docker build -f ./centos-dockerfile -t woniu_centos:1 .
[root@localhost docker-file]# docker images

注意事项:

利用当前centos-dockerfile文件构建镜像 -t woniu_centos:1 指定新镜像的名称和版本, 后面的 . 不能省略
参数:-f 表示dockerfile -t 表示tag

案例2:定义dockerfile文件构建镜像,发布springboot项目

步骤1:创建dockerfile文件并编写内容

[root@localhost docker-file]#vim springboot-dockerfile
编写内容如下:
FROM java:8
MAINTAINER  woniu.cn>
ADD springboot.jar app.jar   
CMD java -jar /app.jar

说明:

ADD springboot.jar app.jar 表示把宿主机的springboot.jar复制到镜像里并更名为app.jar,当用镜像做容器时,app.jar默认在容器的根目录

步骤2:通过dockerfile构建镜像

[root@localhost docker-file]# docker build -f  ./springboot-dockerfile -t  springboot-app:1.0 .
[root@localhost docker-file]# docker images

步骤3:通过springboot-app:1.0镜像创建容器

[root@localhost docker-file]# docker run -it --name=app -p 8080:8080 springboot-app:1.0
[root@localhost docker-file]#docker logs --tail 100 -f  app    #查看app容器的日志  末尾100行

[email protected]
ADD springboot.jar app.jar
CMD java -jar /app.jar


> 说明:
>
> ADD springboot.jar app.jar   表示把宿主机的springboot.jar复制到镜像里并更名为app.jar,当用镜像做容器时,app.jar默认在容器的根目录

步骤2:通过dockerfile构建镜像

~~~powershell
[root@localhost docker-file]# docker build -f  ./springboot-dockerfile -t  springboot-app:1.0 .
[root@localhost docker-file]# docker images

步骤3:通过springboot-app:1.0镜像创建容器

[root@localhost docker-file]# docker run -it --name=app -p 8080:8080 springboot-app:1.0
[root@localhost docker-file]#docker logs --tail 100 -f  app    #查看app容器的日志  末尾100行

你可能感兴趣的:(docker,容器,运维)