K8s - Kubernetes使用详解6(Service的创建和使用)

作者: hangge 发布时间: 2019-09-02 浏览: 1985 次 编辑

    Pod 中的容器很可能因为各种原因发生故障而死掉, Controller 会通过动态创建和销毁 Pod 来保证应用整体的健壮性。而由于每次新 Pod 都会分配到新的 IP 地址,为了能让客户端找到并访问这个服务,Kubernetes 给出了 Service 这个解决方案。

六、Service 的创建和使用

1,Service 介绍

(1)Kubernetes Service 从逻辑上代表了一组 Pod,具体是哪些 Pod 则是由 label 来挑选。

(2)Service 有自己 IP,而且这个 IP 是不变的。

  • 客户端只需要访问 Service 的 IPKubernetes 则负责建立和维护 Service 与 Pod 的映射关系。

  • 无论后端 Pod 如何变化,对客户端不会有任何影响,因为 Service 没有变。

2,基本用法

(1)首先编辑一个配置文件 httpd.yml,内容如下:

多个资源文件可以都在一个 YAML 中定义,用“---”分割。这里我们将 Deployment 和 Service 都放在一个配置文件中:

  • Deployment 部分:启动了三个 pod,运行 httpd 镜像,label 是 run:httpdservice 将会用这个 label 来挑选 pod。 

  • Service 部分:挑选那些 label 为 run:httpd 的 pod 作为 service 后端的,并且将 8080 端口映射到 pod 的 80 端口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: httpd
spec:
  replicas: 3
  template:
    metadata:
      labels:
        run: httpd
    spec:
      containers:
      - name: httpd
        image: httpd
        ports:
        - containerPort: 80
---
apiVersion: v1 # v1是service的apiversion
kind: Service # 当前资源的类型为 Service。
metadata:
  name: httpd-svc # Service 的名字为 httpd-svc。
spec:
  selector: # elector 指明挑选那些 label 为 run: httpd 的 Pod 作为 Service 的后端。
    run: httpd
  ports: # 将 Service 的 8080 端口映射到 Pod 的 80 端口,使用 TCP 协议。
  - protocol: TCP
    port: 8080
    targetPort: 80


(2)接着执行如下命令创建 Deployment 和 Service

1
kubectl apply -f httpd.yml


(3)可以看到目前启动了三个 podpod 分配了各自的 IP,这些 IP 只能被 kubernetes Cluster 中的容器和节点访问。

1
kubectl get pod -o wide

原文:K8s - Kubernetes使用详解6(Service的创建和使用)


(4)执行如下命令可以查看我们创建的 Service(名字为 httpd-svc),它被分配到了一个 CLUSTER-IP 10.104.166.77

1
kubectl get service

原文:K8s - Kubernetes使用详解6(Service的创建和使用)


(5)我们可以通过这个 IP 访问后端的 httpd Pod。具体转发到哪个后端 Pod,使用的是类似轮询的负载均衡策略。

1
curl 10.104.166.77:8080

原文:K8s - Kubernetes使用详解6(Service的创建和使用)

(6)执行如下命令可以查看 httpd-svc 与 Pod 的对应关系。

1
kubectl describe service httpd-svc

原文:K8s - Kubernetes使用详解6(Service的创建和使用)

3,DNS 访问 Service

    在 Cluster 中,除了可以通过 Cluster IP 访问 ServiceKubernetes 还提供了更为方便的 DNS 访问。 kubeadm 部署时会默认安装 kube-dns 组件。kube-dns 是一个 DNS 服务器。每当有新的 Service 被创建,kube-dns 会添加该 Service 的 DNS 记录。

(1)集群中的 Pod 可以通过 <SERVICE_NAME>.<NAMESPACE_NAME> 访问 Service。比如下面我们在一个临时的 busybox Pod 中访问之前创建的 httpd-svc 这个 Service

1
2
kubectl run busybox --rm -ti --image=busybox /bin/sh
wget httpd-svc.default:8080

原文:K8s - Kubernetes使用详解6(Service的创建和使用)


(2)由于这个临时的 busybox Pod 与 httpd-svc 同属一个default 命名空间(namespace),可以省略 default 直接用 httpd-svc 访问 Service

1
wget httpd-svc:8080

原文:K8s - Kubernetes使用详解6(Service的创建和使用)

4,从外网访问 Service

在之前的样例中,我们创建的 Service 通过 Cluster 内部的 IP 对外提供服务,这种方式只有 Cluster 内的节点和 Pod 可访问。
有时我们希望应用的 Service 能够暴露给 Cluster 外部,那么 Service 可以通过 Cluster 节点的静态端口对外提供服务。Cluster 外部可以通过 <NodeIP>:<NodePort> 访问 Service

(1)要启用 NodePort,首先我们需要在 Service 配置中添加 type: NodePort

原文:K8s - Kubernetes使用详解6(Service的创建和使用)


(2)接着重新创建 httpd-svc 后可以发现,Kubernetes 依然会为 httpd-svc 分配一个 ClusterIP,不同的是 PORT(S) 变为了 8080:31512

  • 8080 是 ClusterIP 监听的端口

  • 31512 则是节点上监听的端口(Kubernetes 会从 30000-32767 中分配一个可用的端口,每个节点都会监听此端口并将请求转发给 Service

原文:K8s - Kubernetes使用详解6(Service的创建和使用)


(3)外部网络通过任一节点 IP + 31512 端口都能访问 httpd-svc

原文:K8s - Kubernetes使用详解6(Service的创建和使用)


(4)NodePort 默认是的随机选择,不过我们可以用 nodePort 指定某个特定端口。比如下面指定使用 31111 端口。

原文:K8s - Kubernetes使用详解6(Service的创建和使用)


原文链接:https://www.hangge.com/blog/cache/detail_2435.html