KJH
ansible 본문
많은 머신들에게 일괄적으로 명령을 보낼 수 있게 하는 툴입니다.
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 |