使用Azure Web应用程序,Azure PostgreSQL和Azure Kubernetes Service部署Web应用程序
#devops #云 #database #azure

我们将使用Azure Web应用程序,Azure PostgreSQL和Azure Kubernetes服务来构建,部署和管理Azure中的三层应用程序。三层应用程序基本上是一个具有显示层(前端),应用程序层(后端)和数据层(数据库)的应用程序。

目录

s 1. Prerequisites
2. Sample Application
3. Install Azure CLI and log in
4. Create resource group in azure
5. Deploy and run a containerized web app with Azure App Service
5.1。 Run Application Locally
5.2。 Create Dockerfile
3 .. Build Docker image and run Docker container
©it –4。 abiaooqian9
©5。 Create and deploy a web app from Azure Container Registry repository
6. Create PostgreSQL Database
到6.1。 abiaooqian12
6.2。 Create Database
- Connect to Database
- eward。 Get Connection String
7. Deploy Microservices using AKS
7.1。 ABIAOOQIAN17
7.2。 Get environment variables
7.3。 ABIAOOQIAN19
- 4。 abiaoqianqi20
7.5。 Configure API Gateway using Reverse Proxy
7.6。 Create Images
7.7。 Tag Container Images and Push to Registry
7.8。 Create a Kubernetes cluster
A.9。 Install the Kubernetes CLI
abiaooqiqi 7.10。 Connect to the cluster using kubectl
©7.11。 Create deployment and service manifest files and configure environment variables.
- 12欧元。 Abiaoqiqian28 in 7.13。 Expose Proxy endpoint and test application
8. Build Frontend container image
9. Test Application
10. Continuous Integration with Azure pipelines
11. Clean up resources

先决条件

  • Azure帐户和订阅。如果您没有帐户,则可以创建一个here。如果有一个Login到您的帐户。
  • 对微服务体系结构的基本理解。
  • 使用Docker命令存储和检索Docker Images的基本经验。
  • 对Kubernetes概念的基本理解。
  • 已安装了Docker桌面,或者您可以安装here
  • 安装Azure Data Studio。

样本应用

我们将部署用于验证用户银行帐号的应用程序。前端是由Vuejs和Expressjs的后端建造的。我们将将后端整体应用程序分为微服务体系结构。反向代理将用于将传入的请求路由到右微服务。

将对前端应用程序进行扩展,将其推入Azure容器注册表并使用Azure Web应用程序服务部署。后端应用程序将被停靠,将其推入Azure容器注册表并使用Azure Kubernetes服务部署。 Azure PostGressQL数据库将用于存储用户数据。

安装Azure CLI并登录

Azure CLI是连接到Azure并在Azure资源上执行管理命令的命令行工具。使用此link安装操作系统。

我正在使用macOS,所以我使用了命令:

brew update && brew install azure-cli

安装后,确认CLI通过在终端中运行az version成功安装。如果您获得了如下所示的版本,那么您现在可以运行Azure命令。

Install Azure CLI

登录通过运行命令
来验证您的帐户

az login

在Azure中创建资源组

要在Azure中创建任何资源,我们需要拥有一个资源组来持有解决方案的相关资源。您可以在Azure Portal或使用CLI中创建资源组。

在Azure Portal中,

  1. 搜索资源组
  2. 单击创建创建资源组按钮。
  3. 填写资源组名称,然后选择一个区域您希望在其中托管资源。 Create Azure Resource Group
  4. 单击评论 +创建按钮。然后,选择创建

使用Azure CLI,我们传递了资源组的名称和位置,如下所示。在终端中运行命令。

az group create --name sca-project --location eastus

使用Azure应用服务部署并运行一个容器化的Web应用程序

让我们首先部署并运行我们的前端应用程序。如果您想跟随,请克隆起始代码here

本地运行应用程序

要在本地运行,请使用npm install安装所有依赖项。创建一个 .env 文件,然后将 .env.sample 的内容复制到其中。在=之后添加申请后端base url值https://verify-account-api.onrender.com。然后,运行命令NPM运行服务。

创建Dockerfile

dockerfile是一个文件,其中包含指令和命令,这些指令和命令将自动运行以构建Docker映像。在项目的根部创建名为Dockerfile的文件,内容为:

# Stage 1: Build the Vue app
FROM node:16 as build-stage
WORKDIR /app
ARG VUE_APP_BASE_URL
ENV VUE_APP_BASE_URL $VUE_APP_BASE_URL
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Stage 2: Serve the Vue app using NGINX
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

此Dockerfile表示使用节点版本16. WorkDir用于定义容器的工作目录。它创建和更改目录,这是MKDIR和CD命令的组合。 ENV提供了应用程序所需的环境变量。封装文件已复制,安装依赖项,将文件从本地到docker容器复制,然后运行构建命令。使用Nginx提供该应用程序。我们将在端口80中公开应用程序。

构建Docker Image并运行Docker容器

打开Docker Desktop应用程序,该应用程序提供了构建和运行容器化应用程序的环境。在终端上,使用:
构建Docker映像

docker build -t <docker-image-name> .

<docker-image-name>替换为要给图像的名称。

Building Docker image

从图像创建一个容器,并使用以下方式运行容器:

docker run -it -p 8080:80 --rm --name <container-name> <docker-image-name>

<container-name><docker-image-name>替换为要给容器和Docker映像名称的名称。我们还使用-p 8080:80将容器端口发布至8080,并使用--rm标志自动卸下出口时的容器。在此处阅读有关Docker Run命令的更多信息。

http://localhost:8080/上查看申请。退出使用CTRL + C命令运行容器。

创建Azure容器注册表并推动Docker Image。

Azure容器注册表是一项服务,可让您在私人注册表中构建,存储和管理容器图像。像Docker Hub一样,容器注册表也使用包含一个或多个图像的存储库。

使用容器注册表的一个主要理由是因为它提供了更好的安全性。另外,由于它托管在Azure上,您可以将图像存储在将部署的位置附近存储。

您可以在Azure Portal上创建Azure容器注册表或使用Azure CLI。

在Azure Portal中,

  1. 搜索容器注册
  2. 单击创建创建容器注册表按钮。
  3. 选择资源组先前创建的。另外,填写注册表名称。将其他字段留为默认值。 Create Container Registry
  4. 单击评论 +创建按钮。然后,选择创建。

使用Azure CLI,我们通过资源名称资源组作为参数,如下所示。

az acr create --name <resource-name> --resource-group <resource-group-name> --sku standard --admin-enabled true

参数:

  • 资源名称:必须是字母数字,它是您的容器注册表的名称。
  • 资源组名称:使用先前创建的资源组名称。

托管前面创建的Docker映像,使用:

az acr build --registry <container_registry_name> --image <docker-image-name> .

用您先前创建的注册表的名称替换为<docker-image-name>,而<docker-image-name>则用前面创建的图像替换。

如果您想在Azure上构建Docker映像,请运行此命令。此命令将文件内容复制到容器注册表,然后使用DockerFile来构建图像并存储它。

az acr build --file Dockerfile --registry <container_registry_name> --image <new-docker-image-name> .

<container_registry_name>替换为您之前创建的注册表的名称,将<new-docker-image-name>作为将要创建的Docker Image的名称。

构建需要一段时间。完成后,通过选择存储库来查看容器注册表中的Docker映像。

View Container Registry

从Azure容器注册表存储库中创建和部署Web应用程序

要创建和部署Web应用程序,请按照以下步骤:

  1. 搜索 Web应用程序并选择。
  2. 基础上选项卡上,输入每个设置的以下值。一些领域被预先占领。确保确认它们是您想使用的。输入Web应用程序名称,该名称将为默认URL。对于发布,将其更改为Docker容器,因为我们将从容器中部署。我还将定价计划更新为免费计划。 Creating Azure Web App - Basics
  3. 选择接下来:docker
  4. docker 选项卡上,将图像源更改为Azure容器注册表。然后,确认注册表的详细信息。 Creating Azure Web App - Docker
  5. 选择审查并创建,然后选择创建。部署需要一段时间。
  6. 部署成功后,选择转到资源查看刚刚创建的Web应用程序。
  7. 在顶部菜单栏中,选择浏览以在新的浏览器选项卡中打开站点或复制URL。该网站可能需要一段时间才能显示。 Open Application from Web App Service
  8. 查看应用程序。 View application

创建PostgreSQL数据库

我们将创建一个PostgreSQL Server和数据库,以存储用户注册时的信息,并在登录过程中检索。

为PostgreSQL创建一个Azure数据库 - 灵活服务器

这可以在Azure Portal或使用CLI中创建。

在Azure Portal中,

  1. 搜索 azure数据库for Postgresql 并选择它。
  2. 单击在左卡上创建以创建数据库。 Creating Azure PostgreSQL Database
  3. 基础知识选项卡中,确保填写所有必需字段,如下所示。输入资源组和数据库服务器名称Creating Azure PostgreSQL Database - Flexible Server Basics 1 对于工作负载类型,请选择开发,因为我们将其用于个人项目。 Creating Azure PostgreSQL Database - Flexible Server Basics 2 设置用户名密码用于身份验证 Creating Azure PostgreSQL Database - Flexible Server Basics 3
  4. 网络选项卡中,允许公共访问权限,您还可以添加当前的IP地址。 Creating Azure PostgreSQL Database - Flexible Server Networking
  5. 选择审查并创建。然后,创建
  6. 部署后,转到资源

使用Azure CLI,我们可以使用此命令使用自定义参数创建PostgreSQL灵活服务器。

az postgres flexible-server create --location <location> --resource-group <resource-group> \
  --name <database-server-name> --admin-user <username> --admin-password <password> \
  --sku-name Standard_B1ms --tier Burstable --public-access all --storage-size 128 \
  --version 14

用正确的值替换<location><resource-group><database-server-name><username><password>

注意:数据库服务器名称应该是全球唯一的。

创建数据库

导航到数据库选项卡。选择添加按钮。填写数据库名称和保存

Create Database

连接到数据库

Open Azure Data Studio 应用程序。转到“扩展”选项卡,然后搜索 PostgreSQL

Installing postgresql extension.

如果遇到扩展程序问题,请检查此link

链接Azure帐户,并通过添加服务器和数据库名称连接到数据库。另外,添加您的身份验证详细信息。

Connecting to Azure Database

创建一个将由后端应用程序使用的用户表。

Create Users table

获取连接字符串

在Azure中,转到连接字符串选项卡。
Azure PostgreSQL Database connection strings

有几种连接的方法,但是我们将使用PostgreSQL连接URL,因为它适合我们将使用的应用程序。请注意,我们将用数据库名称verify-account替换靠近URL末端的Postgres。

使用AK部署微服务

在这里,我们将将后端应用程序分为微服务体系结构。然后,我们将扩展到应用程序,设置应用程序网关并部署在Kubernetes群集中。如果您想跟随,请克隆起始代码here

查看已部署的微服务应用程序代码here

重组整体应用在微服务体系结构中

当前项目包含 /用户和 /验证-Account端点的逻辑。我们将将API代码分解为可以独立运行的2种不同的服务。

创建两个名为用户的新目录(作为服务)和验证符合。删除package-lock.json文件。然后,将根目录的内容复制到两个文件夹中。文件夹目录应该看起来像这样。

New Microservice folder directory

浏览文件夹和文件,并删除与每个服务无关的代码。如果您陷入困境或不确定剩下的东西,请与代码here相比。

获取环境变量

对于DATABASE_URL,使用PostgreSQL连接URL并替换密码。要获取MAIL_USERNAMEMAIL_PASSWORDOAUTH_CLIENTIDOAUTH_CLIENT_SECRETOAUTH_REFRESH_TOKEN,请检查此guide,以了解如何为NodeMailer创建这些钥匙。如果您不想设置这些,则可以使用它来评论代码中的零件。 TOKEN_KEYRESET_TOKEN_KEY是用于哈希用户密码的随机字符串。创建一个PayStack帐户,添加业务并使用测试API Secret Key作为PAYSTACK_SECRET_KEYFRONTEND_BASE_URL也在电子邮件中使用,将用户路由返回前端应用程序。

本地运行代码

对于每个微服务,将目录更改为MicroService文件夹,然后运行npm install命令以安装所有项目依赖项。创建一个 .env 文件,然后复制 .env.sample 文件的内容。将值放在上面。运行npm startnpm run dev进行测试。

让我们测试注册用户端点http://localhost:8080/api/users/register

Register user endpoint

如果端点没有返回响应,则出了问题。尝试调试并解决问题。

设置Dockerfile

记住我们之前为前端应用程序创建的Dockerfile。我们将为微服务创建类似的。在Microservices Project目录中,创建一个名为Dockerfile的文件并粘贴此代码:

FROM node:14
# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
COPY package*.json ./
RUN npm install

# Bundle app source
COPY . .
EXPOSE 8080
CMD [ "npm", "start" ]

另外,创建一个.dockerignore文件并添加node_modules。

使用反向代理配置API网关

API Gateway用于确保请求路由到正确的服务。有几种方法可以做到。其中包括使用Azure API管理,Azure应用程序网关等,但我们将使用反向代理。

创建一个文件夹并将其命名为reverse-proxy。在其中创建一个Dockerfile并粘贴以下:

FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf

另外,创建一个nginx.conf文件并配置它。阅读有关其工作原理的here

worker_processes 1;  
events { worker_connections 1024; }
error_log /dev/stdout debug;
http {
    sendfile on;
    upstream user {
        server user:8080;
    }
    upstream verify-account {
        server verify-account:8080;
    }
    proxy_set_header   Host $host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-NginX-Proxy true;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Host $server_name;    
    server {
        listen 8080;
        location /api/verify-account {
            proxy_pass         http://verify-account;
        }
        location /api/users {
            proxy_pass         http://user;
        }            
    }
}

创建图像

要从不同的dockerfile构建多个图像,我们需要在项目root目录中创建一个docker-compose-build.yaml文件。

该文件包含到不同目录的路径,您还指定了图像名称。这就是docker-compose-build.yaml文件的外观。

version: "3"
services:
  reverseproxy:
    build:
      context: ./reverse-proxy
    image: reverseproxy
  verify_account:
    build:
      context: ./verify-account
    image: verify-account
  user:
    build:
      context: ./user
    image: user

然后运行此命令构建图像。

docker compose -f docker-compose-build.yaml build --parallel

要在容器中运行图像,创建一个docker-compose.yaml文件。

version: "3"
services:
  reverseproxy:
      image: reverseproxy
      ports:
          - 8080:8080
      restart: always
      depends_on:
        - user
        - verify-account
  user:
    image: user
    environment:
      DATABASE_URL: $DATABASE_URL
      MAIL_USERNAME: $MAIL_USERNAME
      MAIL_PASSWORD: $MAIL_PASSWORD
      OAUTH_CLIENTID: $OAUTH_CLIENTID
      OAUTH_CLIENT_SECRET: $OAUTH_CLIENT_SECRET
      OAUTH_REFRESH_TOKEN: $OAUTH_REFRESH_TOKEN
      TOKEN_KEY: $TOKEN_KEY
      RESET_TOKEN_KEY: $RESET_TOKEN_KEY
      PAYSTACK_SECRET_KEY: $PAYSTACK_SECRET_KEY
      FRONTEND_BASE_URL: $FRONTEND_BASE_URL
  verify-account:
    image: verify-account
    environment:
      TOKEN_KEY: $TOKEN_KEY
      RESET_TOKEN_KEY: $RESET_TOKEN_KEY

在根目录中创建一个.env文件并粘贴所有项目环境变量。使用docker compose config确认所有环境变量已设置。然后,使用此命令运行容器。

docker compose up

使用任何端点测试应用程序。它应该像以前一样工作。当您访问数据库并查询所有用户时,您应该看到添加了用户。

Send Request to Register Endpoint

Query Database

建立并推向注册表

登录到容器注册表以从本地计算机连接到Kubernetes群集。 <acrName>是容器注册表的名称,例如scacloudproject。

az acr login --name <acrName>

构建图像并使用acr build命令推向容器注册表。

az acr build --file Dockerfile --registry <container_registry_name> --image <new-docker-image-name> .

通过检查门户网站成功推动图像。

Container images

您也可以使用:
在CLI中查看

az acr repository list --name <acrName> --output table

创建一个kubernetes群集

您可以使用下面的命令来创建一个kubernetes群集。如果您没有所有者 Azure帐户管理员角色在您的Azure订阅中,请使用此guide创建具有基于角色的访问控制的Kubernetes群集。



az aks create \
    --resource-group <resource-group> \
    --name <aks-cluster-name> \
    --node-count 2 \
    --generate-ssh-keys \
    --attach-acr <acrName>

此命令需要一段时间才能运行。您也可以使用此guide在门户中创建它。

安装Kubernetes CLI

使用Kubernetes CLI,Kubectl,从本地计算机连接到Kubernetes群集。

az aks install-cli

使用kubectl连接到集群

连接到集群。

az aks get-credentials --resource-group <resource-group> --name <aks-cluster-name>

要验证与群集的连接,运行kubectl获取节点以返回群集节点的列表。

kubectl get nodes

List of nodes

创建部署和服务清单文件并配置环境变量。

清单文件通常是一个YAML文件,用于指定可以创建和更新一组相同pods的Kubernetes对象的配置。每个POD都运行特定的容器,这些容器是在YAML配置的spec.template字段中定义的。

kubernetes还有助于处理POD的可扩展性,确保正确的豆荚运行数量,并持续照顾对POD的更新。所有这些活动都可以通过部署yaml中的字段进行配置。

在项目根目录中创建一个部署文件夹以存储所有清单文件。为所有服务创建清单文件。确保为每个POD添加正确的图像

这是user-deployment.yamlfile的外观。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: user
spec:
  replicas: 2
  selector:
    matchLabels:
      app: user
  template:
    metadata:
      labels:
        app: user
    spec:
      containers:
      - name: user
        image: scacloudproject.azurecr.io/user
        envFrom:
          - secretRef:
            name: verify-account-secret
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 250m
            memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
  name: user
spec:
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
  selector:
    app: user

从上面的文件中,我们可以看到指定在哪里获取环境变量的Envfrom变量。让我们配置secret文件。

kubectl create secret generic <secret-name> <data-source>

Create Secret File

在部署文件中获取ENV变量的其他方法是指定directly或使用configmap进行配置变量。

部署应用程序

要部署所有清单文件,在deployments文件夹中创建一个名为deploy.sh的bash脚本,并为每个容器添加所有部署命令。

kubectl apply -f <filename>

List of Kubernetes Deployment Commands

将目录更改为deployments目录,并使用./deploy.sh运行脚本。

运行kubectl get pods以检查豆荚的状态。

List of pods

调试
如果您遇到部署的任何问题,请检查您的缩进,因为它在YAML文件中非常重要或尝试在线搜索帮助。另外,您需要使用这些命令删除所有部署和服务。

kubectl delete --all service
kubectl delete --all deployment

运行kubectl get pods以确保没有运行。然后,再次运行脚本./deploy.sh。然后,运行kubectl get pods并确保所有PODS状态正在运行。

公开代理端点和测试申请

要获取URL,我们将用于访问前端微服务,我们将公开反向代理端口。之后,使用kubectl get services获取带有端口号的IP地址。

kubectl expose deployment <reverse-proxy-name> --type=LoadBalancer --name=<public-reverse-proxy-name>

Expose proxy endpoint and get url

尝试使用任何端点在Postman应用程序中提出一个请求以测试URL。

Test AKS Deployed application

构建前端容器图像

再次构建容器图像以使用URL。运行

az acr build --file Dockerfile --registry <container_registry_name> --image <docker-image-name> . --build-arg VUE_APP_BASE_URL=<api-base-url>

测试申请

配置中,在“常规设置”选项卡下,仅关闭HTTPS请求。

Set up Configurations

还将后端URL添加到CORS,以防止CORS起源问题。

Updated Cors Origin

我遇到了混合内容错误,因为HTTPS网站试图访问HTTP URL。在Google Chrome上,通过转到网站锁定,然后单击网站设置。向下滚动以进行不安全的内容,允许。重新启动应用程序服务。

回到应用程序并提出请求。

Web application

在不属于基本路线的路线上重新加载时,我遇到了一个404错误,这是单页应用程序发生的404个错误。要解决此问题,请在Frontend Project root文件夹中创建一个nginx.conf文件,然后添加此代码以路由请求。

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

另外,将其添加到Dockerfile,重建图像并重新启动应用程序服务。

Updated Dockerfile

查看部署的应用程序

与Azure管道连续集成

为了避免手动构建图像,是设置连续集成过程的理想选择,以确保每次推送到分支或PR合并的每个推动,将图像构建并将其推向容器。

这可以通过转到Azure DevOps上的“管道”选项卡并创建新管道来轻松完成。使用此guide来设置管道,因为我无法获得某些权限。

清理资源

我们使用Azure订阅创建了几个资源。我们将清理这些资源,以免我们继续为它们收取费用。您可以在CLI或门户上删除。

使用CLI删除:

az group delete --name myResourceGroup --yes --no-wait

在门户中,

  1. 在Azure中,选择资源组
  2. 找到您使用的资源组名称并选择它。
  3. 在资源组的概述选项卡中,选择删除资源组。
  4. 似乎有一个对话框提示您确认删除。再次输入资源组的名称,然后选择 delete
  5. 选择删除再次确认删除。这将删除创建的所有资源。