블로그 목록
SW 개발 연대기

2021년 개발 연대기: 장기지원 플랫폼과 AI 코딩, 그리고 공급망의 경고

Java 17, .NET 6, GitHub Copilot 기술 프리뷰, Kubernetes 1.21, Log4Shell, 국내 백신 예약 시스템 개선과 금융 마이데이터 시범 서비스로 2021년의 개발 흐름을 살펴봅니다.

2026년 7월 24일약 21분
#2021#Java 17#.NET 6#GitHub Copilot#Kubernetes#Log4Shell#백신 예약#마이데이터#개발 연대기

2021년에는 빠르게 변한 개발 생태계가 안정적인 운영 기준을 다시 찾았다. Java 17과 .NET 6이라는 장기지원 version이 나왔고, Kubernetes는 오랫동안 beta였던 CronJob을 안정 API로 올렸다. 전년의 비대면 전환을 임시 조치로 끝내지 않고 장기간 운영할 platform과 upgrade 경로를 마련하는 일이 중요해졌다.

동시에 개발 방식의 다음 변화가 모습을 드러냈다. GitHub Copilot 기술 preview는 editor 안에서 문맥에 맞는 code를 생성하는 AI assistant를 제한된 개발자에게 공개했다. 연말의 Log4Shell은 정반대 방향에서 software가 얼마나 많은 보이지 않는 open source dependency 위에 놓여 있는지 드러냈다. code를 더 빨리 만드는 능력과 사용 중인 code를 정확히 추적하는 능력이 함께 필요했다.

국내에서는 접속 폭주로 장애를 겪은 코로나19 백신 사전예약 system을 민관 협력으로 개선했다. 금융 마이데이터는 개인신용정보를 scraping이 아닌 표준 API로 전송하는 시범 서비스를 시작했다. 대규모 traffic과 민감 data를 다루는 system에서 인증, 분산 처리와 이용자 동의가 핵심 설계 조건이 됐다.

2021년을 보여주는 장면

분야주요 변화개발자에게 생긴 의미
JavaJava 17 LTS 출시sealed class·record·pattern matching 등 누적된 언어 변화가 장기지원 기준점에 도달
.NET.NET 6 LTS 출시통합 platform, minimal API와 Arm64 지원을 장기 운영 version으로 제공
AI 개발 도구GitHub Copilot 기술 preview자연어와 code 문맥으로 editor에서 구현안을 제안받는 방식 등장
containerKubernetes 1.21CronJob과 PodDisruptionBudget 등 오래 검증된 기능이 안정화
보안Log4Shell 공개transitive dependency inventory와 긴급 patch 능력이 공급망 보안의 핵심으로 부상
국내 행정백신 사전예약 system 개선인증을 cloud로 분산하고 대기열·중복 접속 제어로 대규모 traffic 대응
국내 금융금융 마이데이터 API 시범 서비스개인이 동의한 신용정보를 표준 API로 전송하는 체계 시작

Java 17, 네 번의 release를 건너 도착한 장기지원 기준점

Oracle은 9월 14일 Java 17을 출시했다. Java 11 이후 12개 minor release와 3년 만에 나온 LTS version이었다. 6개월마다 기능 release를 내고 몇 년 간격으로 장기지원 기준을 제공하는 방식이 Java 생태계에 자리 잡았다.

Java 12부터 16까지 preview와 정식 기능으로 다듬어진 언어 변화가 Java 17에 모였다. record는 data carrier class의 반복적인 constructor, accessor와 equality code를 줄였고, sealed class는 어떤 class가 상속하거나 구현할 수 있는지 명시했다. instanceof pattern matching은 type 검사와 casting을 하나의 표현으로 묶었다.

sealed interface Result permits Success, Failure {}

record Success(String value) implements Result {}
record Failure(String message) implements Result {}

static String describe(Result result) {
    if (result instanceof Success success) {
        return success.value();
    }
    return ((Failure) result).message();
}

위 기능의 시점을 구분할 필요가 있다. record와 instanceof pattern matching은 Java 16에서 정식 기능이 됐고, sealed class가 Java 17에서 정식화됐다. Java 17이 이 모든 문법을 처음 발명한 version이 아니라 LTS 사용자가 한꺼번에 받아들일 수 있는 기준점이 된 것이다.

Java 17은 JDK 내부 API의 강한 encapsulation을 강화했고 Security Manager는 향후 제거를 위한 deprecated 상태가 됐다. 이전 JDK의 내부 구현을 reflection으로 사용하던 library는 upgrade 과정에서 수정이 필요했다. LTS 전환은 새 문법보다 framework·build tool·application server와 monitoring agent의 호환성 검증이 더 큰 일이 될 수 있었다.

Oracle JDK의 지원·license 정책과 각 OpenJDK distribution의 update 기간은 공급자마다 달랐다. 따라서 Java 17 LTS라는 이름만 보고 동일한 지원 조건이라고 가정해서는 안 됐다. 조직은 JDK distribution과 patch 공급 경로까지 함께 정해야 했다.

.NET 6, 통합의 약속이 장기지원 version으로

Microsoft는 11월 8일 .NET 6을 출시했다. 3년 지원을 약속한 LTS release였으며 .NET 5에서 미완성이던 platform 통합을 더 진전시켰다. browser, cloud, desktop, IoT와 mobile을 공통 SDK와 base library 아래 두는 방향이었다. 다만 .NET MAUI의 정식 출시는 2022년으로 미뤄졌으므로 mobile 통합까지 그날 모두 완료된 것은 아니었다.

C# 10은 global using, file-scoped namespace와 record struct를 추가했다. ASP.NET Core의 minimal API는 작은 HTTP service를 적은 ceremony로 정의할 수 있게 했다.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/posts/{year:int}", (int year) =>
    Results.Ok(new { year, title = $"{year}년 개발 연대기" }));

app.Run();

minimal API는 controller architecture를 없애야 한다는 선언이 아니었다. 작은 API와 microservice의 시작 비용을 낮춘 선택지였고, 큰 application에서는 validation, authorization, filter와 구조화된 module 설계가 여전히 필요했다.

.NET 6은 Apple Silicon Arm64를 native 지원하고 Windows Arm64 지원도 개선했다. HTTP/3, OpenTelemetry 진단, JSON source generator와 single-file 배포 기능이 더해졌다. .NET 5 application에는 지원 종료가 빠르게 다가왔으므로 annual current release와 격년 LTS를 구분해 upgrade 계획을 세우는 것이 중요해졌다.

GitHub Copilot, code editor 안으로 들어온 생성형 AI

GitHub은 6월 29일 GitHub Copilot 기술 preview를 공개했다. OpenAI Codex를 기반으로 현재 file의 code와 comment 문맥을 읽고 한 줄부터 함수 전체까지 completion을 제안하는 Visual Studio Code extension이었다. Python, JavaScript, TypeScript, Ruby와 Go에서 특히 잘 작동한다고 소개됐다.

개발자가 함수 이름과 자연어 comment로 의도를 적으면 Copilot이 구현 후보를 제안하고, tab으로 받아들이거나 다른 제안을 볼 수 있었다. test case와 반복적인 mapping code, 익숙하지 않은 API 사용법의 초안을 빠르게 만들 가능성을 보여줬다.

그러나 2021년의 Copilot은 제한된 인원을 받는 기술 preview였다. 모든 개발자에게 유료 일반 제공된 시점은 2022년 6월이다. 당시 제안을 정확한 code로 보장하지 않았고, 생성된 code가 bug·취약점·오래된 API를 포함할 수 있으므로 개발자가 검토하고 test해야 했다.

공개 source code를 포함한 data로 학습한 model이 유사 code를 생성할 가능성과 license·attribution 문제도 논쟁이 됐다. AI가 제안하는 code의 authorship와 책임은 누구에게 있는지, private context를 도구에 어디까지 보낼지 같은 질문이 개발 tool 선택의 일부가 되기 시작했다.

Copilot의 등장은 compiler나 autocomplete가 발전한 사건과는 다른 감각을 줬다. 정확히 정의된 syntax tree의 다음 token이 아니라 개발 의도에 맞는 구현 후보를 확률적으로 생성했다. 개발자의 역할에는 생성 속도보다 요구사항을 분명히 표현하고 결과를 검증하는 능력이 더해졌다.

Kubernetes 1.21, 영구 beta를 줄이다

Kubernetes 1.21은 4월 8일 출시됐다. 51개 enhancement 가운데 13개가 안정 단계로 올라갔다. 대표적으로 CronJob은 batch/v1 API가 되며 2017년 1.8부터 이어진 beta를 마쳤다. backup, report 생성처럼 정해진 시간에 반복하는 Job을 안정 API로 선언할 수 있게 됐다.

안정화 과정에서 controller 구현도 바뀌었다. 기존 controller는 모든 CronJob을 주기적으로 선형 scan해 수천 개가 있으면 schedule이 늦어질 수 있었다. 새 controller는 각 object의 다음 실행 시점을 queue로 관리해 많은 CronJob에서도 지연을 줄였고 1.21에서 기본이 됐다.

PodDisruptionBudget도 안정화돼 node drain이나 cluster upgrade 같은 자발적 중단 때 동시에 unavailable 상태가 될 pod 수를 제한할 수 있었다. immutable Secret과 ConfigMap은 설정이 의도치 않게 바뀌는 일을 막고 API server의 watch 부담을 줄였다.

Kubernetes는 1.20부터 beta API가 무기한 머무르지 않도록 정책을 강화했다. 널리 쓴다는 이유만으로 영구 beta를 유지하기보다 안정화하거나 deprecated 절차를 밟게 한 것이다. platform의 성숙은 새 기능 수보다 API의 보장 범위와 migration 경로를 명확히 하는 쪽으로 이동했다.

Log4Shell, 작은 logging library가 전 세계의 긴급 과제가 되다

12월 초 Apache Log4j 2의 취약점 CVE-2021-44228이 공개됐다. Log4j의 message lookup과 JNDI 기능이 공격자가 통제한 문자열을 처리하면서 외부 LDAP 등의 endpoint를 조회할 수 있었고, 취약한 구성에서는 인증 없이 remote code execution으로 이어질 수 있었다. CVSS 점수 10.0을 받은 이 취약점은 Log4Shell로 불렸다.

문제는 application이 Log4j를 직접 선언하지 않아도 framework나 vendor product의 transitive dependency로 포함할 수 있다는 데 있었다. fat JAR 안의 또 다른 JAR, container image와 commercial appliance까지 확인해야 했다. 단순히 source repository에서 log4j 문자열을 검색하는 것으로 inventory가 끝나지 않았다.

Apache는 2.15.0을 내놓은 뒤 추가 문제와 hardening을 반영해 2.16.0, 2.17.0 등을 빠르게 배포했다. 적용해야 할 안전 version은 사용 중인 Java version과 이후 공개된 CVE에 따라 달랐다. 초기 임시 mitigation만 믿기보다 공식 advisory를 계속 확인하고 fixed version으로 upgrade해야 했다.

사건은 software bill of materials, SBOM과 dependency scanning, artifact provenance의 필요성을 대중적으로 드러냈다. 운영 중인 service가 어느 library version을 포함하는지 모르면 patch가 있어도 영향을 판단할 수 없다. 또한 logging처럼 입력을 기록하는 기능도 외부 resource를 조회하는 실행 능력을 가지면 공격 표면이 될 수 있음을 보여줬다.

Log4Shell을 open source의 실패로만 볼 수는 없다. 전 세계가 중요한 library에 의존하면서 유지보수와 검토 책임을 소수 maintainer에게 집중시킨 구조의 문제이기도 했다. dependency를 무료 부품이 아니라 지속적으로 update하고 기여해야 할 공급망으로 보는 관점이 커졌다.

국내: 백신 예약 폭주를 민관 협력으로 다시 설계하다

코로나19 예방접종 사전예약 system은 2021년 4월부터 연령대별 예약을 처리했다. 7월 50대 예약이 시작되자 짧은 시간에 이용자가 몰려 접속 지연과 장애가 발생했다. login과 본인인증, 예약 대상 확인, 날짜·기관 선택이 한꺼번에 기존 system으로 집중됐다.

정부는 7월 22일부터 민관 합동 task force를 구성하고 8월 예약을 앞두고 system을 개선했다. 가장 큰 부하 지점이던 본인인증을 민간 cloud로 이관하고 여러 간편인증 수단의 상태를 화면에 표시했다. 대기열을 적용하고 한 사람이 여러 device에서 동시에 접속하는 것을 제한했으며 예약 대상자를 생년월일 끝자리로 나누는 10부제도 사용했다.

8월 5일 정부 briefing은 개선된 system이 시간당 최대 200만 건의 예약을 처리하도록 준비됐다고 밝혔다. capacity 숫자만 늘린 것이 아니라 정적 content, 인증과 core reservation을 분리하고 앞단에서 traffic을 제어한 것이 핵심이었다. 병목을 system 전체의 평균 처리량이 아니라 가장 집중되는 인증과 database transaction에서 찾아야 했다.

대리예약 제한과 동시접속 차단은 부하를 낮췄지만 이용 편의와 접근성의 trade-off를 만들었다. digital 기기 사용이 어려운 사람을 위한 call center와 주민센터 지원이 병행돼야 했다. 대규모 public service의 성능 설계는 server 증설뿐 아니라 공정한 순서, 실패 후 재시도와 alternative channel까지 포함해야 했다.

국내: 금융 마이데이터, scraping에서 표준 API로

금융 마이데이터는 개인이 여러 금융회사에 흩어진 자신의 신용정보를 허가받은 사업자에게 전송하도록 요구하고 통합 조회·분석 서비스를 받는 체계다. 2021년에는 사업자 허가, service·기술 guideline, test bed와 표준 API 구축이 본격 진행됐다.

당초 8월 4일 API 의무화를 목표로 했지만 충분한 test와 인증 수단 준비를 위해 일정이 조정됐다. 12월 1일 오후 4시부터 준비된 17개 사업자가 희망 이용자를 대상으로 API 방식 시범 서비스를 시작했고, 전면 시행은 2022년 1월 1일로 정해졌다.

기존 자산관리 service는 이용자가 맡긴 인증정보로 각 금융회사 화면에 login해 data를 scraping하는 경우가 많았다. 표준 API 방식에서는 이용자가 직접 인증하고 전송 항목과 수신 사업자, 기간에 동의한다. 제공 기관은 정해진 schema와 인증 절차로 data를 전송하므로 password 공유 위험과 화면 변경에 따른 수집 장애를 줄일 수 있었다.

표준화가 모든 의미 차이를 없애지는 않았다. 기관마다 상품·거래 code와 갱신 주기가 달랐고 consent lifecycle, token 만료, 정정·삭제와 철회 처리를 구현해야 했다. 여러 기관이 동시에 참여하므로 한 제공자의 지연이 전체 자산 화면을 막지 않게 partial response와 retry 정책도 필요했다.

2021년은 마이데이터가 전면 시행된 해가 아니라 API 기반 시범 서비스를 시작한 해다. 정보주권이라는 정책 개념이 OAuth형 authorization, 표준 schema, 암호화 전송, audit log와 사용자 동의 화면이라는 구체적인 software requirement로 바뀌는 과정이었다.

2021년의 의미

2021년은 안정과 변화가 동시에 나타난 해였다. Java 17과 .NET 6은 빠른 release cadence 속에서 조직이 오래 운영할 기준점을 제공했고, Kubernetes는 검증된 beta 기능을 안정 API로 정리했다. 전년의 급격한 digital 전환을 유지 가능한 platform과 lifecycle로 바꾸는 작업이었다.

GitHub Copilot은 code 생성이 search와 autocomplete를 넘어 AI와 대화하는 방향으로 갈 가능성을 보여줬다. 반면 Log4Shell은 빠르게 조립된 software가 어떤 dependency를 품고 있는지 모르면 작은 library의 문제가 전 세계 service의 긴급 장애가 될 수 있음을 경고했다. 생산성과 공급망 가시성은 따로 갈 수 없었다.

국내 백신 예약 system 개선은 cloud 분산과 traffic control을 public service에 적용한 사례였고, 마이데이터 시범 서비스는 개인의 동의를 표준 API와 audit 가능한 전송 절차로 구현했다. 2022년에는 AI 코딩 도구가 일반 제공되고 마이데이터가 전면 시행되는 한편, cloud와 platform 집중이 대규모 장애에 어떤 영향을 주는지도 더 선명하게 드러난다.

참고 자료