{"id":18830666,"url":"https://github.com/materializeinc/k8s-eip-operator","last_synced_at":"2025-04-14T03:43:06.036Z","repository":{"id":37788715,"uuid":"385340170","full_name":"MaterializeInc/k8s-eip-operator","owner":"MaterializeInc","description":null,"archived":false,"fork":false,"pushed_at":"2025-03-04T16:07:31.000Z","size":743,"stargazers_count":11,"open_issues_count":14,"forks_count":2,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-08T12:01:47.948Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MaterializeInc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-12T18:07:12.000Z","updated_at":"2025-03-04T16:07:34.000Z","dependencies_parsed_at":"2023-11-29T02:26:20.164Z","dependency_job_id":"4be78a10-6823-4146-a45c-fa8ae728e921","html_url":"https://github.com/MaterializeInc/k8s-eip-operator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaterializeInc%2Fk8s-eip-operator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaterializeInc%2Fk8s-eip-operator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaterializeInc%2Fk8s-eip-operator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaterializeInc%2Fk8s-eip-operator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MaterializeInc","download_url":"https://codeload.github.com/MaterializeInc/k8s-eip-operator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248818974,"owners_count":21166469,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T01:49:52.554Z","updated_at":"2025-04-14T03:43:06.014Z","avatar_url":"https://github.com/MaterializeInc.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"⚠️⚠️ **WARNING!** ⚠️⚠️ The Materialize K8s-eip-operator will soon be archived and is no longer be under active development.\n# k8s-eip-operator\n\nManage external connections to Kubernetes pods or nodes using AWS Elastic IPs (EIPs).\n\nThis operator manages the following:\n* Creation of an EIP Custom Resource Definition in K8S.\n* Creation/destruction of EIP allocations in AWS.\n    * These AWS EIPs will be tagged with the K8S EIP uid they will be assigned to (`eip.materialize.cloud/eip_uid`) for later identification.\n* Association/disassociation of the EIP to the Elastic Network Interface (ENI) on the private IP of the pod or node.\n* Annotation of `external-dns.alpha.kubernetes.io/target` on the pod, so that the `external-dns` operator knows to use the IP of the EIP instead of the external IP of the primary ENI on the host.\n\n## Prerequisites\n\n* You must be using the [AWS VPC CNI plugin](https://github.com/aws/amazon-vpc-cni-k8s). This is the default for AWS EKS, so you probably don't need to change anything here.\n\n* You must set `AWS_VPC_K8S_CNI_EXTERNALSNAT=true` on the aws-node daemonset.\n    ```\n    kubectl set env daemonset -n kube-system aws-node AWS_VPC_K8S_CNI_EXTERNALSNAT=true\n    ```\n    See the [AWS external-snat docs](https://docs.aws.amazon.com/eks/latest/userguide/external-snat.html) for more details.\n\n* For `external-dns` support, you must be using a version with headless ClusterIp support, either by waiting until [this PR is merged](https://github.com/kubernetes-sigs/external-dns/pull/2115) or by using a [fork with it already included](https://github.com/MaterializeInc/external-dns).\n\n## Installation\n\n1. Create an AWS IAM role with the following policy:\n    ```json\n    {\n        \"Version\": \"2012-10-17\",\n        \"Statement\": [\n            {\n                \"Action\": [\n                    \"ec2:AllocateAddress\",\n                    \"ec2:ReleaseAddress\",\n                    \"ec2:DescribeAddresses\",\n                    \"ec2:AssociateAddress\",\n                    \"ec2:DisassociateAddress\",\n                    \"ec2:DescribeNetworkInterfaces\",\n                    \"ec2:CreateTags\",\n                    \"ec2:DeleteTags\",\n                    \"ec2:DescribeInstances\",\n                    \"ec2:ModifyNetworkInterfaceAttribute\",\n                    \"servicequotas:GetServiceQuota\"\n                ],\n                \"Effect\": \"Allow\",\n                \"Resource\": \"*\"\n            }\n        ]\n    }\n    ```\n2. Create a K8S ServiceAccount.\n    ```yaml\n    apiVersion: v1\n    kind: ServiceAccount\n    metadata:\n      name: eip-operator\n      annotations:\n        eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT-ID:role/IAM-SERVICE-ROLE-NAME\n    ```\n3. Create a K8S ClusterRole.\n    ```yaml\n    apiVersion: rbac.authorization.k8s.io/v1\n    kind: ClusterRole\n    metadata:\n      name: eip-operator\n    rules:\n    - apiGroups: [\"\"]\n      resources: [\"pods\", \"pods/status\"]\n      verbs: [\"get\", \"watch\", \"list\", \"update\", \"patch\"]\n    - apiGroups: [\"\"]\n      resources: [\"nodes\", \"nodes/status\"]\n      verbs: [\"get\"]\n    ```\n4. Create a K8S ClusterRoleBinding.\n    ```yaml\n    apiVersion: rbac.authorization.k8s.io/v1\n    kind: ClusterRoleBinding\n    metadata:\n      name: eip-operator-viewer\n    roleRef:\n      apiGroup: rbac.authorization.k8s.io\n      kind: ClusterRole\n      name: eip-operator\n    subjects:\n    - kind: ServiceAccount\n      name: eip-operator\n      namespace: default\n    ```\n5. Create a K8S Deployment.\nYou must specify the `CLUSTER_NAME` environment variable. `NAMESPACE` and `DEFAULT_TAGS` are optional.\nIf you do not set the `NAMESPACE` environment variable, the eip-operator will operate on all namespaces.\nEven in this global mode, the eip and pod must be in the same namespace.\n    ```yaml\n    apiVersion: apps/v1\n    kind: Deployment\n    metadata:\n      name: eip-operator\n    spec:\n      strategy:\n        type: Recreate\n      selector:\n        matchLabels:\n          app: eip-operator\n      template:\n        metadata:\n          labels:\n            app: eip-operator\n        spec:\n          containers:\n          - name: eip-operator\n            image: materialize/k8s-eip-operator:latest\n            env:\n            - name: NAMESPACE\n              value: default\n            - name: CLUSTER_NAME\n              value: my-example-cluster\n            - name: DEFAULT_TAGS\n              value: '{\"tag1\": \"value1\", \"tag2\": \"value2\"}'\n    ```\n\n## Usage\n\n##### A. If you want your EIP to survive beyond the lifetime of the pod (ie: for static reservations when updating a statefulset):\n\nInstantiate an Eip Kubernetes object, specifying the `podName` in the spec.\n```yaml\napiVersion: \"materialize.cloud/v2\"\nkind: Eip\nmetadata:\n  name: my-new-eip\nspec:\n  selector:\n    pod:\n      podName: my-pod\n```\n\nAdd the `eip.materialize.cloud/manage=true` label to the pod with name matching the `podName` specified above.\n\n##### B. If you don't care about getting a new IP if the pod gets recreated:\n\nNo need to manually create the Eip in this case, the operator can do it for you.\n\nAdd both the `eip.materialize.cloud/manage=true` and `eip.materialize.cloud/autocreate_eip=true` labels to your pod.\n\nDo NOT manually create the Eip Kubernetes object if setting the `eip.materialize.cloud/autocreate_eip=true` label, or the two objects will fight over your pod.\n\n##### C. If you want to attach an EIP to attach to a node directly instead of a pod, specify a node selector instead in the Eip Kubernetes resource:\n```yaml\napiVersion: \"materialize.cloud/v2\"\nkind: Eip\nmetadata:\n  name: my-new-eip\nspec:\n  selector:\n    node:\n      selector:\n        some-label: some-value\n        some-other-label: some-other-value\n```\n\nThe node selector should contain a set of labels which should match a single node - if multiple nodes are matched, the EIP will be attached to one of them arbitrarily.\n\nAdd the `eip.materialize.cloud/manage=true` label to the node whose labels match the labels in the selector.\n\n## Cilium Support\n\nIf using Cilium in ENI mode, you can still use this operator, but you will need to disable masquerade for pods with EIPs assigned.\nCilium (as of 1.12.0) does not seem to support configuring masquerade on a per-pod basis, so you will need to do one of the following:\n\n##### A. Disable masquerade globally.\n\n##### B. Run a privileged daemonset in the host network to inject ip rules for pods managed by the eip-operator.\n\n```yaml\napiVersion: apps/v1\nkind: DaemonSet\nmetadata:\n  name: cilium-eip-no-masquerade-agent\nspec:\n  selector:\n    matchLabels:\n      app: cilium-eip-no-masquerade-agent\n  template:\n    metadata:\n      labels:\n        app: cilium-eip-no-masquerade-agent\n    spec:\n      containers:\n      - command:\n        - ./cilium-eip-no-masquerade-agent\n        env:\n        - name: RUST_LOG\n          value: INFO\n        image: materialize/k8s-eip-operator\n        name: eip-operator\n        securityContext:\n          privileged: true\n      dnsPolicy: ClusterFirstWithHostNet\n      hostNetwork: true\n      restartPolicy: Always\n      serviceAccount: eip-operator\n      serviceAccountName: eip-operator\n```\n\n### Testing\n\n- Install the [KUTTL](https://kuttl.dev/docs/) testing tool\n- Run `./bin/run-tests`\n\n## OpenTelemetry Integration\n\nWe now have support for sending traces using the OpenTelemetry OTLP format. This is configured through environment variables:\n\n`OPENTELEMETRY_ENDPOINT` is the endpoint to send the logs to.\n\n`OPENTELEMETRY_HEADERS` is a json formatted map of key/value pairs to be included in the GRPC request headers.\n\n`OPENTELEMETRY_TOPLEVEL_FIELDS` is a json formatted map of key/value pairs to be included in all trace spans emitted from the service.\n\n`OPENTELEMETRY_LEVEL_TARGETS` is a [`tracing` crate level filter](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html). Defaults to `\"DEBUG\"`.\n\n`OPENTELEMETRY_SAMPLE_RATE` is a float value controlling the trace sample rate. Default is 0.05.\n\n\n## References\n* https://dzone.com/articles/oxidizing-the-kubernetes-operator\n* https://github.com/LogMeIn/k8s-aws-operator\n* https://github.com/kubernetes-sigs/external-dns/pull/2115/files\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaterializeinc%2Fk8s-eip-operator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaterializeinc%2Fk8s-eip-operator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaterializeinc%2Fk8s-eip-operator/lists"}