5장. Operator 개발
5.1. 토큰 인증 링크 복사링크가 클립보드에 복사되었습니다!
5.1.1. 클라우드 공급업체의 운영자를 위한 토큰 인증 링크 복사링크가 클립보드에 복사되었습니다!
많은 클라우드 공급업체는 단기적이고 제한된 권한의 보안 자격 증명을 제공하는 계정 토큰을 사용하여 인증을 활성화할 수 있습니다.
OpenShift 컨테이너 플랫폼에는 CCO(Cloud Credential Operator)가 포함되어 있으며, CRD(Custom Resource Definitions)로 클라우드 공급업체 자격 증명을 관리합니다. CCO는 CredentialsRequest(사용자 정의 리소스)에서 동기화되어 OpenShift Container Platform 구성 요소가 클러스터를 실행하는 데 필요한 특정 권한이 있는 클라우드 공급자 자격 증명을 요청할 수 있습니다.
이전에는 CCO가 수동 모드인 클러스터에서 Operator Lifecycle Manager(OLM)에서 관리하는 운영자는 사용자가 수동으로 필요한 클라우드 자격 증명을 프로비저닝할 수 있는 방법에 대해 OperatorHub에서 상세한 지침을 제공했습니다.
OpenShift Container Platform 4.14에서 시작하여 CCO는 특정 클라우드 공급업체에서 단기 자격 증명을 사용할 수 있는 클러스터에서 실행되는 경우를 감지할 수 있습니다. 그런 다음 Operator 작성자가 업데이트된 CCO를 지원하도록 Operator를 활성화했을 경우 특정 자격 증명을 반자동 프로비저닝할 수 있습니다.
5.1.2. AWS STS를 사용하여 OLM 관리 Operator의 CCO 기반 워크플로 링크 복사링크가 클립보드에 복사되었습니다!
AWS에서 실행되는 OpenShift Container Platform 클러스터가 Security Token Service(STS) 모드에 있으면 클러스터가 AWS 및 OpenShift Container Platform의 기능을 활용하여 애플리케이션 수준에서 IAM 역할을 사용하는 것을 의미합니다. STS는 애플리케이션이 IAM ROLE 수용할 수 있는 JSON 웹 토큰(JWT)을 제공할 수 있게 해줍니다.
JWT에는 sts:AssumeRoleWithWebIdentity IAM 작업에 대한 Amazon 리소스 이름(ARN)이 포함되어 서비스 계정에 대한 임시 허가 권한이 허용됩니다. JWT에는 AWS IAM이 검증할 수 있는 ProjectedServiceAccountToken의 서명 키가 포함되어 있습니다. 서명된 서비스 계정 토큰 자체는 AWS ROLE 가정하는 데 필요한 JWT로 사용됩니다.
Cloud Credential Operator(CCO)는 클러스터 운영자입니다. 클러스터 운영자는 클라우드 공급자에서 실행되는 OpenShift Container Platform 클러스터에 기본적으로 설치됩니다. STS의 목적을 위해 CCO는 다음과 같은 기능을 제공합니다.
- STS를 지원하는 클러스터에서 실행되는 경우를 감지
-
운영자에게 AWS 리소스에 대한 액세스를 부여하는 데 필요한 정보를 제공하는 필드가 있는지 확인하는
CredentialsRequest객체
CCO는 수동 모드에서도 이 검사를 수행합니다. CCO가 올바르게 구성되면 필요한 액세스 정보가 포함된 비밀 객체를 Operator 이름 공간에 프로젝션합니다.
OpenShift Container Platform 4.14에서 시작하여 CCO는 STS 워크플로우에 필요한 정보를 포함하는 비밀을 생성하도록 요청할 수 있는 CredentialsRequest 객체의 확장된 사용을 통해 이 작업을 반자동화할 수 있습니다. 사용자는 웹 콘솔 또는 CLI Operator를 설치할 때 ROLE ARN을 제공할 수 있습니다.
업데이트에 대한 자동 승인을 갖춘 구독은 업데이트 전에 변경해야 할 권한이 있기 때문에 권장되지 않습니다. 업데이트에 대한 수동 승인을 제공하는 구독은 관리자가 최신 버전의 권한을 확인하고 필요한 모든 단계를 수행한 후 업데이트할 수 있도록 합니다.
OpenShift 컨테이너 플랫폼 4.14 이상의 업데이트된 CCO와 함께 사용하기 위해 Operator를 준비하는 Operator 작성자로서, STS 토큰 인증을 처리하는 것 외에도 이전 CCO 버전의 차이를 처리하기 위해 사용자를 지시하고 코드를 추가해야 합니다(여러분의 Operator가 STS를 이미 활성화하지 않은 경우). 권장되는 방법은 CredentialsRequest 객체에 올바르게 채워진 STS 필드를 제공하고 CCO가 비밀을 생성하도록 하는 것입니다.
4.14 버전 이전의 OpenShift 컨테이너 플랫폼 클러스터를 지원하려는 경우 CCO 유틸리티(ccoctl)를 사용하여 STS 활성화 정보로 비밀을 수동으로 생성하는 방법에 대한 지침을 사용자에게 제공하는 것을 고려하십시오. 이전 CCO 버전은 클러스터의 STS 모드를 알지 못하며 비밀을 만들 수 없습니다.
귀하의 코드는 결코 나타나지 않는 비밀을 확인하고 사용자에게 귀하가 제공한 반환 지침을 따르도록 경고해야 합니다. 자세한 내용은 "다른 방법"의 하위 섹션을 참조하십시오.
5.1.2.1. 운영자가 AWS STS를 사용하여 CCO 기반 워크플로스를 지원하도록 허용 링크 복사링크가 클립보드에 복사되었습니다!
Operator Lifecycle Manager(OLM)에서 프로젝트를 실행하도록 설계하는 Operator 작성자로서, 프로젝트를 사용자 정의하여 Cloud Credential Operator(CCO)를 지원하여 STS를 지원하는 OpenShift Container Platform 클러스터에서 AWS에 대한 인증을 활성화할 수 있습니다.
이 방법을 사용하면 Operator가 CredentialsRequest 객체를 생성하고 결과의 Secret 객체를 읽기 위해 RBAC 권한을 책임지고 필요합니다.
기본적으로 Operator deployment에 관련된 pods는 serviceAccountToken 볼륨을 마운트하여 결과가 발생하는 Secret 객체에서 서비스 계정 토큰을 참조할 수 있습니다.
사전 요구 사항
- OpenShift Container Platform 4.14 이상
- STS 모드의 클러스터
- OLM 기반 운영자 프로젝트
프로세스
Operator 프로젝트의
ClusterServiceVersion(CSV) 객체를 업데이트합니다.Operator가
CredentialsRequests객체를 만들 수 있는 RBAC 권한이 있는지 확인합니다.예
clusterPermissions목록# ... install: spec: clusterPermissions: - rules: - apiGroups: - "cloudcredential.openshift.io" resources: - credentialsrequests verbs: - create - delete - get - list - patch - update - watch다음 항목을 추가하여 AWS STS를 사용하여 CCO 기반 워크플로우의 이 방법에 대한 지원을 요구합니다.
# ... metadata: annotations: features.operators.openshift.io/token-auth-aws: "true"
Operator 프로젝트 코드를 업데이트합니다.
Subscription객체에 의해 pod에 설정된 환경 변수에서 ROLE ARN을 가져옵니다. 예를 들면 다음과 같습니다.// Get ENV var roleARN := os.Getenv("ROLEARN") setupLog.Info("getting role ARN", "role ARN = ", roleARN) webIdentityTokenPath := "/var/run/secrets/openshift/serviceaccount/token"패치 및 적용할 준비가 된
CredentialsRequest객체가 있는지 확인합니다. 예를 들면 다음과 같습니다.예제
CredentialsRequest개체 생성import ( minterv1 "github.com/openshift/cloud-credential-operator/pkg/apis/cloudcredential/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var in = minterv1.AWSProviderSpec{ StatementEntries: []minterv1.StatementEntry{ { Action: []string{ "s3:*", }, Effect: "Allow", Resource: "arn:aws:s3:*:*:*", }, }, STSIAMRoleARN: "<role_arn>", } var codec = minterv1.Codec var ProviderSpec, _ = codec.EncodeProviderSpec(in.DeepCopyObject()) const ( name = "<credential_request_name>" namespace = "<namespace_name>" ) var CredentialsRequestTemplate = &minterv1.CredentialsRequest{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: "openshift-cloud-credential-operator", }, Spec: minterv1.CredentialsRequestSpec{ ProviderSpec: ProviderSpec, SecretRef: corev1.ObjectReference{ Name: "<secret_name>", Namespace: namespace, }, ServiceAccountNames: []string{ "<service_account_name>", }, CloudTokenPath: "", }, }또는 YAML 형식의
CredentialsRequest객체에서 시작하는 경우(예를 들어, Operator 프로젝트 코드의 일부로), 다른 방법으로 처리할 수 있습니다.예제
인증서 YAML 양식에서 객체 생성 요청// CredentialsRequest is a struct that represents a request for credentials type CredentialsRequest struct { APIVersion string `yaml:"apiVersion"` Kind string `yaml:"kind"` Metadata struct { Name string `yaml:"name"` Namespace string `yaml:"namespace"` } `yaml:"metadata"` Spec struct { SecretRef struct { Name string `yaml:"name"` Namespace string `yaml:"namespace"` } `yaml:"secretRef"` ProviderSpec struct { APIVersion string `yaml:"apiVersion"` Kind string `yaml:"kind"` StatementEntries []struct { Effect string `yaml:"effect"` Action []string `yaml:"action"` Resource string `yaml:"resource"` } `yaml:"statementEntries"` STSIAMRoleARN string `yaml:"stsIAMRoleARN"` } `yaml:"providerSpec"` // added new field CloudTokenPath string `yaml:"cloudTokenPath"` } `yaml:"spec"` } // ConsumeCredsRequestAddingTokenInfo is a function that takes a YAML filename and two strings as arguments // It unmarshals the YAML file to a CredentialsRequest object and adds the token information. func ConsumeCredsRequestAddingTokenInfo(fileName, tokenString, tokenPath string) (*CredentialsRequest, error) { // open a file containing YAML form of a CredentialsRequest file, err := os.Open(fileName) if err != nil { return nil, err } defer file.Close() // create a new CredentialsRequest object cr := &CredentialsRequest{} // decode the yaml file to the object decoder := yaml.NewDecoder(file) err = decoder.Decode(cr) if err != nil { return nil, err } // assign the string to the existing field in the object cr.Spec.CloudTokenPath = tokenPath // return the modified object return cr, nil }참고Operator 번들에
CredentialsRequest객체를 추가하는 것은 현재 지원되지 않습니다.ROLE ARN 및 웹 정체성 토큰 경로를 자격 증명 요청에 추가하고 Operator 초기화 중에 적용합니다.
Operator 초기화 중
CredentialsRequest객체 적용 예// apply CredentialsRequest on install credReq := credreq.CredentialsRequestTemplate credReq.Spec.CloudTokenPath = webIdentityTokenPath c := mgr.GetClient() if err := c.Create(context.TODO(), credReq); err != nil { if !errors.IsAlreadyExists(err) { setupLog.Error(err, "unable to create CredRequest") os.Exit(1) } }Operator 에서 조정하는 다른 항목과 함께 호출되는 다음 예제와 같이 CCO 에서
비밀객체가 나타나기를 기다릴 수 있는지 확인합니다.비밀객체 대기 예// WaitForSecret is a function that takes a Kubernetes client, a namespace, and a v1 "k8s.io/api/core/v1" name as arguments // It waits until the secret object with the given name exists in the given namespace // It returns the secret object or an error if the timeout is exceeded func WaitForSecret(client kubernetes.Interface, namespace, name string) (*v1.Secret, error) { // set a timeout of 10 minutes timeout := time.After(10 * time.Minute) // set a polling interval of 10 seconds ticker := time.NewTicker(10 * time.Second) // loop until the timeout or the secret is found for { select { case <-timeout: // timeout is exceeded, return an error return nil, fmt.Errorf("timed out waiting for secret %s in namespace %s", name, namespace) // add to this error with a pointer to instructions for following a manual path to a Secret that will work on STS case <-ticker.C: // polling interval is reached, try to get the secret secret, err := client.CoreV1().Secrets(namespace).Get(context.Background(), name, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { // secret does not exist yet, continue waiting continue } else { // some other error occurred, return it return nil, err } } else { // secret is found, return it return secret, nil } } } }타임오트값은 CCO가 추가된CredentialsRequest객체를 얼마나 빨리 탐지하고비밀객체를 생성할 수 있는지에 대한 예측을 기반으로 합니다. 운영자가 아직 클라우드 리소스를 액세스하지 않는 이유를 궁금해하는 클러스터 관리자를 위해 시간을 줄이거나 사용자 지정 피드백을 생성할 수도 있습니다.CCO가 자격 증명 요청에서 생성한 비밀을 읽고 해당 비밀에서 데이터를 포함하는 AWS 구성 파일을 생성하여 AWS 구성을 설정합니다.
AWS 구성 생성 예제
func SharedCredentialsFileFromSecret(secret *corev1.Secret) (string, error) { var data []byte switch { case len(secret.Data["credentials"]) > 0: data = secret.Data["credentials"] default: return "", errors.New("invalid secret for aws credentials") } f, err := ioutil.TempFile("", "aws-shared-credentials") if err != nil { return "", errors.Wrap(err, "failed to create file for shared credentials") } defer f.Close() if _, err := f.Write(data); err != nil { return "", errors.Wrapf(err, "failed to write credentials to %s", f.Name()) } return f.Name(), nil }중요비밀은 존재한다고 가정하지만, CCO가 비밀을 만들 수 있도록 이 비밀을 사용할 때 운영자 코드를 기다리고 다시 시도해야 합니다.
또한 대기 기간이 끝나고 사용자가 OpenShift Container Platform 클러스터 버전과 따라서 CCO가 STS 탐지 기능을 갖춘
CredentialsRequest객체 워크플로우를 지원하지 않는 이전 버전일 수 있음을 경고해야 합니다. 이러한 경우에는 다른 방법을 사용하여 비밀을 추가해야 한다는 사용자에게 지시합니다.예를 들어 AWS SDK 세션을 구성합니다.
AWS SDK 세션 구성 예제
sharedCredentialsFile, err := SharedCredentialsFileFromSecret(secret) if err != nil { // handle error } options := session.Options{ SharedConfigState: session.SharedConfigEnable, SharedConfigFiles: []string{sharedCredentialsFile}, }
5.1.2.2. ROLE 사양 링크 복사링크가 클립보드에 복사되었습니다!
AWS Security Token Service(STS)를 사용하는 Operator를 설치하려면 Operator가 필요로 하는 IAM ROLE, 이상적으로 관리자가 실행할 수 있는 스크립트로 지정해야 합니다.
다음 예에서는 필수 AWS IAM ROLE 생성하고 신뢰 정책을 첨부하는 스크립트를 보여줍니다.
예제 ROLE 생성 스크립트
#!/bin/bash
set -x
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
OIDC_PROVIDER=$(oc get authentication cluster -ojson | jq -r .spec.serviceAccountIssuer | sed -e "s/^https:\/\///")
NAMESPACE=my-namespace
SERVICE_ACCOUNT_NAME="my-service-account"
POLICY_ARN_STRINGS="arn:aws:iam::aws:policy/AmazonS3FullAccess"
read -r -d '' TRUST_RELATIONSHIP <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${OIDC_PROVIDER}:sub": "system:serviceaccount:${NAMESPACE}:${SERVICE_ACCOUNT_NAME}"
}
}
}
]
}
EOF
echo "${TRUST_RELATIONSHIP}" > trust.json
aws iam create-role --role-name "$SERVICE_ACCOUNT_NAME" --assume-role-policy-document file://trust.json --description "role for demo"
while IFS= read -r POLICY_ARN; do
echo -n "Attaching $POLICY_ARN ... "
aws iam attach-role-policy \
--role-name "$SERVICE_ACCOUNT_NAME" \
--policy-arn "${POLICY_ARN}"
echo "ok."
done <<< "$POLICY_ARN_STRINGS"
5.1.2.3. 인증 실패의 문제 해결 링크 복사링크가 클립보드에 복사되었습니다!
인증이 성공하지 않으면 운영자에게 제공된 토큰을 사용하여 웹 정체성을 사용하여 ROLE 수행할 수 있는지 확인합니다.
프로세스
Pod에서 토큰을 추출:
$ oc exec operator-pod -n <namespace_name> \ -- cat /var/run/secrets/openshift/serviceaccount/tokenpod에서 ROLE ARN을 추출합니다.
$ oc exec operator-pod -n <namespace_name> \ -- cat /<path>/<to>/<secret_name>경로를 위해 뿌리를 사용하지 마십시오.
웹 정체성 토큰으로 ROLE 가정하십시오.
$ aws sts assume-role-with-web-identity \ --role-arn $ROLEARN \ --role-session-name <session_name> \ --web-identity-token $TOKEN
5.1.2.4. 문제 해결 비밀이 올바르게 마운팅되지 않습니다. 링크 복사링크가 클립보드에 복사되었습니다!
비 루트 팟에서 자격 증명 파일 마운트 실패를 방지하려면 비밀을 쓰기 가능한 위치에 마운트하고 AWS SDK에서 공유 자격 증명 파일 옵션을 활성화하십시오.
5.1.2.5. 대체 방법 링크 복사링크가 클립보드에 복사되었습니다!
Operator 작성자를 위한 대체 방법으로, Operator를 설치하기 전에 사용자가 Cloud Credential Operator(CCO)에 대한 CredentialsRequest 객체를 생성할 책임이 있는지 지정할 수 있습니다.
운영자 지침은 사용자에게 다음 사항을 나타내야 합니다.
-
CredentialsRequest객체의 YAML 버전을 제공하는 방법은 지침에 YAML 인라인을 제공하거나 사용자를 다운로드 위치로 지시함 -
사용자에게
CredentialsRequest객체를 만들도록 지시합니다.
OpenShift Container Platform 4.14 이상에서 해당 STS 정보를 추가한 클러스터에 CredentialsRequest 객체가 나타나면 운영자는 CCO 생성된 비밀을 읽거나 클러스터 서비스 버전(CSV)에서 마운트를 정의한 후 마운트를 마운트할 수 있습니다.
이전 버전의 OpenShift 컨테이너 플랫폼의 경우 운영자 지침은 사용자에게 다음 사항을 표시해야 합니다.
-
CCO 유틸리티(
ccoctl)를 사용하여CredentialsRequest객체에서SecretYAML 객체를 생성합니다. -
적절한 이름 공간에서 클러스터에
비밀객체를 적용합니다.
운영자는 여전히 클라우드 API와 통신하기 위해 결과의 비밀을 소비 할 수 있어야합니다. 이 경우 비밀은 Operator가 설치되기 전에 사용자가 생성하기 때문에 Operator는 다음 중 하나를 수행할 수 있습니다.
-
CSV 내의
Deployment객체에서 명시 마운트를 정의합니다. -
API 서버에서
비밀객체를 프로그래밍 방식으로 읽습니다. "AWS STS를 사용하여 CCO 기반 워크플로우를 지원할 수 있도록 운영자에게 허용하는" 메서드에 표시된 바와 같이
5.1.3. Microsoft Entra Workload ID가 있는 OLM 관리 Operator의 CCO 기반 워크플로 링크 복사링크가 클립보드에 복사되었습니다!
Azure에서 실행되는 OpenShift 컨테이너 플랫폼 클러스터가 Workload Identity / Federated Identity 모드에 있으면 클러스터가 Azure 및 OpenShift 컨테이너 플랫폼의 기능을 활용하여 애플리케이션 수준에서 Microsoft Entra Workload ID에서 사용자 지정 관리 ID 또는 프로그램 등록을 적용합니다.
Cloud Credential Operator(CCO)는 클러스터 운영자입니다. 클러스터 운영자는 클라우드 공급자에서 실행되는 OpenShift Container Platform 클러스터에 기본적으로 설치됩니다. OpenShift Container Platform 4.14.8에서 시작하여 CCO는 워크로드 ID가 있는 OLM 관리 운영자를 위한 워크플로우를 지원합니다.
워크로드 ID의 경우 CCO는 다음과 같은 기능을 제공합니다.
- Workload ID를 사용하는 클러스터에서 실행되는 경우를 감지
-
운영자에게 Azure 리소스에 대한 액세스를 부여하는 데 필요한 정보를 제공하는 필드가 있는지 확인하는
CredentialsRequest객체
CCO 는 CredentialsRequest 객체의 확장된 사용을 통해 이 프로세스를 반자동화할 수 있으며, 이 객체는 워크로드 ID 작업 흐름에 필요한 정보를 포함하는 비밀을 생성하도록 요청할 수 있습니다.
업데이트에 대한 자동 승인을 갖춘 구독은 업데이트 전에 변경해야 할 권한이 있기 때문에 권장되지 않습니다. 업데이트에 대한 수동 승인을 제공하는 구독은 관리자가 최신 버전의 권한을 확인하고 필요한 모든 단계를 수행한 후 업데이트할 수 있도록 합니다.
OpenShift 컨테이너 플랫폼 4.14 이상의 업데이트된 CCO와 함께 사용하기 위해 Operator를 준비하는 Operator 작성자로서, Workload ID 토큰 인증을 처리하는 것 외에도 이전 CCO 버전의 차이를 처리하기 위해 사용자를 지시하고 코드를 추가해야 합니다(Operator가 아직 활성화되지 않은 경우). 권장되는 방법은 CredentialsRequest 객체에 올바르게 채워진 Workload ID 필드를 제공하고 CCO가 Secret 객체를 만들 수 있도록 하는 것입니다.
4.14 버전 이전의 OpenShift 컨테이너 플랫폼 클러스터를 지원하려는 경우 CCO 유틸리티(ccoctl)를 사용하여 워크로드 ID를 사용하여 수동으로 비밀을 생성하는 방법에 대한 지침을 사용자에게 제공하는 것을 고려하십시오. 이전 CCO 버전은 클러스터의 Workload ID 모드를 알지 못하며 비밀을 만들 수 없습니다.
귀하의 코드는 결코 나타나지 않는 비밀을 확인하고 사용자에게 귀하가 제공한 반환 지침을 따르도록 경고해야 합니다.
Workload ID로 인증하려면 다음 정보가 필요합니다.
-
azure_client_id -
azure_tenant_id -
azure_region -
azure_subscription_id -
azure_federated_token_file
웹 콘솔의 Install Operator 페이지를 사용하면 클러스터 관리자가 설치 시 이 정보를 제공할 수 있습니다. 그런 다음 이 정보는 Operator pod의 환경 변수로 Subscription 객체에 전파됩니다.
5.1.3.1. 운영자가 Microsoft Entra 워크로드 ID를 사용하여 CCO 기반 작업 흐름을 지원하도록 설정 링크 복사링크가 클립보드에 복사되었습니다!
Operator Lifecycle Manager(OLM)에서 프로젝트를 실행하도록 설계하는 Operator 작성자로서, 프로젝트를 사용자 정의하여 Cloud Credential Operator(CCO)를 지원하여 Microsoft Entra Workload ID를 지원하는 OpenShift 컨테이너 플랫폼 클러스터에 대해 Operator 인증을 허용할 수 있습니다.
이 방법을 사용하면 Operator가 CredentialsRequest 객체를 생성하고 결과의 Secret 객체를 읽기 위해 RBAC 권한을 책임지고 필요합니다.
기본적으로 Operator deployment에 관련된 pods는 serviceAccountToken 볼륨을 마운트하여 결과가 발생하는 Secret 객체에서 서비스 계정 토큰을 참조할 수 있습니다.
사전 요구 사항
- OpenShift Container Platform 4.14 이상
- Workload ID 모드의 클러스터
- OLM 기반 운영자 프로젝트
프로세스
Operator 프로젝트의
ClusterServiceVersion(CSV) 객체를 업데이트합니다.Operator가
CredentialsRequests객체를 만들 수 있는 RBAC 권한이 있는지 확인합니다.예
clusterPermissions목록# ... install: spec: clusterPermissions: - rules: - apiGroups: - "cloudcredential.openshift.io" resources: - credentialsrequests verbs: - create - delete - get - list - patch - update - watchWorkload ID를 사용하여 CCO 기반 워크플로의 이 방법에 대한 지원을 요구하기 위해 다음 문서를 추가합니다.
# ... metadata: annotations: features.operators.openshift.io/token-auth-azure: "true"
Operator 프로젝트 코드를 업데이트합니다.
Subscription객체에 의해 pod에 설정된 환경 변수에서 클라이언트 ID, 테넌트 ID 및 구독 ID를 가져옵니다. 예를 들면 다음과 같습니다.// Get ENV var clientID := os.Getenv("CLIENTID") tenantID := os.Getenv("TENANTID") subscriptionID := os.Getenv("SUBSCRIPTIONID") azureFederatedTokenFile := "/var/run/secrets/openshift/serviceaccount/token"패치 및 적용할 준비가 된
CredentialsRequest객체가 있는지 확인합니다.참고Operator 번들에
CredentialsRequest객체를 추가하는 것은 현재 지원되지 않습니다.Azure 자격 증명 정보 및 웹 정체성 토큰 경로를 자격 증명 요청에 추가하고 Operator 초기화 중에 적용합니다.
Operator 초기화 중
CredentialsRequest객체 적용 예// apply CredentialsRequest on install credReqTemplate.Spec.AzureProviderSpec.AzureClientID = clientID credReqTemplate.Spec.AzureProviderSpec.AzureTenantID = tenantID credReqTemplate.Spec.AzureProviderSpec.AzureRegion = "centralus" credReqTemplate.Spec.AzureProviderSpec.AzureSubscriptionID = subscriptionID credReqTemplate.CloudTokenPath = azureFederatedTokenFile c := mgr.GetClient() if err := c.Create(context.TODO(), credReq); err != nil { if !errors.IsAlreadyExists(err) { setupLog.Error(err, "unable to create CredRequest") os.Exit(1) } }Operator 에서 조정하는 다른 항목과 함께 호출되는 다음 예제와 같이 CCO 에서
비밀객체가 나타나기를 기다릴 수 있는지 확인합니다.비밀객체 대기 예// WaitForSecret is a function that takes a Kubernetes client, a namespace, and a v1 "k8s.io/api/core/v1" name as arguments // It waits until the secret object with the given name exists in the given namespace // It returns the secret object or an error if the timeout is exceeded func WaitForSecret(client kubernetes.Interface, namespace, name string) (*v1.Secret, error) { // set a timeout of 10 minutes timeout := time.After(10 * time.Minute) // set a polling interval of 10 seconds ticker := time.NewTicker(10 * time.Second) // loop until the timeout or the secret is found for { select { case <-timeout: // timeout is exceeded, return an error return nil, fmt.Errorf("timed out waiting for secret %s in namespace %s", name, namespace) // add to this error with a pointer to instructions for following a manual path to a Secret that will work on STS case <-ticker.C: // polling interval is reached, try to get the secret secret, err := client.CoreV1().Secrets(namespace).Get(context.Background(), name, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { // secret does not exist yet, continue waiting continue } else { // some other error occurred, return it return nil, err } } else { // secret is found, return it return secret, nil } } } }타임오트값은 CCO가 추가된CredentialsRequest객체를 얼마나 빨리 탐지하고비밀객체를 생성할 수 있는지에 대한 예측을 기반으로 합니다. 운영자가 아직 클라우드 리소스를 액세스하지 않는 이유를 궁금해하는 클러스터 관리자를 위해 시간을 줄이거나 사용자 지정 피드백을 생성할 수도 있습니다.-
CCO가
CredentialsRequest객체에서 생성한 비밀을 읽어 Azure로 인증하고 필요한 인증서를 수신합니다.
5.1.4. GCP Workload Identity가 있는 OLM 관리 Operator의 CCO 기반 워크플로 링크 복사링크가 클립보드에 복사되었습니다!
Google Cloud에서 실행되는 OpenShift 컨테이너 플랫폼 클러스터가 GCP 워크로드 ID / Federated Identity 모드에 있으면 클러스터가 Google Cloud 및 OpenShift 컨테이너 플랫폼의 기능을 활용하여 애플리케이션 수준에서 GCP 워크로드 ID의 권한을 적용합니다.
Cloud Credential Operator(CCO)는 클러스터 운영자입니다. 클러스터 운영자는 클라우드 공급자에서 실행되는 OpenShift Container Platform 클러스터에 기본적으로 설치됩니다. OpenShift Container Platform 4.17에서 시작하여 CCO는 GCP 워크로드 ID를 사용하는 OLM 관리 운영자에게 작업 흐름을 지원합니다.
GCP 워크로드 정체성을 위해 CCO는 다음과 같은 기능을 제공합니다.
- GCP Workload Identity를 사용하는 클러스터에서 실행되는 경우를 감지
-
운영자에게 Google Cloud 리소스에 대한 액세스 권한을 부여하는 데 필요한 정보를 제공하는 필드가 있는지 확인하는
CredentialsRequest객체
CCO 는 GCP Workload Identity 워크플로우에 필요한 정보를 포함하는 비밀의 생성을 요청할 수 있는 CredentialsRequest 객체의 확장된 사용을 통해 이 프로세스를 반자동화할 수 있습니다.
업데이트에 대한 자동 승인을 갖춘 구독은 업데이트 전에 변경해야 할 권한이 있기 때문에 권장되지 않습니다. 업데이트에 대한 수동 승인을 제공하는 구독은 관리자가 최신 버전의 권한을 확인하고 필요한 모든 단계를 수행한 후 업데이트할 수 있도록 합니다.
OpenShift Container Platform 4.17 이상의 업데이트된 CCO와 함께 사용하기 위해 Operator를 준비하는 Operator 작성자로서, GCP Workload Identity 토큰 인증을 처리하는 것 외에도 이전 CCO 버전의 차이를 처리하기 위해 사용자를 지시하고 코드를 추가해야 합니다(Operator가 이미 활성화되지 않은 경우). 권장 방법은 CredentialsRequest 객체에 올바르게 채워진 GCP Workload Identity 필드를 제공하고 CCO가 Secret 객체를 작성하도록 하는 것입니다.
4.17 버전 이전의 OpenShift 컨테이너 플랫폼 클러스터를 지원하려는 경우 CCO 유틸리티(ccoctl)를 사용하여 GCP 워크로드 ID 활성화 정보로 비밀을 수동으로 생성하는 방법에 대한 지침을 사용자에게 제공하는 것을 고려하십시오. 이전 CCO 버전은 클러스터의 GCP 워크로드 ID 모드를 알지 못하며 비밀을 만들 수 없습니다.
귀하의 코드는 결코 나타나지 않는 비밀을 확인하고 사용자에게 귀하가 제공한 반환 지침을 따르도록 경고해야 합니다.
Google Cloud Platform Workload Identity를 통해 단기 토큰을 사용하여 Google Cloud에서 인증하려면 운영자가 다음 정보를 제공해야 합니다.
관객관리자가 GCP Workload Identity를 설정할 때 Google Cloud에서 생성한
AUDIENCE값은 다음 형식의 사전 포맷된 URL이어야 합니다.//iam.googleapis.com/projects/<project_number>/locations/global/workloadIdentityPools/<pool_id>/providers/<provider_id>SERVICE_ACCOUNT_EMAILSERVICE_ACCOUNT_EMAIL값은 Google Cloud 서비스 계정의 이메일입니다. 이 이메일은 운영자 작업 중 척하는 것입니다.<service_account_name>@<project_id>.iam.gserviceaccount.com
웹 콘솔의 Install Operator 페이지를 사용하면 클러스터 관리자가 설치 시 이 정보를 제공할 수 있습니다. 그런 다음 이 정보는 Operator pod의 환경 변수로 Subscription 객체에 전파됩니다.
5.1.4.1. 운영자가 GCP Workload Identity를 사용하여 CCO 기반 작업 흐름을 지원하는 방법 링크 복사링크가 클립보드에 복사되었습니다!
Operator Lifecycle Manager(OLM)에서 프로젝트를 실행하도록 설계하는 Operator 작성자로서, 프로젝트를 사용자 정의하여 Cloud Credential Operator(CCO)를 지원하여 OpenShift 컨테이너 플랫폼 클러스터의 Google Cloud Platform Workload Identity에 대한 인증을 활성화할 수 있습니다.
이 방법을 사용하면 Operator가 CredentialsRequest 객체를 생성하고 결과의 Secret 객체를 읽기 위해 RBAC 권한을 책임지고 필요합니다.
기본적으로 Operator deployment에 관련된 pods는 serviceAccountToken 볼륨을 마운트하여 결과가 발생하는 Secret 객체에서 서비스 계정 토큰을 참조할 수 있습니다.
사전 요구 사항
- OpenShift Container Platform 4.17 이상
- GCP 워크로드 ID / Federated Identity 모드의 클러스터
- OLM 기반 운영자 프로젝트
프로세스
Operator 프로젝트의
ClusterServiceVersion(CSV) 객체를 업데이트합니다.CSV의 Operator deployment에는 다음과 같은
volumeMounts및volumes필드를 포함하여 Operator가 웹 ID로 ROLE를 수행할 수 있는지 확인합니다.예
Volume수량및Volumes필드# ... volumeMounts: - name: bound-sa-token mountPath: /var/run/secrets/openshift/serviceaccount readOnly: true volumes: # This service account token can be used to provide identity outside the cluster. - name: bound-sa-token projected: sources: - serviceAccountToken: path: token audience: openshiftOperator가
CredentialsRequests객체를 만들 수 있는 RBAC 권한이 있는지 확인합니다.예
clusterPermissions목록# ... install: spec: clusterPermissions: - rules: - apiGroups: - "cloudcredential.openshift.io" resources: - credentialsrequests verbs: - create - delete - get - list - patch - update - watch다음 항목을 추가하여 GCP Workload Identity를 사용하여 CCO 기반 워크플로의 이 방법에 대한 지원을 요구합니다.
# ... metadata: annotations: features.operators.openshift.io/token-auth-gcp: "true"
Operator 프로젝트 코드를 업데이트합니다.
구독 구성에 의해 pod에 설정된 환경 변수에서
고객및serviceAccountEmail값을 가져옵니다.// Get ENV var audience := os.Getenv("AUDIENCE") serviceAccountEmail := os.Getenv("SERVICE_ACCOUNT_EMAIL") gcpIdentityTokenFile := "/var/run/secrets/openshift/serviceaccount/token"패치 및 적용할 준비가 된
CredentialsRequest객체가 있는지 확인합니다.참고Operator 번들에
CredentialsRequest객체를 추가하는 것은 현재 지원되지 않습니다.GCP Workload Identity 변수를 자격 증명 요청에 추가하고 Operator 초기화 중에 적용합니다.
Operator 초기화 중
CredentialsRequest객체 적용 예// apply CredentialsRequest on install credReqTemplate.Spec.GCPProviderSpec.Audience = audience credReqTemplate.Spec.GCPProviderSpec.ServiceAccountEmail = serviceAccountEmail credReqTemplate.CloudTokenPath = gcpIdentityTokenFile c := mgr.GetClient() if err := c.Create(context.TODO(), credReq); err != nil { if !errors.IsAlreadyExists(err) { setupLog.Error(err, "unable to create CredRequest") os.Exit(1) } }Operator 에서 조정하는 다른 항목과 함께 호출되는 다음 예제와 같이 CCO 에서
비밀객체가 나타나기를 기다릴 수 있는지 확인합니다.비밀객체 대기 예// WaitForSecret is a function that takes a Kubernetes client, a namespace, and a v1 "k8s.io/api/core/v1" name as arguments // It waits until the secret object with the given name exists in the given namespace // It returns the secret object or an error if the timeout is exceeded func WaitForSecret(client kubernetes.Interface, namespace, name string) (*v1.Secret, error) { // set a timeout of 10 minutes timeout := time.After(10 * time.Minute) // set a polling interval of 10 seconds ticker := time.NewTicker(10 * time.Second) // loop until the timeout or the secret is found for { select { case <-timeout: // timeout is exceeded, return an error return nil, fmt.Errorf("timed out waiting for secret %s in namespace %s", name, namespace) // add to this error with a pointer to instructions for following a manual path to a Secret that will work case <-ticker.C: // polling interval is reached, try to get the secret secret, err := client.CoreV1().Secrets(namespace).Get(context.Background(), name, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { // secret does not exist yet, continue waiting continue } else { // some other error occurred, return it return nil, err } } else { // secret is found, return it return secret, nil } } } }타임오트값은 CCO가 추가된CredentialsRequest객체를 얼마나 빨리 탐지하고비밀객체를 생성할 수 있는지에 대한 예측을 기반으로 합니다. 운영자가 아직 클라우드 리소스를 액세스하지 않는 이유를 궁금해하는 클러스터 관리자를 위해 시간을 줄이거나 사용자 지정 피드백을 생성할 수도 있습니다.비밀에서
service_account.json필드를 읽고 Google Cloud 클라이언트를 인증합니다.service_account_json := secret.StringData["service_account.json"]