Kubernetes 使用 ingress 配置 https 集羣(十五)

[TOC]

一、背景

1.1 需求

我們有這樣的一個需求,就是把 Pod 集羣升級爲 https,目前的辦法就是要麼每個容器配置 https,然後前端通過 Service 進行調度,但是這樣配置起來會比較麻煩,以及每個容器的建立都通過 https ,也增加了建立連接的負擔。

我們需要一種這樣的改造,就是客戶端連接到 Service 是通過 https,而 Service 向後端 Pod 的調度通過 http,這樣可以極大的優化我們的集羣,這裏我們就需要用到 Kubernetes 的另外一種資源 Ingress

Kubernetes 使用 ingress 配置 https 集羣(十五)

1.2 Ingress

Ingress 就是一個負載均衡的應用,它和 Service 的不同之處在於,Service 只可以支持 4 層的負載均衡,而 Ingress 是支持 7 層的負載均衡,支持 http 和 https,包括通過主機名的訪問已經路徑訪問的過濾。

那爲什麼不直接使用 Nginx?這是因爲在 K8S 集羣中,如果每加入一個服務,我們都在 Nginx 中添加一個配置,其實是一個重複性的體力活,只要是重複性的體力活,我們都應該通過技術將它幹掉。

Ingress就可以解決上面的問題,其包含兩個組件Ingress ControllerIngress

  • Ingress:將Nginx的配置抽象成一個Ingress對象,每添加一個新的服務只需寫一個新的Ingress的yaml文件即可;
  • Ingress Controller:將新加入的 Ingress 轉化成 Nginx 的配置文件並使之生效,包含 Contour、F5、HAProxy、Istio、Kong、Nginx、Traefik,官方推薦我們使用 Nginx。

Kubernetes 使用 ingress 配置 https 集羣(十五)

1.3 環境介紹

我們是採用了三臺服務器的一個集羣,部署文檔請查看我之前的博文

IP 角色
192.168.1.200 k8s-master
192.168.1.201 k8s-node01
192.168.1.202 k8s-node02
[root@master ~]# kubectl get nodes
NAME     STATUS   ROLES    AGE    VERSION
master   Ready    master   117s   v1.13.0
node01   Ready    <none>   52s    v1.13.0
node02   Ready    <none>   42s    v1.13.0

二、安裝部署

我們這裏只針對上面架構圖中的域名www.wzlinux.com改造成https。

我們將以官方的標準腳本爲基礎進行搭建,參考請戳官方文檔。官方文檔中要求執行如下命令:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml

2.1、創建後端 Pod 應用

我們創建一個控制器wzlinux-deploy.yaml,內容如下:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: wzlinux-dep
spec:
  replicas: 3
  template:
    metadata:
      labels:
        run: wzlinux
    spec:
      containers:
      - name: wzlinux
        image: wangzan18/mytest:v1
        ports:
        - containerPort: 8080

創建好之後查看如下:

[root@master ingress]# kubectl get pod
NAME                           READY   STATUS    RESTARTS   AGE
wzlinux-dep-78d5d86c7c-fj8f5   1/1     Running   0          53m
wzlinux-dep-78d5d86c7c-hr6gd   1/1     Running   0          53m
wzlinux-dep-78d5d86c7c-jqf59   1/1     Running   0          53m

2.2 創建後端 Pod Service

測試好 Pod 一些正常之後,我們爲這一組 Pod 創建一個 Service,文件wzlinux-svc.yaml內容如下:

apiVersion: v1
kind: Service
metadata:
  name: wzlinux-svc
spec:
  selector:
    run: wzlinux
  ports:
  - port: 80
    targetPort: 8080

這個 Service 並不是我們用了代理訪問 Pod 的,只是用來ingress-controller來進行選擇控制使用的,所以上圖描述爲虛線。

[root@master ingress]# kubectl get svc
NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kubernetes    ClusterIP   10.96.0.1        <none>        443/TCP    58m
wzlinux-svc   ClusterIP   10.106.219.230   <none>        8080/TCP   50m
[root@master ingress]# curl 10.106.219.230:8080
Hello Kubernetes bootcamp! | Running on: wzlinux-dep-78d5d86c7c-fj8f5 | v=1

2.3、創建 ingress 資源

爲了實現過濾以及 https 功能,我們需要創建 ingress 資源文件,ingress controller 把其中的資源加載到 nginx 裏面,資源文件wzlinux-ingress.yaml文件內容如下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: wzlinux-ingress
spec:
  rules:
  - host: www.wzlinux.com
    http:
      paths:
      - path:
        backend:
          serviceName: wzlinux-svc
          servicePort: 8080

我們這裏先不改爲 https,先使用虛擬主機域名過濾模式,創建好資源之後查看

[root@master ingress]# kubectl get ingress
NAME              HOSTS             ADDRESS   PORTS   AGE
wzlinux-ingress   www.wzlinux.com             80      37m

可以看到配置了域名www.wzlinux.com,其他地址訪問將返回404。

2.4、爲 Nginx Pod 創建 Service

我們可以查看部署的 Nginx Pod 容器,我們設定的 ingress 資源會被 controller 更新到裏面,我們可以查看如下:

[root@master ingress]# kubectl get pod -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-766c77b7d4-dlcpf   1/1     Running   0          31m

爲了是外網可以訪問到這個 Nginx Pod,我們需要爲其再創建一個 Service,文件ingress-nginx.yaml,文件內容如下:

apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: 80
    nodePort: 30080
  - name: https
    port: 443
    targetPort: 443
    nodePort: 30443
  selector:
    app.kubernetes.io/name: ingress-nginx

測試是否正常,記得在/etc/hosts中把域名執行的IP改爲node節點的地址。

[root@master ~]# curl 192.168.1.200:30080
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.15.6</center>
</body>
</html>
[root@master ~]# curl www.wzlinux.com:30080
Hello Kubernetes bootcamp! | Running on: wzlinux-dep-78d5d86c7c-hr6gd | v=1

可以看到通過域名訪問正常調度到後端,其他地址訪問返回404,目前整個流程已經測試完成,下面我們升級爲 https。

三、升級爲 https

3.1 首先我們要製作證書

關於證書大家可以使用 openssl 製作,創建私有:

openssl genrsa -out wzlinux.key 2048

製作自簽證書。

openssl req -new -x509 -key wzlinux.key -out wzlinux.crt -subj /C=CN/ST=Shanghai/L=Shanghai/O=DevOps/CN=www.wzlinux.com

不過我這裏使用阿里雲的官方免費證書,大家可以到阿里雲進行申請。
Kubernetes 使用 ingress 配置 https 集羣(十五)

Kubernetes 使用 ingress 配置 https 集羣(十五)
製作好證書之後下載即可,裏面包含公鑰和私鑰。

3.2、創建 secret 資源

可以使用 yaml 文件創建,文件名稱wzlinux-secret.yaml內容如下:

apiVersion: v1
kind: Secret
data:
  tls.crt: base64 encoded cert
  tls.key: base64 encoded key
metadata:
  name: wzlinux-secret
  namespace: default
type: Opaque

因爲編碼的密碼太長,我們這裏直接使用命令行進行創建吧,操作比較簡單。

kubectl create secret tls wzlinux-secret --cert=wzlinux.crt --key=wzlinux.key

查看創建好的 secret。

[root@master ingress]# kubectl describe secret wzlinux-secret
Name:         wzlinux-secret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  kubernetes.io/tls

Data
====
tls.crt:  1996 bytes
tls.key:  1675 bytes

3.3 更改 ingress 資源

重新編輯wzlinux-ingress.yaml,增加一個 tls 字段:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: wzlinux-ingress
spec:
  tls:
  - hosts:
    - www.wzlinux.com
    secretName: wzlinux-secret
  rules:
  - host: www.wzlinux.com
    http:
      paths:
      - path:
        backend:
          serviceName: wzlinux-svc
          servicePort: 8080

3.4 瀏覽器訪問驗證

打開瀏覽器,記得修改好 hosts 域名解析。
Kubernetes 使用 ingress 配置 https 集羣(十五)

四、ingress 資源介紹

4.1、通過訪問路徑過濾

foo.bar.com -> 178.91.123.132 -> / foo    service1:4200
                                 / bar    service2:8080

配置文件我們設置爲如下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: simple-fanout-example
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /foo
        backend:
          serviceName: service1
          servicePort: 4200
      - path: /bar
        backend:
          serviceName: service2
          servicePort: 8080

4.2、基於名稱解析的虛擬主機

foo.bar.com --|                 |-> foo.bar.com s1:80
              | 178.91.123.132  |
bar.foo.com --|                 |-> bar.foo.com s2:80

配置文件內容格式如下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: name-virtual-host-ingress
spec:
  rules:
  - host: first.bar.com
    http:
      paths:
      - backend:
          serviceName: service1
          servicePort: 80
  - host: second.foo.com
    http:
      paths:
      - backend:
          serviceName: service2
          servicePort: 80
  - http:
      paths:
      - backend:
          serviceName: service3
          servicePort: 80

4.3、https

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: tls-example-ingress
spec:
  tls:
  - hosts:
    - sslexample.foo.com
    secretName: testsecret-tls
  rules:
    - host: sslexample.foo.com
      http:
        paths:
        - path: /
          backend:
            serviceName: service1
            servicePort: 80
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章