将Go服务用Docker和K8s部署到两个Pod中

目前我对运维相关的东西也不熟,这里仅仅是简单地使用,部署在多个Pod中运行的Go服务主要是用于对分布式锁是否生效的测试。

集群、节点、Pod、容器、镜像仓库、镜像的关系大致如下:

电脑中已经安装好了docker和k8s:

shell 复制代码
$ kubectl version --short
Flag --short has been deprecated, and will be removed in the future. The --short output will become the default.
Client Version: v1.25.9
Kustomize Version: v4.5.7
Server Version: v1.25.9
$ docker version
Client:
 Cloud integration: v1.0.33
 Version:           24.0.2
 API version:       1.43
 Go version:        go1.20.4
 Git commit:        cb74dfc
 Built:             Thu May 25 21:51:16 2023
 OS/Arch:           darwin/amd64
 Context:           desktop-linux

Server: Docker Desktop 4.20.1 (110738)
 Engine:
  Version:          24.0.2
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.4
  Git commit:       659604f
  Built:            Thu May 25 21:52:17 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.21
  GitCommit:        3dce8eb055cbb6872793272b4f20ed16117344f8
 runc:
  Version:          1.1.7
  GitCommit:        v1.1.7-0-g860f061
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

K8s官方文档docker官方文档

构建镜像

创建Dockerfile文件,内容如下:

dockerfile 复制代码
# FROM 指定基础镜像
FROM ubuntu:20.04
# 把编译好的rdl可执行文件复制到Docker内的 /app/rdl中
COPY rdl /app/rdl
# 指定/app为工作目录
WORKDIR /app
# Docker的启动程序的命令是
CMD ["/app/rdl"]

为了执行命令比较方便,创建Makefile文件,内容如下:

mekefile 复制代码
.PHONY: build
build:
# 删除之前生成的rdl可执行文件, 如果文件不存在, 会走到 || true
	@rm rdl || true
# 编译出在linux环境下执行的可执行文件
	@GOOS=linux GOARCH=arm go build -o rdl .
# 删除已经存在的镜像
	@docker rmi -f rengmo/rdl:v0.0.1
# 构建镜像
	@docker build -t rengmo/rdl:v0.0.1 .

在终端执行以下命令构建镜像:

shell 复制代码
$ make build

构建成功之后打开Docker桌面应用程序能看到新构建的镜像:

K8s部署服务

创建Go服务的Deployment配置文件web/deployment.yaml,内容如下:

yaml 复制代码
# 按照apps/v1的方式处理这个配置
apiVersion: apps/v1
# 配置的类型是Deployment
kind: Deployment
# 元数据
metadata:
  # 名称
  name: rdl
# specification 规范说明
spec:
  # 表示运行2个Pod
  replicas: 2
  # 选择器
  selector:
    # 选择包含以下标签的Pod
    matchLabels:
      app: rdl
  # 模板表示如何创建Pod
  # 比如以下内容就表示创建包含标签app:rdl, 容器rengmo/rdl:v0.0.1, 有一定资源大小限制, 容器监听的端口号是8080的Pod
  template:
    # Pod的元数据
    metadata:
      # 包含标签app: rdl
      labels:
        app: rdl
    # 规范说明
    spec:
      # 包含的容器
      containers:
      # 容器的名称
      - name: rdl
        # 容器中包含的镜像
        image: rengmo/rdl:v0.0.1
        # 资源的配置
        # resources:
        #   # 限制使用资源的大小
        #   limits:
        #     memory: "128Mi"
        #     cpu: "500m"
        # 端口号
        ports:
        # 容器中的镜像,也就是rengmo/rdl:v0.0.1监听的端口号
        - containerPort: 8080

创建Go服务的Service配置文件web/service.yaml

yaml 复制代码
# 按照v1的方式处理这个配置
apiVersion: v1
# 配置的类型是Service
kind: Service
# 元数据
metadata:
  # 配置的名称为rdl
  name: rdl
# 规范说明
spec:
  # 选择标签为app: rdl的Pod
  selector:
    app: rdl
  # 端口号
  ports:
  # 外部访问的端口
  - port: 8080
  # 内部pod使用的端口
    targetPort: 8080
  # 使用k8s的负载均衡器提供外部可访问的IP地址
  type: LoadBalancer

创建Redis的Deployment配置文件redis/deployment.yaml

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: rdl-redis
spec:
  selector:
    matchLabels:
      app: rdl-redis
  template:
    metadata:
      labels:
        app: rdl-redis
    spec:
      containers:
      - name: rdl-redis
        image: redis:7.0.0
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 6379

创建Redis的Service配置文件redis/service.yaml

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: rdl-redis
spec:
  selector:
    app: rdl-redis
  ports:
  - port: 6380
    nodePort: 31379
    targetPort: 6379
  type: LoadBalancer

执行以命令应用配置:

shell 复制代码
$ kubectl apply -f ./deployment/redis/deployment.yaml 
deployment.apps/rdl-redis created
$ kubectl apply -f ./deployment/redis/service.yaml   
service/rdl-redis created
$ kubectl apply -f ./deployment/web/deployment.yaml 
deployment.apps/rdl created
$ kubectl apply -f ./deployment/web/service.yaml    
service/rdl created

为了方便配置文件修改之后重新应用,在Makefile文件中添加了以下内容:

makefile 复制代码
# 重新应用配置
reapply: k8sd k8sa
.PHONY: reapply

# 应用配置
.PHONY: k8sa
k8sa:
	@kubectl apply -f ./deployment/redis/deployment.yaml
	@kubectl apply -f ./deployment/redis/service.yaml
	@kubectl apply -f ./deployment/web/deployment.yaml
	@kubectl apply -f ./deployment/web/service.yaml 

# 删除资源
.PHONY: k8sd
k8sd:
	@kubectl delete deployment rdl
	@kubectl delete service rdl
	@kubectl delete deployment rdl-redis
	@kubectl delete service rdl-redis

执行make k8sa应用所有对应的配置文件,执行make k8sd删除对应的资源,在修改了配置文件之后,可以使用make reapply指令重新应用配置文件。

应用完配置文件之后可以打开Docker桌面应用程序,可以在Container中看到服务的日志:

在终端执行以下命令查看是否能正常连接Redis服务:

shell 复制代码
$ redis-cli -h 127.0.0.1 -p 6380

执行以下命令查看是否能正常请求接口:

shell 复制代码
$ curl -X POST http://localhost:8080/inventory/sale

解决问题

  1. 执行完之后查看pod,发现有一个pod一直处于pending中:
shell 复制代码
$ kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
rdl-56b6f9f5b8-lcq95         1/1     Running   1          25m
rdl-56b6f9f5b8-r8bzb         0/1     Pending   0          25m
rdl-redis-64755679bf-pxq75   1/1     Running   2          26m

把service配置文件的资源限制部分注释了就不存在这个问题了。应该是由于分配的资源不足才会一直Pending的。

相关推荐
陌北v19 分钟前
Docker Compose 配置指南
运维·docker·容器·docker-compose
catoop37 分钟前
K8s 无头服务(Headless Service)
云原生·容器·kubernetes
阿里嘎多学长1 小时前
docker怎么部署高斯数据库
运维·数据库·docker·容器
明 庭1 小时前
Ubuntu下通过Docker部署Caddy服务器
服务器·ubuntu·docker
liuxuzxx2 小时前
1.24.1-Istio安装
kubernetes·istio·service mesh
G_whang2 小时前
windos 安装docker
运维·docker·容器
道一云黑板报2 小时前
Flink集群批作业实践:七析BI批作业执行
大数据·分布式·数据分析·flink·kubernetes
Mitch3113 小时前
【漏洞复现】CVE-2021-45788 SQL Injection
sql·web安全·docker·prometheus·metersphere
运维小文3 小时前
K8S中的PV、PVC介绍和使用
docker·云原生·容器·kubernetes·存储
CYX_cheng3 小时前
Docker挂载
docker