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: