멀티 클러스터 #4 Workload

codelab·2023년 10월 22일
0

Multi Cloud

목록 보기
8/11

cluster api 로 oci 구획에 일반 워크로드 생성


관리 클러스터에 대한 권한 설정

관리 클러스터의 oci cli 실행 권한

사전에 ~/.oci를 추가하고 key.pem, key_public.pem, config, oci_cli_rc를 등록합니다.
저는 oci 계정이 서울과 춘천에 각각 1개씩 있어서 config에 모두 프로필로 등록해 두었습니다.

계정이 2개 이상인 경우 oci_cli_rc를 추가하면 손쉽게 권한 프로필을 전환할 수 있습니다.
아래는 config 파일에 [SEOUL] 로 정의해 놓은 profile을 사용하겠다는 의미입니다.

cat <<EOT> oci_cli_rc
# CHUNCHEON
# SEOUL
[OCI_CLI_SETTINGS]
default_profile=SEOUL
EOT

이 권한으로 oci 명령을 실행할 수 있으며 oci 명령으로 관리 클러스터에 접근하는 설정(kubeconfig)을 생성할 수 있습니다.
현재 관리 클러스터를 서울에 설치하였기 서울용 프로필을 사용하도록 합니다.
(oci_cli_rc를 그냥 두시면 됩니다.)

cf. 테넌시가 현재 구독중인 지역 확인

export TENANCY_ID=<OCI_TENANCY_ID>
oci iam region-subscription list --tenancy-id $TENANCY_ID              
{
  "data": [
    {
      "is-home-region": true,
      "region-key": "ICN",
      "region-name": "ap-seoul-1",
      "status": "READY"
    }
  ]
}

관리 클러스터에 접근할 수 있도록 kubecofig 설정

oke 콘솔에서 관리 클러스터의 kubeconfig 생성 커맨드를 확인할 수 있습니다.


클러스터에 엑세스 를 클릭합니다.


복사를 눌러서 커맨드를 복사하고 devops 터미널에서 실행하면 oci kubeconfig가 생성됩니다.


워크로드 클러스터 생성 준비

워크로드가 생성될 구획에 대한 권한 설정

워크로드가 생성될 지역 및 구획에 컴퓨트 리소스, 네트워크 리소스 등을 사용할 수 있도록 권한을 설정합니다.
권한은 크게 사용자 주체 권한과 인스턴스 주체 권한이 있습니다. 예시에서는 사용자는 Administrator 권한을 가지고 있고 사용자 주체 권한을 사용합니다.
(인스턴스 주체 권한은 실제 oci 인스턴스의 권한을 부여하여 사용하는 것으로, 인스턴스 생성, 동적 그룹설정, 정책 등록 등의 추가 작업이 필요합니다.)

# 에러 방지 # 1)
sudo sysctl fs.inotify.max_user_watches=1048576
sudo sysctl fs.inotify.max_user_instances=8192

vi ~/.zshrc
export GITHUB_TOKEN=<GITHUB_TOKEN> # 2)

# oci 사용자 주체 권한 설정 3)
export OCI_CLI_AUTH=api_key # 인스턴스 주체 권한 설정 시: instance_principal
export USE_INSTANCE_PRINCIPAL=false # 인스턴스 주체 권한 설정 시: true
export USE_INSTANCE_PRINCIPAL_B64=$(echo -n "$USE_INSTANCE_PRINCIPAL" | base64 | tr -d '\n')

export OCI_TENANCY_ID=<OCI_TENANCY_ID>
export OCI_USER_ID=<OCI_USER_ID>
export OCI_REGION=<OCI_REGION>
export OCI_CREDENTIALS_KEY_PATH=~/.oci/key.pem
export OCI_CREDENTIALS_FINGERPRINT=<OCI_CREDENTIALS_FINGERPRINT>

export OCI_TENANCY_ID_B64="$(echo -n "$OCI_TENANCY_ID" | base64 | tr -d '\n')"
export OCI_CREDENTIALS_FINGERPRINT_B64="$(echo -n "$OCI_CREDENTIALS_FINGERPRINT" | base64 | tr -d '\n')"
export OCI_USER_ID_B64="$(echo -n "$OCI_USER_ID" | base64 | tr -d '\n')"
export OCI_REGION_B64="$(echo -n "$OCI_REGION" | base64 | tr -d '\n')"
export OCI_CREDENTIALS_KEY_B64=$( cat ~/.oci/key.pem | base64 | tr -d '\n' )

source ~/.zshrc
  1. Failed to allocate directory watch: Too many open files 에러를 방지하기 위해서 devops 환경(os가 리눅스일 때)에서 해당 커맨드를 실행합니다.

  2. GITHUB_TOKEN
    api provider 등을 가져올 때 github api를 호출하는데 capi provider 의 api 호출 횟수를 제한하기 때문에 clusterctl init 시 실패할 수 있습니다. 자신의 github 토큰을 활용해서 호출하면 실패를 방지할 수 있습니다.

  3. 관리 클러스터와 생성할 워크로드 클러스터의 지역이 다를 경우 이 부분이 다소 헛갈릴 수 있는데 관리 클러스터 접속은 oci cli 권한과 kubeconfig 로 하는 것이고, export로 설정하는 권한은 워크로드 클러스터를 생성하기 위해 필요한 해당 지역의 사용자 권한입니다.


워크로드가 생성될 구획에 사용자 정의 이미지 업로드

마스터 노드와 워커 노드를 생성하기 위한 컨테이너 이미지를 생성합니다.
워크로드가 생성될 지역, COMPARTMENT 구역에 이미지를 업로드한 후 해당 IMAGE_ID와 COMPARTMENT_ID를 익스포트합니다.

vi ~/.zshrc
export OCI_COMPARTMENT_ID=<OCI_COMPARTMENT_ID>
export OCI_IMAGE_ID=<OCI_IMAGE_ID>
source ~/.zshrc

해당 부분은 일단 간략하게 흐름만 파악하고
이미지 생성 및 업로드는 추후 추가하겠습니다.


워크로드 생성 스크립트를 만들 때 필요한 매개변수 설정

export CLUSTER_TOPOLOGY=true
export CLUSTER_NAME="management"
export KUBERNETES_VERSION="v1.28.2"
export CONTROL_PLANE_MACHINE_COUNT=2
export NODE_MACHINE_COUNT=2
export NAMESPACE=cluster-prod
export OCI_WORKLOAD_REGION=ap-chuncheon-1
export OCI_SSH_KEY=$(cat ~/.ssh/authorized_keys) # 1)


# managed cluster 생성 시 필요한 매개변수
export EXP_MACHINE_POOL=true
export EXP_CLUSTER_RESOURCE_SET=true
export OCI_MANAGED_NODE_SHAPE=VM.Standard.A1.Flex
export OCI_MANAGED_NODE_MACHINE_TYPE_OCPUS=2
  1. ~/.ssh/authorized_keys
    devops instance 생성 시 ssh public key를 설정하였으면 해당 키가 authorized_keys로 존재합니다.
    만약 ssh public key를 설정하지 않았다면 기존 워크스테이션의 ~/.ssh/id_rsa, id_rsa.pub를 복사하여 붙여넣거나 새로 생성합니다.

관리 클러스터의 Cluster API 초기화

$ clusterctl init --infrastructure oci
Fetching providers
Installing cert-manager Version="v1.12.3"
Waiting for cert-manager to be available...
Installing Provider="cluster-api" Version="v1.5.1" TargetNamespace="capi-system"
Installing Provider="bootstrap-kubeadm" Version="v1.5.1" TargetNamespace="capi-kubeadm-bootstrap-system"
Installing Provider="control-plane-kubeadm" Version="v1.5.1" TargetNamespace="capi-kubeadm-control-plane-system"
Installing Provider="infrastructure-oci" Version="v0.13.0" TargetNamespace="cluster-api-provider-oci-system"

Your management cluster has been initialized successfully!

You can now create your first workload cluster by running the following:

  clusterctl generate cluster [name] --kubernetes-version [version] | kubectl apply -f -

워크로드 생성

# 일반 클러스터 워크로드 생성용 스크립트 만들기
clusterctl generate cluster prod \
--from https://raw.githubusercontent.com/codelab-kr/devops/feature/cluster-template-alternative-region-free.yaml > prod.yaml


# managed cluster 워크로드 생성용 스크립트 만들기
clusterctl generate cluster managed \
--from https://raw.githubusercontent.com/oracle/cluster-api-provider-oci/main/templates/cluster-template-managed.yaml > managed.yaml


# 안타깝게도 clusterctl generate cluster 명령은 네임스페이스 매개변수를 인식하지 못 하는 것으로 보입니다. 따라서 특정 네임스페이스를 지정해 주려면 스크립트 내부의 default 를 워크로드의 네임스페이스(예제에서는 cluster-prod)로 수정해 주셔야 합니다.

# 워크로드 네임스페이스 생성
kubectl create ns cluster-prod
kubectl create ns cluster-managed

# 워크로드 생성
kubectl apply -f prod.yaml
kubectl apply -f managed.yaml

워크로드 생성 진행 및 결과 확인

# 프로비전 상태 확인
kubectl get cluster -A -w

# 상세 확인
kubectl get cluster-api -A -o wide

# 표 형태로 확인
clusterctl describe --show-conditions all cluster prod -n cluster-prod
clusterctl describe --show-conditions all cluster managed -n cluster-managed

# 로그 확인
kubectl logs -f deployment.apps/capoci-controller-manager  -n cluster-api-provider-oci-system

이후 작업은 일반 클러스터 워크로드에서만 실행합니다.

워크로드 클러스터에 CNI 설치

clusterctl describe --show-conditions all cluster prod -n cluster-prod 

아마 결과가 대부분 true 이고 Workers 관련 항목 및 NodeHealthy만 false 인 상태에서 더 이상 진행되지 않을 것입니다.

이 문제를 해결해 봅시다.

새로 생성된 워크로드에 접근하려면 kubeconfig 가 필요합니다.
아래 커맨드로 생성할 수 있습니다.

echo $CLUSTER_NAME

clusterctl get kubeconfig ${CLUSTER_NAME} -n cluster-prod > ~/.kube/${CLUSTER_NAME}.config

kubeconfig를 사용하여 워크로드의 노드를 조회해 봅니다.

➜  kubectl --kubeconfig ~/.kube/${CLUSTER_NAME}.config get node
NAME                       STATUS     ROLES           AGE   VERSION
prod-control-plane-pdfhl   NotReady   control-plane   27m   v1.27.2
prod-md-4n8cn              NotReady   <none>          24m   v1.27.2
prod-md-wx85m              NotReady   <none>          24m   v1.27.2

상태가 NotReady 입니다.
이것은 워크로드 클러스터 내부에 컨테이너 네트워크 인터페이스(CNI)가 존재하지 않아서 발생하는 현상입니다.
Calico CNI 를 설치합니다.

kubectl --kubeconfig ~/.kube/${CLUSTER_NAME}.config apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.2/manifests/calico.yaml

설치가 완료되면 Ready로 상태가 변경됩니다.

kubectl --kubeconfig ~/.kube/${CLUSTER_NAME}.config get node -w
NAME                       STATUS   ROLES           AGE   VERSION
prod-control-plane-pdfhl   Ready    control-plane   31m   v1.27.2
prod-md-4n8cn              Ready    <none>          28m   v1.27.2
prod-md-wx85m              Ready    <none>          28m   v1.27.2

워크로드 클러스터에 CCM 설치

아직 끝나지 않았습니다.

 kubectl --kubeconfig ~/.kube/${CLUSTER_NAME}.config get pod,deploy -A
NAMESPACE     NAME                                                   READY   STATUS    RESTARTS   AGE
kube-system   pod/calico-kube-controllers-5c596bd8b-z4g2p            0/1     Pending   0          7m17s
kube-system   pod/calico-node-ggckt                                  1/1     Running   0          7m17s
kube-system   pod/calico-node-hfwgb                                  1/1     Running   0          7m17s
kube-system   pod/calico-node-ncwlp                                  1/1     Running   0          7m17s
kube-system   pod/coredns-5d78c9869d-bjzzg                           0/1     Pending   0          37m
kube-system   pod/coredns-5d78c9869d-shqgm                           0/1     Pending   0          37m
kube-system   pod/etcd-prod-control-plane-pdfhl                      1/1     Running   0          37m
kube-system   pod/kube-apiserver-prod-control-plane-pdfhl            1/1     Running   0          37m
kube-system   pod/kube-controller-manager-prod-control-plane-pdfhl   1/1     Running   0          37m
kube-system   pod/kube-proxy-hjlhv                                   1/1     Running   0          34m
kube-system   pod/kube-proxy-pbd2c                                   1/1     Running   0          34m
kube-system   pod/kube-proxy-vjdx4                                   1/1     Running   0          37m
kube-system   pod/kube-scheduler-prod-control-plane-pdfhl            1/1     Running   0          37m

NAMESPACE     NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   deployment.apps/calico-kube-controllers   0/1     1            0           7m17s
kube-system   deployment.apps/coredns                   0/2     2            0           37m

calico-kube-controllers와 coredns pods이 Pending 상태입니다.
이 문제를 해결하려면 클라우드 컨트롤 매니지(CCM)이 필요합니다.
관리 클러스터에서는 초기화 과정에서 oci ccm 이 설치되었습니다. 관리 클러스터의 입장에서는 우리가 설치를 해준 것입니다.
워크로드 생성 로그를 확인하던 deployment.apps/capoci-controller-manager가 ccm입니다.
워크로드 클러스터에도 ccm 이 필요합니다. 관리 클러스터의 ccm 과 다르기 때문에 별도로 설치해 주어야 합니다.


설치해 봅시다.

공홈의 설명을 거의 그대로 가져왔습니다.
Install Oracle Cloud Infrastructure Cloud Controller Manager

비밀 생성

  1. example configuration file을 다운로드 합니다.
curl -L https://raw.githubusercontent.com/oracle/oci-cloud-controller-manager/master/manifests/provider-config-example.yaml -o cloud-provider-example.${CLUSTER_NAME}.yaml
  1. Update values in the configuration file as necessary.

    As an example using the provided [cluster-template.yaml](https://github.com/oracle/cluster-api-provider-oci/blob/main/templates/cluster-template.yaml) you would modify the cloud-provider-example.yaml and make sure to set compartment and vcn with the correct OCIDs. Then set subnet1 to the OCID of your service-lb subnet and remove subnet2. You would then set securityListManagementMode to "None".

  1. Create a secret:

    # kubectl --kubeconfig ~/.kube/${CLUSTER_NAME}.config delete secrets oci-cloud-controller-manager -n kube-system
    kubectl --kubeconfig ~/.kube/${CLUSTER_NAME}.config create secret generic oci-cloud-controller-manager -n kube-system --from-file=cloud-provider.yaml=cloud-provider-example.${CLUSTER_NAME}.yaml
    
    secret/oci-cloud-controller-manager created  

CCM 설치

Install CCM

  1. Navigate to the release page of CCM and export the version that you want to install. Typically, the latest version can be installed.

  2. Download the deployment manifests:

    export CCM_RELEASE_VERSION=v1.27.0
    
    curl -L "https://github.com/oracle/oci-cloud-controller-manager/releases/download/${CCM_RELEASE_VERSION}/oci-cloud-controller-manager.yaml" -o oci-cloud-controller-manager.yaml
    
    curl -L "https://github.com/oracle/oci-cloud-controller-manager/releases/download/${CCM_RELEASE_VERSION}/oci-cloud-controller-manager-rbac.yaml" -o oci-cloud-controller-manager-rbac.yaml
    
  3. Deploy the CCM:

    # kubectl --kubeconfig ~/.kube/${CLUSTER_NAME}.config delete -f oci-cloud-controller-manager.yaml
    $ kubectl --kubeconfig ~/.kube/${CLUSTER_NAME}.config apply -f oci-cloud-controller-manager.yaml
    
    daemonset.apps/oci-cloud-controller-manager created
    
  4. Deploy the RBAC rules:

    
    # kubectl --kubeconfig ~/.kube/${CLUSTER_NAME}.config delete -f oci-cloud-controller-manager-rbac.yaml
    $ kubectl --kubeconfig ~/.kube/${CLUSTER_NAME}.config apply -f oci-cloud-controller-manager-rbac.yaml
    
    serviceaccount/cloud-controller-manager created
    clusterrole.rbac.authorization.k8s.io/system:cloud-controller-manager created
    clusterrolebinding.rbac.authorization.k8s.io/oci-cloud-controller-manager created
    

CCM 확인

Check the CCM logs to verify OCI CCM is running correctly

```bash
$ kubectl --kubeconfig ~/.kube/${CLUSTER_NAME}.config -n kube-system get po | grep oci

oci-cloud-controller-manager-pshh6               1/1     Running             0             18s

# 로그 확인
$ kubectl -n kube-system --kubeconfig ~/.kube/${CLUSTER_NAME}.config logs -f oci-cloud-controller-manager-vfnrv

# 포드 상태가 러닝으로 변경되었는지 확인
kubectl --kubeconfig ~/.kube/${CLUSTER_NAME}.config get all -A
```

워크로드 클러스터에 CSI 설치

https://github.com/oracle/oci-cloud-controller-manager/blob/master/container-storage-interface.md

export KUBECONFIG=~/.kube/${CLUSTER_NAME}.config
export RELEASE=v1.27.0
cp cloud-provider-example.prod.yaml provider-config-example.prod.yaml

이후는 위 url 을 따라하시면 됩니다.

profile
Think about a better architecture

0개의 댓글