web-dev-qa-db-ja.com

コンテナ内でkubectlコマンドを実行する方法は?

ポッド内のコンテナーで、kubectlを使用してコマンドを実行するにはどうすればよいですか?たとえば、コンテナ内でこのようなことをする必要がある場合:

kubectl get pods

私はこれを試しました:私のdockerfileには、これらのコマンドがあります:

RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/AMD64/kubectl
RUN chmod +x ./kubectl
RUN Sudo mv ./kubectl /usr/local/bin/kubectl

編集:OSXファイルを試していましたが、Linuxバイナリファイルに修正しました。 (@svenwltrにより修正

Dockerファイルの作成中、これは成功しますが、コンテナ内でkubectl get podを実行すると、

kubectl get pods

私はこのエラーを受け取ります:

サーバーへの接続:拒否されました-適切なホストまたはポートを指定しましたか?

ローカルに展開しているときに、Docker-machineが実行されていない場合にこのエラーが発生していましたが、コンテナー内でdocker-machineを実行するにはどうすればよいですか?

ローカルでは、次のコマンドを実行してこのエラーを回避します(devはdocker-machineの名前です)

docker-machine env dev
eval $(docker-machine env dev)

誰かが私に何をする必要があるのか​​教えてもらえますか?

40
Dreams

Kubernetes apiを使用します。kubectlの代わりにcurlをインストールするだけで、残りは安心です。

curl http://localhost:8080/api/v1/namespaces/default/pods

私のAPIサーバーの1つで上記のコマンドを実行しています。 localhostapiserver ip address/dns nameに変更します。

構成に応じて、sslを使用するか、クライアント証明書を提供する必要があります。

APIエンドポイントを見つけるには、--v=8kubectlを使用できます。

例:

kubectl get pods --v=8

リソース:

Kubernetes APIドキュメント

RBACの更新:

すでにrbacを設定し、ポッド用のサービスアカウントを作成し、それを使用して実行していると思います。このサービスアカウントには、必要なネームスペースのポッドに対するリスト権限が必要です。そのためには、そのサービスアカウントのロールとロールバインディングを作成する必要があります。

クラスター内のすべてのコンテナーには、APIサーバーへの認証に使用できるトークンが入力されます。確認するには、コンテナ内で次を実行します。

cat /var/run/secrets/kubernetes.io/serviceaccount/token

Apiserverにリクエストを行うには、コンテナ内で次を実行します。

curl -ik \
     -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
     https://kubernetes.default.svc.cluster.local/api/v1/namespaces/default/pods
21
Farhad Farahi

ここでのパーティーに少し遅れましたが、これは私の2セントです。

コンテナ内でkubectlを使用すると、クラスターのAPIを呼び出すよりもはるかに簡単であることがわかりました。

(なぜ?自動認証!)

kubectlの使用が必要なNode.jsプロジェクトをデプロイするとします。

  1. コンテナ内でkubectlをダウンロードしてビルドします
  2. kubectlをコンテナにコピーして、アプリケーションをビルドします
  3. Voila!kubectlは、kubernetesクラスターを管理するための豊富なcliを提供します

役立つドキュメント

---編集---

クラスターポッドでkubectlを操作した後、ポッドを認証してk8s API呼び出しを行えるようにするより効果的な方法を見つけました。この方法は、より厳密な認証を提供します。

  1. ポッドのServiceAccountを作成し、上記のアカウントを使用するようにポッドを構成します。 k8sサービスアカウントドキュメント
  2. RoleBindingまたはClusterRoleBindingを設定して、サービスがk8s APIと通信するための承認を持つようにします。 k8s Role Binding docs
  3. APIを直接呼び出すか、 k8s-client を使用してAPI呼び出しを管理します。クライアントを使用することを強くお勧めします。通常のリクエストに必要な認証トークンのステップを削除するポッドの自動構成があります。

完了すると、次のようになります:ServiceAccountClusterRoleBindingDeployment(ポッド)

明確な方向性が必要な場合は、お気軽にコメントしてください。できる限りお手伝いします。

オールインオンの例

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: k8s-101
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: k8s-101
    spec:
      serviceAccountName: k8s-101-role
      containers:
      - name: k8s-101
        imagePullPolicy: Always
        image: salathielgenese/k8s-101
        ports:
        - name: app
          containerPort: 3000
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: k8s-101-role
subjects:
- kind: ServiceAccount
  name: k8s-101-role
  namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: k8s-101-role

salathielgenese/k8s-101画像にはkubectlが含まれています。したがって、ポッドコンテナーにログインして、k8sホストで実行しているようにkubectlを実行できます。kubectl exec -it pod-container-id -- kubectl get pods

15
mster

最初の質問

/usr/local/bin/kubectl: cannot execute binary file

kubectlのOSXバイナリをダウンロードしたようです。 Dockerで実行する場合は、おそらくLinuxが必要です。

https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/AMD64/kubectl

二番目の質問

適切に構成されたKubernetesクラスターでkubectlを実行すると、apiserverに接続できるはずです。

kubectlは、基本的にこのコードを使用してapiserverを見つけ、認証します。 github.com/kubernetes/client-go/rest.InClusterConfig

これの意味は:

  • Apiserverのホストとポートは、環境変数KUBERNETES_SERVICE_HostおよびKUBERNETES_SERVICE_PORTに保存されます。
  • アクセストークンはvar/run/secrets/kubernetes.io/serviceaccount/tokenにマウントされます。
  • サーバー証明書は/var/run/secrets/kubernetes.io/serviceaccount/ca.crtにマウントされます。

これは、kubectlがapiserverに接続するために知る必要があるすべてのデータです。

これがなぜ機能しないのか、いくつかの考え:

  • コンテナはKubernetesで実行されません。
    • 同じDockerホストを使用するだけでは不十分です。コンテナはポッド定義の一部として実行する必要があります。
  • アクセスは authorization plugin (デフォルトではありません)を使用して制限されます。
  • サービスアカウントの資格情報は、 pod definitionspec.serviceAccountName)によって上書きされます。
12
svenwltr