k8s 之 Service 资源

Service 资源是为动态管理的 Pod 对象添加一个固定访问入口。

Service 为四层调度器

service 通过标签选择器关联至拥有相关标签的 Pod 对象

客户端向 Service 进行请求,而非目标 Pod 对象,当 Service 资源变动时,有 kube-proxy 控制器将规则应用至本机 iptables 或者 ipvs 规则。

而 kube-proxy 为 DaemonSet 控制器将会在集群中每个节点运行一个 Pod 或者守护进程
如果需要转换 ipvs 规则,则需要手动加载 ipvs 模块进入内核

iptables 代理模式,对于每个 Service 对象,kube-proxy 会创建 iptables 规则直接捕获到达 cluster ip 和 Port 流量,并将其重定向至当前 Service 对象的后端 Pod 资源,对于每个 Endpoint 对象,Service 资源会为其创建 iptables 规则并关联

ipvs 代理模式 kube-proxy 跟踪 API server 上 Service 和 Endpoints(ip+port) 对象变动,来调用 netlink 接口创建 ipvs 规则,并确保于 API server 中变动同步,于 iptables 规则不同之处仅在处于其请求流量的调度功能有 ipvs 实现,余下的其他功仍然由 iptables 完成

servcie 资源定义:

|

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

|

[root@node1 ~]# vim svc.yml

apiVersion: v1

kind: Service

metadata:

  name: myapp

  namespace: prod

spec:

  ports: #ports 字段定义 svc 端口与后端哪个端口相关连

  - name: http #ports 字段名称

    port: 80 #svc 端口

    targetPort: 80# 目标后端端口

    nodePort: 30080 #自定义 nodePort 端口

  selector:# 标签选择器

    app: myapp

    rel: stable

type: NodePort#NodePort 可以定义一个端口给外部范围

##### 直接访问 svc 地址就会调度至后端匹配的标签的 pod 中即便控制器增加或者减少,svc 也会自动关联新增 pod

[root@node1 chapter5]# kubectl get svc

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

kubernetes ClusterIP 10.96.0.1 443/TCP        2d5h

myweb        NodePort    10.100.112.31 80:30593/TCP 2d1h

[root@node1 chapter5]# kubectl get svc -n prod

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

myapp ClusterIP 10.105.226.215 80/TCP    2m2s

[root@node1 chapter5]# curl 10.105.226.215

Hello MyApp | Version: v2 | Pod Name

[root@node1 chapter5]#

|

svc 类型

clusterIP:为一个 svc 分配一个当前集群内的动态地址,客户端 pod 对象访问服务的 Pod 对象时不会进行源地址转换,且不会被外部地址访问,只能在集群内部被访问。

NodePort:对于某 svc 来说会在每个节点生成一个 ipvs 规则打开节点端口,映射至 svc ip 的端口上。

还可以手动创建 endpoints 资源将 ip 地址指向外部。将名称命名为 svc 相同时即可

|

1

2

|

kubectl edit cm kube-proxy -n kube-system

|

在线修改 configmap 文件,使其加载 ipvs 规则

|

1

2

|

kubectl delete pod -l k8s-app=kube-proxy,pod-template-generation=1 -n kube-system ## 删除 pod,让 ipvs 规则在 kube-proxy 生效

|

生效之后的 pod 会生成 ipvs 规则。

Ingress 资源,7 层代理 | 调度

标准的 api 对象,管理外部请求到内部流量。协议为 http,仅用域定义流量转发和调度的通用格式的配置信息,它们需要转换为特定的具有 http 协议转发和调度功能的应用程序的配置文件,并由相应的应用程序生效,相应的配置后完成流量转发

|

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

|

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml 部署 ingress

[root@node1 ingress]# vim ingress-svc.yml              

apiVersion: v1

kind: Service

metadata:

  name: ingress

  namespace: ingress-nginx

spec:

  selector:

    app.kubernetes.io/name: ingress-nginx

    app.kubernetes.io/part-of: ingress-nginx

  ports:

  - name: http

    port: 80

  - name: https

    port: 443

  type: NodePort

|

部署 svc 使其外部网络能够访问至 ingress


创建后端 pod,并为 pod 指定 svc 资源

|

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

|

[root@node1 ~]# vim myns-ingress.yaml              

apiVersion: apps/v1

kind: Deployment

metadata:

  name: myapp

  namespace: myns

spec:

  replicas: 2

  selector:

    matchLabels:

      app: myapp

      rel: beta

  template:

    metadata:

      namespace: myns

      labels:

        app: myapp

        rel: beta

    spec:

      containers:

      - name: myapp

        image: ikubernetes/myapp:v1


apiVersion: v1

kind: Service

metadata:

  name: myapp

  namespace: myns

spec:

  selector:

    app: myapp

    rel: beta

  ports:

  - name: http

    port: 80

    targetPort: 80

|

创建 ingress 资源,为之前创建的 ingress-nginx 这个程序提供 ingress 配置。

|

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

|

apiVersion: extensions/v1beta1

kind: Ingress #资源类型

metadata: #元数据

  name: myapp

  namespace: myns

  annotations: #此字段为资源注解,作为配置信息提供方

    kubernetes.io/ingress.class: “nginx”

spec: #定义 ingress 内部资源

  rules:

  - host: www.node1.com #定义后端主机

  - http: ## 定义后端资源

      paths:

      - path: / #定义后端映射路径为 /

        backend: #后端资源

          serviceName: myapp #此为 svc 资源名称

          servicePort: 80 #此为 svc 端口

|

创建成功,会自动关联至 myapp 此 svc,且会绑定后端资源

此时直接访问宿主机即可访问后端资源

使用 https 访问

|

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

|

openssl genrsa -out myapp.key 2048 ## 生成私钥

openssl req -new -x509 -key myapp.key -out myapp.crt -subj /C=CN/ST=Beijing/L=Beijing/O=ops/CN=www.node.com -days 365 #自签名

[root@node1 ~]# kubectl create secret tls ilinux-cert -n myns –cert=myapp.crt –key=myapp.key

secret/ilinux-cert created #在集群中创建证书。

## 配置成使用证书的 ingress

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: tls-ingress

  namespace: myns

  annotations:

    kubernetes.io/ingress.class: “nginx”

spec:

  tls: #引用证书

  - hosts: #此主机需要为证书签名时指定的域名一致

    -  www.node.com

    secretName: ilinux-cert #secre 资源的名称。就是我们刚才创建的 k8s 资源

  rules: #后端规则,需前一份资源系统

    - host: www.node1.com

      http:

        paths:

        - path: /

          backend:

            serviceName: myapp

            servicePort: 80

#############################

[root@node1 ~]# kubectl get ingress -n myns

NAME          HOSTS ADDRESS PORTS AGE

myapp www.node1.com 80        52m

tls-ingress www.node.com              80, 443 51s

|

创建完成

|

1

2

|

kubectl exec -it nginx-ingress-controller-568867bf56-lrm4f -n ingress-nginx – /bin/sh## 连接至 pod 内容器,配置文件会自动填充我们定义的 ingress 的配置

|