การตั้งค่า Ingress Controller สำหรับ Kubernetes cluster (RKE 2) ที่ใช้ kube-vip


ในการเปิดช่องทางให้ผู้ใช้สามารถเข้าถึง Pod หรือ Deployment จากภายนอกนั้น นอกจากการใช้ Service ประเภท NodePort หรือ LoadBalancer แล้ว ยังสามารถใช้ Ingress เพื่อเปิดให้เข้าถึง Pod/Deployment ผ่าน hostname ที่ถูกเรียกใช้งานได้อีกด้วย ตัวอย่างเช่น

  • เข้าผ่าน app1.example.com ให้เชื่อมต่อไปที่ Deployment ชื่อ app1
  • เข้าผ่าน app2.example.com ให้เชื่อมต่อไปที่ Deployment ชื่อ app2
  • เข้าผ่าน app2.example.com/api/v1 ให้เชื่อมต่อไปที่ Deployment ชื่อ app2-api-v1

โดย Ingress จะเป็นทรัพยากรที่ใช้ตั้งค่า เช่นให้ hostname ไหนใช้ Pod/Deployment ไหน แต่ส่วนที่ทำหน้าที่ประมวลผลการตั้งค่าเหล่านี้คือ Ingress Controller

Ingress Controller ที่ติดตั้งมาพร้อมกัน RKE 2 คือ Ingress NGINX Controller ที่ผ่านการปรับการตั้งค่าให้เหมาะสำหรับ Kubernetes cluster ที่ติดตั้งภายในองค์กร ซึ่งโดยทั่วไปแล้วมักจะไม่รองรับทรัพยากร LoadBalancer เหมือนผู้ให้บริการคลาวด์

อย่างไรก็ตาม หากติดตั้ง kube-vip ใน Kubernetes cluster ด้วยวิธีการจากบทความก่อนหน้า จะทำให้สามารถใช้งานทรัพยากร LoadBalancer ได้ จึงควรปรับค่า Ingress NGINX Controller ให้กลับมาใช้งาน LoadBalancer เพื่อเพิ่มประสิทธิภาพในการกระจายภาระงาน

RKE 2 มีความสามารถในการติดตั้งทรัพยากรที่อยู่ในโฟลเดอร์ /var/lib/rancher/rke2/server/manifests ของโนดโดยอัตโนมัติ จึงสามารถนำไฟล์ YAML หรือแม้แต่ไฟล์ Helm Chart ไปวางไว้เพื่อสร้างทรัพยากรใน Kubernetes cluster ได้ ซึ่งส่วนประกอบที่สำคัญ รวมถึง Ingress Controller ที่มาพร้อมกับ RKE 2 ก็ติดตั้งโดยใช้วิธีนี้เช่นเดียวกัน ดังจะเห็นได้จากไฟล์ที่อยู่ในนั้น

$ sudo ls /var/lib/rancher/rke2/server/manifests
kube-vip-cloud-controller.yml          kube-vip.yml       rke2-ingress-nginx.yaml
kube-vip-cloud-provider-configmap.yml  rke2-canal.yaml    rke2-metrics-server.yaml
kube-vip-rbac.yml                      rke2-coredns.yaml

บทความนี้จะเป็นการปรับการตั้งค่า Ingress Controller สำหรับ Kubernetes cluster (RKE 2) ที่ใช้ kube-vip โดยมีขั้นตอนดังนี้

  1. ปรับค่า Ingress NGINX Controller ให้กลับมาใช้งาน LoadBalancer
  2. สร้าง Ingress Controller เพิ่มเติมสำหรับการเข้าถึงจากภายนอก

ปรับค่า Ingress NGINX Controller ให้กลับมาใช้งาน LoadBalancer

การปรับการตั้งค่าทรัพยากรเดิมใน RKE 2 สามารถทำได้โดยใช้ HelmChartConfig ดังนั้น หากต้องการปรับค่า Ingress NGINX Controller เดิม ให้สร้างไฟล์ rke2-ingress-nginx-config.yaml ขึ้นมา ให้มีเนื้อหาดังนี้

apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: rke2-ingress-nginx
  namespace: kube-system
spec:
  valuesContent: |-
    controller:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app.kubernetes.io/instance
                operator: In
                values:
                - rke2-ingress-nginx
            topologyKey: "kubernetes.io/hostname"
      hostPort:
        enabled: false
      ingressClassResource:
        default: true
      kind: Deployment
      publishService:
        enabled: true
      service:
        enabled: true

จากนั้นจึงคัดลอกไปไว้ในโฟลเดอร์สำหรับติดตั้ง manifest โดยใช้คำสั่ง sudo mv rke2-ingress-nginx-config.yaml /var/lib/rancher/rke2/server/manifests และรอให้การติดตั้งสิ้นสุด โดยตรวจสอบได้โดยใช้คำสั่ง kubectl -n kube-system get svc หาก TYPE ของรายการ rke2-ingress-nginx-controller กลายเป็น LoadBalancer แสดงว่าติดตั้งสำเร็จแล้ว ตัวอย่าง:

NAME                                 TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                      AGE
...
rke2-ingress-nginx-controller        LoadBalancer   10.41.116.24   192.168.0.195   80:31510/TCP,443:31792/TCP   1d
...

สร้าง Ingress Controller เพิ่มเติมสำหรับการเข้าถึงจากภายนอก

องค์กรอาจจะมีการจัดกลุ่มระบบงานสำหรับใช้ภายใน (intranet) และระบบงานที่เปิดให้เข้าถึงได้จากสาธารณะ (internet) ซึ่งสามารถนำมาปรับใช้ใน Kubernetes cluster โดยการใช้ Ingress Controller 2 ชุด ดังนี้

  • rke2-ingress-nginx มีเฉพาะ private ip
  • rke2-ingress-nginx-public มี private ip ที่ port forward ไปยัง public ip

ซึ่ง RKE 2 มี rke2-ingress-nginx อยู่แล้ว จึงเหลือเฉพาะส่วนที่ต้องตั้งค่าเพิ่มเติม คือ rke2-ingress-nginx-public ซึ่งสามารถทำได้โดยคัดลอกไฟล์ manifest ของ Ingress Controller เดิมมาไว้พักไว้และเปลี่ยนชื่อโดยใช้คำสั่ง sudo cp /var/lib/rancher/rke2/server/manifests/rke2-ingress-nginx.yaml . && mv rke2-ingress-nginx.yaml rke2-ingress-nginx-public.yaml จากนั้นแก้ไขไฟล์ ดังนี้

  1. แก้ metadata.name จาก rke2-ingress-nginx เป็น rke2-ingress-nginx-public
  2. เพิ่ม spec.valuesContent ตามตัวอย่างด้านล่าง
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  annotations:
    helm.cattle.io/chart-url: https://rke2-charts.rancher.io/assets/rke2-ingress-nginx/rke2-ingress-nginx-4.1.004.tgz
  name: rke2-ingress-nginx-public
  namespace: kube-system
spec:
  chartContent: H4sICGHX2WICA3Rtc...
  set:
    ...
  valuesContent: |-
    controller:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app.kubernetes.io/instance
                operator: In
                values:
                - rke2-ingress-nginx-public
            topologyKey: "kubernetes.io/hostname"
      containerName: "controller"
      electionID: public-ingress-controller-leader
      hostPort:
        enabled: false
      ingressClass: public-nginx
      ingressClassResource:
        name: public-nginx
        controllerValue: "k8s.io/public-ingress-nginx"
      kind: Deployment
      publishService:
        enabled: true
      service:
        enabled: true
      watchIngressWithoutClass: false
status: {}

จากนั้นจึงคัดลอกไฟล์ที่แก้ไขแล้วไปไว้ในโฟลเดอร์ manifest โดยใช้คำสั่ง sudo mv rke2-ingress-nginx-public.yaml /var/lib/rancher/rke2/server/manifests และรอให้การติดตั้งสิ้นสุด โดยตรวจสอบได้โดยใช้คำสั่ง kubectl -n kube-system get svc หากมีรายการ rke2-ingress-nginx-public-controller เพิ่มขึ้นมา แสดงว่าติดตั้งสำเร็จแล้ว ตัวอย่าง:

$ kubectl -n kube-system get svc
NAME                                   TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                      AGE
...
rke2-ingress-nginx-public-controller   LoadBalancer   10.41.22.144   192.168.0.191   80:30661/TCP,443:31087/TCP   1d
...

ตัวอย่างการใช้งาน

จากการตั้งค่า Ingress Controller ด้านบน กรณีที่ต้องการสร้าง Ingress สำหรับใช้งานภายใน ไม่ต้องระบุ spec.ingressClassName หรือระบุให้เป็น nginx ดังนี้

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  ...
spec:
  ingressClassName: nginx
  ...

กรณีที่ต้องการสร้าง Ingress ที่เข้าถึงได้จากอินเทอร์เน็ต ให้ระบุ spec.ingressClassName เป็น public-nginx ดังนี้

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  ...
spec:
  ingressClassName: public-nginx
  ...

แสดงความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *