ubuntu@worker1:~$ curl -sfL https://get.k3s.io | K3S_URL=https://master:6443 K3S_TOKEN=K104869223bb6e5c3c1bb95bc7dcc505cb2d5576cf2253e9bd0df1b3a7852f91397::server:368a64fba85ad0718fe841967df1717f sh - [INFO] Finding release for channel stable [INFO] Using v1.32.3+k3s1 as release [INFO] Downloading hash https://github.com/k3s-io/k3s/releases/download/v1.32.3+k3s1/sha256sum-amd64.txt [INFO] Downloading binary https://github.com/k3s-io/k3s/releases/download/v1.32.3+k3s1/k3s [INFO] Verifying binary download [INFO] Installing k3s to /usr/local/bin/k3s [INFO] Skipping installation of SELinux RPM [INFO] Creating /usr/local/bin/kubectl symlink to k3s [INFO] Creating /usr/local/bin/crictl symlink to k3s [INFO] Creating /usr/local/bin/ctr symlink to k3s [INFO] Creating killall script /usr/local/bin/k3s-killall.sh [INFO] Creating uninstall script /usr/local/bin/k3s-agent-uninstall.sh [INFO] env: Creating environment file /etc/systemd/system/k3s-agent.service.env [INFO] systemd: Creating service file /etc/systemd/system/k3s-agent.service [INFO] systemd: Enabling k3s-agent unit Created symlink /etc/systemd/system/multi-user.target.wants/k3s-agent.service → /etc/systemd/system/k3s-agent.service. [INFO] systemd: Starting k3s-agent
节点都部署完后,节点状态如下:
1 2 3 4 5
ubuntu@master:~$ sudo kubectl get node NAME STATUS ROLES AGE VERSION master Ready control-plane,master 18m v1.32.3+k3s1 worker1 Ready <none> 29s v1.32.3+k3s1 worker2 Ready <none> 5s v1.32.3+k3s1
ubuntu@master:~/apps$ sudo kubectl apply -f nginx-deployment.yaml deployment.apps/nginx created
使用kubectl get deployment查看运行状态,使用kubectl get pods查看 Pod 状态:
1 2 3 4 5 6 7
ubuntu@master:~/apps$ sudo kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE nginx 2/2 2 2 17s ubuntu@master:~/apps$ sudo kubectl get pods -l app=nginx NAME READY STATUS RESTARTS AGE nginx-96b9d695-gfjvq 1/1 Running 0 25s nginx-96b9d695-w5qxx 1/1 Running 0 25s
可以看到 Deployment 创建 Pod 的命名规则:${DeploymentName}-${DeploymentUid}-${Hash}。
使用 kubectl get pod -o wide 查看 Pod 运行状态和 IP 地址,可以看到 nginx 被创建了两个 Pod 副本,分别部署在了 worker1 和 worker2 上面:
1 2 3 4
ubuntu@master:~/apps$ sudo kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-96b9d695-gfjvq 1/1 Running 0 8m42s 10.42.2.3 worker2 <none> <none> nginx-96b9d695-w5qxx 1/1 Running 0 8m42s 10.42.1.3 worker1 <none> <none>
此时的 nginx 还不能被外部访问,他们的 IP 是 Cluster 的内部私有 IP,只能在集群内部访问。 并且这些 IP 是浮动的,Pod 重启后,IP 也会变化。 这时就需要创建 Service 来解决这个问题。
创建 Service
Service 是 Kubernetes 中一种网络抽象,用于为一组 Pod 提供统一访问入口。 简单来说,Pod 是会变化的(比如被删除、替换),而 Service 提供一个 固定 IP / 名称 / 端口,始终指向一组后端 Pod。
1 2 3 4 5 6 7 8 9 10 11 12
apiVersion: v1 # 使用 v1 API,Service 资源的标准版本 kind: Service # 声明该资源类型为 Service metadata: name: nginx-service # Service 的名字,供集群中引用、DNS 名称生成等使用 spec: type: NodePort # 设置 Service 类型为 NodePort,支持通过任意节点的 IP + nodePort 端口访问服务 selector: app: nginx # 选择所有标签为 app=nginx 的 Pod ports: - port: 80 # Service 自己监听的端口,供集群内其他 Pod 调用这个服务时使用 targetPort: 80 # 转发到后端 Pod 的哪个端口(nginx 监听的端口) nodePort: 30080 # 外部访问时的端口(可不写,系统会自动分配 30000~32767)
使用 kubectl apply 命令创建 Service,使用 kubectl get service 查看运行状态:
1 2 3 4 5 6
ubuntu@master:~/apps/nginx$ sudo kubectl apply -f nginx-service.yaml service/nginx-service created ubuntu@master:~/apps/nginx$ sudo kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 72m nginx-service NodePort 10.43.119.114 <none> 80:30080/TCP 2m57s
## 工具安装 .PHONY: init init: @echo "Installing required tools..." go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest go install github.com/go-kratos/kratos/cmd/kratos/v2@latest go install github.com/go-kratos/kratos/cmd/protoc-gen-go-http/v2@latest go install github.com/google/gnostic/cmd/protoc-gen-openapi@latest go install github.com/google/wire/cmd/wire@latest
## 内部 Proto 生成 .PHONY: config config: @echo "Generating internal protobuf files..." @test -n "$(INTERNAL_PROTO_FILES)" || (echo "No proto files found in $(INTERNAL_DIR)" && exit 1) protoc --proto_path=$(INTERNAL_DIR) \ --proto_path=$(THIRD_PARTY_DIR) \ --go_out=paths=source_relative:$(INTERNAL_DIR) \ $(INTERNAL_PROTO_FILES)
## API Proto 生成 .PHONY: api api: @echo "Generating API protobuf files..." @test -n "$(API_PROTO_FILES)" || (echo "No proto files found in $(API_DIR)" && exit 1) protoc --proto_path=$(API_DIR) \ --proto_path=$(THIRD_PARTY_DIR) \ --go_out=paths=source_relative:$(API_DIR) \ --go-http_out=paths=source_relative:$(API_DIR) \ --go-grpc_out=paths=source_relative:$(API_DIR) \ --openapi_out=fq_schema_naming=true,default_response=false:$(API_DIR) \ $(API_PROTO_FILES)