keel介绍

Keel旨在成为一种简单、健壮的后台服务,可以自动更新 Kubernetes 工作负载,以便用户可以专注于重要的事情

更多参考keel官网

部署

使用yaml文件部署

---
apiVersion: v1
kind: Namespace
metadata:
  name: keel
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: keel
  namespace: keel
  labels:
    app: keel
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: keel
rules:
  - apiGroups:
      - ""
    resources:
      - namespaces
    verbs:
      - watch
      - list
  - apiGroups:
      - ""
    resources:
      - secrets
    verbs:
      - get
      - watch
      - list
  - apiGroups:
      - ""
      - extensions
      - apps
      - batch
    resources:
      - pods
      - replicasets
      - replicationcontrollers
      - statefulsets
      - deployments
      - daemonsets
      - jobs
      - cronjobs
    verbs:
      - get
      - delete #required to delete pods during force upgrade of the same tag
      - watch
      - list
      - update
  - apiGroups:
      - ""
    resources:
      - configmaps
      - pods/portforward
    verbs:
      - get
      - create
      - update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: keel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: keel
subjects:
  - kind: ServiceAccount
    name: keel
    namespace: keel
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: keel-data
  namespace: keel
  labels:
    app: keel
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  storageClassName: managed-nfs-storage    
---
apiVersion: v1
kind: Service
metadata:
  name: keel
  namespace: keel
  labels:
    app: keel
spec:
  type: NodePort
  ports:
    - name: keel
      port: 9300
      targetPort: 9300
      protocol: TCP
      nodePort: 30930
  selector:
    app: keel
  sessionAffinity: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: keel
    release: keel
  name: keel
  namespace: keel
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  selector:
    matchLabels:
      app: keel
      release: keel
  template:
    metadata:
      labels:
        app: keel
        release: keel
    spec:
      serviceAccountName: keel
      containers:
        - command:
            - /bin/keel
          env:
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.namespace
            - name: POLL
              value: "true"
            - name: POLL_DEFAULTSCHEDULE
              value: "@every 1m"
            - name: BASIC_AUTH_USER
              value: admin
            - name: BASIC_AUTH_PASSWORD
              value: admin@123456
            - name: MAIL_SMTP_SERVER
              value: smtp.mail.com
            - name: MAIL_SMTP_PORT
              value: "25"
            - name: MAIL_SMTP_USER
              value: email@mail.com
            - name: MAIL_TO
              value: email@mail.com
            - name: MAIL_FROM
              value: email@mail.com
            - name: NOTIFICATION_LEVEL
              value: info
          image: keelhq/keel:0.19.1
          imagePullPolicy: Always
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 9300
              scheme: HTTP
            initialDelaySeconds: 30
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          name: keel
          ports:
            - containerPort: 9300
              protocol: TCP
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 9300
              scheme: HTTP
            initialDelaySeconds: 30
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          resources:
            limits:
              cpu: 100m
              memory: 128Mi
            requests:
              cpu: 50m
              memory: 64Mi
              
 [root@k8s01 keel]# kubectl apply -f keel.yaml 
namespace/keel created
serviceaccount/keel created
clusterrole.rbac.authorization.k8s.io/keel created
clusterrolebinding.rbac.authorization.k8s.io/keel created
persistentvolumeclaim/keel-data created
service/keel created
deployment.apps/keel created

[root@k8s01 keel]# kubectl get -n keel po
NAME                    READY   STATUS    RESTARTS   AGE
keel-7548bdbd67-9lzw6   1/1     Running   0          24s
[root@k8s01 keel]# kubectl get -n keel svc             
NAME   TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
keel   NodePort   10.96.53.180   <none>        9300:30930/TCP   31s             

使用helm部署

[root@k8s01 keel]# helm repo add keel https://charts.keel.sh 
[root@k8s01 keel]# helm repo update
[root@k8s01 keel]# vim values.yaml 
# Default values for keel.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates

image:
  repository: keelhq/keel
  tag: null
  pullPolicy: Always

# Enable insecure registries
insecureRegistry: false

# Polling is enabled by default,
# you can disable it setting value below to false
polling:
  enabled: true
  defaultSchedule: "@every 10m"

# Extra Containers to run alongside Keel
# extraContainers:
#   - name: busybox
#     image: busybox
#     imagePullPolicy: Always
#     command: ['sh', '-c', 'echo Container 1 is Running ; sleep 3600']

# Helm provider support
helmProvider:
  enabled: false
  # set to version "v3" for Helm v3
  version: "v2"
  tillerNamespace: "kube-system"
  # optional Tiller address (if portforwarder tunnel doesn't work),
  # if you are using default configuration, setting it to
  # 'tiller-deploy:44134' is usually fine
  tillerAddress: 'tiller-deploy:44134'
#  helmDriver: ''
#  helmDriverSqlConnectionString: ''

# Google Container Registry
# GCP Project ID
gcr:
  enabled: false
  projectId: ""
  gcpServiceAccount: ""
  clusterName: ""
  pubSub:
    enabled: false

# Notification level (debug, info, success, warn, error, fatal)
notificationLevel: info

# AWS Elastic Container Registry
# https://keel.sh/v1/guide/documentation.html#Polling-with-AWS-ECR
ecr:
  enabled: false
  roleArn: ""
  accessKeyId: ""
  secretAccessKey: ""
  region: ""

# Webhook Notification
# Remote webhook endpoint for notification delivery
webhook:
  enabled: false
  endpoint: ""

# Slack Notification
# bot name (default keel) must exist!
slack:
  enabled: false
  botName: ""
  token: ""
  channel: ""
  approvalsChannel: ""

# Hipchat notification and approvals
hipchat:
  enabled: false
  token: ""
  channel: ""
  approvalsChannel: ""
  botName: ""
  userName: ""
  password: ""

# Mattermost notifications
mattermost:
  enabled: false
  endpoint: ""

# MS Teams notifications
teams:
  enabled: false
  webhookUrl: ""

# Discord notifications
discord:
  enabled: false
  webhookUrl: ""

# Mail notifications
mail:
  enabled: false
  from: "dev@xxx.com"
  to: "ops@xxx.com"
  smtp:
    server: "smtp.exmail.qq.com"
    port: 465
    user: "dev@xxx.com"
    pass: "xxxxxxx"

# Basic auth on approvals
basicauth:
  enabled: true
  user: "admin"
  password: "admin@2024"

# Keel service
# Enable to receive webhooks from Docker registries
service:
  enabled: true
  type: LoadBalancer
  externalPort: 9300
  clusterIP: ""

# Webhook Relay service
# If you don’t want to expose your Keel service, you can use https://webhookrelay.com/
# which can deliver webhooks to your internal Keel service through Keel sidecar container.
webhookRelay:
  enabled: false
  bucket: ""
  # webhookrelay.com credentials
  # Set the key and secret values here to create the keel-webhookrelay secret with this
  # chart -or- leave key and secret blank and create the keel-webhookrelay secret separately.
  key: ""
  secret: ""
  # webhookrelay docker image
  image:
    repository: webhookrelay/webhookrelayd
    tag: latest
    pullPolicy: IfNotPresent

# Use a secret file to define passwords and tokens of third parties.
secret:
  # Leave blank to use `keel.fullname`
  name: ""
  # Set to false to manage your own secret file, with terraform for example.
  create: true

# Keel self-update
# uncomment lines below if you want Keel to automaticly
# self-update to the latest release version
keel:
  # keel policy (all/major/minor/patch/force)
  policy: patch
  # trigger type, defaults to events such as pubsub, webhooks
  trigger: poll
  # polling schedule
  pollSchedule: "@every 10080m"
  # images to track and update
  images:
    - repository: image.repository
      tag: image.tag

# RBAC manifests management
rbac:
  enabled: true
  serviceAccount:
    # Kubernetes service account name to be used for ClusterRoleBinding and Deployment.
    # name:
    # Create a new Kubernetes service account automatically. Set to false if you want to use your own service account.
    # If rbac.serviceAccount.name is not set, a new name for the service account is generated
    create: true

# Resources
resources:
  limits:
    cpu: 200m
    memory: 512Mi
  requests:
    cpu: 100m
    memory: 256Mi

# NodeSelector
nodeSelector: {}

affinity: {}

tolerations: {}

# base64 encoded json of GCP service account
# more info available here: https://cloud.google.com/kubernetes-engine/docs/tutorials/authenticating-to-cloud-platform
# e.g. --set googleApplicationCredentials=$(cat <JSON_KEY_FIEL> | base64)
googleApplicationCredentials: ""

# Enable DEBUG logging
debug: false

# This is used by the static manifest generator in order to create a static
# namespace manifest for the namespace that keel is being installed
# within. It should **not** be used if you are using Helm for deployment.
createNamespaceResource: false

podAnnotations: {}

serviceAnnotations: {}
# Useful for making the load balancer internal
# serviceAnnotations:
#    cloud.google.com/load-balancer-type: Internal

aws:
  region: null

podDisruptionBudget:
  enabled: false
  maxUnavailable: 1
  minAvailable: null

# Google Cloud Certificates
gcloud:
  managedCertificates:
    enabled: false
    domains:
      - ""

ingress:
  enabled: false
  labels: {}
  annotations: {}
  #  kubernetes.io/ingress.class: nginx
  #  kubernetes.io/tls-acme: "true"
  hosts: []
#    - host: chart-example.local
#      paths:
#        - /
  tls: []
#    - secretName: chart-example-tls
#      hosts:
#        - chart-example.local

dockerRegistry:
  enabled: false
  name: ""
  key: ""

persistence:
  enabled: false
  storageClass: "-"
  size: 1Gi
    
[root@k8s01 keel]# helm upgrade --install keel --namespace=keel --create-namespace keel/keel -f values.yaml

环境变量

# Google Cloud configuration
PROJECT_ID=<project ID> - Enable GCR with pub/sub support
PUBSUB - Set to '1' or 'true' to enable GCR pubsub

# Database location (optional, although if you want stats and audit logs to persist, set it) 
XDG_DATA_HOME=/data

# Authentication
BASIC_AUTH_USER=<admin username>
BASIC_AUTH_PASSWORD=<admin password>
AUTHENTICATED_WEBHOOKS=<true/false>
TOKEN_SECRET=<optional JWT signing secret, auto generated if empty>

## Helm configuration
HELM_PROVIDER - set to "1" to enable Tiller
TILLER_ADDRESS - 

# Enable AWS ECR
AWS_ACCESS_KEY_ID=<access key ID>
AWS_SECRET_ACCESS_KEY=<access key>
AWS_REGION=<region>

# Enable outgoing webhooks
WEBHOOK_ENDPOINT=<https://your-endpoint>

# Enable mattermost endpoint
MATTERMOST_ENDPOINT=<mattermost incoming webhook endpoint>

# Slack configuration
SLACK_TOKEN

SLACK_CHANNELS=<slack channel, defaults to "general">
SLACK_APPROVALS_CHANNEL=<slack approvals channel, defaults to "general">
SLACK_BOT_NAME=<slack bot name, defaults to "keel">

# Enable hipchat approvials and notification
HIPCHAT_TOKEN
HIPCHAT_CHANNELS
HIPCHAT_APPROVALS_CHANNEL
HIPCHAT_APPROVALS_BOT_NAME
HIPCHAT_APPROVALS_USER_NAME
HIPCHAT_APPROVALS_PASSWORT

# System wide notification level (webhooks, chat)
NOTIFICATION_LEVEL="info"
# Enable insecure registries
INSECURE_REGISTRY="true"

策略

可用策略:

  • 全部:每当出现版本升级或创建新的预发行版时进行更新(即:1.0.0 -> 1.0.1-rc1)

  • 主要:更新主要和次要和补丁版本

  • 次要版本:仅更新次要版本和补丁版本(忽略主要版本)

  • 补丁:仅更新补丁版本(忽略次要版本和主要版本)

  • force:即使 tag 不是 semver,也强制更新,即:,可选标签:keel.sh/match-tag=true,这将强制只有相同的标签才会触发强制更新latest

  • glob:使用通配符匹配版本,例如:

apiVersion: extensions/v1beta1
kind: Deployment
metadata: 
  name: test
  namespace: default
  labels: 
      name: "test"
  annotations:
      keel.sh/policy: "glob:build-*"  # <- build-1, build-2, build-foo will match this
  • 正则表达式:使用正则表达式匹配版本,示例:

apiVersion: extensions/v1beta1
kind: Deployment
metadata: 
  name: test
  namespace: default
  labels: 
      name: "test"
  annotations:
      keel.sh/policy: "regexp:^([a-zA-Z]+)$"

具体参考官网配置

访问

通过IP:NodePort访问

keel-1.pngkeel-2.png配置keel自动更新服务

主要在镜像仓库添加webhooks,一旦有镜像被push,就触发pod更新,更多详情可查看keel官网

Harbor添加webhooks

keel-3.pngkeel-4.pngyaml文件配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ec-oss
  annotations:
    k8s.kuboard.cn/workload: ec-oss
    keel.sh/policy: force     # update policy (available: patch, minor, major, all, force)
    keel.sh/trigger: webhooks     # enable active repository checking (webhooks and GCR would still work)
    # keel.sh/approvals: "1"    # required approvals to update
    keel.sh/match-tag: "true" # only makes a difference when used with 'force' policy, will only update if tag matches :dev->:dev, :prod->:prod 
    # keel.sh/pollSchedule: "@every 5m"
  ...      
文章作者: 鲜花的主人
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 爱吃可爱多
Kubernetes Tools Kubernetes Tools
喜欢就支持一下吧
打赏
微信 微信
支付宝 支付宝