Merge pull request #10231 from mwielgus/cassandra

Fix IP field name and add namespace support in Cassandra example
This commit is contained in:
Victor Marmol
2015-07-08 14:37:14 -07:00
5 changed files with 26 additions and 5 deletions

View File

@@ -45,6 +45,10 @@ spec:
value: 512M value: 512M
- name: HEAP_NEWSIZE - name: HEAP_NEWSIZE
value: 100M value: 100M
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumes: volumes:
- name: data - name: data
emptyDir: {} emptyDir: {}
@@ -52,7 +56,7 @@ spec:
There are a few things to note in this description. First is that we are running the ```kubernetes/cassandra``` image. This is a standard Cassandra installation on top of Debian. However it also adds a custom [```SeedProvider```](https://svn.apache.org/repos/asf/cassandra/trunk/src/java/org/apache/cassandra/locator/SeedProvider.java) to Cassandra. In Cassandra, a ```SeedProvider``` bootstraps the gossip protocol that Cassandra uses to find other nodes. The ```KubernetesSeedProvider``` discovers the Kubernetes API Server using the built in Kubernetes discovery service, and then uses the Kubernetes API to find new nodes (more on this later) There are a few things to note in this description. First is that we are running the ```kubernetes/cassandra``` image. This is a standard Cassandra installation on top of Debian. However it also adds a custom [```SeedProvider```](https://svn.apache.org/repos/asf/cassandra/trunk/src/java/org/apache/cassandra/locator/SeedProvider.java) to Cassandra. In Cassandra, a ```SeedProvider``` bootstraps the gossip protocol that Cassandra uses to find other nodes. The ```KubernetesSeedProvider``` discovers the Kubernetes API Server using the built in Kubernetes discovery service, and then uses the Kubernetes API to find new nodes (more on this later)
You may also note that we are setting some Cassandra parameters (```MAX_HEAP_SIZE``` and ```HEAP_NEWSIZE```). We also tell Kubernetes that the container exposes both the ```CQL``` and ```Thrift``` API ports. Finally, we tell the cluster manager that we need 0.5 cpu (0.5 core). You may also note that we are setting some Cassandra parameters (```MAX_HEAP_SIZE``` and ```HEAP_NEWSIZE```) and adding information about the [namespace](https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/namespaces.md). We also tell Kubernetes that the container exposes both the ```CQL``` and ```Thrift``` API ports. Finally, we tell the cluster manager that we need 0.5 cpu (0.5 core).
In theory could create a single Cassandra pod right now but since `KubernetesSeedProvider` needs to learn what nodes are in the Cassandra deployment we need to create a service first. In theory could create a single Cassandra pod right now but since `KubernetesSeedProvider` needs to learn what nodes are in the Cassandra deployment we need to create a service first.
@@ -158,6 +162,10 @@ spec:
value: 512M value: 512M
- name: HEAP_NEWSIZE - name: HEAP_NEWSIZE
value: 100M value: 100M
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: gcr.io/google_containers/cassandra:v4 image: gcr.io/google_containers/cassandra:v4
name: cassandra name: cassandra
ports: ports:

View File

@@ -24,6 +24,10 @@ spec:
value: 512M value: 512M
- name: HEAP_NEWSIZE - name: HEAP_NEWSIZE
value: 100M value: 100M
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: gcr.io/google_containers/cassandra:v4 image: gcr.io/google_containers/cassandra:v4
name: cassandra name: cassandra
ports: ports:

View File

@@ -26,6 +26,10 @@ spec:
value: 512M value: 512M
- name: HEAP_NEWSIZE - name: HEAP_NEWSIZE
value: 100M value: 100M
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumes: volumes:
- name: data - name: data
emptyDir: {} emptyDir: {}

View File

@@ -35,7 +35,7 @@ public class KubernetesSeedProvider implements SeedProvider {
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
static class Address { static class Address {
public String IP; public String ip;
} }
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
@@ -102,7 +102,8 @@ public class KubernetesSeedProvider implements SeedProvider {
List<InetAddress> list = new ArrayList<InetAddress>(); List<InetAddress> list = new ArrayList<InetAddress>();
String host = "https://kubernetes.default.cluster.local"; String host = "https://kubernetes.default.cluster.local";
String serviceName = getEnvOrDefault("CASSANDRA_SERVICE", "cassandra"); String serviceName = getEnvOrDefault("CASSANDRA_SERVICE", "cassandra");
String path = "/api/v1/namespaces/default/endpoints/"; String podNamespace = getEnvOrDefault("POD_NAMESPACE", "default");
String path = String.format("/api/v1/namespaces/%s/endpoints/", podNamespace);
try { try {
String token = getServiceAccountToken(); String token = getServiceAccountToken();
@@ -110,6 +111,7 @@ public class KubernetesSeedProvider implements SeedProvider {
ctx.init(null, trustAll, new SecureRandom()); ctx.init(null, trustAll, new SecureRandom());
URL url = new URL(host + path + serviceName); URL url = new URL(host + path + serviceName);
logger.info("Getting endpoints from " + url);
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
// TODO: Remove this once the CA cert is propogated everywhere, and replace // TODO: Remove this once the CA cert is propogated everywhere, and replace
@@ -125,10 +127,13 @@ public class KubernetesSeedProvider implements SeedProvider {
if (endpoints.subsets != null && !endpoints.subsets.isEmpty()){ if (endpoints.subsets != null && !endpoints.subsets.isEmpty()){
for (Subset subset : endpoints.subsets) { for (Subset subset : endpoints.subsets) {
for (Address address : subset.addresses) { for (Address address : subset.addresses) {
list.add(InetAddress.getByName(address.IP)); list.add(InetAddress.getByName(address.ip));
} }
} }
} }
logger.info("Available endpoints: " + list);
} else {
logger.warn("Endpoints are not available");
} }
} catch (IOException | NoSuchAlgorithmException | KeyManagementException ex) { } catch (IOException | NoSuchAlgorithmException | KeyManagementException ex) {
logger.warn("Request to kubernetes apiserver failed", ex); logger.warn("Request to kubernetes apiserver failed", ex);