PRIVATE CLOUD OPENSHIFT – P3: Sử dụng OKD kết hợp với NFS server

Bài viết này là một phần của chùm bài viết: Private cloud OpenShift Bạn có thể đọc phần trước: “PRIVATE CLOUD OPENSHIFT – P2: Nâng cấp“ Ở bài viết P1, NFS server có tên là okd4-nfs và có ip là 192.168.99.53 NFS server này dùng để chứa Registry và các Data cần được mount vào

Bài viết này là một phần của chùm bài viết: Private cloud OpenShift

Bạn có thể đọc phần trước: “PRIVATE CLOUD OPENSHIFT – P2: Nâng cấp

Ở bài viết P1, NFS server có tên là okd4-nfs và có ip là 192.168.99.53
NFS server này dùng để chứa Registry và các Data cần được mount vào các container như là database chẳng hạn.

I/ Cài đặt okd4-nfs:

1. Tiền xử lý:

Cài hệ điều hành CentOS-8.3.2011-x86_64, với ip là 192.168.99.53 và để DNS: 192.168.99.51
Cài dịch vụ để đồng bộ ngày giờ: chrony
Cài NFS server: nfs-utils

2. Cấu hình NFS server:

-Firewalld

$ firewall-cmd --permanent --add-service=nfs
$ firewall-cmd --permanent --add-service=rpc-bind
$ firewall-cmd --permanent --add-service=mountd
$ firewall-cmd --reload

-Thiết lập thư mục để share:

$ mkdir /data
$ mkdir /data/registry
$ mkdir /data/opt
$ mkdir /data /database
$ chmod 777 /data/registry
$ chown nobody:nobody /data/registry

(Thư mục /data được thiết lập để chứa dữ liệu lớn, mount ổ đĩa 2Tb vào chẳng hạn)
-Thiết lập /etc/export:

/data 192.168.99.0/24(rw,sync,no_root_squash,no_all_squash,no_wdelay)

-Refresh và Verify lại NFS khi vừa thay đổi cấu hình

$ exportfs -r
$ exportfs -v

II/ Các vấn đề cần xử lý khi vừa cài xong OKD:

1. image-registry operator:

-Đứng tại okd4-services, tạo file /tmp/registry_pv.yaml với nội dung sau:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: registry-pv
spec:
  capacity:
    storage: 300Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /data/registry
    server: 192.168.99.53

-Tạo Persistent Volume cho Registry:

$ oc create -f /tmp/registry_pv.yaml
$ oc get pv
NAME          CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM  STORAGECLASS   REASON   AGE
registry-pv   300Gi      RWX            Retain           Avaiable                                10s

-Sửa image-registry operator:

$ oc edit configs.imageregistry.operator.openshift.io
sửa: managementState: Removed -> managementState: Managed
sửa: storage: {} -> storage:
                      pvc:
                        claim:
$ oc get pv
NAME          CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                             STORAGECLASS   REASON   AGE
registry-pv   300Gi      RWX            Retain           Bound    openshift-image-registry/image-registry-storage                           2m

-Expose service image-registry

$ oc patch svc image-registry -p '{"spec":{"externalIPs":["192.168.99.64","192.168.99.65"]}}' -n openshift-image-registry
$ oc get svc -n openshift-image-registry
NAME                              TYPE          CLUSTER-IP        EXTERNAL-IP                     PORT(S)      AGE
image-registry                    ClusterIP     172.30.120.99     192.168.100.64,192.168.100.65   5000/TCP     3d
image-registry-operator           ClusterIP     None              <none>                          60000/TCP    3d

2. HTPasswd Setup:

-Tạo thêm các user đăng nhập vào OKD

$ cd /tmp
$ htpasswd -c -B -b users.htpasswd k.admin abcxyz
$ htpasswd -B -b users.htpasswd kevin.chu abcxyz

(ví dụ tạo thêm 2 user: admin và kevin.chu có password là abcxyz)
-Apply vào OKD:

$ oc create secret generic htpass-secret --from-file=htpasswd=users.htpasswd -n openshift-config
$ oc apply -f htpasswd_provider.yaml
>oauth.config.openshift.io/cluster configured

-Gán quyền cluster-admin đến user k.admin:

$ oc adm policy add-cluster-role-to-user cluster-admin k.admin
>clusterrole.rbac.authorization.k8s.io/cluster-admin added: "k.admin"

Sau khi tạo xong, mỗi lần đăng nhập OKD sẽ thấy như hình sau:

Click vào htpasswd_provider và đăng nhập vào OKD với user k.admin vừa tạo ở trên.

III/ Chạy thử 1 app

App được chọn làm ví dụ là database Postgres 15.1
App sẽ được quản lý dưới project test

-Tạo nơi lưu trữ dữ liệu database postgres:
Đứng ở server nfs

$ mkdir /data/test-testdb
$ chown 999:999 /data/test-testdb

Những bước còn lại thao tác trên server okd-services

-Tạo project “test” từ user k.admin đã được tạo ở trên
Đây là 1 điểm khác biệt của OpenShift với Kubernetes: OpenShift dùng khái niệm project, còn Kubernetes dùng khái niệm namespace. Tuy nhiên 2 cái là một

Khi login vào OKD từ command line “oc login”, nó cần có certificate-authority (mặc dù đã dùng tham số insecure-skip-tls-verify=true)
Tạo file certificate-authority giả:

$ touch /tmp/a.crt

Login vào OKD và tạo project test

$ oc login -u k.admin -p abcxyz --certificate-authority=/tmp/a.crt --insecure-skip-tls-verify=true
$ oc new-project test

1 điểm khác biệt nữa của OpenShift với Kubernetes là các Container của OpenShift hầu như là chạy với user thường.

Do image postgres được build chạy với user 999 nên phải gán quyền cho container được chạy và được truy cập đến nfs

-Tạo và gán quyền truy cập đến nfs
Tạo 1 service account đặt tên là “mytest”

$ oc create serviceaccount mytest -n test

Tạo 1 scc, với nội dung sau: file /tmp/scc999.yaml

# Create SCC for Postgres resources
kind: SecurityContextConstraints
apiVersion: security.openshift.io/v1
metadata:
  name: scc999
allowPrivilegedContainer: true
runAsUser:
  type: MustRunAs
  uid: 999
seLinuxContext:
  type: RunAsAny
fsGroup:
  type: RunAsAny
supplementalGroups:
  type: RunAsAny
$ oc create -f /tmp/scc999.yaml

Gán scc999 cho service account mytest

$ oc adm policy add-scc-to-user scc999 -z mytest -n test

-Tạo deployment: tạo file postgres_deployment_version_limit_resource.json với nội dung dạng template sau:

{
  "apiVersion": "v1",
  "kind": "Template",
  "labels": {
    "template": "postgres-deployment-template"
  },
  "metadata": {
    "name": "postgres-deployment-template"
  },
  "objects": [
    {
      "kind": "Deployment",
      "apiVersion": "apps/v1",
      "metadata": {
        "name": "${PNAME}-${NAME}",
        "labels": {
          "name": "${PNAME}-${NAME}"
        }
      },
      "spec": {
        "replicas": 1,
        "selector": {
          "matchLabels": {
            "app": "${PNAME}-${NAME}"
          }
        },
        "template": {
          "metadata": {
            "labels": {
              "app": "${PNAME}-${NAME}"
            }
          },
          "spec": {
            "containers": [
              {
                "name": "${PNAME}-${NAME}",
                "image": "docker.io/library/postgres:${VERSION}",
                "ports": [
                  {
                    "containerPort": 5432,
                    "protocol": "TCP"
                  }
                ],
                "env": [
                  {
                    "name": "POSTGRES_PASSWORD",
                    "value": "${POSTGRES_PASSWORD}"
                  }
                ],
                "resources": {
                    "limits": {
                       "memory": "16Gi",
                       "cpu": "2000m"
                    },
                    "requests": {
                       "memory": "128Mi",
                       "cpu": "200m"
                    }
                 },
                "volumeMounts": [
                  {
                    "name": "postgres-env",
                    "mountPath": "/var/lib/postgresql/data"
                  }
                ],
                "terminationMessagePath": "/dev/termination-log",
                "imagePullPolicy": "IfNotPresent",
                "securityContext": {
                  "capabilities": {},
                  "runAsUser": 999
                }
              }
            ],
            "volumes": [
              {
                "name": "postgres-env",
                "nfs":
                  {
                     "server": "${SERVER_IP}",
                     "path": "/data/${PNAME}-${NAME}"
                  }
              }
            ],
            "restartPolicy": "Always",
            "dnsPolicy": "ClusterFirst",
            "serviceAccount": "mytest"
          }
        }
      }
    }
  ],
  "parameters": [
    {
      "description": "Project",
      "displayName": "PNAME",
      "name": "PNAME",
      "required": true
    },
    {
      "description": "Ten muon dat",
      "displayName": "NAME",
      "name": "NAME",
      "required": true
    },
    {
      "description": "version db postgres",
      "displayName": "VERSION",
      "name": "VERSION",
      "required": true,
      "value": "14.3"
    },
    {
      "description": "Password postgres",
      "displayName": "POSTGRES_PASSWORD",
      "name": "POSTGRES_PASSWORD",
      "value": "p123"
    },
    {
      "description": "IP's Server nfs share",
      "displayName": "IP's Server nfs share",
      "name": "SERVER_IP"
    }
  ]
}
$ oc process -f /tmp/postgres_deployment_version_limit_resource.json -p PNAME=test -p VERSION=15.1 -p NAME=testdb -p SERVER_IP=192.168.100.53 | oc create -f -
>deployment.apps/test-testdb created

-Expose service: tạo file postgres_svc_ip_expose.json với nội dung dạng template sau:

{
  "apiVersion": "v1",
  "kind": "Template",
  "labels": {
    "template": "postgres-svc-template"
  },
  "metadata": {
    "name": "postgres-svc-template"
  },
  "objects": [
    {
      "apiVersion": "v1",
      "kind": "Service",
      "metadata": {
        "name": "${PNAME}-${NAME}",
        "labels": {
          "app": "${PNAME}-${NAME}"
        }
      },
      "spec": {
        "selector": {
          "app": "${PNAME}-${NAME}"
        },
        "ports": [
          {
            "protocol": "TCP",
            "port": "${{PORT}}",
            "targetPort": 5432
          }
        ],
        "externalIPs": [
          "${IP_EXPOSE1}",
          "${IP_EXPOSE2}"
        ]
      }
    }
  ],
  "parameters": [
    {
      "description": "Project",
      "displayName": "PNAME",
      "name": "PNAME",
      "required": true
    },
    {
      "description": "Ten muon dat",
      "displayName": "NAME",
      "name": "NAME",
      "required": true
    },
    {
      "description": "PORT",
      "displayName": "PORT",
      "name": "PORT",
      "value": "5432",
      "required": true
    },
    {
      "description": "externalIP1",
      "displayName": "externalIP1",
      "name": "IP_EXPOSE1",
      "value": "192.168.99.64"
    },
    {
      "description": "externalIP2",
      "displayName": "externalIP2",
      "name": "IP_EXPOSE2",
      "value": "192.168.99.65"
    }
  ]
}
$ oc process -f /tmp/postgres_svc_ip_expose.json -p PNAME=test -p NAME=testdb -p PORT=5499 | oc create -f -
>service/test-testdb created

Lưu ý: mấy file dạng template khi đã test chạy ổn định rồi thì có thể build nó ra template để sau này tạo mấy database postgres mới mà không cần các file json

-Thử kết nối vào db mới tạo:

$ psql -h 192.168.99.64 -p 5499 -U postgres postgres
Password for user postgres:
psql (14.3, server 15.1 (Debian 15.1-1.pgdg110+1))
WARNING: psql major version 14, server major version 15.
         Some psql features might not work.
Type "help" for help.

postgres=#

Như vậy đã xong phần số 3 và hiện thời là 2 giờ sáng…

Hãy đón đọc bài tiếp theo “PRIVATE CLOUD OPENSHIFT – P4: Ingress”

Nguồn: viblo.asia

Bài viết liên quan

Thay đổi Package Name của Android Studio dể dàng với plugin APR

Nếu bạn đang gặp khó khăn hoặc bế tắc trong việc thay đổi package name trong And

Lỗi không Update Meta_Value Khi thay thế hình ảnh cũ bằng hình ảnh mới trong WordPress

Mã dưới đây hoạt động tốt có 1 lỗi không update được postmeta ” meta_key=

Bài 1 – React Native DevOps các khái niệm và các cài đặt căn bản

Hướng dẫn setup jenkins agent để bắt đầu build mobile bằng jenkins cho devloper an t

Chuyển đổi từ monolith sang microservices qua ví dụ

1. Why microservices? Microservices là kiến trúc hệ thống phần mềm hướng dịch vụ,