k8s-service使用

时间:2022-07-22
本文章向大家介绍k8s-service使用,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

为什么要使用Service?

在K8s中,我们知道Pod是最小的运行单元,所有的容器均在跑在Pod中,我们希望Pod是健壮的,但Pod中的容器可能因为各种原因而挂掉,而Deployment控制器会通过动态创建和销毁Pod来保证应用整体的健壮性,而Pod都有自己的IP地址,当控制器通过调度,用新的Pod替代发生故障的Pod时,Pod的IP地址肯定会发生变化的,所以问题就来了,假如发生故障的这一组Pod是对外提供HTTP服务的,客户端通过访问这个地址来获取资源,现在地址变化了,客户端就得更改请求地址,这样就会非常麻烦,所以kubernetes提供了Service。

Service从逻辑上代表了一组Pod,具体是哪些Pod则是由label来进行挑选,而Sercice自己的IP是保持不变的,无论后端Pod的IP如何发生变化,kubernetes都能保证Service与Pod的映射关系保持不变,对客户端来说不会有任何影响

下面看示例

# cat httpd-svc.yaml

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
kind: Service
metadata:
name: httpd-svc
spec:
selector:
​    run: httpd
ports:
- protocol: TCP
​    port: 8080
​    targetPort: 80

这里将多个资源写在了一个yml文件中,用—分隔

查看Service

# kubectl get svc

NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
httpd-svc             ClusterIP   10.110.222.103   <none>        8080/TCP         23m

查看Pod情况

# kubectl get pods -o wide

NAME                      READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES

httpd-8c6c4bd9b-9x7s4     1/1     Running   0          25m   10.244.2.31   node2   <none>           <none>

httpd-8c6c4bd9b-jr9gl     1/1     Running   0          25m   10.244.1.41   node1   <none>           <none>

httpd-8c6c4bd9b-jskg4     1/1     Running   0          25m   10.244.1.42   node1   <none>           <none>

这里删除一个Pod

# kubectl delete pods httpd-8c6c4bd9b-9x7s4

pod "httpd-8c6c4bd9b-9x7s4" deleted

再次查看Pod情况

# kubectl get pods -o wide

NAME                      READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES

httpd-8c6c4bd9b-jr9gl     1/1     Running   0          26m   10.244.1.41   node1   <none>           <none>

httpd-8c6c4bd9b-jskg4     1/1     Running   0          26m   10.244.1.42   node1   <none>           <none>

httpd-8c6c4bd9b-znlhn     1/1     Running   0          16s   10.244.2.34   node2   <none>           <none>


Pod的IP地址已经发生了变化,再看下Service的地址是否变化

# kubectl get svc -o wide

NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE   SELECTOR

httpd-svc             ClusterIP   10.110.222.103   <none>        8080/TCP         28m   run=httpd

访问测试

# curl 10.110.222.103:8080

<html><body><h1>It works!</h1></body></html>

以上是在整个集群内部访问的,但是如果我们需要对外提供服务怎么办呢?先来看下提供了哪几种类型的Service

  • ClusterIP
    • Service通过Cluster内部的IP对外提供服务,只有Cluster内的节点和Pod可访问,这是默认的Service类型
  • NodePort
    • Service通过Cluster节点的静态端口对外提供服务
  • LoadBalancer
    • Service利用Cloud provider特有的load balancer对外提供服务,cloud provider负责将Load balancer的流量导向Service

下面以NodePort为例

# cat httpd2-svc.yml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: httpd2
spec:
replicas: 3
template:
​    metadata:
​      labels:
​        run: httpd2
​    spec:
​      containers:
​      - name: httpd2
​        image: httpd
​        ports:
​        - containerPort: 80 

---
apiVersion: v1
kind: Service
metadata:
name: httpd2-svc
spec:
type: NodePort
selector:
​    run: httpd2
ports:
- protocol: TCP
​    nodePort: 30000      #这里可以设定要映射的端口,默认会随机生成一个
​    port: 8080
​    targetPort: 80

查看映射后的Service情况

# kubectl get svc -o wide

NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE   SELECTOR

httpd-svc             ClusterIP   10.110.222.103   <none>        8080/TCP         40m   run=httpd

httpd2-svc            NodePort    10.100.91.36     <none>        8080:30000/TCP   38m   run=httpd2

访问测试

# curl 192.168.152.143:30000

<html><body><h1>It works!</h1></body></html>