파이썬 slackbot 포드에서 kubectl 명령을 실행

  • Python의 slackbot을 Kubernetes에 배포하여 Pod 상태를 확인합니다.

  • 라고 하는 기사를 썼지만, Python의 Kubernetes Client 라이브러리 를 사용했기 때문에, get pod 하고 싶은 등, 각각의 조작마다 Bot의 동작을 기재할 필요가 있어 불편. Python Client 대신 Bot 컨테이너 내에서 직접 kubectl 명령을 실행합니다.

    Pod에서 kubectl 명령을 실행하려면 kubectl의 바이너리를 컨테이너 이미지에 넣고 RBAC에서 Pod를 실행하는 ServiceAccount에 적절한 권한을 부여해야합니다.
  • Kubernetes 클러스터의 Pod에서 kubectl 실행

  • 준비



    Slack 측의 준비에 대해서는 마지막 기사를 참조.

    파이썬


    slackbot 모듈 사용법은 아래 공식 리포지토리를 참조하십시오.
  • htps : // 기주 b. 코 m / ぃ s05 / s ぁ 쿠보 t

  • 코드 작성



    다음 세 가지 파일을 만듭니다. → GitHubslacbot_settings.pyrun.py지난번 와 같다.
    python_slackbot
    ├── mybot.py
    ├── run.py
    └── slackbot_settings.py
    
    mybot.py 는 다음과 같이 작성. kubernetes 모듈이나 출력의 정형에 사용하고 있었다 prettytable 모듈은 삭제해, kubectl 커멘드를 서브 프로세스로 실행하는 함수를 추가했다.
    import re
    import subprocess
    
    from slackbot.bot import listen_to
    from slackbot.bot import respond_to
    
    
    # こんにちはに応答する
    @respond_to('hello', re.IGNORECASE)
    @respond_to('こんにちは|こんにちわ')
    def mention_hello(message):
        message.reply('こんにちは!')
    
    
    # kubernetesに反応する
    @listen_to('kubernetes', re.IGNORECASE)
    def listen_kubernetes(message):
        message.reply('kubernetesかっこいい!')
        message.react('+1')
    
    
    # helmに反応する
    @listen_to('helm', re.IGNORECASE)
    def listen_helm(message):
        message.reply('helmかっこいい!')
        message.react('+1')
    
    
    # kubectl
    @respond_to(r'^kubectl (.*)')
    def mention_kubectl(message, kubectl_args):
    
        try:
            cmd = 'kubectl {}'.format(kubectl_args)
            completed_process = subprocess.run(cmd.split(),
                                               check=True,
                                               capture_output=True)
            result_str = completed_process.stdout.decode('utf-8')
    
        except subprocess.CalledProcessError as e:
            result_str = e.stderr.decode('utf-8')
    
        msg = '```\n' + result_str + '```'
        message.reply(msg)
    

    로컬 실행



    로컬에서 실행하는 경우는 HOME/.kube/config
    필요한 모듈을 설치합니다.
    pip install slackbot
    

    API 토큰을 kubectl config 한다.
    export SLACKBOT_API_TOKEN=hogehoge
    

    Bot을 시작합니다.
    python run.py
    

    가동 확인



    Bot에 멘션하여 임의의 kubectl 명령을 실행한다.



    Kubernetes에 배포



    Kubernetes에 Bot을 배포합니다.

    이미지 빌드


    exportrequirements.txt 를 작성한다.

    requirements.txt
    slackbot
    

    Dockerfile
    FROM python:3-alpine
    
    WORKDIR /usr/src/app
    
    COPY requirements.txt ./
    RUN pip install --no-cache-dir -r requirements.txt
    
    COPY ./*.py ./
    
    RUN wget https://storage.googleapis.com/kubernetes-release/release/$(wget -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl \
      && mv kubectl /usr/local/bin/kubectl \
      && chmod +x /usr/local/bin/kubectl
    
    ENTRYPOINT [ "python", "./run.py" ]
    

    파일 배치는 이하와 같다.
    python_slackbot
    ├── Dockerfile
    ├── mybot.py
    ├── requirements.txt
    ├── run.py
    └── slackbot_settings.py
    

    이미지를 빌드합니다.
    docker build -t sotoiwa540/slackbot:1.1 .
    docker push sotoiwa540/slackbot:1.1
    

    Kubernetes에 배포



    이번에는 Slackbot을 배포하는 전용 Namespace를 만든다.
    kubectl create ns slackbot
    

    로컬로 실행하는 경우는, kubectl는 Dockerfile 로부터 자격 증명을 읽어들입니다만, Kubernetes상에서 Pod로서 실행하는 경우는 Pod를 실행하는 ServiceAccount의 권한으로 실행되므로, 적절한 권한을 줄 필요가 있다.

    Pod에 명시 적으로 ServiceAccount를 지정하지 않으면 Pod는 실행되는 Namespace HOME/.kube/config의 ServiceAccount 권한으로 실행됩니다.

    이번에는, 디폴트로 존재하는 default 라고 하는 읽기만으로 같은 ClusterRole를, view 의 ServiceAccount에 할당하는 ClusterRoleBinding를 작성한다. 무엇이든 실행할 수 있게 하고 싶으면 default 의 ClusterRole 라든지를 할당하면 된다.

    slackbot-rolebinding.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: slackbot
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: view
    subjects:
    - kind: ServiceAccount
      name: default
      namespace: slackbot
    
    kubectl apply -f slackbot-clusterrolebinding.yaml -n slackbot
    

    Slack의 API 토큰을 저장하는 Secret을 만듭니다.
    kubectl create secret generic slackbot-secret -n slackbot \
      --from-literal=SLACKBOT_API_TOKEN=hogehoge
    

    Deployment를 작성합니다.
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      annotations:
      labels:
        app: slackbot
      name: slackbot
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: slackbot
      strategy:
        type: Recreate
      template:
        metadata:
          labels:
            app: slackbot
        spec:
          containers:
          - name: slackbot
            image: sotoiwa540/slackbot:1.1
            imagePullPolicy: Always
            env:
            - name: SLACKBOT_API_TOKEN
              valueFrom:
                secretKeyRef:
                  key: SLACKBOT_API_TOKEN
                  name: slackbot-secret
    
    kubectl apply -f slackbot-deployment.yaml -n slackbot
    

    포드가 실행되었는지 확인합니다.
    $ kubectl get po -n slackbot
    NAME                       READY   STATUS    RESTARTS   AGE
    slackbot-8544c9454-q5jtc   1/1     Running   0          19s
    $
    

    가동 확인



    Bot에 멘션하여 cluster-admin 명령을 실행할 수 있는지 확인.

    좋은 웹페이지 즐겨찾기