.NET Core + K8S Play Container Orchestration

insert image description here
Production-Grade Container Orchestration - Automated container deployment, scaling, and management.
Production-Grade Container Orchestration - Automated container deployment, scaling, and management.

  1. Introduction
    Since I am learning microservices recently, I will play with k8s (Kubernetes) based on the previous docker to understand the basic concepts and core functions.

  2. What's k8s?
    k8s involves a lot of basic concepts, you can take ten minutes to take you to understand the core concepts of Kubernetes quickly.
    The following picture contains the core components of k8s:
    K8S cluster
    insert image description here

Here is a simple list as follows:

k8s Master: k8s master node, mainly includes:
API Server: Provides a REST endpoint that can be used to interact with the cluster.
Replication Controller: used to create and replicate Pods.
Node: k8s node, which can be a virtual machine or a physical machine. It in turn contains the following components:
Kubelet: is the master node agent.
Kube-proxy: Used by the Service to route links to Pods, as described above.
Docker or Rocket: Container technology used by Kubernetes to create containers.
Pod: Used to host application instances, including:
Container: Running container
Volume: Shared storage (volume)
IP Address: IP address
Labels: Labels, used to label pods
Service: Services, consisting of a group of Pods with the same Label , the strategy used to control access to Pods
3. Environment preparation
After sorting out the basic concepts, let's play with it. There are three ways to play: one is to follow the k8s official online laboratory for practical operations; the second is to play based on the k8s integrated in Docker For Windows; the third is to install MiniKube for tinkering. The second option is chosen here for explanation.

PS: Many beginners give up directly after encountering setbacks in the environment preparation stage. The author also spent a lot of time building this k8s environment, including reinstalling the system once, sweat! I hope the following steps will help you get off to a good start in your k8s journey.

3.1. Enable Kubernetes in Docker for Windows
First make sure you have installed Docker for Windows.
Because of that wall, enabling Kubernetes in Docker For Windows Client did not go as smoothly as expected. Finally, refer to this article to successfully enable it: Enable Kubernetes in Docker for Mac/Windows for Chinese users.
If you have installed the latest version of the docker for windows client (v2.0.0.3), you can refer to the following steps:

Configure Docker Hub’s Chinese official image acceleration for Docker daemon https://registry.docker-cn.com
git clone https://github.com/AliyunContainerService/k8s-for-docker-desktop.git
cd k8s-for-docker- desktop
git checkout v2.0.0.2 (this step is very important!!!)
Powell shell executes ./load_images.ps1
Enable Kubernetes
executes kubectl cluster-info, the following output indicates normal startup.
Kubernetes master is running at https://localhost:6445
KubeDNS is running at https://localhost:6445/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Once the environment is successfully built, you are halfway to success. Please make persistent efforts to complete the following experiments!

  1. Run the first Pod
    4.1. Create initial image
    1: First, we execute dotnet new mvc -n K8s.NET.Demo to create an ASP.NET Core Mvc application K8s.NET.Demo
    and modify HomeController as follows:

public class HomeController : Controller {
public IActionResult Index () {
var hostname = Dns.GetHostName ();
ViewBag.HostName = hostname;
ViewBag.HostIp = Dns.GetHostAddresses (hostname).FirstOrDefault (ip => ip.AddressFamily == AddressFamily.InterNetwork);
return View ();
}
public IActionResult Privacy () {
return View ();
}
public IActionResult CheckHealth () {
if (new Random ().Next (100) > 50) {
return Ok (“OK”);
} else {
return BadRequest ();
}
}
[ResponseCache (Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error () {
return View (new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
Modify Index.cshtml as follows:

@{
ViewData[“Title”] = “Home Page”;
}

Welcome

Host Name:@ViewBag.HostName

Host IP:@ViewBag.HostIp

Learn about building Web apps with ASP.NET Core.

2: Then add Dockerfile:

FROM microsoft/dotnet:sdk AS build-env
WORKDIR /app

Copy csproj and restore as distinct layers

COPY *.csproj ./
RUN dotnet restore

Copy everything else and build

COPY . ./
RUN dotnet publish -c Release -o out

Build runtime image

FROM microsoft/dotnet:aspnetcore-runtime
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT [“dotnet”, “K8s.NET.Demo.dll”]
3: Then execute docker build -t k8s. net.demo. Construct the mirror image. After the construction is successful, execute docker images to view the image named k8s.net.demo.

4.2. Create a pod description file
Add the k8s-web-pod.yaml file as follows:

apiVersion: v1
kind: Pod # Define the type of Kubernetes resource as Pod
metadata:
name: k8s-net-pod # Define the name of the resource
labels: # Label the Pod, and its usefulness will be introduced later
app: k8s-net-pod
spec : # Define the status of resources. For Pod, the most important attribute is containers
containers: # containers is an array type. If you want to deploy multiple containers, you can add multiple items
- name: web # Define the name of the container in this Pod
image: k8s.net.demo # Define the address of the container image that Pod starts
imagePullPolicy: IfNotPresent # The default value of k8s is Always, which always pulls the image from the remote end, and uses the local image by setting IfNotPresent or Never
ports:
- containerPort: 80 # Define the port where the container listens (similar to EXPOSE in Dockerfile, just to provide document information)
livenessProbe: # Liveness probe definition
httpGet:
path: /Home/CheckHealth # Liveness probe request path
port: 80 # Liveness probe request port
4.3 . Use kubectl create to create a pod
Execute the following command to complete the pod creation:

$ kubectl create -f k8s-web-pod.yaml
pod “k8s-web-pod.yaml” created
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
k8s-net-pod 1/1 Running 0 1m
4.4. Access pod running In order for the container
to communicate with the pod, it can be done by configuring port forwarding through kubectl port-forward.

$ kubectl port-forward k8s-net-pod 8090:80
Forwarding from 127.0.0.1:8090 -> 80
Forwarding from [::1]:8090 -> 80
Browser access http://localhost:8090/, the effect is as shown below Shown:
insert image description here

So far we have successfully run the first pod.

At this point you may ask, what is the difference between this and running a container directly with docker run -d -p 8091:80 k8s.net.demo? Didn't see where k8s is so powerful? !
Don't worry, you can execute kubectl get pod again now, and I will tell you the answer.

$ kubectl get po
NAME READY STATUS RESTARTS AGE
k8s-net-pod 1/1 Running 17 1h
If there is no RESTARTS column, it is used to indicate how many times the pod has been restarted. Use docker to run the container. If the container hangs up, docker will not be responsible for restarting the container for you.
In k8s, you only need to configure the survival probe, and k8s will automatically detect the running status of the container and restart it automatically. The liveness probe only needs to specify the livenessProbe node in the yaml file. (PS: /home/checkhealth uses random numbers to simulate the running status of container applications. When the random number is less than 50, BadRequest is returned.)

And this is just the tip of the iceberg of k8s.

  1. Run the first Service
    Pod to run inside the cluster. Although you can use kubect port-forward to map the port to access locally, it is still inaccessible to the outside. If you need to expose it for external direct access, you need to create a service.

5.1. Using kubectl expose to create a service
We can directly expose the currently running pod instance through kubectl expose pod.

$ kubectl expose pod k8s-net-pod --name k8s-net-service --type=NodePort
service “k8s-net-service” exposed
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
k8s- net-service NodePort 10.98.62.192 80:30942/TCP 7m
As above, it has a CLUSTER-IP of 10.98.62.192, so we can use 10.98.62.192:80 in the cluster to access the service, if it is outside the cluster, you can Use NodeIP:30942 (the IP of the server where the node is located) to access.

5.2. Use the servive description file to create
Another way is to create a description file, add the k8s-net-service.yaml file:

apiVersion: v1
kind: Service # Define the type of Kubernetes resource as Service
metadata:
name: k8s-net-service # Define the name of the resource
spec:
selector: # Specify the corresponding Pod
app: k8s-net-pod # Specify the label of the Pod as k8s-net-pod
ports:

  • protocol: TCP # Protocol type
    port: 80 # Specify the port for Service access
    targetPort: 80 # Specify the port for Service forwarding requests
    nodePort: 30000
    type: NodePort # Specify the type of Service, here use NodePort for external access
    and execute kubectl create -f k8s -net-service.yaml to create service.

$ kubectl create -f k8s-net-service.yaml
service “k8s-net-service” created
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
k8s-net-service NodePort 10.98.62.192 80:30942 /TCP 23m
k8s-net-service NodePort 10.97.110.150 80:30000/TCP 34s
kubernetes ClusterIP 10.96.0.1 443/TCP 1d
6. Try the free scaling of k8s
It's time to experience the powerful automatic scaling function of k8s. In k8s, pods are managed by creating ReplicaSet or Deployment, and then automatic expansion and management are completed.
PS: ReplicaController can also be used, but ReplicaSet is recommended because its label matching function is more powerful.

6.1. Run the first ReplicaSet
First define the ReplicaSet description file k8s-net-replicaset.yaml:

apiVersion: apps/v1beta2 # The version number of rs is apps/v1beta2
kind: ReplicaSet # Define the type of Kubernetes resource as ReplicaSet
metadata:
name: k8s-net-replicaset # Define the name of the resource
spec:
replicas: 3 # Specify the number of pod instances Number
selector: # pod selector
matchLabels: # Specify the matching label
app: k8s-net-pod # Specify the label of the Pod as k8s-net-pod
template: # Create a new pod template configuration
metadata:
labels:
app: k8s-net -pod # Specify which pod to use
spec:
containers:
- name: k8s-net-replicaset
image: k8s.net.demo # Specify the image to use
imagePullPolicy: IfNotPresent # The default value of k8s is Always, which always pulls the image from the remote end, Use the local image by setting IfNotPresent or Never
Execute the following command to create a ReplicaSet, and observe the automatically created pod instance.

$ kubectl create -f k8s-net-replicaset.yaml
replicaset.apps “k8s-net-replicaset” created
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
k8s-net-replicaset 3 3 3 8s
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
k8s-net-pod 1/1 Running 61 12h
k8s-net-replicaset-bxw9c 1/1 Running 0 35s
k8s-net-replicaset-k6kf7 1/1 Running 0 35s
$ kubectl delete po k8s-net-replicaset-bxw9c
pod “k8s-net-replicaset-bxw9c” deleted
$ kubectl get po
NAME READY STATUS RESTARTS AGE
k8s-net-pod 1/1 Running 61 12h
k8s-net-replicaset-bxw9c 0/1 Terminating 0 2m
k8s-net-replicaset-k6kf7 1/1 Running 0 2m
k8s-net-replicaset-xvb9l 1/1 Running 0 6s
As you can see from the above, k8s-net-replicaset created two additional pod copies using k8s-net-pod as a template. When we try to delete one of the copies and check the pod list again, replicaset will automatically recreate a pod for us.
Then let's try to expose the newly created k8s-net-replicaset as a Service to see what the actual operation is like. Execute the following commands in sequence:

$ kubectl expose replicaset k8s-net-replicaset --type=LoadBalancer --port=8091 --target-port=80 --name k8s-net-rs
-service
service “k8s-net-rs-service” exposed
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
k8s-net-rs-service LoadBalancer 10.99.134.237 localhost 8091:32641/TCP 8s
k8s-net-service NodePort 10.104.21.80 80:30000/TCP 12h
kubernetes Clu sterIP 10.96 .0.1 443/TCP 12h
Then the browser visits http://localhost:8091/, try to refresh the browser several times, the display effect is as follows, we found that ReplicaSet has helped us to do a good job of load balancing.
load balancing effect
insert image description here

If the number of website visits increases sharply now, and the three instances still cannot effectively support it, can horizontal scaling be achieved without stopping the application? Of course, Yes!
Just execute the kubectl scale command to expand.

$ kubectl get pod
NAME READY STATUS RESTARTS AGE
k8s-net-replicaset-g4n6g 1/1 Running 0 13m
k8s-net-replicaset-lkrf7 1/1 Running 0 13m
k8s-net-replicaset-tf992 1/1 Running 0 13m
$ kubectl scale replicaset k8s-net-replicaset --replicas=6
replicaset.extensions “k8s-net-replicaset” scaled
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
k8s-net-replicaset-cz2bs 0/1 ContainerCreating 0 3s
k8s-net-replicaset-g4n6g 1/1 Running 0 13m
k8s-net-replicaset-lkrf7 1/1 Running 0 13m
k8s-net-replicaset-pjl9m 0/1 ContainerCreating 0 3s
k8s-net-replicaset-qpn2l 0/1 ContainerCreating 0 3s
k8s-net-replicaset-tf992 1/1 Running 0 13m
From the above output, we can see that we can expand the pod instance to 6 with one command, isn't it very simple? !

You may ask again, I have passed the peak of visits now, how can I quickly scale the application? Ah, the same as above, you just need to change the --replicas parameter to a smaller point, like this kubectl scale replicaset k8s-net-replicaset --replicas=3.

Guess you like

Origin blog.csdn.net/weixin_43214644/article/details/127627490