Ingress / Service
在一个 k8s cluster中,如果我们需要从外部访问集群可以使用Type为NodePort的Service对外暴露我们的服务。以下是一个依赖关系样例:
# 创建一个nginx-pod
controlplane ~ ➜ kubectl run nginx-pod --image=nginx --port=80
pod/nginx-pod created
再使用以下内容,创建一个Service nginx-pod-svc.yml
apiVersion: v1
kind: Service
metadata:
name: nginx-pod-svc
spec:
type: NodePort
selector:
run: nginx-pod #通过run命令生成的pod所产生的标签
ports:
- port: 80
targetPort: 80
nodePort: 30001
查看Service信息并测试
controlplane ~ ➜ kubectl describe svc nginx-pod-svc
Name: nginx-pod-svc
Namespace: default
Labels: <none>
Annotations: <none>
Selector: run=nginx-pod
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.98.194.212
IPs: 10.98.194.212
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 30001/TCP
Endpoints: 10.244.1.2:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
# 本地测试 curl localhost:30001 访问成功
controlplane ~ ➜ curl localhost:30001
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
但是一般我们不想记住IP地址和端口号,而是使用域名来对应用进行访问,并且可以使用https进行安全链接,我们可以使用Ingress,这样我们就可以不用暴露Service的端口到Node上,通过域名进行访问应用。以下是依赖关系样例:
如果只有Ingress不足以实现流量转发,还需要Ingress Controller去实现
它的作用是评估和处理Ingress rules/管理重定向/进入cluster的入口
Ingress Controller
如果外部拥有云平台的Load Balancer,流量路由路径就会是这样:
Practise
首先修改之前的nginx-pod-svc.yml
,不需要对外暴露端口
controlplane ~ ➜ vi nginx-pod-svc.yml
controlplane ~ ➜ cat nginx-pod-svc.yml
apiVersion: v1
kind: Service
metadata:
name: nginx-pod-svc
spec:
type: ClusterIP
selector:
run: nginx-pod #通过run命令生成的pod所产生的标签
ports:
- port: 80
targetPort: 80
controlplane ~ ➜ kubectl replace -f nginx-pod-svc.yml
service/nginx-pod-svc replaced
controlplane ~ ➜ kubectl describe svc nginx-pod-svc
Name: nginx-pod-svc
Namespace: default
Labels: <none>
Annotations: <none>
Selector: run=nginx-pod
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.98.194.212
IPs: 10.98.194.212
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.2:80
Session Affinity: None
Events: <none>
controlplane ~ ➜ curl localhost:30001
curl: (7) Failed to connect to localhost port 30001 after 0 ms: Connection refused
要使用Ingress,首先需要Ingress Controller
Ingress-Nginx Controller
这里使用Ingress-Nginx Controller
# 使用helm安装
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
# 生成一个新的namespace
controlplane ~ ➜ kubectl get ns
NAME STATUS AGE
default Active 4h15m
ingress-nginx Active 71s
kube-flannel Active 4h15m
kube-node-lease Active 4h15m
kube-public Active 4h15m
kube-system Active 4h15m
# 生成新的Pod
controlplane ~ ➜ kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-controller-69bd47995d-gr55b 1/1 Running 0 72s
然后我们创建提供httpd服务的Pod和Service
controlplane ~ ➜ kubectl run httpd-pod --image=httpd --port=80
pod/httpd-pod created
httpd-pod-svc.yml
apiVersion: v1
kind: Service
metadata:
name: httpd-pod-svc
spec:
type: ClusterIP
selector:
run: httpd-pod #通过run命令生成的pod所产生的标签
ports:
- port: 80
targetPort: 80
测试
controlplane ~ ➜ vi httpd-pod-svc.yml
controlplane ~ ➜ kubectl apply -f httpd-pod-svc.yml
service/httpd-pod-svc created
controlplane ~ ➜ kubectl describe svc httpd-pod-svc
Name: httpd-pod-svc
Namespace: default
Labels: <none>
Annotations: <none>
Selector: run=httpd-pod
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.98.177.252
IPs: 10.98.177.252
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.3:80
Session Affinity: None
Events: <none>
controlplane ~ ➜ curl 10.98.177.252
<html><body><h1>It works!</h1></body></html>
配置Ingress,通过不同的域名访问不同的服务
# 查看ingressclass
controlplane ~ ➜ kubectl get ingressclasses.networking.k8s.io
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none> 19m
Ingress
创建Ingress ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: http-ing
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: nginx-pod-svc.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-pod-svc
port:
number: 80
- host: httpd-pod-svc.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: httpd-pod-svc
port:
number: 80