绝了!k3s (k8s) 安装 ollama 运行 deepseek 全流程揭秘,yaml全公开

举报
福大大架构师每日一题 发表于 2025/03/05 14:56:30 2025/03/05
170 0 0
【摘要】 🎯k3s (k8s) 环境搭建与 ollama 相关 yaml 文件部署在容器编排的世界中,k3s (k8s) 无疑是备受瞩目的存在。此次聚焦在 k3s (k8s) 环境下安装 ollama,并实现运行 deepseek。首先映入眼帘的是一个关键的 yaml 文件 ——ollama.yaml 。这个文件犹如整个部署流程的指挥棒,规定各项参数和配置信息。ollama.yaml 内容如下:# ...

🎯k3s (k8s) 环境搭建与 ollama 相关 yaml 文件部署

在容器编排的世界中,k3s (k8s) 无疑是备受瞩目的存在。此次聚焦在 k3s (k8s) 环境下安装 ollama,并实现运行 deepseek。首先映入眼帘的是一个关键的 yaml 文件 ——ollama.yaml 。这个文件犹如整个部署流程的指挥棒,规定各项参数和配置信息。ollama.yaml 内容如下:

# https://cloud.tencent.com/developer/article/2495842 环境变量

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: ollama
  name: ollama
  namespace: moonfdd
spec:
  strategy:
    type: Recreate
  replicas: 1
  selector:
    matchLabels:
      app: ollama
  template:
    metadata:
      labels:
        app: ollama
    spec:
      containers:
        - env:
            - name: OLLAMA_HOST
              value: "0.0.0.0"
            - name: OLLAMA_PORT
              value: "11434"
            - name: OLLAMA_NUM_PARALLEL
              value: "20" #默认是1
            - name: OLLAMA_ORIGINS
              value: "*"
            - name: OLLAMA_MODELS
              value: "/root/.ollama/models"
          image: 'ollama/ollama:0.5.12'
          command: ["ollama", "serve"]
          imagePullPolicy: IfNotPresent
          name: ollama
          volumeMounts:
            - mountPath: /root/.ollama/models/
              name: data
          resources:
            # nvidia.com/gpu: 1
            # memory: "24Gi"
            # limits:
            #   cpu: 200m
            #   memory: 200Mi
            # requests:
            #   cpu: 100m
            #   memory: 100Mi
        - image: 'ollama/ollama:0.5.12'
          command: ["sh", "-c", "while true; do ollama run deepseek-r1:1.5b; sleep 5; done"]
          imagePullPolicy: IfNotPresent
          name: ollamacmd
      volumes:
        - name: data
          hostPath:
            path: /root/k8s/moonfdd/ollama/root/.ollama/models/
            type: DirectoryOrCreate
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: ollama
  name: ollama
  namespace: moonfdd
spec:
  ports:
    - name: 11434-11434
      port: 11434
      protocol: TCP
      targetPort: 11434
      nodePort: 11434
  selector:
    app: ollama
  type: NodePort

📊ollama 安装与运行实际效果展示

命令如下:

kubectl apply -f ollama.yaml

运行结果如下:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
💻Go 语言调用 deepseek 接口代码分析

单纯有 ollama 环境运行起来还不够,还需要有与之交互的代码来发挥它的功能,这里就出现了 Go 语言调用 deepseek 接口的代码。go代码如下:

package main

import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"time"
)

type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

// 修改请求结构体,添加 Stream 字段
type DeepSeekRequest struct {
	Model       string    `json:"model"`
	Messages    []Message `json:"messages"`
	MaxTokens   int       `json:"max_tokens,omitempty"`
	Temperature float64   `json:"temperature,omitempty"`
	Stream      bool      `json:"stream"` // 新增流式控制字段
}

// 保持其他结构体不变...

const (
	localAPIURL = "http://172.16.11.111:11434/v1/chat/completions"
)

func main() {
	fmt.Println("开始")
	requestData := DeepSeekRequest{
		Model: "deepseek-r1:1.5b",
		Messages: []Message{
			{
				Role:    "user",
				Content: "微信公众号 福大大架构师每日一题 是谁",
			},
		},
		MaxTokens:   512000,
		Temperature: 1,
		Stream:      true, // 启用流式模式
	}

	requestBody, err := json.Marshal(requestData)
	if err != nil {
		panic("JSON编码失败: " + err.Error())
	}

	// 配置更合理的超时时间
	client := &http.Client{
		Transport: &http.Transport{
			DisableKeepAlives: true, // 🔴 关键设置:禁用连接复用
			MaxIdleConns:      1,
			IdleConnTimeout:   30 * time.Second,
		},
		Timeout: 10 * time.Minute, // 大模型响应时间较长
	}

	req, err := http.NewRequest("POST", localAPIURL, bytes.NewBuffer(requestBody))
	if err != nil {
		panic("创建请求失败: " + err.Error())
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Connection", "close") // 显式关闭连接
	req.Close = true
	resp, err := client.Do(req)
	if err != nil {
		panic("请求发送失败: " + err.Error())
	}
	defer resp.Body.Close()

	// 流式响应处理
	if resp.StatusCode != http.StatusOK {
		fmt.Printf("请求失败,状态码:%d\n", resp.StatusCode)
		return
	}

	// 使用 Scanner 逐行读取流式响应
	scanner := bufio.NewScanner(resp.Body)
	scanner.Buffer(make([]byte, 1024), 10*1024*1024) // 扩大缓冲区

	for scanner.Scan() {
		rawData := scanner.Bytes()
		if len(rawData) == 0 {
			continue
		}

		var chunk DeepSeekChunk
		err := json.Unmarshal(rawData[6:], &chunk)
		if err == nil {
			for i := 0; i < len(chunk.Choices); i++ {
				fmt.Print(chunk.Choices[i].Delta.Content)
			}
		} else {
			if string(rawData) == string("data: [DONE]") {

			} else {
				fmt.Println("\r\n接收失败:", err, string(rawData))
			}
			return
		}

	}

	// if err := scanner.Err(); err != nil {
	// 	fmt.Printf("\n流读取错误: %v\n", err)
	// }
}

// DeepSeekChunk 定义与提供的JSON结构相对应的结构体
type DeepSeekChunk struct {
	ID                string   `json:"id"`
	Object            string   `json:"object"`
	Created           int64    `json:"created"`
	Model             string   `json:"model"`
	SystemFingerprint string   `json:"system_fingerprint"`
	Choices           []Choice `json:"choices"`
}

type Choice struct {
	Index        int     `json:"index"`
	Delta        Delta   `json:"delta"`
	FinishReason *string `json:"finish_reason,omitempty"` // 使用指针以处理可能为null的情况 //null "stop"
}

type Delta struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

运行结果如下:

在这里插入图片描述

官网不联网运行结果如下:
在这里插入图片描述
官网联网运行结果如下:
在这里插入图片描述

🎊实际意义与展望

通过在 k3s (k8s) 上完成 ollama 的安装并运行 deepseek,以及编写 Go 语言调用接口代码这一系列操作,具有多方面的实际意义和深远的展望。从技术层面而言,这为开发者在特定的容器编排环境下集成模型服务提供了一套可参考的方法和实践经验。无论是对于后续想要在相似环境里部署其他模型,还是改进和优化当前模型的运行方式,都提供了宝贵参考范例。从应用场景角度来看,能够在这样的技术栈下调用模型进行文本处理、问答交互等,都能为诸多实际项目开发提供强大助力。比如开发智能客服系统、智能助手应用等。展望未来,这种技术实践将不断推动相关技术的发展和融合。随着模型的不断升级迭代,我们可以期待更多强大功能能够被整合进这样的环境里 。同时,通过持续改进和优化 yaml 文件配置以及代码实现细节,将进一步提升系统的性能和稳定性。也相信会有更多开发者基于此进行创新和拓展,探索出更多的应用可能和技术思路。就像一颗石子投入平静湖面,会泛起层层涟漪般,这项技术实践也将在整个技术领域里引发新的探索和变革浪潮。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。