iT邦幫忙

2023 iThome 鐵人賽

DAY 20
0
自我挑戰組

可能會迷路的航行 - 菜雞的kubernetes學習筆記系列 第 20

Day 20 Ingress & Ingress Controller - 2 - 幫資料庫加上 Ingress

  • 分享至 

  • xImage
  •  

雖然 Ingress 只支援將 HTTP(S) request 路由到內部 Service,但 Ingres-Nginx 可以接受外部的 TCP/UDP 請求並轉給內部 Service。因中文的文章似乎滿少示範將 Web 以外的 App 加上 Ingress (還是只是我沒找到),今天就來實作看看。主要設定檔參考官網:https://kubernetes.github.io/ingress-nginx/user-guide/exposing-tcp-udp-services/。

今天用的環境一樣是 Ubuntu 22.04。

DB configuration

以下是這篇建 MySQL 的設定檔,包含 secret、statefulset、headless service。一樣為了方便就先建在 default namespace。

apiVersion: v1
kind: Service
metadata:
  name: mysql-h
spec:
  ports:
    - port: 3306
  selector:
    app: mysql
  clusterIP: None
---
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secret
data:
  MYSQL_ROOT_PASSWORD: eW91cnB3ZA==
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql-h
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:8.1
          resources:
            requests:
              memory: 512Mi
              cpu: 500m
            limits:
              memory: 1Gi
              cpu: 1000m
          ports:
            - containerPort: 3306
          envFrom:
            - secretRef:
              name: mysql-secret
          volumeMounts:
            - name: mysql-vol
              mountPath: /var/lib/mysql
  volumeClaimTemplates:
    - metadata:
        name: mysql-vol
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 1Gi

Secret 的部分建議不要放到 code repository (github, gitlab …)。但在部署的時候要怎麼處理這個 Secret 是另一個問題。恰好看到一篇 - https://ithelp.ithome.com.tw/articles/10250620 ,有興趣的人可以研究看看。怎麼用 Hashicorp Vault 處理 secret 的這個主題...完賽前不曉得能不能研究到。

Exposing TCP (UDP) Services

Ingress-Nginx Controller 如果要接收 TCP or UDP 的請求,安裝時需更改一些設定。

我們會需要建立一個 ConfigMap,其中要定義好使用哪個 port 以及對應的 service name & service 開的 port。

apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: ingress-nginx
data:
  3306: "default/mysql-h:3306"

這邊是使用 port 3306 來暴露 default namespace 中的 mysql-h service (also listening to port 3306)。

接下來把 ingress-nginx 設定檔載下來 (https://kubernetes.github.io/ingress-nginx/deploy/)

curl -o ingress-nginx-deploy.yaml https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml

如果要使用 TCP/UDP,ingress-nginx controller 中的 LoadBalancer service 必須要暴露我們想用的 port。這邊在剛才建立的 ingress-nginx-deploy.yaml 之中,找到 LoadBalancer Service -

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.8.2
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  externalTrafficPolicy: Local
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - appProtocol: http
    name: http
    port: 80
    protocol: TCP
    targetPort: http
  - appProtocol: https
    name: https
    port: 443
    protocol: TCP
    targetPort: https
	# ADD BELOW PORT
	- name: proxied-tcp-3306
		port: 3306
		protocol: TCP
		targetPort: 3306
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  type: LoadBalancer

這邊加上 proxied-tcp-3306 這個 port。

最後在跑 ingress-nginx deployment 時,args 需加上 --tcp-services-configmap 這個 flag。在 ingress-nginx-deploy.yaml 之中,找 name = ingress-nginx-controller 的 Deployment -
https://ithelp.ithome.com.tw/upload/images/20231003/20162795QHfUOG8hs9.png

因內容太長了,只擷取 args 的部分

# ..............
		spec:
      containers:
        - args:
            - /nginx-ingress-controller
						# --tcp-services-configmap=<namespace>/<configmap name>
						- --tcp-services-configmap=ingress-nginx/tcp-services
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
            - --election-id=ingress-nginx-leader
            - --controller-class=k8s.io/ingress-nginx
            - --ingress-class=nginx
            - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
            - --validating-webhook=:8443
            - --validating-webhook-certificate=/usr/local/certificates/cert
            - --validating-webhook-key=/usr/local/certificates/key
# ..............

在跑 containers 需要跑的 argument 加上 - --tcp-services-configmap=ingress-nginx/tcp-services ,其中 ingress-nginx 是 configmap 所在的 namespace、tcp-services 是 configmap name。

最後記得加上 Ingress,將 request 導向前面建立的 mysql-h service

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mysql-ingress
  labels:
    name: mysql-ingress
spec:
	ingressClassName: nginx
  rules:
    - host: mysql.example.com
      http:
        paths:
          - path: /
            pathType: Exact
            backend:
              service:
                name: mysql-h
                port:
                  number: 3306

檔案都準備好了,就可以 apply 這些 yaml 啦。但 tcp-configmap.yaml 執行順序要在 ingress-nginx-deploy.yaml 後面,因在這之前沒有對應的 namespace。
https://ithelp.ithome.com.tw/upload/images/20231003/20162795tl9AXwMskW.png

可以看到 LoadBalancer 開的 Port 比之前多了 3306 port。

再檢查一下 app & ingress 是否都順利被建立
https://ithelp.ithome.com.tw/upload/images/20231003/201627955Kyy34aCRW.png

接下來我們要怎麼測試能不能連得上 mysql,而且使用我們前面設好的 root password 呢?

可以在本機安裝 MySQL,或是,我們跑一個 MySQL 的 Pod (or Docker) 來試試 - 原本是這樣想的但因為種種原因…我只能先跑個 MySQL Pod 透過 LoadBalancer External IP 來連線 -
https://ithelp.ithome.com.tw/upload/images/20231003/20162795sfPgma3sqe.png

這邊輸入的密碼是前面 secret 設定的密碼,成功進去 DB 內!

另外嘗試用 telent 的方式連線,在本機連接得到,但就…無法驗證密碼
https://ithelp.ithome.com.tw/upload/images/20231003/20162795ZUaUwsv3kb.png


有點鳥的結束,推測 MySQL image 的環境應該預設是無法進去 container 中編輯檔案。另一條路則是直接本地安裝 MySQL 也是能使用 MySQL command,但機器規格開太小……

但至少知道除了 HTTP(S) 外還是能透過 Ingress-Nginx 去接走 TCP protocol 的 services。這邊應該還可以測試怎麼真的用另一台主機連線,一樣待補QQ。

Reference
https://kubernetes.github.io/ingress-nginx/user-guide/exposing-tcp-udp-services/


上一篇
Day 19 Ingress & Ingress Controller - 1 - 幫 Web App 加上 Ingress
下一篇
Day 21 Jobs, CronJobs, DaemonSet
系列文
可能會迷路的航行 - 菜雞的kubernetes學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言