함수에 보안 활성화하기
함수에 보안 활성화하기
함수에서 비밀(secret) 값을 안전하게 다루도록 보안을 활성화하는 방법을 정리해 볼게요. 함수가 비밀 API를 쓰려면 먼저 함수 워커(function worker)에 보안 설정을 켜고, 그 다음 함수 컨텍스트에서 비밀을 꺼내 쓰는 구조예요.
보안 설정은 함수 워커의 SecretsProviderConfigurator로 시작해서 함수 인스턴스의 SecretsProvider로 이어져요. 기본 제공 구현 두 가지를 그대로 쓰거나, 필요하면 나만의 구현을 만들 수도 있어요.
출처: 문서
본문
함수에 보안을 활성화하려면 다음 단계를 완료해요.
사전 준비 (Prerequisites)
- 함수에 보안을 활성화하려면 먼저 함수 워커에 보안 설정을 활성화해야 해요.
1단계: 함수 워커 구성하기 (Configure function workers)
컨텍스트의 secret API를 사용하려면 함수 워커에 다음 두 매개변수를 설정해야 해요.
secretsProviderConfiguratorClassNamesecretsProviderConfiguratorConfig
Pulsar Functions는 두 가지 SecretsProviderConfigurator 구현을 제공하고, 둘 다 secretsProviderConfiguratorClassName의 값으로 바로 쓸 수 있어요.
org.apache.pulsar.functions.secretsproviderconfigurator.DefaultSecretsProviderConfigurator— 시크릿 공급자의 기본(뼈대) 버전으로,ClearTextSecretsProvider를 함수 인스턴스에 연결해요.org.apache.pulsar.functions.secretsproviderconfigurator.KubernetesSecretsProviderConfigurator— Kubernetes에서 실행할 때 기본으로 사용되며, Kubernetes 내장 시크릿을 이용해 (환경 기반 시크릿 공급자, EnvironmentBasedSecretsProvider를 통해) 함수 컨테이너 안에 환경 변수로 바인딩해서 런타임에 함수가 시크릿을 쓸 수 있게 해줘요.
함수 워커는 org.apache.pulsar.functions.secretsproviderconfigurator.SecretsProviderConfigurator 인터페이스를 사용해서, 함수 인스턴스를 시작할 때 SecretsProvider 클래스 이름과 관련 설정을 선택해요.
함수 인스턴스는 org.apache.pulsar.functions.secretsprovider.SecretsProvider 인터페이스를 사용해서 시크릿을 가져와요. SecretsProvider가 사용하는 구현은 SecretsProviderConfigurator가 결정해요.
함수 인스턴스에 다른 SecretsProvider를 쓰고 싶다면 나만의 SecretsProviderConfigurator를 구현할 수도 있어요.
알아두기: Java, Python, Go 런타임에는 다음 두 공급자(provider)가 있어요.
ClearTextSecretsProvider(DefaultSecretsProviderConfigurator의 기본값)EnvironmentBasedSecretsProvider(KubernetesSecretsProviderConfigurator의 기본값)
2단계: 시크릿 가져오기 (Get the secret)
SecretsProviderConfigurator를 설정했다면, Context 객체를 사용해서 다음과 같이 시크릿을 가져올 수 있어요.
Java:
import org.apache.pulsar.functions.api.Context;
import org.apache.pulsar.functions.api.Function;
import org.slf4j.Logger;
public class GetSecretValueFunction implements Function<String, Void> {
@Override
public Void process(String input, Context context) throws Exception {
Logger LOG = context.getLogger();
String secretValue = context.getSecret(input);
if (!secretValue.isEmpty()) {
LOG.info("The secret {} has value {}", input, secretValue);
} else {
LOG.warn("No secret with key {}", input);
}
return null;
}
}
Python:
from pulsar import Function
class GetSecretValueFunction(Function):
def process(self, input, context):
logger = context.get_logger()
secret_value = context.get_secret(input)
if secret_provider is None:
logger.warn('No secret with key {0} '.format(input))
else:
logger.info("The secret {0} has value {1}".format(input, secret_value))
Go:
func secretLoggerFunc(ctx context.Context, input []byte) {
fc, ok := pf.FromContext(ctx)
if !ok {
logutil.Fatal("Function context is not defined")
}
secretValue := fc.GetSecretValue(string(input))
if secretValue == nil {
logutil.Warnf("No secret with key %s", input)
} else {
logutil.Infof("The secret %s has value %s", input, secretValue)
}
}
더 알아보기 (Learn more)
- 함수 워커 보안 설정 전반은 함수 워커 문서에서 확인해요.
- Kubernetes에서의 시크릿 관리가 궁금하다면 Kubernetes 런타임 문서를 살펴보세요.
- 인증·암호화 같은 Pulsar 보안 기능은 Pulsar 보안 문서를 참고해요.