Pour assurer l'équilibrage de charge, l'évolutivité et augmenter la tolérance aux pannes, des outils auxiliaires peuvent être utilisés - les orchestrateurs. Parmi eux, le service Kubernetes est désormais très populaire. Le moyen le plus simple de l'essayer dans la pratique est de le déployer dans le cloud, ce que nous ferons aujourd'hui.

Remarque: nous continuons la série de publications de versions complètes d'articles du magazine Hacker. Orthographe et ponctuation de l'auteur enregistrées.
Développez AKS
Nous allons sur le portail Azure , cliquez sur "Créer une ressource" et trouvons un service appelé Service Kubernetes.
Choisissez le nom et le préfixe DNS à votre goût. Le nom affecte la façon dont vous allez accéder à votre cluster, mais le préfixe affecte son adresse FQDN.

La machine virtuelle la moins chère coûte actuellement un peu plus de 30 $ par mois.
La deuxième étape consiste à créer un principal de service. Le principal de service est une sorte de compte de service sous lequel certaines tâches spécifiques peuvent être effectuées. L'avantage est que les droits d'un tel compte peuvent être limités. De plus, vous pouvez créer n'importe quel nombre de ces comptes (alors que le nombre de comptes réguliers est limité par abonnement). Vous pouvez trouver les comptes principaux de service créés dans Active Directory parmi les enregistrements d'applications.

RBAC (contrôle d'accès basé sur les rôles) est la capacité de restreindre ou de fournir l'accès à des ressources spécifiques (ou groupes de ressources). Autrement dit, vous pouvez distinguer les utilisateurs de votre abonnement qui ont des droits d'accès et ceux qui n'en ont pas.

Pour le moment, le processus prend environ 20 minutes, mais tout peut dépendre de la configuration.
Retrouvez les guides officiels en suivant les liens
Créer un cluster AKS à l'aide du portail
Création d'un cluster AKS à l'aide de la CLI
Pour fonctionner, nous avons besoin de la ligne de commande Azure - CLI (Command Line Interface). Il peut être installé à la fois sous Windows et sous macOS ou Linux. Personnellement, je préfère utiliser Azure Cloud Shell. Il s'agit de la ligne de commande qui s'exécute à partir de la page du portail Azure chargée dans le navigateur. Pour fonctionner, il nécessite le stockage d'objets blob créé. Son coût sera de quelques centimes par mois et je préfère donc ne pas me soucier d'installer CLI sur ma voiture.
Kubernetes prend en charge diverses technologies de conteneurs, mais regardons la plus populaire - Docker. docker.hub vous permet de stocker gratuitement une image de docker privé. Si vous en avez besoin de plus, vous pouvez les placer pour de l'argent. Mais pour de l'argent, une image de docker privé peut être placée dans le Registre de conteneurs Azure. Maintenant, les prix commencent à 5 $ par mois (pour SKU de base).
J'ai créé un service ACR sous le nom myservice. Si vous décidez également d'utiliser ACR, la création d'un service vous permettra d'obtenir ses clés.

Il sera alors possible de se connecter en exécutant la commande:
docker login myservice.azurecr.io
Entrez le nom d'utilisateur (myservice) et le mot de passe extraits du portail (PJSeyO9 = lCMRDI7dGkz68wjhFGRGxSY3)
Maintenant, en allant dans le répertoire avec le projet, il sera possible de construire une image tout en la marquant avec la balise souhaitée. Et après cela, envoyez-le au service cloud:
docker build -t myservice.azurecr.io/myservice . docker push myservice.azurecr.io/myservice
Secrets, secrets ... Nous fournissons l'accès à l'image et enregistrons les paramètres.
Lorsque vous travaillez avec AKS déployé, vous devez obtenir ses crédits. Sinon, les commandes kubectl ne s'exécuteront pas. Pour accéder à AKS, la commande suivante est exécutée:
az aks get-credentials --resource-group KubernetesGroup --name verycoolcluster
Afin d'accéder à l'image de docker située dans le référentiel de docker dans un conteneur privé, vous devez créer un secret. Si vous avez une image publique, vous pouvez ignorer cette étape.
Pour créer un fichier secret, vous devez exécuter une commande du formulaire suivant:
kubectl create secret docker-registry regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
Si votre image se trouve dans le référentiel docker, la valeur de <votre-serveur-de-gistrature> sera https://index.docker.io/v1/
Pour Azure Container Registry, le nom de domaine complet sera <registry-name> .azurecr.io
Autrement dit, pour créer un secret pour le conteneur dans mon cas, j'ai fait:
kubectl create secret docker-registry regcred --docker-server="myservice.azurecr.io" --docker-username="myservice" --docker-password="PJSeyO9=lCMRDI7dGkz68wjhFGRGxSY3" --docker-email="asommer@yandex.ru"
Vous pouvez maintenant afficher le contenu du fichier secret créé à l'aide de la commande:
kubectl get secret regcred --output=yaml
INFO
Si vous utilisez AKS, vous ne pouvez pas créer un fichier secret, mais fournir un accès au service ACR au service AKS d'une autre manière - en exécutant un script spécial. Vous pouvez le prendre à partir de la page suivante:
Authentifier avec Azure Container Registry à partir du service Azure Kubernetes
#!/bin/bash AKS_RESOURCE_GROUP=KubernetesGroup AKS_CLUSTER_NAME=verycoolcluster ACR_RESOURCE_GROUP=MyACRGroup ACR_NAME=myservice # Get the id of the service principal configured for AKS CLIENT_ID=$(az aks show --resource-group $AKS_RESOURCE_GROUP --name $AKS_CLUSTER_NAME --query "servicePrincipalProfile.clientId" --output tsv) # Get the ACR registry resource id ACR_ID=$(az acr show --name $ACR_NAME --resource-group $ACR_RESOURCE_GROUP --query "id" --output tsv) # Create role assignment az role assignment create --assignee $CLIENT_ID --role Reader --scope $ACR_ID
Vous pouvez simplement modifier les valeurs des variables AKS * et ACR *, puis copier le script et le coller dans Azure CLI ou Cloud Shell.
Kubernetes contient un magasin d'informations d'identification sécurisé. Autrement dit, vous pouvez créer un fichier avec les paramètres et l'accès à ces paramètres de l'extérieur sera difficile. Ce fichier contient généralement des chaînes de connexion à la base de données et une sorte de crédits. Si vous ne disposez pas de telles informations dans l'application (est-ce vrai?), Vous pouvez ignorer cette étape.
Afin de créer un fichier de paramètres à partir de la ligne de commande, nous devons d'abord considérer la commande vi.
vi < >
créera un fichier s'il est manquant ou ouvre un fichier existant
Pour enregistrer les modifications saisies, appuyez sur ESC puis sur ZZ
Pour quitter simplement sans enregistrer ESC et après: q!
Une très courte description, mais cela devrait suffire. Je peux ajouter que la touche d'insertion peut être très utile.
Ainsi, via Azure Cloud Shell, créez un fichier avec un nom arbitraire (par exemple, appsettings.json) et le contenu dont vous avez besoin. Admettons un tel:
{ "ConnectionString": "some secret string goes there" }
Et après avoir exécuté la commande:
kubectl create secret generic secret-appsettings --from-file=/home/youraccount/appsettings.json
Cette commande créera un secret avec des paramètres appelés secret-appsettings
Vous pouvez savoir par quel chemin remplacer / home / youraccount avec la commande pwd
Créer un déploiement
Les déploiements concernent les services sans état. Ils décrivent comment les Pods et ReplicaSets seront créés et comment ils seront mis à jour. Pod est un groupe de conteneurs (ou un seul conteneur) qui fonctionnent dans le même environnement. Le but de ReplicaSet est de contrôler que le nombre spécifié de pods sera lancé et fonctionnera en permanence.
Sur la base de la création précédente, je crée un fichier deploy.yaml qui créera 3 sous. Le fichier contient le code suivant (je vous rappelle que les espaces dans yaml sont très importants):
apiVersion: apps/v1beta1 kind: Deployment metadata: name: mydeployment spec: replicas: 3 minReadySeconds: 10 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 template: metadata: labels: app: myapp spec: containers: - name: app image: myservice.azurecr.io/myservice:latest ports: - containerPort: 80 name: http protocol: TCP imagePullPolicy: Always env: - name: "ASPNETCORE_ENVIRONMENT" value: "Production" volumeMounts: - name: secrets mountPath: /app/secrets readOnly: true imagePullSecrets: - name: regcred volumes: - name: secrets secret: secretName: secret-appsettings
Considérez le code. Le début décrit le nombre de répliques et la stratégie de mise à jour. Ensuite, le déploiement reçoit un nom (myapp) et une référence à l'image du conteneur est indiquée. Les ports sont enregistrés. 80 est le port standard pour http. Viennent ensuite les paramètres d'environnement ASP.NET Core. Ensuite, les crédits de l'image de docker privé et les paramètres d'application secrets que nous avons récemment créés ont été montés.
strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1
Cette pièce est responsable du processus de mise à niveau. maxSurge - le nombre de foyers créés en plus de ceux existants lors de la mise à jour (en unités ou en pourcentage). maxUnavailable - le nombre maximum de foyers qui peuvent devenir indisponibles pendant le processus de mise à jour.
le déploiement peut être créé à l'aide de la commande:
kubectl apply -f deploy.yaml
Rencontrez Ingress
Afin de fournir un accès aux services de cluster et d'organiser l'équilibrage de charge, un service appelé entrée est utilisé. Une solution assez populaire est l'entrée basée sur nginx. La façon la plus simple de l'installer est d'utiliser le gestionnaire de packages Kubernetes appelé helm. L'avantage d'Azure Cloud Shell est que Helm y est déjà installé. Ce qui reste à faire pour installer nginx-ingress. Entrez:
helm init
Attendez un peu et exécutez:
helm install stable/nginx-ingress --namespace kube-system --set rbac.create=false
Création de certificats SSL avec LetsEncrypt
Étant donné que le certificat SSL est lié à un nom de domaine, nous définirons notre nom de ressource DNS.
Exécutez la commande suivante et prenez l'IP externe
kubectl get service -l app=nginx-ingress --namespace kube-system
IP de substitution et nom que nous avons inventé pour le sous-domaine dans le script suivant
#!/bin/bash # Public IP address of your ingress controller IP="168.63.19.2" # Name to associate with public IP address DNSNAME="myservice-ingress" # Get the resource-id of the public ip PUBLICIPID=$(az network public-ip list --query "[?ipAddress!=null]|[?contains(ipAddress, '$IP')].[id]" --output tsv) # Update public ip address with DNS name az network public-ip update --ids $PUBLICIPID --dns-name $DNSNAME
Nous copions simplement ce script, le collons dans la ligne de commande et l'exécutons de cette manière. Comme nom pour le sous-domaine, j'ai défini un nom très "original" - myservice-ingress
Installez le gestionnaire de certificats de la même manière en copiant et collant le script suivant dans la ligne de commande. Ici, même rien de spécial n'a besoin d'être changé.
helm install \ --name cert-manager \ --namespace kube-system \ stable/cert-manager \ --set ingressShim.defaultIssuerName=letsencrypt-prod \ --set ingressShim.defaultIssuerKind=ClusterIssuer \ --set rbac.create=false \ --set serviceAccount.create=false
INFO
Si nous avions un cluster avec RBAC, le script serait différent.
helm install stable/cert-manager --set ingressShim.defaultIssuerName=letsencrypt-staging --set ingressShim.defaultIssuerKind=ClusterIssuer
Si le fichier de certificat est disponible, vous pouvez l'ajouter quelque chose comme ceci:
kubectl create secret tls tls-secret --cert CERT.crt --key KEY-FOR-CERT.key
Mais comme nous n'avons pas de certificat CA signé, nous devrons danser un peu avec un tambourin. Nous allons créer une autorité de certification en utilisant un service gratuit appelé LetsEncrypt . LetsEncrypt est une autorité de certification qui émet des certificats gratuitement. Une telle organisation altruiste, dont le but est de sécuriser Internet.
Créez donc le fichier cluster-issuer.yaml qui décrit l'organisation qui a émis le certificat.
apiVersion: certmanager.k8s.io/v1alpha1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: youeemail@yourdomain.ru privateKeySecretRef: name: letsencrypt-prod http01: {}
Il vous suffit de remplacer l'e-mail par votre adresse et vous pouvez faire:
kubectl apply -f cluster-issuer.yaml
Ensuite, nous créons le fichier de certificat certificate.yaml en spécifiant le nom du ClusterIssuer créé et le domaine auquel le certificat est destiné - myservice-ingress.westeurope.cloudapp.azure.com
apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: tls-prod-secret spec: secretName: tls-prod-secret dnsNames: - myservice-ingress.westeurope.cloudapp.azure.com acme: config: - http01: ingressClass: nginx domains: - myservice-ingress.westeurope.cloudapp.azure.com issuerRef: name: letsencrypt-prod kind: ClusterIssuer
Nous réalisons:
kubectl apply -f certificate.yaml
Création de service et entrée
Kubernetes peut créer quatre types de services différents.
Le service par défaut est ClusterIP. L'accès à ce service n'est possible qu'à partir du cluster via IP interne.
NodePort crée automatiquement le service ClusterIP. L'accès à NodePort est possible en externe par la route suivante:
L'équilibreur de charge LoadBalancer permet d'accéder au service de l'extérieur, créant automatiquement des services NodePort et ClusterIP.
ExternalName associe le service à un nom externe.
Le service de base nous suffit:
apiVersion: v1 kind: Service metadata: name: myservice spec: type: ClusterIP ports: - port: 80 name: http targetPort: http selector: app: myapp
Avec la valeur du sélecteur nous indiquons le nom de notre déploiement.
Reste à créer un service
kubectl apply -f service.yaml
Et comme étape finale, nous créons une entrée avec laquelle je vous ai déjà présenté un peu plus haut dans cet article. Dans yaml, nous spécifierons le nom de l'émetteur du cluster et le certificat. Nous les avons créés plus tôt.
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: myingress annotations: kubernetes.io/ingress.class: nginx certmanager.k8s.io/cluster-issuer: letsencrypt-prod nginx.ingress.kubernetes.io/rewrite-target: / spec: tls: - hosts: - myservice-ingress.westeurope.cloudapp.azure.com secretName: tls-prod-secret rules: - host: myservice-ingress.westeurope.cloudapp.azure.com http: paths: - path: / backend: serviceName: myservice servicePort: 80
Quelque temps après avoir créé l'entrée en utilisant la même commande kubectl apply, notre microservice devrait devenir disponible sur https: // myservice-ingress.westeurope.cloudapp.azure.com . En cliquant sur le verrou dans la barre d'adresse du navigateur à côté de https, vous pouvez vérifier que le certificat est valide et émis par CA.

Nous vous rappelons qu'il s'agit de la version complète d'un
article du magazine Hacker . Son auteur est
Alexey Sommer .