0%

从零开始搭建k8s集群环境(七)——部署Ingress服务

系列目录:

经过几天的部署、熟悉和理解,对 k8s 的概念和结构都有了一定了解。而在实际操作中,我们的服务运行在服务器,通常都会做反向代理和负载均衡,增强灵活性。这篇博客就来实现 k8s 的反向代理和负载均衡。

环境说明:

  • Master:VBox虚拟机/Centos_7.5-1804/192.168.56.100
  • Images:VBox虚拟机/Centos_7.5-1804/192.168.56.101
  • Node01:VBox虚拟机/Centos_7.5-1804/192.168.56.102

软件环境说明:

  • docker-ce-17.03.2
  • kubernetes-v1.9.0
  • harbor-v1.4.0

一、结构梳理

  再部署之前,我们先过一遍 k8s 的结构。在 k8s 中,我们的服务以 Pod 为单位分布在一个或多个物理 Node 之上,这些 Pod 通过每个 Node 上运行的 kube-proxy 中转向外提供服务。如果同一组 Pod 是运行在同一个 Node 之上的时候,我们可以通过 nodePort 直接向外暴露服务(比如上一篇部署的UI控制台就是通过这种方式),但是通常情况为了提高服务可用性,Pod 一般都是分布在多个 Node 上运行,但每个 Node 的对外 IP 不尽相同,客户调用的时候不方便切换和维护,更重要的是客户很难对众多 Node 做负载均衡等操作。   很明显,我们就需要一个类似 Nginx 这样的服务来“包容”这些提供服务的 Node,把负载均衡、反向代理的事情统统交给他去做。当然我们也可以手动创建一个运行在 k8s 上面的 Nginx 服务,直接实现上面的操作,但又有新的问题,当我们服务变动频繁,岂不是又得跟着手动改动 Nginx ?不!我们是程序员,一切能自动化解决的问题,我们一定要写个程序来实现它!   幸运的是,这个程序已经有人帮我们写好了,他就是——Ingress-Nginx

GitHub:kubernetes/ingress-nginx Home Page:NGINX Ingress Controller

二、部署测试服务

之前在第五篇安装网络的时候我们已经部署了一个用来测试 Pod 直接网络的服务,这里我们仍旧继续使用这个服务作为我们的测试服务,但我们需要改动一下它的 yaml 文件,使其支持 Ingress 自动处理。

http-test.yaml 文件修改后内容如下:

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
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: http-test-dm
spec:
replicas: 3
template:
metadata:
labels:
name: http-test-dm
spec:
containers:
- name: http-test-con
image: registry.cn-shenzhen.aliyuncs.com/lx0758-per/http-test:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: http-test-ser
spec:
ports:
- port: 80
targetPort: 80
selector:
name: http-test-dm
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: http-test-ing
spec:
rules:
- host: test.6xyun.lan
http:
paths:
- path: /
backend:
serviceName: http-test-ser
servicePort: 80

可以看到,我们只是在原来的基础上追加了一个 kind: Ingress 对象,内容就是使用 test.6xyun.lan 这个域名负载均衡到 http-test-ser 这个服务的 80 端口。改动完之后我们把他重新部署。

部署完之后在集群内就多了一样东西:

1
2
3
[root@localhost ~]# kubectl get ing -o wide
NAME HOSTS ADDRESS PORTS AGE
http-test-ing * 80 16m

这就是用以将 ServerIngress 关联起来的东西。

三、部署 Ingress 服务

yaml 文件

1
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml

镜像

由于是从谷歌拉取,所以老规矩,阿里云走起:

1
2
3
4
5
6
7
docker pull registry.cn-shenzhen.aliyuncs.com/lx0758/defaultbackend:1.4
docker tag registry.cn-shenzhen.aliyuncs.com/lx0758/defaultbackend:1.4 gcr.io/google_containers/defaultbackend:1.4
docker rmi registry.cn-shenzhen.aliyuncs.com/lx0758/defaultbackend:1.4

docker pull registry.cn-shenzhen.aliyuncs.com/lx0758/nginx-ingress-controller:0.15.0
docker tag registry.cn-shenzhen.aliyuncs.com/lx0758/nginx-ingress-controller:0.15.0 quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.15.0
docker rmi registry.cn-shenzhen.aliyuncs.com/lx0758/nginx-ingress-controller:0.15.0

修改 yaml 文件

实际操作发现,服务器的 yaml 有些地方并不太合理,所以还得手动修改一下。

修改镜像 pull 策略和部署节点(注意是两个 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
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: default-http-backend
labels:
app: default-http-backend
namespace: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app: default-http-backend
template:
metadata:
labels:
app: default-http-backend
spec:
# 强制部署到某节点
nodeName: localhost.master
terminationGracePeriodSeconds: 60
containers:
- name: default-http-backend
# Any image is permissible as long as:
# 1. It serves a 404 page at /
# 2. It serves 200 on a /healthz endpoint
image: gcr.io/google_containers/defaultbackend:1.4
# 修改镜像 pull 策略
imagePullPolicy: IfNotPresent
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
73
74
75
76
77
78
79
80
81
82
83
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app: ingress-nginx
template:
metadata:
labels:
app: ingress-nginx
annotations:
prometheus.io/port: '10254'
prometheus.io/scrape: 'true'
spec:
# 映射服务到宿主机
hostNetwork: true
# 强制部署到某节点
nodeName: localhost.master
serviceAccountName: nginx-ingress-serviceaccount
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.15.0
# 修改镜像 Pull 策略
imagePullPolicy: IfNotPresent
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
# 增加 ApiServer 配置(两行)
- --apiserver-host=https://192.168.56.100:6443
- --kubeconfig=/etc/kubernetes/master-kubeconfig.yaml
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
securityContext:
runAsNonRoot: false
# 映射 k8s 配置
volumeMounts:
- mountPath: /etc/kubernetes/master-kubeconfig.yaml
name: kubeconfig
# 挂载 k8s 配置
volumes:
- name: kubeconfig
hostPath:
path: /root/.kube/config

应用修改后的 yaml 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost ~]# kubectl create -f mandatory-fix.yaml.0 
namespace "ingress-nginx" created
deployment "default-http-backend" created
service "default-http-backend" created
configmap "nginx-configuration" created
configmap "tcp-services" created
configmap "udp-services" created
serviceaccount "nginx-ingress-serviceaccount" created
clusterrole "nginx-ingress-clusterrole" created
role "nginx-ingress-role" created
rolebinding "nginx-ingress-role-nisa-binding" created
clusterrolebinding "nginx-ingress-clusterrole-nisa-binding" created
deployment "nginx-ingress-controller" created

部署工作到这里接结束了,正常情况我们的 Ingress 就已经开始工作了。

验证配置

上面的 test.6xyun.lan 实际是不存在的,我们可以通过改动 Hosts 文件来虚拟,然后访问这个 test.6xyun.lan 就可以访问到我们部署的测试服务,我这里使用 curl 自定义请求头 host 来模拟:

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
[root@localhost ~]# curl test.6xyun.lan
curl: (6) Could not resolve host: test.6xyun.lan; 未知的错误
[root@localhost ~]# curl 192.168.56.100
default backend - 404
[root@localhost ~]# curl -H host:test.6xyun.lan 192.168.56.100
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
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>

实测,集群中只要还有一个 Pod 可用整个服务就能正常工作。至此,我们的 Ingress 就部署完了。

四、总结

这一个系列是楼主用差不多一周的业余时间来完成 从零开始搭建k8s集群环境,到这里基本就结束了。但博客设计的内容是 k8s 里面最基础的东西,包括这些组件也还只是基本的使用,一些高难度的 骚操作 还需要在实际应用当中去探索、发现和实践。

然后这几篇文字在我不断的学习和填坑的过程中也修改了多次,但我认为依然有错误和不足的地方,所以如果各位发现了错误或者不足,希望能在留言区能够提出来,大家共同学习进步。

经过这个过程之后,原本一窍不通的 k8s 也慢慢变得清晰起来,希望大家如果看了这些文字也能得到收获!

  • 本文作者: 6x
  • 本文链接: https://6xyun.cn/article/59
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-ND 许可协议。转载请注明出处!