1:添加Actions Runner Controller的Helm仓库
helm repo add actions-runner-controller https://actions-runner-controller.github.io/actions-runner-controller
helm repo update
2:创建GitHub Personal Access Token (PAT)
- 登录到你的GitHub账户。
- 访问设置页面,找到“Developer settings”部分。
- 在“Personal access tokens”中生成一个新的访问令牌,赋予它repo和admin:org的权限。
3:创建Kubernetes Secret
使用你的GitHub PAT创建一个Kubernetes Secret,以便Actions Runner Controller可以访问GitHub API。
# 创建命名空间
kubectl create namespace actions-runner-system
kubectl create secret generic actions-runner-controller-manager -n actions-runner-system --from-literal=github_token=<YOUR_GITHUB_TOKEN>
kubectl create secret generic controller-manager \-n actions-runner-system \--from-literal=github_token=<YOUR_GITHUB_TOKEN> # <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>
4:配置Helm values
下载Actions Runner Controller的默认配置文件,并根据需要进行修改,特别是添加Docker Pull Secret。
helm show values actions-runner-controller/actions-runner-controller --version 0.23.7 > values.yaml
# 目前只查看了下不知道配啥
5:安装Actions Runner Controller
使用Helm安装Actions Runner Controller到你的Kubernetes集群。
helm upgrade -i actions-runner-controller actions-runner-controller/actions-runner-controller \--version 0.23.7 \-n actions-runner-system
输出:
Release "actions-runner-controller" does not exist. Installing it now.
NAME: actions-runner-controller
LAST DEPLOYED: Mon Aug 26 16:14:06 2024
NAMESPACE: actions-runner-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:export POD_NAME=$(kubectl get pods --namespace actions-runner-system -l "app.kubernetes.io/name=actions-runner-controller,app.kubernetes.io/instance=actions-runner-controller" -o jsonpath="{.items[0].metadata.name}")export CONTAINER_PORT=$(kubectl get pod --namespace actions-runner-system $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")echo "Visit http://127.0.0.1:8080 to use your application"kubectl --namespace actions-runner-system port-forward $POD_NAME 8080:$CONTAINER_PORT
(X)
6:创建 Runner(不推荐)
不推荐原因:使用下面这种方式创建的runner,一次作业后就会销毁。我在Rancher中发现deploy-web-dev-runner的状态是notReady并找了很久的原因,因此最好不要用这种方式创建Runner。需要创建可以去看看步骤8
执行下面的命令,创建一个名为 deploy-web-dev-runner 的 Runner CR。
kubectl apply -f - <<EOF
apiVersion: actions.summerwind.dev/v1alpha1
kind: Runner
metadata:name: deploy-web-dev-runnernamespace: actions-runner-system
spec:repository: mingchangge/deployWebenv: []
EOF
查看Runner
kubectl get runner -n actions-runner-system deploy-web-dev-runner
输出:
NAME ENTERPRISE ORGANIZATION REPOSITORY GROUP LABELS STATUS MESSAGE WF REPO WF RUN AGE
deploy-web-dev-runner mingchangge/deployWeb Running 15s
在项目仓库的 Settings/Actions/Runners 中可以看到同名的 Runner,处于 idle 状态。
deploy-web-dev-runner没有指定namespace,则Runner建立在默认命名空间即default。
删除建立在默认命名空间资源的命令:kubectl delete runner deploy-web-dev-runner
7:项目推送
在你的GitHub Actions workflow中,将 runs-on 指定为 [self-hosted, linux, X64]
后推送项目,Runner运行。
最后runner运行成功
只是作业运行结果结果失败,报错如下:(Runner执行的机器中缺少node所以不识别npm命令,整个docker私有镜像安装node或许可以解决,目前不想直接在服务器中安装node。这个问题我目前一脑门子浆糊,往后稍稍。)
...
Run echo "npm install"
npm install
/runner/_work/_temp/aadcc564-e286-4996-8f54-5e0824cc9863.sh: line 3: npm: command not found
Error: Process completed with exit code 127.
7.1:排错
runner运行完2天后再次修改前端项目,推送github后,忽然发现作业找不到机器执行,github settings/Actions的Runner列表也没有之前部署的Runner了,截图如下:
Runner执行作业:
github项目settings/Actions/runners:
查看pod状态
kubectl get pods -n actions-runner-system
输出:
NAME READY STATUS RESTARTS AGE
actions-runner-controller-5c996cd9c7-gqm5g 2/2 Running 0 2d19h
deploy-web-dev-runner 1/2 NotReady 0 2d1h
kubectl describe pod deploy-web-dev-runner -n actions-runner-system
kubectl logs deploy-web-dev-runner -n actions-runner-system
kubectl get pods deploy-web-dev-runner -n actions-runner-system -o jsonpath='{.status.containerStatuses[*].ready}'
get pods deploy-web-dev-runner -n actions-runner-system -o jsonpath='{.status.containerStatuses[*].name}'
kubectl get pods deploy-web-dev-runner -n actions-runner-system -o yaml
以上命令均没有输出什么有价值的错误信息导致的Runner notReady,再根据 kubectl describe pod 命令的输出,deploy-web-dev-runner Pod 中的 runner 容器已经终止,状态为 Terminated,并且其退出状态是 Completed 退出码为 0。这表明容器已经成功执行并正常退出。但是,由于容器已经终止,它不会对 Ready 探针做出响应,因此 Kubernetes 报告该容器状态为 NotReady。从执行上来看runner 容器是个一次性任务执行器,NotReady 状态可能不是一个问题,而只是容器生命周期的一个正常部分。
8:创建可重用 Runner
根据网上的参考资料进行下一步创建可重用 Runner
kubectl apply -f - <<EOF
apiVersion: actions.summerwind.dev/v1alpha1
kind: RunnerDeployment
metadata:name: deploy-web-dev-runnernamespace: actions-runner-system
spec:template:spec:repository: mingchangge/deployWebenv: []
EOF
参考文章有言在先,怪我自己没有耐心看完。
actions-runner-controller 提供了三种 CRD:
- Runner:可以理解为 Pod,该 Runner 只能执行一次作业。
- RunnerDeployments:可以理解为Deployment,可以设置要创建的 Runner 数量。Runner 在执行完作业后会销毁,然后 Controller 会创建新的Runner 等待作业调度。
- RunnerSets:可以理解为 StatefulSet,也是基于 StatefulSet 来创建 Pod(即Runner),提供 StatefulSet 的特性。
更多用法,可以参考 actions-runner-controller 官方文档。
创建完可重用Runner,推送项目,发现创建的runner比之前多了一些后缀。
之前的推送处理完成后,本次推送才开始进行处理。
多个请求推送去 Actions 列表会发现,只有一个作业在运行,其他都是 queued 的等待状态。只有等前面的作业执行完成后,后一个作业才会被执行。
由上图可知执行多个任务时,任务需要排队等候不支持并发。但是actions-runner-controller 在 3 个 Runner 的 CRD 之外,还提供了类似 HPA(水平 pod 自动扩缩容) 的 CRD HorizontalRunnerAutoscaler,简称 HRA。
HRA 可以根据指标 PercentageRunnersBusy 或者 TotalNumberOfQueuedAndInProgressWorkflowRuns 来对 runner 进行扩缩容,或者基于 GitHub Events(webhook)来进行扩缩容。这两种都各有优缺点,前者指标是通过 GitHub API 轮训等待的作业数,实现简单,但时效性差;后者基于事件触发时效性更佳,但是实现复杂,需要对外暴露访问端点接收 GitHub Event。
下面的参考的文章是使用前一项的,所以我准备试试Webhook 驱动扩展,成不成功的先做个记录。
(X)
9:Webhook 驱动扩展
失败原因:转来转去又回到了原点,我的服务器连接不了外网,webhook timeout。目前两种解决方式可行:一、使用内网穿透工具如Ngrok,将内网的服务暴露到公网上,从而允许外部访问,不太好的方案;二、开个ssh隧道连接,但又一时找不到可用的服务器,此操作搁置。暂时不扩容了已经卡了很久很久,还是继续往下进行吧。
使用自定义 Kubernetes 入口控制器:
在actions-runner-system命名空间上创建一个新的部署和一个用于接收 Github Webhooks 的服务
helm upgrade --install --namespace actions-runner-system --create-namespace \--wait actions-runner-controller actions-runner-controller/actions-runner-controller \--set "githubWebhookServer.enabled=true"
输出:
Release "actions-runner-controller" has been upgraded. Happy Helming!
NAME: actions-runner-controller
LAST DEPLOYED: Fri Aug 30 10:48:23 2024
NAMESPACE: actions-runner-system
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:export POD_NAME=$(kubectl get pods --namespace actions-runner-system -l "app.kubernetes.io/name=actions-runner-controller,app.kubernetes.io/instance=actions-runner-controller" -o jsonpath="{.items[0].metadata.name}")export CONTAINER_PORT=$(kubectl get pod --namespace actions-runner-system $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")echo "Visit http://127.0.0.1:8080 to use your application"kubectl --namespace actions-runner-system port-forward $POD_NAME 8080:$CONTAINER_PORT
创建名为arc-webhook-server.yaml的Ingress 文件
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: actions-runner-controller-github-webhook-servernamespace: actions-runner-systemannotations:nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:ingressClassName: nginx # 使用这个字段来指定Ingress控制器tls:- hosts:- rancher.lxq.comsecretName: tls-rancher-ingressrules:- http:paths:- path: /actions-runner-controller-github-webhook-serverpathType: Prefixbackend:service:name: actions-runner-controller-github-webhook-serverport:number: 8090
kubectl apply -n actions-runner-system -f arc-webhook-server.yaml
GitHub新增webhook
- 配置 GitHub 开始向您发送 webhook,请转到您的存储库或组织的设置(Settings)页面,单击Webhooks后单击Add webhook。
- 使用您刚刚创建的 webhook URL 设置“Payload URL”字段,如果您遵循上面的示例,则 URL :
https://${您自己的域名}/actions-runner-controller-github-webhook-server - 点击“内容类型”并选择application/json。
- 点击“让我选择单个事件”并选择Workflow Jobs(我还选了几个其他的)。
- 点击Add Webhook。
创建完成后发现webhooke不能正常工作
无效尝试
创建一个针对节点端口的外部负载均衡器,该service一直是Pending状态。
vi webhook-service.yaml
apiVersion: v1 kind: Service metadata:name: webhook-servicenamespace: actions-runner-system # 或者是你的命名空间 spec:type: LoadBalancerexternalIPs:- 192.168.XX.XXXselector:app.kubernetes.io/instance: actions-runner-controller-github-webhook-serverapp.kubernetes.io/name: actions-runner-controllerpod-template-hash: 6b4f5cf858ports:- appProtocol: httpname: httpnodePort: 30080port: 8090protocol: TCPtargetPort: http
kubectl apply -f webhook-service.yaml
kubectl get service webhook-service -n actions-runner-system # 输出: NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE webhook-service LoadBalancer 10.96.127.64 <pending> 8090:30080/TCP 95m
参考
在 Kubernetes 上运行 GitHub Actions Self-hosted Runner
在 Kubernetes 上执行 GitHub Actions 流水线作业
automatically-scaling-runners.md
补充内容:
k8s小白使用命令记录:
查看 ingress配置
kubectl describe ingress -n cattle-system
查看secret
kubectl get secret tls-rancher-ingress -n cattle-system -o yaml
查看使用`kubectl apply -f 命令创建Kubernetes资源的命名空间
当你使用kubectl apply -f
命令创建Kubernetes资源时,资源的命名空间通常在YAML文件中指定。要查看或确认通过这种方式创建的资源的命名空间,你可以:
-
直接查看YAML文件:
在YAML文件中查找metadata
部分,看是否有namespace
字段。例如:metadata:name: my-resourcenamespace: my-namespace
如果
namespace
字段存在,那么资源就被创建在了这个命名空间内。如果namespace
字段不存在,那么资源将被创建在当前的kubectl
上下文中所设置的命名空间内,通常这会是default
命名空间。 -
使用
kubectl get
命令:
你也可以使用kubectl get
命令并指定-A
或--all-namespaces
参数来查看所有命名空间中的资源。例如,要查看所有命名空间中的所有资源,可以运行:kubectl get all --all-namespaces
从输出中,你可以找到你创建的资源,并看到它所在的命名空间。
-
使用
kubectl config
命令:
如果你想要知道当前kubectl
上下文的命名空间,可以使用:kubectl config current-context
然后查看你的
.kube/config
文件中当前上下文的namespace
字段。但是,这方法只能确认当前默认的命名空间,对于直接在YAML文件中指定的命名空间,还是需要查看YAML文件。
删除使用`kubectl apply -f 命令创建Kubernetes资源
使用kubectl apply -f
命令创建的Kubernetes资源,可以通过kubectl delete
命令或者再次使用apply
命令来删除。下面是两种删除资源的方法:
1. 使用kubectl delete
如果已知资源类型和名称,可以直接使用delete
命令:
kubectl delete <resource-type> <resource-name> --namespace=<namespace>
这里,你需要将<resource-type>
替换为资源的类型(如deployment
, service
, pod
等),<resource-name>
替换为资源的名称,<namespace>
替换为资源所在的命名空间。如果资源在默认命名空间中,可以省略--namespace=<namespace>
部分。
例如,删除名为my-service
的服务:
kubectl delete service my-service
如果删除的是由YAML文件创建的资源,而你不知道资源的确切类型或名称,可以通过YAML文件来删除:
kubectl delete -f <path-to-file>
将<path-to-file>
替换为YAML文件的路径。
2. 使用kubectl apply
和--delete-collection
如果你使用的是kubectl apply
,并且你的YAML文件中包含多个资源定义,你可以通过添加--delete-collection
标志来删除由该文件创建的所有资源。但要注意,这通常用于清理整个资源集合,并且可能不保留状态数据,所以在生产环境中使用时要格外小心。
kubectl apply -f <path-to-file> --delete-collection --force
这里,--delete-collection
选项告诉kubectl
删除与YAML文件匹配的所有资源,--force
则确保即使有运行中的Pod也会被强制删除。
但--delete-collection
并不是kubectl apply
的标准行为,它用于清理不再存在的资源。如果你的YAML文件只定义了一个资源,或者你只是想要删除一个特定的资源,使用kubectl delete
会更直接和安全。
示例
假设你有一个名为deployment.yaml
的文件,其中定义了一个名为web
的deployment和一个名为web-service
的服务。
要删除由这个文件创建的所有资源,可以使用:
kubectl delete -f deployment.yaml
或者,如果你想使用apply
来删除:
kubectl apply -f deployment.yaml --delete-collection --force
但请注意,--delete-collection
和--force
的使用要谨慎,确保你理解其行为和可能的后果。