Kubernetes 网络基础介绍

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
简介: 如果你读过该系列的前一篇文章,那么在你的集群里应该已经成功运行着Gitea的deployment了。下一步是能够通过Web浏览器访问它。本文会介绍一些Kubernetes的网络基础知识,并且可以让外部网络可以访问Gitea容器。
如果你读过该系列的 前一篇文章 ,那么在你的集群里应该已经成功运行着Gitea的deployment了。下一步是能够通过Web浏览器访问它。本文会介绍一些Kubernetes的网络基础知识,并且可以让外部网络可以访问Gitea容器。

打开容器端口

Pod默认是和外部隔离的。为了能够将流量导入应用程序,我们需要打开该容器计划使用的一系列端口。

Gitea容器内的软件会监听3000端口上的http请求,以及22端口上的SSH链接。可以通过如下YAML文件打开这些端口:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: gitea-deployment
spec:
replicas: 1
selector:
matchLabels:
 app: gitea
template:
metadata:
 labels:
 app: gitea
spec:
 containers:
 - name: gitea-container
 image: gitea/gitea:1.4
 ports: #+
 - containerPort: 3000 #+
 name: http #+
 - containerPort: 22 #+
 name: ssh 

在集群里应用这个更新过的文件:
$ kubectl apply -f gitea.yaml

这时,就可以运行命令 kubectl describe deployment 来查看新打开的端口了。Pod应该已经打开了3000和22端口。
$ kubectl describe deployment | grep Ports
Ports: 3000/TCP, 22/TCP

1.png

使用端口转发进行调试

容器上的端口应该已经开启了,但是我们仍然需要能够和集群里的pod通信。为了调试的方便,我们可以使用 kubectl port-forward 来连接Pod。
# grab the name of your active pod
$ PODNAME=$(kubectl get pods --output=template \
 --template="{{with index .items 0}}{{.metadata.name}}{{end}}")

# open a port-forward session to the pod
$ kubectl port-forward $PODNAME 3000:3000

这样, kubectl 就会将本机3000端口的所有连接转发到云上的pod里。在浏览器打开 http://localhost:3000 ,你就可以和服务器交互了,服务器就像运行在本地一样。
2.png

3.png

创建外部LoadBanlancer

既然已经验证了Pod工作正常,就可以暴露到公网上了。我们需要添加一个新的Kubernetes资源,它会预配一个公网IP地址并且将入站请求路由到Pod上。可以使用称为Service(服务)的Kubernetes资源来达到这一目的。可以使用 好几种不同类型的服务 ,但是这里我们使用LoadBalancer。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: gitea-deployment
spec:
replicas: 1
selector:
matchLabels:
 app: gitea
template:
metadata:
 labels:
 app: gitea
spec:
 containers:
 - name: gitea-container
 image: gitea/gitea:1.4
 ports:
 - containerPort: 3000
 name: http
 - containerPort: 22
 name: ssh
---
kind: Service #+
apiVersion: v1 #+
metadata: #+
name: gitea-service #+
spec: #+
selector: #+
app: gitea #+
ports: #+
- protocol: TCP #+
targetPort: 3000 #+
port: 80 #+
name: http #+
- protocol: TCP #+
targetPort: 22 #+
port: 22 #+
name: ssh #+
type: LoadBalancer #+

和Deployment一样,Service使用选择器(第29-30行)。这个选择器告诉LoadBanlancer将流量路由到哪些Pod里。当LoadBanlancer收到请求时,它会智能地将负载分发给匹配这个选择器的所有Pod。这里,因为我们仅有一个Pod,所以负载均衡很简单。

LoadBanlancer管理的端口定义在31-39行。除了定义一个唯一名称以及协议类型(TCP/UDP)之外,用户还必须定义“port”和“targetPort”。这两个字段定义了外部IP的端口(port)和容器使用端口(targetPort)的映射。在33和34行里,LoadBanlancer会监听80端口的请求(Web浏览器查看网页的默认端口),并且将请求转发给Pod的3000端口。

我们再次需要将更改应用到集群里:
$ kubectl apply -f gitea.yaml

等待几分钟变更生效后,检查服务:
$ kubectl get service

NAME TYPE CLUSTER-IP EXTERNAL_IP AGE
gitea-service LoadBalancer 10.27.240.34 35.192.x.x 2m

几分钟后,就能看到一个外部IP自动添加到了服务上。在web浏览器里打开这个IP就可以和pod上的web服务器交互了。
4.png

Pod间通信:ClusterIP服务

如果你尝试打开Gitea的注册页面,会看到还缺了一些东西:Gitea要求一个数据库才能提供这个功能。要解决这个问题,我们可以选择在Gitea Pod里以 side-car 的形式添加一个MySQL容器,或者单独创建一个MySQL的Pod。这两种方法都有各自的优势和缺点,选择哪一个取决于具体的需求。本文我们创建一个新的Pod。

我们创建一个名为mysql.yaml的新YAML文件来管理数据库:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mysql-deployment
spec:
replicas: 1
selector:
matchLabels:
 app: mysql
template:
metadata:
 labels:
 app: mysql
spec:
 containers:
 - name: mysql
 image: mysql:5.6
 ports:
 - containerPort: 3306
 # Ignore this for now. It will be explained in the next article
 env:
 - name: MYSQL_ALLOW_EMPTY_PASSWORD
 value: "true"
---
kind: Service
apiVersion: v1
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
type: ClusterIP

大部分内容很类似。我们声明了一个Deployment来管理这个pod,通过Service管理网络连接。这里,service的类型是“ClusterIP”;这意味着这个IP仅仅暴露在集群内部,这和之前使用LoadBanlancer将Gitea服务暴露到外部不一样。

在集群里应用这个新YAML文件:
$ kubectl apply -f mysql.yaml

这时你可以看到集群里新加了一个Pod、Deployment和Service。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
gitea-pod 1/1 Running 0 9m
mysql-pod 1/1 Running 0 9s

$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
gitea-deployment 1 1 1 1 11m
mysql-deployment 1 1 1 1 5m

$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL_IP AGE
gitea-service LoadBalancer 10.27.240.34 35.192.x.x 2m
mysql-service ClusterIP 10.27.254.69 <none> 6m

5.png

ClusterIP服务会自动生成一个内部IP地址,显示在上面控制台输出的“CLUSTER-IP”一栏。集群内的任何容器都可以使用这一地址访问MySQL pod。但是,并不推荐直接使用内部IP地址。Kubernetes提供了更为简单的方式来访问这个新服务:可以在地址字段输入“mysql-service”即可。这是因为内建了“ kube-dns ”Pod,它为所有服务管理内部的DNS解析。这样,用户可以忽略随机生成的内部IP地址,仅仅使用静态的,可读的服务名称就可以了。

要让Gitea能够和MySQL Pod通信,仅仅需要在Web UI的“host”字段输入服务的名称和端口就可以了。如果一切和预期一样,就会看到“access denied”的错误。这意味着Pod可以成功通信了,但是它们需要更多的配置信息才能完成认证。下一篇博客会继续介绍如何完成认证。
6.png

下一步

本文介绍了Kubernetes网络的基础知识,包括容器端口,端口转发,LoadBanlancer以及ClusterIP服务和kube-dns。当然,网络是一个很大的领域,没有讨论的还有很多。如果你想了解Kubernetes的底层网络实现,可以参考 这个系列 。如果你对控制集群里的哪些Pod可以通信感兴趣,可以阅读 网络策略 。如果你想更好地控制服务间的相互通信,可以研究服务网格产品,比如 Istio

备注

  1. LoadBanlancer在云服务,比如GCP上工作很好,但是如果你在Docker或者Minikube上运行本地集群,就需要使用NodePort服务代替
  2. 外部端口可以设置成任意值,但是要记住如果你想访问非标准的东西,在GKE上需要设置防火墙规则。
  3. 这里使用MySQL因为Gitea是这么设计的。MySQL是一种遗留服务,并非Kubernetes原生的,如果你想从头开始设计应用程序,可能别的存储方案更为适合。
  4. Kubernetes管理一些隐藏的pod和服务。可以运行kubectl get pods --namespace=kube-system查看它们。
本文转自DockOne-Kubernetes网络基础介绍
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
3月前
|
Kubernetes 负载均衡 网络安全
Kubernetes 网络模型与实践
【8月更文第29天】Kubernetes(K8s)是当今容器编排领域的佼佼者,它提供了一种高效的方式来管理容器化应用的部署、扩展和运行。Kubernetes 的网络模型是其成功的关键因素之一,它支持服务发现、负载均衡和集群内外通信等功能。本文将深入探讨 Kubernetes 的网络模型,并通过实际代码示例来展示服务发现和服务网格的基本概念及其实现。
111 1
|
3月前
|
Kubernetes Devops 持续交付
DevOps实践:使用Docker和Kubernetes实现持续集成和部署网络安全的守护盾:加密技术与安全意识的重要性
【8月更文挑战第27天】本文将引导读者理解并应用DevOps的核心理念,通过Docker和Kubernetes的实战案例,深入探讨如何在现代软件开发中实现自动化的持续集成和部署。文章不仅提供理论知识,还结合真实示例,旨在帮助开发者提升效率,优化工作流程。
|
1月前
|
Kubernetes 网络协议 网络安全
k8s中网络连接问题
【10月更文挑战第3天】
103 7
|
1月前
|
Kubernetes 应用服务中间件 nginx
搭建Kubernetes v1.31.1服务器集群,采用Calico网络技术
在阿里云服务器上部署k8s集群,一、3台k8s服务器,1个Master节点,2个工作节点,采用Calico网络技术。二、部署nginx服务到k8s集群,并验证nginx服务运行状态。
352 1
|
2月前
|
Kubernetes 容器 Perl
Kubernetes网络插件体系及flannel基础
文章主要介绍了Kubernetes网络插件体系,特别是flannel网络模型的工作原理、配置和测试方法。
105 3
Kubernetes网络插件体系及flannel基础
|
1月前
|
Kubernetes 容器
基于Ubuntu-22.04安装K8s-v1.28.2实验(三)数据卷挂载NFS(网络文件系统)
基于Ubuntu-22.04安装K8s-v1.28.2实验(三)数据卷挂载NFS(网络文件系统)
122 0
|
3月前
|
Kubernetes Cloud Native 网络安全
云原生入门指南:Kubernetes和容器化技术云计算与网络安全:技术融合的新篇章
【8月更文挑战第30天】在云计算的浪潮中,云原生技术如Kubernetes已成为现代软件部署的核心。本文将引导读者理解云原生的基本概念,探索Kubernetes如何管理容器化应用,并展示如何通过实践加深理解。
|
3月前
|
Kubernetes 网络协议 网络安全
在K8S中,容器提供一个服务,外部访问慢,到底是容器网络问题?还是容器服务问题?这种怎么排查?
在K8S中,容器提供一个服务,外部访问慢,到底是容器网络问题?还是容器服务问题?这种怎么排查?
|
3月前
|
Kubernetes 监控 Shell
在K8S中,我们公司用户反应pod连接数非常多,希望看一下这些连接都是什么信息?什么状态?怎么排查?容器里面没有集成bash环境、网络工具,怎么处理?
在K8S中,我们公司用户反应pod连接数非常多,希望看一下这些连接都是什么信息?什么状态?怎么排查?容器里面没有集成bash环境、网络工具,怎么处理?
|
3月前
|
Kubernetes 监控 网络协议
在K8S中,如果因为网络原因导致Pod异常,该如何排查?
在K8S中,如果因为网络原因导致Pod异常,该如何排查?
下一篇
无影云桌面