AWS EKS를 사용하고 있자면 주기적으로 쿠버네티스 버전을 업그레이드 하라는 알림이 옵니다. 간혹 Action Required 딱지가 붙어오는 경우 미뤄뒀던 업그레이드를 반강제적으로 진행해야하는데 AWS 콘솔에서 업그레이드 버튼을 눌러 진행하면 편하겠지만, 실서비스에 영향을 줄 수 있고 Istio도 새로운 버전으로 안전하게 업그레이드할 겸 신규 클러스터를 만들어 세팅하고 최종적으로 접속 도메인의 DNS 수정으로 교체하고 있습니다.
EKS 관리에 필요한 모든 공식 문서는 AWS EKS 사용 설명서를 참고하세요.
eksctl 업그레이드
아래 가이드를 참고하여 EKS 관리툴인 eksctl를 최신 버전으로 설치해 줍니다. eksctl 최신 버전 설치를 위해 영어 문서를 확인해야 합니다. 한글 문서의 경우 영문보다 업데이트가 느려 영문으로 봐야 현재 지원하는 버전으로 설치할 수 있습니다. (우측 상단 한글 --> English 로 전환)
kubectl 업그레이드
아래 AWS에서 제공하는 가이드를 참고하여 kubectl을 가장 최신 버전으로 설치합니다. kubectl 또한 최신 버전 설치를 위해 영문 문서를 확인해야 합니다. (우측 상단 한글 --> English 로 전환)
신규 클러스터 생성
아래 AWS의 문서를 참고하여 새로 세팅할 쿠버네티스 신규 클러스터를 생성합니다.
AWS EKS에서 지원하는 최신의 쿠버네티스 버전은 아래 페이지에서 확인 가능합니다.
아래와 같이 쉘스크립트를 하나 만들어두면 다음 업그레이드때 도움이 될 것 같습니다.
신규 클러스터 생성 스크립트
eksctl create cluster \
--name new-cluster \
--region ap-northeast-2 \
--without-nodegroup \
--vpc-private-subnets subnet-087c2c903873ba81c,subnet-0fba0366fc531f4a9,subnet-038d0d05a4d957171 \
--vpc-public-subnets subnet-05d5eb9eb7af12569,subnet-0dceb3ca5d6c09c3e,subnet-09d47688f210cc6a3
여기서 중요 포인트는 기존 사용중인 VPC 및 Public IP를 그대로 유지하고 싶다면 --vpc-private-subnets 과 --vpc-public-subnets 를 반드시 기존 사용하고 있는 서브넷으로 설정해 주어야 합니다.
신규 노드그룹 생성
아래와 같이 신규 노드그룹 생성 쉘스크립트를 만들어두면 다음번 업그레이드 작업 때 도움이 되겠습니다.
신규 노드그룹 생성 스크립트
eksctl create nodegroup \
--cluster new-cluster \
--region ap-northeast-2 \
--name new-group \
--node-type m5.xlarge \
--nodes 8 \
--nodes-min 2 \
--nodes-max 12 \
--managed \
--node-private-networking \
--ssh-access \
--ssh-public-key mykey-seoul
Autoscaling 설정
metrics 서버 설치
CPU 사용량에 따른 파드 개수를 조절하는 HPA(Horizontal Pod Autoscaler) 사용을 위해 metrics 서버를 설치합니다.
VPA
누리고는 경험부족 및 안정성이 확보되지 않아 Vertical Pod Autoscaler 기능은 사용하지 않습니다. 사용하려면 링크 참조.
권한 설정 (Optional)
AWS 콘솔에서 클러스터 리소스를 보려면 아래와 같이 mapUsers 권한을 추가해 주어야 합니다.
mapUsers: |
- userarn: arn:aws:iam::111111111111:root
username: root
groups:
- system:masters
kubectl edit configmap aws-auth -n kube-system
아래와 같이 mapRoles 아래에 mapUsers를 추가해 줍니다.
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
mapRoles: |
- groups:
- system:bootstrappers
- system:nodes
rolearn: arn:aws:iam::111111111111:role/eksctl-new-cluster-nodegroup-new-group-NodeInstanceRole-NMK1994UOABC
username: system:node:{{EC2PrivateDNSName}}
mapUsers: |
- userarn: arn:aws:iam::111111111111:root
username: root
groups:
- system:masters
kind: ConfigMap
metadata:
creationTimestamp: "2022-07-04T23:05:59Z"
name: aws-auth
namespace: kube-system
resourceVersion: "165300"
uid: 6f6ce2cc-8502-4ace-b196-b3126e5246ac
Istio 신규 버전 설치
아래 Istio 문서를 참고하여 최신 버전의 Istio 를 설치합니다.
Client 설치
아래 명령으로 istioctl 을 설치합니다.
curl -L https://istio.io/downloadIstio | sh -
쿠버네티스 내부에 Istio 서버 설치
아래 명령으로 쿠버네티스 클러스터에 Istio를 설치합니다.
istioctl install --set profile=default -y
ARM으로 클러스터를 구성하셨다면 아래 내용을 참고하여 설치합니다.
Kubernetes 내부에 Istio 서버 설치 (ARM 버전)
ARM64 바이너리 설치를 위해 아래 가이드를 따라야 합니다. istio install 명령 대신 Istio Operator Install 방식으로 설치합니다.
Istio Operator Install
ARM64 바이너리 설치
- Github 참고: https://github.com/resf/istio
istioctl operator init --hub=ghcr.io/resf/istio
kubectl create ns istio-system
kubectl apply -f - <<EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
name: example-istiocontrolplane
spec:
hub: ghcr.io/resf/istio
profile: default
EOF
Envoy sidecar 적용
아래 명령으로 Envoy Sidecar를 활성화 해줍니다.
kubectl label namespace default istio-injection=enabled
Istio Ingress Gateway 설정
누리고에서는 Istio Ingress Gateway를 Public, Private 각각 1개씩 두고 로드밸런서와 연결하여 사용하고 있으므로 아래와 같이 Private용으로 추가 설정을 해줍니다.
Public Ingress Gateway https 접속 설정
먼저 기본적으로 생성된 Ingress Gateway를 Public용도로 사용하기 위해 istio-ingressgateway Service 를 아래와 같이 수정해줍니다.
아래 명령으로 기본 생성된 Public용 Ingress Gateway의 스펙을 얻습니다.
kubectl get svc istio-ingressgateway -n istio-system -o yaml > istio-ingressgateway-service.yaml
아래오 같은 수정 포인트로 istio-ingressgateway-service.yaml 파일을 수정합니다.
- 기존 동일한 SSL 인증서를 유지하기 위해 aws-load-balancer-ssl-cert annotation 추가
- 게이트웨이를 타고 들어온 뒤로 Private Network에서 http로 다루기 위한 annotations 추가
- 443포트를 8080로 타겟 포트로 잡아줄 것
- nodePort는 제거
참고로 누리고에서는 자체 개발된 API Gateway 가 Ingress Gateway 뒤쪽에서 받아주고 있고 포트 8080을 사용하고 있으므로 타겟 포트를 8080으로 잡아줍니다.
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:ap-northeast-2:111111111111:certificate/98c00da2-35c0-496b-8c8d-a3f6076a23d2"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https"
service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "60"
service.beta.kubernetes.io/aws-load-balancer-security-groups: "sg-0c84090ac3a4c6baf"
labels:
app: istio-ingressgateway
install.operator.istio.io/owning-resource: example-istiocontrolplane
install.operator.istio.io/owning-resource-namespace: istio-system
istio: ingressgateway
istio.io/rev: default
operator.istio.io/component: IngressGateways
operator.istio.io/managed: Reconcile
operator.istio.io/version: 1.14.1
release: istio
name: istio-ingressgateway
namespace: istio-system
spec:
ports:
- name: status-port
port: 15021
protocol: TCP
targetPort: 15021
- name: http2
port: 80
protocol: TCP
targetPort: 8080
- name: https
port: 443
protocol: TCP
targetPort: 8080
selector:
app: istio-ingressgateway
istio: ingressgateway
type: LoadBalancer
아래 명령으로 수정된 Service 파일을 적용합니다.
kubectl apply -f istio-ingressgateway-service.yaml
Private Ingress Gateway 추가
Service 생성
Istio Ingress Gateway 를 외부에서 호출 불가능한 Private 용도로 만들기 위해 istio-ingressgateway-service.yaml 파일을 복사하여 Internal LoadBalancer 로 설정해 줍니다.
cp istio-ingressgateway-service.yaml istio-pvt-ingressgateway-service.yaml
아래의 수정 포인트로 복사된 istio-pvt-ingressgateway-service.yaml 파일을 수정해 줍니다.
- ingressgateway 를 pvt-ingressgateway 로 이름 변경
- annotations 에 aws-load-balancer-internal: "true"를 추가하고 나머지는 삭제합니다. (Internal LoadBalancer로 만들어 줍니다.)
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-internal: "true"
labels:
app: istio-pvt-ingressgateway
install.operator.istio.io/owning-resource: example-istiocontrolplane
install.operator.istio.io/owning-resource-namespace: istio-system
istio: pvt-ingressgateway
istio.io/rev: default
operator.istio.io/component: IngressGateways
operator.istio.io/managed: Reconcile
operator.istio.io/version: 1.14.1
release: istio
name: istio-pvt-ingressgateway
namespace: istio-system
spec:
ports:
- name: status-port
port: 15021
protocol: TCP
targetPort: 15021
- name: http2
port: 80
protocol: TCP
targetPort: 8080
- name: https
port: 443
protocol: TCP
targetPort: 8080
- name: grpc
port: 50051
protocol: TCP
targetPort: 50051
selector:
app: istio-pvt-ingressgateway
istio: pvt-ingressgateway
type: LoadBalancer
아래 명령으로 Service 파일을 적용합니다.
kubectl apply -f istio-pvt-ingressgateway-service.yaml
Development 생성
아래 명령으로 Private 용도로 사용할 Ingress Gateway Deployment 스펙을 추출합니다.
kubectl get deployment/istio-ingressgateway -n istio-system -o yaml > istio-pvt-ingressgateway-deployment.yaml
아래의 주안점을 두고 istio-pvt-ingressgateway-deployment.yaml 파일을 수정해줍니다.
- ingressgateway -> pvt-ingressgateway 로 이름 변경
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: istio-pvt-ingressgateway
install.operator.istio.io/owning-resource: example-istiocontrolplane
install.operator.istio.io/owning-resource-namespace: istio-system
istio: pvt-ingressgateway
istio.io/rev: default
operator.istio.io/component: IngressGateways
operator.istio.io/managed: Reconcile
operator.istio.io/version: 1.14.1
release: istio
name: istio-pvt-ingressgateway
namespace: istio-system
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: istio-pvt-ingressgateway
istio: pvt-ingressgateway
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
annotations:
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
sidecar.istio.io/inject: "false"
creationTimestamp: null
labels:
app: istio-pvt-ingressgateway
chart: gateways
heritage: Tiller
install.operator.istio.io/owning-resource: unknown
istio: pvt-ingressgateway
istio.io/rev: default
operator.istio.io/component: IngressGateways
release: istio
service.istio.io/canonical-name: istio-ingressgateway
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- preference:
matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- amd64
weight: 2
- preference:
matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- arm64
weight: 2
- preference:
matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- ppc64le
weight: 2
- preference:
matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- s390x
weight: 2
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- amd64
- arm64
- ppc64le
- s390x
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.cluster.local
- --proxyLogLevel=warning
- --proxyComponentLogLevel=misc:error
- --log_output_level=default:info
env:
- name: JWT_POLICY
value: third-party-jwt
- name: PILOT_CERT_PROVIDER
value: istiod
- name: CA_ADDR
value: istiod.istio-system.svc:15012
- name: NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
- name: HOST_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.hostIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.serviceAccountName
- name: ISTIO_META_WORKLOAD_NAME
value: istio-pvt-ingressgateway
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/istio-system/deployments/istio-pvt-ingressgateway
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
- name: ISTIO_META_UNPRIVILEGED_POD
value: "true"
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
image: ghcr.io/resf/istio/proxyv2:1.14.1
imagePullPolicy: IfNotPresent
name: istio-proxy
ports:
- containerPort: 15021
protocol: TCP
- containerPort: 8080
protocol: TCP
- containerPort: 8443
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 2
successThreshold: 1
timeoutSeconds: 1
resources:
limits:
cpu: "2"
memory: 1Gi
requests:
cpu: 100m
memory: 128Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /etc/istio/config
name: config-volume
- mountPath: /var/run/secrets/istio
name: istiod-ca-cert
- mountPath: /var/run/secrets/tokens
name: istio-token
readOnly: true
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/pod
name: podinfo
- mountPath: /etc/istio/ingressgateway-certs
name: ingressgateway-certs
readOnly: true
- mountPath: /etc/istio/ingressgateway-ca-certs
name: ingressgateway-ca-certs
readOnly: true
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext:
fsGroup: 1337
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
serviceAccount: istio-ingressgateway-service-account
serviceAccountName: istio-ingressgateway-service-account
terminationGracePeriodSeconds: 30
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: workload-certs
- configMap:
defaultMode: 420
name: istio-ca-root-cert
name: istiod-ca-cert
- downwardAPI:
defaultMode: 420
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.labels
path: labels
- fieldRef:
apiVersion: v1
fieldPath: metadata.annotations
path: annotations
name: podinfo
- emptyDir: {}
name: istio-envoy
- emptyDir: {}
name: istio-data
- name: istio-token
projected:
defaultMode: 420
sources:
- serviceAccountToken:
audience: istio-ca
expirationSeconds: 43200
path: istio-token
- configMap:
defaultMode: 420
name: istio
optional: true
name: config-volume
- name: ingressgateway-certs
secret:
defaultMode: 420
optional: true
secretName: istio-ingressgateway-certs
- name: ingressgateway-ca-certs
secret:
defaultMode: 420
optional: true
secretName: istio-ingressgateway-ca-certs
아래 명령으로 Deployment 파일을 적용합니다.
kubectl apply -f istio-pvt-ingressgateway-deployment.yaml
EXTERNAL-IP 확인
로드밸런서 EXTERNAL-IP를 할당 받기 위해서 서브넷 6개 모두 태그를 아래와 같이 추가해 줍니다. (Key 이름에 kubernetes.io/cluster/{cluster-name} 형식)
Key | Value |
---|---|
kubernetes.io/cluster/new-cluster | shared |
아래 문서를 참고하세요.
Amazon EKS VPC 및 서브넷 요구 사항과 고려 사항
도메인 확인
kubectl get svc -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 172.20.186.54 a9f416a4f7fd3468598f34b6c0cfbbac-111111111.ap-northeast-2.elb.amazonaws.com 15021:32015/TCP,80:30359/TCP,443:31588/TCP 42h
istio-pvt-ingressgateway LoadBalancer 172.20.21.235 internal-a37957be60a4f4138a50136b539dbbac-111111111.ap-northeast-2.elb.amazonaws.com 15021:31632/TCP,80:30013/TCP,443:32419/TCP 40h
istiod ClusterIP 172.20.200.23 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 42h
Private 도메인 연결 설정
누리고 API Gateway 내부호출에는 특정 도메인(private-network.solapi-internal.com)을 통해 istio-pvt-ingressgateway 을 호출하므로, AWS Route53 에서 istio-pvt-ingressgateway 에 할당된 Loadbalancer를 private-network.solapi-internal.com 에 연결합니다.
Gateway 설정
gRPC 백엔드 호출을 위한 Gateway 추가
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: grpc-internal-gateway
spec:
selector:
istio: pvt-ingressgateway
servers:
- port:
number: 50051
name: grpc
protocol: GRPC
hosts:
- "private-network.solapi-internal.com"
Public API 용 Gateway 추가
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: public-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 8080
name: http
protocol: HTTP
hosts:
- "api.solapi.com"
Public 웹페이지 용 Gateway 추가
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: webpages-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 8080
name: http
protocol: HTTP
hosts:
- "solapi.com"
- "www.solapi.com"
StorageClass 사용을 위해 aws ebs csi driver 설치
아래 문서를 참고하여 드라이버를 설치해 줍니다.
IAM Policy 생성(업그레이드 시 이미 있으므로 생략)
export EBS_CSI_POLICY_NAME="Amazon_EBS_CSI_Driver"
mkdir ${HOME}/environment/ebs_statefulset
cd ${HOME}/environment/ebs_statefulset
# download the IAM policy document
curl -sSL -o ebs-csi-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-ebs-csi-driver/master/docs/example-iam-policy.json
# Create the IAM policy
aws iam create-policy \
--region ${AWS_REGION} \
--policy-name ${EBS_CSI_POLICY_NAME} \
--policy-document file://${HOME}/environment/ebs_statefulset/ebs-csi-policy.json
# export the policy ARN as a variable
export EBS_CSI_POLICY_ARN=$(aws --region ${AWS_REGION} iam list-policies --query 'Policies[?PolicyName==`'$EBS_CSI_POLICY_NAME'`].Arn' --output text)
OIDC Provider 생성(업그레이드 시 생성 필요)
아래 문서를 참고하여 OIDC Provider를 생성해 줍니다.
# Create an IAM OIDC provider for your cluster
eksctl utils associate-iam-oidc-provider --cluster new-cluster --approve
# Create a service account
# EBS_CSI_POLICY_ARN 값은 arn:aws:iam::111111111111:policy/Amazon_EBS_CSI_Driver
eksctl create iamserviceaccount \
--cluster new-cluster \
--name ebs-csi-controller-irsa \
--namespace kube-system \
--attach-policy-arn $EBS_CSI_POLICY_ARN \
--override-existing-serviceaccounts \
--approve
드라이버 설치
helm upgrade --install aws-ebs-csi-driver \
--namespace kube-system \
--set serviceAccount.controller.create=false \
--set serviceAccount.snapshot.create=false \
--set enableVolumeScheduling=true \
--set enableVolumeResizing=true \
--set enableVolumeSnapshot=true \
--set serviceAccount.snapshot.name=ebs-csi-controller-irsa \
--set serviceAccount.controller.name=ebs-csi-controller-irsa \
aws-ebs-csi-driver/aws-ebs-csi-driver
kubectl -n kube-system rollout status deployment ebs-csi-controller
Local 컴퓨터 환경 설정
argocd 등 관리자 UI 에 접근하기 위해 로컬 컴퓨터에 kubeconfig를 설정합니다. clusters, contexts, users 총 3개 항목을 로컬 컴퓨터로 복사해 옵니다.
- Bastion 서버의 경로: ~/.kube/config
- 로컬 컴퓨터의 경로: ~/.kube/config
로컬 컴퓨터에 kubectl 이 설치되어 있어야 합니다.
- clusters
- cluster:
certificate-authority-data: AB0rAB1TDUdJTiBDRVJUSUZJQ0FURS0tABCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQjABc0ZBREFWJTVNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1EWXlPREF6TVRFeU1Wb1hEVE15TURZeU5UQXpNVEV5TVZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBT2RnCkNybmVMbnFiZXVOcXhsa2FEV09qR05EUUJJRm5jMFhPdUJNT2ppMi9VdU5vcnNVMFY4SkoyZVV3ZnlFdTZ3clQKVitUcnE3VHFkSkZGd0RaY2w1UmNCVWZkUmlSczlrMGNCblpHb0YrWHN5WGVWY0VxL0JJQzBURjRyZktmU0NCZgpVNXpTYWJlcFhVNDY5RnR1cUlQc2VwS1ZYN3g1akVWSFRRdmthWnYyTVJ2Z3lwMk5xbkpuT2pQVnNoV3lBbmpJCi81MjZ4ZlBEUVJ3Vy9jSUNjb1oyL2NJeEl6R2psNkpYTGtIcWNyekRIYUlDR3BRZHlYRnBTN2p3NVJwd0J1eUIKSk5COG52dWx0MUVkWit0aGwyL1F6eFhoSHl1c2ZTUFV6WUJpUzk3QVNEZW1sdzNwcEg2bUxjUGIrUGhoMFQzZAp4Q3RJU2xJN3NMUTFDWlh5a0pNQ0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZIM3EyUHY5TU9ld3R3OUdqeno3dmNvN1UrcDlNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBTVkwOWNQNXVpV2dEV3RKdHByKwp0WTNpVEhLdmlVQnlSSzUweXgwRlp1TW4yVnpOckhvWlVhcVg1YzBJMEM4ZjZSUkxrOWc2S1VDZkRxUTUxOSs1CmdsUkY0RWV3UGxVdWJ5dXBXSElSM1BJVDdYMmRxbURaRUZQNytoRGpwNGl4Ukp1VmNFZ01VaVo3YjYyUEJ6YXgKQVZkZ0Z1VmVrSjlEbkRvTXBvb0o0dkduTThiRzN0eGlMNUtZVEVsdnJ0d2txeFU1R2xqNFl4THhFVDY2V3FjMgp0azdPOU9jajlnejRHbUFXeklSR2wvaDlvRDJHelFTNlZvVmRQbFB0WnVnRW8zZVR6M3EwUHVlbEZ4VlA2bHEyCmJzdklCVGNBQ05KMXFRNlNEUUZnakI1QjE4U1VGWTJFNGcrVS9VZlVvYld1NSgsbFpZKzN1VHlUNHZSM1ZFNWkKa080PQotLS0tLGVORCBDRVJUSUZJQ0QURS0tAB0tgC==
server: https://834BE0B2DJ11B81E3FE7CE3C28980BEE.ab8.ap-northeast-2.eks.amazonaws.com
name: new-cluster.ap-northeast-2.eksctl.io
- contexts
- context:
cluster: new-cluster.ap-northeast-2.eksctl.io
user: user-name@new-cluster.ap-northeast-2.eksctl.io
name: user-name@new-cluster.ap-northeast-2.eksctl.io
- users
- name: user-name@new-cluster.ap-northeast-2.eksctl.io
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
args:
- token
- -i
- new-cluster
command: aws-iam-authenticator
env:
- name: AWS_STS_REGIONAL_ENDPOINTS
value: regional
- name: AWS_DEFAULT_REGION
value: ap-northeast-2
provideClusterInfo: false
alias 추가
alias switch-new='export AWS_DEFAULT_PROFILE=new-cluster; kubectl config use-context user-name@new-cluster.ap-northeast-2.eksctl.io'
alias argocd-connect='kubectl port-forward svc/argocd-server -n argocd 8080:443'
alias argocd-pw='kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d'
alias argocd-ui='open -a "Google Chrome" http://localhost:8080'
argocd 설정
설치
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
NEW APP 설정
argocd 접속(터널링)
> switch-new
> argocd-connect
password 확인
> switch_new
> argocd-pw
ui 띄우기
> switch-new
> argocd-ui
설정 -> Repositories -> CONNECT REPO USING HTTPS
CONNECT REPO USING HTTPS
Type: git
Project: default
Repository URL: https://github.com/nurigo/argocd-manifest
Username (optional): username
Password (optional): ••••••••••••••••••••••••••••••••••••••••
NEW APP 클릭
Self Heal 기능에 체크하지 않도록 주의
GENERAL
- Application Name: new-cluster
- PRoject Name: default
- SYNC POLICY: Automatic
- Repository URL: https://github.com/nurigo/argocd-manifest
- Revision: HEAD
- Path: /testbed DESTINATION
- Cluster URL: https://kubernetes.default.svc
- Namespace: default
yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: new-cluster
spec:
destination:
name: ''
namespace: default
server: 'https://kubernetes.default.svc'
source:
path: testbed
repoURL: 'https://github.com/nurigo/argocd-manifest'
targetRevision: HEAD
project: default
syncPolicy:
automated:
prune: false
selfHeal: false
테스트 도메인 설정
도메인 확인
kubectl get svc -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 172.20.186.54 a9f416a4f7fd3468598f34b6c0cfbbac-111111111.ap-northeast-2.elb.amazonaws.com 15021:32015/TCP,80:30359/TCP,443:31588/TCP 42h
istio-pvt-ingressgateway LoadBalancer 172.20.21.235 internal-a37957be60a4f4138a50136b539dbbac-111111111.ap-northeast-2.elb.amazonaws.com 15021:31632/TCP,80:30013/TCP,443:32419/TCP 40h
istiod ClusterIP 172.20.200.23 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 42h
테스트 용도의 Interanl 도메인 추가
private-network-test.solapi-internal.com A internal-a37957be60a4f4138a50136b539dbbac-111111111.ap-northeast-2.elb.amazonaws.com
테스트 용도의 Public 도메인 추가
api-test.solapi.com A a9f416a4f7fd3468598f34b6c0cfbbac-111111111.ap-northeast-2.elb.amazonaws.com
Internal 호출 테스트
private-network.solapi-internal.com 도메인으로 테스트하고 문제를 찾아 해결합니다. 미리 테스트 스크립트를 많들어 놓은게 있다면 실행해 줍니다.
git clone https://github.com/nurigo/internal-testing
yarn install
yarn test:internal
Public API 테스트
api-test.solapi.com 도메인으로 테스트하고 문제를 찾아 해결합니다. 미리 테스트 스크립트를 많들어 놓은게 있다면 실행해 줍니다.
git clone https://github.com/nurigo/public-testing
yarn install
yarn test:public
Gateway 도메인 수정
Private 도메인 수정
private-network.solapi-internal.com A internal-a37957be60a4f4138a50136b539dbbac-111111111.ap-northeast-2.elb.amazonaws.com
Public 도메인 수정
solapi.com A a9f416a4f7fd3468598f34b6c0cfbbac-111111111.ap-northeast-2.elb.amazonaws.com
api.solapi.com A a9f416a4f7fd3468598f34b6c0cfbbac-111111111.ap-northeast-2.elb.amazonaws.com
www.solapi.com A a9f416a4f7fd3468598f34b6c0cfbbac-111111111.ap-northeast-2.elb.amazonaws.com
도메인 DNS까지 수정하였으니 앞으로 들어오는 요청은 새로 세팅된 쿠버네티스 클러스터로 들어오게 됩니다.
기존 리소스 제거
노드그룹 제거
아래 명령으로 아래 명령으로 노드그룹을 제거합니다.
eksctl delete nodegroup old-group --cluster old-cluster
한번의 실행으로 실서비스가 멈출 수 있으므로 매우 신중히 명령을 내려야 합니다. 도중에 멈추더라도 서비스가 망가지며 돌이킬 수 없습니다.
명령으로 안되면 EKS 콘솔에서 삭제해야 합니다.
클러스터 제거
아래 명령으로 기존 클러스터를 제거해 줍니다.
eksctl delete cluster --name old-cluster
한번의 실행으로 실서비스가 멈출 수 있으므로 매우 신중히 명령을 내려야 합니다. 도중에 멈추더라도 서비스가 망가지며 돌이킬 수 없습니다.
결론
쿠버네티스 버전 업그레이드가 필요할 때마다 매번 이렇게 진행하기엔 휴먼에러도 고려해야 하고 할일이 너무 많네요. 누리고도 이제 Terraform, Pulumi 같은 신문물을 받아들일 때가 된 것 같습니다.