Kubernetes 上部署的微服务运行在它的私有网络中, 经过Pod实例的hostPort或Service实例的NodePort能够暴露到主机端口上,便于用户访问。但这样的方法会占有多台主机的HTTP端口或一台主机的多个端口,既浪费端口资源又增长管理难度和安全风险。python
K8S的 Ingress 对象提供了另外一种服务暴露的方法,它只占用一台主机的 HTTP 端口,经过虚拟主机或者虚拟目录的方式为K8S上的全部HTTP服务提供暴露服务,还能实现 HTTPS、负载均衡、状态统计等功能。nginx
K8S 的 nginx ingress 的做用相似于 mesos 的 marathon-lb,不一样点是:前者基于 nginx;后者基于 haproxy。git
关于nginx ingress的安装,K8S有相关说明,网上也有不少文档可参考:github
https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginxapi
但在前期安装中,按照官网的说明并无成功,查阅了大量资料,并结合实践最终排除了问题。下面分享一下个人安装过程。安全
K8S 1.2网络
http://kubernetes.io/docs/admin/authentication/app
这一步不能忽略,不然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模块:
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.xxxxx.com,不然HTTPS访问会被拒绝。
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.xxxxx.com secretName: k8s-dashboard-secret rules: - host: k8s-dashboard.xxxxx.com http: paths: - backend: serviceName: kubernetes-dashboard servicePort: 80 path: /
注:请设置 tls, 虚拟主机名,backend service等参数
在 DNS 或 hosts文件中建立 k8s-dashboard.xxxxx.com 记录,以后就能够经过 http://k8s-dashboard.xxxxx.com 或者 https://k8s-dashboard.xxxxx.com 来访问 dashboard 了。
nginx status: