可能并非最佳实现, 没有进行系统性学习, 欢迎交流
镜像
镜像管理
安装镜像管理平台 Harbor, 来为集群提供镜像源
在上一篇, 介绍了集群的搭建, 在那个时候配置了集群的镜像源, 也就是说, 这个集群有简单的拉镜像能力, 其次, 安装了 helm, 可以根据 helm 仓库拉取应用
这里介绍拉取原始chart仓库的相关文件的方法安装
- 获取chart仓库的文件
前往 harbor-helm 的 github 仓库
前往 release, 下载源代码, 解压之后拿到其中的templates
文件夹,Chart.yaml
文件,values.yaml
文件 - 修改
values.yaml
文件
详见 附录一我们的小集群既没有https, 又没有持久化存储, 所以这些都不需要写在配置文件中, 直接关掉这些功能即可
admin 的初始化密码在网页登陆后也能改 - 创建 harbor 专属的 namespace
kubectl create namespace harbor
- 启动
cd /path/to/harbor
helm --namespace harbor install harbor .
如果对配置项后悔, 使用 以下命令更新
helm --namespace harbor upgrade harbor .
到 kubepi 中, 即可看到 harbor 的相关镜像在拉取了, 如果镜像配置正确的话, 过一段时间就会拉取成功
在 kubepi 中他会不断重试拉取, 实际上会缓慢拉取成功
我是2M小服务器拉了半个小时+
在拉取成功之后, 第一时间在刚刚 values.yaml
中配置的url中登录, 修改admin密码(如果没有修改默认密码)
向 Harbor 上传镜像
需要一台使用 docker 的机器, 向 Harbor 上传镜像 docker pull
这里我在安装好后才意识到, 我的集群使用的容器运行时 containerd, 好像没有能力对镜像进行修改, 只能对镜像进行部署, 所以令起了一台机子, 安装 docker, 配置镜像源(TODO)
另一种方案是重装集群, 使用 docker 作为 容器运行时, 但我没有选择这个方案
做好准备后 需要对 harbor 进行信任
没有 https 导致的, 有 https 可以跳过这一步
向 /etc/docker/daemon.json
写入
"insecure-registries": ["harbor_ip:port"]
你需要自行处理他的json语法
后, 使用
systemctl daemon-reload
systemctl restart docker
重启 docker
在配置好后, 可以推一个简单的 helloworld镜像
docker login harbor_ip:port
# 这里填入你的账号与密码. 我这里是 admin 与相对于的密码
docker run hello-world:latest
# 修改tag
docker tag hello-world:latest harbor_ip:port/library/hello-world:latest
docker push harbor_ip:port/library/hello-world:latest
登录到 harbor 控制台, 即可看到刚刚推送上来的镜像
集群拉取镜像
如果你没有 https, 则需要以下额外一步, 如果有, 则保证集群可以连接到 harbor 即可
根据不同的集群搭建方法(这里是k3s), 将 harbor 添加进集群可以拉取的镜像源
与普通添加镜像一致, 首先需要到 /etc/rancher/k3s
目录下
向其中的 registries.yaml
添加内容
mirrors:
harbor_ip:port:
endpoint:
- http://harbor_ip:port
configs:
harbor_ip:port:
auth:
username: 你的 harbor 账号
password: 你的 harbor 密码
这里可能
registries.yaml
已经有内容了(配置过镜像源), 你需要根据 yaml 的语法自行处理他们的关系
每一台集群都要这么做
之后, 重启即可
systemctl restart k3s # systemctl restart k3s-agent if agent
在编写好 kubectl 使用的 yaml 后, 即可从 harbor 拉取镜像
感谢 claude-sonnet 帮我写yaml
实战
这里搭建了一个求生之路2的服务器
这里应该有一个求生之路2的简单介绍
docker机子拉取镜像
这里使用的是 HoshinoRei/l4d2server-docker
docker pull hoshinorei/l4d2server:edge
提交镜像
docker tag hoshinorei/l4d2server:edge harbor_ip:port/library/hoshinorei/l4d2server:edge
docker push harbor_ip:port/library/hoshinorei/l4d2server:edge
编写 kubectl 使用的 yaml
Details
apiVersion: apps/v1
kind: Deployment
metadata:
name: l4d2server
spec:
replicas: 1
selector:
matchLabels:
app: l4d2server
template:
metadata:
labels:
app: l4d2server
spec:
containers:
- name: l4d2server
image: harbor_ip:port/library/hoshinorei/l4d2server:edge
command: ["/home/steam/l4d2server/srcds_run", "-game left4dead2", "-secure", "+exec", "server.cfg", "+map", "c1m1_hotel", "-port", "27015", "-tickrate 60", "+sv_setmax 31"]
ports:
- containerPort: 27015
name: tcp-game
- containerPort: 27015
protocol: UDP
name: udp-game
volumeMounts:
- name: addons
mountPath: /home/steam/l4d2server/left4dead2/addons/
- name: server-config
mountPath: /home/steam/l4d2server/left4dead2/cfg/server.cfg
subPath: server.cfg
- name: host-file
mountPath: /home/steam/l4d2server/left4dead2/host.txt
subPath: host.txt
- name: motd-file
mountPath: /home/steam/l4d2server/left4dead2/motd.txt
subPath: motd.txt
- name: cfg
mountPath: /home/steam/l4d2server/left4dead2/cfg/
volumes:
- name: addons
hostPath:
path: /root/l4d2/addons/
type: Directory
- name: server-config
hostPath:
path: /root/l4d2/cfg/
- name: host-file
configMap:
name: l4d2server-host
- name: motd-file
configMap:
name: l4d2server-motd
- name: cfg
hostPath:
path: /root/l4d2/cfg/
type: Directory
---
apiVersion: v1
kind: Service
metadata:
name: l4d2server
spec:
type: NodePort
ports:
- name: tcp-game
port: 27015
targetPort: 27015
protocol: TCP
nodePort: 30015
- name: udp-game
port: 27015
targetPort: 27015
protocol: UDP
nodePort: 30016
selector:
app: l4d2server
---
apiVersion: v1
kind: ConfigMap
metadata:
name: l4d2server-host
data:
host.txt: |
# 这里放置 host.txt 的内容
---
apiVersion: v1
kind: ConfigMap
metadata:
name: l4d2server-motd
data:
motd.txt: |
# 这里放置 motd.txt 的内容
具体的参数细节参考 这里
需要在当前目录创建host.txt
与motd.txt
, 并在里面输入内容, 在服务器进入的时候会显示这些内容
执行
kubectl apply -f l4d2server.yaml
其他
挂载了宿主机的目录来放置 l4d2 mod
进入 kubepi 中, 查看具体被分配到了哪台机子上, 然后去那台机子的 ~/cfg 中, 放置 原始 l4d2 服务器的 cfg (可以通过刚开始的 docker 机子, 进入 docke 容器取得), 之后在 kubepi 重启即可
如果需要添加 mods, 则将 mod 移动到 addons 跟 cfg 中即可(注意 linux 兼容性), 然后重启, 如果需要更改启动命令则需要修改原 yaml
附录
一
这里给出常用的 harbor 的 values.yaml 的选项, 复制自 (https://blog.starry-s.moe/posts/2023/harbor-helm-chart/)
修改的选项
expose:
# expose type, 可以设置为 ingress, clusterIP, nodePort, nodeBalancer,区分大小写
# 默认为 ingress(如果不想使用 80/443 标准端口,可以设置为 nodePort,端口为高位 3000X)
type: ingress
tls:
# 是否启用 TLS (HTTPS),建议启用
enabled: true
# TLS Certificate 的来源,可以为 auto, secret 或 none
# 如果为 secret,需要在安装 Chart 之前先创建 TLS Secret
# 1) auto: generate the tls certificate automatically
# 2) secret: read the tls certificate from the specified secret.
# The tls certificate can be generated manually or by cert manager
# 3) none: configure no tls certificate for the ingress. If the default
# tls certificate is configured in the ingress controller, choose this option
certSource: secret
secret:
# The name of secret which contains keys named:
# "tls.crt" - the certificate
# "tls.key" - the private key
secretName: "harbor-tls"
# Only needed when the "expose.type" is "ingress".
notarySecretName: "harbor-tls"
ingress:
hosts:
# Ingress Host,如果需要允许任意域名/IP 都能访问,将其设置为空字符串(不建议)
# 这里填写的域名务必能解析到当前集群
core: harbor.example.com
notary: notary.example.com
# Harbor external URL
# 与 Ingress Host 相对应,如果启用了 TLS,那就是 https://<domain>
# 如果没启用 TLS,那就是 http://<domain>
# 如果 expose type 为 nodePort,则填写 http(s)://<IP_ADDRESS>:3000X (端口号不能丢)
externalURL: https://harbor.example.com
# 持久卷配置,默认为 true,如果是测试环境可以设置为 enabled: false (重新安装 Chart 时仓库里所有的数据都会丢失,不建议!)
# 如果需要启用持久卷,可以在安装 Chart 之前提前创建好 PVC,并配置 subPath
persistence:
enabled: true
resourcePolicy: "keep"
persistentVolumeClaim:
registry:
# 填写已经创建好的 PVC
existingClaim: "harbor-pvc"
storageClass: ""
# 如果共用一个 PVC,需要设置子目录
subPath: "registry"
accessMode: ReadWriteOnce
size: 5Gi
annotations: {}
jobservice:
jobLog:
existingClaim: "harbor-pvc"
storageClass: ""
subPath: "jobservice"
accessMode: ReadWriteOnce
size: 1Gi
annotations: {}
database:
existingClaim: "harbor-pvc"
storageClass: ""
subPath: "database"
accessMode: ReadWriteOnce
size: 1Gi
annotations: {}
redis:
existingClaim: "harbor-pvc"
storageClass: ""
subPath: "redis"
accessMode: ReadWriteOnce
size: 1Gi
annotations: {}
trivy:
existingClaim: "harbor-pvc"
storageClass: ""
subPath: "trivy"
accessMode: ReadWriteOnce
size: 5Gi
annotations: {}
# Admin 初始密码
harborAdminPassword: "Harbor12345"