0%

Docker--外部访问K8s中Pod的五种方式

HostNetwork

这是一种直接定义Pod网络的方式。
如果在Pod中使用hostNetwork:true配置的话,在这种pod中运行的应用程序可以直接看到pod启动的主机的网络接口。在主机的所有网络接口上都可以访问到该应用程序.
一般配合k8s的亲和使用,需要配置nodeSelector.

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@tmpcluster-master-1 ~]# cat hostNetwork.yaml 
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
hostNetwork: true
containers:
- name: redis
image: redis
imagePullPolicy: IfNotPresent


[root@tmpcluster-master-1 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
redis 1/1 Running 0 101m 18.16.203.103 tmpcluster-worker-1 <none> <none>

[root@tmpcluster-master-1 ~]# ssh tmpcluster-worker-1
Last login: Wed Mar 31 16:02:41 2021 from 18.16.200.2

[root@tmpcluster-worker-1 ~]# ss -natlp|grep 637
LISTEN 0 128 *:6379 *:* users:(("redis-server",pid=330350,fd=6))
LISTEN 0 128 :::6379 :::* users:(("redis-server",pid=330350,fd=7))

[root@tmpcluster-master-1 ~]# telnet 18.16.203.103 6379
Trying 18.16.203.103...
Connected to 18.16.203.103.
Escape character is '^]'.

HostPort

hostPort是直接将容器的端口与所调度的节点上的端口映射,这样用户就可以通过宿主机的IP加上来访问Pod.
切记: 只能调度到没有端口冲突的node上, 需要单独维护pod和宿主机的关系表,相对来说比较麻烦

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@tmpcluster-master-1 ~]# cat hostPort.yaml 
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
ports:
- containerPort: 6379
hostPort: 6379

[root@tmpcluster-master-1 ~]# kubectl create -f hostPort.yaml
[root@tmpcluster-master-1 ~]# telnet 18.16.203.103 6379
Trying 18.16.203.103...
Connected to 18.16.203.103.
Escape character is '^]'.

NodePort

需要配合service使用,K8s中的service大部分情况都是使用Cluster IP这种类型,会产生一个只能在内部访问的Cluster IP,如果想能够直接访问service,需要将svc type修改为nodePort。同时给svc指定一个nodeport值(默认是从30001开始,也可以在设置中自行修改,然后重载docker配置)

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
[root@tmpcluster-master-1 ~]# cat nodeport.yaml nodeport-svc.yaml 
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
kind: Service
apiVersion: v1
metadata:
name: redis
spec:
type: NodePort
ports:
- port: 6379
nodePort: 30000
selector:
name: redis

[root@tmpcluster-master-1 ~]# kubectl describe services redis
Name: redis
Namespace: default
Labels: <none>
Annotations: Selector: name=redis
Type: NodePort
IP: 179.50.24.132
Port: <unset> 6379/TCP
TargetPort: 6379/TCP
NodePort: <unset> 30000/TCP
Endpoints: <none>
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>

[root@tmpcluster-master-1 ~]# telnet 18.16.203.103 6379
Trying 18.16.203.103...
Connected to 18.16.203.103.
Escape character is '^]'.

LoadBalancer

只能在云上符合使用
创建服务时,可以选择自动创建云网络负载均衡器。这提供了一个外部可访问的 IP 地址, 可将流量分配到集群节点上的正确端口上 ( 假设集群在支持的环境中运行,并配置了正确的云负载平衡器提供商包)。

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
[root@tmpcluster-master-1 ~]#  cat k8s-yaml/tmp-ns/test-server/test-server-svc.yaml 
apiVersion: v1
kind: Service
metadata:
name: test-server
annotations:
service.beta.kubernetes.io/backend-type: "eni"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: "lb-xxxxxxxxxxxxx"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-force-override-listeners: "true"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-protocol-port: "http:4010"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-flag: "on"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-type: "http"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-uri: "/health"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-healthy-threshold: "4"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-unhealthy-threshold: "4"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-timeout: "10"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-interval: "3"
labels:
app: test-server
namespace: tmp-ns
spec:
selector:
app: test-server
type: LoadBalancer
ports:
- name: http
port: 4010
protocol: TCP
targetPort: 8080

[root@tmpcluster-master-1 ~]# kubectl get svc security-server -n base-server
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
test-server LoadBalancer 172.21.5.189 192.168.100.222 4010:30533/TCP 10m

[root@tmpcluster-master-1 ~]# kubectl describe svc test-server -n tmp-ns
Name: test-server
Namespace: tmp-ns
Labels: app=test-server
service.beta.kubernetes.io/hash=b841232d1321323c1212327f50sd3a3sdf23b9fb78
Annotations: service.beta.kubernetes.io/alibaba-cloud-loadbalancer-force-override-listeners: true
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-flag: on
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-interval: 3
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-timeout: 10
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-type: http
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-uri: /health
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-healthy-threshold: 4
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: lb-xxxxxxxxxxxxx
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-protocol-port: http:4010
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-unhealthy-threshold: 4
service.beta.kubernetes.io/backend-type: eni
Selector: app=test-server
Type: LoadBalancer
IP: 172.21.5.189
LoadBalancer Ingress: 192.168.100.222
Port: http 4010/TCP
TargetPort: 8080/TCP
NodePort: http 30533/TCP
Endpoints: 192.168.22.46:8080,192.168.24.9:8080
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>

Ingress

Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。
Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。
可以将 Ingress 配置为服务提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及提供基于名称的虚拟主机等能力。 Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
直接以域名的形式进行对外暴露, 可以配合负载均衡和dns解析使用,直接访问对应的域名即可.入口就是80端口,然后Ingress controller直接将流量转发给后端Pod,不需再经过kube-proxy的转发,比LoadBalancer方式更优选。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@tmpcluster-master-1 ~]#  cat test-ingress.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
namespace: test-service
spec:
rules:
- host: aaa.com
http:
paths:
- backend:
serviceName: test
servicePort: 4053

[root@iZbp1egtbul3dj8svxv3x5Z ~]# kubectl get ingress yearning -n ops-service
NAME HOSTS ADDRESS PORTS AGE
yearning aaa.com 22.22.22.22 80 172d