什么是Docker?

听说 docker 也有很长一段时间了,工作中也在用,现在就来总结一下,下面几句文案摘自菜鸟教程,哈哈~~~
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

容器是完全使用沙箱机制,相互之间不会有任何接口, 下面会讲到。

Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。

Docker 的组成

docker client:客户端 用户使用
docker daemon:守护docker主机   // /etc/docker/daemon.json
docker register:镜像仓库   // harbor or aliyun
docker images:镜像
docker container:容器

Docker 解决了什么问题?

  • 上线流程繁琐:开发-测试-申请资源-审批-部署-测试
  • 资源利用率低:服务器利用率低,造成过多浪费
  • 扩容缩容不及时:业务高峰期扩容流程繁琐,上线不及时
  • 服务器环境臃肿:维护、迁移带来困难
  • 准确的说以上四点都是可以通过 k8s 平台来管理,并不是单纯 docker 能解决。

容器Vs虚拟机

  • 虚拟机:模拟一个计算机系统,增加了hypervisor层开销,是一个完整的操作系统,适合做一个基础架构
  • 容器:是一种技术,在虚拟机上做一些操作,打包文件系统,共享宿主机内核,接近于原生,效率更高,更灵活
容器和虚拟机的区别:
	1.启动速度:容器秒级 虚拟机分钟级
	2.运行性能:容器接近原生 虚拟机会有损失
	3.磁盘占用:容器MB 虚拟机GB
	4.数量:容器成百上千 虚拟机一般几十台
	5.隔离性:容器进程级 虚拟机系统性(更彻底)
	6.操作系统:容器主要支持 linux 虚拟机几乎所有
	7.封装成度:只打包项目代码和依赖关系,共享宿主机内核 虚拟机需要完整的操作系统

虚拟机架构:

  • 基础架构物理机
  • 中间软件层:模拟多个操作系统去使用基础架构
  • 二进制文件和库

容器:

  • 基础架构物理机
  • 打包二进制文件和库
  • 共享宿主机内核

Dokcer 设计目标

  • 保持环境的统一性,提供简单的应用程序打包工具,类似于一个压缩包,可以放到任何机器上运行
  • 开发、运维人员职责分离,开发以镜像为交付,运维负责管理容器、监控容器、资源的监控
  • 多环境保持一致性

K8s 设计目标

将镜像最高效,最大化的部署起来

  • 1.集中管理所有容器
  • 2.资源编排-写文件配置
  • 3.资源调度-资源池,创建的容器使用多少资源
  • 4.弹性伸缩-扩容缩容
  • 5.资源隔离-命名空间

安装 Docker

安装依赖包

yum install -y yum-utils device-mapper-persistent-data lvm2

添加 docker 软件包源,默认是 docker.com 官网下载,如果很慢,可以替换源。

yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo

安装 docker

yum install -y docker-ce

启动并设置开机自启

systemctl start docker
systemctl enable docker

如果下载 docker 很慢,可以替换成阿里云的源

cd /etc/yum.repos.d/
rm docker.com.repo
wget http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

配置镜像加速器:

curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io 
查看是否替换成功:cat /etc/docker/daemon.json
注意:一定要重启docker systemctl restart docker

查看:
在这里插入图片描述

什么是镜像?

  • 1.一个分层存储的文件
  • 2.一个软件的环境
  • 3.一个镜像可以创建N个容器
  • 4.一个标准化的交付
  • 5.一个不包含 linux 内核而又精简的 Linux操作系统
    镜像不是一个单一的文件,而是有多层构成。我们可以通过docker histor y <ID/NAME> 查看镜像中各层内容及大小,每层
    对应着Dockerfile中的一条指令。Docker镜像默认存储在/var/lib/docker/<storage-driver>中。
    在这里插入图片描述
    在这里插入图片描述

镜像从哪里来?

Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容器镜像,Docker工具默认从这个公共镜像库下载镜像。地址:https://hub.docker.com

镜像的概念

镜像到底是怎么工作的,怎么做到在系统中可以独立的运行,资源的分配和资源的限制是如何做的。
容器中怎么做的资源隔离,使用 namespace(命名空间):

  • UTS:主机名和域名之间的隔离
  • IPC:消息队列,共享内存隔离
  • PID:通过进程id隔离
  • Network:网络协议哦栈的隔离,比如ip、端口
  • Mount:文件系统之间的不一样
  • User:用户和用户组之间的隔离

资源的限制:cgroup,比如CPU、内存、磁盘IO
UFS:联合文件系统,Copy-on-write,可写层做数据的状态,不做数据的持久化。

Copy-on-write是什么:

在这里插入图片描述
镜像和容器是分开的两块内容,中间会有些许的关联,镜像会为容器提供一个可写层的数据接口,可以简单这样理解,图中绿色部分是我们的操作系统,上面2、3、4是构建镜像的基础镜像,容器是最上面的 Writable Container,容器其实是在镜像的最上面加了一层读写层,在运行容器里文件改动时,
会先从镜像里要写的文件复制到容器自己的文件系统中(读写层)。
如果容器删除了,最上面的读写层也就删除了,改动也就丢失了。所以无论多少个容器共享一个镜像,所做的写操作都是从镜像的文件系统中复制过来操作

创建容器

创建容器需要考虑一下几个点:

  • 1.应用端口怎么暴露出去
  • 2.主机名,IP
  • 3.数据要不要持久化,业务数据,临时数据,数据库数据
  • 4.变量传入做相关动作
  • 5.资源限制,例如cpu、内存
    以上几点在创建容器时都有对应选项供我们使用。

创建容器示例:

docker run -d \        
-p 8888:8080 \          //暴露的端口,左边是宿主机端口,右边是容器端口,意思就是将容器端口8080映射到宿主机的8888端口上面
--name web \             //给容器起个名字
-e abc=123456 \          //传入的变量
-v $PWD/wwwroot:/opt \   // 数据挂载
-m=1G \                 //资源的限制,内存限制
--cpus="2" \            //资源的限制,cpu 限制
镜像名称

创建容器时的选项:

-d:后台运行
-i:交互式
-t:分配一个伪终端
-p:发布容器端口到主机
-e:设置环境变量
-v:挂载一个数据卷到容器中,用于做数据的持久化
-m:最大可以使用的内存量
--cpus:可以使用几核 cpu
示例:
	允许容器最多使用一个半的CPU:
	docker run -d --name nginx04 --cpus="1.5" nginx
	允许容器最多使用50%的CPU:
	docker run -d --name nginx05 --cpus=".5" nginx

数据持久化的三种方式:

  1. volume
volumes:docker 来管理,需要先创建,如果后续容器用到这个volume,那么docker 会将他放到一个目录中
创建volume:docker volume create wwwroot
查看volume详情:docker volume inspect wwwroot,docker会自动给你创建一个目录,作为数据的持久化
/var/lib/docker/volumes/wwwroot/_data
要想使用volume:
		--mount bind=volumes,src=wwwroot,dest=/opt
  1. bind mounts
 挂载目录或者文件挂载到容器中,灵活
 -v $PWD/wwwroot:/opt
  1. tmpfs
 挂载存储在主机系统的内存中,而不会写入主机的文件系统。如果不希望将数据持久存储在任何位置,可以使用
tmpfs,同时避免写入容器可写层提高性能。不常用

容器的网络模式

  • bridge

    默认网络,docker启动后会默认创建一个docker0网桥 默认创建的容器也是添加到这个网桥中
    docker network ls 查看网络模式
    默认情况下启动、创建容器都是用该模式,所以每次docker容器重启时会按照顺序获取对应ip地址,
    这就导致容器每次重启,ip都发生变化

  • host
    容器不会获得一个独立的network namespace 而是与宿主机公用一个

  • none
    获取独立的network namespace,但不为容器进行任何网络配置。没有网卡

  • container
    与指定的容器使用同一个network namespace,网卡配置也都是相同的

  • 自定义

使用 Dockerfile 构建镜像

常用指令,从上往下执行:

1.FROM:新镜像是基于那个镜像
2.LABEL:标签
3.RUN:构建镜像时运行的 shell 命令
4.COPY:拷贝文件或目录到镜像中
5.ENV:设置环境变量
6.USER:指定运行用户
7.EXPOSE:容器运行的服务端口
8.WORKDIR:为RUN、CMD、ENTRYPOINNT、COPY和ADD设置工作目录
9.ENTRYPOINNT:运行容器时执行
10.CMD:运行容器时执行

dockerfile 要求,先知道什么需求,比如:

  • 1.什么语言,依赖环境、服务端口、中间件

  • 2.建议先启动一个容器,在里面跑通流程,然后拷贝到Dockerfile中

  • 3.构建镜像时基于那些操作系统:

     一般有:centos、ubuntu、debian、 alpine:非常轻量级很小的一个linux发行版
     建议:公司使用什么系统,自己就用什么镜像
     基础镜像可能包管理器不一样:yum apt-get apk
    

以nginx为例:
这里建议先跑通再去写Dockerfile。

拉去镜像:docker pull centos:7
创建容器:docker run -itd centos:7
进入容器:docker exec -it 镜像名称 bash
安装nginx:
yum install nginx -y:会报错说找不到这个包
先安装 yum install epel-release -y 这个包
然后安装nginx:yum install nginx -y
配置前台运行:nginx -g daemon off;
可以在浏览器访问一下,能显示说明成功了。

查看结果:
在这里插入图片描述
这里修改了一下index。文件,所以这样显示:
在这里插入图片描述
编写dockerfile:

FROM centos:7
LABEL test
RUN yum install epel-release -y
RUN yum install nginx -y
EXPOSE 80
WORKDIR /user/local
CMD ["nginx","-g","daemon off;"]

构建镜像:

docker build -t nginx:v1 .

在这里插入图片描述

镜像和容器常用命令:

docker --help:docker客户端可以使用的命令
docker images ls:列出镜像
docker image inspect nginx 镜像详情
docker image pull nginx 拉取镜像
docker image push nginx 推送镜像
docker images rmi nginx 删除镜像
docker tag nginx nginx:v1 打标签 
docker rmi image 删除镜像 -f强制删除
docker image --help 镜像全部命令解释

docker ps 查看所有运行中的容器
docker ps -l 查看最新运行的容器
docker ps -a 查看所有状态容器
docker exec -it container bash 进入容器
docker restart container 重启容器
docker stop container 停止运行容器
docker start container 运行容器
docker rm container 删除容器
docker container --help 容器全部命令解释

参考文献

docker 官网:https://docs.docker.com/
菜鸟教程:https://www.runoob.com/docker/docker-command-manual.html

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐