ClusterIP, NodePort, Loadbalance – Các loại service K8S

Trong môi trường Kubernetes, service đóng vai trò quan trọng trong việc duy trì sự kết nối và giao tiếp giữa các ứng dụng và dịch vụ. Trong bài viết này, chúng ta sẽ tìm hiểu về ba loại service chính trong Kubernetes: ClusterIP, NodePort, và LoadBalancer.

Xem thêm:

Tổng quan về kubernetes (k8s)

Containerd là gì ? So sánh Docker và Containerd

1. Cluster IP

Cluster IP là một loại service chỉ cho phép truy cập bên trong cluster. Nghĩa là, các thành phần trong cùng một cluster có thể trao đổi thông tin với nhau, nhưng các thành phần bên ngoài cụm không thể giao tiếp được.

ClusterIP là loại service mặc định trong K8s.

Cluster IP có một địa chỉ IP ảo được sử dụng để truy cập các Pod thuộc service. Địa chỉ IP này được cấp bởi Kubernetes và không thể thay đổi thủ công.

Lợi ích:

  • Bảo mật: Cluster IP cung cấp mức độ bảo mật cao hơn so với các loại service khác vì nó không thể truy cập được từ bên ngoài cluster Kubernetes.
  • Đơn giản: Cluster IP là loại service đơn giản nhất để sử dụng và cấu hình.
apiVersion: v1
kind: Service
metadata:  
  name: my-internal-service
spec:
  selector:    
    app: my-app
  type: ClusterIP
  ports:  
  - name: http
    port: 80
    targetPort: 80
    protocol: TCP
  • targetPort: là cổng trên pod, nơi máy chủ web thực đang chạy, service sẽ chuyển tiếp lưu lượng truy cập đến cổng này. Nếu không có cổng nào được chỉ định, nó sẽ mặc định là 80.
  • port: là port được mở của chính service. cũng giống như tất cả các đối tượng Kubernetes khác, service cũng là một máy chủ ảo trong node, nó cũng sẽ có địa chỉ ip riêng và port là nơi tiếp nhận kết nối đến dịch vụ. Giá trị này là bắt buộc.

Cluster IP

2. NodePort

NodePort là một loại service trong k8s cho phép truy cập tới các thành phần từ bên ngoài cụm Kubernetes thông qua một cổng cụ thể trên mỗi Node

  • nodePort: là cổng được sử dụng để truy cập các pod trong kubernetes. Cổng này được chọn ngẫu nhiên trong phạm vi 30000-32767.
apiVersion: v1
kind: Service
metadata:  
  name: my-nodeport-service
spec:
  selector:    
    app: my-app
  type: NodePort
  ports:  
  - name: http
    port: 80
    targetPort: 80
    nodePort: 30036
    protocol: TCP

– Nhược điểm:

  • Bạn chỉ có thể có một service với mỗi port
  • Bạn chỉ có thể sử dụng port từ 30000–32767
  • Nếu địa chỉ IP của Node, VM thay đổi, bạn sẽ phải xử lí điều đó.

Node Port

3. LoadBalancer

LoadBalancer là dịch vụ cung cấp khả năng cân bằng tải và khả năng truy cập từ bên ngoài cụm Kubernetes thông qua một địa chỉ IP public.

LoadBalancer sử dụng một địa chỉ IP public được cung cấp bởi nhà cung cấp dịch vụ cloud (cloud provider) để truy cập các Pod thuộc service.

– Hạn chế:

  • Chi phí: LoadBalancer tốn kém hơn các loại service khác.
  • LoadBalancer phụ thuộc vào nhà cung cấp dịch vụ cloud để cung cấp địa chỉ IP public.
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 9376
      nodePort: 31000
  selector:
    app: myapp

Load Balancer

 

4. Cách Expose Pod qua NodePort trong Kubernetes

1. Khởi tạo Namespace

Trước tiên, mình sẽ tạo một namespace mới cho dễ quản lý.

kubectl create namespace namedport
truongnt@masternode:~$ kubectl create namespace namedport
namespace/namedport created
truongnt@masternode:~$ kubectl get ns
NAME              STATUS   AGE
default           Active   3d14h
kube-node-lease   Active   3d14h
kube-public       Active   3d14h
kube-system       Active   3d14h
namedport         Active   6s

2. Tạo Deployment và Cấu hình Named Port

Giờ mình sẽ tạo một deployment chạy Nginx.

kubectl -n namedport create deployment named-port-deploy --image nginx --port 80 --dry-run=client -o yaml > named-port-deploy.yaml

Lệnh này chỉ tạo file YAML chứ chưa deploy thật. Mở file ra để chỉnh sửa:

sudo vi named-port-deploy.yaml

Tìm đến phần containerPort và thêm dòng name: http-web-svc như sau:

ports:
- containerPort: 80
  name: http-web-svc

Giờ thì apply thôi:

kubectl create -f named-port-deploy.yaml
truongnt@masternode:~$ kubectl -n namedport create deployment named-port-deploy --image nginx --port 80 --dry-run=client -o yaml > named-port-deploy.yaml
truongnt@masternode:~$ sudo vi named-port-deploy.yaml
[sudo] password for truongnt:
truongnt@masternode:~$ cat named-port-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: named-port-deploy
  name: named-port-deploy
  namespace: namedport
spec:
  replicas: 1
  selector:
    matchLabels:
      app: named-port-deploy
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: named-port-deploy
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80
          name: http-web-svc
        resources: {}
status: {}

truongnt@masternode:~$ kubectl create -f named-port-deploy.yaml
deployment.apps/named-port-deploy created

3. Tạo Service Kiểu NodePort với Named Port

Giờ mình expose deployment đó thành một service kiểu NodePort để truy cập từ bên ngoài cluster.

kubectl -n namedport expose deployment named-port-deploy --port 8080 --target-port=http-web-svc --type=NodePort --dry-run=client -o yaml > named-port-svc.yaml

Sau đó mở file named-port-svc.yaml ra:

sudo vi named-port-svc.yaml

Và sửa thêm phần name: myserviceportnodePort: 31704 như sau:

ports:
- port: 8080
  targetPort: http-web-svc
  nodePort: 31704
  name: myserviceport

Rồi apply:

kubectl create -f named-port-svc.yaml
truongnt@masternode:~$ kubectl -n namedport expose deployment named-port-deploy --port 8080 --target-port=http-web-svc --type=NodePort --dry-run=client -o yaml > named-port-svc.yaml
truongnt@masternode:~$ sudo vi named-port-svc.yaml
truongnt@masternode:~$ cat named-port-svc.yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: named-port-deploy
  name: named-port-deploy
  namespace: namedport
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: http-web-svc
    nodePort: 31704
    name: myserviceport
  selector:
    app: named-port-deploy
  type: NodePort
status:
  loadBalancer: {}
truongnt@masternode:~$ kubectl create -f named-port-svc.yaml
service/named-port-deploy created

4. Truy cập ứng dụng qua CURL

Dùng NodePort

curl 127.0.0.1:31704
curl localhost:31704

Dùng ClusterIP (nếu bạn chạy từ bên trong cluster)

kubectl -n namedport get svc
curl <ClusterIP>:8080

Bạn lấy địa chỉ IP ở dòng CLUSTER-IP rồi chạy curl như trên.

5. Xóa Tất Cả Tài Nguyên

kubectl -n namedport delete all --all
kubectl delete ns namedport

Hy vọng qua bài viết trên bạn đã có những kiến thức cơ bản về 3 loại dịch vụ chính trong k8s. Cảm ơn bạn đã tham khảo kubernetes cơ bản trên ttnguyen.net.

Bài viết liên quan:

Kubenetes Deployments là gì ?

Namespace và Cgroups trong K8S

Nguyễn Tiến Trường

Mình viết về những điều nhỏ nhặt trong cuộc sống, Viết về câu chuyện những ngày không có em