Golang日志服务开发工程师职位讨论 - Unitet Internet技术团队招募
Golang日志服务开发工程师职位讨论 - Unitet Internet技术团队招募 IONOS凭借其商业应用,是欧洲领先的主机和云应用提供商之一。凭借我们先进的技术,我们每天都能赢得来自许多不同国家的超过800万客户的信赖。
您的职责
在IONOS,您将与欧洲领先的云基础设施、云服务和托管服务提供商的不同团队合作。我们为您提供在最具未来前景的行业之一发展的机会。我们以开放的结构、文化和扁平化的层级以及无与伦比的团队精神为特点。我们坚信工作与乐趣可以结合,并为您提供相应的环境。随着业务的持续增长,我们一直在寻找新的同事。我们正在为我们的“日志即服务”团队寻找增援力量。该团队专注于为客户开发和维护日志管理服务。这些服务范围涵盖从日志代理(如Fluent Bit和rsyslog)到日志处理器、数据库以及其他日志分析产品。与其他团队一起,LaaS团队负责我们日志服务的整个生命周期——从构建到交付和运营。加入IONOS,让我们共同成长。
- 使用(主要)Golang进行编程(Kubernetes Operators、REST API、库和其他工具)。
- 设计解决方案并为我们的客户提供新功能。
- 开发、改进和维护完整的工具链(例如 Helm Charts、Github Actions、GitOps)。
- 扎实的应用性能检测技能(例如日志记录、追踪、性能剖析、监控)。
- 在云环境(Kubernetes)中定义服务结构。
- 与团队一起重新思考服务架构,并使用Golang实现组件。
我们看重
- 具备开发、测试、评审和部署高质量工程代码的经验,最好是使用Golang。
- 您拥有使用Kubernetes或AWS等云技术的实践经验。
- 具备Kubernetes容器编排、Kubernetes Operators、控制器、CRD和Helm Charts的经验。
- 具备运维和故障排除生产环境的经验,包括监控、告警和日志分析。
- 具备Linux操作系统经验。
- 您不犹豫提问,但也喜欢自己解决问题,始终保持适应性强和以解决方案为导向的心态。
- 您具备出色的英语口语、书面和演示技能。
更多关于Golang日志服务开发工程师职位讨论 - Unitet Internet技术团队招募的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang日志服务开发工程师职位讨论 - Unitet Internet技术团队招募的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这是一个非常典型的Go语言云原生/基础设施开发职位,专注于日志服务(Logging as a Service)。职位描述清晰地勾勒出一个现代云服务团队的技术栈和职责范围。以下是对其技术要点的分析和相关Go代码示例:
1. Kubernetes Operators 和控制器开发 这是该职位的核心。Operator用于扩展Kubernetes API,管理自定义资源(CRD)以控制日志服务的生命周期(如Fluent Bit配置、日志管道)。
// 示例:一个简化的LogPipeline Operator Reconciler核心逻辑
package controller
import (
"context"
"fmt"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
laasv1alpha1 "github.com/ionos/laas-operator/api/v1alpha1"
)
type LogPipelineReconciler struct {
client.Client
Scheme *runtime.Scheme
}
func (r *LogPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
logger := log.FromContext(ctx)
// 1. 获取自定义资源 LogPipeline
var pipeline laasv1alpha1.LogPipeline
if err := r.Get(ctx, req.NamespacedName, &pipeline); err != nil {
if errors.IsNotFound(err) {
logger.Info("LogPipeline resource not found. Ignoring since object must be deleted")
return ctrl.Result{}, nil
}
logger.Error(err, "Failed to get LogPipeline")
return ctrl.Result{}, err
}
// 2. 检查并创建对应的Fluent Bit DaemonSet
var ds appsv1.DaemonSet
err := r.Get(ctx, req.NamespacedName, &ds)
if err != nil && errors.IsNotFound(err) {
// 创建 DaemonSet
logger.Info("Creating a new DaemonSet", "DaemonSet.Namespace", req.Namespace, "DaemonSet.Name", req.Name)
ds = *constructFluentBitDaemonSet(&pipeline)
if err := r.Create(ctx, &ds); err != nil {
logger.Error(err, "Failed to create new DaemonSet")
return ctrl.Result{}, err
}
// DaemonSet创建成功 - 返回并重入
return ctrl.Result{Requeue: true}, nil
} else if err != nil {
logger.Error(err, "Failed to get DaemonSet")
return ctrl.Result{}, err
}
// 3. 确保DaemonSet规格与自定义资源一致(更新逻辑)
// ... 比较并更新 DaemonSet 的代码 ...
return ctrl.Result{}, nil
}
func (r *LogPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&laasv1alpha1.LogPipeline{}).
Owns(&appsv1.DaemonSet{}).
Complete(r)
}
func constructFluentBitDaemonSet(pipeline *laasv1alpha1.LogPipeline) *appsv1.DaemonSet {
// 根据pipeline.Spec构建Fluent Bit DaemonSet的详细定义
// 例如,镜像、配置卷、环境变量等
return &appsv1.DaemonSet{
// ... DaemonSet 规格定义 ...
}
}
2. REST API 开发 用于提供日志服务的控制平面API,管理日志管道、查询配置等。
// 示例:使用Gin框架提供日志管道管理的REST API端点
package main
import (
"net/http"
"github.com/gin-gonic/gin"
"k8s.io/client-go/kubernetes"
)
type PipelineHandler struct {
k8sClient kubernetes.Interface
}
func (h *PipelineHandler) CreatePipeline(c *gin.Context) {
var req CreatePipelineRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 1. 验证请求
// 2. 通过Kubernetes Client创建或更新对应的LogPipeline CRD
// 3. 返回操作结果
pipelineCR := buildLogPipelineCR(req)
// ... 使用 h.k8sClient 与Kubernetes API交互 ...
c.JSON(http.StatusAccepted, gin.H{
"message": "Pipeline creation accepted",
"name": pipelineCR.Name,
})
}
func (h *PipelineHandler) GetPipelineStatus(c *gin.Context) {
name := c.Param("name")
namespace := c.Param("namespace")
// 通过Kubernetes Client获取LogPipeline CRD状态
// 并聚合其管理的Pod(Fluent Bit实例)的状态
status := h.aggregatePipelineStatus(namespace, name)
c.JSON(http.StatusOK, status)
}
func main() {
r := gin.Default()
handler := &PipelineHandler{}
api := r.Group("/api/v1")
{
api.POST("/pipelines", handler.CreatePipeline)
api.GET("/namespaces/:namespace/pipelines/:name/status", handler.GetPipelineStatus)
}
r.Run(":8080")
}
3. 性能检测与可观测性集成 职位要求“扎实的应用性能检测技能”,这在Go中通常通过结构化日志、指标暴露和分布式追踪实现。
// 示例:在服务中集成OpenTelemetry进行追踪和指标收集
package main
import (
"context"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
"go.opentelemetry.io/otel/exporters/prometheus"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/global"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
"google.golang.org/grpc"
"log"
"time"
)
func initTracer() (*sdktrace.TracerProvider, error) {
// 创建OTLP gRPC导出器(通常指向Jaeger或OTLP Collector)
traceExporter, err := otlptracegrpc.New(context.Background(),
otlptracegrpc.WithInsecure(),
otlptracegrpc.WithEndpoint("otel-collector:4317"),
)
if err != nil {
return nil, err
}
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(traceExporter),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceName("laas-api"),
attribute.String("environment", "production"),
)),
)
otel.SetTracerProvider(tp)
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
return tp, nil
}
func initMeter() (*metric.MeterProvider, error) {
// 设置Prometheus指标导出器
exporter, err := prometheus.New()
if err != nil {
return nil, err
}
mp := metric.NewMeterProvider(metric.WithReader(exporter))
global.SetMeterProvider(mp)
return mp, nil
}
func processLogBatch(ctx context.Context) {
tracer := otel.Tracer("laas-processor")
meter := global.Meter("laas-processor")
// 创建一个计数器指标
logsProcessed, _ := meter.Int64Counter(
"logs_processed_total",
metric.WithDescription("Total number of processed log entries"),
)
// 创建一个直方图指标
processDuration, _ := meter.Float64Histogram(
"log_batch_process_duration_seconds",
metric.WithDescription("Duration of log batch processing"),
)
ctx, span := tracer.Start(ctx, "processLogBatch")
defer span.End()
start := time.Now()
// 模拟处理逻辑
time.Sleep(10 * time.Millisecond)
batchSize := int64(1000)
// 记录属性到Span
span.SetAttributes(
attribute.Int64("log.batch.size", batchSize),
attribute.String("log.source", "k8s.container"),
)
// 增加计数器
logsProcessed.Add(ctx, batchSize)
// 记录直方图
duration := time.Since(start).Seconds()
processDuration.Record(ctx, duration)
// 记录结构化日志(与追踪关联)
log.Printf("Processed log batch. size=%d, duration=%.3fs, traceID=%s",
batchSize, duration, span.SpanContext().TraceID().String())
}
4. Helm Charts 与 GitOps 团队负责“完整的工具链”,包括Helm Charts。Go常用于编写Helm模板的测试工具或辅助程序。
// 示例:使用Go验证Helm Chart值的简单工具
package main
import (
"fmt"
"gopkg.in/yaml.v3"
"io/ioutil"
"os"
)
type ChartValues struct {
ReplicaCount int `yaml:"replicaCount"`
Image struct {
Repository string `yaml:"repository"`
Tag string `yaml:"tag"`
PullPolicy string `yaml:"pullPolicy"`
} `yaml:"image"`
FluentBit struct {
Config string `yaml:"config"`
Parsers string `yaml:"parsers"`
} `yaml:"fluentBit"`
}
func validateValues(valuesPath string) error {
data, err := ioutil.ReadFile(valuesPath)
if err != nil {
return fmt.Errorf("failed to read values file: %w", err)
}
var values ChartValues
if err := yaml.Unmarshal(data, &values); err != nil {
return fmt.Errorf("failed to unmarshal YAML: %w", err)
}
// 执行验证规则
if values.ReplicaCount <= 0 {
return fmt.Errorf("replicaCount must be positive, got %d", values.ReplicaCount)
}
if values.Image.Repository == "" {
return fmt.Errorf("image.repository is required")
}
if values.FluentBit.Config == "" {
return fmt.Errorf("fluentBit.config is required")
}
fmt.Println("Values validation passed")
return nil
}
func main() {
if err := validateValues("values.yaml"); err != nil {
fmt.Fprintf(os.Stderr, "Validation error: %v\n", err)
os.Exit(1)
}
}
这个职位要求的技术组合(Go、Kubernetes Operators、云原生可观测性、基础设施即代码)代表了当前企业级云服务开发的典型要求。代码示例展示了在这些领域使用Go的实际模式。

