preface

Play K8S also has a period of time, with the help of cloud service providers K8S console, can be very convenient rapid deployment applications to K8S. With a simple click, you can help create K8S objects in one go: Deployment, Service, Ingress, ConfigMap, and so on. But when the scale of the service increases, this approach is a bit stretched. Especially when you need to update multiple associated services at the same time, you need to change them one by one, which is a little inconvenient. To solve this problem, I recently put the Helm into practice and found a huge increase in productivity.

Helm profile

Helm is a package manager built for K8S. The Helm makes it easy to manage Kubernetes applications. Helm mainly has two core concepts: Charts and Release.

  1. Chart: used to define, install and upgrade K8S applications. Can also share and version control.
  2. Release: Similar to Image for Container, Release is a running instance of Chart.

The latest version of Helm is V3.1, which removes server Tiller from the overall architecture. Choco install Kubernetes-helm For Windows. Check whether kubernetes-helm is successfully installed by running helm version. Version. BuildInfo {version: “v3.1.0 GitCommit:” b29d20baf09943e134c2fa5e1e1cab3bf93315fa GitTreeState: “clean”, GoVersion: “go1.13.7}”

Moving forward, make sure you have the basics of K8S and that Docker and K8S are installed on this machine. ASP.NET Core plays with container choreography with K8S.

For our first encounter with Helm.NETer we can take a quick look at VS 2019. Make sure Visual Studio Tools for Kubernetes is installed.

Create Chart (helm Create)

Open the VS Create project and select The Container Application for Kubernetes to create an empty ASP.NET Core Web project.

charts
Dockerfile
azds.yaml

Container Application for Kubernetes
charts
Dockerfile
azds.yaml

It can also be created by helm Create.

Install Chart (helm Install)

Before expanding, let’s take a quick look at the Chart directory:

k8shelmdemo/                         # Chart directory├ ─ ─ charts# This Charts relies on other charts that are always installed├ ─ ─ Chart. YamlDescribe the information about this Chart, including name, description, version, etc├ ─ ─ templates# template directory│ ├ ─ ─ deployment. Yaml# Deployment controller Go template file│ ├ ─ ─ _helpers. TPL# files beginning with _ are not deployed to K8S and can be used to customize generic information│ ├ ─ ─ ingress. Yaml# ingress template file│ ├ ─ ─ NOTES. TXT# Chart help text, which is displayed to the user after installation, such as: How to use, list defaults│ ├ ─ ─ service. YamlGo template file for service│ ├ ─ ─ secrets. Yaml# Secrets Go template file│ ├ ─ garbage │ ├ ─test- connection. Yaml └ ─ ─ values. The yamlThese values are applied to the GO template at installation time to generate the deployment file
Copy the code

In simple terms, Helm Chart defines common K8S object templates, which are populated with values. Yaml. So let’s see what the output looks like after we fill it. Open a command prompt and go to the Chart directory, Chart can be tested by using the helm template –debug [release name] [chart dir] command (or by helm –dry-run –debug [release name] [chart dir]). You can see the output of Service and Deployment. You may be wondering why two YAML files are output instead of four K8S object templates. I’m going to hold it down here.

PS \K8S.Helm.Demo\charts> helm template --debug k8s-helm-demo .\k8shelmdemo\
install.go:158: [debug] Original chart version: ""
install.go:175: [debug] CHART PATH: \K8S.Helm.Demo\charts\k8shelmdemo
---
# Source: k8shelmdemo/templates/service.yamlApiVersion: v1 kind: Service metadata: name: k8ShelmDemo Labels: app: k8Shelmdemo chart: k8ShelmDemo 0.1.0 release: k8s-helm-demo heritage: Helm spec:type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: k8shelmdemo
    release: k8s-helm-demo
---
# Source: k8shelmdemo/templates/deployment.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: k8shelmdemo
  labels:
    app: k8shelmdemo
    chart: k8shelmdemo-0.1.0
    draft: draft-app
    release: k8s-helm-demo
    heritage: Helm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: k8shelmdemo
      release: k8s-helm-demo
  template:
    metadata:
      labels:
        app: k8shelmdemo
        draft: draft-app
        release: k8s-helm-demo
      annotations:
        buildID: ""
    spec:
      containers:
        - name: k8shelmdemo
          image: "k8shelmdemo:stable"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          env:
          resources:
            {}
Copy the code

One thing to note here for now is that the image used in the Deployment output above is **image: “k8shelmdemo:stable”**. So before we can install the Chart, we need to construct the image. Image construction is simple, just right-click Dockerfile in Vs and select Build (make sure Docker is started).

1>K8S.Helm.Demo -> D: \ Programming, Coding, dotnet \ K8S Ocelot. The Demo \ SRC \ K8S Helm. Demo \ bin \ Debug \ netcoreapp3.1 \ K8S Helm. Demo. DLL 1 > Docker Version 19.03.1, build 74b1e89 1>docker build -f "d:\programming\coding\dotnet\k8s.ocelot.demo\src\k8s.helm.demo\dockerfile" --force-rm -t k8shelmdemo --label "com.microsoft.created-by=visual-studio" --label "com.microsoft.visual-studio.project-name=K8S.Helm.Demo" "d:\programming\coding\dotnet\k8s.ocelot.demo\src" 1>Sending Build context to Docker Daemon 6.192MB 1> 1>Step 1/18: The FROM McR.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base 1 > 2/18 Step: WORKDIR /app 1> ---> e28362768eed 1> ---> Using cache 1> ---> 6457841dbdf1 1>Step 3/18 : EXPOSE 80 1> ---> Using cache 1> ---> bb9dc51530fe 1>Step 4/18 : The FROM McR.microsoft.com/dotnet/core/sdk:3.1-buster AS build 1 > -- -- -- > 0 a4c7c13f9d6 1 > 5/18 Step: WORKDIR /src 1> ---> Using cache 1> ---> ddc36742b71c 1>Step 6/18 : COPY ["K8S.Helm.Demo/K8S.Helm.Demo.csproj", "K8S.Helm.Demo/"] 1> ---> d18831c83acd 1>Step 7/18 : The RUN dotnet restore "K8S. Helm. Demo/K8S. Helm. Demo. Csproj" 1 > -- > Running in 64 d3624eb9c0 1 > restore completed in 7.19 SEC  for /src/K8S.Helm.Demo/K8S.Helm.Demo.csproj. 1>Removing intermediate container 64d3624eb9c0 1> ---> ba3624442138 1>Step  8/18 : COPY . . 1> ---> 43c4f6c4769f 1>Step 9/18 : WORKDIR "/src/K8S.Helm.Demo" 1> ---> Running in 145e155d3a5d 1>Removing intermediate container 145e155d3a5d 1>Step 10/18 : RUN dotnet build "K8S.Helm.Demo.csproj" -c Release -o /app/build 1> ---> e547e8caed4a 1> ---> Running in 146df981f291 1>Microsoft (R) Build Engine Version 16.4.0+ E901037FE for.net Core 1>Copyright (C) Microsoft Corporation. All Rights Reserved. 1 > 1 > Restore completed in 27.08 ms for/SRC/K8S Helm. The Demo/K8S Helm. Demo. Csproj. 1 > K8S. Helm. Demo - > / app/build/K8S. Helm. Demo. DLL 1 > build succeeded. 1 > 0 Warning (s) > 1 > Time Elapsed 00:00:02. 09 > 0 1 Error (s) 1 > o intermediate container 146df981f291 1>Step 11/18 : FROM build AS publish 1> ---> 94f07ad82c1c 1> ---> 94f07ad82c1c 1>Step 12/18 : RUN dotnet publish "K8S.Helm.Demo.csproj" -c Release -o /app/publish 1> ---> Running in 60d63984fe28 1>Microsoft (R) Build Engine Version 16.4.0+ E901037FE for.net Core 1> 1>Copyright (C) Microsoft Corporation. All Rights reserved. 1> Restore completed in 26.94 ms for/SRC/K8S Helm. The Demo/K8S Helm. Demo. Csproj. 1 > K8S. Helm. Demo - > / SRC/K8S. Helm. Demo/bin/Release/netcoreapp3.1 / K8S Helm. Demo. DLL 1 > K8S. Helm. Demo - > / app/publish / 1 > o intermediate  container 60d63984fe28 1>Step 13/18 : FROM base AS final 1> ---> 85d893dc4a81 1> ---> bb9dc51530fe 1>Step 14/18 : WORKDIR /app 1> ---> Running in 69b7fd56c371 1>Removing intermediate container 69b7fd56c371 1> ---> 219310025c54 1>Step 15/18 : COPY --from=publish /app/publish . 1>Step 16/18 : ENTRYPOINT ["dotnet", "K8S.Helm.Demo.dll"] 1> ---> 6e63a4449dbb 1> ---> Running in a43a0516c6dc 1>Removing intermediate container a43a0516c6dc  1> ---> 36f422c923fd 1>Step 17/18 : LABEL com.microsoft.created-by=visual-studio 1> ---> Running in 88d100227ee1 1>Removing intermediate container 88d100227ee1 1> ---> 4a71f8e5e761 1>Step 18/18 : LABEL com.microsoft.visual-studio.project-name=K8S.Helm.Demo 1> ---> Running in f609881010ad 1>Removing intermediate container f609881010ad 1> ---> 3301427c0fb8 1>Successfully built 3301427c0fb8 1>Successfully tagged k8shelmdemo:latest 1>SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build  context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files  and directories. ========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========Copy the code

The image name of the final build is K8ShelmDemo: Latest. Inconsistent with the image k8ShelmDemo :stable we used in the Chart above. If Chart is installed now, the application will not find the corresponding image and will not start. So what to do. Looking at the deployment.yaml template file, we see that its image reference is defined as image: “{{.values.image.repository}}:{{.values.image.tag}}”. Check values. Yaml and find the following definition:

image:
  repository: k8shelmdemo
  tag: stable
  pullPolicy: IfNotPresent
Copy the code

Change values.yaml to latest. Helm Template –debug [release name] [chart dir] Next, install Chart via Helm Install. Before executing, we create a separate namespace through Kubectl Create NS Helmdemo to facilitate validation and cleanup. Then run helm install k8shelmdemo.\k8shelmdemo\ -n Helmdemo installation (-n specifies the namespace we just created). Specific commands are as follows:

PS \K8S.Helm.Demo\charts> kubectl create ns helmdemo
namespace/helmdemo created
PS \K8S.Helm.Demo\charts> helm install k8shelmdemo .\k8shelmdemo\ -n helmdemo
NAME: k8shelmdemo
LAST DEPLOYED: Sun Feb 23 17:33:54 2020
NAMESPACE: helmdemo
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace helmdemo -l "app=k8shelmdemo,release=k8shelmdemo" -o jsonpath="{.items[0].metadat
a.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:80
PS \K8S.Helm.Demo\charts>
Copy the code

We see NOTES templates in the templates folder printed at the same time, indicating that the helm is installed. So how do you make sure the installation is successful? Proceed with the following command:

PS \K8S.Helm.Demo\charts> helm list -n helmdemo # view chart installed in the specified namespace, that is, the running ReleaseNAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION K8ShelmDemo HelmDemo 1 2020-02-23 17:33:54.2196357 +0800 CST Deployed K8shelmdemo-0.1.0 deployed k8s.helm. Demo\charts> Kubectl get all-n HelmdemoSelect * from K8S; select * from K8SNAME READY STATUS RESTARTS AGE pod/k8shelmdemo-689bd54677-fcfx7 1/1 Running 0 5m8s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/ k8Shelmdemo ClusterIP 10.97.204.227 < None > 80/TCP 5m8s NAME READY up-to-date AVAILABLE AGE deployment.apps/k8shelmdemo 1/1 1 1 5m8s NAME DESIRED CURRENT READY AGE replicaset.apps/k8shelmdemo-689bd54677 1 1 1 5m8sCopy the code

At this point we can confirm the successful installation of Chart. How to access the newly deployed Web application, install the newly installed Notes of Chart, and configure port forwarding through Kubectl port-forward. From the output above we know that the corresponding Pod Name is k8shelmDemo-689bd54677 -fcfx7. Kubectl port-forward k8shelmDemo-689bd54677 -fcfx7 8090:80

PS \K8S.Helm.Demo\charts> kubectl port-forward k8shelmdemo-689bd54677-fcfx7 8090:80 -n helmdemo
Forwarding from 127.0.0.1:8090 -> 80
Forwarding from [::1]:8090 -> 80
Copy the code

Using curl -l http://localhost:8090, you will see Hello world.

Update Chart (Helm Upgrade)

Let’s say I now want to update the output to Hello Helm, so let’s see what happens. To update the output for the current application, simply change Startup’s Hello World to Hello Helm and rebuild the image. Think about it here, since the reconstructed image Tag is still K8ShelmDemo :latest, there is no need to change the current Helm Chart, so there is no need to update it. So how do we update the app? If you have a K8S foundation, you should be able to quickly figure out, just delete Pod. As you can see from kubectl get all-n Helmdemo, Chart automatically creates a ReplicaSet instance for our application. ReplicaSet is used to ensure that the application always has a specified number of instances running. So if a Pod is deleted, K8S will re-enable a new Pod according to ReplicaSet’s definition. Re-execute kubectl port-forward to see that the application has been updated.

PS: Because the current demo uses a local image, the Pod deleted and re-run can output the updated result. If the mirror source is not local, consider updating the mirror pull strategy for the same mirror tag.

PS \K8S.Helm.Demo\charts> kubectl delete pod/k8shelmdemo-689bd54677-fcfx7 -n helmdemo # remove pod
PS \K8S.Helm.Demo\charts> kubectl get all -n helmdemo
NAME                               READY   STATUS    RESTARTS   AGE
pod/k8shelmdemo-689bd54677-mrr64   1/1     Running   0          29s The new Pod was created successfullyNAME TYPE cluster-ip external-ip PORT(S) AGE service/k8shelmdemo ClusterIP 10.97.204.227 < None > 80/TCP 33m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/k8shelmdemo 1/1 1 1 33m NAME DESIRED CURRENT READY AGE replicaset.apps/k8shelmdemo-689bd54677 1 1 1 33mCopy the code

Assume that the service needs to be directly accessed through the specified port after deployment, without using kubeclt port-forward for port forwarding. We need to update Chart accordingly to change the generated Service type from the default Cluster to LoadBalancer mode. Update the service node in values.yaml as follows:

service:
  type: LoadBalancer
  port: 8093
Copy the code

Then run helm upgrade [release name] [chart dir] to update the application, as shown below.

PS \K8S.Helm.Demo\charts> helm upgrade k8shelmdemo .\k8shelmdemo\ -n helmdemo
Release "k8shelmdemo" has been upgraded. Happy Helming!
NAME: k8shelmdemo
LAST DEPLOYED: Sun Feb 23 18:39:30 2020
NAMESPACE: helmdemo
STATUS: deployed
REVISION: 3
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
           You can watch the status of by running 'kubectl get svc -w k8shelmdemo'
  export SERVICE_IP=$(kubectl get svc --namespace helmdemo k8shelmdemo -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
  echo http://$SERVICE_IP:8093 PS \K8S.Helm.Demo\charts> kubectl get all -n helmdemo NAME READY STATUS RESTARTS AGE pod/k8shelmdemo-689bd54677-pj5pd 1/1 Running 0 22m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/k8shelmdemo LoadBalancer 10.97.204.227 localhost: 8093 30035 / TCP 65 m NAME READY the UP - TO - DATE AVAILABLE AGE deployment. The apps/k8shelmdemo 1/1 1 1 65m NAME DESIRED CURRENT READY AGE replicaset.apps/k8shelmdemo-689bd54677 1 1 1 65m PS \K8S.Ocelot.Demo\src\K8S.Helm.Demo\charts> curl-l localhost:8093
Hello Helm!
PS \K8S.Helm.Demo\charts> helm ls -n helmdemo The version has been updatedNAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION K8ShelmDemo HelmDemo 2 2020-02-23 18:39:30.2059395 +0800 CST Deployed k8shelmdemo - 0.1.0 from 1.0Copy the code

Delete Chart (helm delete)

Helm delete K8shelmdemo -n Helmdemo

PS \K8S.Helm.Demo\charts> helm delete k8shelmdemo -n helmdemo
release "k8shelmdemo" uninstalled
PS \K8S.Helm.Demo\charts> helm ls -n helmdemo
NAME    NAMESPACE       REVISION        UPDATED STATUS  CHART   APP VERSION
PS \K8S.Helm.Demo\charts> kubectl get all -n helmdemo
No resources found.
Copy the code

After execution, you can see that the created K8S resources have also been cleaned up.

The last

This is a brief introduction to how to deploy ASP.NET Core to K8S using Helm. For complex Helm applications, which are mainly filled with templates, you can learn about them by combining the official Helm documents and Helm examples in eShopOnContainer.

Get started with Visual Studio Kubernetes Tools 2. Play K8S must not HELM