kubernetes(k8s)大白学习02:容器和docker基础使用架构学习

Posted 九卷技术录--关注技术架构,管理,产品业务

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kubernetes(k8s)大白学习02:容器和docker基础使用架构学习相关的知识,希望对你有一定的参考价值。

一、什么是容器

容器简介

简单说:容器(container)就是计算机上的一个沙盒进程,它与计算机上的所有其它进程相隔离。

这种隔离是怎么做到的呢?它利用了内核提供的 namespace 和 cgroup 这 2 种技术。这些技术能力在 Linux 中已经存在了很长时间。而 Docker 或容器技术致力于将这些功能更易于使用和更方便使用。容器技术把 linux 中已存在的这些技术显性化了,让用户容易操作使用,体验更好。

”沙盒“就像是一个集装箱,能够把应用及其相关依赖软件装在一起。在 docker 的隔离下,应用和应用之间就有了边界,相互隔离不被打扰,也方便“搬来搬去”,搬到各种服务器环境中运行。

Docker 的 logo 是一条鲸鱼驼着许多"四方盒子“ - 标准集装箱,很形象的表达。把软件打包标准化,像一个一个集装箱,可以方便快捷运输到各种服务器环境中并安装。

Docker 的口号:

Develop faster. Run anywhere.

Docker 是容器技术的一种实现,还有其它容器比如 Podman,Container 等。

容器的实质是进程。但与直接运行在宿主机上的进程不同,容器进程运行在属于自己独立的命名空间。因此,容器可以拥有自己独立的 root 文件系统、网络配置、进程空间、自己的用户 ID 空间等等。

容器的一些特性总结:

  1. 它是镜像(image)的一个运行实例。比如你能够使用 docker api 或 cli 创建、启动、停止、移动或删除容器。
  2. 它可以在本地机器、虚拟机或云服务器上运行。
  3. 它可以在任何操作系统上运行。
  4. 它可以与其它容器隔离并运行自己的软件、二进制文件和配置信息。
  5. 它可以自包含一些软件,这样就可以使应用程序几乎在任何地方以相同的方式运行。

比如开发人员在自己笔记本上创建并测试好的容器,无须修改就可以在生产系统的虚拟机、服务器等上面运行。

容器解决了什么问题

我们把应用程序开发完之后,部署到服务器上时,会有很多软件需要部署,比如部署 PHP 程序开发的应用项目,就有 MySQL,Redis,Nginx 等各种软件需要部署。

部署的服务器环境呈现多样化,比如物理服务器,云服务器,虚拟机等,不同服务器上安装的操作系统可能又不同,运行环境不同,依赖各不同。

面对这种多个软件需要部署,不同的服务器环境、不同的操作系统,环境差异这么大,如何能做到一键部署且屏蔽彼此的各种差异?如何做到构建一次完之后就能部署到各种不同的服务器环境中?也就是,一次构建,多地多次部署,且都能顺利运行。

这时容器技术就可以解决这些问题。容器能够把应用程序及其依赖的软件打包到一个容器中,然后发布到各种服务器上。

这样就能加快运行环境搭建、应用程序的部署,解决了运维效率和成本高的一些问题。

一次构建,随时随地搬运,任意环境运行

​ (Build,Ship and Run Anywhere)

Docker 还提供了一种类似“编程的方式”来方便构建镜像:Dockerfile。

二、什么是镜像

镜像(Container Image)是一个模板,一种容器化标准化交付物,容器应用打包的标准格式,用于打包应用程序及其依赖环境。

容器和镜像的关系,这个就相当于面向对象编程语言中,类(container image)和实例(container instance)的关系。镜像是静态定义,容器是镜像运行时的实体。容器可以被创建、启动、删除、暂停等。

容器镜像是一个随时可以运行的软件包,当运行一个容器时,它使用一个隔离的文件系统,这个自定义的文件系统包含应用程序所需的依赖项、配置、脚本、二进制文件等,镜像也包含其它平台的设置。

我们可以借用 Buildah 等开源工具,来创建兼容 OCI 和 Docker 的镜像文件。

Dockerfile 是用来构建镜像的文本文件,文本内容包含了构建镜像所需的指令和说明。Docker 等工具可以通过读取 Dockerfile 中的指令自动构建生成容器镜像。

三、镜像仓库

镜像仓库(container repository)是存储、分发镜像文件的地方。这些镜像文件放在镜像仓库里。镜像仓库可以是开放的镜像仓库,例如 docker hub;也可以是自建的镜像仓库,比如用 docker-registryharborNexus 等。

四、什么是Docker

Docker 简介

Docker 是用 Go 开发实现,基于 linux 的 cgroup,namespace 和 UniosFS 等主要技术,对进程进行封装隔离,在操作系统之上的虚拟化技术。隔离的进程是独立于宿主和其它进程,它又称为容器。

Docker 容器,又进一步的封装,从文件系统、网络到进程隔离等,简化了容器的创建、启动、删除等操作。Docker 技术比虚拟机技术更为轻便。

Docker 可以快速、一致性的交付你的应用程序。

Docker和虚拟机比较

(来自 kubernetes 官网)

从上图软件交付的变化历程图可以看出,容器和传统虚拟机的不同。

  • 传统虚拟机是虚拟出一套硬件,在其上运行完整操作系统,在这之上再来运行各种应用软件。

  • 容器直接运行在容器运行时上,容器运行时直接运行在宿主机的内核里,它也不需要进行硬件虚拟化。

虚拟机和容器的比较:

特点 容器 虚拟机
隔离性 较弱的隔离 强隔离
启动速度 秒级 分钟级
镜像大小 最小的几 MB 几百 MB 到几个 GB
性能(与裸机比) 损耗小于 2% 损耗 15% 左右
系统支持数量 单机可支持 100 个到 1000 个容器 单机支持 10 到 100 个左右
安全性 1.容器内的用户从普通用户权限提升到root用户,就直接具备宿主机root权限 2. 容器中没有硬件隔离,这使得容器攻击彼此牵连 1.虚拟机租户root权限和主机的root权限是分离的 2.硬件隔离技术:防止虚拟机彼此交互

五、Docker架构和执行流程

Docker 整体架构

Docker 整体架构图:

​ (来自:docker docs architecture

Docker 架构是一个客户端-服务端架构,客户端是 Client,服务端是 Docker Host。后面的 Registry 是一个镜像仓库。

Docker 客户端与 Docker daemon 守护进程进行通信,守护进程负责构建、运行和分发 Docker 容器。Docker 客户端和 Docker 守护进程直接进行信息交互。Docker 还有另外一个客户端 Docker Compose,它处理一组容器组成的应用程序。

Client :docker 客户端。docker rundocker builddocker pull,都是 docker 里的命令。

  • docker build:执行 docker 构建命令,会根据 docker 文件构建一个镜像存放在本机上。
  • docker run:执行 docker 启动命令,它会将镜像运行为容器。
  • docker pull:该命令从镜像仓库拉取镜像文件至本地 docker 主机,或将本地镜像推送至远端镜像仓库。

Docker Host:docker 主机。Docker daemon,守护进程;Images,镜像;Containers,容器。

Registry:镜像仓库,存储镜像的仓库。

docker 执行流程

其实上面的架构图已经把 docker 执行流程画出来了。只不过看起来不太明显,在简化下:

​ (docker 命令执行流程,实线条不同颜色代表不同步骤)

从图上可以看出,docker 客户端发出命令,后都会与 docker host(docker 主机)交互,然后在由 docker 主机进行后面的操作。

比如 docker 构建:在 docker 客户端发出命令,docker 主机的守护进程接收命令,然后它通过镜像来运行出一个容器。

docker 底层技术

请看下面的架构图:

​ (docker 底层技术构成简图)

linux kernel,docker 技术的实现依赖了 linux 底层一些技术特性:

  • Namespace:每个容器都有自己独立的命名空间,运行在其中的应用像是在独立操作系统上运行。命名空间保证了容器彼此不受影响。
  • CGroups:对共享资源进行隔离、限制等。比如对CPU、内存的限制。
  • Union FS:联合文件系统是一种分层、轻量级且高性能的文件系统。

Docker 使用存储驱动程序(storage driver)来存储 image 的图像层,将数据存储在容器的可写层中。

Docker 镜像是由一系列层(layers)构建而成,每层代表 Dockerfile 的一条指令。除了最后一层之外每一层都是只读的。

Docker 用 UnionFS (联合文件系统)把这些层联合在一起。

​ (来源docker storage driver:images and layers

​ (图片来源网络侵删)

docker engine

docker engine 引擎里的 runc 是开放容器运行时,它是 OCI(Open Container Initiative)Spec 的一个实现。

docker engine 在 linux 下提供了很多存储驱动,Docker Storage Driver:

Docker Storage Driver
overlay2
fuse-overlayfs
btrfs and zfs
vfs
devicemapper

关于上面 docker storage driver 的更多信息请查看:https://docs.docker.com/storage/storagedriver/select-storage-driver/

六、Docker安装

Docker 可以在不同的操作系统中安装,官方安装地址:

我在虚拟机中装的 ubuntu 操作系统:

Description: Ubuntu 20.04.2 LTS, Codename: focal

该系统对应 docker 官方安装地址:https://docs.docker.com/engine/install/ubuntu/

具体安装 docker 就不详细说明了,请按照官方文档一步一步进行安装。

我安装的docker版本:

$ docker -v
Docker version 24.0.1, build 6802122

验证是否安装成功:

$ sudo docker run hello-world
Unable to find image \'hello-world:latest\' locally
latest: Pulling from library/hello-world
719385e32844: Pull complete 
Digest: sha256:fc6cf906cbfa013e80938cdf0bb199fbdbb86d6e3e013783e5a766f50f5dbce0
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

七、Docker简单使用

docker cli文档地址:https://docs.docker.com/engine/reference/commandline/cli/

启动容器

启动容器

创建或启动一个新容器的命令:docker run , 语法为:

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

获取更多 docker run 帮助文档:docker run --help

比如,下面的命令输出一个“hello world”后,终止容器。

因为我本地没有 ubuntu:20.04 这个镜像,所以要先下载,docker run 会自动下载这个镜像,命令和运行过程如下:

$ sudo docker run ubuntu:20.04 /bin/echo \'hello world\'
Unable to find image \'ubuntu:20.04\' locally
20.04: Pulling from library/ubuntu
ca1778b69356: Pull complete 
Digest: sha256:db8bf6f4fb351aa7a26e27ba2686cf35a6a409f65603e59d4c203e58387dc6b3
Status: Downloaded newer image for ubuntu:20.04
hello world

下载完镜像后,自动运行这个镜像,最后输出了 hello world 。

启动一个 bash 终端,允许用户进入容器终端进行交互:

$ sudo docker run -t -i ubuntu:20.04 /bin/bash
root@049706bffe28:/#

输入 ls 命令:

root@049706bffe28:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

来解释一下 docker run -t -i 这个命令中的参数:

-t 选项让 docker 分配一个伪终端并绑定到容器的标准输入上

-i 交互式操作,也就是命令行模式进入容器

这2个参数也可以写一起:docker run -it ubuntu:20.04 /bin/bash

退出容器终端可以输入命令 exit

上面的两个参数还可以合一起:

docker run -dit ubuntu:20.04
  • 大部分情况下,我们希望 docker 是在后台的运行的。加 -d 指定容器运行模式, 默认不会进入容器,想要进入容器需要继续执行指令 docker exec,下面会介绍。

如果 docker 命令太长,还可以用 \\ 来换行,如下:

docker run -it --rm \\
    ubuntu:20.04 \\
    /bin/bash
  • -it:-i 交互操作,-t 终端,上面解释了
  • --rm:这个参数表示容器退出后随之将其删除
  • ubuntu:20.04:以 ubuntu:20.04 镜像为基础来启动容器
  • /bin/bash:放在镜像后面的是命令,有一个交互式的 shell,这里使用的 bash

启动已停止运行容器

启动已经停止运行容器:docker startdocker container start

重新启动容器:docker container restart 命令将一个运行态的容器终止,然后重新启动它

终止运行中容器:docker container stop 来终止一个运行中的容器

查看所有的容器:

VirtualBox:~$ sudo docker ps -a
CONTAINER ID   IMAGE       COMMAND      CREATED         STATUS          PORTS     NAMES
56ca83925f03 ubuntu:20.04  "/bin/bash"  15 minutes ago  Up 15 minutes             strange_allen   
c1482012b069 ubuntu:20.04  "/bin/bash"  26 minutes ago  Exited (0) 20 minutes ago gallant_ellis     

启动停止的容器 container id c1482012b069:

VirtualBox:~$ sudo docker start c1482012b069
c1482012b069
VirtualBox:~$ sudo docker ps -a
CONTAINER ID  IMAGE        COMMAND      CREATED         STATUS        PORTS     NAMES
56ca83925f03  ubuntu:20.04 "/bin/bash"  21 minutes ago   Up 20 minutes         strange_allen       
c1482012b069  ubuntu:20.04  "/bin/bash" 31 minutes ago   Up 8 seconds          gallant_ellis       

获取镜像

大量的镜像文件都存储在远端的镜像仓库中,比如 docker hub 。获取镜像的命令 docker pull ,语法为:

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

  • OPTIONS:选项,比如,-a
  • NAME[:TAG|@DIGEST]:镜像地址

获取 docker pull 更详细参数:docker pull --help

比如,拉取 ubuntu:20.04 这个镜像文件:

$ sudo docker pull ubuntu:20.04
20.04: Pulling from library/ubuntu
Digest: sha256:db8bf6f4fb351aa7a26e27ba2686cf35a6a409f65603e59d4c203e58387dc6b3
Status: Image is up to date for ubuntu:20.04
docker.io/library/ubuntu:20.04

由于前面启动镜像命令 docker run 运行了这个镜像文件,显示 Image is up to date for ubuntu:20.04 。

拉取镜像后,就可以启动这个镜像,命令 docker run

$ sudo docker run -it --rm ubuntu:20.04 bash
root@5c2a77428b80:/# 

-it-i 表示交互操作,-t 表示是一个终端

--rm:这个参数表示容器退出后会将其删除。在默认情况下,为了排障需要,退出的容器并不会马上删除,触发手动执行 docker rm。我这里只是演示命令的执行,不需要排障,--rm 可以避免浪费空间

ubuntu:20.04:表示镜像,以这个镜像来作为启动容器

bash:放在镜像后面的是命令。这里希望进入交互式 shell,所以用 bash

列出镜像

列出所有镜像

列出镜像的命令:docker image ls ,显示镜像下载到本地后,展开后各层所占用空间的总和。语法:

docker image ls [OPTIONS] [REPOSITORY[:TAG]]

关于 docker image ls 更多用法,可以查看帮助命令:docker image ls --help

$ sudo docker image ls
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
hello-world   latest    9c7a54a9a43c   2 weeks ago   13.3kB
ubuntu        20.04     88bd68917189   5 weeks ago   72.8MB

列出了仓库名、标签、镜像ID、创建时间、所占用的空间大小。

镜像ID是镜像的唯一标识符,一个镜像可以对应多个标签

列出部分镜像

列出部分镜像的命令:docker image ls 镜像名

比如下面例子;

$ sudo docker image ls ubuntu
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
ubuntu       20.04     88bd68917189   5 weeks ago   72.8MB

还可以加过滤的参数 --filter

$ sudo docker image ls --format ".ID: .Repository"
9c7a54a9a43c: hello-world
88bd68917189: ubuntu

删除本地镜像

删除本地镜像的命令:docker image rm,语法:

docker image rm [OPTIONS] IMAGE [IMAGE...]

上面大家镜像 IMAGE ,可以是镜像长ID、镜像短ID、镜像名 或镜像摘要。

比如用镜像短ID来删除镜像:

$ sudo docker image ls
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
hello-world   latest    9c7a54a9a43c   2 weeks ago   13.3kB
ubuntu        20.04     88bd68917189   5 weeks ago   72.8MB

$ sudo docker image rm 189

查看镜像详情

查看镜像详细信息的命令:docker image inspect

查看镜像 hello-world:latest 的详细信息:

docker image inspect hello-world:latest

搜索仓库镜像

搜索远程仓库镜像命令:docker search

例如 查看远程仓库中 ubuntu 的镜像有哪些:

docker search ubuntu

进入容器

使用 -d 参数,容器启动后可以进入后台。

在容器启动后,我们有时需要进入容器镜像操作,命令有 docker attachdocker exec ,推荐使用 docker exec , 因为 docker attach 进入容器操作完 exit 退出后,会导致容器停止,而 exec 不会。

docker attach 进入容器:

$ sudo docker run -dit ubuntu:20.04
c1482012b06914449cafd461931eb890dec01fa8e6858233d3fcc98de9ceb4bc

$ sudo docker container ls
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
c1482012b069   ubuntu:20.04   "/bin/bash"   53 seconds ago   Up 42 seconds             gallant_ellis

$ sudo docker attach c148
root@c1482012b069:/# 

上面参数 -d 表示容器启动后会进入后台运行。

注意:上面容器用 exit 退出后会导致容器停止运行

root@c1482012b069:/# exit
exit
VirtualBox:~$ sudo docker container ls
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

用命令查看容器,刚才运行的容器退出了。exec 就不会。

docker exec 进入容器:

// 运行容器
VirtualBox:~$ sudo docker run -dit ubuntu:20.04
56ca83925f039f9ba087aff8a521678e2dcc87836bffede90ed2f2614aec8065

// 列出容器列表
VirtualBox:~$ sudo docker container ls
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
56ca83925f03   ubuntu:20.04   "/bin/bash"   16 seconds ago   Up 13 seconds             strange_allen

// 进入容器
VirtualBox:~$ sudo docker exec -it 56ca bash
root@56ca83925f03:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

// 退出容器
root@56ca83925f03:/# exit
exit

退出容器后,在列出容器列表:

VirtualBox:~$ sudo docker container ls
CONTAINER ID   IMAGE          COMMAND       CREATED         STATUS         PORTS     NAMES
56ca83925f03   ubuntu:20.04   "/bin/bash"   2 minutes ago   Up 2 minutes             strange_allen

CONTAINER ID 和前面显示的 CONTAINER ID 相同,STATUS 状态也是 Up 2 minutes,运行状态,容器没有退出。

删除容器

删除终止状态的容器命令:docker container rm

docker container rm strange_allen
  • 如果要删除一个运行中的容器,加参数 -f

欢迎大家提建议,讨论,点赞

八、参考

Kubernetes 学习总结(20)—— Kubernetes 与微服务和容器之间是什么关系?

什么是微服务?

什么是微服务?你应该使用微服务吗?微服务与容器和 Kubernetes 有什么关系?从根本上讲,微服务只是一个运行在服务器或虚拟计算实例上并响应网络请求的计算机程序。这与典型的 Rails/Django/Node.js 应用程序有何不同?它根本上没有什么不同。事实上,您可能会发现您的组织中已经部署了十几个微服务。没有任何新的神奇技术使您的应用程序有资格称为微服务。微服务不是由它的构建方式来定义的,而是由它如何变成更通用的系统或解决方案来定义的。那么是如何使服务成为微服务呢?一般来说,微服务的范围更窄,专注于做好较小的任务。让我们通过看一个例子来进一步探索。

微服务示例:亚马逊产品列表

让我们检查在 Amazon 上为您提供此产品页面的系统。它包含几个信息块,可能是从不同的数据库中检索到的:

  • 产品描述,包括价格、标题、照片等。

  • 推荐项目,即其他人购买的类似书籍。

  • 与此项目相关的赞助商列表。

  • 关于本书作者的信息。

  • 顾客评论。

  • 您自己在亚马逊商店中浏览其他商品的历史记录。

如果您要快速编写用于此列表的代码,那么简单的方法将如下所示:

 当用户的请求来自浏览器时,它将由 Web 应用程序(Linux 或 Windows 进程)提供服务。通常,被调用的应用程序代码片段称为请求处理程序。处理程序内部的逻辑将依次多次调用数据库,获取呈现页面所需的信息并将其拼接在一起,然后呈现返回给用户的网页。很简单吧?事实上,许多 Ruby on Rails 书籍都有类似这样的教程和示例。那么,你可能会问,为什么要把事情复杂化?想象一下随着应用程序的增长和越来越多的工程师参与其中会发生什么。上面例子中的推荐引擎是由一小群程序员和数据科学家维护的。有几十个不同的团队负责渲染该页面的某些组件。这些团队中的每一个通常都希望获得以下自由:

  • 更改他们的数据库架构。

  • 快速且频繁地将他们的代码发布到生产环境中。

  • 使用他们选择的编程语言或数据存储等开发工具。

  • 在计算资源和开发人员生产力之间做出自己的权衡。

  • 偏好维护/监控其功能。

可以想象,随着时间的推移,让团队就发布 Web 商店应用程序的新版本的所有内容达成一致将变得更加困难。解决方案是将组件拆分为更小的、独立的服务(也就是微服务)。

 升级流程变得更小、更笨。它基本上是一个代理,它简单地将传入的页面请求分解为几个专门的请求,并将它们转发给相应的微服务,这些微服务现在是他们自己的进程并在其他地方运行。“应用微服务”基本上是专门服务返回的数据的聚合器。您甚至可以完全摆脱它并将该工作卸载到用户的设备上,让此代码在浏览器中作为单页 JavaScript 应用程序运行。其他微服务现在被分离出来,每个开发微服务的开发团队都可以:

  • 随心所欲地部署他们的服务,而不会干扰其他团队。

  • 以他们认为合适的方式扩展他们的服务。例如,使用他们选择的 AWS 实例类型,或者可能在专用硬件上运行。

  • 拥有自己特定于其服务的监控、备份和灾难恢复。

什么是容器?

从技术上讲,容器只是一个从可执行文件产生的进程,运行在 Linux 机器上,它有一些限制,例如:

  • 容器不允许“看到”所有文件系统,它只能访问其中的指定部分。

  • 一个容器不允许使用所有的 CPU 或 RAM。

  • 容器在如何使用网络方面受到限制。

从历史上看,现代操作系统总是对进程施加限制,例如每个 Linux 进程都以系统用户的权限运行,但是容器化技术引入了更多可能的限制并使其更加灵活。基本上,任何 Linux 可执行文件都可以受到限制,即可以“容器化”。大多数情况下,当人们说“容器”时,他们不仅仅指的是 Linux 进程,还指的是可执行文件的打包和存储方式。类似的工具 Docker 允许开发人员获取他们的可执行文件及其依赖项,以及他们想要的任何其他文件,并将它们全部打包成一个文件。这项技术与 tarball 之类的存档没有太大区别。Docker 还允许包含一些额外的指令和配置来运行这个打包的可执行文件。通常这些文件,通常称为“容器镜像”,也称为容器。但为了简单起见,请记住:

  • 一个容器就是一个运行受限制的 linux 进程

  • 容器镜像是可执行进程的依赖和配置打包

容器镜像是自给自足的。它们将在任何 Linux 机器上运行,因此容器化使得将代码从开发人员的机器复制(部署)到任何环境变得更加容易。

微服务和容器有什么区别?

我们刚刚了解到,容器只是一种打包、部署和运行 Linux 程序/进程的方法。您可以将一个巨大的单体应用程序作为容器,也可以拥有一群完全不使用容器的微服务。容器是一种有用的资源分配和共享技术。这是 DevOps 人们感到兴奋的事情。微服务是一种软件设计架构。这是开发人员感到兴奋的事情。它们是相关的,但不需要彼此。您可以将单体应用部署为容器,也可以拥有不受限制的、非容器化的微服务。

什么时候使用微服务?

微服务背后的想法并不新鲜。几十年来,软件架构师一直致力于将单体应用程序分解为可重用的组件。

微服务的优点

微服务的好处很多,包括:

  • 更简单的自动化测试;

  • 快速灵活的部署模式;

  • 更强弹性扩缩容。

采用微服务的另一个好处是能够为工作选择最佳工具。应用程序的某些部分可以从 C++ 的速度中受益,而其他部分可以从更高级别语言(例如 Python 或 JavaScript)的生产力提高中受益。

微服务的缺点

微服务的缺点包括:

  • 需要更仔细的规划;

  • 更高的研发投入;

  • 过度设计的诱惑。

如果应用程序和开发团队足够小并且工作量不具有挑战性,则通常无需投入额外的工程资源来解决您尚未解决的问题并使用微服务。但是,如果您开始看到微服务的利大于弊,这里有一些具体的设计注意事项:

  • 计算和存储分离。随着您对 CPU 能力和存储需求的增长,这些资源具有非常不同的扩展成本和特性。从一开始就不必依赖本地存储,这将使您能够相对轻松地适应未来的工作负载。这既适用于文件系统等简单的存储形式,也适用于数据库等更复杂的解决方案。

  • 异步处理。通过添加越来越多的相互调用的子进程或对象来逐步构建应用程序的传统方法随着工作负载的增长而停止工作,并且应用程序本身必须跨多台机器甚至数据中心扩展。将需要围绕事件驱动模型重新构建应用程序。这意味着发送事件(而不是等待结果)而不是调用函数并同步等待结果。

  • 拥抱消息总线。这是必须实现异步处理模型的直接后果。随着您的单体应用程序被分解为事件处理程序和事件发射器,就需要一个健壮、高性能和灵活的消息总线。有多种选择,选择取决于应用程序规模和复杂性。对于一个简单的用例,像 Redis 这样的东西就可以做到。如果您需要您的应用程序真正是云原生的并自行扩展和缩减,您可能需要能够处理来自多个事件源的事件:从 Kafka 等流管道到基础设施,甚至监控事件。

  • API 版本控制。由于您的微服务将使用彼此的 API 通过总线相互通信,因此设计用于保持向后兼容性的架构将是至关重要的。只需部署一个微服务的最新版本,开发人员就不应该要求其他人升级他们的代码。这将是向整体方法向后兼容的一步,开发团队必须在永远支持旧 API 和保持更高的开发速度之间达成合理的妥协。这也意味着 API 设计成为一项重要的技能。频繁的破坏性 API 更改是团队无法高效开发复杂微服务的原因之一。

  • 重新考虑您的安全性。许多开发人员没有意识到这一点,但迁移到微服务为更好的安全模型创造了机会。由于每个微服务都是一个专门的进程,因此最好只允许它访问所需的资源。这样,仅一个微服务中的漏洞就不会将系统的其余部分暴露给攻击者。这与大型单体形成对比,后者倾向于以更高的特权(每个人都需要的超集)运行,并且可能导致更多的违规行为。

Kubernetes 与微服务有什么关系?

Kubernetes 太复杂了,无法在此详细描述,但值得对其进行概述,因为很多人在有关微服务的对话中都会提到它。严格来说,Kubernetes(又名 K8s)的主要好处是通过跨多个进程高效共享计算资源来提高基础设施利用率。Kubernetes 是动态分配计算资源以满足需求的大师。这允许组织避免为他们不使用的计算资源付费。但是,K8s 的一些附带好处使向微服务的过渡变得更加容易。当您将单体应用程序分解为单独的、松散耦合的微服务时,您的团队将获得更多的自主权和自由度。但是,在与微服务必须运行的基础设施进行交互时,它们仍然必须密切合作。您必须解决以下问题:

  • 预测每个服务需要多少计算资源;

  • 这些要求在负载下如何变化;

  • 如何划分基础设施分区并将它们划分到微服务之间;

  • 实施资源限制。

Kubernetes 非常优雅地解决了这些问题,并提供了一个通用框架来描述、检查和推理基础设施资源的共享和利用。这就是为什么采用 Kubernetes 作为微服务重新架构的一部分是一个好主意。然而,Kubernetes 是一项需要学习的复杂技术,而且更难管理。如果可以,您应该利用云提供商提供的托管 Kubernetes 服务。但是,对于需要跨多个云提供商和企业数据中心运行自己的 Kubernetes 集群的公司来说,这并不总是可行的。

总结

  • 容器只是具有应用受限制的 Linux 进程。限制的示例包括允许进程使用多少 CPU 或内存。Docker 之类的工具允许开发人员将他们的可执行文件与依赖项和附加配置打包在一起。这些包被称为 镜像,并且经常且容易混淆地也被称为容器。

  • 微服务并不新鲜。这是一种旧的软件设计模式,由于互联网公司的规模不断扩大,它越来越受欢迎。微服务不一定要容器化。同样,单体应用程序可以是微服务。

  • 小项目不应该回避整体设计。它为较小的团队提供更高的生产力。

  • Kubernetes 是由多个微服务组成的复杂应用程序的绝佳平台。

  • Kubernetes 也是一个复杂的系统,学习曲线陡峭,管理成本非常高。

以上是关于kubernetes(k8s)大白学习02:容器和docker基础使用架构学习的主要内容,如果未能解决你的问题,请参考以下文章

Kubernetes快速实战与核心原理剖析

Kubernetes快速实战与核心原理剖析

k8s功能02:了解k8s全部功能

kubernetes(K8S) 容器管理“扫盲“ 学习笔记

kubernetes(K8S) 容器管理“扫盲“ 学习笔记

K8s学习从零开始搭建kubernetes集群环境(虚拟机/kubeadm方式)