VM 시작 루틴 구성

베어메탈용 GKE 버전 1.13.0 이상을 사용할 때는 시작 시 VM 초기화를 맞춤설정하도록 시작 루틴을 지정할 수 있습니다. SSH 키를 만들고, 사용자 및 비밀번호를 추가하고, 패키지를 설치하고, 파일을 작성하고, 네트워크 설정을 구성 등을 수행하도록 VM을 구성할 수 있습니다.

이러한 시작 작업은 cloud-init API 또는 시작 스크립트 API 중 하나만 사용하여 구성됩니다. 이러한 시작 지시문은 VirtualMachine YAML 매니페스트 파일에 지정되고 VM이 시작될 때마다 자동으로 실행됩니다.

기본 요건

시작 지시문으로 VM을 구성하려면 다음 기본 요건을 충족해야 합니다.

  • GDC용 VM 런타임을 사용 설정합니다.

  • 확인된 Linux 게스트 OS를 사용하고 VM 매니페스트에서 osTypeLinux로 설정합니다. Windows 게스트 OS는 cloud-init를 지원하지 않으므로 이 기능에 사용할 수 없습니다.

  • 게스트 OS에 cloud-init가 설치되었는지 확인합니다. 최신 Linux OS에는 cloud-init가 포함되어 있습니다.

다음 섹션에서는 cloud-init API 또는 시작 스크립트를 사용하여 VM 매니페스트에서 시작 루틴을 지정하는 방법을 설명합니다.

cloud-init API를 사용하여 VM 초기화

Cloud-init는 일반적으로 클라우드 인스턴스 초기화 및 시작 중 VM 맞춤설정을 위해 사용됩니다. VM 초기화에는 일반적으로 패키지 설치, 저장소 설정, SSH 키 만들기, 파일에 데이터 쓰기, 기타 VM 요소 설정과 같은 태스크가 포함됩니다. spec.cloudInit 필드를 사용해서 cloud-init 구성 YAML을 VirtualMachine 커스텀 리소스에 통합합니다. VM 인스턴스가 시작되면 cloud-init가 제공된 데이터를 읽고 그에 따라 VM을 초기화합니다.

cloud-init 구현에 대한 다음 세부정보를 참조하세요.

  • VM을 만들거나 업데이트할 때 VirtualMachine YAML 매니페스트에 cloud-init 데이터를 지정합니다. 매니페스트를 적용하여 VM을 만들려면 튜토리얼: GDC용 VM 런타임에서 Linux VM 만들기 및 관리를 참조하세요.

  • VM 사양에서 NoCloud 데이터 소스, spec.cloudInit.noCloud를 사용합니다.

  • VirtualMachine 매니페스트의 개별 섹션에서 사용자 데이터네트워크 데이터를 지정합니다. 섹션 이름 지정 및 구조체는 사용하기로 결정한 데이터 형식에 따라 달라집니다.

  • 다음 데이터 형식으로 cloud-init 구성 정보를 지정할 수 있습니다.

    • 텍스트 삭제
    • Base64로 인코딩된 문자열
    • Kubernetes 보안 비밀

쉽게 시작할 수 있도록 일반적인 VM 초기화 태스크에 대해 몇 가지 구성 예시가 제공되었습니다.

Cloud-init 사용자 데이터

GDC용 VM 런타임은 cloud-config 구문에서 cloud-init 사용자 데이터를 지원하므로, #cloud-config로 사용자 데이터를 시작합니다. 사용자 데이터는 일반 텍스트, base64로 인코딩된 문자열, Kubernetes 보안 비밀로 형식을 지정할 수 있습니다.

사용자 데이터 구문 및 모듈 참조에 대한 자세한 내용은 cloud-init 문서를 참조하세요.

Cloud-init 사용자 데이터를 일반 텍스트로 지정

다음 예시 매니페스트는 사용자 데이터를 일반 텍스트로 지정하는 방법을 보여줍니다. 이 경우 cloud-init는 VM이 시작될 때 명령어를 실행합니다.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        runcmd:
          - echo hello

Cloud-init 사용자 데이터를 base64로 인코딩된 문자열로 지정

다음 예시에서는 사용자 데이터를 base64로 인코딩된 형식으로 지정하는 방법을 보여줍니다. 이 예시에서 사용자 데이터는 일반 텍스트 예시와 동일한 echo hello 명령어로 구성됩니다.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userDataBase64: I2Nsb3VkLWNvbmZpZwpydW5jbWQ6CiAgLSBlY2hvIGhlbGxvCg==

Cloud-init 사용자 데이터를 Kubernetes 보안 비밀로 지정

다음 예시는 VirtualMachineSecret 모두에 대한 YAML 매니페스트를 보여줍니다. VirtualMachine 구성에서 spec.cloudInit.noCloud.secretRef 섹션은 cloud-init 사용자 데이터가 my-sec라는 Kubernetes 보안 비밀에 있음을 보여줍니다. 해당 Secret 구성은 사용자 데이터를 키-값 쌍으로 지정합니다. 이 경우 base64로 인코딩된 값은 cloud-config 구문의 cloud-init 사용자 데이터입니다.

참조된 보안 비밀에서 데이터 키 userData(표시) 또는 userdata를 사용하여 cloud-init 사용자 데이터를 지정합니다.

이 예시에서 사용자 데이터는 일반 텍스트 예시와 동일한 echo hello 명령어로 구성됩니다.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      secretRef:
        name: my-sec
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: my-sec
data:
  userData: I2Nsb3VkLWNvbmZpZwpydW5jbWQ6CiAgLSBlY2hvIGhlbGxvCg==

참조된 보안 비밀을 찾을 수 없거나 데이터 키 userData 또는 userdata가 보안 비밀에 없으면 다음 VM 시작 동작에 주의하세요.

  • VM 생성의 경우 VM이 자세한 이유 및 메시지와 함께 ErrorConfiguration 상태로 설정됩니다.

  • 다른 경우에는 VM이 올바르게 구성될 때까지 VM에서 이전 cloud-init 사용자 데이터가 계속 사용됩니다. 따라서 VM이 올바르게 구성될 때까지 게스트 에이전트 사용 설정 또는 중지 업데이트가 적용되지 않습니다.

사용된 cloud-init 사용자 데이터를 포함하여 VM 정보를 검색하려면 다음 명령어를 사용합니다.

kubectl get vm VM_NAME -o yaml --kubeconfig KUBECONFIG_PATH

다음을 바꿉니다.

  • VM_NAME: VM의 이름입니다.

  • KUBECONFIG_PATH: VM이 포함된 클러스터에 대한 kubeconfig 파일의 경로입니다.

관련 Kubernetes 경고 이벤트를 검색하려면 kubectl get event 또는 kubectl describe gvm을 사용합니다.

Cloud-init 네트워크 데이터

사용자 데이터와 비슷하게, 네트워크 데이터도 일반 텍스트, base64로 인코딩된 문자열, Kubernetes 보안 비밀로 형식을 지정할 수 있습니다. 사용자 데이터와 달리 네트워크 데이터에는 cloud-config 구문이 사용되지 않습니다.

일반 텍스트 또는 base64로 인코딩된 문자열을 사용할 때 허용되는 최대 크기는 2,048바이트입니다. 사용자 데이터 크기가 2,048바이트에 가깝거나 보다 크면 이를 Kubernetes 보안 비밀로 지정합니다.

네트워크 데이터 구문 및 관련 세부정보에 대한 자세한 내용은 cloud-init 문서에서 네트워킹 구성 버전 2를 참조하세요.

Cloud-init 네트워크 데이터를 일반 텍스트로 지정

다음 예시 매니페스트는 네트워크 데이터를 일반 텍스트로 지정하는 방법을 보여줍니다. 여기에서 cloud-init는 'e'(e*)로 시작하는 이름의 모든 이더넷 기기에 대해 DHCP를 사용 설정합니다.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        runcmd:
          - echo hello
      networkData: |
        version: 2
        ethernets:
          alleths:
            match:
              name: e*
            dhcp4: true

Cloud-init 네트워크 데이터를 base64로 인코딩된 문자열로 지정

다음 예시에서는 네트워크 데이터를 base64로 인코딩된 형식으로 지정하는 방법을 보여줍니다. 이 예시에서 네트워크 데이터는 일반 텍스트 예시에 지정된 것과 동일한 DHCP 구성으로 구성됩니다.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      networkDataBase64: dmVyc2lvbjogMgpldGhlcm5ldHM6CiAgYWxsZXRoczoKICAgIG1hdGNoOgogICAgICBuYW1lOiBlKgogICAgZGhjcDQ6IHRydWUK

Cloud-init 네트워크 데이터를 Kubernetes 보안 비밀로 지정

다음 예시는 VirtualMachineSecret 모두에 대한 YAML 매니페스트를 보여줍니다. VirtualMachine 구성에서 spec.cloudInit.noCloud.networkDataSecretRef 섹션은 cloud-init 네트워크 데이터가 my-sec라는 Kubernetes 보안 비밀에 있음을 보여줍니다. 해당 Secret 구성은 네트워크 데이터를 키-값 쌍으로 지정합니다. 이 경우 base64로 인코딩된 값은 cloud-init 네트워크 데이터입니다.

참조된 보안 비밀에서 데이터 키 networkData(표시) 또는 networkdata를 사용하여 cloud-init 네트워크 데이터를 지정합니다.

이 예시에서 네트워크 데이터는 일반 텍스트 예시에 지정된 것과 동일한 DHCP 구성으로 구성됩니다.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      networkDataSecretRef:
        name: my-sec
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: my-sec
data:
  networkData: dmVyc2lvbjogMgpldGhlcm5ldHM6CiAgYWxsZXRoczoKICAgIG1hdGNoOgogICAgICBuYW1lOiBlKgogICAgZGhjcDQ6IHRydWUK

Cloud-init 예시

다음 섹션에는 cloud-init로 VM을 초기화하기 위한 몇 가지 일반적인 사용 사례의 일반 텍스트 예시가 포함됩니다.

승인된 SSH 키 구성

다음 사용자 데이터 예시는 승인된 SSH 키 ssh-rsa AAAAB3NzaK8L93bWxnyp를 기본 사용자에 할당합니다.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        ssh_authorized_keys:
          - ssh-rsa AAAAB3NzaK8L93bWxnyp

새 사용자 추가

다음 사용자 데이터 예시는 test 사용자를 만들고 test에 전체 sudo 액세스 권한을 부여합니다. 이 예시에서는 만료되지 않는 pwd 비밀번호를 사용자에게 할당합니다.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        users:
        - default
        - name: test
          sudo: ALL=(ALL) NOPASSWD:ALL
        chpasswd:
          list: |
            test:pwd
          expire: False

처음 시작 시 명령어 실행

다음 사용자 데이터 예시는 echo 명령어 및 ls 명령어를 실행합니다. 명령어를 사용하여 VM이 시작할 때 패키지 등을 설치할 수 있습니다.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        runcmd:
          - [ echo, hello ]
          - [ ls, -l, / ]

파일 쓰기

다음 사용자 데이터 예시는 VM의 /var/lib/google 디렉터리에 있는 test 파일에 bash 스크립트를 작성합니다. cloud-init 지시문은 파일 소유자에 대해 파일 읽기, 쓰기, 실행(0744) 권한을 설정합니다.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        write_files:
        - path: /var/lib/google/test
          permissions: 0744
          content: |
            #!/bin/bash
            echo hello

cloud-init 문제 해결

VM 초기화 문제가 발생하고 cloud-init를 사용 중이면 VM에서 다음 cloud-init 로그를 확인합니다.

  • /var/log/cloud-init.log: 기본적으로 cloud-init는 수준이 DEBUG 이상인 모든 이벤트를 이 로그에 기록합니다.

  • /var/log/cloud-init-output.log: 기본적으로 cloud-init는 모든 cloud-init 단계에서 stdout 및 stderr을 이 로그로 보냅니다.

시작 스크립트를 사용하여 VM 초기화

시작 스크립트는 가상 머신(VM) 인스턴스의 시작 프로세스 동안 태스크를 수행합니다. VirtualMachine 사양의 spec.startupScripts 섹션에서 하나 이상의 스크립트를 지정할 수 있습니다. 시작 스크립트를 사용하여 VM을 초기화할 수 있습니다. VM 초기화에는 일반적으로 패키지 설치, 저장소 설정, SSH 키 만들기, 파일에 데이터 쓰기, 기타 VM 요소 설정과 같은 태스크가 포함됩니다.

시작 스크립트에 대해 다음 세부정보를 확인하세요.

  • VM을 만들거나 업데이트할 때 VirtualMachine YAML 매니페스트에 시작 스크립트를 지정합니다. 매니페스트를 적용하여 VM을 만들려면 튜토리얼: GDC용 VM 런타임에서 Linux VM 만들기 및 관리를 참조하세요.

  • 지정된 스크립트는 VM이 시작할 때마다 실행됩니다.

  • 스크립트 인터프리터를 나타내기 위해 스크립트 위에 #!/bin/...을 포함합니다. 예를 들어 Bash 셸로 스크립트를 실행하려면 #!/bin/bash를 포함합니다.

  • cloud-init API 지시문(spec.cloudInit) 및 시작 스크립트(spec.startupScripts)를 모두 동일한 VirtualMachine 매니페스트에 지정할 수는 없습니다.

스크립트 형식

다음 데이터 형식으로 시작 스크립트를 지정할 수 있습니다.

  • 텍스트 삭제
  • Base64로 인코딩된 문자열
  • Kubernetes 보안 비밀

다른 여러 스크립트 형식으로 작동하기 위해 다음 규칙에 유의하세요.

  • 일반 텍스트 또는 base64로 인코딩된 문자열을 사용할 때 스크립트 콘텐츠에 허용되는 최대 크기는 2,048바이트입니다. 스크립트 콘텐츠 크기가 2,048바이트에 가깝거나 보다 크면 스크립트를 Kubernetes 보안 비밀로 지정합니다.

  • Kubernetes 보안 비밀을 사용할 때는 참조된 보안 비밀에서 데이터 키 script를 사용하여 스크립트 콘텐츠를 지정합니다.

  • 참조된 보안 비밀을 찾을 수 없거나 데이터 키 script가 참조된 보안 비밀에 없으면 VM이 계속 스크립트를 실행합니다. 그러나 VM은 스크립트 콘텐츠를 작성하거나 업데이트하지 않습니다. 이 경우 Kubernetes 경고 이벤트를 kubectl get event 또는 kubectl describe gvm으로 찾을 수 없습니다.

다음 샘플 VirtualMachine YAML 매니페스트에는 지원되는 각 형식에 하나씩 3개의 스크립트가 포함되어 있습니다. 이 경우 각 스크립트는 일반 텍스트 예시인 myscript1에 표시된 echo hello 명령어를 실행합니다.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  startupScripts:
  - name: myscript1
    script: |
      #!/bin/bash
      echo hello
  - name: myscript2
    scriptBase64: IyEvYmluL2Jhc2gKICAgICAgZWNobyBoZWxsbwo=
  - name: myscript3
    scriptSecretRef:
      name: my-sec
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: my-sec
data:
  script: IyEvYmluL2Jhc2gKICAgICAgZWNobyBoZWxsbwo=

스크립트 문제 해결

스크립트 결과 또는 로그를 확인하려면 다음 명령어를 실행합니다.

journalctl -u cloud-final

시작 스크립트 로그 항목은 다음 텍스트로 시작합니다.

started to run the command /var/lib/google/startup-scripts/SCRIPT_NAME ...

로그 항목에는 시작 스크립트의 이름인 SCRIPT_NAME이 포함됩니다.