k8s学习(15):Ingress-负载均衡

Ingress-nginx github地址: https://github.com/kubernetes/ingress-nginx

Ingress-nginx 官方网站: https://kubernetes.github.io/ingress-nginx

image-20200201175404733

这里依然是NodePort方式

image-20200201175657978

部署Ingress Nginx

1
2
3
4
5
6
7
8
9
# 下载资源清单配置文件
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.28.0/deploy/static/mandatory.yaml
# 国内无法访问quay.io地址,可以修改成国内源
sed -i 's#quay.io#quay-mirror.qiniu.com#g' mandatory.yaml
kubectl apply -f mandatory.yaml

# 以NodePort方式暴露出来
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.28.0/deploy/static/provider/baremetal/service-nodeport.yaml
kubectl apply -f service-nodeport.yaml
1
2
3
4
# 查看ingress pod
kubectl get pod -n ingress-nginx
# 查看ingress svc
kubectl get svc -n ingress-nginx

Ingress HTTP代理访问

deployment、Service、Ingress 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
42
43
44
45
46
47
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deploy
namespace: default
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: hub.test.com/library/myapp:v1
imagePullPolicy: IfNotPolicy
ports:
- name: http
containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx
ports:
- name: http
protocol: TCP
targetPort: 80
port: 80
type: ClusterIP
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
spec:
rules:
- host: www.test.com
http:
paths:
- path: /
backend:
serviceName: nginx-svc # 这里的nginx-svc链接的是Service的名称:nginx-svc
servicePort: 80
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看ingress
kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
nginx-ingress www.test.com 80 9s
# 查看ingress端口
kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.111.109.71 <none> 80:30153/TCP,443:31846/TCP 3h15m
# 首先在本机添加映射
- Linux: /etc/hosts
- Windows:C:\Windows\System32\drivers\etc\hosts
# 访问www.test.com:30153
curl www.test.com:30153
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

举个栗子

Ingress虚拟主机 virtual-host

第一个deployment、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
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: deploy-1
spec:
replicas: 2
template:
metadata:
labels:
app: deploy-1
spec:
containers:
- name: deploy-1
image: hub.test.com/library/myapp:v1
---
apiVersion: v1
kind: Service
metadata:
name: svc-1
spec:
selector:
app: deploy-1
ports:
- port: 80
targetPort: 80

第二个deployment、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
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: deploy-2
spec:
replicas: 2
template:
metadata:
labels:
app: deploy-2
spec:
containers:
- name: deploy-2
image: hub.test.com/library/myapp:v2
---
apiVersion: v1
kind: Service
metadata:
name: svc-2
spec:
selector:
app: deploy-2
ports:
- port: 80
targetPort: 80
1
2
3
4
5
6
7
8
9
10
11
12
13
# 查看pod是否running
kubectl get pods
# 查看svcIP地址
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d8h
svc-1 ClusterIP 10.98.201.103 <none> 80/TCP 11m
svc-2 ClusterIP 10.98.22.123 <none> 80/TCP 10m
# 验证svc是否正确链接到pod
[root@k8s-master ingress-vh]# curl 10.98.201.103
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-master ingress-vh]# curl 10.98.22.123
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>

Ingress rule 规则创建

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
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-1
spec:
rules:
- host: www.test1.com
http:
paths:
- path: /
backend:
serviceName: svc-1
servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-2
spec:
rules:
- host: www.test2.com
http:
paths:
- path: /
backend:
serviceName: svc-2
servicePort: 80
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 查看ingress,这里需要等待ADDRESS地址出来之后才能正常访问
kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
ingress-1 www.test1.com 10.111.109.71 80 48s
ingress-2 www.test2.com 10.111.109.71 80 94s

# 查看ingress端口
kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.111.109.71 <none> 80:30153/TCP,443:31846/TCP 3h51m
# 验证是否能够访问
# curl www.test1.com:30153
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
# curl www.test2.com:30153
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>

image-20200202012014428

image-20200202012021522

Ingress HTTPS代理访问

创建证书,以及cert存储方式

1
2
3
4
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/0=nginxsvc"
kubectl create secert tls tls-secert --key tls.key --cert tls.crt
# 查看 secret
kubectl get secret

创建deployment、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
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-3
spec:
replicas: 2
template:
metadata:
labels:
app: nginx-3
spec:
containers:
- name: nginx-3
image: hub.test.com/library/myapp:v3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: svc-3
spec:
selector:
app: nginx-3
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
1
2
3
4
kubectl apply -f nginx-3.yaml
kubectl get pods
kubectl get svc
curl ClusterIP

创建ingress https

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-https
spec:
tls:
- hosts:
- www.test3.com
secretName: tls-secret
rules:
- host: www.test3.com
http:
paths:
- path: /
backend:
serviceName: svc-3
servicePort: 80
1
2
3
4
5
6
7
8
9
# 查看ingress,等待ADDRESS出来
kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
nginx-https www.test3.com 10.111.109.71 80, 443 65s
# 查看端口
kubectl get svc -n ingress-svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.111.109.71 <none> 80:30153/TCP,443:31846/TCP 4h22m
# 浏览器访问

image-20200202011945503

Nginx进行BasicAuth

1
2
3
4
yum -y install httpd
htpasswd -c auth foo
kubectl create secret generic basic-auth --from-file=auth

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: ingress-with-auth
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo'
spec:
rules:
- hosts: www.test4.com
http:
paths:
- path: /
backend:
serviceName: svc-1
servicePort: 80
1
2
3
4
5
# 查看ingress
kubectl get pods
# 查看svc端口
kubectl get svc -n ingress-nginx
# 添加hosts映射信息

image-20200202013336313

image-20200202014205832

Nginx进行重写

image-20200202013508869

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-rewrite
annotations:
nginx.ingress.kubernetes.io/rewrite-target: https://www.test3.com:31846
spec:
rules:
- host: www.test5.com
http:
paths:
- path: /
backend:
serviceName: svc-1
servicePort: 80

这里输入http://www.test5.com:30135会跳转到https://www.test3.com:31846

而且后面写的serviceName: svc-1不起作用

image-20200202015216510