部署 k8s 与配置项目
容器与云原生

部署 k8s 与配置项目

JACIN··20 分钟阅读

部署k8s(使用 k3s)#

一般在*/root/k8s进行配置*

vim /root/k8s/config.yaml

python
dtoken: "password"     # 你的密码。当想把另一台服务器加入到这个 K8s 集群,
  #   让它成为 Worker Node(打工节点)时,那台新机器需要提供这个 Token 才能入伙。
tls-san:
  - "127.0.0.1"                        # 你的公网IP
https-listen-port: 6443              # API 端口
write-kubeconfig-mode: "644"         # 权限设置

# 关键:禁用 Traefik,防止占用 80/443,因为有 nginx 了
disable:
  - traefik

# 2. 【核心修改】指定数据存储位置
# 所有的数据库、容器镜像、证书都会存到这里
data-dir: "/root/k8s/data"

# curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --config /root/k8s/config.yaml" sh -

部署命令

text
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --config /root/k8s/config.yaml" sh -

部署可视化#

python
kubectl apply -n portainer -f https://raw.githubusercontent.com/portainer/k8s/master/deploy/manifests/portainer/portainer.yaml

查看信息:

python
kubectl get svc -n portainer

这样就部署成功了
portainer   NodePort   10.43.245.87   <none>        9000:30777/TCP,9443:30779/TCP,30776:30776/TCP   133m

注意该应用只能 https 访问,如果 5 分钟没有设置密码,kubectl delete pod -n portainer --all 重新启动下。

这里贴一下我的 nginx, /etc/nginx/sites-available/k8s-ui

python
server {
    listen 443 ssl http2;
    server_name k8s-ui.jacin.me;
    ssl_certificate     /root/fast-proxy/ssl/origin.crt;
    ssl_certificate_key /root/fast-proxy/ssl/origin.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;
    location / {
        proxy_pass https://localhost:30779;
        proxy_ssl_verify off; ### 关闭验证
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";

        # 禁用代理缓冲
        proxy_buffering off;

        # 允许大文件上传(50M)
        client_max_body_size 50M;
    }
}

部署k8s 项目的配置信息#

我不喜欢在 ui 界面进行 add from form ,因为有很多内容无法设置,所以还是手撕 yaml 文件。

在 k8s/app

这里就是放置 yaml + env 信息

例如,从配置文件读取

python
kubectl create secret generic ragapi-env --from-env-file=ragapi.env

可以在这里进行修改:

配置 yaml

注意, type: RollingUpdate 是 可以滚动更新的配置

externalTrafficPolicy: Local 可以让内部 ip 变成真实访问者的 ip

python
# 第一部分:Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ragapi
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ragapi
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0 # 辞退策略:旧人没交接完,绝不辞退(零停机)
  template:
    metadata:
      labels:
        app: ragapi
    spec:
      containers:
      - name: ragapi
        image: hub.jacin.me/rag_api:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8006
        
        # ▼▼▼ 修改了这里 ▼▼▼
        # 只要这一段,它会自动把 ragapi-env 里所有的变量(WORKERS, PASSWORD等)注入进去
        envFrom:
        - secretRef:
            name: ragapi-env
        # ▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲

      imagePullSecrets:
      - name: registry-1

--- 
# 第二部分:Service (这部分保持不变)
apiVersion: v1
kind: Service
metadata:
  name: ragapi
  namespace: default
spec:
  type: NodePort
  # ▼▼▼▼▼▼ 加入这一行核心配置,可以展示 ip ▼▼▼▼▼▼
  externalTrafficPolicy: Local
  # ▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
  selector:
    app: ragapi
  ports:
    - protocol: TCP
      port: 18006 # 公司内线:内部同事打这个电话 (ClusterIP 端口)
      targetPort: 8006  # 最终灶台:转接到厨师的哪个耳朵 (容器端口)
      nodePort: 31817 # 对外窗口:顾客打这个电话 (公网端口)

K8s 为了安全,把配置分成了两类:

  1. ConfigMap (配置字典):不敏感的信息。
    • 比如:WORKERS=5, LOG_LEVEL=INFO, THEME=DARK
    • 这就像贴在墙上的**“公司规章制度”**,谁看都无所谓。
  2. Secret (保密字典):敏感的信息。
    • 比如:PASSWORD, API_KEY, SSH_PRIVATE_KEY
    • 这就像放在**“保险柜”**里的机密文件。

“Docker Compose 的 .env 就像把银行卡密码写在了便利贴上,贴在屏幕边。 方便是方便,但谁都能看见。

Kubernetes 的 Secret 就像把密码锁进了保险柜。 当程序启动时,K8s 会悄悄把密码取出来告诉程序,用完立刻销毁,绝不在硬盘上留下痕迹。”

service与deployment#

  • Deployment 专注内部运维:怎么更新代码、要多少副本、环境变量是什么。
  • Service 专注流量治理:负载均衡、服务发现、要不要暴露公网。

核心逻辑:动静分离

  • Deployment (部署) = 餐厅后厨团队 (里子)
    • 特点:动态的。
    • 厨师(Pod)会生病(Crash)、会换班(Update)、会因为生意好增加人手(Scale)。
    • 每个厨师都有自己的工号(Pod IP),但这个工号是临时的,随时会变。
  • Service (服务) = 餐厅前台/接待 (面子)
    • 特点:静态的。
    • 前台电话(Service IP)和门牌号(NodePort)是永久不变的。
    • 顾客不需要知道今天是“张三”炒菜还是“李四”炒菜,顾客只管找前台点餐,前台负责把单子递给当前正在上班且健康的厨师。
  • 当你更新 Deployment 时,旧 Pod 销毁,新 Pod 产生,IP 全变了。
  • 但是 Service 完全不动,IP 和端口都不变。
  • Service 只是默默地修改了手里的“员工名单”(Endpoints),把流量指向了新的 Pod。外部用户感觉不到任何变化。

kubectl 常用命令#

1. 查看容器状态 (docker ps)

python
# 查看 Pod (最常用的)
kubectl get pods

# 查看更详细的信息 (比如 IP、所在节点)
kubectl get pods -o wide

# 查看所有东西 (Pod, Service, Deployment 一锅端)
kubectl get pod,svc,deploy

2. 查看日志 (docker logs)

python

# -l app=ragapi 意思是:我要看所有贴了 "app: ragapi" 标签的 Pod 的日志
kubectl logs -f -l app=ragapi

3. 查看资源占用 (docker stats)

python
# 查看 Pod 的资源占用
kubectl top pods

# 查看节点的资源占用 (你的 VPS 还能扛得住吗?)
kubectl top nodes

4. 进入容器内部 (docker exec)

python
# 格式:kubectl exec -it <Pod名字> -- <命令>
kubectl exec -it ragapi-676879fb8c-xxxxx -- /bin/bash

# 如果进不去,试试 /bin/sh (有的精简镜像没有 bash)
kubectl exec -it ragapi-676879fb8c-xxxxx -- /bin/sh

5. 重启容器 (docker restart) K8s 没有直接的 restart pod 命令。因为 Pod 是“一次性”的,所谓的重启其实是**“杀旧换新”**。 •

K8s (优雅做法): 重启 Deployment(这会触发滚动更新):

python
kubectl rollout restart deployment/ragapi

K8s (暴力做法): 直接删掉 Pod,K8s 会立马自动新建一个:

python
kubectl delete pod ragapi-676879fb8c-xxxxx

评论

还没有评论,来发第一个吧