AWS의 EKS(탄력적 Kubernetes 서비스)에서 Golang을 사용하여 SQS 메시지 소비
며칠 전, 나는 Golang에서 SQS에 종사했다.상당히 까다롭지만, 나에게는 스트레스가 충분하다.5일을 버텼기 때문에, 단지 내 소비자들이 EKS에서 좋은 모습을 보일 수 있도록 하기 위해서였다.
일부 컨텍스트를 제공하기 위해 SQS는 단순 대기열 서비스를 나타냅니다.AWS에서 제공하는 메시지 대기열 서비스입니다.자세한 내용은 SQS from AWS의 공식 페이지를 참조하십시오.
간단히 말하면, SQS에서 온 많은 정보를 소모하는 응용 프로그램이 있다고 가정해 보세요.
간단히 말하면, 우리는 AWS SDK를 사용하여 SQS 메시지를 사용할 수 있다.하지만 이 절차는 Google Pubsub에서 경험한 것과 크게 다르다.GCP에서 그들은 Google Pubsub에서 온 메시지를 장시간 소비/유동적으로 전송하는 기능을 갖춘 완전한 SDK를 준비했다.AWS, 특히 SQS에서는 대기 중인 메시지를 추출하기 위해 긴 순환과 REST 호출이 필요합니다.
그래서 우리가 하는 일은 기본적으로 이 훌륭한 문장인'SQS Consumer Design: Achieving High Scalability while managing concurrency in Go'을 복제하는 것이다.
func (c \*consumer) Consume() {
for w := 1; w <= c.workerPool; w++ {
go c.worker(w)
}
}func (c \*consumer) worker(id int) {
for {
output, err := retrieveSQSMessages(c.QueueURL, maxMessages)
if err != nil {
continue
} var wg sync.WaitGroup
for \_, message := range output.Messages {
wg.Add(1)
go func(m \*message) {
defer wg.Done()
if err := h(m); err != nil {
//log error
continue
}
c.delete(m) //MESSAGE CONSUMED
}(newMessage(m))
wg.Wait()
}
}
}
네, 저는 단지 그의 코드를 복사했을 뿐입니다.왜냐하면 그것은 이미 좋아 보이기 때문이다.노동자 모델을 채택하다.그런데 왜 그것을 정확하게 사용하지 않습니까?너무 길어서 읽을 수가 없어요.하지만 지금 나는 두 가지 문제가 있다
문제 진술
체인 자격 증명
우리의 문제는 노동자나 다른 사람에게 있지 않다.먼저 SDK를 소개합니다.
문제는 기본 SDK에 인증 순서가 있습니다.이 페이지로 이동하면 "Configuring the AWS SDK for Go"체인 증명서 주문서를 발견할 수 있습니다.
미국 용접학회
이 문서에서는 SDK가 먼저 ENV 키를 찾습니다.존재하지 않으면 공유 자격 증명 파일을 찾습니다.자격 증명 파일이 존재하지 않으면 EC2의 IAM 역할이 표시됩니다.
여기서 문제는 SDK의 기본 구성이 먼저 ENV 변수를 불러오기 때문에 이 변수가 존재하지 않으면 AWS\u WEB\u IDENTITY\u TOKEN\u 파일과 유사한 공유 자격 증명 파일을 찾습니다.로컬 작업공간의 경우 ~/에 있는 AWS 구성에서 자격 증명 파일을 찾습니다.aws/credentials(Mac/Linux)(자세한 정보는 here 참조).
이것은 우리에게 있어서 문제다.이 프로젝트는 우리뿐만 아니라 다른 팀의 다른 엔지니어들에게도 사용될 수 있기 때문이다.AWS 구성을 로컬로 구성한 다른 엔지니어에게는 ~/에 위치할 수 있습니다.aws/인증서.우리는 그들이 로컬에서 응용 프로그램을 실행할 기회가 있다고 가정하지만, ~/에 설정된 생산 접근 증명서를 사용한다.aws/인증서.
그래서 우리가 진정으로 원하는 것은 다음과 같다.
우리의 첫 번째 해결 방안은 우리가 먼저 IAM 역할을 검사한 다음에 확정하는 것이다.존재하지 않는 경우 AWS\u ACCESS\u key\u ID 및 AWS\u SECRET\u ACCESS\u key 등 ENV 키를 찾습니다.
그리고 우리는 우리의 체인 증명서를 다음과 같이 맞춤형으로 만들었다.
상기 함수, 특히credProviders를 보신다면, 저희는 인증서 링크 제공 프로그램의 순서를 지정할 것입니다. 우선, 실례 IAM 역할을 찾은 다음에 ENV 제공 프로그램을 찾을 것입니다.따라서 공유 자격 증명 파일을 사용하는 인증을 기본적으로 삭제했습니다.따라서 엔지니어가 ~/에 있는 PC에 AWS 자격 증명 키를 구성할 때마다SDK는 IAM 역할과 ENV 키만 찾기 때문에 여전히 안전합니다.
질문
사용자 정의 체인 자격 증명을 만든 후에 우리는 또 다른 문제를 발견했다.EC2 인스턴스에서 잘 실행되지만 EKS에서는 실행할 수 없습니다.간단히 말하면, 우리의 체인 증명서는 EC2 인스턴스 수준에서만 작동합니다.EKS의 경우 IAM이 노드 레벨에서만 작동하도록 허용하면
보안의 경우 EKS의 경우 노드 레벨이 아닌 서비스 계정 레벨이나pods 레벨에서 IAM 역할을 사용하기를 원합니다. 예를 들어'Introducing fine-grained IAM roles for service accounts'에서 보듯이
그래서 우리의 사용자 정의 체인 증명서가 EKS에서 잘 작동하지 않는 것은 분명하다.그래서 우리는 체인식 방법을 바꿔야 한다
최종 솔루션
이 문제를 해결하기 위해서 우리는 우리의 인프라 시설 엔지니어와 함께 앉았다.응용 프로그램을 토론하고 디버깅합니다.하루 종일 노력한 끝에 우리는 응용 프로그램에서 합리적인 맞춤형 해결 방안을 결정하였다
EKS에서 작업하려면 공유 자격 증명 파일을 사용해야 한다는 사실이 증명되었습니다.이는 EKS에서 article 기반 AWS\u WEB\u IDENTITY\u TOKEN\u 파일을 사용하기 때문입니다
따라서 웹 표지 영패 파일을 사용하려면 파일을 사용해야 합니다.우리는 우선 어떤 것을 피해야 하지만, EKS에서 잘 작동하기 위해서, 공유 증명서 파일을 사용하여 체인 인증을 사용하기로 결정합니다
하지만 엔지니어의 로컬 공유 증빙 파일을 피하기 위해~/.의외로aws/credentials를 사용했기 때문에, 우리는 응용 프로그램에서 논리 처리 (코드로 정적 작성) 를 하기로 결정했습니다
ENV 변수 APP\u ENV를 사용하여 환경이 로컬 환경인지 확인합니다
// IsLocal will return true if the APP\_ENV is not listed in those
// three condition
func IsLocal() bool {
envLevel := MustHaveEnv("APP\_ENV")
return envLevel != "production" &&
envLevel != "staging" &&
envLevel != "integration"
}
따라서 APP\u ENV의 가치가 어떻든 생산, 임시 저장 또는 통합이 아니라면 우리는 APP\u ENV가 로컬이라고 가정합니다
보시다시피 환경이 로컬이 아닌 경우 (if! IsLocal () 공유 프로필을 사용합니다.만약 그것이 로컬에 있다면, 우리는 ENV 키를 사용해야 한다. 이것은 필수적이기 때문에, 우리는 의외로 엔지니어의 로컬 작업공간에서 생산 접근 증명서를 사용하는 것을 피할 수 있다.aws/인증서
이렇게 해서 우리는 마침내 SDK 자격 증명 문제를 안전하게 해결하였다.엔지니어에게 ENV 키를 로컬에서 사용하도록 강요합니다(localstack 사용).공유 자격 증명 파일이 임시 저장 및 프로덕션에 사용됩니다
Using Customized HTTP Client
또 다른 문제는 SQS 메시지를 사용하려고 할 때입니다.그러나 이 점을 상세히 소개하기 전에 상하문을 제공하기 위해 우리는 AWS SDK 문서 페이지에서 이 글'Creating a Custom HTTP Client'을 찾았다.그 페이지에서 HTTP 클라이언트를 사용자 정의하는 방법을 찾았습니다
그럼, 우리는 단지 이러한 절차를 따를 뿐이다.HTTP 클라이언트를 사용자 정의했습니다.우리는 시간 초과, 최대 유휴 연결 등을 설정한 후에 로컬에서 실행합니다(localstack).우리는 현지에서 테스트를 하는데, 모든 것이 정상이다.잘했어
질문
그러나 EKS에 배포하려고 할 때EKS에 배치된 후 많은 오류가 발생했습니다
time="2020-02-06T07:23:02Z" level=error msg="there was an error reading messages from SQS RequestError: send request failed\ncaused by: Post [https://sqs.ap-southeast-2.amazonaws.com/](https://sqs.ap-southeast-2.amazonaws.com/): net/http: request canceled (Client.Timeout exceeded while awaiting headers)"
time="2020-02-06T07:23:02Z" level=error msg="there was an error reading messages from SQS RequestError: send request failed\ncaused by: Post [https://sqs.ap-southeast-2.amazonaws.com/](https://sqs.ap-southeast-2.amazonaws.com/): net/http: request canceled (Client.Timeout exceeded while awaiting headers)"
실제로 이것은 큰 문제가 아니지만, 이것은 사람을 화나게 하고 우리의 로그 저장소를 증가시킨다. 왜냐하면 이것은 실시간으로 실행되기 때문이다. 왜냐하면 우리는 HTTP 호출을 사용하여 SQS에서 장기적으로 정보를 가져오기 때문이다.이 문제를 해결하는데 이틀이 걸렸어요!!!이것 때문에 나는 꼬박 이틀을 다 끝냈다.WTF
최종 솔루션
나는 매우 낙담했다. 왜 이 문제가 내 팀에서 발생했는지 아무도 모른다.그리고 고프의 게으름뱅이 팀에게 물어보기로 했어요
André Eriksson과 Zach Easey 및 느슨한 두더지 https://gophers.slack.com/archives/C029RQSEE/p1580979593499800 중 다른 분들께 감사 드립니다.그들은 나를 도와 나의 문제를 해결했다
한 마디로 하면 이런 상황이 발생한 것은 우리가 긴 폴링을 사용했기 때문이지만, 긴 폴링과 연결을 사용한 상황에서 우리는 HTTP 클라이언트를 사용자 정의했기 때문이다
따라서 해결 방안은 SQS에서 오는 메시지를 장시간 윤문하는 데 HTTP 클라이언트를 사용자 정의해서는 안 되고 기본 클라이언트를 사용해야 한다는 것이다.HTTP 클라이언트 (예: 시간 초과 등) 를 사용자 정의하면 긴 폴링 연결 시간과 경쟁하기 때문에 요청이 취소됩니다. (헤더를 기다리는 동안client.timeout) 오류가 발생할 때
이것은 상당히 까다롭다. 왜냐하면 내가 알기로는 나쁜 시간 초과와 사용자 체험을 피하기 위해 나는 통상적으로 나의 HTTP 클라이언트를 맞춤 제작한다.그러나 이러한 상황에서 SQS의 경우 긴 폴링 호출을 사용하기 때문에 정확한 해결 방안은 시간 초과 설정이 없는 기본 HTTP 클라이언트만 사용하는 것입니다
Conclusions
SQS와 Go-in EKS를 통합할 때 전체 프로젝트의 성과는
- AWS SDK의 사용자 정의 체인 자격 증명을 수동으로 처리하여 로컬 작업공간 엔지니어 ~/의 생산 액세스 자격 증명 파일을 의외로 사용하지 않도록 합니다.aws/인증서.
- 은pods급에서 IAM 역할을 사용하기 위해 SDK가 공유 자격 증명 파일을 사용할 수 있도록 허용해야 합니다. 이것은 매우 까다롭습니다. 왜냐하면 로컬 작업공간에서 사용하지 않기 때문입니다.
- 우리는 추가 ENV 키(예를 들어 APP\u ENV)를 사용하여 코드에서 체인 증명서를 논리적으로 처리합니다.
- SQS 메시지를 사용하기 위해 긴 폴링 연결을 사용하려면 기본 HTTP 클라이언트를 사용해야 합니다. 시간 초과를 사용자 정의하지 마십시오. 그렇지 않으면 시간 초과 오류가 발생할 수 있습니다.
https://medium.com/media/1f83e4a733ad3206f47e6dd38aa4fc6d/href
Reference
이 문제에 관하여(AWS의 EKS(탄력적 Kubernetes 서비스)에서 Golang을 사용하여 SQS 메시지 소비), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/bxcodec/consuming-sqs-message-using-golang-in-eks-elastic-kubernetes-service-from-aws-3p2p텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)