레이블이 slack인 게시물을 표시합니다. 모든 게시물 표시
레이블이 slack인 게시물을 표시합니다. 모든 게시물 표시

argocd image-updater and notification

# argocd-image-updater 설치
# 이미지가 업데이트되면 해당 이미지를 사용하는 argocd app 에 반영할 수 있다.
# 0.14.0 버전이 남아 있어 삭제할때
kubectl delete -n kave-argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/v0.14.0/manifests/install.yaml
# 최신 1.2.2 버전 설치
kubectl apply -n kave-argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/v1.2.2/config/install.yaml

# docker.io quay.io, ghcr.io 등의 image registry 외
# 커스텀 image 저장소인 경우 configmap 에 추가
data:
  log.level: debug
  registries.conf: |
    registries:
    - name: ysoftman_images
      api_url: https://ysoftman.image.io
      prefix: ysoftman.image.io

# argocd-image-updater 재시작
kubectl -n argocd rollout restart deployment argocd-image-updater-controller

# k8s > argocd-image-updater pod 에 ssh 접속해서 다음 명령으로 작동여부를 확인할 수 있다.
argocd-image-updater test <이미지명>

# argocd app 에 annotation 추가
# latest: 최근 이미지 태그가 생성된것으로 업데이트
# digest: 이미 이미지 태그가 있는 상태에서 태그의 이미지가 변경되면 업데이트(dev, stage, prod, latest 태그 처럼 계속 이미지가 변경되는 경우)
# helm 설정에서 image.tag 가 아닌 ysoftmanApp.image.tag 필드를 사용중인 경우
# v0.x 에서는 app 에 어노테이션
kubectl annotate app <argocd 앱이름> -n argocd \
argocd-image-updater.argoproj.io/image-list="myapp=<이미지경로:태그>" \
argocd-image-updater.argoproj.io/myapp.update-strategy=digest \
argocd-image-updater.argoproj.io/myapp.helm.image-tag=ysoftmanApp.image.tag

# v1.x 에부터는 아래처럼 ImageUpdater CR 을 사용한다.
apiVersion: argocd-image-updater.argoproj.io/v1alpha1
kind: ImageUpdater
metadata:
  name: myapp
  namespace: argocd            # 대상 Application 과 같은 네임스페이스
spec:
  applicationRefs:
    - namePattern: "myapp" # 대상 Argo CD Application 이름 (glob 가능)
      images:
        - alias: "myapp"
          imageName: "myapp:dev"
          commonUpdateSettings:
            updateStrategy: "digest"
          manifestTargets:
            helm:
              tag: "ysoftmanApp.image.tag"

# 이제 태그 이미지가 변경되면 변경된 이미지 layer(digest)를 받고
# deployment > image > 이미지경로:태그@sha256:xxxxx 로 변경돼 pod 가 재시작된다.
 
# image updater pod 로그에서 다음과 같은 에러 발생시
error listing applications: applications.argoproj.io is forbidden: User "system:serviceaccount:argocd:argocd-image-updater" cannot list resource "applications" in API group "argoproj.io" at the cluster scope"

# argocd-image-updater-manager-rolebinding 의 subject 에 namespace추가
kubectl -n kave-argocd patch rolebinding argocd-image-updater-manager-rolebinding \
  --type=json -p='[{"op":"add","path":"/subjects/0/namespace","value":"argocd"}]'

# 권한 적용 확인, 정상이면 yes 출력된다.
kubectl auth can-i list applications.argoproj.io --as=system:serviceaccount:argocd:argocd-image-updater --all-namespaces

#####

# argocd-notification 로 argocd 상태를 slack, github, webhook 등으로 노티를 보내 보자.
# argocd-notification 은 argocd 설치시 기본으로 포함되어 있다.

# 슬랙으로 알람 보내는 경우
# argocd-notifications-secret 에 슬랙 토큰을 추가한다.
# 참고로 stringData 로 저장하면 data 로 바뀌고 값은 base64 인코딩된다.
kind: Secret
stringData:
  slack-token: <slack oauth access token>

# 현재 설정된 configmap 을 가져오자.
kubectl get cm argocd-notifications-cm -o yaml -n argocd > argocd-notification-cm.yaml

# app sync 성공시 특정 URL 로 노티 보내기 위해 다음을 내용을 추가한다.
# https://argocd-notifications.readthedocs.io/en/stable/services/webhook/ 가 문서가 있는데 데 subscriptions.recipients 부분 설명이 없어 아래 예시에 추가했다.
kind: ConfigMap
data:
  subscriptions: |
    - recipients:
      - ysoftman

  # x-www-form-urlencoded 인 경우
  service.webhook.ysoftman: |
    url: https://ysoftman.test.com
    headers:
    - name: Content-Type
      value: application/x-www-form-urlencoded
  template.app-sync-succeeded: |
    webhook:
      ysoftman:
        method: POST
        body: key1=value1&key2=value2

  # json 인 경우
  service.webhook.ysoftman: |
    url: https://ysoftman.test.com
    headers:
    - name: Content-Type
      value: application/json
  template.app-sync-succeeded: |
    webhook:
      ysoftman:
        method: POST
        body: |
          {
            "key1":123,
            "key2":"aaa"
          }

  # 기본 템플릿에서 참조할 argocd url 명시
  context: |
    argocdUrl: https://ysoftman.argocd

  # 슬랙 사용시 위에서 저장한 시크릿을 토큰으로 참조하도록 한다.
  service.slack: |
    token: $slack-token

# 기본 트리거/템플릿 설정을 다음과 같이 설치하면 configmap 에 추가된다.
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/notifications_catalog/install.yaml

# (kubectl.kubernetes.io/last-applied-configuration 는 삭제후) 적용
kubectl apply -f ./argocd-notification-cm.yaml

# 노티를 사용할 application 에 다음 annotations 를 추가한다.
# 또는 arogcd ui > app > summary > edit > notification subscriptions 
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  annotations:
    notifications.argoproj.io/subscribe.on-deployed.ysoftman: ""
    notifications.argoproj.io/subscribe.on-sync-succeeded.ysoftman: ""
    notifications.argoproj.io/subscribe.on-sync-failed.ysoftman: ""
    notifications.argoproj.io/subscribe.on-sync-running.slack: my_channel
    notifications.argoproj.io/subscribe.on-sync-succeeded.slack: my_channel

drone ci 사용하기

# golang 으로 만들고 docker 환경으로 실행되는 drone ci 를 사용해보자.

# 우선 로컬에서 테스트하기 때문에 
# (reverse proxy 로 ngrok 도메인 -> localhost 로 터널링 해주는) ngrok 설치
brew install ngrok

# http://fe9b41d98488.ngrok.io -> http://localhost:80 포워딩을 위해 실행
# 참고 https (tls) 터널링은 유료 버전만 가능하고, 그외 동시접속 제한이 있다.
ngrok http 80

# github oauth 로 drone 앱(서버)를 등록
# github -> settings -> developers -> oauth apps 에서 신규 생성한다.
# homepage url : http://dd441e3e9f16.ngrok.io
# callback url : http://dd441e3e9f16.ngrok.io/login

# oauth app 생성후
# client -> DRONE_GITHUB_CLIENT_ID
# client secret -> DRONE_GITHUB_CLIENT_SECRET 로 사용한다.
# generate a new client secret(생성후 한번 볼 수 있어 복붙해둬야 한다) -> DRONE_GITHUB_CLIENT_SECRET 값으로 사용

# drone <-> runner 간 RPC 통신을 위한 secret 생성 -> DRONE_RPC_SECRET 값으로 사용
openssl rand -hex 16                         
d087c94b8155367b1982238df930c2f2

# drone 도커 이미지 다운로드
docker pull drone/drone:1

# 실행
# github enterprise 는 깃헙 서버 환경 변수 설정 필요
# --env=DRONE_GITHUB_SERVER=https://github.ysoftman.com \
# 볼륨 연결로 /data/database.sqlite -> 호스트의 /var/lib/drone/database.sqlite 로 저장
docker run \
  --volume=/var/lib/drone:/data \
  --env=DRONE_DATABASE_DRIVER=sqlite3 \
  --env=DRONE_DATABASE_DATASOURCE=/data/database.sqlite \
  --env=DRONE_GITHUB_CLIENT_ID=깃헙_클라이언트_id \
  --env=DRONE_GITHUB_CLIENT_SECRET=깃헙_클라이언트_secret \
  --env=DRONE_RPC_SECRET=d087c94b8155367b1982238df930c2f2 \
  --env=DRONE_SERVER_HOST=127.0.0.1 \
  --env=DRONE_SERVER_PROTO=http \
  --env=DRONE_WEBHOOK_ENDPOINT=http://dd441e3e9f16.ngrok.io/hook \
  --env=DRONE_WEBHOOK_SECRET=d087c94b8155367b1982238df930c2f2 \
  --env=DRONE_REPOSITORY_FILTER=ysoftman,bill \
  --publish=80:80 \
  --publish=443:443 \
  --restart=always \
  --detach=true \
  --name=drone \
  drone/drone:1

# 이제 다음 url 로 github authorize 하면 깃헙으로 로그인상태로 drone ci 를 사용할 수 있다.
http://dd441e3e9f16.ngrok.io

# DRONE_REPOSITORY_FILTER 으로 특정 저장소에만 drone과 연결 할 수 있다.
# 설정 변경 후 사용자별로 로그아웃 후 다시 로그인 해야 반영된다.

#####

# 상황에 맞는 여러 runner(러너)가 있다.
# docker(임시 컨테이너를 생성해 실행할때 사용) 러너 설치
docker pull drone/drone-runner-docker:1
docker run -d \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e DRONE_RPC_PROTO=http \
  -e DRONE_RPC_HOST=dd441e3e9f16.ngrok.io \
  -e DRONE_RPC_SECRET=d087c94b8155367b1982238df930c2f \
  -e DRONE_RUNNER_CAPACITY=2 \
  -e DRONE_RUNNER_NAME=${HOSTNAME} \
  -e DRONE_DEBUG=true \
  -e DRONE_TRACE=true \
  -p 3000:3000 \
  --restart always \
  --name runner \
  drone/drone-runner-docker:1

# exec(docker 와 같은 고립된 환경이 아닌 drone 서버 장비에서 쉘 환경에서 명령을 실행할 때 사용) 러너를 설치
curl --proxy "필요한 경우 프록시 설정" -L https://github.com/drone-runners/drone-runner-exec/releases/latest/download/drone_runner_exec_linux_amd64.tar.gz | tar zx
sudo install -t /usr/local/bin drone-runner-exec
mkdir -p /home/ysoftman/.drone-runner-exec
touch /home/ysoftman/.drone-runner-exec/config
cat > /etc/drone-runner-exec/config << eof
DRONE_RPC_PROTO=http
DRONE_RPC_HOST=dd441e3e9f16.ngrok.io
DRONE_RPC_SECRET=d087c94b8155367b1982238df930c2f
DRONE_LOG_FILE=/home/ysoftman/.drone-runner-exec/log.txt
eof
drone-runner-exec service install
drone-runner-exec service start

# drone-runner-exec 서비스 상태 확인
systemctl status drone-runner-exec.service

# docker 환경 변수 확인
docker inspect -f "{{.Config.Env}}" drone  | tr " " "\n"


# ssh(ssh 로 서버에 접속해 명령을 실행하는 용도) 러너 설치
docker pull drone/drone-runner-ssh
docker run -d \
  -e DRONE_RPC_PROTO=http \
  -e DRONE_RPC_HOST=dd441e3e9f16.ngrok.io \
  -e DRONE_RPC_SECRET=d087c94b8155367b1982238df930c2f \
  -p 3000:3000 \
  --restart always \
  --name runner \
  drone/drone-runner-ssh

# 루트 경로에 .drone.yml 를 작성한다.
# 파일명은 drone ci settings 에서 변경 가능하다.
---
kind: pipeline
type: exec
name: default

platform:
  os: linux
  arch: amd64

trigger:
  event:
    - push
steps:
  - name: 작업1
    commands:
      - echo hello world1
  - name: 작업2
    commands:
      - echo hello world2
  - name: 슬랙 알림
    # environment:
    #   noti_msg: "Branch: ${DRONE_BRANCH}\nAuthor: ${DRONE_COMMIT_AUTHOR}\nLink: ${DRONE_COMMIT_LINK}"
    #   build_status: "✅ build ${DRONE_BUILD_NUMBER} succeeded. Good job."
    commands:
      - echo "파이프 종료"
      - export HTTP_PROXY="http://프록시서버"
      - export noti_msg="Branch ${DRONE_BRANCH}\nAuthor ${DRONE_COMMIT_AUTHOR}\nLink ${DRONE_COMMIT_LINK}"
      - export build_status="✅ build ${DRONE_BUILD_NUMBER} succeeded. Good job."
      - echo $DRONE_BUILD_STATUS
      - if [[ $DRONE_BUILD_STATUS == "failure" ]]; then build_status="❌ build ${DRONE_BUILD_NUMBER} failed. Fix me please."; fi
      - |
        curl https://hooks.slack.com/services/..... -d "payload={\"channel\": \"#billtest\", \"text\": \"파이프 라인 시작\n$noti_msg\n$build_status\"}"
# ---
# kind: pipeline
# type: ssh
# name: default
# # 접속할 대상 서버
# server:
#   host: ysoftman-server.com
#   user: deploy
#   password:
#     from_secret: password
# steps:
#   - name: 작업1
#     commands:
#       - echo hello world1
#   - name: 작업2
#     commands:
#       - echo hello world2
# ---
# kind: pipeline
# type: docker
# name: slack notification
# # 사내환경등에서 외부 접속이 안되는 경우 프록시 환경 변수 설정
# environment:
#  HTTP_PROXY: "http://프록시주소"
#  HTTPS_PROXY: "http://프록시주소"
# steps:
#   - name: 슬랙 알림
#     # 사내환경등에서 외부 이미지 다운로드가 안되는 경우 알맞게 변경
#     image: plugins/slack
#     settings:
#       # https://my.slack.com/services/new/incoming-webhook 참고
#       webhook: https://hooks.slack.com/services/.....
#       channel: ysoftman-test
#       template: >
#         {{#success build.status}}
#           build {{build.number}} succeeded. Good job.
#         {{else}}
#           build {{build.number}} failed. Fix me please.
#         {{/success}}
#         Branch: {{ build.branch }}
#         Author: {{ build.author }}
#         Link: {{ build.link }}

# 이제 drone DRONE_WEBHOOK_ENDPOINT 변수로 설정된 url 을
# github 저장소 webhook url 을 추가해 push 되면 drone 에 알리도록 한다.
http://dd441e3e9f16.ngrok.io/hook

# 참고로 위의 HTTP_PROXY 와 같은 환경변수를 사용할때 
# ${HTTP_PROXY} 는 안되고 {} 를 제거한 $HTTP_PROXY 로 사용해야 한다.

#####

# drone cli 툴 사용 https://docs.drone.io/cli/install/
# 설치
brew install drone-cli

# aaaaabbbbb11111 는 drone > User Settings > token 로 확인
# 접속할 drone 서버 환경 변수 설정
export DRONE_SERVER=http://dd441e3e9f16.ngrok.io
export DRONE_TOKEN=aaaaabbbbb11111

# 접속 여부 확인
drone info

# .drone.yml 작업 수행(커밋 전에 미리 로컬에서 테스트할 수 있다.)
# drone exec 현재 type: docker 만 실행된다.
# .drone.yml 을 다음과 같이 만들고
kind: pipeline
type: docker
name: default

steps:
- name: build
  image: golang:1.13
  commands:
  - echo "aaa"

# 실행
# .drone.yml syntax 체크등에 활용할 수 있다.
drone exec

slack app 만들기

# google app engine 으로 미세먼지 정보 요청 처리 서버를 만들어 두었다.
# 참고로 아래 스샷은 크롬 stylish 익스텐션 black slack 테마를 적용한것임.
# slack 에서 app 만들기
https://api.slack.com/apps
administration -> manage apps -> build -> building slack apps -> create slack app -> app name  과  slack workspace 선택

# app feature 에 보면 몇개의 기능을 사용할 수 있는데
# slash command (/명령어) 입력해서 실행하는 방법을 만들어 보자.
# 명령어 정하고 미세먼지 요청 URL 을 명시하면 된다.


# 생성한 slash command


# mise 앱 -> settings -> basic information -> display information -> 아이콘 추가 -> save changes

# 아이콘은 가로x세로가 똑같은 정사각형만 된다.


# 이제 mise 앱 -> settings -> install app 으로 설치하면 된다.
# slack 채널에서 /미세먼지 를 입력하면 다음과 같이 보인다.
# 아래 화면을 보면 'only visible to you' 라고 나오는데,
# slash command 는 일반적인 메시지 형식이 아닌 ephemeral(휘발성 메시지)라 채널에 기록되지 않는다.
# refresh 하면 사라진다.


slack api 사용하기

# slack(슬랙)에서 제공하는 web api 를 통해 다양한 기능을 사용할수 있다.
# 우선 api 를 사용하기 우해선 내 토큰 생성(파악)해야 한다.

# 특정 채널에 메시지 보내기
https://api.slack.com/methods/chat.postMessage
# curl 로 슬랙 api 사용하도록 하자.
curl -X POST -d "token=abc123&channel=mychannel&text=테스트 메시지&username=ysoftman's bot" https://slack.com/api/chat.postMessage

# 이모지 사용자 설정 내용 파악
curl -X POST -d "token=abc123" https://slack.com/api/emoji.list

# 그밖의 슬랙 api

#####

# jenkins -> slack 알림

# slack 설정
# 내슬랙.slack.com -> apps -> jenkins ci 앱검색 -> 추가 또는 기존 settings
# 토큰값을 파악하고

# jenkins slack 플러그인 설치
# jenkins -> credentials -> secret text 타입으로 slack 토큰 등록
# jenkins -> 시스템 설정 -> slack -> workspace, credential, channel 설정

Prev