Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

KJH

ansible 본문

DevOps

ansible

모이스쳐라이징 2023. 10. 20. 23:38

많은 머신들에게 일괄적으로 명령을 보낼 수 있게 하는 툴입니다.

 

k8s에서 helm차트로 ansible job을 사용하는 예제

 

Dockerfile

ansible playbook용 image

FROM alpine:3.14

RUN apk --no-cache add ansible openssh-client python3 py3-pip bash curl
RUN pip install pywinrm

WORKDIR /ansible-playbooks

CMD ["ansible-playbook", "--version"]

 

 

Job.yaml

job이 시작, 종료 됐을 때 각각 로그를 incoming webhook으로 slack에 전송합니다.

각종 shell은 configmap mount로 job이 돌때 가져오게 되어 있습니다.

apiVersion: batch/v1
kind: Job
metadata:
  name: {{ include "ansible.fullname" . }}-job-{{ now | unixEpoch }}
  labels:
    {{- include "ansible.labels" . | nindent 4 }}
spec:
  ttlSecondsAfterFinished: {{ .Values.ttl.seconds }}
  template:
    spec:
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}"
        env:
        lifecycle:
          postStart:
            exec:
              command: ["/bin/sh", "-c", "/etc/ansible/statusLog.sh {{ .Values.slack.webhook }} start"]
        command: 
        - "/bin/sh"
        - "-c"
        - |
          ansible-playbook -vvvv -i /etc/ansible/hosts.ini /etc/ansible/main.yaml -f {{ .Values.job.parallel }} -l '{{ .Values.targetMachines }}'; 
          /etc/ansible/statusLog.sh {{ .Values.slack.webhook }} end
        volumeMounts:
        - name: ansible-config-volume
          mountPath: /etc/ansible
      volumes:
      - name: ansible-config-volume
        configMap:
          name: {{ include "ansible.fullname" . }}
          defaultMode: 0777
      restartPolicy: Never
      {{- with .Values.imagePullSecrets }}
      imagePullSecrets:
        {{- toYaml . | nindent 8 }}
      {{- end }}
  backoffLimit: 0

 

 

Configmap.yaml

재료가 될 file들을 동적으로 불러오고, helm차트로 매번 필요한 명령만 사용 

delegate_to 원격 호스트 대신 지정된 호스트에서 실행하도록 하는 옵션
localhost일 경우 ansible playbook이 실행되는 머신(여기서는 alpine linux)
ignore_unreachable 타겟 호스트가 접근 불가능한 경우 해당 작업을 실패로 간주하겠다는 의미
ignore_errors 작업 중 발생하는 오류를 무시하지 않겠다는 의미
register 해당 작업의 결과를 변수에 저장
until 주어진 조건이 만족될 때까지 작업을 반복적으로 실행
run_once 해당 작업을 한 번만 실행하겠다는 의미
when 해당 작업을 실행할 조건을 지정

 

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "ansible.fullname" . }}
data:
# helm chart 내 files 폴더에 있는 모든 파일을 동적으로 configmap으로 불러옴
{{- range $path, $bytes := .Files.Glob "files/*" }}
  {{ base $path }}: |-
{{ $.Files.Get $path | indent 6 }}
{{- end }}
  main.yaml: |-
    - name: Call main playbook
      hosts: all
      gather_facts: false
      tasks:
		# 머신 연결을 약 3분 정도 동안 재시도 함
        # 실행환경 alpine linux
        - name: block
          block:
            - name: Ensure host is reachable
              command: timeout 10 telnet {{ "{{ ansible_host }}" }} 5986
              ignore_unreachable: false
              ignore_errors: false
              register: telnet_result
              until: telnet_result.rc == 0
              retries: 15
              delay: 3
              delegate_to: localhost
              
            - name: Include main playbook
              include: {{ .Values.job.targetYaml }}.yaml
              ignore_unreachable: false
              ignore_errors: false
              register: include_result
              retries: 3
              delay: 10
              until: include_result is succeeded
		# 동작에 실패했을때 에러를 긁어와서 slack에 보내줌
          rescue:
            - name: Send a notification to Slack via Incoming Webhook
              include: rescue.yaml
              delegate_to: localhost
        # 특정 작업에 한해 완료 메세지 보내기
          always:
            - name: ai docker deploy complete message
              include: always.yaml
              when: "'{{ .Values.job.targetYaml }}' in 'docker'"
              delegate_to: localhost
              run_once: true

{{- if .Values.ansible.cli.enabled }}
  cli.yaml: |-
            - name: run cli
              win_shell: {{ .Values.ansible.cli.command }}        
{{- end }}

{{- if .Values.ansible.copy.enabled }}
  copy.yaml: |-
            - name: Copy a file to Windows server
              win_copy:
                src: /etc/ansible/{{ .Values.ansible.copy.scriptName }}
                dest: {{ .Values.ansible.copy.baseFolder }}{{ .Values.ansible.copy.scriptName }}
            - name: run shell
              win_shell: {{ .Values.ansible.copy.baseFolder }}{{ .Values.ansible.copy.scriptName }}
              timeout: 3600
{{- end }}

{{- if .Values.ansible.agent.enabled }}
  agent.yaml: |-
            - name: Copy a file to Windows server
              win_copy:
                src: /etc/ansible/{{ .Values.ansible.agent.scriptName }}
                dest: {{ .Values.ansible.agent.baseFolder }}{{ .Values.ansible.agent.scriptName }}
            - name: run {{ .Values.ansible.agent.scriptName }}
              win_shell: {{ .Values.ansible.agent.baseFolder }}{{ .Values.ansible.agent.scriptName }} -tag {{ .Values.ansible.agent.tag }} -env {{ .Values.logENV }}
{{- end }}

  rescue.yaml: |-
            - name: Send a notification to Slack via Incoming Webhook
              uri:
                url: '{{ .Values.slack.webhook }}' 
                method: POST
                body_format: json
                body: {"text": "`{{ "{{ inventory_hostname }}" }}` task failed \n stderr: `{{ "{{ ansible_failed_result['stderr_lines'] }}" }}` \n stdout: `{{ "{{ ansible_failed_result['stdout_lines'] }}" }}` \n msg: `{{ "{{ ansible_failed_result['msg'] }}" }}` "}

  always.yaml: |-
            - name: Send a notification to Slack via Incoming Webhook
              script: /etc/ansible/dockerDeployLog.sh
              delegate_to: localhost

'DevOps' 카테고리의 다른 글

사설 인증서 발급  (0) 2023.11.04
Terraform (Azure)  (0) 2023.11.01
Prometheus (Windows exporter)  (0) 2023.10.20
azure keyvault secrets provider  (0) 2023.10.17
Packer  (0) 2023.10.17