在 k8s 中通過 Ingress 配置域名訪問

shanyue發表於2019-10-30

在上篇文章中我們已經使用 k8s 部署了第一個應用,此時我們可以使用 Ingress 使它可以在網際網路上可以被訪問到 (當然你要有自己的域名並且指向正確)

以下是官網搬用的關於 Ingress 的一幅圖,用以描述 Ingress 的作用。如果你對它一無所知,你可以把它理解為傳統的 nginx,用以配置自己網站的域名使之能夠通過外網訪問。

internet
    |
[ Ingress ]
--|-----|--
[ Services ]
複製程式碼

其中,Ingress 包含兩個元件

  • Ingress: 配置轉發規則,類似於 nginx 的配置檔案
  • Ingress Controller: 轉發,類似於 nginx,它會讀取 Ingress 的規則並轉化為 nginx 的配置檔案

Ingress Controller 除了 nginx 外還有 haproxyingress 等等,我們選用 nginx 作為 Ingress Controller

使用 helm 部署 nginx Ingress Controller

我們使用 helm 選擇官方的 stable/nginx-ingress chart 進行部署。

nginx-ingress 會配置一個 type 為 LoadBalancer 的 service, 因此需要配置 EXTERNAL-IP 為k8s叢集節點的 IP。 在這裡 external-ip 會設定為 [172.17.68.39, 172.17.68.40]

我們可以通過 kubectl get nodes 來獲取 IP 地址

# 獲取node的 INTERNAL-IP,作為 LoadBalancer 的 EXTERNAL-IP
$ kubectl get nodes -o wide
NAME       STATUS   ROLES    AGE   VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION               CONTAINER-RUNTIME
shanyue    Ready    master   13d   v1.16.0   172.17.68.39   <none>        CentOS Linux 7 (Core)   3.10.0-957.21.3.el7.x86_64   docker://18.6.2
shuifeng   Ready    <none>   13d   v1.16.0   172.17.68.40   <none>        CentOS Linux 7 (Core)   3.10.0-957.21.3.el7.x86_64   docker://18.6.2
複製程式碼

在這裡 external-ip 會設定為 [172.17.68.39, 172.17.68.40]

controller.service.externalIPs[0]=172.17.68.39
controller.service.externalIPs[1]=172.17.68.40
複製程式碼
# 使用 helm v3 部署,如果使用 helm v2 部署的話,把 release-name 使用 --name 指定
$ helm install nginx-ingress stable/nginx-ingress --set "controller.service.externalIPs[0]=172.17.68.39,controller.service.externalIPs[1]=172.17.68.40"
NAME: nginx-ingress
LAST DEPLOYED: 2019-10-18 21:21:44.115902395 +0800 CST m=+1.904554085
NAMESPACE: default
STATUS: deployed
NOTES:
The nginx-ingress controller has been installed.
It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status by running 'kubectl --namespace default get services -o wide -w nginx-ingress-controller'

An example Ingress that makes use of the controller:

  apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    annotations:
      kubernetes.io/ingress.class: nginx
    name: example
    namespace: foo
  spec:
    rules:
      - host: www.example.com
        http:
          paths:
            - backend:
                serviceName: exampleService
                servicePort: 80
              path: /
    # This section is only required if TLS is to be enabled for the Ingress
    tls:
        - hosts:
            - www.example.com
          secretName: example-tls

If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:

  apiVersion: v1
  kind: Secret
  metadata:
    name: example-tls
    namespace: foo
  data:
    tls.crt: <base64 encoded cert>
    tls.key: <base64 encoded key>
  type: kubernetes.io/tls
複製程式碼

校驗 nginx-ingress 的部署情況

$ helm ls
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART
nginx-ingress   default         1               2019-10-18 11:21:44.115902395 +0800 CST deployed        nginx-ingress-1.24.0

# 檢視 nginx-ingress 所有的 service
$ kubectl get svc -l app=nginx-ingress
NAME                            TYPE           CLUSTER-IP     EXTERNAL-IP                 PORT(S)                      AGE
nginx-ingress-controller        LoadBalancer   10.101.64.64   172.17.68.39,172.17.68.40   80:30285/TCP,443:31094/TCP   7m19s
nginx-ingress-default-backend   ClusterIP      10.110.76.15   <none>                      80/TCP                       7m19s
複製程式碼

配置 Ingress 對映域名

與已知知識關聯有助於我們更好地學習新知識,以下是關於 nginx 與 ingress 部署一個部落格應用的簡單配置檔案

  1. 外網通過域名 nginx.xiange.tech 來訪問應用
  2. 代理服務 nginx 來做負載均衡
  3. nginx 暴露出 80 埠
server {
  listen 80
  server_name nginx.xiange.tech

  location / {
    proxy_pass: http://nginx:80
  }
}
複製程式碼

使用 Ingress 配置路由規則如下

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: nginx-service-ingress
spec:
  rules:
  - host: nginx.xiange.tech
    http:
      paths:
      - backend:
          serviceName: nginx-service
          servicePort: 80
        path: /
複製程式碼

我們使用 Ingress 把它配置到了 nginx.xiange.tech 該域名下,在公網環境下的瀏覽器中開啟域名 nginx.xiange.tech,可以看到熟悉的 nginx 配置頁面

在 k8s 中通過 Ingress 配置域名訪問

小結

部署一個應用從 DeploymentService 再到 Ingress 的完整配置檔案如下

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

---

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: nginx-service-ingress
spec:
  rules:
  - host: nginx.xiange.tech
    http:
      paths:
      - backend:
          serviceName: nginx-service
          servicePort: 80
        path: /
複製程式碼

關注我

歡迎關注公眾號山月行,我會定期分享一些前後端以及運維的文章,並且會有技術與生活上的每日回顧與總結,歡迎關注交流

歡迎關注公眾號山月行,我會定期分享一些前後端以及運維的文章

相關文章