[toc]

Service网络服务

资源分类

  • NodePort:
    • 宿主机节点的端口
  • ClusterIP:
    • 用来动态发现和负载均衡POD的IP,通过 Label(标签) 绑定POD
  • PodIP:
    • 提供POD使用的IP

image-20230614171404803

ClusterIP资源

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 编写ClusterIP资源清单
vim clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: apache-cluster
spec:
selector:
run: php-apache ## POD的标签
ports:
- name: php
port: 8080 ## clusterIP 端口
protocol: TCP
targetPort: 80 ## POD的端口
type: ClusterIP

# 应用资源清单
kubectl apply -f clusterip.yaml
service/apache-cluster created

# 查看service资源
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
apache-cluster ClusterIP 10.1.154.54 <none> 8080/TCP 84s
kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 6d8h

# 查看service资源
kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
apache-cluster ClusterIP 10.1.154.54 <none> 8080/TCP 3m41s
kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 6d8h

# 测试网络是否连通
curl 10.1.154.54:8080

# 查看cluster资源详细信息
kubectl describe svc apache-cluster
Name: apache-cluster
Namespace: default
Labels: <none>
Annotations: <none>
Selector: run=php-apache
Type: ClusterIP
IP: 10.1.154.54
Port: php 8080/TCP
TargetPort: 80/TCP
Endpoints: 10.2.1.30:80
Session Affinity: None
Events: <none>

NodePort资源

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
29
30
31
32
33
34
35
36
37
# 编写NodePort资源清单
vim nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: apache-nodeport
spec:
selector:
run: php-apache
ports:
- name: php
port: 8080 ## clusterIP端口
protocol: TCP
targetPort: 80 ## POD的端口
nodePort: 30000 ## node宿主机上映射的端口
type: NodePort

# 端口映射结构
宿主机:30000 -> ClusterIP:8080 -> POD:80

# 应用资源清单
kubectl apply -f nodeport.yaml

# 查看service资源
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
apache-nodeport NodePort 10.1.234.200 <none> 8080:30000/TCP 12s
kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 6d8h
## 注意:如果使用nodeport,默认会启动一个clusterIP
1.宿主机使用30000端口,用户体验不好?
2.域名该绑定在哪台机器?

# 应用资源清单
kubectl apply -f nodeport.yaml
The Service "apache-nodeport" is invalid: spec.ports[0].nodePort: Invalid value:
80: provided port is not in the valid range. The range of valid ports is 30000-
32767

示例:使用k8s资源启动h5小游戏(ns:h5)

分开创建资源清单

  • 需求

  • 指定名称空间:h5

  • 名称空间资源

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # 编辑创建h5名称空间的资源清单
    vim h5-ns.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
    name: h5

    # 应用资源清单
    kubectl apply -f h5-ns.yaml
    namespace/h5 created

    # 查看名称空间
    kubectl get ns
    NAME STATUS AGE
    default Active 6d8h
    h5 Active 5s
    kube-flannel Active 6d7h
    kube-node-lease Active 6d8h
    kube-public Active 6d8h
    kube-system Active 6d8h
    nginx-ingress Active 7h40m
    test-mysql Active 5d8h
  • POD资源:deployment控制器

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    # 编辑资源清单
    vim h5-dp.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: h5-dp
    namespace: h5
    spec:
    selector:
    matchLabels:
    app: h5
    replicas: 5
    template:
    metadata:
    labels:
    app: h5
    name: h5-pod
    namespace: h5
    spec:
    volumes:
    - name: h5-code
    hostPath:
    path: /code/h5
    containers:
    - name: h5-container
    image: nginx:alpine
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: h5-code
    mountPath: /usr/share/nginx/html/

    # 应用资源清单
    kubectl apply -f h5-dp.yaml

    # 查看pod启动状态
    kubectl get pod -n h5
    NAME READY STATUS RESTARTS AGE
    h5-dp-59f7b9c546-8kb8b 1/1 Running 0 25s
    h5-dp-59f7b9c546-m5g7w 1/1 Running 0 25s
    h5-dp-59f7b9c546-p4nkz 1/1 Running 0 25s
    h5-dp-59f7b9c546-pcx79 1/1 Running 0 25s
    h5-dp-59f7b9c546-s5d74 1/1 Running 0 25s
  • HPA

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    # 编辑资源清单
    vim h5-hpa.yaml
    apiVersion: autoscaling/v1
    kind: HorizontalPodAutoscaler
    metadata:
    name: h5-hpa
    namespace: h5
    spec:
    maxReplicas: 10
    minReplicas: 1
    scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: h5-dp
    targetCPUUtilizationPercentage: 50

    # 应用资源清单
    kubectl apply -f h5-hpa.yaml

    # 查看HPA资源状态
    kubectl get hpa -n h5
    NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
    h5-hpa Deployment/h5-dp <unknown>/50% 1 10 5 40s
  • ClusterIP/NodePort

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    # 编辑资源清单
    vim h5-node.yaml
    apiVersion: v1
    kind: Service
    metadata:
    name: h5-nodeport
    namespace: h5
    spec:
    selector:
    app: h5
    ports:
    - name: h5
    port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 32767
    type: NodePort

    # 应用资源清单
    kubectl apply -f h5-node.yaml

    # 查看service资源状态
    kubectl get svc -n h5
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    h5-nodeport NodePort 10.1.168.14 <none> 80:32767/TCP 25s

    # 查看service资源详细状态
    kubectl describe svc h5-nodeport -n h5
    Name: h5-nodeport
    Namespace: h5
    Labels: <none>
    Annotations: <none>
    Selector: app=h5
    Type: NodePort
    IP: 10.1.168.14
    Port: h5 80/TCP
    TargetPort: 80/TCP
    NodePort: h5 32767/TCP
    Endpoints: 10.2.1.31:80,10.2.1.32:80,10.2.1.33:80 + 2 more...
    Session Affinity: None
    External Traffic Policy: Cluster
    Events: <none>

优化:合并资源清单

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# 编辑资源清单
vim h5-game.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: h5

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: h5-dp
namespace: h5
spec:
selector:
matchLabels:
app: h5
replicas: 5
template:
metadata:
labels:
app: h5
name: h5-pod
namespace: h5
spec:
volumes:
- name: h5-code
hostPath:
path: /code/h5
containers:
- name: h5-container
image: nginx:alpine
imagePullPolicy: IfNotPresent
volumeMounts:
- name: h5-code
mountPath: /usr/share/nginx/html/

---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: h5-hpa
namespace: h5
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: h5-dp
targetCPUUtilizationPercentage: 50

---
apiVersion: v1
kind: Service
metadata:
name: h5-nodeport
namespace: h5
spec:
selector:
app: h5
ports:
- name: h5
port: 80
protocol: TCP
targetPort: 80
nodePort: 32767
type: NodePort

# 应用资源清单
kubectl apply -f h5-game.yaml

nodeport 缺点

  1. 没有ingress之前,pod对外提供服务只能通过NodeIP:NodePort的形式,但是这种形式有缺点,一个节点上的port不能重复利用。比如某个服务占用了80,那么其他服务就不能在用这个端口了。
  2. NodePort是4层代理,不能解析7层的http,不能通过域名区分流量
  3. 为了解决这个问题,我们需要用到资源控制器叫Ingress,作用就是提供一个统一的访问入口。工作在7层
  4. 虽然我们可以使用nginx/haproxy来实现类似的效果,但是传统部署不能动态的发现我们新创建的资源,必须手动修改配置文件并重启。
  5. 适用于k8s的ingress控制器主流的有nginx-ingress和traefik

ingress网络资源

使用ingress解决nodeport缺陷

image-20230614171625442

ingress部署

1
2
3
# 官方ingress
wget https://raw.githubusercontent.com/kubernetes/ingressnginx/master/deploy/static/provider/baremetal/deploy.yaml -O nginx-ingress.yaml
# github搜索kubeguide

image-20230614210538910

image-20230614210559900

image-20230614210617887

image-20230614210635900

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 找到第五版,第四章
wget https://github.com/kubeguide/K8sDefinitiveGuide-V5-Sourcecode/blob/main/Chapter04/4.6.1%20nginx-ingress-controller.yaml

# 修改资源清单
1)"kind: Deployment"改为"kind: DaemonSet"
2)删除 replicas: 1
3)删除:
nodeSelector:
role: ingress-nginx-controller

# 应用资源清单
kubectl apply -f ingress.yaml

# 查看pod状态
kubectl get pod -n nginx-ingress
NAME READY STATUS RESTARTS AGE
nginx-ingress-84xwq 1/1 Running 0 8h
nginx-ingress-p6rdx 1/1 Running 0 8h

使用ingress启动h5网站

  • 创建名称空间

    1
    2
    3
    4
    5
    6
    # 编辑资源清单
    vim h5-ns.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
    name: h5
  • 启动pod和deploment控制器

    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
    29
    30
    # 编辑资源清单
    vim h5-dp.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: h5-dp
    namespace: h5
    spec:
    selector:
    matchLabels:
    app: h5
    replicas: 5
    template:
    metadata:
    labels:
    app: h5
    name: h5-pod
    namespace: h5
    spec:
    volumes:
    - name: h5-code
    hostPath:
    path: /code/h5
    containers:
    - name: h5-container
    image: nginx:alpine
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: h5-code
    mountPath: /usr/share/nginx/html/
  • service资源

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # 编辑资源清单
    vim h5-cluster.yaml
    apiVersion: v1
    kind: Service
    metadata:
    name: h5-cluster
    namespace: h5
    spec:
    selector:
    app: h5
    ports:
    - name: h5
    port: 80
    protocol: TCP
    targetPort: 80
    type: ClusterIP
  • 合并优化资源清单

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    # 编辑资源清单
    vim ingress-h5.yaml
    ---
    apiVersion: v1
    kind: Namespace
    metadata:
    name: h5

    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: h5-dp
    namespace: h5
    spec:
    selector:
    matchLabels:
    app: h5
    replicas: 5
    template:
    metadata:
    labels:
    app: h5
    name: h5-pod
    namespace: h5
    spec:
    volumes:
    - name: h5-code
    hostPath:
    path: /code/h5
    containers:
    - name: h5-container
    image: nginx:alpine
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: h5-code
    mountPath: /usr/share/nginx/html/

    ---
    apiVersion: v1
    kind: Service
    metadata:
    name: h5-cluster
    namespace: h5
    spec:
    selector:
    app: h5
    ports:
    - name: h5
    port: 80
    protocol: TCP
    targetPort: 80
    type: ClusterIP
  • 应用资源清单

    1
    kubectl apply -f ingress-h5.yaml
  • 查看状态

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # 查看POD状态
    kubectl get pod -n h5
    NAME READY STATUS RESTARTS AGE
    h5-dp-59f7b9c546-8kb8b 1/1 Running 0 74m
    h5-dp-59f7b9c546-m5g7w 1/1 Running 0 74m
    h5-dp-59f7b9c546-p4nkz 1/1 Running 0 74m
    h5-dp-59f7b9c546-pcx79 1/1 Running 0 74m
    h5-dp-59f7b9c546-s5d74 1/1 Running 0 74m

    # 查看ns状态
    kubectl get ns
    NAME STATUS AGE
    default Active 6d10h
    h5 Active 80m

    # 查看ClusterIP
    kubectl get svc -n h5
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    h5-cluster ClusterIP 10.1.173.4 <none> 80/TCP 3m4s
  • 使用ingress关联ClusterIP

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 使用ingress关联ClusterIP
vim h5-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: h5-ingress
namespace: h5
spec:
rules:
- host: www.h5.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: h5-cluster
port:
number: 80

# ingress配置详解
spec:
rules: # 网站规则
- host: www.h5.com # 域名
http: # http层配置
paths: # location
- path: / # location /{}
pathType: ImplementationSpecific # 路径匹配规则 系统默认
backend: # 后端配置,ingress需要找到后端的clusterIP
service: # service网络
name: h5-cluster # clusterIP的名字 kubectl get svc -n h5
port: # clusterIP的端口
number: 80 # 端口号
# pathType(路径匹配规则)
- ImplementationSpecific 系统默认,由IngressClass控制器提供
- Exact 精确匹配URL路径,区分大小写
- Prefix 匹配URL路径的前缀,区分大小写

# 启动ingress资源
kubectl apply -f h5-ingress.yaml
ingress.networking.k8s.io/h5-ingress created

# 查看ingress状态
kubectl get ingress -n h5
NAME CLASS HOSTS ADDRESS PORTS AGE
h5-ingress <none> www.h5.com 80 22s

服务发现

概念

我们也可以使用DNS域名的形式访问Service,如果在同一个命名空间里甚至可以直接使用service(clusterIP的名字)名来访问服务。

但即便处于不同的名称空间都可以进行通讯

结构图示

image-20230615180518095

使用语法

在不同的名称空间,进行通信的语法

1
2
3
4
5
# 语法格式
servicename.namespace.svc.cluster.local

# 示例
ping php-cluster.default.svc.cluster.local