控制论乐团。 云中具有.NET Core应用程序的Docker容器编排

为了确保负载平衡,可伸缩性并提高容错能力,可以使用辅助工具-编排器。 其中,Kubernetes服务现在非常受欢迎。 在实践中尝试最简单的方法是将其部署在云中,我们今天将这样做。



注意:我们将继续阅读Hacker杂志的文章的完整版本系列。 作者的拼写和标点符号得以保存。


展开AKS


我们转到Azure门户 ,单击“创建资源”,然后找到名为Kubernetes Service的服务。


选择名称并根据您的喜好添加DNS前缀。 名称会影响您访问群集的方式,但前缀会影响其FQDN地址。



目前,最便宜的虚拟机每月的费用仅为30美元。


第二步是创建服务主体。 服务主体是一种服务帐户,可以在其中执行某些特定任务。 优点是可以限制该帐户的权限。 此外,您可以创建任意数量的此类帐户(而普通帐户的数量受订阅限制)。 您可以在Active Directory中的“应用程序注册”中找到创建的服务主体帐户。



RBAC(基于角色的访问控制)是限制或提供对特定资源(或资源组)的访问的能力。 也就是说,您可以区分您的订阅中的哪些用户具有访问权限,哪些没有。



目前,此过程大约需要20分钟,但所有过程都可能取决于配置。


通过以下链接查找官方指南
使用门户创建AKS集群
使用CLI创建AKS集群


要工作,我们需要Azure命令行-CLI(命令行界面)。 它既可以安装在Windows下,也可以安装在macOS或Linux下。 就个人而言,我更喜欢使用Azure Cloud Shell。 这是从加载到浏览器的Azure门户页面运行的命令行。 要工作,它需要创建的Blob存储。 它的成本是每月几美分,因此我不想担心在汽车上安装CLI。


Kubernetes支持多种容器技术,但让我们看一下最受欢迎的容器技术-Docker。 docker.hub允许免费存储一个私有docker映像。 如果您需要更多,可以将它们放在钱上。 但是为了赚钱,可以将私有docker映像放置在Azure容器注册表中。 现在价格从每月5美元起(基本SKU)。


我创建了一个名为myservice的ACR服务。 如果您还决定使用ACR,则在创建服务时将需要获取其密钥。



然后,可以通过运行以下命令登录:


docker login myservice.azurecr.io 

输入从门户获取的用户名(myservice)和密码(PJSeyO9 = lCMRDI7dGkz68wjhFGRGxSY3)


现在,通过转到该项目的目录,可以在使用所需标签标记图像的同时构建图像。 然后将其发送到云服务:


 docker build -t myservice.azurecr.io/myservice . docker push myservice.azurecr.io/myservice 

机密,机密...我们提供对图像的访问并保存设置。


使用已部署的AKS时,您需要获得他的荣誉。 否则,kubectl命令将不会执行。 要访问AKS,执行以下命令:


 az aks get-credentials --resource-group KubernetesGroup --name verycoolcluster 

为了访问私有容器中位于docker存储库中的docker映像,您需要创建一个密钥。 如果您有公开的图片,则可以跳过此步骤。


要创建机密文件,必须运行以下格式的命令:


 kubectl create secret docker-registry regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email> 

如果您的映像位于docker存储库中,则<your-registry-server>的值为https://index.docker.io/v1/


对于Azure容器注册表,FQDN将为<registry-name> .azurecr.io


也就是说,要为我的容器创建一个秘密,我做了:


 kubectl create secret docker-registry regcred --docker-server="myservice.azurecr.io" --docker-username="myservice" --docker-password="PJSeyO9=lCMRDI7dGkz68wjhFGRGxSY3" --docker-email="asommer@yandex.ru" 

现在,您可以使用以下命令查看创建的机密文件的内容:


 kubectl get secret regcred --output=yaml 

资讯


如果使用AKS,则不能创建机密文件,而可以通过执行特殊脚本以另一种方式向AKS服务提供对ACR服务的访问。 您可以从以下页面获取它:


通过Azure Kubernetes Service使用Azure容器注册表进行身份验证


 #!/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 

您可以简单地修改AKS *和ACR *变量的值,然后复制脚本并将其粘贴到Azure CLI或Cloud Shell中。


Kubernetes包含一个安全的凭证存储。 也就是说,您可以使用设置创建文件,并且很难从外部访问这些设置。 该文件通常包含数据库连接字符串和某种信用。 如果应用程序中没有此类信息(是吗?),则可以跳过此步骤。


为了从命令行创建设置文件,我们首先需要考虑vi命令。


 vi < > 

如果文件丢失或打开现有文件,将创建一个文件


为了保存输入的更改,请按ESC,然后按ZZ


为了简单退出而不保存ESC,请执行以下操作:q!


一个非常简短的描述,但是足够了。 我可以补充一点,Insert键非常有用。


因此,通过Azure Cloud Shell,创建一个具有任意名称(例如appsettings.json)和所需内容的文件。 让我们承认这样的:


 { "ConnectionString": "some secret string goes there" } 

在执行命令之后:


 kubectl create secret generic secret-appsettings --from-file=/home/youraccount/appsettings.json 

此命令将使用称为secret-appsettings的设置创建一个秘密
您可以使用pwd命令找出替换/ home / youraccount的路径


创建部署


部署是针对无状态服务的。 它们描述了如何创建Pods和ReplicaSet,以及如何更新它们。 Pod是在相同环境中工作的一组容器(或单个容器)。 ReplicaSet的目的是控制指定数量的Pod将被启动并持续工作。
基于先前创建的内容,我创建了一个deploy.yaml文件,该文件将创建3个子目录。 该文件包含以下代码(我提醒您yaml中的空格非常重要):


 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 

考虑代码。 开头描述了副本数和更新策略。 然后,为部署指定名称(myapp),并指示对容器映像的引用。 端口已注册。 80是http的标准端口。 接下来是ASP.NET Core环境设置。 然后安装私有docker映像的信誉和我们最近创建的秘密应用程序设置。


  strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 

这一部分负责升级过程。 maxSurge-更新时创建的炉膛数量超出现有炉膛数量(以单位或百分比为单位)。 maxUnavailable-在更新过程中可能无法使用的炉床的最大数量。
可以使用以下命令创建部署:


 kubectl apply -f deploy.yaml 

认识入口


为了提供对群集服务的访问并组织负载平衡,使用了称为入口的服务。 一个比较流行的解决方案是基于nginx的入口。 安装它的最简单方法是使用称为helm的Kubernetes软件包管理器。 Azure Cloud Shell的优势在于已经在其中安装了头盔。 要安装nginx-ingress,还需要做些什么。 输入:


 helm init 

等一下然后执行:


 helm install stable/nginx-ingress --namespace kube-system --set rbac.create=false 

使用LetsEncrypt创建SSL证书


由于SSL证书绑定到某些域名,因此我们将设置DNS资源名称。


运行以下命令并获取外部IP


 kubectl get service -l app=nginx-ingress --namespace kube-system 

在以下脚本中用IP和我们为子域发明的名称


 #!/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 

我们只需复制此脚本,然后将其粘贴到命令行中并以这种方式执行即可。 作为子域的名称,我设置了一个非常“原始”的名称-myservice-ingress


通过将以下脚本复制并粘贴到命令行中,以相同的方式安装证书管理器。 在这里,甚至没有什么特别的需要改变。


 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 

资讯


如果我们有一个带有RBAC的集群,那么脚本将有所不同。


 helm install stable/cert-manager --set ingressShim.defaultIssuerName=letsencrypt-staging --set ingressShim.defaultIssuerKind=ClusterIssuer 

如果证书文件可用,则可以将其添加如下:


 kubectl create secret tls tls-secret --cert CERT.crt --key KEY-FOR-CERT.key 

但是,由于我们没有签名的CA证书,因此我们必须用铃鼓跳舞一些。 我们将使用名为LetsEncrypt的免费服务创建一个CA。 LetsEncrypt是一个免费颁发证书的证书颁发机构。 这样一个无私的组织,其目标是保护Internet。


因此,创建cluster-issuer.yaml文件,其中描述了颁发证书的组织。


 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: {} 

您只需要用您的地址替换电子邮件,就可以:


 kubectl apply -f cluster-issuer.yaml 

然后,我们创建certificate.yaml证书文件,该文件指定创建的ClusterIssuer的名称以及该证书打算使用的域-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 

我们执行:


 kubectl apply -f certificate.yaml 

服务创建和入口


Kubernetes可以创建四种不同类型的服务。
默认服务是ClusterIP。 仅可以通过内部IP从群集访问此服务。


NodePort自动创建ClusterIP服务。 可以通过以下途径从外部访问NodePort:

通过LoadBalancer负载平衡器可以从外部访问服务,从而自动创建NodePort和ClusterIP服务。


ExternalName将服务与外部名称关联。


基本服务足以满足我们的需求:


 apiVersion: v1 kind: Service metadata: name: myservice spec: type: ClusterIP ports: - port: 80 name: http targetPort: http selector: app: myapp 

使用选择器的值,我们指示部署的名称。
剩下的就是创建服务


 kubectl apply -f service.yaml 

最后,我们创建一个入口,在本文中我已经向您介绍了一点。 在yaml中,我们将指定cluster-issuer的名称和证书。 我们之前创建了它们。


 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 

使用相同的kubectl apply命令创建入口后的一段时间,我们的微服务应可在https://myservice-ingress.westeurope.cloudapp.azure.com上使用 。 通过单击浏览器地址栏上https旁边的锁,可以验证证书是否有效并由CA颁发。




我们提醒您,这是《黑客》杂志上文章的完整版。 它的作者是阿列克谢·索默Alexey Sommer)

Source: https://habr.com/ru/post/zh-CN435870/


All Articles