kubernetes REST API에 외부에서 연결

7804 단어 gcpGKEkubernetes
kubernetes 에는 kubectl 라고 하는 커멘드가 있어 평상시의 오퍼레이션은 그곳에서 하는 일이 많다고 생각합니다만, 서버로부터 kubernetes 를 컨트롤 하고 싶다고 하는 요구도 있다고도 생각합니다.

kubernetes 에는 REST API 가 준비되어 있으므로 그것에 액세스 하면 됩니다만, 어떻게 인증하면 좋은지 헤매었으므로 메모를 남겨 둡니다.

인증



일부 인증 방식 준비 되었습니다.
  • X509 인증서
  • BASIC 인증
  • TOKEN
  • Service Account
  • OpenID

  • 이번에는 TOKEN 방식으로 해보겠습니다.

    토큰 획득



    토큰과 인증서는 포드에 들어가 /var/run/secrets/kubernetes.io/에 있습니다. 수동으로 취하는 것은 과연 힘들기 때문에, 이하의 커멘드를 두드립니다.
    $(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ') \
      | grep -E '^token' | cut -f2 -d':' | tr -d '\t')
    

    이제 토큰을 얻을 수 있어야 합니다.

    API 서버의 IP



    그런 다음 curl로 두드리는 IP 주소를 얻습니다. 이하의 커멘드로 취득할 수 있습니다만, 복수의 클러스터를 설정하고 있는 경우는 복수 나가 버리므로 주의해 주세요.
    kubectl config view | grep server | cut -f 2- -d ":" | tr -d " "
    

    GKE라면 제어판의 다음 부분에서 확인할 수 있습니다.



    방문해보기


    TOKEN=$(kubectl describe secret $(kubectl get secrets | \
      grep default | cut -f1 -d ' ') | \
      grep -E '^token' | cut -f2 -d':' | tr -d '\t')
    
    curl https://example.com/api/v1/namespaces/default/pods \
      --header "Authorization: Bearer $TOKEN" --insecure
    

    이제 포드 목록을 얻을 수 있어야 합니다. 최고군요. 그런 다음 REST API 참조을보고 kubernetes와 잘 지내십시오. 또한 버전에 따라 사용할 수 있는 API와 사용할 수 없는 API가 있으므로 주의하십시오.

    kubectl proxy라는 방법도



    공식에서는 이쪽을 추천하고 있습니다.
    kubectl proxy --port=8080 &
    
    $ curl http://localhost:8080/api/
    {
      "versions": [
        "v1"
      ]
    }
    

    클라이언트 라이브러리



    클라이언트 라이브러리는 각 언어마다 몇 가지 있습니다.
  • Client Libraries

  • 공식적으로 Go 와 Python 이군요. Ruby라면 abonas/kubeclient 근처가 좋을 것 같습니다.

    abonas/kubeclient



    Ruby gem abonas/kubeclient을 사용하여 API에 액세스해보십시오. 전술한 TOKEN의 취득이 되어 있으면 환경 변수등에 부치 넣어 접속하는 것 뿐입니다.
    auth_options = {
      bearer_token: ENV['K8S_API_TOKEN']
    }
    
    client = Kubeclient::Client.new(
      "https://#{ENV['K8S_API_HOST']}/api/", 'v1', auth_options: auth_options
    )
    
    client.get_pods
    

    다만, 이것만이라면 SSL로 에러가 나온다고 생각합니다. kubernetes는 자체 인증서를 사용하므로 그대로 연결할 수 없기 때문입니다. 실제로 명령을 실행하려고하면 KubeException: SSL_connect returned=1 errno=0 state=error: certificate verify failed 이런 느낌의 오류가 발생합니다.

    인증서 설정


    OpenSSL::SSL::VERIFY_NONE 하는 손도 있지만 추천하지 않습니다.

    먼저 연결을 위한 인증서를 만듭니다.
    openssl genrsa -aes128 2048 > client.key
    openssl req -new -key client.key > client.csr
    openssl x509 -in client.csr -days 365000 -req -signkey client.key > client.crt
    openssl rsa -in client.key -out client.key
    

    그런 다음 kubernetes 인증서를 가져옵니다. 포드 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt에 있습니다.

    마지막으로 abonas/kubeclient로 연결합니다.
    auth_options = {
      bearer_token: ENV['K8S_API_TOKEN']
    }
    
    ssl_options = {
      client_cert: OpenSSL::X509::Certificate.new(File.read(Rails.root.join("secrets", "k8s_client.crt"))),
      client_key:  OpenSSL::PKey::RSA.new(File.read(Rails.root.join("secrets", "k8s_client.key"))),
      ca_file:     Rails.root.join("secrets", "k8s_ca.crt"),
      verify_ssl:  OpenSSL::SSL::VERIFY_PEER
    }
    
    client = Kubeclient::Client.new(
      "https://#{ENV['K8S_API_HOST']}/api/", 'v1',
      auth_options: auth_options,
      ssl_options: ssl_options
    )
    
    client.get_pods
    

    이상으로 접속할 수 있게 됩니다.

    좋은 웹페이지 즐겨찾기