随着互联网时代的到来,计算机的各项技术都有了巨大提高,推动了虚拟化、 容器化技术的产生和发展,以及现在的云原生时代的到来,都极大提高了其资源利用率。
Docker
Docker 本身不是容器,它只是一个应用容器引擎,这么解释可能有些抽象,大家理解下面内容。
三大核心
- 镜像(Image)
- 容器 (Container)
- 仓库(Repository)
镜像(Image)
容器镜像解决了环境打包
的问题,可以把镜像理解成一个压缩包,里面包含了我们需要的东西,使用时解压就可以。
容器(Container)
什么是容器?
容器技术其实是调用操作系统的 Cgroups 和 Namespace 机制为每一个应用单独创建一个称作“沙盒
”的隔离环境,然后在“沙盒”中启动这些应用进程。容器技术也是大家口中常说的沙盒技术。通过这两种机制在启动进程时设置一些参数实现了隔离不相关资源后的一个特殊进程
- Cgroups是对资源限制,Namespace是隔离资源
- 容器本身没有价值,有价值的是“容器编排” ,编排主要就是容器之间的关系。对象之间的关系远重要于对象本身
仓库(Repository)
顾名思义是Docker用来存放镜像的地方,Docker仓库可以分为公开仓库和私有仓库两种形式。目前,最大的公开仓库是Docker Hub, 存放了数量庞大的镜像供用户下载。
作用
1.解决环境问题
在我们的学习过程中,很多时间都浪费在了环境搭建中,如果我装了一个干净的系统,想要去搭建一个环境,首先我们得需要各种软件包下载安装,还需要配置各种环境变量。
相信很多人自己重装过系统,如果我们下载纯净windows镜像,那我们安装之后桌面之只有一个回收站。如果我们使用的ghost镜像,它会自带一些安装好的软件,简单来说ghost镜像中已经预装好了这些软件。
Docker 也是这种思路,把我们需要的环境打包成一个镜像,然后发送到网上, 有需要的时候,可以自己从网上拉去下来就可以使用了。
2.解决应用隔离
通过“沙盒”机制形成的隔离环境,我们可以把一个容器看做一个终端,它们有自己的文件系统,容器的启动和创建都十分方便。
应用部署
总的来说分为三个阶段,
- 物理机部署
- 虚拟机部署
- 容器化部署
1.物理机部署
早先的物联网公司一定会经历的阶段,一台服务器,至少 32 核 CPU、64G 内存, 如果我们只用来部署一个应用就实在是太浪费了。于是就把多个应用同时部署在一个机器上
弊端:如果某个进程抢占资源。CPU 直接爆满,其他进程无法正常提供。那可能就会造成 多个应用进程同时无法提供服务的情况
2.虚拟机部署
虚拟机顾名思义就是物理机通过虚拟技术,把一台变多台。每个虚拟机都有整套的操作系统,这样我们的应用可以放在不同的虚机上面,就算一台出现异常也不会影响其他机器上应用的正常运行,这样起到了隔离的作用。
弊端:操作系统的一些文件,会占用大量空间,而且虚机的创建和启动会十分的慢,学习linux的同学一定会用到Vmware Workstation,通过它创建虚机供我们学习
3.容器化部署
Docker容器其实一个应用层面的抽象,将自己所需的应用整合打包在一起。多个容器可以运行在同一个系统上,各个容器都是作为独 立的进程在用户的空间中运行。
与虚拟机相比之下,容器的创建所占用的空间会 更少,启动也很快,所以说 Docker 容器是一台轻量级服务器。
Dockerfile
制作容器镜像 Docker
为我们提供了一种更便捷的方式,叫作 Dockerfile
简单案例
# 使用官方提供的golang开发镜像作为基础镜像
FROM golang
# 将工作目录切换为/app
WORKDIR /app
# 将当前目录下的所有内容复制到/app下
ADD . /app
# 使用go命令进行构建
RUN go build -tags netgo -o web-service web-service.go
# 允许外界访问容器的9090端口
EXPOSE 9090
# 设置环境变量
ENV NAME World
# 设置容器进程为:./web-service
CMD ["./web-service"]
通过这个文件的内容,你可以看到 Dockerfile 的设计思想,是使用一些标准的指令,描述我们所要构建的 Docker 镜像。
下面是一段go代码
package main
import (
"fmt"
"net/http"
"strings"
"log"
)
func sayhelloName(w http.ResponseWriter, r *http.Request) {
r.ParseForm() // 解析参数,默认是不会解析的
fmt.Println(r.Form) // 这些信息是输出到服务器端的打印信息
fmt.Println("path", r.URL.Path)
fmt.Println("scheme", r.URL.Scheme)
fmt.Println(r.Form["url_long"])
for k, v := range r.Form {
fmt.Println("key:", k)
fmt.Println("val:", strings.Join(v, ""))
}
fmt.Fprintf(w, "Hello World!") // 这个写入到 w 的是输出到客户端的
}
func main() {
http.HandleFunc("/", sayhelloName) // 设置访问的路由
err := http.ListenAndServe(":9090", nil) // 设置监听的端口
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
接下来,我就可以让 Docker 制作这个镜像了,在当前目录执行:
[root@ycloud test]# ll
total 8
-rw-r--r-- 1 root root 493 Oct 2 10:42 Dockerfile
-rw-r--r-- 1 root root 812 Oct 2 10:39 web-service.go
[root@ycloud test]# docker build -t webservice .
-t 的作用是给这个镜像加一个 Tag ,
Dockerfile
中的每个指令执行后,都会生成一个对应的镜像层。
让我们查看并且运行刚才我们创建的镜像
[root@ycloud ~]# docker images
webservice latest 623370cadc93 6 minutes ago 350MB
[root@ycloud ~]# docker run -d -p 9090:9090 webservice ## -d 后台运行 -p 映射端口
[root@ycloud ~]# curl localhost:9090
Hello World!
Docker监控
使用 Docker 时运行多个容器时,容器的一些基本情况都是需要了解的,这 个时候就需要监控。对于 docker 的监控有很多,docker 其本身也自带命令进行监控
- docker ps,可以查看容器状态及运行在这台宿主机容器数量
[root@ycloud ~]# docker ps -a| grep web
d7e697239678 webservice "./web-service" 45 seconds ago Up 44 seconds 0.0.0.0:9090->9090/tcp
- docker top,可以查看对应容器进程,可以不用指定单个容器
[root@ycloud ~]# docker top d7e697239678
UID PID PPID C STIME TTY TIME CMD
root 2634763 2634744 0 11:00 ? 00:00:00 ./web-service
- docker stats,显示容器资源使用统计数据的实时流
[root@ycloud ~]# docker stats d7e697239678
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
d7e697239678 ecstatic_meninsky 0.00% 2.867MiB / 125.2GiB 0.00% 0B / 0B 0B / 0B 5
还有很多好用的Docker监控组件,比如:Weave Scope 、cAdvisor
总结
这篇文章主要讲了一些概念性的内容,让大家了解是什么容器,应用部署的发展历程,Docker解决了什么样的问题。深入学习后面的内容,基础部分一定要牢固,为后面的云原生打基础。一起努力学习吧