Ingress 介紹
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
但在前期安裝中,按照官網的說明並沒有成功,查閱了大量資料,並結合實踐最終排除了問題。下面分享一下我的安裝過程。
1. 准備安裝環境
K8S 1.2
2. 啟用Kubernetes API 認證
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后重新部署。
3. 安裝 Nginx Ingress
做完上述准備工作后,就可以按照官方文檔進行安裝了:
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" ~
4. 實例
下面使用 nginx ingress 基於虛擬主機對 kubernetes-dashboards 進行服務暴露,並增加HTTPS功能:
4.1 創建 dashboard secret
https://github.com/kubernetes/contrib/blob/master/ingress/controllers/nginx/examples/tls/README.md
注意:創建密鑰時,請填入虛擬主機名,比如:k8s-dashboard.xxxxx.com,否則HTTPS訪問會被拒絕。
4.2 部署 dashboard
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
4.3 創建 dashboard Ingress 實例
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等參數
4.4 設置 DNS 或 hosts文件
在 DNS 或 hosts文件中創建 k8s-dashboard.xxxxx.com 記錄,之后就可以通過 http://k8s-dashboard.xxxxx.com 或者 https://k8s-dashboard.xxxxx.com 來訪問 dashboard 了。
nginx status: