자체 Kubernetes 구축 - 파트 5 - 노드 명령
27147 단어 programminggokubernetesdevops
시작하기 전에 코드에서 몇 가지 사소한 수정 사항이 있었습니다. 노드에서 동일한 이름을 사용할 것이기 때문에 cmd/pod.go에서 명령 변수의 이름을 바꾸고 에이전트 포드 경로를 포드로 변경하고 REST에서 BP로 포드가 아닌 포드로 변경합니다. GenerateNewID 기능을 pkg/util.go로 옮겼습니다. Dockerfile에 큰 변화가 있었습니다. 로컬에서 노드 이미지를 빌드하기 위해 명령을 실행하는 환경에 의존하고 있으므로 기본 프로그램, 에이전트 및 노드 이미지를 빌드하기 위해 Makefile을 만들었습니다.
메이크파일:
default: build
build: build-agent build-node-image
go build -o bin/main main.go
build-node-image:
sudo docker build -t own-kube-node .
build-agent:
go build -o bin/agent pkg/agent/agent.go
결과적으로 이미지를 빌드할 때 이미 빌드된 에이전트의 바이너리에 의존할 수 있으므로 Dockerfile에서 빌드를 제거했습니다.
# Dockerfile for node image
FROM ubuntu
WORKDIR /agent
RUN apt-get update && apt-get install -y wget containerd
COPY bin/agent .
EXPOSE 10250
ENTRYPOINT [ "./agent" ]
노드 기능부터 시작하겠습니다. 포드와 마찬가지로
pkg/node
에 노드 기능과 관련된 파일이 있습니다.pkg/node/constraints.go
에서 시작하여 작업에 대한 몇 가지 제약 조건을 정의합니다.package node
import "github.com/jonatan5524/own-kubernetes/pkg/agent/api"
const (
NODE_NAME = "node"
NODE_IMAGE = "own-kube-node"
NODE_PORT = api.PORT + "/tcp"
NODE_PORT_HOST_IP = "0.0.0.0"
MEMORY_LIMIT = 2.9e+9 // 2900MB
CPU_LIMIT = 2
NODE_HOST_MIN_PORT = 10250
NODE_HOST_MAX_PORT = 10300
)
모든 제약 조건은 다음 파일에서 사용되며 모든 값은 docker 컨테이너 노드를 실행할 때 마지막 기사에서 가져옵니다.
pkg/node.go
에서 Node 구조체를 정의합니다.type Node struct {
Id string
Port string
}
Id - 노드에 대해 생성된 ID
포트 - 노드에 사용되지 않는 포트 생성
이 파일에서 docker sdk을 사용하여 새 노드를 생성하는 함수도 정의합니다.
func NewNode(cli *client.Client, ctx context.Context) (*Node, error) {
exists, err := isNodeImageExists(cli, ctx)
if err != nil {
return nil, err
} else if exists == false {
return nil, fmt.Errorf("node image: %s not exists locally, need to build the image", NODE_IMAGE)
}
id := pkg.GenerateNewID(NODE_NAME)
config := &container.Config{
Image: NODE_IMAGE,
}
hostConfig := &container.HostConfig{
PortBindings: nat.PortMap{
nat.Port(fmt.Sprintf("%s/tcp", api.PORT)): []nat.PortBinding{
{
HostIP: NODE_PORT_HOST_IP,
HostPort: "0",
},
},
},
Resources: container.Resources{
Memory: MEMORY_LIMIT,
CPUShares: CPU_LIMIT,
},
Privileged: true,
}
_, err = cli.ContainerCreate(ctx, config, hostConfig, nil, nil, id)
if err != nil {
return nil, err
}
return &Node{Id: id}, nil
}
먼저 노드 이미지가 있는지 확인한 다음 ID를 생성하고 컨테이너에 대한 일부 구성을 만듭니다.
모든 구성은 이전 기사에서 실행한 명령과 동일합니다.
sudo docker run -it --memory="2900MB" --cpus="2" -p 10250:10250 --privileged --name test --rm containerd_test
그런 다음 구성 및 생성된 ID로 컨테이너를 만들고 새 노드 구조체를 반환합니다.
isNodeImageExists
함수 구현:func isNodeImageExists(cli *client.Client, ctx context.Context) (bool, error) {
images, err := cli.ImageList(ctx, types.ImageListOptions{})
if err != nil {
return false, err
}
for _, image := range images {
if strings.Contains(image.RepoTags[0], NODE_IMAGE) {
return true, nil
}
}
return false, nil
}
기능은 기존 이미지를 나열하고 각 이미지를 살펴보고 해당 RepoTag에 다음이 포함되어 있는지 확인합니다
own-kube-node
.pkg/node/service.go
로 이동해 보겠습니다. 첫 번째로 수행할 함수는 도커 클라이언트와 컨텍스트를 초기화한 initDockerConnection
입니다.func initDockerConnection() (*client.Client, context.Context, error) {
ctx := context.Background()
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return nil, nil, err
}
return cli, ctx, nil
}
다음은 새 노드를 만들고 컨테이너를 시작하는
NewNodeAndRun
함수입니다.func NewNodeAndRun() (*Node, error) {
cli, ctx, err := initDockerConnection()
if err != nil {
return nil, err
}
defer cli.Close()
node, err := NewNode(cli, ctx)
if err != nil {
return nil, err
}
if err := cli.ContainerStart(ctx, node.Id, types.ContainerStartOptions{}); err != nil {
return nil, err
}
log.Printf("node created: %s\n", node.Id)
log.Printf("starting node\n")
container, err := cli.ContainerInspect(ctx, node.Id)
if err != nil {
return nil, err
}
// get linux generated port
node.Port = container.NetworkSettings.Ports[nat.Port(fmt.Sprintf("%s/tcp", api.PORT))][0].HostPort
log.Printf("node assign port: %s\n", node.Port)
return node, nil
}
이 함수에서 볼 수 있듯이 docker 데몬에 대한 연결을 초기화하고 새 노드와 컨테이너를 만들고 컨테이너를 시작한 다음 포트 0을 할당했기 때문에 시스템에서 할당된 포트를 검색해야 합니다.
다음 함수는
ListRunningNodes
입니다.func ListRunningNodes() ([]string, error) {
cli, ctx, err := initDockerConnection()
if err != nil {
return []string{}, err
}
defer cli.Close()
runningNodes := []string{}
filter := filters.NewArgs(filters.KeyValuePair{Key: "ancestor", Value: NODE_IMAGE})
containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Filters: filter})
if err != nil {
return runningNodes, err
}
for _, container := range containers {
runningNodes = append(runningNodes, container.Names[0])
}
return runningNodes, nil
}
함수는 연결을 초기화하고 필터링할 이미지를 의미하는
ContainerList
필터와 함께 ancestor
메서드를 호출한 다음 각 컨테이너를 실행하여 이름 목록을 만듭니다.마지막 함수는 단순히 컨테이너를 중지하고 제거하는
KillNode
함수입니다.func KillNode(name string) (string, error) {
cli, ctx, err := initDockerConnection()
if err != nil {
return "", err
}
defer cli.Close()
if err := cli.ContainerStop(ctx, name, nil); err != nil {
return "", err
}
removeOptions := types.ContainerRemoveOptions{
RemoveVolumes: true,
Force: true,
}
if err := cli.ContainerRemove(ctx, name, removeOptions); err != nil {
return "", err
}
return name, nil
}
우리가 완료해야 하는 마지막 부분은
cmd/node.go
그 구조는 cmd/pod.go
와 동일합니다. 이 문서가 너무 길기 때문에 여기에 이 파일을 추가하지 않을 것입니다. 소스 코드에서 볼 수 있습니다.터미널에서 모든 것이 작동하는 것을 볼 수 있습니다.
❯ make
go build -o bin/agent pkg/agent/agent.go
sudo docker build -t own-kube-node .
...
❯ sudo ./bin/main node create
2022/10/12 19:18:26 node created: node-7daf80ec-0a46-4977-952c-66deb81e32f7
2022/10/12 19:18:26 starting node
2022/10/12 19:18:26 node assign port: 49167
❯ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2066e8e0b933 own-kube-node "./agent" 5 seconds ago Up 4 seconds 0.0.0.0:49167->10250/tcp node-7daf80ec-0a46-4977-952c-66deb81e32f
❯ curl -X POST localhost:49167/pods -H 'Content-Type: application/json' -d '{"name": "redis", "image registry": "docker.io/library/redis:alpine"}'
{"image registry":"docker.io/library/redis:alpine","name":"redis-a1cfce57-5db9-4894-a8cf-c277444e1b0c"}
이제 API 호출을 사용하여 명령으로 생성된 노드가 있습니다. 이 노드는 노드 내부에 포드를 생성할 수도 있습니다!
항상 그렇듯이 소스 코드는 here , 변경 사항은
pkg/node
, Dockerfile
, Makefile
, cmd/node
에서 찾을 수 있습니다.
Reference
이 문제에 관하여(자체 Kubernetes 구축 - 파트 5 - 노드 명령), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jonatan5524/build-own-kubernetes-part-5-node-commands-1ep5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)