Actions Runner Controller
Introduction
Section titled “Introduction”Actions Runner Controller(ARC)是一个 Kubernetes operator,用于编排并伸缩 Gitea Actions 的自托管 Runner。更多信息参见 Kubernetes 官方文档中的 Operator pattern。
借助 ARC,您可以创建 runner scale set,它会根据仓库(repository)、组织(organization)或企业(enterprise)中正在运行的工作流数量自动伸缩。由于受控的 Runner 可以是基于容器的临时实例,新的 Runner 实例能够快速、干净地扩容或缩容。
Prerequisites
Section titled “Prerequisites”要使用 ARC,请确保满足以下条件。
- 已激活的 Gitea Enterprise Edition,版本号高于 23.8.0
- 一个 Kubernetes 集群
Local Persistent Volume
Section titled “Local Persistent Volume”kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.31/deploy/local-path-storage.yaml成功后的输出与以下内容类似。
namespace/local-path-storage createdserviceaccount/local-path-provisioner-service-account createdrole.rbac.authorization.k8s.io/local-path-provisioner-role createdWarning: resource clusterroles/local-path-provisioner-role is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.clusterrole.rbac.authorization.k8s.io/local-path-provisioner-role configuredrolebinding.rbac.authorization.k8s.io/local-path-provisioner-bind createdWarning: resource clusterrolebindings/local-path-provisioner-bind is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.clusterrolebinding.rbac.authorization.k8s.io/local-path-provisioner-bind configureddeployment.apps/local-path-provisioner createdWarning: resource storageclasses/local-path is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.storageclass.storage.k8s.io/local-path configuredconfigmap/local-path-config created关于 local-path-provisioner 的更多信息,参见 local-path-provisioner README
Installing Actions Runner Controller
Section titled “Installing Actions Runner Controller”cat > install.yml << EOFapiVersion: v1kind: Namespacemetadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: runner-controller control-plane: controller-manager name: runner-controller-system---apiVersion: apiextensions.k8s.io/v1kind: CustomResourceDefinitionmetadata: annotations: controller-gen.kubebuilder.io/version: v0.16.1 name: runners.gitea.comspec: group: gitea.com names: kind: Runner listKind: RunnerList plural: runners singular: runner scope: Namespaced versions: - name: v1 schema: openAPIV3Schema: description: Runner is the Schema for the runners API properties: apiVersion: description: |- APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: description: |- Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object spec: description: RunnerSpec defines the desired state of Runner properties: affinity: description: Affinity is the affinity for the runner pods properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. items: description: |- An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated with the corresponding weight. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: description: |- A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: description: |- Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: description: |- An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. items: description: |- A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: description: |- Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: description: |- An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic weight: description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. format: int32 type: integer required: - preference - weight type: object type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: description: |- A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: description: |- A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: description: |- Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: description: |- An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. items: description: |- A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: description: |- Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: description: |- An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic type: array x-kubernetes-list-type: atomic required: - nodeSelectorTerms type: object x-kubernetes-map-type: atomic type: object podAffinity: description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) properties: podAffinityTerm: description: Required. A pod affinity term, associated with the corresponding weight. properties: labelSelector: description: |- A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: description: |- A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: description: |- operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: description: |- values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string description: |- matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: description: |- A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: description: |- operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: description: |- values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string description: |- matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: description: |- namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: description: |- weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer required: - podAffinityTerm - weight type: object type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. items: description: |- Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key <topologyKey> matches that of any node on which a pod of the set of pods is running properties: labelSelector: description: |- A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: description: |- A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: description: |- operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: description: |- values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string description: |- matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: description: |- A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: description: |- operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: description: |- values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string description: |- matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: description: |- namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. type: string required: - topologyKey type: object type: array x-kubernetes-list-type: atomic type: object podAntiAffinity: description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) properties: podAffinityTerm: description: Required. A pod affinity term, associated with the corresponding weight. properties: labelSelector: description: |- A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: description: |- A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: description: |- operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: description: |- values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string description: |- matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: description: |- A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: description: |- operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: description: |- values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string description: |- matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: description: |- namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: description: |- weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer required: - podAffinityTerm - weight type: object type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. items: description: |- Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key <topologyKey> matches that of any node on which a pod of the set of pods is running properties: labelSelector: description: |- A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: description: |- A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: description: |- operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: description: |- values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string description: |- matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: description: |- A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: description: |- operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: description: |- values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string description: |- matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: description: |- namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. type: string required: - topologyKey type: object type: array x-kubernetes-list-type: atomic type: object type: object cacheServer: description: |- CacheServer is the cache server spec. NOTE: If runnerConfigMapName is set, this cacheServer config is ignored and no built-in cache server is created. properties: externalSecret: description: |- ExternalSecret is the shared secret between the runner and the external cache server. Required by gitea-runner when external_server is in use: the runner pre-registers each job's ACTIONS_RUNTIME_TOKEN with the cache-server, which enforces bearer auth + per-repo cache isolation. Ignored when ExternalServerURL is empty. type: string externalServerURL: description: |- ExternalServerURL is the external cache server URL. If it's set, the controller will use this external cache server and won't create a cache-server. Host and Port will be ignored. type: string host: description: Host is the host for the cache server type: string port: default: 80 description: |- Port is the port for the cache server NOTE: act_runner's built-in cache server does not support TLS, so 443 is not recommended. format: int32 type: integer type: object gitea: description: Gitea is the Gitea spec properties: instanceUrl: description: InstanceUrl is the URL of the Gitea instance format: url type: string registrationToken: description: RegistrationToken is the registration token of the runner type: string skipTlsVerify: default: false description: SkipTlsVerify is the skip TLS verify flag type: boolean required: - instanceUrl - registrationToken type: object imagePullSecrets: description: ImagePullSecrets are the image pull secrets for the runner pods items: description: |- LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace. properties: name: default: "" description: |- Name of the referent. This field is effectively required, but due to backwards compatibility is allowed to be empty. Instances of this type with an empty value here are almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names type: string type: object x-kubernetes-map-type: atomic type: array nodeSelector: additionalProperties: type: string description: NodeSelector is the node selector for the runner pods type: object runtime: default: image: gitea/runner:nightly-dind labels: ubuntu-20.04: docker://gitea/runner-images:ubuntu-20.04 ubuntu-22.04: docker://gitea/runner-images:ubuntu-22.04 ubuntu-latest: docker://gitea/runner-images:ubuntu-latest description: Runtime is the runtime spec properties: configMapMounts: description: ConfigMapMounts are additional ConfigMap mounts for runner pods. items: properties: configMapName: description: ConfigMapName is the name of the ConfigMap to mount. type: string defaultMode: description: 'DefaultMode is optional: mode bits used to set permissions on created files by default.' format: int32 type: integer items: description: Items is a list of key-to-path mappings to project from the config map. items: description: Maps a string key to a path within a volume. properties: key: description: key is the key to project. type: string mode: description: |- mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set. format: int32 type: integer path: description: |- path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. type: string required: - key - path type: object type: array mountPath: description: MountPath is the path to mount the config map. type: string optional: description: Optional specifies whether the ConfigMap or its keys must be defined. type: boolean readOnly: description: ReadOnly indicates if the volume should be mounted read-only. type: boolean volumeName: description: VolumeName is the volume name for the config map mount. type: string required: - configMapName - mountPath - volumeName type: object type: array envs: description: Envs are additional environment variables written into runner config (runner.envs in config.yaml). items: properties: name: description: Name is the environment variable name. type: string value: description: Value is the environment variable value. type: string required: - name - value type: object type: array image: default: gitea/runner:nightly-dind description: Image is the image of the runner type: string imagePullPolicy: description: |- ImagePullPolicy controls when the runner image is pulled. Leave unset to use the kubelet default. enum: - Always - IfNotPresent - Never type: string labels: additionalProperties: type: string default: ubuntu-20.04: docker://gitea/runner-images:ubuntu-20.04 ubuntu-22.04: docker://gitea/runner-images:ubuntu-22.04 ubuntu-latest: docker://gitea/runner-images:ubuntu-latest description: Labels is the labels of the runner type: object pvcMounts: description: |- PVCMounts mount existing PVCs into runner worker pods. When runnerConfigMapName is not set, their mount paths are also added to container.valid_volumes so workflows can explicitly use them. items: properties: claimName: description: ClaimName is the name of an existing PVC in the same namespace as the runner worker pod. type: string mountPath: description: |- MountPath is the absolute container path to mount the PVC in the runner worker pod. The same path is added to container.valid_volumes when config.yaml is auto-generated. type: string readOnly: default: true description: ReadOnly controls whether the PVC mount is read-only. Defaults to true. type: boolean volumeName: description: VolumeName is the volume name for the PVC mount. type: string required: - claimName - mountPath - volumeName type: object x-kubernetes-validations: - message: mountPath must be an absolute path rule: self.mountPath.startsWith('/') type: array runnerConfigMapName: description: |- RunnerConfigMapName specifies an existing ConfigMap to mount as the runner config. If set, the controller will NOT generate a ConfigMap and any auto-generated settings (Labels, Gitea SkipTlsVerify/insecure, CacheServer URL, etc.) will be ignored, and the built-in cache server will not be created. type: string secretMounts: description: SecretMounts are additional secret mounts for runner pods. items: properties: defaultMode: description: |- defaultMode is Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set. format: int32 type: integer items: description: |- items If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. items: description: Maps a string key to a path within a volume. properties: key: description: key is the key to project. type: string mode: description: |- mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set. format: int32 type: integer path: description: |- path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. type: string required: - key - path type: object type: array x-kubernetes-list-type: atomic mountPath: description: MountPath is the path to mount the secret. type: string optional: description: optional field specify whether the Secret or its keys must be defined type: boolean readOnly: description: ReadOnly indicates if the volume should be mounted read-only. type: boolean secretName: description: |- secretName is the name of the secret in the pod's namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret type: string volumeName: description: VolumeName is the volume name for the secret mount. type: string required: - mountPath - volumeName type: object x-kubernetes-validations: - message: secretName is required rule: has(self.secretName) type: array required: - labels type: object scalability: default: cpuRequest: "2" maxSize: 10 memoryRequest: 4Gi description: Scalability is the scalability spec properties: cpuRequest: anyOf: - type: integer - type: string default: "2" description: CpuRequest is the CPU request of each runner pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true maxSize: default: 10 description: MaxSize is the maximum size of the runner maximum: 9999 minimum: 1 type: integer memoryRequest: anyOf: - type: integer - type: string default: 4Gi description: MemoryRequest is the memory request of each runner pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: object storage: default: cacheServerVolumeSize: 500Gi cacheVolumeSize: 100Gi className: standard dataVolumeSize: 100Mi description: Storage is the storage spec properties: cacheServerVolumeSize: anyOf: - type: integer - type: string default: 500Gi description: CacheServerVolumeSize is the size of the cache server volume pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true cacheVolumeSize: anyOf: - type: integer - type: string default: 100Gi description: CacheVolumeSize is the size of the cache volume pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true className: default: standard description: ClassName is the storage class name type: string dataVolumeSize: anyOf: - type: integer - type: string default: 100Mi description: DataVolumeSize is the size of the data volume pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: object required: - gitea type: object status: description: RunnerStatus defines the observed state of Runner properties: targetSize: type: integer targetSizeUpdatedAt: format: date-time type: string required: - targetSize - targetSizeUpdatedAt type: object type: object served: true storage: true subresources: status: {}---apiVersion: v1kind: ServiceAccountmetadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: runner-controller name: runner-controller-controller-manager namespace: runner-controller-system---apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: runner-controller name: runner-controller-leader-election-role namespace: runner-controller-systemrules:- apiGroups: - "" resources: - configmaps verbs: - get - list - watch - create - update - patch - delete- apiGroups: - coordination.k8s.io resources: - leases verbs: - get - list - watch - create - update - patch - delete- apiGroups: - "" resources: - events verbs: - create - patch---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: runner-controller-manager-rolerules:- apiGroups: - "" resources: - configmaps - events - persistentvolumeclaims - persistentvolumes - pods - secrets - services verbs: - create - delete - get - list - patch - update - watch- apiGroups: - gitea.com resources: - runners verbs: - create - delete - get - list - patch - update - watch- apiGroups: - gitea.com resources: - runners/finalizers verbs: - update- apiGroups: - gitea.com resources: - runners/status verbs: - get - patch - update---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: runner-controller-metrics-auth-rolerules:- apiGroups: - authentication.k8s.io resources: - tokenreviews verbs: - create- apiGroups: - authorization.k8s.io resources: - subjectaccessreviews verbs: - create---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: runner-controller-metrics-readerrules:- nonResourceURLs: - /metrics verbs: - get---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: runner-controller name: runner-controller-runner-editor-rolerules:- apiGroups: - gitea.com resources: - runners verbs: - create - delete - get - list - patch - update - watch- apiGroups: - gitea.com resources: - runners/status verbs: - get---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: runner-controller name: runner-controller-runner-viewer-rolerules:- apiGroups: - gitea.com resources: - runners verbs: - get - list - watch- apiGroups: - gitea.com resources: - runners/status verbs: - get---apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: runner-controller name: runner-controller-leader-election-rolebinding namespace: runner-controller-systemroleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: runner-controller-leader-election-rolesubjects:- kind: ServiceAccount name: runner-controller-controller-manager namespace: runner-controller-system---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: runner-controller name: runner-controller-manager-rolebindingroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: runner-controller-manager-rolesubjects:- kind: ServiceAccount name: runner-controller-controller-manager namespace: runner-controller-system---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: runner-controller-metrics-auth-rolebindingroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: runner-controller-metrics-auth-rolesubjects:- kind: ServiceAccount name: runner-controller-controller-manager namespace: runner-controller-system---apiVersion: v1kind: Servicemetadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: runner-controller control-plane: controller-manager name: runner-controller-controller-manager-metrics-service namespace: runner-controller-systemspec: ports: - name: https port: 8443 protocol: TCP targetPort: 8443 selector: control-plane: controller-manager---apiVersion: apps/v1kind: Deploymentmetadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: runner-controller control-plane: controller-manager name: runner-controller-controller-manager namespace: runner-controller-systemspec: replicas: 1 selector: matchLabels: control-plane: controller-manager template: metadata: annotations: kubectl.kubernetes.io/default-container: manager labels: control-plane: controller-manager spec: containers: - args: - --metrics-bind-address=:8443 - --leader-elect - --health-probe-bind-address=:8081 command: - /manager image: commitgo/runner-controller:v0.6.0 livenessProbe: httpGet: path: /healthz port: 8081 initialDelaySeconds: 15 periodSeconds: 20 name: manager readinessProbe: httpGet: path: /readyz port: 8081 initialDelaySeconds: 5 periodSeconds: 10 resources: limits: cpu: 500m memory: 128Mi requests: cpu: 10m memory: 64Mi securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL securityContext: runAsNonRoot: true serviceAccountName: runner-controller-controller-manager terminationGracePeriodSeconds: 10EOFkubectl apply -f install.yml成功后的输出与以下内容类似。
namespace/runner-controller-system createdcustomresourcedefinition.apiextensions.k8s.io/runners.gitea.com createdserviceaccount/runner-controller-controller-manager createdrole.rbac.authorization.k8s.io/runner-controller-leader-election-role createdclusterrole.rbac.authorization.k8s.io/runner-controller-manager-role createdclusterrole.rbac.authorization.k8s.io/runner-controller-metrics-auth-role createdclusterrole.rbac.authorization.k8s.io/runner-controller-metrics-reader createdclusterrole.rbac.authorization.k8s.io/runner-controller-runner-editor-role createdclusterrole.rbac.authorization.k8s.io/runner-controller-runner-viewer-role createdrolebinding.rbac.authorization.k8s.io/runner-controller-leader-election-rolebinding createdclusterrolebinding.rbac.authorization.k8s.io/runner-controller-manager-rolebinding createdclusterrolebinding.rbac.authorization.k8s.io/runner-controller-metrics-auth-rolebinding createdservice/runner-controller-controller-manager-metrics-service createddeployment.apps/runner-controller-controller-manager createdConfiguration
Section titled “Configuration”cat > runner.yml << EOFapiVersion: gitea.com/v1kind: Runnermetadata: labels: app.kubernetes.io/name: runner-controller app.kubernetes.io/managed-by: kustomize name: "gitea-runner" # TODO,替换为您的名称,例如 my-runnerspec: gitea: instanceUrl: "Your Gitea instanlce URL" # TODO,替换为您的 Gitea 实例地址,例如 https://mygitea.com/ registrationToken: "<Your registration token>" # TODO,与注册 Runner 时使用的 token 相同 runtime: labels: ubuntu-latest: docker://gitea/runner-images:ubuntu-latest ubuntu-22.04: docker://gitea/runner-images:ubuntu-22.04 ubuntu-20.04: docker://gitea/runner-images:ubuntu-20.04 storage: className: "local-path" # TODO,应替换为您 k8s 集群中真实的 storage class scalability: maxSize: 10 cpuRequest: 4 memoryRequest: 8GiEOFMounting existing PVCs into runner worker pods
Section titled “Mounting existing PVCs into runner worker pods”spec.runtime.pvcMounts 可以将已有的 PersistentVolumeClaim(PVC)挂载到 Runner 工作 Pod 中,使工作流任务能够在共享存储上读写数据。
apiVersion: gitea.com/v1kind: Runnermetadata: name: gitea-runnerspec: # ... runtime: pvcMounts: - volumeName: shared-data claimName: my-existing-pvc mountPath: /mnt/shared readOnly: true每一项包含以下字段:
volumeName(必填):工作 Pod 规格中该卷所使用的名称,在pvcMounts内必须唯一。claimName(必填):已存在的 PVC 名称。该 PVC 必须已经存在于与 Runner 工作 Pod 相同的 namespace 中——controller 不会创建它。mountPath(必填):PVC 在工作 Pod 内被挂载的绝对容器路径。readOnly(可选):默认值为true。将其设为false可允许工作流任务写入该卷。
默认情况下,每个 mountPath 及其 mountPath/** 通配符也会被添加到工作 Pod 自动生成的 config.yaml 中的 container.valid_volumes。这使得工作流任务可以通过 container.volumes 将相同的路径挂载到其任务容器中,例如:
jobs: example: runs-on: ubuntu-latest container: image: ubuntu:latest volumes: - /mnt/shared:/data steps: - run: ls /dataUsing an external cache server
Section titled “Using an external cache server”默认情况下,controller 会为每个 Runner 都创建一个内置的缓存服务器(*-cache-server Pod)。若要改为复用已有的缓存服务器,请配置 spec.cacheServer.externalServerURL 与 spec.cacheServer.externalSecret。
apiVersion: gitea.com/v1kind: Runnermetadata: name: gitea-runnerspec: # ... cacheServer: externalServerURL: "http://my-cache-server.example.com/" externalSecret: "<shared bearer secret>"externalServerURL:设置后,controller 将不再创建内置的 cache-server Pod,工作 Pod 会改用该 URL。externalSecret:Runner 与外部缓存服务器之间共享的 bearer secret。Runner 使用该 secret 强制执行 bearer 认证。当externalServerURL为空时,该字段会被忽略。
要应用 runner.yml,运行:
kubectl apply -f runner.yml成功后的输出与以下内容类似。
runner.gitea.com/gitea-runner created
- 获取 Runner 相关的 Pod
NAME READY STATUS RESTARTS AGErunner-controller-controller-manager-ff9cbc7b-kbxzh 1/1 Running 0 14m- 获取 Runner 相关的日志
kubectl -n runner-controller-system logs -f runner-controller-controller-manager-ff9cbc7b-kbxzh
Using runner scale sets
Section titled “Using runner scale sets”现在您将创建并运行一个使用 runner scale set 的简单测试工作流。
在一个仓库中,创建一个类似以下示例的工作流。runs-on 的值应与您安装 autoscaling runner set 时使用的 Runner runtime label 名称一致。
-
在一个仓库中,创建一个类似以下示例的工作流。
runs-on的值应与您安装 autoscaling runner set 时使用的 Runner runtime label 名称一致。关于如何向仓库添加工作流的更多信息,参见 Quickstart for Gitea Actions。
name: Gitea Actions Demorun-name: ${{ gitea.actor }} is testing out Gitea Actionson: [push]jobs:Explore-Gitea-Actions:runs-on: ubuntu-lateststeps:- run: echo " The job was automatically triggered by a ${{ gitea.event_name }} event."- run: echo " This job is now running on a ${{ runner.os }} server hosted by Gitea!"- run: echo " The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."- name: Check out repository codeuses: actions/checkout@v4- run: echo " The ${{ gitea.repository }} repository has been cloned to the runner."- run: echo " The workflow is now ready to test your code on the runner."- name: List files in the repositoryrun: |ls ${{ gitea.workspace }}- run: echo " This job's status is ${{ job.status }}."


- 在工作流运行期间,若要查看正在创建的 Runner Pod,请在终端中运行以下命令。
kubectl get pods- 成功后的输出与以下内容类似。
NAME READY STATUS RESTARTS AGEgitea-runner-0001 1/1 Running 0 56sgitea-runner-cache-server 1/1 Running 0 26s