Git Product home page Git Product logo

katalog-sync's Introduction

katalog-sync GoDoc Build Status Go Report Card

katalog-sync is a node-local mechanism for syncing k8s pods to consul services.

katalog-sync has:

  • node-local syncing to local consul-agent
  • agent-services in consul, meaning health of those endpoints is tied to the node agent
  • sync readiness state from k8s as check to consul
  • (optional) sidecar service to ensure consul registration before a pod is marked "ready"

katalog-sync makes the following assumptions:

  • You have a consul-agent running on each node (presumably as a Daemonset)
  • You are running a consul-agent which supports ServiceMetadata (>= 1.0.7)
  • You want to sync Pods to consul services and have the readiness values reflected
  • Your pods can communicate with Daemonsets running on the same node

katalog-sync overview

  1. Kubelet starts container on Node
  2. (optional) katalog-sync-sidecar calls to katalog-sync-daemonset waiting until registration with consul is complete
  3. Daemonset syncs changes from kubelet through the local kubelet API
  4. Daemonset syncs changes to consul

k8s pod annotations

Annotation
katalog-sync.wish.com/service-names Comma-separated list of service names
katalog-sync.wish.com/service-port Port for the consul service
katalog-sync.wish.com/service-port-SERVICE-NAME Port override to use for a specific service name
katalog-sync.wish.com/service-tags Tags for the consul service
katalog-sync.wish.com/service-tags-SERVICE-NAME Tags override to use for a specific service name
katalog-sync.wish.com/service-meta ServiceMeta for the consul service
katalog-sync.wish.com/service-meta-SERVICE-NAME ServiceMeta override to use for a specific service name
katalog-sync.wish.com/service-health Use a fixed health status string regardless of pod readiness, valid values: 'passing', 'warning', 'critical'
katalog-sync.wish.com/serivce-health-SERVICE-NAME health overrride for a specific service name
katalog-sync.wish.com/sidecar Container name of the katalog-sync-sidecar
katalog-sync.wish.com/sync-interval How frequently to sync this service with consul
katalog-sync.wish.com/service-check-ttl TTL for the service checks put into consul
katalog-sync.wish.com/container-exclude Comma-separated list of containers to exclude in readiness check

katalog-sync-daemon options

$ ./katalog-sync-daemon  -h
Usage:
  katalog-sync-daemon [OPTIONS]

Application Options:
      --log-level=                        Log level (default: info) [$LOG_LEVEL]
      --bind-address=                     address for binding RPC interface for
                                          sidecar [$BIND_ADDRESS]
      --pprof-bind-address=               address for binding pprof
                                          [$PPROF_BIND_ADDRESS]
      --min-sync-interval=                minimum duration allowed for sync
                                          (default: 500ms) [$MIN_SYNC_INTERVAL]
      --max-sync-interval=                maximum duration allowed for sync
                                          (default: 5s) [$MAX_SYNC_INTERVAL]
      --default-sync-interval=
      --default-check-ttl=
      --sync-ttl-buffer-duration=         how much time to ensure is between
                                          sync time and ttl (default: 10s)
                                          [$SYNC_TTL_BUFFER_DURATION]
      --kubelet-api=                      kubelet API endpoint (default:
                                          http://localhost:10255/pods)
                                          [$KUBELET_API]
      --kubelet-api-insecure-skip-verify  skip verification of TLS certificate
                                          from kubelet API
                                          [$KUBELET_API_INSECURE_SKIP_VERIFY]

Help Options:
  -h, --help                              Show this help message

katalog-sync-sidecar options

$ ./katalog-sync-sidecar -h
Usage:
  katalog-sync-sidecar [OPTIONS]

Application Options:
      --log-level=                       Log level (default: info) [$LOG_LEVEL]
      --katalog-sync-daemon=             katalog-sync-daemon API endpoint [$KATALOG_SYNC_DAEMON]
      --katalog-sync-daemon-max-backoff= katalog-sync-daemon API max backoff (default: 1s) [$KATALOG_SYNC_DAEMON_MAX_BACKOFF]
      --bind-address=                    address for binding checks to [$BIND_ADDRESS]
      --namespace=                       k8s namespace this is running in [$NAMESPACE]
      --pod-name=                        k8s pod this is running in [$POD_NAME]
      --container-name=                  k8s container this is running in [$CONTAINER_NAME]

Help Options:
  -h, --help                             Show this help message

katalog-sync's People

Contributors

akursell-wish avatar dependabot[bot] avatar gempesaw avatar jacksontj avatar tvirgl-wish avatar yiyan-wish avatar zengmin-wish avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

katalog-sync's Issues

Add support for readinessGate

In k8s 1.14 ReadinessGates were added as a way for external services to influence the ready state of pods. This would remove the need for the katalog-sync-sidecar and move that ready-sync state to a more-standard spec configuration.

This would (high-level) require katalog-sync-daemon to maintain a condition (e.g. katalog-sync.wish.com/sync-readiness) on the pods it watches

ACLs

Hello,

I have not found any parameters or settings that would allow for specifying ACL tokens for registering the service. Is there a plan to add it?

High CPU edge case

Hey, I'm encountering a high CPU edge case for katalog-sync. By high CPU i mean it uses all available CPU assigned to it in a resource limit.

Scenario:

  • MyPod does not have a readiness gate
  • MyPod starts with a failing readiness check

If MyPod starts with a passing readiness check, then later fails - it does not trigger high CPU on katalog-sync

After some digging, it looks like the daemon method waitPod is being called (https://github.com/wish/katalog-sync/blob/master/pkg/daemon/daemon.go#L329) continuously, expecting the Service to be ready - which in my scenario it is not.

Workaround that we've been using:
At L329 - add in an if statement.

				if p.OutstandingReadinessGate {
					go d.waitPod(p)
				}

The if condition is used a couple of times in a method of the pod struct already (e.g. https://github.com/wish/katalog-sync/blob/master/pkg/daemon/struct.go#L313)

Is this a viable way of solving the high CPU?
Also, im wondering what about a back off in the for loop, or a limit to the numbner of times it runs?

Thanks

specify service level parameters in a json struct

sth like:
'katalog-sync.wish.com/service': '{"name": "foo", "port": 1234, "meta": "...", "tags": "..."}'

That's cleaner(one annotation for each service) and easy to expand to include new parameters.

Unable to find pod with katalog-sync annotation (katalog-sync.wish.com/service-names)

time="2020-03-11T10:45:36Z" level=error msg="error registering with katalog-sync-daemon: Unknown rpc error: code = Unknown desc = Unable to find pod with katalog-sync annotation (katalog-sync.wish.com/service-names): /api/v1/namespaces/default/pods/hw-7c88d77f6-99c2m"

deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
name: hw
labels:
app: hw
annotations:
katalog-sync.wish.com/sidecar: "katalog-sync-sidecar"
katalog-sync.wish.com/service-names: "hw"
katalog-sync.wish.com/service-port: '8080'
spec:
replicas: 1
selector:
matchLabels:
app: hw
template:
metadata:
labels:
app: hw
annotations:
"katalog-sync.wish.com/sidecar": "katalog-sync-sidecar"
"katalog-sync.wish.com/service-names": "hw"
"katalog-sync.wish.com/service-port": '8080'
#katalog-sync.wish.com/service-port-servicename: '12345'
#katalog-sync.wish.com/service-meta: 'a:1,b:2'
#katalog-sync.wish.com/service-meta-servicename: 'b:1,c:2'
#katalog-sync.wish.com/service-tags: a,b
"katalog-sync.wish.com/sync-interval": 2s
spec:
terminationGracePeriodSeconds: 1
containers:
- name: hw
image: "... IMAGE ..."
imagePullPolicy: Always
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: "/live"
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
httpGet:
path: "/ready"
port: 8080
periodSeconds: 5
- command:
- "/bin/katalog-sync-sidecar"
args:
- "--katalog-sync-daemon=$(HOST_IP):8501"
- "--namespace=$(MY_POD_NAMESPACE)"
- "--pod-name=$(MY_POD_NAME)"
- "--container-name=katalog-sync-sidecar"
- "--bind-address=:8888"
env:
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
image: "... IMAGE ..."
imagePullPolicy: Always
name: katalog-sync-sidecar
readinessProbe:
httpGet:
path: "/ready"
port: 8080
initialDelaySeconds: 1
periodSeconds: 5

NodePort and node ip

i'm trying to use this and i'm having several problems, so this is a question/bug/feature request ticket. I can create different issues for each bug/feature request, but lets first find what is a bug or missing feature or bad user.

The first one is that i can only register in consul a deployment/pods, when trying to register a service, nothing show up in consul... so does this support services registration? can it be added?

This is what i'm trying to do:

apiVersion: v1
kind: Service
metadata:
  name: thumbor
  namespace: thumbor-dev
  labels:
    run: thumbor
  annotations:
    katalog-sync.wish.com/service-names: thumbor-nodeport
spec:
  selector:
    app: thumbor
  type: NodePort
  ports:
    - port: 9900
      nodePort: 31111

The second problem is that, using pod registration, in consul dns the pods show with the internal kubernetes ip, This is ok for internal kubernetes access, but i need to use this from outside kubernetes, i need the NodeIP and NodePort ... as nodeport is managed by service, this is probably the above request... or i'm missing something?

With a daemonset, using hostPort, i get the correct IP and ports, so this part works fine

thanks for the help

k8s deprecated read-only port

Hi

since kubernetes/kubeadm#732, the port 10255 is deprecated and at least in aws it doesn't exist anymore:
awslabs/amazon-eks-ami#128

Addjng this seem to mostly solve this:

--kubelet-api=https://localhost:10250/pods
--kubelet-api-insecure-skip-verify

but that returns this error in the log:

level=error msg="Error fetching state from k8s: invalid character 'F' looking for beginning of value"

and doesn't look like katalog-sync is sending the services to consul

[Question] init container Vs sidecar service

I was wondering if you have already considered to use an init container instead of a sidecar one to ensure consul registration before a pod is marked "ready".
If you already run a pool of sidecars will save a bit of resources.

as it is today the sidecar code can't be used as init container, because it also manages the deregister call.

Any thoughts?

Add support for service-level annotations

Today katalog-sync has annotations on the pods to be synced to consul. It would be nice to support similar annotations on a Service object as well. To implement this we'd need to watch all services with the annotation and sync any local pods that are endpoints of that given service.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.