• Русский
  • Быстрый старт

    Установка Tekton Results

    В этом документе описано, как установить Tekton Results с использованием существующей базы данных.

    NOTE

    В настоящее время встроенная база данных PostgreSQL не поддерживается, пожалуйста, используйте внешнюю базу данных.

    Подробнее о внешней базе данных см. Using PostgreSQL from Data Services

    Предварительные требования

    1. В кластере должны быть установлены Tekton Pipelines.

      TIP

      Следующие инструкции предполагают, что по умолчанию вы установили Results в namespace tekton-pipelines.

      Если вы установили его в другой namespace, замените tekton-pipelines на ваш namespace.

    2. Создайте root-пароль базы данных.

      Пользователи должны сгенерировать root-пароль базы данных и сохранить его в Kubernetes Secret перед установкой. По умолчанию Tekton Results ожидает, что этот Secret будет содержать следующие атрибуты:

      • Namespace: tekton-pipelines
      • Имя: tekton-results-postgres
      • Следующие поля:
        • POSTGRES_USER=<your_username>
        • POSTGRES_PASSWORD=<your_password>

      Вы можете быстро сгенерировать Secret с помощью следующей команды:

      kubectl create secret generic tekton-results-postgres --namespace="tekton-pipelines" --from-literal=POSTGRES_USER={POSTGRES} --from-literal=POSTGRES_PASSWORD={PASSWORD}
    3. Сгенерируйте пару сертификат/ключ. Примечание: для этого можно использовать любое ПО для управления сертификатами!

      Tekton Results ожидает, что пара сертификат/ключ будет храниться в TLS Kubernetes Secret с именем tekton-results-tls.

      • Сгенерируйте новый самоподписанный сертификат

        openssl req -x509 \
          -newkey rsa:4096 \
          -keyout key.pem \
          -out cert.pem \
          -days 365 \
          -nodes \
          -subj "/CN=tekton-results-api-service.tekton-pipelines.svc.cluster.local" \
          -addext "subjectAltName = DNS:tekton-results-api-service.tekton-pipelines.svc.cluster.local"
        TIP

        Если ваша версия openssl слишком старая и не поддерживает некоторые параметры, обновите openssl с помощью openssl binaries .

      • Создайте новый TLS Secret из сертификата.

        kubectl create secret tls -n tekton-pipelines tekton-results-tls \
          --cert=cert.pem \
          --key=key.pem
    4. Создайте PVC, если вы используете PVC для хранения логов.

      cat <<EOF | kubectl create -f -
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: tekton-logs
        namespace: tekton-pipelines
      spec:
        accessModes:
          - ReadWriteOnce  # Режим доступа, указывающий, что запись и чтение возможны с одной ноды
        resources:
          requests:
            storage: 100Gi  # Запрошенный размер хранилища
      EOF
      • При необходимости скорректируйте размер PVC.

    Установка с использованием TektonConfig CR

    $ cat <<EOF | kubectl create -f -
    apiVersion: operator.tekton.dev/v1alpha1
    kind: TektonConfig
    metadata:
      name: config
    spec:
      # Целевой namespace
      targetNamespace: tekton-pipelines
      result:
        # Обновите адрес базы данных
        db_host: <database_host>
        db_port: 5432
        db_name: <database_name>
        # Использовать внешнюю базу данных
        is_external_db: true
        # Secret, содержащий ранее созданные сведения об учетной записи базы данных
        db_secret_name: tekton-results-postgres
        # Основные настройки
        server_port: 8080
        # Отключить аутентификацию
        auth_disable: true
        db_enable_auto_migration: true
        log_level: debug
        # Использовать службу хранения логов
        logs_api: true
        logs_type: File
        # logs_type: S3
        # secret_name: tekton-results-s3-credentials
        logs_path: /logs
        logs_buffer_size: 92160
        logging_pvc_name: tekton-logs
    EOF

    :::details {title="Пояснение полей YAML"} В ресурсе TektonConfig targetNamespace настраивается в spec, а поля Tekton Results — в spec.result.

    • db_host: Host базы данных.
    • db_port: Port базы данных.
    • db_name: Имя базы данных.
    • is_external_db: Использовать ли внешнюю базу данных.
      • true: Использовать внешнюю базу данных.
    • db_secret_name: Имя Secret, содержащего сведения об учетной записи базы данных.
      • Это Secret, созданный на предыдущем шаге.
    • server_port: Port сервера.
    • targetNamespace: Namespace, в который развернуты Results.
    • auth_disable: Отключить ли аутентификацию.
    • db_enable_auto_migration: Включить ли автоматическую миграцию базы данных.
    • log_level: Уровень логирования.
    • logs_api: Включить ли Logs API.
      • true: Включить Logs API.
    • logs_type: Тип логов.
      • File: Хранить логи в файле.
      • S3: Хранить логи в объектном хранилище, совместимом с S3.
    • secret_name: Имя Secret, содержащего учетные данные S3.
    • logs_path: Путь к логам.
    • logs_buffer_size: Размер буфера логов.
    • logging_pvc_name: Имя PVC для хранения логов при использовании типа логов File.
      • Это PVC, созданный на предыдущем шаге. :::
    TIP

    Подробнее о конфигурации базы данных см. PostgreSQL Configuration

    После развертывания вы сможете увидеть, что статус results-api / results-retention-policy-agent / results-watcherRunning

    $ kubectl get pods -n tekton-pipelines
    
    NAME                                                    READY   STATUS    RESTARTS   AGE
    tekton-results-api-68bb657996-bb487                     1/1     Running   0          14s
    tekton-results-retention-policy-agent-c6ff5575b-prczg   1/1     Running   0          14s
    tekton-results-watcher-6d7c68f576-p2gbl                 1/1     Running   0          14s

    Проверка функциональности

    Функциональность можно проверить с помощью простого taskrun.

    1. Создайте ресурс TaskRun

    $ cat <<'EOF' | kubectl create -f -
    apiVersion: tekton.dev/v1
    kind: TaskRun
    metadata:
      name: hello
    spec:
      taskSpec:
        steps:
          - name: hello
            image: alpine
            command: ["echo", "hello"]
    EOF
    NOTE

    Для изолированных сред без доступа к сети измените адрес образа alpine на другой, доступный в сети

    2. Дождитесь завершения выполнения taskrun

    $ kubectl get taskruns.tekton.dev -n default -w
    
    hello                                        Unknown     Pending     3s
    hello                                        True        Succeeded   11s         0s

    3. Используйте curl для запроса результатов

    Дополнительные сценарии использования см. в официальной документации Tekton Results API

    Подготовка прав доступа
    $ cat <<EOF | kubectl create -f -
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: tekton-results-readonly
    rules:
      - apiGroups: ["results.tekton.dev"]
        resources: ["results", "records"]
        verbs: ["get", "list"]
    
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: tekton-results-impersonate
    rules:
      - apiGroups: [""]
        resources: ["users", "groups", "serviceaccounts"]
        verbs: ["impersonate"]
      - apiGroups: ["authentication.k8s.io"]
        resources: ["uids"]
        verbs: ["impersonate"]
    
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: tekton-results-impersonate
    subjects:
      - kind: ServiceAccount
        name: impersonate-admin
        namespace: tekton-pipelines
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: tekton-results-impersonate
    
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: tekton-results-user
    subjects:
      - kind: ServiceAccount
        name: impersonate-user
        namespace: user-namespace
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: tekton-results-readonly
    EOF
    Проверка прав доступа
    $ kubectl create --validate=false --as=system:serviceaccount:tekton-pipelines:tekton-results-watcher -n tekton-pipelines -f - -o yaml << EOF
    apiVersion: authorization.k8s.io/v1
    kind: SelfSubjectAccessReview
    spec:
      resourceAttributes:
        group: results.tekton.dev
        resource: results
        verb: get
    EOF
    
    apiVersion: authorization.k8s.io/v1
    kind: SelfSubjectAccessReview
    metadata:
      creationTimestamp: null
    spec:
      resourceAttributes:
        group: results.tekton.dev
        resource: results
        verb: get
    status:
      allowed: true
      reason: 'RBAC: allowed by ClusterRoleBinding "tekton-results-watcher" of ClusterRole
        "tekton-results-watcher" to ServiceAccount "tekton-results-watcher/tekton-pipelines"'
    Проброс портов

    Проксируйте службу на локальный порт 8080

    $ kubectl port-forward -n tekton-pipelines service/tekton-results-api-service 8080
    Получение Token
    $ token=$(kubectl create token impersonate-admin -n tekton-pipelines)
    Запрос результатов
    $ curl -s -k \
      -H 'authorization: Bearer '${token} \
      -H 'Impersonate-User: system:serviceaccount:user-namespace:impersonate-user' \
      https://localhost:8080/apis/results.tekton.dev/v1alpha2/parents/default/results
    
    {"results":[{"name":"default/results/0b165174-fd12-47f9-a8d8-c4ffcb1be0d4", "id":"65662a09-216a-4e6b-960c-260a2b05de9c", "uid":"65662a09-216a-4e6b-960c-260a2b05de9c", "createdTime":"2025-02-20T05:59:52.403661Z", "createTime":"2025-02-20T05:59:52.403661Z", "updatedTime":"2025-02-20T06:00:09.033206Z", "updateTime":"2025-02-20T06:00:09.033206Z", "annotations":{"object.metadata.name":"large-result-pipeline-run-c2mg4", "tekton.dev/pipeline":"large-result-pipeline"}, "etag":"65662a09-216a-4e6b-960c-260a2b05de9c-1740031209033206096", "summary":{"record":"default/results/0b165174-fd12-47f9-a8d8-c4ffcb1be0d4/records/0b165174-fd12-47f9-a8d8-c4ffcb1be0d4", "type":"tekton.dev/v1.PipelineRun", "startTime":null, "endTime":"2025-02-20T06:00:09Z", "status":"SUCCESS", "annotations":{}}}, {"name":"default/results/c308db48-9613-4652-8b5a-edd10eb9bda9", "id":"98d2bda3-2039-4e03-b78a-4e44637df4f2", "uid":"98d2bda3-2039-4e03-b78a-4e44637df4f2", "createdTime":"2025-02-20T05:25:44.226246Z", "createTime":"2025-02-20T05:25:44.226246Z", "updatedTime":"2025-02-20T13:12:20.823170Z", "updateTime":"2025-02-20T13:12:20.823170Z", "annotations":{"object.metadata.name":"hello"}, "etag":"98d2bda3-2039-4e03-b78a-4e44637df4f2-1740057140823170246", "summary":{"record":"default/results/c308db48-9613-4652-8b5a-edd10eb9bda9/records/c308db48-9613-4652-8b5a-edd10eb9bda9", "type":"tekton.dev/v1.TaskRun", "startTime":null, "endTime":"2025-02-20T13:12:20Z", "status":"SUCCESS", "annotations":{}}}, {"name":"default/results/e536090f-0819-46ae-86e6-1fe2fce6dc56", "id":"a7e8b252-bbce-4cb1-aa22-71cfb5a83639", "uid":"a7e8b252-bbce-4cb1-aa22-71cfb5a83639", "createdTime":"2025-02-20T13:13:33.323381Z", "createTime":"2025-02-20T13:13:33.323381Z", "updatedTime":"2025-02-20T13:13:45.480690Z", "updateTime":"2025-02-20T13:13:45.480690Z", "annotations":{"object.metadata.name":"large-result-pipeline-run-twnxc", "tekton.dev/pipeline":"large-result-pipeline"}, "etag":"a7e8b252-bbce-4cb1-aa22-71cfb5a83639-1740057225480690745", "summary":{"record":"default/results/e536090f-0819-46ae-86e6-1fe2fce6dc56/records/e536090f-0819-46ae-86e6-1fe2fce6dc56", "type":"tekton.dev/v1.PipelineRun", "startTime":null, "endTime":"2025-02-20T13:13:45Z", "status":"SUCCESS", "annotations":{}}}], "nextPageToken":""}

    4. Используйте tkn-results CLI для запроса результатов

    Подготовка CLI

    tkn — это командная строка для работы с Tekton. Вы можете скачать ее со страницы проекта.

    Вам нужно собрать tkn-results с помощью golang.

    Не собирайте всегда из main. Используйте release branch, который соответствует версии Tekton Results, развернутой в вашей среде. Версию компонента Results можно найти в Release Notes (столбец Results), а затем выполнить checkout соответствующей ветки release-v<version>.x.

    # 1. Клонируйте репозиторий
    git clone https://github.com/tektoncd/results.git
    
    # 2. Перейдите в каталог проекта
    cd results
    
    # 3. Выполните checkout соответствующей release branch (пример: Results 0.15.x -> release-v0.15.x)
    git checkout release-v<version>.x
    
    # 4. Соберите бинарный файл
    go build -o tkn-results ./cmd/tkn-results/main.go
    
    # 5. Скопируйте бинарный файл в каталог, входящий в ваш PATH
    Поведение подключения

    Если --addr не задан, tkn-results попытается автоматически выполнить port-forward к Results API service.

    Во многих версиях (включая release-v0.15.x) целевым объектом автоматически будет tekton-pipelines/tekton-results-api-service. Если в вашем развертывании Results используется другой namespace или имя service, автоматический режим может не сработать.

    Если --addr задан, tkn-results подключается напрямую к этому адресу. В этом случае обычно нужно самостоятельно запускать kubectl port-forward.

    Запрос списка записей выполнения
    $ tkn results --insecure records list default/results/-
    
    default/results/209dcb81-e3c0-47cd-b082-d910e15702ae/records/209dcb81-e3c0-47cd-b082-d910e15702ae  tekton.dev/v1.TaskRun                   2025-02-19 16:17:11 +0800 CST           2025-02-19 16:17:21 +0800 CST
    default/results/209dcb81-e3c0-47cd-b082-d910e15702ae/records/a750035d-0479-34a1-9db2-9a256b53243f  results.tekton.dev/v1alpha3.Log         2025-02-19 16:17:21 +0800 CST           2025-02-19 16:17:21 +0800 CST
    Резервный вариант, если автоматический port-forward не сработал
    $ kubectl port-forward -n <results-namespace> service/tekton-results-api-service 8080
    
    $ tkn results --insecure --addr localhost:8080 records list default/results/-
    $ tkn results --insecure --addr localhost:8080 records get -o textproto default/results/<result-uid>/records/<record-uid>
    $ tkn results --insecure --addr localhost:8080 logs list default/results/-
    $ tkn results --insecure --addr localhost:8080 logs get -o textproto default/results/<result-uid>/logs/<log-uid>
    # Если logs get возвращает "unknown service tekton.results.v1alpha3.Logs", повторите команду с флагом:
    $ tkn results --insecure --addr localhost:8080 --v1alpha2 logs get -o textproto default/results/<result-uid>/logs/<log-uid>
    Запрос одной записи выполнения
    $ tkn results --insecure records get -o textproto default/results/209dcb81-e3c0-47cd-b082-d910e15702ae/records/209dcb81-e3c0-47cd-b082-d910e15702ae
    
    name: "default/results/209dcb81-e3c0-47cd-b082-d910e15702ae/records/209dcb81-e3c0-47cd-b082-d910e15702ae"
    id: "0805bbd0-e390-40dc-a1ea-f65ae9401930"
    uid: "0805bbd0-e390-40dc-a1ea-f65ae9401930"
    data: {
      type: "tekton.dev/v1.TaskRun"
      value: "{\"kind\": \"TaskRun\", \"spec\": {\"timeout\": \"1h0m0s\", \"taskSpec\": {\"steps\": [{\"name\": \"hello\", \"image\": \"152-231-registry.alauda.cn:60070/ops/ubuntu:latest\", \"command\": [\"echo\", \"hello\"], \"computeResources\": {}}]}, \"serviceAccountName\": \"default\"}, \"status\": {\"steps\": [{\"name\": \"hello\", \"imageID\": \"alpine\", \"container\": \"step-hello\", \"terminated\": {\"reason\": \"Completed\", \"exitCode\": 0, \"startedAt\": \"2025-02-19T08:17:20Z\", \"finishedAt\": \"2025-02-19T08:17:20Z\", \"containerID\": \"containerd://5e2cb72ca758fc976744b06b5ee97564bcc0958ca9cee2a54fdaab64323a1bf9\"}, \"terminationReason\": \"Completed\"}], \"podName\": \"hello-pod\", \"taskSpec\": {\"steps\": [{\"name\": \"hello\", \"image\": \"152-231-registry.alauda.cn:60070/ops/ubuntu:latest\", \"command\": [\"echo\", \"hello\"], \"computeResources\": {}}]}, \"startTime\": \"2025-02-19T08:17:10Z\", \"conditions\": [{\"type\": \"Succeeded\", \"reason\": \"Succeeded\", \"status\": \"True\", \"message\": \"All Steps have completed executing\", \"lastTransitionTime\": \"2025-02-19T08:17:21Z\"}], \"provenance\": {\"featureFlags\": {\"Coschedule\": \"workspaces\", \"MaxResultSize\": 4096, \"EnableAPIFields\": \"beta\", \"EnableArtifacts\": false, \"EnableParamEnum\": false, \"DisableCredsInit\": false, \"EnableStepActions\": true, \"SetSecurityContext\": false, \"AwaitSidecarReadiness\": true, \"EnableKeepPodOnCancel\": false, \"EnableTektonOCIBundles\": false, \"ResultExtractionMethod\": \"termination-message\", \"SendCloudEventsForRuns\": false, \"DisableAffinityAssistant\": false, \"EnableProvenanceInStatus\": true, \"EnforceNonfalsifiability\": \"none\", \"EnableCELInWhenExpression\": false, \"VerificationNoMatchPolicy\": \"ignore\", \"ScopeWhenExpressionsToTask\": false, \"RequireGitSSHSecretKnownHosts\": false, \"RunningInEnvWithInjectedSidecars\": true}}, \"completionTime\": \"2025-02-19T08:17:21Z\"}, \"metadata\": {\"uid\": \"209dcb81-e3c0-47cd-b082-d910e15702ae\", \"name\": \"hello\", \"labels\": {\"app.kubernetes.io/managed-by\": \"tekton-pipelines\"}, \"namespace\": \"default\", \"finalizers\": [\"results.tekton.dev/taskrun\", \"chains.tekton.dev\"], \"generation\": 1, \"annotations\": {\"results.tekton.dev/log\": \"default/results/209dcb81-e3c0-47cd-b082-d910e15702ae/logs/a750035d-0479-34a1-9db2-9a256b53243f\", \"chains.tekton.dev/signed\": \"true\", \"results.tekton.dev/record\": \"default/results/209dcb81-e3c0-47cd-b082-d910e15702ae/records/209dcb81-e3c0-47cd-b082-d910e15702ae\", \"results.tekton.dev/result\": \"default/results/209dcb81-e3c0-47cd-b082-d910e15702ae\", \"pipeline.tekton.dev/release\": \"8bfd3273cbe7776847884d7fa5004481e6be8f4a\"}, \"managedFields\": [{\"time\": \"2025-02-19T08:17:10Z\", \"manager\": \"kubectl-create\", \"fieldsV1\": {\"f:spec\": {\".\": {}, \"f:taskSpec\": {\".\": {}, \"f:steps\": {}}}}, \"operation\": \"Update\", \"apiVersion\": \"tekton.dev/v1\", \"fieldsType\": \"FieldsV1\"}, {\"time\": \"2025-02-19T08:17:21Z\", \"manager\": \"controller\", \"fieldsV1\": {\"f:metadata\": {\"f:finalizers\": {\"v:\\\"chains.tekton.dev\\\"\": {}}, \"f:annotations\": {\"f:chains.tekton.dev/signed\": {}, \"f:pipeline.tekton.dev/release\": {}}}}, \"operation\": \"Update\", \"apiVersion\": \"tekton.dev/v1\", \"fieldsType\": \"FieldsV1\"}, {\"time\": \"2025-02-19T08:17:21Z\", \"manager\": \"controller\", \"fieldsV1\": {\"f:status\": {\".\": {}, \"f:steps\": {}, \"f:podName\": {}, \"f:taskSpec\": {\".\": {}, \"f:steps\": {}}, \"f:artifacts\": {}, \"f:startTime\": {}, \"f:conditions\": {}, \"f:provenance\": {\".\": {}, \"f:featureFlags\": {\".\": {}, \"f:Coschedule\": {}, \"f:MaxResultSize\": {}, \"f:EnableAPIFields\": {}, \"f:EnableArtifacts\": {}, \"f:EnableParamEnum\": {}, \"f:DisableCredsInit\": {}, \"f:DisableInlineSpec\": {}, \"f:EnableStepActions\": {}, \"f:SetSecurityContext\": {}, \"f:AwaitSidecarReadiness\": {}, \"f:EnableKeepPodOnCancel\": {}, \"f:ResultExtractionMethod\": {}, \"f:SendCloudEventsForRuns\": {}, \"f:EnableKubernetesSidecar\": {}, \"f:DisableAffinityAssistant\": {}, \"f:EnableProvenanceInStatus\": {}, \"f:EnforceNonfalsifiability\": {}, \"f:EnableCELInWhenExpression\": {}, \"f:VerificationNoMatchPolicy\": {}, \"f:EnableConciseResolverSyntax\": {}, \"f:RequireGitSSHSecretKnownHosts\": {}, \"f:RunningInEnvWithInjectedSidecars\": {}}}, \"f:completionTime\": {}}}, \"operation\": \"Update\", \"apiVersion\": \"tekton.dev/v1\", \"fieldsType\": \"FieldsV1\", \"subresource\": \"status\"}, {\"time\": \"2025-02-19T08:17:21Z\", \"manager\": \"watcher\", \"fieldsV1\": {\"f:metadata\": {\"f:finalizers\": {\".\": {}, \"v:\\\"results.tekton.dev/taskrun\\\"\": {}}, \"f:annotations\": {\".\": {}, \"f:results.tekton.dev/log\": {}, \"f:results.tekton.dev/record\": {}, \"f:results.tekton.dev/result\": {}}}}, \"operation\": \"Update\", \"apiVersion\": \"tekton.dev/v1\", \"fieldsType\": \"FieldsV1\"}], \"resourceVersion\": \"1592422\", \"creationTimestamp\": \"2025-02-19T08:17:10Z\"}, \"apiVersion\": \"tekton.dev/v1\"}"
    }
    etag: "0805bbd0-e390-40dc-a1ea-f65ae9401930-1739953041309658421"
    created_time: {
      seconds: 1739953031
      nanos: 16922000
    }
    create_time: {
      seconds: 1739953031
      nanos: 16922000
    }
    updated_time: {
      seconds: 1739953041
      nanos: 309658000
    }
    update_time: {
      seconds: 1739953041
      nanos: 309658000
    }
    Запрос списка логов
    $ tkn results --insecure logs list default/results/-
    
    default/results/209dcb81-e3c0-47cd-b082-d910e15702ae/logs/a750035d-0479-34a1-9db2-9a256b53243f  results.tekton.dev/v1alpha3.Log         2025-02-19 16:17:21 +0800 CST           2025-02-19 16:17:21 +0800 CST
    Запрос одного лога

    Версия Logs API может отличаться в зависимости от развертывания. Если вы столкнетесь с unknown service tekton.results.v1alpha3.Logs, повторите команду с флагом --v1alpha2.

    $ tkn results --insecure logs get -o textproto default/results/209dcb81-e3c0-47cd-b082-d910e15702ae/logs/a750035d-0479-34a1-9db2-9a256b53243f
    
    content_type: "text/plain"
    data: "[prepare] 2025/02/19 08:17:12 Entrypoint initialization\n\n[hello] hello\n\n"

    Ссылки