从 Kubernetes 谈容器网络

26 篇文章 5 订阅
21 篇文章 2 订阅

基本概念

在 Kubernetes 中,资源从管理粒度上分为三级:容器、Pod、Service。

容器

即 Docker 或者 Rocket 容器(1.0 中仅支持这两种容器)。

容器是最低粒度的资源,但是不能被直接操作。

Pod

Kubernetes 中的基本操作单元(非单个容器)。

Pod 是一组共享了下面资源的(运行在同一节点上的)容器:

  • 进程命名空间
  • 网络命名空间
  • IPC 命名空间(可以 SystemV IPC 或 POSIX 消息队列通信)
  • UTS 命名空间(同一主机名称)

可以将一个 Pod 当作是一个抽象的“虚拟机”,里面运行若干个不同的进程(每个进程实际上就是一个容器)。

比如某个后端应用是若干处理组件组成,可以作为一个后端 Pod。

一个 Pod,往往带有若干 label,比如 type=prod, app=nginx 之类,并且被 kubelet 汇报到 Endpoints 中记录。

实现上,是先创建一个 gcr.io/google_containers/pause 容器,然后创建同一个 Pod 中的其它容器,共享 pause 容器的命名空间。

Kubernetes 要干的事情是要把这些 Pod 给互相连接起来,是不是联想到了什么了?跟虚拟机网络的基本需求是相同的。

Service

Service 是一类运行相同/相似应用(通过 label 来过滤)的 Pod,组成一个完整的服务。比如一组前端 Pod,形成一个前端 Service。

Service 主要是为了: 解耦直接对 Pod 的访问(Pod 是动态的,随时可能停止或变化) 提供隐式的负载均衡(可以配置均衡策略到后端真实的 Pod)

访问其实是以 Service 为单位的,可以通过 DNS 或者(写入环境变量的) Cluster 地址来解耦掉实际的 Pod 地址。实现上是通过 Kube-Proxy 进程。

kube-proxy

实际上,每个节点上都会运行一个 Kube-Proxy 进程,负责将到某个 Service 的访问给代理或者均衡(仅支持 TCP)到具体的 Pod 上去。

具体的,对每一个 service 的访问地址(比如:10.0.0.2:80),Kube-Proxy 都会配置 DNAT 规则(从容器出来的访问,从本地主机的访问两方面),将到这个地址的访问映射到本地的一个随机端口。然后 Kube-Proxy 会监听在本地的对应端口,将到这个端口的访问给代理到远端真实的 pod 地址上去。

Replication-Controller

Replication-Controller 主要是为了实现对 Pod 的自动化运维管理(类似 Linux/Nodejs 等平台上的 sueprvisor 工具)。它可以保障集群内某个 Pod 的运行实例的个数。

这样,当某 Pod 出现故障停止时候,可以自动启动新的同样类型的 Pod 来避免服务受到影响。一般推荐通过 Replication-Controller 来创建和管理 Pod。Pod 需要设置 RestartPolicy = Always,同时也是默认值。

设计理念

其实 Docker 默认采用 NAT 的方式已经组成了简单的网络了。但Kubernetes 认为 Docker 的默认网络采用了 NAT 方式,跨节点通信就需要进行端口映射,这会给服务的访问带来麻烦。

设计理念包括如下几点:

  • 所有容器不使用 NAT 就可以互相通信(这跟 Docker 的默认实现是不同的);
  • 所有节点跟容器之间不使用 NAT 就可以互相通信;
  • 容器自己看到的地址,跟其他人访问自己使用的地址应该是一样的(其实还是在说不要有 NAT)。

实现

要满足上面的要求,也不难,最简单的方法,容器网络地址空间跟外部网络的数据空间打通即可,即容器内网络地址直接暴露到物理网上去。

Kubernetes 的基于 GCE 的实现就是这种机制,给每个物理节点直接分配一个内部子网(默认是 /24 的),这样每个 Pod 就能分到一个地址了(意味着每个节点最多 256 个 Pod)。这个地址是直接暴露到物理网络上的,可以直接进行路由。

想让 Pod 访问外网也很简单,在通往外部网络的网关上做一把 SNAT 即可。

扩展

当然,在此基础上还可以进行扩展,比如下面几种方案:

CoreOS 的 Flannel

Flannel内部流量出到物理网之前,非本地的流量过一下整个内部网的网关,然后用 UDP/VXLAN 封装下,直接 tunnel 到对端后进行解包。

Weave

Weave

Weave 的网络设计也是对承载网这部分进行改进,对这部分流量进行封装,发送到对端的 peer 上,但不清楚封装协议类型。

socketplane

SocketPlane 的思路也是大同小异,在主机之间建 Tunnel,本地网桥默认使用 OpenvSwitch。

不同的主机发现采用 mDNS。

这家被 Docker 给收购了,很奇怪,背后应该有一些故事。

OpenStack Neutron

其实,现在的面向虚拟机的网络方案(比如 OpenStack Neutron)早就已经实现了上面的几点,而且使用网络虚拟化的手段,能做到比上面具有更加丰富和灵活的特性。例如,不同物理机上的容器可以拥有任意相同或者不同的子网,并且可以实现多租户的概念。

如果使用 Nova-Docker 来管容器的话,默认采用的就是 Neutron 网络。

结论和展望

网络的设计离不开对需求的深入分析。

从目前的几个项目来看,大家都是在模仿虚拟机的网络来实现容器的网络,甚至还有不少地方没有达到虚拟机网络的成熟度。

未来至少应该从下面两个方面去考虑设计容器网络:

  • 本地的优化:虚拟机的本地网络经过多年优化已经逼近了线速,但容器网络在这方面还有不少坑,特别对物理设备虚拟化技术的支持等。挖掘性能,降低对主机资源的消耗,仍有一些工作要做;
  • 网络特性的优化:容器网络根本上跟虚拟机网络存在很大的差异,这体现在容器的生命周期和使用行为上有很大的不同,传统的网络特性并不能很好地满足这些需求。

转载请注明:http://blog.csdn.net/yeasy/article/details/46443933


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是 Hyperf 官方提供的通过 Kubernetes 实现容器化部署的文档,供您参考: 1. 部署环境要求 - 操作系统:Linux - Docker:18.06.0-ce 或更高版本 - Kubernetes:1.11.0 或更高版本 2. 部署步骤 2.1 创建 Docker 镜像 首先,您需要创建一个 Docker 镜像,该镜像包含了 Hyperf 应用程序以及其依赖项。您可以使用 Dockerfile 来定义镜像的构建过程。示例 Dockerfile 如下: ``` FROM php:7.4-fpm # 安装依赖 RUN apt-get update && \ apt-get install -y git zip unzip && \ docker-php-ext-install pdo_mysql && \ pecl install redis && \ docker-php-ext-enable redis # 安装 Composer COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # 复制 Hyperf 应用程序 COPY . /var/www # 安装依赖项 WORKDIR /var/www RUN composer install # 暴露端口 EXPOSE 9501 # 启动命令 CMD ["php", "bin/hyperf.php", "start"] ``` 其中,我们使用了 `php:7.4-fpm` 作为基础镜像,安装了 Hyperf 应用程序所需的依赖项,并将应用程序复制到了 `/var/www` 目录中。我们还使用了 Composer 安装了应用程序的依赖项,并暴露了端口 `9501`。在启动容器时,我们使用了 `php bin/hyperf.php start` 命令来启动 Hyperf 应用程序。您可以根据实际情况修改 Dockerfile。 然后,使用以下命令构建 Docker 镜像: ``` docker build -t your-image-name . ``` 其中,`your-image-name` 是您的镜像名称。 2.2 创建 Kubernetes 部署文件 接下来,您需要创建 Kubernetes 的部署文件,该文件定义了如何部署 Hyperf 应用程序。示例部署文件如下: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: your-deployment-name labels: app: your-app-name spec: replicas: 3 selector: matchLabels: app: your-app-name template: metadata: labels: app: your-app-name spec: containers: - name: your-container-name image: your-image-name ports: - name: http containerPort: 9501 ``` 其中,您需要修改以下部分: - `your-deployment-name`:您的部署名称。 - `your-app-name`:您的应用程序名称。 - `your-container-name`:您的容器名称。 - `your-image-name`:您的 Docker 镜像名称。 该部署文件定义了一个名为 `your-deployment-name` 的部署,使用了名为 `your-image-name` 的 Docker 镜像,并将端口 `9501` 暴露出来。该部署文件还定义了应用程序的副本数为 `3`。 2.3 创建 Kubernetes 服务文件 接下来,您需要创建 Kubernetes 的服务文件,该文件定义了如何访问 Hyperf 应用程序。示例服务文件如下: ```yaml apiVersion: v1 kind: Service metadata: name: your-service-name spec: selector: app: your-app-name ports: - name: http port: 80 targetPort: http type: LoadBalancer ``` 其中,您需要修改以下部分: - `your-service-name`:您的服务名称。 - `your-app-name`:您的应用程序名称。 该服务文件定义了一个名为 `your-service-name` 的服务,使用了应用程序名称为 `your-app-name` 的部署。该服务将端口 `80` 映射到了端口 `9501`,并使用了负载均衡器。 2.4 部署应用程序 最后,使用以下命令部署应用程序: ``` kubectl apply -f your-deployment-file.yaml kubectl apply -f your-service-file.yaml ``` 其中,`your-deployment-file.yaml` 和 `your-service-file.yaml` 分别是您的部署文件和服务文件。 部署完成后,您可以使用以下命令查看服务的 IP 地址和端口号: ``` kubectl get services ``` 然后,您可以使用浏览器或其他工具访问 Hyperf 应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值