“This is the 18th day of my participation in the First Challenge 2022. For details: First Challenge 2022”

【 K8S series 】 K8S Learn 26-3, Statefulset Combat 1

In the last part, I will share with you the differences between Statefulset and RplicaSet, as well as the features of Statefulset, some things that can be done, and some considerations

Now let’s try using Statefulset to deploy our application. We can have an application and then a persistent volume

Start deploying the application using Statefulset

Statefulset deployment application, we need to complete the creation of these resources:

  • Make the application and mirror
  • Write the Service
  • Write the Statefulset specified POD template and mount it

Make the application and mirror

Write an application

Here we can make an application that will write data to a path on disk, so let’s use Golang to write a simple HTTP server

  • Listen on port 8080
  • Provide GET and POST requests
    • Description The contents of /var/data/stateful. TXT was read when a GET request was received
    • The MESSAGE was written to the /var/data/stateful. TXT file when a POST request was received

The file directory looks like this

Main. go can be divided into these sections

  • HTTP server part

const (
	filePath = "/var/data/stateful.txt"
	fileDir  = "/var/data"
)

func main(a) {

	r := gin.Default()
	r.GET("/".func(c *gin.Context) {

		str, err := readFileContent(filePath)
		iferr ! =nil {
			fmt.Println(" readFileContent err : ", err)
			return
		}
		// Outputs the JSON result to the caller
		c.JSON(200, gin.H{
			"message": str,
		})
	})
	r.POST("/".func(c *gin.Context) {
		buf := make([]byte.1024)
		n, _ := c.Request.Body.Read(buf)
		fmt.Println(string(buf[0:n]))

		err := writeFileContent(filePath, buf[0:n])
		iferr ! =nil {
			fmt.Println(" writeFileContent err : ", err)
			return
		}
		// Outputs the JSON result to the caller
		c.JSON(http.StatusOK, gin.H{
			"message": string(buf[0:n]),
		})
	})

	r.Run(": 8080")}Copy the code

The GIN framework in Golang is used to provide a GET method for reading file contents and a POST method for writing file contents

  • Write file section
func processFileErr(err error, file string) (*os.File, error) {
	var f *os.File
	if os.IsNotExist(err) {
		gErr := os.MkdirAll(fileDir, 0775)
		ifgErr ! =nil {
			fmt.Println("MkdirAll file error : ", gErr)
			return nil, gErr
		}
		f, gErr = os.Create(file)
		ifgErr ! =nil {
			fmt.Println("Create file error : ", gErr)
			return nil, gErr
		}
	} else {
		fmt.Println("OpenFile file error : ", err)
		return nil, err
	}
	return f, nil
}

func writeFileContent(file string, content []byte) error {
	f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
	iferr ! =nil {
		var pErr error
		f, pErr = processFileErr(err, file)
		ifpErr ! =nil {
			fmt.Println("processFileErr error : ", pErr)
			return pErr
		}
	}
	defer f.Close()

	fmt.Println("Write content : ".string(content))

	_, err = f.Write(content)
	iferr ! =nil {
		fmt.Println("Write file error : ", err)
		return err
	}
	return nil
}
Copy the code

The writeFileContent method is primarily used to write data to a file

ProcessFileErr handles the error message that the file does not exist, creates the nonexistent path and file, and returns the pointer to the file that created the file

  • Read file information section
func readFileContent(file string) (string, error) {
	f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE, 0775)
	iferr ! =nil {
		var pErr error
		f, pErr = processFileErr(err, file)
		ifpErr ! =nil {
			fmt.Println("processFileErr error : ", pErr)
			return "", pErr
		}
	}

	defer f.Close()

	buf := make([]byte.1024)
	n, err := f.Read(buf)
	if err == io.EOF {
		return "".nil
	}
	iferr ! =nil {
		fmt.Println("Read file error : ", err)
	}
	fmt.Println("read content : ".string(buf))
	return string(buf[0:n]), nil
}
Copy the code

For the file reading part, processFileErr is also used to handle the error message that the file does not exist, reading the contents of the file from the incoming file and returning the value as a string

To make the mirror

Dockerfile:

Add the myHTTP executable to the image

FROM node:7
ADD myhttp /myhttp
ENTRYPOINT ["./myhttp"]
Copy the code

Run the following command to create an image:

See here brother, please upload the image to your own account below, remember to log in oh

docker build -t xiaomotong888/sta-kubia .
docker push xiaomotong888/sta-kubia
Copy the code

After uploading the image, you can view your image list by using the docker search account name. If you see the following content, you can continue to complete other steps

Write the Service

Next comes the listing for the Service part. When we play with Statefulset managing pods, we create stateful pods, and we also need to create a Headless Service to provide network identification between pods

For example, we can create it like this

sta-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: sta-kubia
spec:
  clusterIP: None
  selector:
    app: sta-kubia
  ports:
  - name: http
    port: 80
Copy the code

A Service created

  • Name of the sta – kubia
  • The SELECTED POD tag is STA-kubia
  • The internal port of an SVC cluster is 80

If type is not specified, then the default value of Service is clusterIP. If type is not specified, then the default value of Service is clusterIP

Yaml: kubectl create -f sta-service.yaml: kubectl create -f sta-service.yaml: kubectl create -f sta-service

curl localhost:8001/api/v1/namespaces/default/pods/sta-kubia-0/proxy/
Copy the code

curl  -X POST -d 'helloworld sta-kubia-0' localhost:8001/api/v1/namespaces/default/pods/sta-kubia-0/proxy/
Copy the code

Today is here, learning, if there is a deviation, please correct

Welcome to like, follow and favorites

Friends, your support and encouragement, I insist on sharing, improve the quality of the power

All right, that’s it for this time

Technology is open, our mentality, should be more open. Embrace change, live in the sun, and strive to move forward.

I am Nezha, welcome to like, see you next time ~