DéveloppeurWeb.Com
    DéveloppeurWeb.Com
    • Agile Zone
    • AI Zone
    • Cloud Zone
    • Database Zone
    • DevOps Zone
    • Integration Zone
    • Web Dev Zone
    DéveloppeurWeb.Com
    Home»Cloud Zone»Écrivez votre infrastructure Kubernetes en tant que code Go – Combinez CDK8 avec AWS CDK
    Cloud Zone

    Écrivez votre infrastructure Kubernetes en tant que code Go – Combinez CDK8 avec AWS CDK

    novembre 22, 2022
    Écrivez votre infrastructure Kubernetes en tant que code Go - Combinez CDK8 avec AWS CDK
    Share
    Facebook Twitter Pinterest Reddit WhatsApp Email

    Dans un article de blog précédent, vous avez vu comment utiliser cdk8s avec AWS Controllers for Kubernetes (également connu sous le nom ACK), grâce au fait que vous pouvez importer des définitions de ressources personnalisées Kubernetes existantes à l’aide de cdk8s! Cela a permis de déployer DynamoDB avec une application cliente, en utilisant cdk8s et Kubernetes.

    Mais que se passe-t-il si vous continuez à utiliser AWS CDK pour l’infrastructure AWS et exploitez la puissance cdk8s (et cdk8s-plus!) pour définir les ressources Kubernetes à l’aide de code normal ? Grâce à l’intégration native entre le module AWS EKS et cdk8s, vous pouvez avoir le meilleur des deux mondes !

    Le but de cet article de blog est de le démontrer avec quelques exemples. Nous commencerons par un exemple simple (basé sur nginx) avant de passer à une pile d’applications complète (y compris DynamoDB etc.). Les deux utiliseront le langage de programmation Go qui est bien pris en charge dans AWS CDK ainsi que dans cdk8s.

    Tout le code discuté dans ce blog est disponible dans ce dépôt GitHub

    Conditions préalables

    Pour suivre étape par étape, en plus d’un compte AWS, vous aurez besoin des CLI suivantes : AWS CLI, cdk8s CLI et kubectl. N’oubliez pas non plus d’installer AWS CDK, le langage de programmation Go (v1.16 ou supérieur) ainsi que Docker, si vous ne les avez pas déjà.

    Rester simple avec Nginx sur EKS

    Comme pour la plupart des choses dans la vie, il y a deux manières – la manière facile ou la manière difficile 😉 Vous verrez les deux ! Essayons d’abord les choses, voyons-les fonctionner, puis regardons le code.

    Pour commencer, clonez le référentiel et accédez au bon répertoire :

    git clone https://github.com/abhirockzz/cdk8s-for-go-developers
    cd cdk8s-for-go-developers/part6-cdk-eks-cdk8s/cdk-cdk8s-nginx-eks

    Pour tout configurer, il vous suffit d’une seule commande :

    vous pouvez aussi utiliser cdk synth pour générer et inspecter le modèle Cloud Formation en premier

    Vous serez invité à confirmer. Une fois que vous aurez fait cela, le processus démarrera – cela prendra un certain temps car de nombreuses ressources AWS seront créées, y compris VPC, cluster EKS, etc.

    N’hésitez pas à consulter la console AWS Cloud Formation pour suivre la progression.

    Une fois le processus terminé, vous devez vous connecter au cluster EKS à l’aide de kubectl. La commande requise pour cela sera disponible à la suite de la cdk deploy processus (dans le terminal) ou vous pouvez vous référer au Les sorties section de la pile AWS Cloud Formation.

    Sortie AWS CloudFormation

    Une fois que vous avez configuré kubectl pour pointer vers votre cluster EKS, vous pouvez vérifier le Nginx Deployment et Service.

    kubectl get deployment
    
    # output
    
    NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment-cdk8s        1/1     1            1           1m
    nginx-deployment-cdk          1/1     1            1           1m

    Vous verrez que deux Deployments ont été créés – plus à ce sujet bientôt. De même, si vous cochez la case Service (kubectl get svc), vous devriez en voir deux – nginx-service-cdk et nginx-service-cdk8s.

    Pour accéder à Nginx, sélectionnez EXTERNAL-IP de l’un des deux Services. Par exemple:

    APP_URL=$(kubectl get service/nginx-service-cdk -o jsonpath="{.status.loadBalancer.ingress[0].hostname}")
    
    echo $APP_URL
    
    # to access nginx (notice we are using port 9090)
    curl -i http://$APP_URL:9090

    Si vous obtenez un Could not resolve host erreur lors de l’accès à l’URL LB, attendez environ une minute et réessayez

    Dans les coulisses

    Regardons le code maintenant – cela clarifiera pourquoi nous avons deux Nginx Deployments.

    Grâce à AWS CDK, la création de VPC est une ligne avec la fonction awsec2.NewVpc et la création d’un cluster EKS n’est pas trop difficile non plus !

    func NewNginxOnEKSStack(scope constructs.Construct, id string, props *CdkStackProps) awscdk.Stack {
      //...
      vpc := awsec2.NewVpc(stack, jsii.String("demo-vpc"), nil)
    
        eksSecurityGroup := awsec2.NewSecurityGroup(stack, jsii.String("eks-demo-sg"),
            &awsec2.SecurityGroupProps{
                Vpc:               vpc,
                SecurityGroupName: jsii.String("eks-demo-sg"),
                AllowAllOutbound:  jsii.Bool(true)})
    
        eksCluster := awseks.NewCluster(stack, jsii.String("demo-eks"),
            &awseks.ClusterProps{
                ClusterName:   jsii.String("demo-eks-cluster"),
                Version:       awseks.KubernetesVersion_V1_21(),
                Vpc:           vpc,
                SecurityGroup: eksSecurityGroup,
                VpcSubnets: &[]*awsec2.SubnetSelection{
                    {Subnets: vpc.PrivateSubnets()}},
                DefaultCapacity:         jsii.Number(2),
                DefaultCapacityInstance: awsec2.InstanceType_Of(awsec2.InstanceClass_BURSTABLE3, awsec2.InstanceSize_SMALL), DefaultCapacityType: awseks.DefaultCapacityType_NODEGROUP,
                OutputConfigCommand: jsii.Bool(true),
                EndpointAccess:      awseks.EndpointAccess_PUBLIC()})
    //...

    Nginx sur Kubernetes, à la dure !

    Nous examinons maintenant deux manières différentes de créer Nginx, en commençant par la manière « difficile ». Dans ce cas, nous utilisons AWS CDK (ne pas cdk8s) pour définir la Deployment et Service Ressources.

    func deployNginxUsingCDK(eksCluster awseks.Cluster) {
    
        appLabel := map[string]*string{
            "app": jsii.String("nginx-eks-cdk"),
        }
    
        deployment := map[string]interface{}{
            "apiVersion": jsii.String("apps/v1"),
            "kind":       jsii.String("Deployment"),
            "metadata": map[string]*string{
                "name": jsii.String("nginx-deployment-cdk"),
            },
            "spec": map[string]interface{}{
                "replicas": jsii.Number(1),
                "selector": map[string]map[string]*string{
                    "matchLabels": appLabel,
                },
                "template": map[string]interface{}{
                    "metadata": map[string]map[string]*string{
                        "labels": appLabel,
                    },
                    "spec": map[string][]map[string]interface{}{
                        "containers": {
                            {
                                "name":  jsii.String("nginx"),
                                "image": jsii.String("nginx"),
                                "ports": []map[string]*float64{
                                    {
                                        "containerPort": jsii.Number(80),
                                    },
                                },
                            },
                        },
                    },
                },
            },
        }
    
        service := map[string]interface{}{
            "apiVersion": jsii.String("v1"),
            "kind":       jsii.String("Service"),
            "metadata": map[string]*string{
                "name": jsii.String("nginx-service-cdk"),
            },
            "spec": map[string]interface{}{
                "type": jsii.String("LoadBalancer"),
                "ports": []map[string]*float64{
                    {
                        "port":       jsii.Number(9090),
                        "targetPort": jsii.Number(80),
                    },
                },
                "selector": appLabel,
            },
        }
    
        eksCluster.AddManifest(jsii.String("app-deployment"), &service, &deployment)

    Enfin, pour le créer dans EKS, nous invoquons AddManifest (considérez-le comme l’équivalent programmatique de kubectl apply). Cela fonctionne, mais il y a quelques lacunes dans cette approche :

    • Nous ne sommes pas en mesure de récolter les bénéfices du Go qui est un fortement typé Langue. C’est parce que l’API est librement tapé, grâce à map[string]interface{} partout. Cela le rend très sujet aux erreurs (j’ai aussi fait quelques erreurs !)
    • La verbosité est également évidente. Il semble que nous écrivions YAML dans Go – pas trop d’amélioration !

    Existe-t-il un meilleur moyen ..?

    Regardons la deuxième fonction deployNginxUsingCDK8s – par le nom, il est évident que nous avons utilisé cdk8spas seulement CDK)

    func deployNginxUsingCDK8s(eksCluster awseks.Cluster) {
    
        app := cdk8s.NewApp(nil)
        eksCluster.AddCdk8sChart(jsii.String("nginx-eks-chart"), NewNginxChart(app, "nginx-cdk8s", nil), nil)
    }

    Cela semble « trop ​​facile » pour être vrai ! Mais c’est rendu possible grâce à l’interopérabilité entre CDK et cdk8s. Cela implique que vous pouvez utiliser définir Ressources Kubernetes utilisant cdk8s Charts et appliquez-les à un cluster EKS créé avec CDK (cela en fait une sorte de système hybride).

    Le héros de notre histoire est la fonction AddCdk8sChart, qui accepte une construction. Construire (rappelez-vous, tout est une construction !). Dans ce cas, le Construct se trouve être un cdk8s.Chart renvoyé par NewNginxChart fonction – alors jetons un coup d’œil à cela.

    func NewNginxChart(scope constructs.Construct, id string, props *MyChartProps) cdk8s.Chart {
      //....
    
        dep := cdk8splus22.NewDeployment(chart, jsii.String("nginx-deployment"),
            &cdk8splus22.DeploymentProps{
                Metadata: &cdk8s.ApiObjectMetadata{
                    Name: jsii.String("nginx-deployment-cdk8s")}})
    
        dep.AddContainer(&cdk8splus22.ContainerProps{
            Name:  jsii.String("nginx-container"),
            Image: jsii.String("nginx"),
            Port:  jsii.Number(80)})
    
        dep.ExposeViaService(&cdk8splus22.DeploymentExposeViaServiceOptions{
            Name:        jsii.String("nginx-service-cdk8s"),
            ServiceType: cdk8splus22.ServiceType_LOAD_BALANCER,
            Ports: &[]*cdk8splus22.ServicePort{{
                Port:       jsii.Number(9090),
                TargetPort: jsii.Number(80)}}})
    
        return chart
    }

    Si vous avez travaillé avec cdk8s (and Go) ou lisez certains de mes blogs précédents sur ce sujet, cela devrait vous sembler familier – une API fortement typée, compacte et expressive ! Je n’ai même pas besoin de vous expliquer cela car c’est tellement lisible – nous utilisons cdk8s-plus pour créer un Nginx Deploymentajoutez les informations sur le conteneur et enfin exposez-le via un Service afin que nous puissions accéder au Nginx depuis l’extérieur d’EKS.

    C’était un exemple assez simple pour aider à faire ressortir la différence entre les deux approches. Le scénario suivant est différent – en plus du cluster EKS, il a…

    Share. Facebook Twitter Pinterest LinkedIn WhatsApp Reddit Email
    Add A Comment

    Leave A Reply Cancel Reply

    Catégories

    • Politique de cookies
    • Politique de confidentialité
    • CONTACT
    • Politique du DMCA
    • CONDITIONS D’UTILISATION
    • Avertissement
    © 2023 DéveloppeurWeb.Com.

    Type above and press Enter to search. Press Esc to cancel.