Golang初级开发工程师职位 - United Internet招聘

Golang初级开发工程师职位 - United Internet招聘 IONOS凭借其商业应用,是欧洲领先的主机和云应用提供商之一。凭借我们先进的技术,我们每天都能赢得来自许多不同国家的超过800万客户的信赖。

你的任务

IONOS PaaS 托管 Kubernetes 团队正在寻找一位积极主动的软件工程师。

PaaS 托管 Kubernetes 团队负责为我们客户开发和维护托管 Kubernetes 服务。利用 Kubernetes Operators,我们管理 IONOS 云基础设施,以配置和维护可靠、地理冗余的 Kubernetes 集群。我们负责企业客户大量节点和集群的整个生命周期,持续更新 Kubernetes 堆栈以及我们自己的驱动程序,例如云控制器管理器和容器存储接口。

我们的小团队负责服务的整个生命周期:我们构建它、交付它、运行它。我们正在寻找一位成员加入我们的团队,与我们一起努力提供尽可能好的产品。

  • 使用(主要是)Golang 进行编程(Kubernetes Operators、REST API、库和工具)。
  • 设计解决方案,为客户提供新功能。
  • 开发、改进和维护完整的工具链(例如 Helm Charts、Github Actions、GitOps)。
  • 自动化繁琐的任务,特别是平台的自愈机制。
  • 在自愈机制不足时承担待命职责。

我们看重

  • 编程经验,最好是 Go 语言。
  • 云环境经验。
  • Kubernetes 经验。
  • Linux 操作系统经验。

在此申请


更多关于Golang初级开发工程师职位 - United Internet招聘的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang初级开发工程师职位 - United Internet招聘的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是一个非常典型的Golang云原生开发职位,专注于Kubernetes Operator开发。以下是该职位所需的核心技术栈和示例代码:

核心要求分析:

  1. Golang Kubernetes Operator开发 - 使用controller-runtime和kubebuilder
  2. REST API开发 - 通常使用Gin或Echo框架
  3. 云基础设施集成 - 与IONOS云API交互
  4. GitOps工具链 - Helm Charts、GitHub Actions

示例代码 - 基础Kubernetes Operator结构:

package controllers

import (
    "context"
    "fmt"
    appsv1 "k8s.io/api/apps/v1"
    corev1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "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"
)

// 自定义资源定义
type MyCluster struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`
    Spec   ClusterSpec   `json:"spec,omitempty"`
    Status ClusterStatus `json:"status,omitempty"`
}

type ClusterSpec struct {
    Replicas int32  `json:"replicas"`
    Region   string `json:"region"`
}

type ClusterStatus struct {
    Nodes    int32  `json:"nodes"`
    Phase    string `json:"phase"`
}

// 控制器实现
type MyClusterReconciler struct {
    client.Client
    Scheme *runtime.Scheme
}

func (r *MyClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    logger := log.FromContext(ctx)
    
    // 获取自定义资源
    var cluster MyCluster
    if err := r.Get(ctx, req.NamespacedName, &cluster); err != nil {
        return ctrl.Result{}, client.IgnoreNotFound(err)
    }
    
    // 检查并创建Deployment
    var deployment appsv1.Deployment
    err := r.Get(ctx, client.ObjectKey{
        Name:      fmt.Sprintf("%s-deployment", cluster.Name),
        Namespace: cluster.Namespace,
    }, &deployment)
    
    if err != nil {
        // 创建新的Deployment
        deployment = *r.constructDeployment(&cluster)
        if err := r.Create(ctx, &deployment); err != nil {
            logger.Error(err, "failed to create deployment")
            return ctrl.Result{}, err
        }
    }
    
    // 更新状态
    cluster.Status.Nodes = 3
    cluster.Status.Phase = "Running"
    if err := r.Status().Update(ctx, &cluster); err != nil {
        logger.Error(err, "failed to update cluster status")
        return ctrl.Result{}, err
    }
    
    return ctrl.Result{}, nil
}

func (r *MyClusterReconciler) constructDeployment(cluster *MyCluster) *appsv1.Deployment {
    return &appsv1.Deployment{
        ObjectMeta: metav1.ObjectMeta{
            Name:      fmt.Sprintf("%s-deployment", cluster.Name),
            Namespace: cluster.Namespace,
        },
        Spec: appsv1.DeploymentSpec{
            Replicas: &cluster.Spec.Replicas,
            Selector: &metav1.LabelSelector{
                MatchLabels: map[string]string{"app": cluster.Name},
            },
            Template: corev1.PodTemplateSpec{
                ObjectMeta: metav1.ObjectMeta{
                    Labels: map[string]string{"app": cluster.Name},
                },
                Spec: corev1.PodSpec{
                    Containers: []corev1.Container{
                        {
                            Name:  "main",
                            Image: "nginx:latest",
                        },
                    },
                },
            },
        },
    }
}

func (r *MyClusterReconciler) SetupWithManager(mgr ctrl.Manager) error {
    return ctrl.NewControllerManagedBy(mgr).
        For(&MyCluster{}).
        Owns(&appsv1.Deployment{}).
        Complete(r)
}

示例代码 - REST API端点(使用Gin):

package main

import (
    "net/http"
    "github.com/gin-gonic/gin"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/clientcmd"
)

type ClusterAPI struct {
    k8sClient *kubernetes.Clientset
}

func NewClusterAPI() (*ClusterAPI, error) {
    config, err := clientcmd.BuildConfigFromFlags("", "/path/to/kubeconfig")
    if err != nil {
        return nil, err
    }
    
    clientSet, err := kubernetes.NewForConfig(config)
    if err != nil {
        return nil, err
    }
    
    return &ClusterAPI{k8sClient: clientSet}, nil
}

func (api *ClusterAPI) GetClusters(c *gin.Context) {
    // 从IONOS云API获取集群列表
    clusters := []map[string]interface{}{
        {"id": "cluster-1", "status": "running", "nodes": 3},
        {"id": "cluster-2", "status": "provisioning", "nodes": 0},
    }
    
    c.JSON(http.StatusOK, gin.H{
        "clusters": clusters,
        "count":    len(clusters),
    })
}

func (api *ClusterAPI) CreateCluster(c *gin.Context) {
    var request struct {
        Name     string `json:"name" binding:"required"`
        Region   string `json:"region" binding:"required"`
        NodeType string `json:"node_type"`
    }
    
    if err := c.ShouldBindJSON(&request); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    
    // 调用IONOS云API创建集群
    // 这里应该是实际的云API调用
    
    c.JSON(http.StatusCreated, gin.H{
        "id":     "new-cluster-id",
        "status": "provisioning",
        "name":   request.Name,
    })
}

func main() {
    api, err := NewClusterAPI()
    if err != nil {
        panic(err)
    }
    
    router := gin.Default()
    
    router.GET("/api/v1/clusters", api.GetClusters)
    router.POST("/api/v1/clusters", api.CreateCluster)
    
    router.Run(":8080")
}

示例代码 - Helm Chart模板片段:

# values.yaml
replicaCount: 3
image:
  repository: nginx
  tag: latest
  pullPolicy: IfNotPresent

resources:
  limits:
    cpu: 200m
    memory: 256Mi
  requests:
    cpu: 100m
    memory: 128Mi

autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 10
  targetCPUUtilizationPercentage: 80

# deployment.yaml模板
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "ionos-operator.fullname" . }}
  labels:
    {{- include "ionos-operator.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "ionos-operator.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "ionos-operator.selectorLabels" . | nindent 8 }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}

这个职位需要熟练掌握Kubernetes Operator模式、Golang并发编程、云API集成和完整的CI/CD流水线。代码示例展示了Operator的基本结构、REST API实现和Helm Chart配置,这些都是该职位日常工作的核心内容。

回到顶部