You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/02/20 12:27:04 UTC

[02/32] ignite git commit: IGNITE-4159: Kubernetes IP finder.

IGNITE-4159: Kubernetes IP finder.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/37c0a220
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/37c0a220
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/37c0a220

Branch: refs/heads/ignite-4705
Commit: 37c0a220284527a38b181561865e8a57cfb1549b
Parents: 3ef7a0e
Author: Denis Magda <dm...@gridgain.com>
Authored: Mon Feb 13 17:33:32 2017 -0800
Committer: Denis Magda <dm...@gridgain.com>
Committed: Mon Feb 13 17:33:32 2017 -0800

----------------------------------------------------------------------
 modules/kubernetes/DEVNOTES.txt                 |  63 ++++
 modules/kubernetes/README.txt                   |  33 ++
 modules/kubernetes/config/Dockerfile            |  45 +++
 modules/kubernetes/config/example-kube.xml      |  44 +++
 .../kubernetes/config/ignite-deployment.yaml    |  26 ++
 modules/kubernetes/config/ignite-service.yaml   |  14 +
 modules/kubernetes/config/run.sh                |  50 +++
 modules/kubernetes/licenses/apache-2.0.txt      | 202 ++++++++++++
 modules/kubernetes/pom.xml                      |  93 ++++++
 .../TcpDiscoveryKubernetesIpFinder.java         | 315 +++++++++++++++++++
 .../tcp/ipfinder/kubernetes/package-info.java   |  22 ++
 .../TcpDiscoveryKubernetesIpFinderSelfTest.java |  93 ++++++
 .../tcp/ipfinder/kubernetes/package-info.java   |  22 ++
 .../testsuites/IgniteKubernetesTestSuite.java   |  41 +++
 pom.xml                                         |   1 +
 15 files changed, 1064 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/modules/kubernetes/DEVNOTES.txt
----------------------------------------------------------------------
diff --git a/modules/kubernetes/DEVNOTES.txt b/modules/kubernetes/DEVNOTES.txt
new file mode 100644
index 0000000..b2a8173
--- /dev/null
+++ b/modules/kubernetes/DEVNOTES.txt
@@ -0,0 +1,63 @@
+Building and testing Kubernetes module
+=========================================
+
+The instructions provide a guidance on how to build and test Ignite Kubernetes IP finder in Kubernetes environment.
+
+To test the IP finder you have to build the whole Apache Ignite project, package the binary as a Docker image and
+feed the image to your kubernetes environment.
+
+Building Apache Ignite
+=========================
+
+Use the command below to assemble an Apache Ignite binary:
+    mvn clean package -Prelease -Dignite.edition=fabric-lgpl -DskipTests
+
+Note, if you alter the build instruction somehow make sure to update the files under 'config' folder if needed.
+
+Installing Docker and Minikube
+==============================
+
+Install Docker and Minikube for testing purpose in your development environment.
+
+Once this is done, make sure that Minikube sees Docker images registered locally:
+    eval $(minikube docker-env)
+
+Start Minikube:
+    minikube start --vm-driver=xhyve
+
+Assembling Apache Ignite Docker Image
+=====================================
+
+Create a folder for all the files to be placed in the Docker image and copy the following there:
+    - Apache Ignite binary in a zip form built at the step above.
+    - Dockerfile from `ignite-kubernetes/config/Dockerfile`.
+    - Ignite configuration with enabled Kubernetes IP finder from `ignite-kubernetes/config/example-kube.xml`.
+    - The executable file that will start an Ignite node process from `ignite-kubernetes/config/run.sh`
+
+Go to the folder and execute a command below to prepare the image:
+    docker build -t ignite-kube:v1 .
+
+Creating containerized Ignite pods and Ignite lookup service
+============================================================
+
+Start the Kubernetes service that is used for IP addresses lookup. Use `ignite-kubernetes/config/ignite-service.yaml`:
+	kubectl create -f {path_to}/ignite-service.yaml
+
+Create and deploy Ignite pods using `ignite-kubernetes/config/ignite-deployment.yaml` configuration:
+    kubectl create -f {path_to}/ignite-deployment.yaml
+
+Make sure that the pods were deployed and running properly:
+    kubectl get pod
+    kubectl logs {pod name}
+
+Increase or decrease number of Ignite pods checking that Kubernetes IP finder works as expected:
+    kubectl scale --replicas=4 -f {path_to}/ignite-deployment.yaml
+
+Docker Image Redeployment
+=========================
+
+If you need to redeploy the docker image after it gets updated and you prefer not to change the image version then
+delete a current Kubernetes Ignite deployment (don't delete the service):
+    kubectl delete deployment ignite-cluster
+
+After that you are free to build and deploy an updated docker image using the same commands as listed above.

http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/modules/kubernetes/README.txt
----------------------------------------------------------------------
diff --git a/modules/kubernetes/README.txt b/modules/kubernetes/README.txt
new file mode 100644
index 0000000..a9a5a09
--- /dev/null
+++ b/modules/kubernetes/README.txt
@@ -0,0 +1,33 @@
+Apache Ignite Kubernetes Module
+------------------------
+
+Apache Ignite Kubernetes module provides a TCP Discovery IP Finder that uses a dedicated Kubernetes service
+for IP addresses lookup of Apache Ignite pods containerized by Kubernetes.
+
+To enable Kubernetes module when starting a standalone node, move 'optional/ignite-kubernetes' folder to
+'libs' folder before running 'ignite.{sh|bat}' script. The content of the module folder will
+be added to classpath in this case.
+
+Importing Kubernetes Module In Maven Project
+-------------------------------------
+
+If you are using Maven to manage dependencies of your project, you can add Kubernetes module
+dependency like this (replace '${ignite.version}' with actual Ignite version you are
+interested in):
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+                        http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    ...
+    <dependencies>
+        ...
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-kubernetes</artifactId>
+            <version>${ignite.version}</version>
+        </dependency>
+        ...
+    </dependencies>
+    ...
+</project>

http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/modules/kubernetes/config/Dockerfile
----------------------------------------------------------------------
diff --git a/modules/kubernetes/config/Dockerfile b/modules/kubernetes/config/Dockerfile
new file mode 100644
index 0000000..4e08ce8
--- /dev/null
+++ b/modules/kubernetes/config/Dockerfile
@@ -0,0 +1,45 @@
+# Use Java 8 image as default one.
+FROM java:8
+
+# Set Apache Ignite version.
+ENV IGNITE_VERSION 2.0.0-SNAPSHOT
+
+# Set IGNITE_HOME variable.
+ENV IGNITE_HOME /opt/ignite/apache-ignite-fabric-lgpl-${IGNITE_VERSION}-bin
+
+# Setting a path to an Apache Ignite configuration file. Used by run.sh script below.
+ENV CONFIG_URI ${IGNITE_HOME}/config/example-kube.xml
+
+# Make sure kubernetes lib is copied to 'libs' folder.
+ENV OPTION_LIBS ignite-kubernetes
+
+# Disabling quiet mode.
+ENV IGNITE_QUIET=false
+
+# Install or update needed tools.
+RUN apt-get update && apt-get install -y --no-install-recommends unzip
+
+# Creating and setting a working directory for following commands.
+WORKDIR /opt/ignite
+
+# Copying local Apache Ignite build to the docker image.
+COPY ./apache-ignite-fabric-lgpl-${IGNITE_VERSION}-bin.zip apache-ignite-fabric-lgpl-${IGNITE_VERSION}-bin.zip
+
+# Unpacking the build.
+RUN unzip apache-ignite-fabric-lgpl-${IGNITE_VERSION}-bin.zip
+RUN rm apache-ignite-fabric-lgpl-${IGNITE_VERSION}-bin.zip
+
+# Copying the executable file and setting permissions.
+COPY ./run.sh $IGNITE_HOME/
+RUN chmod +x $IGNITE_HOME/run.sh
+
+# Copying the configuration.
+COPY ./example-kube.xml $IGNITE_HOME/config
+
+# Starting an Apache Ignite node.
+CMD $IGNITE_HOME/run.sh
+
+# Exposing the ports.
+EXPOSE 11211 47100 47500 49112
+
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/modules/kubernetes/config/example-kube.xml
----------------------------------------------------------------------
diff --git a/modules/kubernetes/config/example-kube.xml b/modules/kubernetes/config/example-kube.xml
new file mode 100644
index 0000000..bc04463
--- /dev/null
+++ b/modules/kubernetes/config/example-kube.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<!--
+    Configuration example with Kubernetes IP finder enabled.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+        http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+    <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+
+        <!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. -->
+        <property name="discoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+                <property name="ipFinder">
+                    <!--
+                        Enables Kubernetes IP finder with default settings.
+                    -->
+                    <bean
+                        class="org.apache.ignite.spi.discovery.tcp.ipfinder.kubernetes.TcpDiscoveryKubernetesIpFinder"/>
+                </property>
+            </bean>
+        </property>
+    </bean>
+</beans>

http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/modules/kubernetes/config/ignite-deployment.yaml
----------------------------------------------------------------------
diff --git a/modules/kubernetes/config/ignite-deployment.yaml b/modules/kubernetes/config/ignite-deployment.yaml
new file mode 100644
index 0000000..ed5c102
--- /dev/null
+++ b/modules/kubernetes/config/ignite-deployment.yaml
@@ -0,0 +1,26 @@
+# An example of a Kubernetes configuration for Ignite pods deployment.
+apiVersion: extensions/v1beta1
+kind: Deployment
+metadata:
+  # Custom Ignite cluster's name.
+  name: ignite-cluster
+spec:
+  # Number of nodes to be started by Kubernetes initially.
+  replicas: 2
+  template:
+    metadata:
+      labels:
+        # Must be equal to Ignite's Kubernetes service name.
+        app: ignite
+    spec:
+      containers:
+        # Custom Ignite node's pod  name.
+      - name: ignite-node
+        # Custom Ignite Docker image name.
+        image: ignite-kube:v1
+        ports:
+        # Ports to open.
+        - containerPort: 11211 # REST port number.
+        - containerPort: 47100 # communication SPI port number.
+        - containerPort: 47500 # discovery SPI port number.
+        - containerPort: 49112 # JMX port number.

http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/modules/kubernetes/config/ignite-service.yaml
----------------------------------------------------------------------
diff --git a/modules/kubernetes/config/ignite-service.yaml b/modules/kubernetes/config/ignite-service.yaml
new file mode 100644
index 0000000..07b7516
--- /dev/null
+++ b/modules/kubernetes/config/ignite-service.yaml
@@ -0,0 +1,14 @@
+# An example of a Kubernetes configuration for Ignite lookup service deployment.
+apiVersion: v1
+kind: Service
+metadata:
+  # Name of Ignite Service used by Kubernetes IP finder for IP addresses lookup.
+  # The name must be equal to TcpDiscoveryKubernetesIpFinder.setServiceName parameter.
+  name: ignite
+spec:
+  clusterIP: None
+  ports:
+    - port: 9042 # some custom port (optional).
+  selector:
+    # Must be equal to the label set for Ignite pods.
+    app: ignite

http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/modules/kubernetes/config/run.sh
----------------------------------------------------------------------
diff --git a/modules/kubernetes/config/run.sh b/modules/kubernetes/config/run.sh
new file mode 100644
index 0000000..dbf2871
--- /dev/null
+++ b/modules/kubernetes/config/run.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+if [ ! -z "$OPTION_LIBS" ]; then
+  IFS=, LIBS_LIST=("$OPTION_LIBS")
+
+  for lib in ${LIBS_LIST[@]}; do
+    cp -r $IGNITE_HOME/libs/optional/"$lib"/* \
+        $IGNITE_HOME/libs/
+  done
+fi
+
+if [ ! -z "$EXTERNAL_LIBS" ]; then
+  IFS=, LIBS_LIST=("$EXTERNAL_LIBS")
+
+  for lib in ${LIBS_LIST[@]}; do
+    echo $lib >> temp
+  done
+
+  wget -i temp -P $IGNITE_HOME/libs
+
+  rm temp
+fi
+
+QUIET=""
+
+if [ "$IGNITE_QUIET" = "false" ]; then
+  QUIET="-v"
+fi
+
+if [ -z $CONFIG_URI ]; then
+  $IGNITE_HOME/bin/ignite.sh $QUIET
+else
+  $IGNITE_HOME/bin/ignite.sh $QUIET $CONFIG_URI
+fi

http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/modules/kubernetes/licenses/apache-2.0.txt
----------------------------------------------------------------------
diff --git a/modules/kubernetes/licenses/apache-2.0.txt b/modules/kubernetes/licenses/apache-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/modules/kubernetes/licenses/apache-2.0.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/modules/kubernetes/pom.xml
----------------------------------------------------------------------
diff --git a/modules/kubernetes/pom.xml b/modules/kubernetes/pom.xml
new file mode 100644
index 0000000..5d4e5f0
--- /dev/null
+++ b/modules/kubernetes/pom.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<!--
+    POM file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ignite</groupId>
+        <artifactId>ignite-parent</artifactId>
+        <version>1</version>
+        <relativePath>../../parent</relativePath>
+    </parent>
+
+    <artifactId>ignite-kubernetes</artifactId>
+    <version>2.0.0-SNAPSHOT</version>
+    <url>http://ignite.apache.org</url>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-core-asl</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-core</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-beans</artifactId>
+            <version>${spring.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <version>${spring.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-core</artifactId>
+            <version>${spring.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/modules/kubernetes/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/TcpDiscoveryKubernetesIpFinder.java
----------------------------------------------------------------------
diff --git a/modules/kubernetes/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/TcpDiscoveryKubernetesIpFinder.java b/modules/kubernetes/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/TcpDiscoveryKubernetesIpFinder.java
new file mode 100644
index 0000000..a5bd24f
--- /dev/null
+++ b/modules/kubernetes/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/TcpDiscoveryKubernetesIpFinder.java
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.spi.discovery.tcp.ipfinder.kubernetes;
+
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.internal.IgniteInterruptedCheckedException;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.resources.LoggerResource;
+import org.apache.ignite.spi.IgniteSpiException;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinderAdapter;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.ObjectMapper;
+
+/**
+ * IP finder for automatic lookup of Ignite nodes running in Kubernetes environment. All Ignite nodes have to deployed
+ * as Kubernetes pods in order to be discovered. An application that uses Ignite client nodes as a gateway to the
+ * cluster is required to be containerized as well. Applications and Ignite nodes running outside of Kubernetes will
+ * not be able to reach the containerized counterparts.
+ * <p>
+ * The implementation is based on a dedicated Kubernetes service that has to be created and should be deployed prior
+ * Ignite nodes startup. The service will maintain a list of all endpoints (internal IP addresses) of all containerized
+ * Ignite pods running so far. The name of the service must be equal to {@link #setServiceName(String)} which is
+ * `ignite` by default.
+ * <p>
+ * As for Ignite pods, it's recommended to label them in such a way that the service will use the label in its selector
+ * configuration excluding endpoints of irrelevant Kubernetes pods running in parallel.
+ * <p>
+ * The IP finder, in its turn, will call this service to retrieve Ignite pods IP addresses. The port will be
+ * either the one that is set with {@link TcpDiscoverySpi#setLocalPort(int)} or {@link TcpDiscoverySpi#DFLT_PORT}.
+ * Make sure that all Ignite pods occupy a similar discovery port, otherwise they will not be able to discover each
+ * other using this IP finder.
+ * <h2 class="header">Optional configuration</h2>
+ * <ul>
+ *      <li>The Kubernetes service name for IP addresses lookup (see {@link #setServiceName(String)})</li>
+ *      <li>The Kubernetes service namespace for IP addresses lookup (see {@link #setNamespace(String)}</li>
+ *      <li>The host name of the Kubernetes API server (see {@link #setMasterUrl(String)})</li>
+ *      <li>Path to the service token (see {@link #setAccountToken(String)}</li>
+ * </ul>
+ * <p>
+ * Both {@link #registerAddresses(Collection)} and {@link #unregisterAddresses(Collection)} have no effect.
+ * <p>
+ * Note, this IP finder is only workable when it used in Kubernetes environment.
+ * Choose another implementation of {@link org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder} for local
+ * or home network tests.
+ */
+public class TcpDiscoveryKubernetesIpFinder extends TcpDiscoveryIpFinderAdapter {
+    /** Grid logger. */
+    @LoggerResource
+    private IgniteLogger log;
+
+    /** Init routine guard. */
+    private final AtomicBoolean initGuard = new AtomicBoolean();
+
+    /** Init routine latch. */
+    private final CountDownLatch initLatch = new CountDownLatch(1);
+
+    /** Trust manager. */
+    private TrustManager[] trustAll = new TrustManager[] {
+        new X509TrustManager() {
+            public void checkServerTrusted(X509Certificate[] certs, String authType) {}
+            public void checkClientTrusted(X509Certificate[] certs, String authType) {}
+            public X509Certificate[] getAcceptedIssuers() { return null; }
+        }
+    };
+
+    /** Host verifier. */
+    private HostnameVerifier trustAllHosts = new HostnameVerifier() {
+        public boolean verify(String hostname, SSLSession session) {
+            return true;
+        }
+    };
+
+    /** Ignite's Kubernetes Service name. */
+    private String serviceName = "ignite";
+
+    /** Ignite Pod setNamespace name. */
+    private String namespace = "default";
+
+    /** Kubernetes API server URL in a string form. */
+    private String master = "https://kubernetes.default.svc.cluster.local:443";
+
+    /** Account token location. */
+    private String accountToken = "/var/run/secrets/kubernetes.io/serviceaccount/token";
+
+    /** Kubernetes API server URL. */
+    private URL url;
+
+    /** SSL context */
+    private SSLContext ctx;
+
+    /**
+     * Creates an instance of Kubernetes IP finder.
+     */
+    public TcpDiscoveryKubernetesIpFinder() {
+        setShared(true);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<InetSocketAddress> getRegisteredAddresses() throws IgniteSpiException {
+        init();
+
+        Collection<InetSocketAddress> addrs = new ArrayList<>();
+
+        try {
+            System.out.println("Getting Apache Ignite endpoints from: " + url);
+
+            HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
+
+            conn.setHostnameVerifier(trustAllHosts);
+
+            conn.setSSLSocketFactory(ctx.getSocketFactory());
+            conn.addRequestProperty("Authorization", "Bearer " + serviceAccountToken(accountToken));
+
+            // Sending the request and processing a response.
+            ObjectMapper mapper = new ObjectMapper();
+
+            Endpoints endpoints = mapper.readValue(conn.getInputStream(), Endpoints.class);
+
+            if (endpoints != null) {
+                if (endpoints.subsets != null && !endpoints.subsets.isEmpty()) {
+                    for (Subset subset : endpoints.subsets) {
+
+                        if (subset.addresses != null && !subset.addresses.isEmpty()) {
+                            for (Address address : subset.addresses) {
+                                addrs.add(new InetSocketAddress(address.ip, 0));
+
+                                System.out.println("Added an address to the list: " + address.ip);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        catch (Exception e) {
+            throw new IgniteSpiException("Failed to retrieve Ignite pods IP addresses.", e);
+        }
+
+        return addrs;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void registerAddresses(Collection<InetSocketAddress> addrs) throws IgniteSpiException {
+        // No-op
+    }
+
+    /** {@inheritDoc} */
+    @Override public void unregisterAddresses(Collection<InetSocketAddress> addrs) throws IgniteSpiException {
+        // No-op
+    }
+
+    /**
+     * Sets the name of Kubernetes service for Ignite pods' IP addresses lookup. The name of the service must be equal
+     * to the name set in service's Kubernetes configuration. If this parameter is not changed then the name of the
+     * service has to be set to 'ignite' in the corresponding Kubernetes configuration.
+     *
+     * @param service Kubernetes service name for IP addresses lookup. If it's not set then 'ignite' is used by default.
+     */
+    public void setServiceName(String service) {
+        this.serviceName = service;
+    }
+
+    /**
+     * Sets the namespace the Kubernetes service belongs to. By default, it's supposed that the service is running under
+     * Kubernetes `default` namespace.
+     *
+     * @param namespace The Kubernetes service namespace for IP addresses lookup.
+     */
+    public void setNamespace(String namespace) {
+        this.namespace = namespace;
+    }
+
+    /**
+     * Sets the host name of the Kubernetes API server. By default the following host name is used:
+     * 'https://kubernetes.default.svc.cluster.local:443'.
+     *
+     * @param master The host name of the Kubernetes API server.
+     */
+    public void setMasterUrl(String master) {
+        this.master = master;
+    }
+
+    /**
+     * Specifies the path to the service token file. By default the following account token is used:
+     * '/var/run/secrets/kubernetes.io/serviceaccount/token'.
+     *
+     * @param accountToken The path to the service token file.
+     */
+    public void setAccountToken(String accountToken) {
+        this.accountToken = accountToken;
+    }
+
+    /**
+     * Kubernetes IP finder initialization.
+     *
+     * @throws IgniteSpiException In case of error.
+     */
+    private void init() throws IgniteSpiException {
+        if (initGuard.compareAndSet(false, true)) {
+
+            if (serviceName == null || serviceName.isEmpty() ||
+                namespace == null || namespace.isEmpty() ||
+                master == null || master.isEmpty() ||
+                accountToken == null || accountToken.isEmpty()) {
+                throw new IgniteSpiException(
+                    "One or more configuration parameters are invalid [setServiceName=" +
+                        serviceName + ", setNamespace=" + namespace + ", setMasterUrl=" +
+                        master + ", setAccountToken=" + accountToken + "]");
+            }
+
+            try {
+                // Preparing the URL and SSL context to be used for connection purposes.
+                String path = String.format("/api/v1/namespaces/%s/endpoints/%s", namespace, serviceName);
+
+                url = new URL(master + path);
+
+                ctx = SSLContext.getInstance("SSL");
+
+                ctx.init(null, trustAll, new SecureRandom());
+            }
+            catch (Exception e) {
+                throw new IgniteSpiException("Failed to connect to Ignite's Kubernetes Service.", e);
+            }
+            finally {
+                initLatch.countDown();
+            }
+        }
+        else {
+            try {
+                U.await(initLatch);
+            }
+            catch (IgniteInterruptedCheckedException e) {
+                throw new IgniteSpiException("Thread has been interrupted.", e);
+            }
+
+            if (url == null || ctx == null)
+                throw new IgniteSpiException("IP finder has not been initialized properly.");
+        }
+    }
+
+    /**
+     * Reads content of the service account token file.
+     *
+     * @param file The path to the service account token.
+     * @return Service account token.
+     */
+    private String serviceAccountToken(String file)  {
+        try {
+            return new String(Files.readAllBytes(Paths.get(file)));
+        } catch (IOException e) {
+            throw new IgniteSpiException("Failed to load services account token [setAccountToken= " + file + "]", e);
+        }
+    }
+
+    /**
+     * Object used by Jackson for processing of Kubernetes lookup service's response.
+     */
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    private static class Address {
+        /** */
+        public String ip;
+    }
+
+    /**
+     * Object used by Jackson for processing of Kubernetes lookup service's response.
+     */
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    private static class Subset {
+        /** */
+        public List<Address> addresses;
+    }
+
+    /**
+     * Object used by Jackson for processing of Kubernetes lookup service's response.
+     */
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    private static class Endpoints {
+        /** */
+        public List<Subset> subsets;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/modules/kubernetes/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/package-info.java
----------------------------------------------------------------------
diff --git a/modules/kubernetes/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/package-info.java b/modules/kubernetes/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/package-info.java
new file mode 100644
index 0000000..a572cb2
--- /dev/null
+++ b/modules/kubernetes/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * <!-- Package description. -->
+ * Contains Kubernetes IP finder implementation.
+ */
+package org.apache.ignite.spi.discovery.tcp.ipfinder.kubernetes;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/modules/kubernetes/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/TcpDiscoveryKubernetesIpFinderSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/kubernetes/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/TcpDiscoveryKubernetesIpFinderSelfTest.java b/modules/kubernetes/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/TcpDiscoveryKubernetesIpFinderSelfTest.java
new file mode 100644
index 0000000..fd3e2a3
--- /dev/null
+++ b/modules/kubernetes/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/TcpDiscoveryKubernetesIpFinderSelfTest.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.spi.discovery.tcp.ipfinder.kubernetes;
+
+import org.apache.ignite.spi.IgniteSpiException;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinderAbstractSelfTest;
+
+/**
+ * TcpDiscoveryKubernetesIpFinder test.
+ */
+public class TcpDiscoveryKubernetesIpFinderSelfTest extends
+    TcpDiscoveryIpFinderAbstractSelfTest<TcpDiscoveryKubernetesIpFinder> {
+    /**
+     * Constructor.
+     *
+     * @throws Exception If any error occurs.
+     */
+    public TcpDiscoveryKubernetesIpFinderSelfTest() throws Exception {
+        // No-op.
+    }
+
+    @Override protected void beforeTest() throws Exception {
+        // No-op.
+    }
+
+    /* {@inheritDoc} */
+    @Override protected TcpDiscoveryKubernetesIpFinder ipFinder() throws Exception {
+        // No-op.
+        return null;
+    }
+
+    /* {@inheritDoc} */
+    @Override public void testIpFinder() throws Exception {
+        TcpDiscoveryKubernetesIpFinder ipFinder = new TcpDiscoveryKubernetesIpFinder();
+
+        ipFinder.setAccountToken(null);
+
+        try {
+            ipFinder.getRegisteredAddresses();
+        }
+        catch (IgniteSpiException e) {
+            assertTrue(e.getMessage().startsWith("One or more configuration parameters are invalid"));
+        }
+
+        ipFinder = new TcpDiscoveryKubernetesIpFinder();
+
+        ipFinder.setMasterUrl(null);
+
+        try {
+            ipFinder.getRegisteredAddresses();
+        }
+        catch (IgniteSpiException e) {
+            assertTrue(e.getMessage().startsWith("One or more configuration parameters are invalid"));
+        }
+
+        ipFinder = new TcpDiscoveryKubernetesIpFinder();
+
+        ipFinder.setNamespace(null);
+
+        try {
+            ipFinder.getRegisteredAddresses();
+        }
+        catch (IgniteSpiException e) {
+            assertTrue(e.getMessage().startsWith("One or more configuration parameters are invalid"));
+        }
+
+        ipFinder = new TcpDiscoveryKubernetesIpFinder();
+
+        ipFinder.setServiceName("");
+
+        try {
+            ipFinder.getRegisteredAddresses();
+        }
+        catch (IgniteSpiException e) {
+            assertTrue(e.getMessage().startsWith("One or more configuration parameters are invalid"));
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/modules/kubernetes/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/package-info.java
----------------------------------------------------------------------
diff --git a/modules/kubernetes/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/package-info.java b/modules/kubernetes/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/package-info.java
new file mode 100644
index 0000000..83ab56f
--- /dev/null
+++ b/modules/kubernetes/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/kubernetes/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * <!-- Package description. -->
+ * Contains Kubernetes IP finder internal tests.
+ */
+package org.apache.ignite.spi.discovery.tcp.ipfinder.kubernetes;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/modules/kubernetes/src/test/java/org/apache/ignite/testsuites/IgniteKubernetesTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/kubernetes/src/test/java/org/apache/ignite/testsuites/IgniteKubernetesTestSuite.java b/modules/kubernetes/src/test/java/org/apache/ignite/testsuites/IgniteKubernetesTestSuite.java
new file mode 100644
index 0000000..540657e
--- /dev/null
+++ b/modules/kubernetes/src/test/java/org/apache/ignite/testsuites/IgniteKubernetesTestSuite.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.testsuites;
+
+
+import junit.framework.TestSuite;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.kubernetes.TcpDiscoveryKubernetesIpFinderSelfTest;
+import org.apache.ignite.testframework.IgniteTestSuite;
+
+/**
+ * Ignite Kubernetes integration test.
+ */
+public class IgniteKubernetesTestSuite extends TestSuite {
+    /**
+     * @return Test suite.
+     * @throws Exception Thrown in case of the failure.
+     */
+    public static TestSuite suite() throws Exception {
+        TestSuite suite = new IgniteTestSuite("Kubernetes Integration Test Suite");
+
+        // Cloud Nodes IP finder.
+        suite.addTestSuite(TcpDiscoveryKubernetesIpFinderSelfTest.class);
+
+        return suite;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/37c0a220/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index ea76053..238361b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -88,6 +88,7 @@
         <module>modules/web/ignite-websphere-test</module>
         <module>modules/cassandra</module>
         <module>modules/flink</module>
+        <module>modules/kubernetes</module>
     </modules>
 
     <profiles>