아이엠 !나이롱맨😎
article thumbnail
반응형

설명은 필요없고 결론만 알고 싶은 분들을 위한

$ sed "$(grep -n 'image:' nginx.yaml | grep -Eo '^[^:]+')s/nginx:1.0/nginx:2.0/g" nginx.yaml

본문의 기능이 필요한 상황 예시

 

위 이미지는 개발자가 코드를 커밋한 후 자동으로 k8s cluster에 배포되기 까지의 과정을 파이프라인으로 도식화한 이미지입니다.

 

개발자가 운영 중인 서비스에 새로운 기능을 추가하거나 버그를 수정 했다고 가정해봅시다. 그렇게 될 경우 GitOpsRepo의 있는 컨테이너 이미지의 버전 또한 바꿔주어야 합니다. 

 

그렇게 될 경우 젠킨스에서 GitOps Repo에 push를 할 때 새롭게 만든 컨테이너 이미지의 버전으로 수정해줘야 합니다. 그래야 argoCD에서 git Hook을 인지하고 새롭게 만든 컨테이너 이미지를 기반으로 파드를 재배포해줄테니까요.

 

이럴 때 "파일에서 문자열 검색 한 후 그 문자열의 라인 넘버 가져오기" 가 필요로 됩니다.

 

# yaml
images: nginx:1.0

# yaml
images: nginx:2.0

#으로 수정해줘야 합니다

처음에는 이렇게 했었습니다.  sed 명령어로 "image:"라는 단어를 통째로 찾은 후 그 라인을 아예 새롭게 바꿔주었죠.

즉, 라인 자체를 바꿔줍니다. 뭔가 좋아보이진 않습니다.. 그리고 실제론 버전과 저장소 이름, 컨테이너 이미지까지 동적으로 지정해줘야 하기 때문에 훨씬 코드가 지저분해집니다.

$ sed -i "/image:/c\\        image: nginx:2.0" nginx.yaml

# 실제로 CICD에서 사용한 명령어
$ sed -i "/image:/c\\        image: $(echo $DOCKER_USER_ID)/$(echo $image_name):$(echo $BUILD_NUMBER)" deployment.yaml

 

그래서 다른 방법을 모색해봤습니다. sed 라는 명령어는 행번호를 주게되면 그 행번호에서만 찾게되는 기능도 있습니다. 따라서 행번호를 주어 그 행번호에서만 문자열 치환이 가능하도록 해보겠습니다.

 

sed -i "행번호s/기존문자열/새문자열/" 파일명

 

실습은 아래 nginx.yaml로 진행하겠습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.0 # 여기를 바꾸고 싶습니다.
        name: nginx
        resources: {}
status: {}

 

우선 "image:"이라는 단어를 찾아 그 단어가 포함되는 라인의 넘버를 출력해주는 명령어입니다.

$ grep -n "image:" nginx.yaml

grep -n "image:" nginx.yaml

하지만 원하던 것은 "21:      - image: nginx:1.0"이 아니고 "21" 하나기 때문에 아래와 같은 명령어를 입력해줍니다.

$ grep -n 'image:' nginx.yaml | grep -Eo '^[^:]+'

 

21만 출력됩니다. 원하던 값을 찾았습니다!!

$ sed -i "행번호s/기존문자열/새문자열/" 파일명

 

그럼 위 명령어를 활용해서 아래와 같이 명령어를 수정해주었습니다.

$ sed "$(grep -n 'image:' nginx.yaml | grep -Eo '^[^:]+')s/nginx:1.0/nginx:2.0/g" nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:2.0 #잘 바뀌었습니다.
        name: nginx
        resources: {}
status: {}

 

사실 위 명령어도 깨끗해보이지 않지만 확실히 맨처음 짠 코드보다는 훨씬 안정성이 있는 느낌입니다. 처음 명령어는 "image:"라는 명령어를 전역에서 찾고, 찾은 단어의 라인을 지워버리고 다시 생성하는 거니깐 띄어쓰기가 중요한 yaml에서는 치환되는 과정에서 에러가 발생할 수도 있습니다.

 

즉, 딱 버전만 찾아 바꾸게 되니깐 훨씬 안정성이 있어보입니다!!

 

반응형

article prev thumbnail

다음 글

[Linux] VM을 NFS로 사용하기

2021.12.08

article next thumbnail
profile on loading

Loading...