k8s(二)、對外服務

前言

在上文完成k8s集羣搭建的基礎上k8s(一)、1.9.0高可用集羣本地離線部署記錄,承接上文,本文簡單介紹一下k8s對外暴露服務

拓撲圖:
這裏寫圖片描述

一、k8s對外暴露服務方式介紹

1.Load Blance

目前已經有很多主流的公有云平臺已經都提供基於k8s服務的組件,工作的原理本質上是k8s的服務向雲平臺申請一個負載均衡器來對外服務。因此這種方式只適合在雲平臺內部使用,這裏略過.

2.Nodeport

針對某一個k8s service,k8s集羣內的每一個node都將暴露node的一個指定接口,來爲此service提供服務。此方式要求每一個node都提供一個端口,即使此node上沒有承載有該service 的pod服務載體,因此此方式會帶來一定資源的浪費和管理不便。

3.Ingress

 Ingress注入方式,有三個組件,來協同完成對外服務的過程:
 1.reverse proxy LB
 2.ingress controller
 3.k8s Ingress組件

1.reverse proxy LB

將服務請求反向代理至後端服務對應的node上,node收到後再由kube-proxy將請求轉交給endpoint pod.

2.ingress controller

監控apiserver上的svc關聯關係的變化,若svc關聯發生變化(例如svc後端對應的pods發生變化),則動態地獲取變化,更新前面反向代理的配置文件和熱重載。

3.k8s ingress

k8s的一種資源類型,可以基於訪問的虛擬主機、字段等進行區別路由映射到後端不同的k8s service上,ingress controller要實時監控每個ingress對象上指定的service來保證LB配置文件的熱更新


在本文,採用traefik作爲ingress工具演示。

### traefik:
由於微服務架構以及 Docker 、 kubernetes 編排工具最近纔開始流行,因此常用的反向代理服務器 nginx並未提供對k8s ingress的支持,所以Ingress Controller 這個中間件的存在就是用來做 kubernetes 和前端LB來做銜接的;Ingress Controller工作的方式是讀取k8s ingress,通過與k8s api交互實時監控service,當serivce映射關係變化時,能重寫 nginx 配置和熱更新。traefik的出現簡化了這個流程,traefik本身是一個輕量級的reverse proxy LB,並且它原生支持跟 kubernetes API 交互,感知後端變化,因此traefik可以取代上面的1、2組件,簡化結構。

traefik官方介紹圖:
這裏寫圖片描述

二、服務部署

首先來部署一組簡單的nginx應用容器。
準備好yaml文件:

[root@171 nginx]# ls
nginx-deploy.yaml  nginx_ingress.yaml  nginx_service.yaml
[root@171 nginx]# cat nginx-deploy.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "2"
  creationTimestamp: 2018-04-09T04:02:02Z
  generation: 4
  labels:
    app: nginx
  name: nginx-deploy
  namespace: default
  resourceVersion: "111504"
  selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deploy
  uid: c28090c0-3baa-11e8-b75a-000c29858eab
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.9.1
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 2
  conditions:
  - lastTransitionTime: 2018-04-09T04:57:27Z
    lastUpdateTime: 2018-04-09T04:57:27Z
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  observedGeneration: 4
  readyReplicas: 2
  replicas: 2
  updatedReplicas: 2
[root@171 nginx]# cat nginx_service.yaml 
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: 2018-04-09T11:34:09Z
  labels:
    run: nginx
  name: nginx
  namespace: default
  resourceVersion: "140236"
  selfLink: /api/v1/namespaces/default/services/nginx
  uid: eb57a21b-3be9-11e8-b75a-000c29858eab
spec:
  clusterIP: 10.99.59.56
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}
[root@171 nginx]# cat nginx_ingress.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  creationTimestamp: 2018-04-09T11:39:48Z
  generation: 1
  name: test
  namespace: default
  resourceVersion: "140644"
  selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/test
  uid: b54bbda8-3bea-11e8-b75a-000c29858eab
spec:
  rules:
  - host: test.nginx.com
    http:
      paths:
      - backend:
          serviceName: nginx
          servicePort: 80
status:
  loadBalancer: {}

創建nginx的deploy、svc、ing資源,使用–record命令後面可以看到revision記錄:

kubectl create -f nginx-deploy.yaml --record
kubectl create -f nginx-service.yaml --record
kubectl create -f nginx-ingress.yaml --record

過1分鐘後查看狀態:

[root@171 nginx]# kubectl get pods -o wide | grep nginx
nginx-deploy-5964dfd755-b2xj5   1/1       Running   2          1d        10.244.0.16   170
nginx-deploy-5964dfd755-v6tdq   1/1       Running   1          4h        10.244.0.17   170


[root@171 nginx]# kubectl get ing | grep nginx
test         test.nginx.com             80        23h

[root@171 nginx]# kubectl get svc | grep nginx
nginx        ClusterIP   10.99.59.56   <none>        80/TCP    23h

在本地curl pod ip和service 的clusterIP測試:

[root@171 nginx]# curl http://10.244.0.16
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>


[root@171 nginx]# curl http://10.244.0.17
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>



[root@171 nginx]# curl http://10.99.59.56
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

nginx資源已經創建好了,但是目前只能在本地和集羣內訪問,集羣外部無法訪問,需要把網絡路由打通

三、網絡配置

1.vmware網絡配置:(無網絡限制這一步可跳過)
在公司的電腦上搭的wmware虛擬機,公司網絡上網認證限制外網,單人只允許使用單IP訪問外網,因此虛擬機爲了訪問外網,使用的是NAT模式轉接的物理機的網絡,vmware NAT方式虛擬機通信配置:
首先,每臺vm都要配置:
這裏寫圖片描述
vmware–編輯–虛擬網絡編輯器:
這裏寫圖片描述
這裏寫圖片描述

爲了直接訪問vm網段,在windows物理機上配置路由:
打開cmd,輸入:

route add 192.168.0.0 MASK 255.255.255.0  192.168.0.1 IF 9

IF是接口編號,可以使用route print查看自己電腦上vmnet8網卡對應的網卡接口編號
打開windows網絡共享中心,找到物理網卡,右鍵–屬性–共享,勾選開啓網絡連接共享(類似linux內核設置開啓IP forward轉發):
這裏寫圖片描述

2.k8s服務網段、pods網段路由,dns配置:
步驟1是隻是打通了外部到vm之間的網絡,如果沒有網絡限制,vm跟外部在同一網段的可以跳過上面的步驟1。

步驟2是外部添加k8s的服務網段、pods網段:
windows cmd添加

route add 10.96.0.0  MASK 255.240.0.0  192.168.0.169 IF 9
route add 10.244.0.0 MASK 255.255.0.0  192.168.0.169 IF 9

windows添加dns記錄:
C:\Windows\System32\drivers\etc\hosts打開編輯,添加dns記錄:

192.168.0.169       test.nginx.com
192.168.0.169       ui.traefik.com

打開瀏覽器測試訪問pod ip、服務的cluster ip:
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
可以直接訪問!
下面開始部署traefik,通過虛擬主機名訪問.

四、traefik部署

[root@171 traefik]# ls
traefik-ds.yaml  traefik_ingress.yaml  traefik-rbac.yaml


[root@171 traefik]# cat traefik-rbac.yaml 
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
  name: traefik-ingress-controller
  namespace: kube-system



[root@171 traefik]# cat traefik-ds.yaml 
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
---
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      hostNetwork: true
      containers:
      - image: traefik
        name: traefik-ingress-lb
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: admin
          containerPort: 8080
        securityContext:
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
        args:
        - --api
        - --kubernetes
        - --logLevel=INFO
---
kind: Service
apiVersion: v1
metadata:
  name: traefik-ingress-service
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      port: 80
      name: web
    - protocol: TCP
      port: 8080
      name: admin
  type: NodePort



[root@171 traefik]# cat traefik_ingress.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  creationTimestamp: 2018-04-09T11:39:48Z
  generation: 1
  name: traefik-ui
  namespace: default
  resourceVersion: "140644"
  selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/test
  uid: b54bbda8-3bea-11e8-b75a-000c29858eab
spec:
  rules:
  - host: ui.traefik.com
    http:
      paths:
      - backend:
          serviceName: traefik-ingress-service
          servicePort: 80
status:
  loadBalancer: {}

創建資源:

kubectl create -f traefik-rbac.yaml --record
kubectl create -f traefik-ds.yaml --record
kubectl create -f traefik-ingress.yaml --record

1分鐘後查看創建情況:

[root@171 traefik]# kubectl get pods -o wide -n kube-system| grep trae
traefik-ingress-controller-8lht4       1/1       Running   0          3h        192.168.0.171   171
traefik-ingress-controller-ddvws       1/1       Running   0          3h        192.168.0.170   170


[root@171 traefik]# kubectl get ds  -n kube-system| grep trae
traefik-ingress-controller   2         2         2         2            2           <none>          3h


[root@171 traefik]# kubectl get ing 
NAME         HOSTS            ADDRESS   PORTS     AGE
test         test.nginx.com             80        1d
traefik-ui   ui.traefik.com             80        3h

打開瀏覽器測試:
這裏寫圖片描述
這裏寫圖片描述

總結

k8s的各種功能組件、名詞概念、資源類型(pod/svc/ds/rs/ingress/configmap/role….)、工作流程 等頗爲複雜,理解起來不太容易,需要花時間閱讀官方文檔,因爲k8s更新很快,有一些新功能或者即將淘汰的舊功能,官方的中文文檔更新不太及時,建議直接閱讀英文文檔。

另外這裏爲了方便展示,用的windows查看效果,用linux curl工具測試是一樣的,且網絡的限制,使用的是vmware的NAT,需要多配置一步物理機網絡到vm網絡之間打通,再使用靜態路由讓k8s內部集羣網絡進行通信。有時間回家裏電腦嘗試下GNS3模擬路由器,搭建外部bgp,發佈到集羣bgp內部。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章