1、上集回顧前端
一、Service 3種模型:userspace,iptables,ipvsnode
二、Service類型nginx
ClusterIP,NodePortgit
NodePort:client -> NodeIP:NodePort -> ClusterIP:ServicePort -> PodIP:containerPortgithub
LoadBalancerjson
ExternelName後端
No ClusterIP: Hedless Serviceapi
serviceName -> PodIPtomcat
2、ingress安全
一、在客戶端訪問咱們k8s服務時,四層調度器自己是沒有辦法解除ssl會話的,這就意味着客戶端必須與後端服務器(pod)之間直接創建ssl會話,這裏還有個顯著的問題在於若是調度器在ssl會話創建之後的下一個請求被調度到第二臺服務器上那麼這個ssl還要從新創建,所以咱們只要認爲內部網絡是安全的那麼咱們能夠把會話在前端調度器上卸載,可是四層調度是不能卸載的,所以咱們須要七層的負載均衡機制。所以若是他們是http服務咱們又指望構建https,那麼咱們只須要他在互聯網上這個不安全的網絡中傳輸實現https,內網中使用http,所以咱們須要使用卸載器,可是咱們Service調度時,不管是iptables仍是ipvs都只是四層調度,所以也就意味着若是你想要在k8s上運行一個應用基於https提供服務,咱們就必須得在後端每個pod上配置https,由於只有這樣他們纔會創建起https聯繫,因此咱們如今也指望在接入那一層上就可以卸載ssl,向內部調度時就再也不是ssl了。對這種需求,k8s採用一種很獨特的方式來實現,咱們在整個集羣中,在進行調度時後端被代理的pod資源是不配置https的,就是明文的http,可是我使用一個獨特的調度器(運行在pod中),對於此pod來說,其是一個運行在七層(用戶空間)的正常的應用程序,好比nginx,haproxy等,當用戶試圖訪問某一服務時,咱們不讓他先去到達前端的service,而是先到這個pod,而後pod與pod之間不須要service而是直接通訊來完成反向代理,咱們用一個pod來反代至後端咱們真正提供服務的pod,此前咱們用service代理的,如今用pod,而這個pod若是須要被訪問到那麼仍是須要通過service,所以客戶端通過此pod的service調度之後,與咱們專門配置了https的此pod進行交互,這裏的service咱們定義成nodePort,依然沒有什麼問題,依然老路徑仍是存在的,可是等到達這個pod之後由此pod直接代理至兩個明文的pod,所以此pod就成爲https的會話卸載器了。若是這種方式進行調度那麼調度方式以下: client --> LB --> nodePort --> service -->會話卸載器pod --> 後端pod 這種方式性能確定會很是很是差,如圖。
二、其實咱們還能夠這樣幹,可讓咱們pod直接共享咱們節點的網絡名稱空間,因而,上述中的會話卸載器pod咱們能夠直接讓他共享節點網絡名稱空間,這就意味着其監聽着宿主機的地址,這樣咱們客戶端的請求就能夠之間到達這個pod,而後再由他進行調度。
三、在一個節點上運行的容器,容器可使用本身的虛擬網絡,也能夠共享宿主機的網絡,若是這個容器共享宿主機的網絡也就意味着這個容器內的進程一旦監聽套接字時它監聽的是宿主機的地址,至關於一個進程運行在宿主機上同樣的,這樣一來這個pod在每一個節點上就只能運行一個了,通常來說集羣中只有一個,那麼其只須要運行在集羣的某一個節點便可,可是若是 監聽在節點的端口時就會有問題,service時不管訪問哪個節點的端口都行,由於你訪問哪個節點的nodePort他都能經過它的ip地址送達到後端pod上,可是如今這個Pod要監聽節點的網絡名稱空間,而且經過這個節點的網絡名稱空間直達這個pod,那麼若是運行這種類型的pod那麼就必定只能運行在一個節點上,訪問時客戶端就只能訪問這個節點,而且若是這個節點掛了呢?
四、要解決這個問題,咱們能夠用DaemonSet控制器,它能夠在每一個節點上都運行相應的pod 副本而且只運行一個,這樣假如咱們有三個節點那麼咱們三個節點上均可以運行這個pod。這樣就都能實現代理和負載均衡,可是又回到了調度到哪個節點均可以的問題,這樣不管哪一個節點掛掉了都仍是能夠訪問到,可是若是咱們有太多的節點那麼每一個節點都運行一個這樣的pod就太佔資源。daemonset還可讓pod運行在有限的節點的範圍上(部分節點),因而再未來作k8s集羣時能夠這樣幹,好比咱們有三千個節點,那麼咱們專門拿三個節點出來作pod的接入式的負載均衡的專用主機,而且給這三個節點打上污點讓其它pod沒法調度上來,而後咱們就定義這個DaemonSet控制器上的pod只運行在這三個節點上各自運行一份而且能容忍這些污點,因此這三個主機在集羣中只容許這一個類型的pod,專門負責爲集羣接入外部的七層調度的流量。而這個pod在k8s中有個專門的稱呼叫 Ingress Controller。這個Ingress Controller比較獨特,以前講的DaemonSet,deployment,replacSet等控制器都不同,DaemonSet deployment,replaciSet等等都是做爲Controller manager的一部分存在,衆多控制器都是做爲Controller manager的一個子組件做爲其組成部分組成的。而Ingress Controller倒是本身獨立運行的一個或一組pod資源,它一般就是一個應用程序,這個應用程序就是擁有七層代理能力和調度能力的應用程序,目前k8s上的選擇有四種,其中最不受待見的就是Haproxy,通常默認是nginx,如今在服務網格中你們比較傾向Envoy,固然還有其它與nginx相競爭的聽說原本就是爲微服務而生的Traefik,因此用Ingress Controller時會發現咱們有三種選擇:
a、nginx:這是後來改造的
b、Traefik:這種設計就是爲微服務這種動態生成而生的
c、Envoy :去作微服務的你們都比較傾向於Envoy
五、做爲調度器,有時候要調度不僅一個後端服務,假若有一個調度器pod,後端有一組pod提供電商服務,第二組pod提供了社交服務,第三組pod提供了論壇服務,第四組pod提供了網關服務。那麼咱們這四組http服務怎麼可以分別調度呢?
a、從nginx的角度來說,接入服務端時咱們經過uptream_server便可,可是接入客戶端時咱們應該如何標識這四種不一樣的請求呢,首先咱們能夠在nginx上作四個虛擬主機,在四個主機名上作四個主機,每個主機名對應一組後端的pod。那萬一咱們沒那麼多主機名呢?此時咱們能夠經過不一樣的路徑來作url映射,而後每一組路徑就映射到一組後端pod上,可是pod存在生命週期,隨時均可能掛掉替換爲一個新pod,新pod的ip就會變了,另外咱們pod的應用的規模也能夠動態伸縮的,咱們簡單改一下副本數其數量也會變,這種一變前面代理的配置也就無效了,咱們service經過關聯標籤來解決這個問題,並且service隨時 watch着api server上的api時刻來關注本身關聯的slector的資源是否變更了,只要變更咱們api server就會當即通知service而後service當即改變。 因此service經過label selector始終關聯着對應label能適配的後端pod,不管怎麼變都能應付並且能及時做出反應,那麼此處nginx運行在pod中也就意味着這個配置是在pod內部而且後端pod隨時還會發生變更,Ingress 也會時刻watch着api 中的後端pod資源的改變。那它怎麼知道這是哪一個pod資源呢?Ingress Controller本身沒有這個能力,它並不知道目前符合本身條件關聯的被代理的pod資源有哪些,它必須藉助於service來實現,咱們要想定義一個這種調度能力功能其實仍是須要建service,這個service經過label selector關聯至後端的pod上來,但這個service不是被當作被代理時的中間節點,它僅僅是幫忙分類的,這個service 關聯了幾個pod那麼咱們就將這幾個pod配置寫在這個upstream中,調度時是不會通過service的,service在此處僅僅是幫忙分組的,分完組之後咱們須要獲得的也不是service的IP,而是pod的ip,所以此時可使用headless service,可是這個service卻沒有用,是否是headless都無所謂,它只要幫忙完成分組知道找哪幾個pod就能夠了,pod一變,service對應的資源也就變了,問題是變了後這個結果怎麼反應到這個配置文件中來,此時須要依賴於一個專門的資源 Ingress。
六、在k8s上有一種特殊的資源叫Ingress,Ingress 和Ingress Controller是兩回事,咱們定義一個Ingress 時就是說了它其實就是定義咱們指望這個Ingress Controller是如何給咱們建一個前端(多是一個虛擬主機,也多是一個url映射)接入層,同時又給咱們定義一個後端upstream_server,這個upstream_server中有幾個主機 Ingress是經過這個service 獲得的,而且Ingress有一個特色,做爲資源來說他能夠經過編輯注入到Ingress Controller裏面來,直接把它注入並保存爲配置文件,並且一旦Ingress發現Service選定的後端的pod資源發生改變了,這個改變必定會及時返回到Ingress中,這個Ingress會及時注入到這個前端調度器pod中,就是注入到upstream配置文件中,並且還能觸發這個pod中的主容器中的進程重載配置文件。因此咱們要想使用這個功能咱們須要在集羣中:
a、要有個service去對後端某一個特定類型的pod資源進行分類,這個service只是起分類做用的。
b、Ingress基於這個分類識別出有幾個pod,而且識別其ip地址是什麼,而且將這個ip地址返回的結果生成配置信息注入到upstream_server(以nginx爲例),可是nginx又不是特別適用這個場景,每次變更都在重載,若是是Traefik和Envoy 等天生就是爲這種場景而生的,只要動了就加載生效,不須要重載。(它能夠監控這個配置文件發生變化,只要發生變化就會動態重載)。
七、若是咱們想要使用代理,咱們應該怎麼作?
a、須要先部署一個Ingress Controller,而後部署一個pod進來,這個pod可能原本是空的,沒有什麼有效的東西,接下來咱們要根據本身的須要 經過虛擬主機的方式或者經過url代理的方式來配置一個前端,而後再根據咱們Service收集到的後端pod的IP定義成upstream_server,把這些信息反應在Ingress當中由Ingress動態注入到Ingress Controller中才能夠
b、從圖中咱們能夠看到,當訪問咱們服務時首先由外部的負載均衡器將請求調度到咱們nodePort的Service上,而nodePort上的Service再將請求調度至咱們內部的一個pod 叫IngressController上來,Ingress Controller根據Ingress中的定義(虛擬主機或url),每個主機名對應後面的一組pod資源(經過service分組),所以此處用到兩組Service,第一個Service是幫集羣接入外部流量的(固然也能夠不用,能夠把這個Ingress Controller pod運行爲共享網絡節點網絡名稱空間方式而且將其定義爲Dameset方式運行在特定節點上就能夠了),那麼咱們在定義pod資源時只須要在pod的一個配置選項中加入hostnetwork便可。第二個Service只用來作pod歸組不被調度時使用。
c、接下來咱們要使用ingress的功能得先去安裝部署Ingress Controller 這個pod,然後再定義Ingress,然後再定義後端pod生成Service,而後再創建關聯關係。
3、Ingress 定義
一、Ingress 也是標準的kubernetes資源對象,所以也擁有相應的對象屬性。
[root@k8smaster ~]# kubectl explain ingress.spec KIND: Ingress VERSION: extensions/v1beta1 RESOURCE: spec <Object> DESCRIPTION: Spec is the desired state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status IngressSpec describes the Ingress the user wishes to exist. FIELDS: backend <Object> #定義後端主機,定義後端有哪幾個pod,其屬性有serviceName和sericePort A default backend capable of servicing requests that don't match any rule. At least one of 'backend' or 'rules' must be specified. This field is optional to allow the loadbalancer controller or defaulting logic to specify a global default. rules <[]Object> #定義規則,分爲主機和http,http又有paths路徑定義調度到哪兒去。 (即主機調度和路徑調度兩種方式) A list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend. tls <[]Object> TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI.
[root@k8smaster ~]# kubectl explain ingress.spec.backend KIND: Ingress VERSION: extensions/v1beta1 RESOURCE: backend <Object> DESCRIPTION: A default backend capable of servicing requests that don't match any rule. At least one of 'backend' or 'rules' must be specified. This field is optional to allow the loadbalancer controller or defaulting logic to specify a global default. IngressBackend describes all endpoints for a given service and port. FIELDS: serviceName <string> -required- #backend正是靠咱們service的定義來找到咱們後端相關聯的有哪幾個pod資源的,一旦pod資源發生變化這個service就發生變化,service變化Ingress就變化,
Ingress變化就開始注入到Ingress Controller中去。
Specifies the name of the referenced service. servicePort <string> -required- Specifies the port of the referenced service.
二、部署Ingress,k8s集羣由master,node和附件組成,一共有四個核心附件:
a、dns
b、Heapster
c、Dashboard
d、Ingress Controller
4、Ingress建立
一、首先下載github上對應的yaml文件
[root@k8smaster ingress-nginx]# for file in namespace.yaml configmap.yaml rbac.yaml tcp-services-configmap.yaml with-rbac.yaml udp-services-configmap.yaml default-backend.yaml; \ > do wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.17.1/deploy/$file; done ...
二、將下載yaml文件建立使用
[root@k8smaster ingress-nginx]# ls configmap.yaml namespace.yaml rbac.yaml tcp-services-configmap.yaml udp-services-configmap.yaml with-rbac.yaml [root@k8smaster ingress-nginx]# kubectl apply -f namespace.yaml namespace/ingress-nginx created [root@k8smaster ingress-nginx]# kubectl apply -f ./ configmap/nginx-configuration created namespace/ingress-nginx configured serviceaccount/nginx-ingress-serviceaccount created clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created role.rbac.authorization.k8s.io/nginx-ingress-role created rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created configmap/tcp-services created configmap/udp-services created deployment.extensions/nginx-ingress-controller created
也可直接使用一次性部署yaml文件
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
[root@k8smaster ingress-nginx]# kubectl get pods -n ingress-nginx -o wide NAME READY STATUS RESTARTS AGE IP NODE default-http-backend-846b65fb5f-ggwwp 1/1 Running 0 29m 10.244.1.77 k8snode1 nginx-ingress-controller-d658896cd-nqt4b 1/1 Running 21 2h 10.244.2.76 k8snode2
三、嘗試建立Ingress,爲了讓某個Ingress能顯現真正的效果來咱們要作一些前提準備,好比咱們要部署幾個後端被代理的應用
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test-ingress annotations: #此屬性相當重要,由於在annotations中咱們必須指明ingress controller類型是nginx nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - http: paths: - path: /testpath backend: serviceName: test servicePort: 80
四、直接部署在裸機上時要額外加上一項叫作service-nodeport.yaml,若是不加上這一項會發現ingress controller部署完之後在集羣內部能夠被訪問,在集羣外部是沒法被訪問到的,由於ingress controller沒法接入外部的流量,若是要接入流量則須要再部署一個nodePort的service,或者也能夠將ingress controller部署爲直接共享節點網絡名稱空間的方式,但這個時候咱們須要手動改造with-rbac.yaml這個文件中的kind 類型由Deployent改成DaemonSet,而後去掉replicas,而後在pod template上的spec中加一項hostnetwork用於共享宿主機的網絡名稱空間,固然須要保證監聽的端口不被衝突。
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml
五、接下來能夠嘗試使用ingress規則來應用
a、首先建立一組應用pod和對應的service
[root@k8smaster ingress]# cat deploy-demo.yaml apiVersion: v1 kind: Service metadata: name: myapp namespace: default spec: selector: app: myapp release: canary ports: - name: http targetPort: 80 port: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: myapp release: canary template: metadata: labels: app: myapp release: canary spec: containers: - name: myapp image: ikubernetes/myapp:v2 ports: - name: http containerPort: 80
b、建立nodePort service
[root@k8smaster ingress-nginx]# cat service-nodeport.yaml apiVersion: v1 kind: Service metadata: name: ingress-nginx namespace: ingress-nginx spec: type: NodePort ports: - name: http #服務爲http port: 80 #service端口爲80 targetPort: 80 #容器端口爲80 protocol: TCP nodePort: 30080 - name: https port: 443 #service 端口爲443 targetPort: 443 #容器端口爲443 protocol: TCP nodePort: 30443 selector: app: ingress-nginx --- [root@k8smaster ingress-nginx]# kubectl apply -f ./ configmap/nginx-configuration unchanged deployment.extensions/default-http-backend unchanged service/default-http-backend unchanged namespace/ingress-nginx configured serviceaccount/nginx-ingress-serviceaccount unchanged clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole configured role.rbac.authorization.k8s.io/nginx-ingress-role unchanged rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding unchanged clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding configured service/ingress-nginx created configmap/tcp-services unchanged configmap/udp-services unchanged deployment.extensions/nginx-ingress-controller unchanged
[root@k8smaster ingress]# kubectl get pods -n ingress-nginx -o wide --show-labels
NAME READY STATUS RESTARTS AGE IP NODE LABELS
default-http-backend-846b65fb5f-ggwwp 1/1 Running 1 1d 10.244.1.82 k8snode1 app=default-http-backend,pod-template-hash=4026219619
nginx-ingress-controller-d658896cd-nqt4b 1/1 Running 22 1d 10.244.2.81 k8snode2 app=ingress-nginx,pod-template-hash=821445278
此時訪問咱們節點端口顯示 default backend - 404 ,此時表示咱們調度器已經正常工做。
c、此時將步驟a中建立的myapp Deploymet開始使用咱們b中這個Service發佈出去而不在咱們裏面同時建立的這個service上本身改爲nodePort發佈出去了
[root@k8smaster ingress]# cat ingress-myapp.yaml apiVersion: extensions/v1beta1 Kind: Ingress metadata: name: ingress-myapp namespaces: default annotations: #進行說明咱們接下來要用到的規則是nginx,就是靠annotations來識別類型的,只有進行註解了才能轉化爲對應的與controller相匹配的規則 kubernetes.io/ingress.class: "nginx" spec: rules: #定義把誰轉到誰那兒去 - host: myapp.wohaoshuai.com #要確保在外部經過互聯網訪問時能解析此主機名,而且解析結果恰好能到達咱們Service nodePort映射的主機上去 http: #定義先後端路徑 paths: #不給默認爲/ - path: #前端路徑,空表示默認的/ backend: #匹配後端service serviceName: myapp servicePort: 80 [root@k8smaster ingress]# kubectl apply -f ingress-myapp.yaml ingress.extensions/ingress-myapp created [root@k8smaster ingress]# kubectl get ingress NAME HOSTS ADDRESS PORTS AGE ingress-myapp myapp.wohaoshuai.com 80 10s [root@k8smaster ingress]# kubectl describe ingress ingress-myapp Name: ingress-myapp Namespace: default Address: Default backend: default-http-backend:80 (<none>) Rules: Host Path Backends ---- ---- -------- myapp.wohaoshuai.com myapp:80 (<none>) Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"ingress-my app","namespace":"default"},"spec":{"rules":[{"host":"myapp.wohaoshuai.com","http":{"paths":[{"backend":{"serviceName":"myapp","servicePort":80},"path":null}]}}]}} kubernetes.io/ingress.class: nginx Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 30s nginx-ingress-controller Ingress default/ingress-myapp
d、上述建立完成的ingress一旦應用其會自動注入到ingress controller中去,也就是說其會自動轉換成nginx的配置文件(從下面信息中可看到),訪問myapp.wohaoshuai.com:30080便可
[root@k8smaster ingress]# kubectl get pods -n ingress-nginx NAME READY STATUS RESTARTS AGE default-http-backend-846b65fb5f-ggwwp 1/1 Running 0 1h nginx-ingress-controller-d658896cd-nqt4b 1/1 Running 21 4h [root@k8smaster ingress]# kubectl exec -it nginx-ingress-controller-d658896cd-nqt4b /bin/bash -n ingress-nginx www-data@nginx-ingress-controller-d658896cd-nqt4b:/etc/nginx$ ls fastcgi.conf fastcgi_params.default koi-win mime.types.default nginx.conf owasp-modsecurity-crs template win-utf fastcgi.conf.default geoip lua modsecurity nginx.conf.default scgi_params uwsgi_params fastcgi_params koi-utf mime.types modules opentracing.json scgi_params.default uwsgi_params.default www-data@nginx-ingress-controller-d658896cd-nqt4b:/etc/nginx$ cat nginx.conf|grep wohaoshuai ## start server myapp.wohaoshuai.com server_name myapp.wohaoshuai.com ; ## end server myapp.wohaoshuai.com
從上面配置文件中能夠看出svc只是起到了識別後端pod信息的做用而不起調度做用
5、建立一個真正可用的ingress 實例
一、咱們如今作這麼一個東西,原本咱們起了兩到三個tomcat pod,每一個pod監聽本身的8080和8009端口,所以咱們在三個pod以前作一個Service做爲一個固定訪問端點代理,可是這個Service待會兒不會用到,它只是用來識別而已,咱們Service對應的8080和8009端口對應後端pod的8080和8009端口。咱們定義一個deployment來部署這三個tomcat,用來監聽8080和8009端口,而後定義一個Service把8080和8009暴露出去,可是沒有真正向集羣外部暴露,由於其是cluster IP類型的,他只是用來被前端等會兒叫ingress controller定義ingress規則向裏面映射的時候所識別後端有哪幾個Pod而已。
二、建立Deployment 和 Service,而後建立ingress
[root@k8smaster ingress]# cat tomcat-deploy.yaml apiVersion: v1 kind: Service metadata: name: tomcat namespace: default spec: selector: app: tomcat release: canary ports: - name: http targetPort: 8080 port: 8080 - name: ajp targetPort: 8009 port: 8009 --- apiVersion: apps/v1 kind: Deployment metadata: name: tomcat-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: tomcat release: canary template: metadata: labels: app: tomcat release: canary spec: containers: - name: myapp image: tomcat:8.5.32-jre8-alpine ports: - name: http containerPort: 8080 - name: ajp containerPort: 8009 [root@k8smaster ingress]# kubectl apply -f tomcat-deploy.yaml service/tomcat created deployment.apps/tomcat-deploy created [root@k8smaster ingress]# cat ingress-tomcat.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-tomcat namespace: default annotations: #進行說明咱們接下來要用到的規則是nginx,就是靠annotations來識別類型的,只有進行註解了才能轉化爲對應的與controller相匹配的規則 kubernetes.io/ingress.class: "nginx" spec: rules: #定義把誰轉到誰那兒去 - host: tomcat.wohaoshuai.com #要確保在外部經過互聯網訪問時能解析此主機名,而且解析結果恰好能到達咱們Service nodePort映射的主機上去 http: #定義先後端路徑 paths: #不給默認爲/ - path: #前端路徑,空表示默認的/ backend: #匹配後端service serviceName: tomcat servicePort: 8080 #咱們沒有指ingress因此默認ingress是80端口 [root@k8smaster ingress]# kubectl apply -f ingress-tomcat.yaml ingress.extensions/ingress-myapp configured
建立完成後在各節點host文件添加tomcat.lwohaoshuai.com解析訪問 tomcat.wohaoshuai.com:30080便可
三、若是咱們想要建立https的虛擬主機就稍微要麻煩一點,第一,這個虛擬主機要工做爲https服務的話在nginx上這個虛擬主機得是ssl虛擬主機配置爲ssl虛擬主機則須要證書和私鑰,而這個證書和私鑰咱們須要將其建立爲特定格式才能提供給咱們的ingress.那麼如今咱們作一組證書和私鑰而且把它們做爲一個獨特的對象,這個叫secret。
a、建立私鑰和證書
[root@k8smaster ingress]# openssl genrsa -out tls.key 2048 #建立私鑰 Generating RSA private key, 2048 bit long modulus ..+++ ........................................+++ e is 65537 (0x10001) [root@k8smaster ingress]# ls deploy-demo.yaml ingress-myapp.yaml ingress-tomcat.yaml tls.key tomcat-deploy.yaml [root@k8smaster ingress]# openssl req -new -x509 -key tls.key -out tls.crt(自簽證書) -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=tomcat.wohaoshuai.com(國家爲CN,所在的省爲北京,地址爲北京,組織爲DevOps,此外,證書中應該包含的名字應該和此前定義的域名一致,爲tomcat.wohaoshuai.com) #建立自簽證書 [root@k8smaster ingress]# ls deploy-demo.yaml ingress-myapp.yaml ingress-tomcat.yaml tls.crt tls.key tomcat-deploy.yaml
b、注意生成的證書是不能直接貼到nginx的pod中去的,咱們須要把它先轉成特殊格式,這個特殊格式叫secret,它也是標準的k8s集羣對象,它能夠直接注入到pod中被pod所引用。所以接下來咱們須要把它作成secret
[root@k8smaster ingress]# kubectl create secret tls tomcat-ingress-secret --cert=tls.crt --key=tls.key secret/tomcat-ingress-secret created [root@k8smaster ingress]# kubectl get secret NAME TYPE DATA AGE default-token-jvtl7 kubernetes.io/service-account-token 3 36d tomcat-ingress-secret kubernetes.io/tls 2 15s [root@k8smaster ingress]# kubectl describe secret tomcat-ingress-secret Name: tomcat-ingress-secret Namespace: default Labels: <none> Annotations: <none> Type: kubernetes.io/tls Data ==== tls.crt: 1306 bytes tls.key: 1679 bytes
c、建立完之後咱們就能夠拿這個secret在ingress.spec.rules中定義了
[root@k8smaster ingress]# kubectl explain ingress.spec.tls KIND: Ingress VERSION: extensions/v1beta1 RESOURCE: tls <[]Object> DESCRIPTION: TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI. IngressTLS describes the transport layer security associated with an Ingress. FIELDS: hosts <[]string> #表示把哪一個主機作成tls格式的 Hosts are a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. secretName <string> #用哪一個secret來獲取證書,私鑰等相關信息 SecretName is the name of the secret used to terminate SSL traffic on 443. Field is left optional to allow SSL routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the Host header is used for routing.
[root@k8smaster ingress]# kubectl apply -f ingress-tomcat-tls.yaml ingress.extensions/ingress-tomcat-tls created [root@k8smaster ingress]# cat ingress-tomcat-tls.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-tomcat-tls namespace: default annotations: #進行說明咱們接下來要用到的規則是nginx,就是靠annotations來識別類型的,只有進行註解了才能轉化爲對應的與controller相匹配的規則 kubernetes.io/ingress.class: "nginx" spec: tls: - hosts: - tomcat.wohaoshuai.com secretName: tomcat-ingress-secret rules: #定義把誰轉到誰那兒去 - host: tomcat.wohaoshuai.com #要確保在外部經過互聯網訪問時能解析此主機名,而且解析結果恰好能到達咱們Service nodePort映射的主機上去 http: #定義先後端路徑 paths: #不給默認爲/ - path: #前端路徑,空表示默認的/ backend: #匹配後端service serviceName: tomcat servicePort: 8080 #咱們沒有指ingress因此默認ingress是80端口 [root@k8smaster ingress]# kubectl get ingress NAME HOSTS ADDRESS PORTS AGE ingress-myapp myapp.wohaoshuai.com 80 20h ingress-tomcat tomcat.wohaoshuai.com 80 18h ingress-tomcat-tls tomcat.wohaoshuai.com 80, 443 33s [root@k8smaster ingress]# kubectl describe ingress ingress-tomcat-tls Name: ingress-tomcat-tls Namespace: default Address: Default backend: default-http-backend:80 (<none>) TLS: tomcat-ingress-secret terminates tomcat.wohaoshuai.com Rules: Host Path Backends ---- ---- -------- tomcat.wohaoshuai.com tomcat:8080 (<none>) Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"ingress-to mcat-tls","namespace":"default"},"spec":{"rules":[{"host":"tomcat.wohaoshuai.com","http":{"paths":[{"backend":{"serviceName":"tomcat","servicePort":8080},"path":null}]}}],"tls":[{"hosts":["tomcat.wohaoshuai.com"],"secretName":"tomcat-ingress-secret"}]}} kubernetes.io/ingress.class: nginx Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 1m nginx-ingress-controller Ingress default/ingress-tomcat-tls [root@k8smaster ingress]# kubectl exec -it nginx-ingress-controller-d658896cd-nqt4b /bin/bash -n ingress-nginx www-data@nginx-ingress-controller-d658896cd-nqt4b:/etc/nginx$ cat nginx.conf|grep ssl
經過https://tomcat.wohaoshuai.com:30443訪問便可。能夠看到咱們ssl主機創建起來了,可是咱們後端pod並無提供任何ssl功能