Kubernetes에서 중복 정의된 환경 변수를 삭제하면 Resource 측면의 환경 변수가 사라집니다
26612 단어 Kubernetestech
개시하다
Kubbernetes의 환경 변수 주변에서 뜻밖의 행동을 당해 사고가 났기 때문에 행동·대응법을 공유하고 싶다.
TL;DR
Pod에서 환경 변수가 사라짐
재현 순서
환경 구조
아마도 어느 Kubernetes도 재현할 수 있을 것 같지만, 이번에는 현지에서 간단하게 구축할 수 있을 것 같다. kind
cluster.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: envvar-cluster
nodes:
- role: control-plane
- role: worker
$ kind create cluster --config cluster.yaml
(略)
Have a nice day!
$
$
$ kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:56066
CoreDNS is running at https://127.0.0.1:56066/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
$
$
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
envvar-cluster-control-plane Ready control-plane,master 72m v1.23.4 172.19.0.3 <none> Ubuntu 21.10 5.10.76-linuxkit containerd://1.5.10
envvar-cluster-worker Ready <none> 72m v1.23.4 172.19.0.2 <none> Ubuntu 21.10 5.10.76-linuxkit containerd://1.5.10
동작 확인
다음의 특이한 점이 없는 Deployment를 토대로 확인합니다.
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: SAMPLE_ENV_VAR1
value: sample1
- name: SAMPLE_ENV_VAR2
value: sample2
1단계: Deployment 만들기
$ kubectl apply -f deployment.yaml
deployment.apps/nginx-deployment created
$
$
$ kubectl get deployment -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 1/1 1 1 16s nginx nginx:latest app=nginx
$
$
$ kubectl get replicasets -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
nginx-deployment-dfc74d86 1 1 1 60s nginx nginx:latest app=nginx,pod-template-hash=dfc74d86
$
$
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-dfc74d86-qmck4 1/1 Running 0 79s 10.244.1.14 envvar-cluster-worker <none> <none>
다음과 같이 환경 변수를 설정합니다.$ kubectl get deployments -o json | jq '.items[].spec.template.spec.containers[].env'
[
{
"name": "SAMPLE_ENV_VAR1",
"value": "sample1"
},
{
"name": "SAMPLE_ENV_VAR2",
"value": "sample2"
}
]
$ kubectl get replicasets -o json | jq '.items[].spec.template.spec.containers[].env'
[
{
"name": "SAMPLE_ENV_VAR1",
"value": "sample1"
},
{
"name": "SAMPLE_ENV_VAR2",
"value": "sample2"
}
]
$ kubectl get pods -o json | jq '.items[].spec.containers[].env'
[
{
"name": "SAMPLE_ENV_VAR1",
"value": "sample1"
},
{
"name": "SAMPLE_ENV_VAR2",
"value": "sample2"
}
]
2단계: 반복 환경 변수
방금 전의 Manifest는 다음과 같이 응용 프로그램을 편집합니다.
env:
- name: SAMPLE_ENV_VAR1
value: sample1
- name: SAMPLE_ENV_VAR2
value: sample2
+ - name: SAMPLE_ENV_VAR2
+ value: sample2
착오가 생길 줄 알았는데 특별히 성공할 줄은 몰랐다.디프도 안 나오니까 이 단계에서 눈치채기 힘들죠?
$ kubectl diff -f deployment.yaml
$
$ kubectl apply -f deployment.yaml
deployment.apps/nginx-deployment configured
diff가 없기 때문에 Resource의 환경 변수도 당연히 변화가 없다.(Deployment, ReplicaSet도 마찬가지이지만 중복되어 로그가 생략됨)
$ kubectl get pods -o json | jq '.items[].spec.containers[].env'
[
{
"name": "SAMPLE_ENV_VAR1",
"value": "sample1"
},
{
"name": "SAMPLE_ENV_VAR2",
"value": "sample2"
}
]
3단계: 중복 제거
중복된
SAMPLE_ENV_VAR2
을 삭제하려면 추가 시 나타나지 않는 diff가 발생합니다. env:
- name: SAMPLE_ENV_VAR1
value: sample1
- name: SAMPLE_ENV_VAR2
value: sample2
- - name: SAMPLE_ENV_VAR2
- value: sample2
$ kubectl diff -f deployment.yaml
diff -u -N /var/folders/wm/yhjlm5nd3vg1g_x433204z7c0000gp/T/LIVE-948535760/apps.v1.Deployment.default.nginx-deployment /var/folders/wm/yhjlm5nd3vg1g_x433204z7c0000gp/T/MERGED-3665042967/apps.v1.Deployment.default.nginx-deployment
--- /var/folders/wm/yhjlm5nd3vg1g_x433204z7c0000gp/T/LIVE-948535760/apps.v1.Deployment.default.nginx-deployment 2022-03-16 00:25:43.000000000 +0900
+++ /var/folders/wm/yhjlm5nd3vg1g_x433204z7c0000gp/T/MERGED-3665042967/apps.v1.Deployment.default.nginx-deployment 2022-03-16 00:25:43.000000000 +0900
@@ -6,7 +6,7 @@
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"nginx"},"name":"nginx-deployment","namespace":"default"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"nginx"}},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"env":[{"name":"SAMPLE_ENV_VAR1","value":"sample1"},{"name":"SAMPLE_ENV_VAR2","value":"sample2"},{"name":"SAMPLE_ENV_VAR2","value":"sample2"}],"image":"nginx:latest","name":"nginx","ports":[{"containerPort":80}]}]}}}}
creationTimestamp: "2022-03-15T15:18:24Z"
- generation: 2
+ generation: 3
labels:
app: nginx
managedFields:
@@ -46,10 +46,6 @@
.: {}
f:name: {}
f:value: {}
- k:{"name":"SAMPLE_ENV_VAR2"}:
- .: {}
- f:name: {}
- f:value: {}
f:image: {}
f:imagePullPolicy: {}
f:name: {}
@@ -130,8 +126,6 @@
- env:
- name: SAMPLE_ENV_VAR1
value: sample1
- - name: SAMPLE_ENV_VAR2
- value: sample2
image: nginx:latest
imagePullPolicy: Always
name: nginx
"대략 움직일 것 같으니까 내주세요"이렇게 앱리하면...?$ kubectl apply -f deployment.yaml
deployment.apps/nginx-deployment configured
diff와 같이 무자비하게 SAMPLEENV_VAR2가 사라졌습니다.참고로
value
의 값은 기존의 값과 같고 중복되지 않고 중복되지 않는다.$ kubectl get pods -o json | jq '.items[].spec.containers[].env'
[
{
"name": "SAMPLE_ENV_VAR1",
"value": "sample1"
}
]
Extra: 새로 만들 때 반복되는 동작
이렇게 중복된 값으로 새로 만들면 경고가 발생하지만 바로 적용되며 특별한 오류가 발생하지 않고 Pod가 정상적으로 상승합니다.
env:
- name: SAMPLE_ENV_VAR1
value: sample1
- name: SAMPLE_ENV_VAR2
value: sample2
- name: SAMPLE_ENV_VAR2
value: sample2-duplicated
$ kubectl apply -f deployment.yaml
Warning: spec.template.spec.containers[0].env[2].name: duplicate name "SAMPLE_ENV_VAR2"
deployment.apps/nginx-deployment created
$
$
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-66759f486b-4qrrr 1/1 Running 0 42s
와 Pod의 설정은 configurd가 중복될 때와 달리 2개의 같은 값이 존재하지만 실제로Pod 내부에서 볼 수 있는 값은 Manifest 뒤에 쓴 값인 것 같다.$ kubectl get pods -o json | jq '.items[].spec.containers[].env'
[
{
"name": "SAMPLE_ENV_VAR1",
"value": "sample1"
},
{
"name": "SAMPLE_ENV_VAR2",
"value": "sample2"
},
{
"name": "SAMPLE_ENV_VAR2",
"value": "sample2-duplicated"
}
]
$
$
$ kubectl exec -it nginx-deployment-66759f486b-4qrrr -- env | grep SAMPLE
SAMPLE_ENV_VAR2=sample2-duplicated
SAMPLE_ENV_VAR1=sample1
Manifest에서 교체SAMPLE_ENV_VAR2
의 순서는 다음과 같다.$ kubectl exec -it nginx-deployment-74f47d648d-nb87h -- env | grep SAMPLE
SAMPLE_ENV_VAR1=sample1
SAMPLE_ENV_VAR2=sample2
중요한 중복된 부분을 삭제할 때의 행동이지만 아까와 마찬가지로 이 환경 변수는 사라졌다.$ kubectl exec -it nginx-deployment-55569b7c8b-vdcvc -- env | grep SAMPLE
SAMPLE_ENV_VAR1=sample1
대응법
이런 사태에 빠지지 않기 위해(예비)
실수로 어플리케이션이 환경 변수를 제거한 경우(소화)
다시 한 번 같은 매니페스트 앱리에서 한다면 현재와의 차별을 메우기 위해 원래 상태로 돌아간다.
당황하지 말고, 당황하지 말고, kubectl apply를 실행하거나, CI/CD 흐름을 다시 한 번 돌려서 다시 디자인하세요.
중복 정의 발견 시(지뢰 처리)
앞에서 말한 바와 같이 임의로 삭제하면 환경 변수가 부족한 팟이 개발돼 사고가 발생하기 때문에 약간의 회피 조치가 필요하다.
갑자기 떠오르는 방법은 별명으로 Deployment을 만들고 서비스의 Label Selector를 잠시 전환해 업무를 놓치게 하고 그 사이 복구하는 것이다.
(이번에는 검증되지 않았지만 kubectl edit로 뭔가를 할 수 있을 것 같다.)
1. 중복 발견
flowchart LR Service-->Dep1["Deployment"]-->RS1["ReplicaSet"]-->Po1["Pod"]-->Database
2. 대피용 Deployment 제작
3. 업무 전환
$ kubectl diff -f service.yaml
(略)
@@ -47,7 +47,7 @@
protocol: TCP
targetPort: 80
selector:
- app: nginx
+ app: nginx-temp
sessionAffinity: None
type: ClusterIP
status:
flowchart LR x["no Service"]-.-Dep1["Deployment"]-.-RS1["ReplicaSet"]-.-Po1["Pod"]-.-Database Service-->Dep2["Deployment(temp)"]-->RS2["ReplicaSet(temp)"]-->Po2["Pod(temp)"]-->Database style x fill:#ccc
4. 복구
4. 업무 리베이트
$ kubectl diff -f service.yaml
(略)
@@ -47,7 +47,7 @@
protocol: TCP
targetPort: 80
selector:
+ app: nginx
- app: nginx-temp
sessionAffinity: None
type: ClusterIP
status:
flowchart LRService-->Dep1["Deployment(fixed)"]-->RS1["ReplicaSet(fixed)"]-->Po1["Pod(fixed)"]-->Database
x["no Service"]-.-Dep2["Deployment(temp)"]-.-RS2["ReplicaSet(temp)"]-.-Po2["Pod(temp)"]-.-Database
style x fill:#ccc
5. 회피용 Deployment 삭제
flowchart LR
Service-->Dep1["Deployment(fixed)"]-->RS1["ReplicaSet(fixed)"]-->Po1["Pod(fixed)"]-->Database
고찰하다.
env:
KeyValue가 아닌 정렬이기 때문에 데이터 구조상 중복 정의가 가능한 것도 어쩔 수 없습니다..items[].spec.template.spec.containers[].env[]
총결산
Reference
이 문제에 관하여(Kubernetes에서 중복 정의된 환경 변수를 삭제하면 Resource 측면의 환경 변수가 사라집니다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/ryo_yamaoka/articles/cb597c4904c249텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)