ในการเปิดช่องทางให้ผู้ใช้สามารถเข้าถึง 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 โดยมีขั้นตอนดังนี้
- ปรับค่า Ingress NGINX Controller ให้กลับมาใช้งาน LoadBalancer
- สร้าง 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
จากนั้นแก้ไขไฟล์ ดังนี้
- แก้
metadata.name
จากrke2-ingress-nginx
เป็นrke2-ingress-nginx-public
- เพิ่ม
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
...