Kubernetes 上部署的微服务运行在它的私有网络中, 通过Pod实例的hostPort或Service实例的NodePort可以暴露到主机端口上,便于用户访问。但这样的方法会占有多台主机的HTTP端口或一台主机的多个端口,既浪费端口资源又增加管理难度和安全风险。
K8S的 Ingress 对象提供了另一种服务暴露的方法,它只占用一台主机的 HTTP 端口,通过虚拟主机或者虚拟目录的方式为K8S上的所有HTTP服务提供暴露服务,还能实现 HTTPS、负载均衡、状态统计等功能。
K8S 的 nginx ingress 的作用类似于 mesos 的 marathon-lb,不同点是:前者基于 nginx;后者基于 haproxy。
关于nginx ingress的安装,K8S有相关说明,网上也有很多文档可参考:
https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx
但在前期安装中,按照官网的说明并没有成功,查阅了大量资料,并结合实践最终排除了问题。下面分享一下我的安装过程。
K8S 1.2
http://kubernetes.io/docs/admin/authentication/
这一步不能忽略,否则nginx ingress无法启动;
还有几点要特别注意,否则nginx ingress启动时会出现TLS握手失败的错误:
1)必须生成serviceAccount证书
证书生成好后参考官网文档在apiserver和controller-manager中启用
2)必须将Kubernetes的内网IP或域名加入到server.crt
#Add Cluster IP of kubernetes to server.crt
subjectAltName=`kubectl get services --all-namespaces |grep 'default'|grep 'kubernetes'|grep '443'|awk '{print $3}'`
echo subjectAltName=IP:${subjectAltName} > extfile.cnf
#According to the ca.key, ca.crt and server.csr generate the server.crt:
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extfile extfile.cnf -out server.crt -days 10000
3)更新证书后重启 K8S 并更新 secret 和 serviceaccount
kubectl get secret --all-namespaces
kubectl get serviceaccount --all-namespaces
查看 default 开头的 secret 和 serviceaccount,将其删除,系统会自动重新生成;
如果上述操作后某些 pod 仍出现TLS握手错误,则删除相关 deployment 或者 replicant后重新部署。
做完上述准备工作后,就可以按照官方文档进行安装了:
https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx
注:为了显示 nginx_status,需要在80, 443 之外再暴露 nginx ingress 的8080端口:
ports:
-
containerPort:
80
hostPort:
80
-
containerPort:
8080
hostPort:
8080
-
containerPort:
443
hostPort:
443
|
同时部署一个configmap文件,启用nginx的vts模块:
1
2
3
4
5
6
7
|
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx
-
load
-
balancer
-
conf
data:
enable
-
vts
-
status:
"true"
~
|
下面使用 nginx ingress 基于虚拟主机对 kubernetes-dashboards 进行服务暴露,并增加HTTPS功能:
https://github.com/kubernetes/contrib/blob/master/ingress/controllers/nginx/examples/tls/README.md
注意:创建密钥时,请填入虚拟主机名,比如:k8s-dashboard.gkkxd.com,否则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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
kind: Deployment
apiVersion: extensions
/
v1beta1
metadata:
labels:
app: kubernetes
-
dashboard
version: v1.
1.0
name: kubernetes
-
dashboard
namespace: kube
-
system
spec:
replicas:
1
selector:
matchLabels:
app: kubernetes
-
dashboard
template:
metadata:
labels:
app: kubernetes
-
dashboard
spec:
containers:
-
name: kubernetes
-
dashboard
image:
172.31
.
17.36
:
5000
/
kubernetes
-
dashboard
-
amd64:v1.
1.0
imagePullPolicy: IfNotPresent
ports:
-
containerPort:
9090
protocol: TCP
args:
# Uncomment the following line to manually specify Kubernetes API server Host
# If not specified, Dashboard will attempt to auto discover the API server and connect
# to it. Uncomment only if the default does not work.
-
-
-
apiserver
-
host
=
http:
/
/
172.31
.
17.81
:
8080
livenessProbe:
httpGet:
path:
/
port:
9090
initialDelaySeconds:
30
timeoutSeconds:
30
-
-
-
kind: Service
apiVersion: v1
metadata:
labels:
app: kubernetes
-
dashboard
name: kubernetes
-
dashboard
namespace: kube
-
system
spec:
ports:
-
port:
80
targetPort:
9090
selector:
app: kubernetes
-
dashboard
|
注:请将service 的port 设置为80
apiVersion: extensions
/
v1beta1
kind: Ingress
metadata:
name: k8s
-
dashboard
namespace: kube
-
system
spec:
tls:
-
hosts:
-
k8s
-
dashboard.gkkxd.com
secretName: k8s
-
dashboard
-
secret
rules:
-
host: k8s
-
dashboard.gkkxd.com
http:
paths:
-
backend:
serviceName: kubernetes
-
dashboard
servicePort:
80
path:
/
|
注:请设置 tls, 虚拟主机名,backend service等参数
在 DNS 或 hosts文件中创建 k8s-dashboard.gkkxd.com 记录,之后就可以通过 http://k8s-dashboard.gkkxd.com 或者 https://k8s-dashboard.gkkxd.com 来访问 dashboard 了。
nginx status: