欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

K8S实践Ⅳ(Service)

程序员文章站 2024-03-11 17:20:01
...

一、Service概念

通过创建service可以为一组具有相同功能的容器应用提供一个统一的入口地址,并将请求负载分发到后端的各个容器应用上。

二、Service基本用法

1.定义一个web服务的RC,由两个tomcat容器副本组成

# cat webapp-rc.yaml 
apiVersion: v1
kind: ReplicationController
metadata:
  name: webapp
spec:
  replicas: 2
  template:
    metadata:
      name: webapp
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: tomcat
        ports:
        - containerPort: 8080

2.创建该RC

# kubectl get pod
NAME           READY   STATUS    RESTARTS   AGE
webapp-t5q4g   1/1     Running   0          17m
webapp-wq88m   1/1     Running   0          17m
# kubectl get pods -l app=webapp -o yaml | grep  podIP
    podIP: 10.44.0.2
    podIP: 10.36.0.1

3.使用kubectl expose创建一个SVC

# kubectl expose rc webapp
service/webapp exposed
# kubectl get svc
webapp       ClusterIP   10.111.192.152   <none>        8080/TCP   8s

4.通过svc地址和端口访问

# curl 10.111.192.152:8080

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/8.5.42</title>
......

对svc地址10.111.192.152:8080的访问被自动负载分发到了后端的两个Pod之一10.44.0.2:8080或10.36.0.1:8080。
kubernets提供了两种负载分发策略:RoundRobin和SessionAffinity,默认情况下采用的是RoundRobin模式进行负载。

  • RoundRobin:轮询模式
  • SessionAffinity:粘性会话,将来自同一个客户端的请求始终转发至同一个后端的Pod对象,可以通过设置service.spec.sessionAffinity: ClientIP来启用

5.使用配置文件方式创建svc

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  type: ClusterIP
  ports:
  - port: 8081
    targetPort: 8080
  selector:
    app: webapp

ports:与后端容器端口关联
selector:关联到哪些pod资源上

# kubectl delete svc webapp
service "webapp" deleted
# kubectl create -f webapp-svc.yaml 
service/webapp created
# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
webapp       ClusterIP   10.96.231.61     <none>        8081/TCP   14s

6.多端口Service创建

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  ports:
  - port: 8080
    targetPort: 8080
    name: web
  - port: 8005
    targetPort: 8005
    name: management
  selector:
    app: webapp

7.使用UDP端口模式

apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "KubeDNS"
spec:
  selector:
    k8s-app: kube-dns
  clusterIP: 169.169.0.100
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP

8.外部服务Service

在一些环境中,应用系统需要将一个外部数据库作为后端服务进行连接,这时可以通过创建一个没有Selector的svc来实现

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

由于这个 Service 没有 selector,就不会创建相关的 Endpoints 对象。可以手动将 Service 映射到指定的 Endpoints:

kind: Endpoints
apiVersion: v1
metadata:
  name: my-service
subsets:
- addresses:
  - IP: 1.2.3.4
  ports:
  - port: 80

三、Headless Service

有时不需要或不想要负载均衡,以及单独的 Service IP。 遇到这种情况,可以通过指定 Cluster IP(spec.clusterIP)的值为 "None" 来创建Headless Service,仅通过Selector将后端的Pod列表返回给调用的客户端

创建一个Headless Service实例

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  ports:
  - port: 80
  clusterIP: None
  selector:
    app: nginx
# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
nginx        ClusterIP   None         <none>        80/TCP    26s

四、从集群外部访问Pod或Service

1.将容器应用的端口映射到物理机

# cat pod-hostport.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: webapp
  labels:
    app: webapp
spec:
  containers:
  - name: webapp
    image: tomcat
    ports:
    - containerPort: 8080
      hostPort: 8081

此处映射的IP地址为该Pod所在node的IP

# curl 20.0.20.103:8081

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/8.5.42</title>
        <link href="favicon.ico" rel="icon" type="image/x-icon" />
        <link href="favicon.ico" rel="shortcut icon" type="image/x-icon" />

通过设置spce.hostNetwork=true,默认hostPort等于containerPort

apiVersion: v1
kind: Pod
metadata:
  name: webapp
  labels:
    app: webapp
spec:
  hostNetwork: true
  containers:
  - name: webapp
    image: tomcat
    ports:
    - containerPort: 8080

2.将Service的端口映射到物理机

# cat webapp-rc.yaml 
apiVersion: v1
kind: ReplicationController
metadata:
  name: webapp
spec:
  replicas: 2
  template:
    metadata:
      name: webapp
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: tomcat
        ports:
        - containerPort: 8080
# cat webapp-svcnodeport.yaml 
apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 30011
  selector:
    app: webapp
# curl 20.0.20.101:30011

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/8.5.42</title>
        <link href="favicon.ico" rel="icon" type="image/x-icon" />
        <link href="favicon.ico" rel="shortcut icon" type="image/x-icon" />