53

Kubernetes 120:网络基础

 5 years ago
source link: http://dockone.io/article/8296?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

如果你读过该系列的前一篇文章,那么在你的集群里应该已经成功运行着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
RBbAnyB.png!web

使用端口转发进行调试

容器上的端口应该已经开启了,但是我们仍然需要能够和集群里的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 ,你就可以和服务器交互了,服务器就像运行在本地一样。

Y7zEbiM.png!webjUF3Uzj.png!web

创建外部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服务器交互了。

7v6NruN.png!web

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

enter link description here

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

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

下一步

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

备注

kubectl get pods --namespace=kube-system
原文链接: Kubernetes 120: Networking Basics (翻译:崔婧雯)

===========================

译者介绍

崔婧雯,现就职于IBM,高级软件工程师,负责IBM WebSphere业务流程管理软件的系统测试工作。曾就职于VMware从事桌面虚拟化产品的质量保证工作。对虚拟化,中间件技术,业务流程管理有浓厚的兴趣。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK