Kubernetes salt formula first version.
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..c71b7f6
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,184 @@
+
+==================
+Kubernetes Formula
+==================
+
+
+Based on official Kubernetes salt
+https://github.com/kubernetes/kubernetes/tree/master/cluster/saltbase
+
+Extended on Contrail contribution https://github.com/Juniper/kubernetes/blob/opencontrail-integration/docs/getting-started-guides/opencontrail.md
+
+
+Sample pillars
+==============
+
+.. code-block:: yaml
+
+ kubernetes:
+ master:
+
+ kubernetes:
+ pool:
+
+
+Kubernetes with OpenContrail
+----------------------------
+
+On Master:
+
+.. code-block:: yaml
+
+ kubernetes:
+ master:
+ network:
+ engine: opencontrail
+ host: 10.0.170.70
+ port: 8082
+ default_domain: default-domain
+ default_project: default-domain:default-project
+ public_network: default-domain:default-project:Public
+ public_ip_range: 185.22.97.128/26
+ private_ip_range: 10.150.0.0/16
+ service_cluster_ip_range: 10.254.0.0/16
+ network_label: name
+ service_label: uses
+ cluster_service: kube-system/default
+ network_manager:
+ image: pupapaik/opencontrail-kube-network-manager
+ tag: release-1.1-jpa-final-1
+
+On pools:
+
+.. code-block:: yaml
+
+ kubernetes:
+ pool:
+ network:
+ engine: opencontrail
+
+Kubernetes with Flannel
+-----------------------
+
+On Master:
+
+.. code-block:: yaml
+
+ kubernetes:
+ master:
+ network:
+ engine: flannel
+ common:
+ network:
+ engine: flannel
+
+On pools:
+
+.. code-block:: yaml
+
+ kubernetes:
+ pool:
+ network:
+ engine: flannel
+ common:
+ network:
+ engine: flannel
+
+Kubernetes with Calico
+-----------------------
+
+On Master:
+
+.. code-block:: yaml
+
+ kubernetes:
+ master:
+ network:
+ engine: calico
+
+On pools:
+
+.. code-block:: yaml
+
+ kubernetes:
+ pool:
+ network:
+ engine: calico
+
+Kubernetes Service Definitions
+------------------------------
+
+.. code-block:: yaml
+
+ salt:
+ control:
+ enabled: True
+ hostNetwork: True
+ service:
+ memcached:
+ privileged: True
+ service: memcached
+ role: server
+ type: LoadBalancer
+ replicas: 3
+ kind: Deployment
+ apiVersion: extensions/v1beta1
+ ports:
+ - port: 8774
+ name: nova-api
+ - port: 8775
+ name: nova-metadata
+ volume:
+ volume_name:
+ type: hostPath
+ mount: /certs
+ path: /etc/certs
+ container:
+ memcached:
+ image: memcached
+ tag:2
+ ports:
+ - port: 8774
+ name: nova-api
+ - port: 8775
+ name: nova-metadata
+ variables:
+ - name: HTTP_TLS_CERTIFICATE:
+ value: /certs/domain.crt
+ - name: HTTP_TLS_KEY
+ value: /certs/domain.key
+ volumes:
+ - name: /etc/certs
+ type: hostPath
+ mount: /certs
+ path: /etc/certs
+
+Volumes
+-------
+
+hostPath
+===========
+
+.. code-block:: yaml
+
+ container:
+ memcached:
+ ...
+ volumes:
+ - name: /etc/certs
+ mount: /certs
+ type: hostPath
+ path: /etc/certs
+
+emptyDir
+===========
+
+.. code-block:: yaml
+
+ container:
+ memcached:
+ ...
+ volumes:
+ - name: /etc/certs
+ mount: /certs
+ type: emptyDir
\ No newline at end of file
diff --git a/kubernetes/_common.sls b/kubernetes/_common.sls
new file mode 100644
index 0000000..5025617
--- /dev/null
+++ b/kubernetes/_common.sls
@@ -0,0 +1,31 @@
+{% from "kubernetes/map.jinja" import common with context %}
+
+kubernetes_pkgs:
+ pkg.installed:
+ - names: {{ common.pkgs }}
+
+kubernetes_binaries:
+ cmd.run:
+ - name: 'wget -r --no-parent --reject "index.html*" http://apt.tcpcloud.eu/kubernetes/bin/{{ common.binaries_version }}/ && chmod +x -R /root/apt.tcpcloud.eu/kubernetes/bin/{{ common.binaries_version }}/*'
+ - pwd: /root
+ - unless: test -d /root/apt.tcpcloud.eu/kubernetes/bin/
+
+etcdctl_binaries:
+ cmd.run:
+ - name: "curl -L https://github.com/coreos/etcd/releases/download/v2.2.1/etcd-v2.2.1-linux-amd64.tar.gz -o etcd-v2.2.1-linux-amd64.tar.gz;tar -zxvf etcd-v2.2.1-linux-amd64.tar.gz"
+ - pwd: /root
+ - unless: test -f /root/etcd-v2.2.1-linux-amd64.tar.gz
+
+{%- if common.network.get('engine', 'none') == 'flannel' %}
+flannel-tar:
+ archive:
+ - extracted
+ - user: root
+ - name: /usr/local/src
+ - makedirs: True
+ - source: https://storage.googleapis.com/kubernetes-release/flannel/flannel-0.5.5-linux-amd64.tar.gz
+ - tar_options: v
+ - source_hash: md5=972c717254775bef528f040af804f2cc
+ - archive_format: tar
+ - if_missing: /usr/local/src/flannel/flannel-0.5.5/
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/control/cluster.sls b/kubernetes/control/cluster.sls
new file mode 100644
index 0000000..d0d7ac0
--- /dev/null
+++ b/kubernetes/control/cluster.sls
@@ -0,0 +1,38 @@
+{% from "kubernetes/map.jinja" import control with context %}
+{%- if control.enabled %}
+
+/srv/kubernetes:
+ file.directory:
+ - makedirs: true
+
+{%- for service_name, service in control.service.iteritems() %}
+
+{%- if service.enabled == true %}
+/srv/kubernetes/services/{{ service_name }}-svc.yml:
+ file.managed:
+ - source: salt://kubernetes/files/svc.yml
+ - user: root
+ - group: root
+ - template: jinja
+ - makedirs: true
+ - require:
+ - file: /srv/kubernetes
+ - defaults:
+ service: {{ service|yaml }}
+{%- endif %}
+
+/srv/kubernetes/{{ service.cluster }}/{{ service_name }}-{{ service.kind }}.yml:
+ file.managed:
+ - source: salt://kubernetes/files/rc.yml
+ - user: root
+ - group: root
+ - template: jinja
+ - makedirs: true
+ - require:
+ - file: /srv/kubernetes
+ - defaults:
+ service: {{ service|yaml }}
+
+{%- endfor %}
+
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/control/init.sls b/kubernetes/control/init.sls
new file mode 100644
index 0000000..35c5745
--- /dev/null
+++ b/kubernetes/control/init.sls
@@ -0,0 +1,3 @@
+
+include:
+- kubernetes.control.cluster
diff --git a/kubernetes/files/basic_auth.csv b/kubernetes/files/basic_auth.csv
new file mode 100644
index 0000000..69740b5
--- /dev/null
+++ b/kubernetes/files/basic_auth.csv
@@ -0,0 +1,2 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{{ master.admin.username }},{{ master.admin.password }},admin
\ No newline at end of file
diff --git a/kubernetes/files/calico/calico-node.service b/kubernetes/files/calico/calico-node.service
new file mode 100644
index 0000000..5a206db
--- /dev/null
+++ b/kubernetes/files/calico/calico-node.service
@@ -0,0 +1,16 @@
+[Unit]
+Description=Calico per-node agent
+Documentation=https://github.com/projectcalico/calico-docker
+Requires=docker.service
+After=docker.service
+
+[Service]
+User=root
+EnvironmentFile=/etc/calico/network-environment
+PermissionsStartOnly=true
+ExecStart=/usr/bin/calicoctl node --ip=${DEFAULT_IPV4} --detach=false
+Restart=always
+RestartSec=10
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/kubernetes/files/calico/calico.conf b/kubernetes/files/calico/calico.conf
new file mode 100644
index 0000000..c6cb273
--- /dev/null
+++ b/kubernetes/files/calico/calico.conf
@@ -0,0 +1,10 @@
+{%- from "kubernetes/map.jinja" import pool with context %}
+{
+ "name": "calico-k8s-network",
+ "type": "calico",
+ "etcd_authority": "{{ pool.master.host }}:6666",
+ "log_level": "info",
+ "ipam": {
+ "type": "calico-ipam"
+ }
+}
\ No newline at end of file
diff --git a/kubernetes/files/calico/network-environment.master b/kubernetes/files/calico/network-environment.master
new file mode 100644
index 0000000..64e55dc
--- /dev/null
+++ b/kubernetes/files/calico/network-environment.master
@@ -0,0 +1,7 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+# This host's IPv4 address (the source IP address used to reach other nodes
+# in the Kubernetes cluster).
+DEFAULT_IPV4={{ master.apiserver.address }}
+
+# IP and port of etcd instance used by Calico
+ETCD_AUTHORITY={{ master.apiserver.address }}:6666
\ No newline at end of file
diff --git a/kubernetes/files/calico/network-environment.pool b/kubernetes/files/calico/network-environment.pool
new file mode 100644
index 0000000..aa0126e
--- /dev/null
+++ b/kubernetes/files/calico/network-environment.pool
@@ -0,0 +1,10 @@
+{%- from "kubernetes/map.jinja" import pool with context %}
+# This host's IPv4 address (the source IP address used to reach other nodes
+# in the Kubernetes cluster).
+DEFAULT_IPV4={{ pool.address }}
+
+# The Kubernetes master IP
+KUBERNETES_MASTER={{ pool.master.host }}
+
+# IP and port of etcd instance used by Calico
+ETCD_AUTHORITY={{ pool.master.host }}:6666
\ No newline at end of file
diff --git a/kubernetes/files/flannel/default.master b/kubernetes/files/flannel/default.master
new file mode 100644
index 0000000..61fbc6d
--- /dev/null
+++ b/kubernetes/files/flannel/default.master
@@ -0,0 +1,3 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+
+DAEMON_ARGS="--etcd-endpoints={% for member in master.etcd.members %}http://{{ member.host }}:4001{% if not loop.last %},{% endif %}{% endfor %} --ip-masq --etcd-prefix=/kubernetes.io/network"
\ No newline at end of file
diff --git a/kubernetes/files/flannel/default.pool b/kubernetes/files/flannel/default.pool
new file mode 100644
index 0000000..bd1a506
--- /dev/null
+++ b/kubernetes/files/flannel/default.pool
@@ -0,0 +1,3 @@
+{%- from "kubernetes/map.jinja" import pool with context %}
+
+DAEMON_ARGS="--etcd-endpoints={% for member in pool.master.etcd.members %}http://{{ member.host }}:4001{% if not loop.last %},{% endif %}{% endfor %} --ip-masq --etcd-prefix=/kubernetes.io/network"
\ No newline at end of file
diff --git a/kubernetes/files/flannel/initd b/kubernetes/files/flannel/initd
new file mode 100644
index 0000000..7da921a
--- /dev/null
+++ b/kubernetes/files/flannel/initd
@@ -0,0 +1,126 @@
+#!/bin/bash
+#
+### BEGIN INIT INFO
+# Provides: flanneld
+# Required-Start: $local_fs $network $syslog
+# Required-Stop:
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: Flannel daemon
+# Description:
+# Flannel daemon.
+### END INIT INFO
+
+
+# PATH should only include /usr/* if it runs after the mountnfs.sh script
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
+DESC="Flannel overlay network daemon"
+NAME=flannel
+DAEMON=/usr/local/bin/flanneld
+DAEMON_ARGS="--ip-masq"
+DAEMON_LOG_FILE=/var/log/$NAME.log
+PIDFILE=/var/run/$NAME.pid
+SCRIPTNAME=/etc/init.d/$NAME
+DAEMON_USER=root
+
+# Exit if the package is not installed
+[ -x "$DAEMON" ] || exit 0
+
+# Read configuration variable file if it is present
+[ -r /etc/default/$NAME ] && . /etc/default/$NAME
+
+# Define LSB log_* functions.
+# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
+# and status_of_proc is working.
+. /lib/lsb/init-functions
+
+#
+# Function that starts the daemon/service
+#
+do_start()
+{
+ # Avoid a potential race at boot time when both monit and init.d start
+ # the same service
+ PIDS=$(pidof $DAEMON)
+ for PID in ${PIDS}; do
+ kill -9 $PID
+ done
+
+ # Return
+ # 0 if daemon has been started
+ # 1 if daemon was already running
+ # 2 if daemon could not be started
+ start-stop-daemon --start --quiet --background --no-close \
+ --make-pidfile --pidfile $PIDFILE \
+ --exec $DAEMON -c $DAEMON_USER --test > /dev/null \
+ || return 1
+ start-stop-daemon --start --quiet --background --no-close \
+ --make-pidfile --pidfile $PIDFILE \
+ --exec $DAEMON -c $DAEMON_USER -- \
+ $DAEMON_ARGS >> $DAEMON_LOG_FILE 2>&1 \
+ || return 2
+}
+
+#
+# Function that stops the daemon/service
+#
+do_stop()
+{
+ # Return
+ # 0 if daemon has been stopped
+ # 1 if daemon was already stopped
+ # 2 if daemon could not be stopped
+ # other if a failure occurred
+ start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
+ RETVAL="$?"
+ [ "$RETVAL" = 2 ] && return 2
+ # Many daemons don't delete their pidfiles when they exit.
+ rm -f $PIDFILE
+ return "$RETVAL"
+}
+
+
+case "$1" in
+ start)
+ log_daemon_msg "Starting $DESC" "$NAME"
+ do_start
+ case "$?" in
+ 0|1) log_end_msg 0 || exit 0 ;;
+ 2) log_end_msg 1 || exit 1 ;;
+ esac
+ ;;
+ stop)
+ log_daemon_msg "Stopping $DESC" "$NAME"
+ do_stop
+ case "$?" in
+ 0|1) log_end_msg 0 ;;
+ 2) exit 1 ;;
+ esac
+ ;;
+ status)
+ status_of_proc -p $PIDFILE "$DAEMON" "$NAME" && exit 0 || exit $?
+ ;;
+
+ restart|force-reload)
+ log_daemon_msg "Restarting $DESC" "$NAME"
+ do_stop
+ case "$?" in
+ 0|1)
+ do_start
+ case "$?" in
+ 0) log_end_msg 0 ;;
+ 1) log_end_msg 1 ;; # Old process is still running
+ *) log_end_msg 1 ;; # Failed to start
+ esac
+ ;;
+ *)
+ # Failed to stop
+ log_end_msg 1
+ ;;
+ esac
+ ;;
+ *)
+ echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
+ exit 3
+ ;;
+esac
\ No newline at end of file
diff --git a/kubernetes/files/flannel/network.json b/kubernetes/files/flannel/network.json
new file mode 100644
index 0000000..d45fef2
--- /dev/null
+++ b/kubernetes/files/flannel/network.json
@@ -0,0 +1,9 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{
+ "Network": "{{ master.network.private_ip_range }}",
+ "SubnetLen": 24,
+ "Backend": {
+ "Type": "vxlan",
+ "VNI": 1
+ }
+}
\ No newline at end of file
diff --git a/kubernetes/files/known_tokens.csv b/kubernetes/files/known_tokens.csv
new file mode 100644
index 0000000..3bc3198
--- /dev/null
+++ b/kubernetes/files/known_tokens.csv
@@ -0,0 +1,9 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{{ master.token.admin }},admin,admin
+{{ master.token.kubelet }},kubelet,kubelet
+{{ master.token.kube_proxy }},kube_proxy,kube_proxy
+{{ master.token.scheduler }},system:scheduler,system:scheduler
+{{ master.token.controller_manager }},system:controller_manager,system:controller_manager
+{{ master.token.logging }},system:logging,system:logging
+{{ master.token.monitoring }},system:monitoring,system:monitoring
+{{ master.token.dns }},system:dns,system:dns
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/dashboard/dashboard-address.yaml b/kubernetes/files/kube-addons/dashboard/dashboard-address.yaml
new file mode 100644
index 0000000..8ca2a27
--- /dev/null
+++ b/kubernetes/files/kube-addons/dashboard/dashboard-address.yaml
@@ -0,0 +1,17 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: Service
+metadata:
+ name: kubernetes-dashboard-address
+ namespace: kube-system
+ labels:
+ k8s-app: kubernetes-dashboard
+ kubernetes.io/cluster-service: "true"
+spec:
+ selector:
+ k8s-app: kubernetes-dashboard
+ deprecatedPublicIPs: ["{{ master.addons.ui.public_ip }}"]
+ type: LoadBalancer
+ ports:
+ - port: 80
+ targetPort: 9090
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/dashboard/dashboard-controller.yaml b/kubernetes/files/kube-addons/dashboard/dashboard-controller.yaml
new file mode 100644
index 0000000..c2eba63
--- /dev/null
+++ b/kubernetes/files/kube-addons/dashboard/dashboard-controller.yaml
@@ -0,0 +1,39 @@
+apiVersion: v1
+kind: ReplicationController
+metadata:
+ # Keep the name in sync with image version and
+ # gce/coreos/kube-manifests/addons/dashboard counterparts
+ name: kubernetes-dashboard-v1.1.0-beta2
+ namespace: kube-system
+ labels:
+ k8s-app: kubernetes-dashboard
+ kubernetes.io/cluster-service: "true"
+spec:
+ replicas: 1
+ selector:
+ k8s-app: kubernetes-dashboard
+ template:
+ metadata:
+ labels:
+ k8s-app: kubernetes-dashboard
+ kubernetes.io/cluster-service: "true"
+ spec:
+ containers:
+ - name: kubernetes-dashboard
+ image: gcr.io/google_containers/kubernetes-dashboard-amd64:v1.1.0-beta2
+ resources:
+ # keep request = limit to keep this container in guaranteed class
+ limits:
+ cpu: 100m
+ memory: 50Mi
+ requests:
+ cpu: 100m
+ memory: 50Mi
+ ports:
+ - containerPort: 9090
+ livenessProbe:
+ httpGet:
+ path: /
+ port: 9090
+ initialDelaySeconds: 30
+ timeoutSeconds: 30
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/dashboard/dashboard-endpoint.yaml b/kubernetes/files/kube-addons/dashboard/dashboard-endpoint.yaml
new file mode 100644
index 0000000..35ace0f
--- /dev/null
+++ b/kubernetes/files/kube-addons/dashboard/dashboard-endpoint.yaml
@@ -0,0 +1,16 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: Endpoints
+metadata:
+ name: kubernetes-dashboard
+ namespace: kube-system
+ labels:
+ k8s-app: kubernetes-dashboard
+ kubernetes.io/cluster-service: "true"
+subsets:
+ - addresses:
+ - ip: {{ master.addons.ui.public_ip }}
+
+ ports:
+ - port: 9090
+ protocol: TCP
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/dashboard/dashboard-service.yaml b/kubernetes/files/kube-addons/dashboard/dashboard-service.yaml
new file mode 100644
index 0000000..2c2ce3f
--- /dev/null
+++ b/kubernetes/files/kube-addons/dashboard/dashboard-service.yaml
@@ -0,0 +1,18 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: Service
+metadata:
+ name: kubernetes-dashboard
+ namespace: kube-system
+ labels:
+ k8s-app: kubernetes-dashboard
+ kubernetes.io/cluster-service: "true"
+spec:
+{%- if master.network.engine != 'opencontrail' %}
+ selector:
+ k8s-app: kubernetes-dashboard
+ type: NodePort
+{%- endif %}
+ ports:
+ - port: 80
+ targetPort: 9090
diff --git a/kubernetes/files/kube-addons/dns/skydns-rc.yaml b/kubernetes/files/kube-addons/dns/skydns-rc.yaml
new file mode 100644
index 0000000..c7b7969
--- /dev/null
+++ b/kubernetes/files/kube-addons/dns/skydns-rc.yaml
@@ -0,0 +1,100 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: ReplicationController
+metadata:
+ name: kube-dns-v9
+ namespace: kube-system
+ labels:
+ k8s-app: kube-dns
+ version: v9
+ kubernetes.io/cluster-service: "true"
+spec:
+ replicas: {{ master.addons.dns.replicas }}
+ selector:
+ k8s-app: kube-dns
+ version: v9
+ template:
+ metadata:
+ labels:
+ k8s-app: kube-dns
+ version: v9
+ kubernetes.io/cluster-service: "true"
+ spec:
+ containers:
+ - name: etcd
+ image: gcr.io/google_containers/etcd:2.0.9
+ resources:
+ limits:
+ cpu: 100m
+ memory: 50Mi
+ command:
+ - /usr/local/bin/etcd
+ - -data-dir
+ - /var/etcd/data
+ - -listen-client-urls
+ - http://127.0.0.1:2379,http://127.0.0.1:4001
+ - -advertise-client-urls
+ - http://127.0.0.1:2379,http://127.0.0.1:4001
+ - -initial-cluster-token
+ - skydns-etcd
+ volumeMounts:
+ - name: etcd-storage
+ mountPath: /var/etcd/data
+ - name: kube2sky
+ image: gcr.io/google_containers/kube2sky:1.11
+ resources:
+ limits:
+ cpu: 100m
+ memory: 50Mi
+ args:
+ # command = "/kube2sky"
+ - -domain={{ master.addons.dns.domain }}
+ - name: skydns
+ image: gcr.io/google_containers/skydns:2015-10-13-8c72f8c
+ resources:
+ limits:
+ cpu: 100m
+ memory: 50Mi
+ args:
+ # command = "/skydns"
+ - -machines=http://127.0.0.1:4001
+ - -addr=0.0.0.0:53
+ - -ns-rotate=false
+ - -domain={{ master.addons.dns.domain }}.
+ ports:
+ - containerPort: 53
+ name: dns
+ protocol: UDP
+ - containerPort: 53
+ name: dns-tcp
+ protocol: TCP
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: 8080
+ scheme: HTTP
+ initialDelaySeconds: 30
+ timeoutSeconds: 5
+ readinessProbe:
+ httpGet:
+ path: /healthz
+ port: 8080
+ scheme: HTTP
+ initialDelaySeconds: 1
+ timeoutSeconds: 5
+ - name: healthz
+ image: gcr.io/google_containers/exechealthz:1.0
+ resources:
+ limits:
+ cpu: 10m
+ memory: 20Mi
+ args:
+ - -cmd=nslookup kubernetes.default.svc.{{ master.addons.dns.domain }} localhost >/dev/null
+ - -port=8080
+ ports:
+ - containerPort: 8080
+ protocol: TCP
+ volumes:
+ - name: etcd-storage
+ emptyDir: {}
+ dnsPolicy: Default # Don't use cluster DNS.
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/dns/skydns-svc.yaml b/kubernetes/files/kube-addons/dns/skydns-svc.yaml
new file mode 100644
index 0000000..88ebf0b
--- /dev/null
+++ b/kubernetes/files/kube-addons/dns/skydns-svc.yaml
@@ -0,0 +1,21 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: Service
+metadata:
+ name: kube-dns
+ namespace: kube-system
+ labels:
+ k8s-app: kube-dns
+ kubernetes.io/cluster-service: "true"
+ kubernetes.io/name: "KubeDNS"
+spec:
+ selector:
+ k8s-app: kube-dns
+ clusterIP: {{ master.addons.dns.server }}
+ ports:
+ - name: dns
+ port: 53
+ protocol: UDP
+ - name: dns-tcp
+ port: 53
+ protocol: TCP
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/heapster-influxdb/heapster-address.yaml b/kubernetes/files/kube-addons/heapster-influxdb/heapster-address.yaml
new file mode 100644
index 0000000..28f2c24
--- /dev/null
+++ b/kubernetes/files/kube-addons/heapster-influxdb/heapster-address.yaml
@@ -0,0 +1,18 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ k8s-app: heapster
+ kubernetes.io/cluster-service: 'true'
+ kubernetes.io/name: 'Heapster'
+ name: heapster-address
+ namespace: kube-system
+spec:
+ ports:
+ - port: 80
+ targetPort: 8082
+ selector:
+ k8s-app: heapster
+ deprecatedPublicIPs: ['{{ master.addons.heapster_influxdb.public_ip }}']
+ type: LoadBalancer
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/heapster-influxdb/heapster-controller.yaml b/kubernetes/files/kube-addons/heapster-influxdb/heapster-controller.yaml
new file mode 100644
index 0000000..8b3f251
--- /dev/null
+++ b/kubernetes/files/kube-addons/heapster-influxdb/heapster-controller.yaml
@@ -0,0 +1,30 @@
+apiVersion: v1
+kind: ReplicationController
+metadata:
+ labels:
+ k8s-app: heapster
+ version: v6
+ name: heapster
+ namespace: kube-system
+spec:
+ replicas: 1
+ selector:
+ k8s-app: heapster
+ version: v6
+ template:
+ metadata:
+ labels:
+# name: heapster
+ uses: monitoring-influxdb
+ k8s-app: heapster
+ version: v6
+ kubernetes.io/cluster-service: "true"
+ spec:
+ containers:
+ - name: heapster
+ image: kubernetes/heapster:canary
+ imagePullPolicy: Always
+ command:
+ - /heapster
+ - --source=kubernetes:https://kubernetes.default
+ - --sink=influxdb:http://monitoring-influxdb:8086
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/heapster-influxdb/heapster-endpoint.yaml b/kubernetes/files/kube-addons/heapster-influxdb/heapster-endpoint.yaml
new file mode 100644
index 0000000..35a140c
--- /dev/null
+++ b/kubernetes/files/kube-addons/heapster-influxdb/heapster-endpoint.yaml
@@ -0,0 +1,17 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: Endpoints
+metadata:
+ name: heapster
+ namespace: kube-system
+ labels:
+ k8s-app: heapster
+ kubernetes.io/cluster-service: "true"
+ kubernetes.io/name: "Heapster"
+subsets:
+ - addresses:
+ - ip: {{ master.addons.heapster_influxdb.public_ip }}
+
+ ports:
+ - port: 8082
+ protocol: TCP
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/heapster-influxdb/heapster-service.yaml b/kubernetes/files/kube-addons/heapster-influxdb/heapster-service.yaml
new file mode 100644
index 0000000..f04cf83
--- /dev/null
+++ b/kubernetes/files/kube-addons/heapster-influxdb/heapster-service.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ k8s-app: heapster
+ kubernetes.io/cluster-service: 'true'
+ kubernetes.io/name: 'Heapster'
+ name: heapster
+ namespace: kube-system
+spec:
+ ports:
+ - port: 80
+ targetPort: 8082
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/heapster-influxdb/influxdb-controller.yaml b/kubernetes/files/kube-addons/heapster-influxdb/influxdb-controller.yaml
new file mode 100644
index 0000000..6235c18
--- /dev/null
+++ b/kubernetes/files/kube-addons/heapster-influxdb/influxdb-controller.yaml
@@ -0,0 +1,25 @@
+apiVersion: v1
+kind: ReplicationController
+metadata:
+ labels:
+ name: influxGrafana
+ name: influxdb-grafana
+ namespace: kube-system
+spec:
+ replicas: 1
+ selector:
+ name: influxGrafana
+ template:
+ metadata:
+ labels:
+ name: influxGrafana
+ spec:
+ containers:
+ - name: influxdb
+ image: kubernetes/heapster_influxdb:v0.6
+ volumeMounts:
+ - mountPath: /data
+ name: influxdb-storage
+ volumes:
+ - name: influxdb-storage
+ emptyDir: {}
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/heapster-influxdb/influxdb-service.yaml b/kubernetes/files/kube-addons/heapster-influxdb/influxdb-service.yaml
new file mode 100644
index 0000000..64bed1e
--- /dev/null
+++ b/kubernetes/files/kube-addons/heapster-influxdb/influxdb-service.yaml
@@ -0,0 +1,17 @@
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ name: monitoring-influxdb
+ name: monitoring-influxdb
+ namespace: kube-system
+spec:
+ ports:
+ - name: http
+ port: 8083
+ targetPort: 8083
+ - name: api
+ port: 8086
+ targetPort: 8086
+ selector:
+ name: influxGrafana
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/initd b/kubernetes/files/kube-addons/initd
new file mode 100644
index 0000000..0ed6f47
--- /dev/null
+++ b/kubernetes/files/kube-addons/initd
@@ -0,0 +1,120 @@
+#!/bin/bash
+#
+### BEGIN INIT INFO
+# Provides: kube-addons
+# Required-Start: $local_fs $network $syslog kube-apiserver
+# Required-Stop:
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: Kubernetes Addon Object Manager
+# Description:
+# Enforces installation of Kubernetes Addon Objects
+### END INIT INFO
+
+
+# PATH should only include /usr/* if it runs after the mountnfs.sh script
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
+DESC="Kubernetes Addon Object Manager"
+NAME=kube-addons
+DAEMON_LOG_FILE=/var/log/${NAME}.log
+PIDFILE=/var/run/${NAME}.pid
+SCRIPTNAME=/etc/init.d/${NAME}
+KUBE_ADDONS_SH=/etc/kubernetes/kube-addons.sh
+
+# Define LSB log_* functions.
+# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
+# and status_of_proc is working.
+. /lib/lsb/init-functions
+
+
+
+
+#
+# Function that starts the daemon/service
+#
+do_start()
+{
+ # use setsid to make sure the new daemon has its own group (I suppose
+ # start-stop-daemon does create a process group, but let's stay on the
+ # safe side).
+ setsid start-stop-daemon --start --verbose --background --no-close --make-pidfile --pidfile "${PIDFILE}" --startas "${KUBE_ADDONS_SH}" </dev/null >> ${DAEMON_LOG_FILE} 2>&1
+}
+
+#
+# Function that stops the daemon/service
+#
+do_stop()
+{
+ # start-stop-daemon is not used because we have to stop all children
+ # limitations:
+ # - stop does not work if the pid file is missing
+ # - stop does not work if the daemon process is missing (children will not
+ # be killed)
+ # This is sufficient - remaining processes will end after a while.
+
+ local pid
+ pid=$(cat "${PIDFILE}" 2> /dev/null)
+ if [[ $? != 0 ]]; then
+ return 1
+ fi
+ local pgrp
+ # find the process group for the service and kill entire group
+ # o - output format: pgpg - process group
+ pgrp=$(ps --no-headers --pid "${pid}" -o pgrp 2>/dev/null)
+ if [[ $? != 0 ]] || [[ "${pgrp}" == "" ]]; then
+ return 1
+ fi
+ pgrp=$(echo -e ${pgrp}) # strip whitespaces (that's why there are no quotes around pgrp)
+ # negative pid is for killing entire group
+ kill -- -${pgrp} 2> /dev/null
+ if [[ $? != 0 ]]; then
+ return 2
+ fi
+ rm -f "${PIDFILE}"
+ return
+}
+
+case "$1" in
+ start)
+ log_daemon_msg "Starting ${DESC}" "${NAME}"
+ do_start
+ case "$?" in
+ 0|1) log_end_msg 0 || exit 0 ;;
+ 2) log_end_msg 1 || exit 1 ;;
+ esac
+ ;;
+ stop)
+ log_daemon_msg "Stopping ${DESC}" "${NAME}"
+ do_stop
+ case "$?" in
+ 0|1) log_end_msg 0 || exit 0 ;;
+ 2) log_end_msg 1 || exit 1 ;;
+ esac
+ ;;
+ status)
+ status_of_proc -p "${PIDFILE}" "${KUBE_ADDONS_SH}" "${NAME}"
+ ;;
+
+ restart|force-reload)
+ log_daemon_msg "Restarting ${DESC}" "${NAME}"
+ do_stop
+ case "$?" in
+ 0|1)
+ do_start
+ case "$?" in
+ 0) log_end_msg 0 ;;
+ 1) log_end_msg 1 ;; # Old process is still running
+ *) log_end_msg 1 ;; # Failed to start
+ esac
+ ;;
+ *)
+ # Failed to stop
+ log_end_msg 1
+ ;;
+ esac
+ ;;
+ *)
+ echo "Usage: ${SCRIPTNAME} {start|stop|status|restart|force-reload}" >&2
+ exit 3
+ ;;
+esac
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/kube-addon-update.sh b/kubernetes/files/kube-addons/kube-addon-update.sh
new file mode 100644
index 0000000..77534a1
--- /dev/null
+++ b/kubernetes/files/kube-addons/kube-addon-update.sh
@@ -0,0 +1,507 @@
+#!/bin/bash
+
+# Copyright 2015 The Kubernetes Authors All rights reserved.
+#
+# 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.
+
+# The business logic for whether a given object should be created
+# was already enforced by salt, and /etc/kubernetes/addons is the
+# managed result is of that. Start everything below that directory.
+
+# Parameters
+# $1 path to add-ons
+
+
+# LIMITATIONS
+# 1. controllers are not updated unless their name is changed
+# 3. Services will not be updated unless their name is changed,
+# but for services we actually want updates without name change.
+# 4. Json files are not handled at all. Currently addons must be
+# in yaml files
+# 5. exit code is probably not always correct (I haven't checked
+# carefully if it works in 100% cases)
+# 6. There are no unittests
+# 8. Will not work if the total length of paths to addons is greater than
+# bash can handle. Probably it is not a problem: ARG_MAX=2097152 on GCE.
+# 9. Performance issue: yaml files are read many times in a single execution.
+
+# cosmetic improvements to be done
+# 1. improve the log function; add timestamp, file name, etc.
+# 2. logging doesn't work from files that print things out.
+# 3. kubectl prints the output to stderr (the output should be captured and then
+# logged)
+
+
+
+# global config
+KUBECTL=${TEST_KUBECTL:-} # substitute for tests
+KUBECTL=${KUBECTL:-${KUBECTL_BIN:-}}
+KUBECTL=${KUBECTL:-/usr/local/bin/kubectl}
+if [[ ! -x ${KUBECTL} ]]; then
+ echo "ERROR: kubectl command (${KUBECTL}) not found or is not executable" 1>&2
+ exit 1
+fi
+
+# If an add-on definition is incorrect, or a definition has just disappeared
+# from the local directory, the script will still keep on retrying.
+# The script does not end until all retries are done, so
+# one invalid manifest may block updates of other add-ons.
+# Be careful how you set these parameters
+NUM_TRIES=1 # will be updated based on input parameters
+DELAY_AFTER_ERROR_SEC=${TEST_DELAY_AFTER_ERROR_SEC:=10}
+
+
+# remember that you can't log from functions that print some output (because
+# logs are also printed on stdout)
+# $1 level
+# $2 message
+function log() {
+ # manage log levels manually here
+
+ # add the timestamp if you find it useful
+ case $1 in
+ DB3 )
+# echo "$1: $2"
+ ;;
+ DB2 )
+# echo "$1: $2"
+ ;;
+ DBG )
+# echo "$1: $2"
+ ;;
+ INFO )
+ echo "$1: $2"
+ ;;
+ WRN )
+ echo "$1: $2"
+ ;;
+ ERR )
+ echo "$1: $2"
+ ;;
+ * )
+ echo "INVALID_LOG_LEVEL $1: $2"
+ ;;
+ esac
+}
+
+#$1 yaml file path
+function get-object-kind-from-file() {
+ # prints to stdout, so log cannot be used
+ #WARNING: only yaml is supported
+ cat $1 | python -c '''
+try:
+ import pipes,sys,yaml
+ y = yaml.load(sys.stdin)
+ labels = y["metadata"]["labels"]
+ if ("kubernetes.io/cluster-service", "true") not in labels.iteritems():
+ # all add-ons must have the label "kubernetes.io/cluster-service".
+ # Otherwise we are ignoring them (the update will not work anyway)
+ print "ERROR"
+ else:
+ print y["kind"]
+except Exception, ex:
+ print "ERROR"
+ '''
+}
+
+# $1 yaml file path
+# returns a string of the form <namespace>/<name> (we call it nsnames)
+function get-object-nsname-from-file() {
+ # prints to stdout, so log cannot be used
+ #WARNING: only yaml is supported
+ #addons that do not specify a namespace are assumed to be in "default".
+ cat $1 | python -c '''
+try:
+ import pipes,sys,yaml
+ y = yaml.load(sys.stdin)
+ labels = y["metadata"]["labels"]
+ if ("kubernetes.io/cluster-service", "true") not in labels.iteritems():
+ # all add-ons must have the label "kubernetes.io/cluster-service".
+ # Otherwise we are ignoring them (the update will not work anyway)
+ print "ERROR"
+ else:
+ try:
+ print "%s/%s" % (y["metadata"]["namespace"], y["metadata"]["name"])
+ except Exception, ex:
+ print "default/%s" % y["metadata"]["name"]
+except Exception, ex:
+ print "ERROR"
+ '''
+}
+
+# $1 addon directory path
+# $2 addon type (e.g. ReplicationController)
+# echoes the string with paths to files containing addon for the given type
+# works only for yaml files (!) (ignores json files)
+function get-addon-paths-from-disk() {
+ # prints to stdout, so log cannot be used
+ local -r addon_dir=$1
+ local -r obj_type=$2
+ local kind
+ local file_path
+ for file_path in $(find ${addon_dir} -name \*.yaml); do
+ kind=$(get-object-kind-from-file ${file_path})
+ # WARNING: assumption that the topmost indentation is zero (I'm not sure yaml allows for topmost indentation)
+ if [[ "${kind}" == "${obj_type}" ]]; then
+ echo ${file_path}
+ fi
+ done
+}
+
+# waits for all subprocesses
+# returns 0 if all of them were successful and 1 otherwise
+function wait-for-jobs() {
+ local rv=0
+ local pid
+ for pid in $(jobs -p); do
+ wait ${pid}
+ if [[ $? -ne 0 ]]; then
+ rv=1;
+ log ERR "error in pid ${pid}"
+ fi
+ log DB2 "pid ${pid} completed, current error code: ${rv}"
+ done
+ return ${rv}
+}
+
+
+function run-until-success() {
+ local -r command=$1
+ local tries=$2
+ local -r delay=$3
+ local -r command_name=$1
+ while [ ${tries} -gt 0 ]; do
+ log DBG "executing: '$command'"
+ # let's give the command as an argument to bash -c, so that we can use
+ # && and || inside the command itself
+ /bin/bash -c "${command}" && \
+ log DB3 "== Successfully executed ${command_name} at $(date -Is) ==" && \
+ return 0
+ let tries=tries-1
+ log INFO "== Failed to execute ${command_name} at $(date -Is). ${tries} tries remaining. =="
+ sleep ${delay}
+ done
+ return 1
+}
+
+# $1 object type
+# returns a list of <namespace>/<name> pairs (nsnames)
+function get-addon-nsnames-from-server() {
+ local -r obj_type=$1
+ "${KUBECTL}" get "${obj_type}" --all-namespaces -o go-template="{{range.items}}{{.metadata.namespace}}/{{.metadata.name}} {{end}}" --api-version=v1 -l kubernetes.io/cluster-service=true
+}
+
+# returns the characters after the last separator (including)
+# If the separator is empty or if it doesn't appear in the string,
+# an empty string is printed
+# $1 input string
+# $2 separator (must be single character, or empty)
+function get-suffix() {
+ # prints to stdout, so log cannot be used
+ local -r input_string=$1
+ local -r separator=$2
+ local suffix
+
+ if [[ "${separator}" == "" ]]; then
+ echo ""
+ return
+ fi
+
+ if [[ "${input_string}" == *"${separator}"* ]]; then
+ suffix=$(echo "${input_string}" | rev | cut -d "${separator}" -f1 | rev)
+ echo "${separator}${suffix}"
+ else
+ echo ""
+ fi
+}
+
+# returns the characters up to the last '-' (without it)
+# $1 input string
+# $2 separator
+function get-basename() {
+ # prints to stdout, so log cannot be used
+ local -r input_string=$1
+ local -r separator=$2
+ local suffix
+ suffix="$(get-suffix ${input_string} ${separator})"
+ # this will strip the suffix (if matches)
+ echo ${input_string%$suffix}
+}
+
+function stop-object() {
+ local -r obj_type=$1
+ local -r namespace=$2
+ local -r obj_name=$3
+ log INFO "Stopping ${obj_type} ${namespace}/${obj_name}"
+
+ run-until-success "${KUBECTL} stop --namespace=${namespace} ${obj_type} ${obj_name}" ${NUM_TRIES} ${DELAY_AFTER_ERROR_SEC}
+}
+
+function create-object() {
+ local -r obj_type=$1
+ local -r file_path=$2
+
+ local nsname_from_file
+ nsname_from_file=$(get-object-nsname-from-file ${file_path})
+ if [[ "${nsname_from_file}" == "ERROR" ]]; then
+ log INFO "Cannot read object name from ${file_path}. Ignoring"
+ return 1
+ fi
+ IFS='/' read namespace obj_name <<< "${nsname_from_file}"
+
+ log INFO "Creating new ${obj_type} from file ${file_path} in namespace ${namespace}, name: ${obj_name}"
+ # this will keep on failing if the ${file_path} disappeared in the meantime.
+ # Do not use too many retries.
+ run-until-success "${KUBECTL} create --namespace=${namespace} -f ${file_path}" ${NUM_TRIES} ${DELAY_AFTER_ERROR_SEC}
+}
+
+function update-object() {
+ local -r obj_type=$1
+ local -r namespace=$2
+ local -r obj_name=$3
+ local -r file_path=$4
+ log INFO "updating the ${obj_type} ${namespace}/${obj_name} with the new definition ${file_path}"
+ stop-object ${obj_type} ${namespace} ${obj_name}
+ create-object ${obj_type} ${file_path}
+}
+
+# deletes the objects from the server
+# $1 object type
+# $2 a list of object nsnames
+function stop-objects() {
+ local -r obj_type=$1
+ local -r obj_nsnames=$2
+ local namespace
+ local obj_name
+ for nsname in ${obj_nsnames}; do
+ IFS='/' read namespace obj_name <<< "${nsname}"
+ stop-object ${obj_type} ${namespace} ${obj_name} &
+ done
+}
+
+# creates objects from the given files
+# $1 object type
+# $2 a list of paths to definition files
+function create-objects() {
+ local -r obj_type=$1
+ local -r file_paths=$2
+ local file_path
+ for file_path in ${file_paths}; do
+ # Remember that the file may have disappear by now
+ # But we don't want to check it here because
+ # such race condition may always happen after
+ # we check it. Let's have the race
+ # condition happen a bit more often so that
+ # we see that our tests pass anyway.
+ create-object ${obj_type} ${file_path} &
+ done
+}
+
+# updates objects
+# $1 object type
+# $2 a list of update specifications
+# each update specification is a ';' separated pair: <nsname>;<file path>
+function update-objects() {
+ local -r obj_type=$1 # ignored
+ local -r update_spec=$2
+ local objdesc
+ local nsname
+ local obj_name
+ local namespace
+
+ for objdesc in ${update_spec}; do
+ IFS=';' read nsname file_path <<< "${objdesc}"
+ IFS='/' read namespace obj_name <<< "${nsname}"
+
+ update-object ${obj_type} ${namespace} ${obj_name} ${file_path} &
+ done
+}
+
+# Global variables set by function match-objects.
+nsnames_for_delete="" # a list of object nsnames to be deleted
+for_update="" # a list of pairs <nsname>;<filePath> for objects that should be updated
+nsnames_for_ignore="" # a list of object nsnames that will be ignored
+new_files="" # a list of file paths that weren't matched by any existing objects (these objects must be created now)
+
+
+# $1 path to files with objects
+# $2 object type in the API (ReplicationController or Service)
+# $3 name separator (single character or empty)
+function match-objects() {
+ local -r addon_dir=$1
+ local -r obj_type=$2
+ local -r separator=$3
+
+ # output variables (globals)
+ nsnames_for_delete=""
+ for_update=""
+ nsnames_for_ignore=""
+ new_files=""
+
+ addon_nsnames_on_server=$(get-addon-nsnames-from-server "${obj_type}")
+ addon_paths_in_files=$(get-addon-paths-from-disk "${addon_dir}" "${obj_type}")
+
+ log DB2 "addon_nsnames_on_server=${addon_nsnames_on_server}"
+ log DB2 "addon_paths_in_files=${addon_paths_in_files}"
+
+ local matched_files=""
+
+ local basensname_on_server=""
+ local nsname_on_server=""
+ local suffix_on_server=""
+ local nsname_from_file=""
+ local suffix_from_file=""
+ local found=0
+ local addon_path=""
+
+ # objects that were moved between namespaces will have different nsname
+ # because the namespace is included. So they will be treated
+ # like different objects and not updated but deleted and created again
+ # (in the current version update is also delete+create, so it does not matter)
+ for nsname_on_server in ${addon_nsnames_on_server}; do
+ basensname_on_server=$(get-basename ${nsname_on_server} ${separator})
+ suffix_on_server="$(get-suffix ${nsname_on_server} ${separator})"
+
+ log DB3 "Found existing addon ${nsname_on_server}, basename=${basensname_on_server}"
+
+ # check if the addon is present in the directory and decide
+ # what to do with it
+ # this is not optimal because we're reading the files over and over
+ # again. But for small number of addons it doesn't matter so much.
+ found=0
+ for addon_path in ${addon_paths_in_files}; do
+ nsname_from_file=$(get-object-nsname-from-file ${addon_path})
+ if [[ "${nsname_from_file}" == "ERROR" ]]; then
+ log INFO "Cannot read object name from ${addon_path}. Ignoring"
+ continue
+ else
+ log DB2 "Found object name '${nsname_from_file}' in file ${addon_path}"
+ fi
+ suffix_from_file="$(get-suffix ${nsname_from_file} ${separator})"
+
+ log DB3 "matching: ${basensname_on_server}${suffix_from_file} == ${nsname_from_file}"
+ if [[ "${basensname_on_server}${suffix_from_file}" == "${nsname_from_file}" ]]; then
+ log DB3 "matched existing ${obj_type} ${nsname_on_server} to file ${addon_path}; suffix_on_server=${suffix_on_server}, suffix_from_file=${suffix_from_file}"
+ found=1
+ matched_files="${matched_files} ${addon_path}"
+ if [[ "${suffix_on_server}" == "${suffix_from_file}" ]]; then
+ nsnames_for_ignore="${nsnames_for_ignore} ${nsname_from_file}"
+ else
+ for_update="${for_update} ${nsname_on_server};${addon_path}"
+ fi
+ break
+ fi
+ done
+ if [[ ${found} -eq 0 ]]; then
+ log DB2 "No definition file found for replication controller ${nsname_on_server}. Scheduling for deletion"
+ nsnames_for_delete="${nsnames_for_delete} ${nsname_on_server}"
+ fi
+ done
+
+ log DB3 "matched_files=${matched_files}"
+
+
+ # note that if the addon file is invalid (or got removed after listing files
+ # but before we managed to match it) it will not be matched to any
+ # of the existing objects. So we will treat it as a new file
+ # and try to create its object.
+ for addon_path in ${addon_paths_in_files}; do
+ echo ${matched_files} | grep "${addon_path}" >/dev/null
+ if [[ $? -ne 0 ]]; then
+ new_files="${new_files} ${addon_path}"
+ fi
+ done
+}
+
+
+
+function reconcile-objects() {
+ local -r addon_path=$1
+ local -r obj_type=$2
+ local -r separator=$3 # name separator
+ match-objects ${addon_path} ${obj_type} ${separator}
+
+ log DBG "${obj_type}: nsnames_for_delete=${nsnames_for_delete}"
+ log DBG "${obj_type}: for_update=${for_update}"
+ log DBG "${obj_type}: nsnames_for_ignore=${nsnames_for_ignore}"
+ log DBG "${obj_type}: new_files=${new_files}"
+
+ stop-objects "${obj_type}" "${nsnames_for_delete}"
+ # wait for jobs below is a protection against changing the basename
+ # of a replication controllerm without changing the selector.
+ # If we don't wait, the new rc may be created before the old one is deleted
+ # In such case the old one will wait for all its pods to be gone, but the pods
+ # are created by the new replication controller.
+ # passing --cascade=false could solve the problem, but we want
+ # all orphan pods to be deleted.
+ wait-for-jobs
+ stopResult=$?
+
+ create-objects "${obj_type}" "${new_files}"
+ update-objects "${obj_type}" "${for_update}"
+
+ local nsname
+ for nsname in ${nsnames_for_ignore}; do
+ log DB2 "The ${obj_type} ${nsname} is already up to date"
+ done
+
+ wait-for-jobs
+ createUpdateResult=$?
+
+ if [[ ${stopResult} -eq 0 ]] && [[ ${createUpdateResult} -eq 0 ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+function update-addons() {
+ local -r addon_path=$1
+ # be careful, reconcile-objects uses global variables
+ reconcile-objects ${addon_path} ReplicationController "-" &
+
+ # We don't expect names to be versioned for the following kinds, so
+ # we match the entire name, ignoring version suffix.
+ # That's why we pass an empty string as the version separator.
+ # If the description differs on disk, the object should be recreated.
+ # This is not implemented in this version.
+ reconcile-objects ${addon_path} Service "" &
+ reconcile-objects ${addon_path} PersistentVolume "" &
+ reconcile-objects ${addon_path} PersistentVolumeClaim "" &
+
+ wait-for-jobs
+ if [[ $? -eq 0 ]]; then
+ log INFO "== Kubernetes addon update completed successfully at $(date -Is) =="
+ else
+ log WRN "== Kubernetes addon update completed with errors at $(date -Is) =="
+ fi
+}
+
+# input parameters:
+# $1 input directory
+# $2 retry period in seconds - the script will retry api-server errors for approximately
+# this amound of time (it is not very precise), at interval equal $DELAY_AFTER_ERROR_SEC.
+#
+
+if [[ $# -ne 2 ]]; then
+ echo "Illegal number of parameters. Usage $0 addon-dir [retry-period]" 1>&2
+ exit 1
+fi
+
+NUM_TRIES=$(($2 / ${DELAY_AFTER_ERROR_SEC}))
+if [[ ${NUM_TRIES} -le 0 ]]; then
+ NUM_TRIES=1
+fi
+
+addon_path=$1
+update-addons ${addon_path}
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/kube-addons.service b/kubernetes/files/kube-addons/kube-addons.service
new file mode 100644
index 0000000..920f356
--- /dev/null
+++ b/kubernetes/files/kube-addons/kube-addons.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=Kubernetes Addon Object Manager
+Documentation=https://github.com/GoogleCloudPlatform/kubernetes
+
+[Service]
+ExecStart=/etc/kubernetes/kube-addons.sh
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/kube-addons.sh b/kubernetes/files/kube-addons/kube-addons.sh
new file mode 100644
index 0000000..c1deea1
--- /dev/null
+++ b/kubernetes/files/kube-addons/kube-addons.sh
@@ -0,0 +1,226 @@
+#!/bin/bash
+
+# Copyright 2014 The Kubernetes Authors All rights reserved.
+#
+# 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.
+
+# The business logic for whether a given object should be created
+# was already enforced by salt, and /etc/kubernetes/addons is the
+# managed result is of that. Start everything below that directory.
+KUBECTL=${KUBECTL_BIN:-/usr/local/bin/kubectl}
+
+ADDON_CHECK_INTERVAL_SEC=${TEST_ADDON_CHECK_INTERVAL_SEC:-600}
+
+SYSTEM_NAMESPACE=kube-system
+token_dir=${TOKEN_DIR:-/srv/kubernetes}
+
+function create-kubeconfig-secret() {
+ local -r token=$1
+ local -r username=$2
+ local -r server=$3
+ local -r safe_username=$(tr -s ':_' '--' <<< "${username}")
+
+ # Make a kubeconfig file with the token.
+ if [[ ! -z "${CA_CERT:-}" ]]; then
+ # If the CA cert is available, put it into the secret rather than using
+ # insecure-skip-tls-verify.
+ read -r -d '' kubeconfig <<EOF
+apiVersion: v1
+kind: Config
+users:
+- name: ${username}
+ user:
+ token: ${token}
+clusters:
+- name: local
+ cluster:
+ server: ${server}
+ certificate-authority-data: ${CA_CERT}
+contexts:
+- context:
+ cluster: local
+ user: ${username}
+ namespace: ${SYSTEM_NAMESPACE}
+ name: service-account-context
+current-context: service-account-context
+EOF
+ else
+ read -r -d '' kubeconfig <<EOF
+apiVersion: v1
+kind: Config
+users:
+- name: ${username}
+ user:
+ token: ${token}
+clusters:
+- name: local
+ cluster:
+ server: ${server}
+ insecure-skip-tls-verify: true
+contexts:
+- context:
+ cluster: local
+ user: ${username}
+ namespace: ${SYSTEM_NAMESPACE}
+ name: service-account-context
+current-context: service-account-context
+EOF
+ fi
+
+ local -r kubeconfig_base64=$(echo "${kubeconfig}" | base64 -w0)
+ read -r -d '' secretyaml <<EOF
+apiVersion: v1
+data:
+ kubeconfig: ${kubeconfig_base64}
+kind: Secret
+metadata:
+ name: token-${safe_username}
+type: Opaque
+EOF
+ create-resource-from-string "${secretyaml}" 100 10 "Secret-for-token-for-user-${username}" "${SYSTEM_NAMESPACE}" &
+}
+
+# $1 filename of addon to start.
+# $2 count of tries to start the addon.
+# $3 delay in seconds between two consecutive tries
+# $4 namespace
+function start_addon() {
+ local -r addon_filename=$1;
+ local -r tries=$2;
+ local -r delay=$3;
+ local -r namespace=$4
+
+ create-resource-from-string "$(cat ${addon_filename})" "${tries}" "${delay}" "${addon_filename}" "${namespace}"
+}
+
+# $1 string with json or yaml.
+# $2 count of tries to start the addon.
+# $3 delay in seconds between two consecutive tries
+# $4 name of this object to use when logging about it.
+# $5 namespace for this object
+function create-resource-from-string() {
+ local -r config_string=$1;
+ local tries=$2;
+ local -r delay=$3;
+ local -r config_name=$4;
+ local -r namespace=$5;
+ while [ ${tries} -gt 0 ]; do
+ echo "${config_string}" | ${KUBECTL} --namespace="${namespace}" create -f - && \
+ echo "== Successfully started ${config_name} in namespace ${namespace} at $(date -Is)" && \
+ return 0;
+ let tries=tries-1;
+ echo "== Failed to start ${config_name} in namespace ${namespace} at $(date -Is). ${tries} tries remaining. =="
+ sleep ${delay};
+ done
+ return 1;
+}
+
+# $1 is the directory containing all of the docker images
+function load-docker-images() {
+ local success
+ local restart_docker
+ while true; do
+ success=true
+ restart_docker=false
+ for image in "$1/"*; do
+ timeout 30 docker load -i "${image}" &>/dev/null
+ rc=$?
+ if [[ "$rc" == 124 ]]; then
+ restart_docker=true
+ elif [[ "$rc" != 0 ]]; then
+ success=false
+ fi
+ done
+ if [[ "$success" == "true" ]]; then break; fi
+ if [[ "$restart_docker" == "true" ]]; then service docker restart; fi
+ sleep 15
+ done
+}
+
+# The business logic for whether a given object should be created
+# was already enforced by salt, and /etc/kubernetes/addons is the
+# managed result is of that. Start everything below that directory.
+echo "== Kubernetes addon manager started at $(date -Is) with ADDON_CHECK_INTERVAL_SEC=${ADDON_CHECK_INTERVAL_SEC} =="
+
+# Load the kube-env, which has all the environment variables we care
+# about, in a flat yaml format.
+kube_env_yaml="/var/cache/kubernetes-install/kube_env.yaml"
+if [ ! -e "${kubelet_kubeconfig_file}" ]; then
+ eval $(python -c '''
+import pipes,sys,yaml
+
+for k,v in yaml.load(sys.stdin).iteritems():
+ print "readonly {var}={value}".format(var = k, value = pipes.quote(str(v)))
+''' < "${kube_env_yaml}")
+fi
+
+# Load any images that we may need
+load-docker-images /srv/salt/kube-addons-images
+
+# Create the namespace that will be used to host the cluster-level add-ons.
+start_addon /etc/kubernetes/addons/namespace.yaml 100 10 "" &
+
+# Wait for the default service account to be created in the kube-system namespace.
+token_found=""
+while [ -z "${token_found}" ]; do
+ sleep .5
+ token_found=$(${KUBECTL} get --namespace="${SYSTEM_NAMESPACE}" serviceaccount default -o go-template="{{with index .secrets 0}}{{.name}}{{end}}" || true)
+done
+
+echo "== default service account in the ${SYSTEM_NAMESPACE} namespace has token ${token_found} =="
+
+# Generate secrets for "internal service accounts".
+# TODO(etune): move to a completely yaml/object based
+# workflow so that service accounts can be created
+# at the same time as the services that use them.
+# NOTE: needs to run as root to read this file.
+# Read each line in the csv file of tokens.
+# Expect errors when the script is started again.
+# NOTE: secrets are created asynchronously, in background.
+while read line; do
+ # Split each line into the token and username.
+ IFS=',' read -a parts <<< "${line}"
+ token=${parts[0]}
+ username=${parts[1]}
+ # DNS is special, since it's necessary for cluster bootstrapping.
+ if [[ "${username}" == "system:dns" ]] && [[ ! -z "${KUBERNETES_MASTER_NAME:-}" ]]; then
+ create-kubeconfig-secret "${token}" "${username}" "https://${KUBERNETES_MASTER_NAME}"
+ else
+ # Set the server to https://kubernetes. Pods/components that
+ # do not have DNS available will have to override the server.
+ create-kubeconfig-secret "${token}" "${username}" "https://kubernetes.default"
+ fi
+done < "${token_dir}/known_tokens.csv"
+
+# Create admission_control objects if defined before any other addon services. If the limits
+# are defined in a namespace other than default, we should still create the limits for the
+# default namespace.
+for obj in $(find /etc/kubernetes/admission-controls \( -name \*.yaml -o -name \*.json \)); do
+ start_addon "${obj}" 100 10 default &
+ echo "++ obj ${obj} is created ++"
+done
+
+# Check if the configuration has changed recently - in case the user
+# created/updated/deleted the files on the master.
+while true; do
+ start_sec=$(date +"%s")
+ #kube-addon-update.sh must be deployed in the same directory as this file
+ `dirname $0`/kube-addon-update.sh /etc/kubernetes/addons ${ADDON_CHECK_INTERVAL_SEC}
+ end_sec=$(date +"%s")
+ len_sec=$((${end_sec}-${start_sec}))
+ # subtract the time passed from the sleep time
+ if [[ ${len_sec} -lt ${ADDON_CHECK_INTERVAL_SEC} ]]; then
+ sleep_time=$((${ADDON_CHECK_INTERVAL_SEC}-${len_sec}))
+ sleep ${sleep_time}
+ fi
+done
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/kube-ui/kube-ui-address.yaml b/kubernetes/files/kube-addons/kube-ui/kube-ui-address.yaml
new file mode 100644
index 0000000..f9f3749
--- /dev/null
+++ b/kubernetes/files/kube-addons/kube-ui/kube-ui-address.yaml
@@ -0,0 +1,18 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: Service
+metadata:
+ name: kube-ui-address
+ namespace: kube-system
+ labels:
+ k8s-app: kube-ui
+ kubernetes.io/cluster-service: "true"
+ kubernetes.io/name: "KubeUI"
+spec:
+ selector:
+ k8s-app: kube-ui
+ deprecatedPublicIPs: ["{{ master.addons.ui.public_ip }}"]
+ type: LoadBalancer
+ ports:
+ - port: 80
+ targetPort: 8080
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/kube-ui/kube-ui-endpoint.yaml b/kubernetes/files/kube-addons/kube-ui/kube-ui-endpoint.yaml
new file mode 100644
index 0000000..9b22ebc
--- /dev/null
+++ b/kubernetes/files/kube-addons/kube-ui/kube-ui-endpoint.yaml
@@ -0,0 +1,17 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: Endpoints
+metadata:
+ name: kube-ui
+ namespace: kube-system
+ labels:
+ k8s-app: kube-ui
+ kubernetes.io/cluster-service: "true"
+ kubernetes.io/name: "KubeUI"
+subsets:
+ - addresses:
+ - ip: {{ master.addons.ui.public_ip }}
+
+ ports:
+ - port: 8080
+ protocol: TCP
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/kube-ui/kube-ui-rc.yaml b/kubernetes/files/kube-addons/kube-ui/kube-ui-rc.yaml
new file mode 100644
index 0000000..9c43389
--- /dev/null
+++ b/kubernetes/files/kube-addons/kube-ui/kube-ui-rc.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+kind: ReplicationController
+metadata:
+ name: kube-ui-v4
+ namespace: kube-system
+ labels:
+ k8s-app: kube-ui
+ version: v4
+ kubernetes.io/cluster-service: "true"
+spec:
+ replicas: 1
+ selector:
+ k8s-app: kube-ui
+ version: v4
+ template:
+ metadata:
+ labels:
+ k8s-app: kube-ui
+ version: v4
+ kubernetes.io/cluster-service: "true"
+ spec:
+ containers:
+ - name: kube-ui
+ image: gcr.io/google_containers/kube-ui:v4
+ resources:
+ limits:
+ cpu: 100m
+ memory: 50Mi
+ ports:
+ - containerPort: 8080
+ livenessProbe:
+ httpGet:
+ path: /
+ port: 8080
+ initialDelaySeconds: 30
+ timeoutSeconds: 5
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/kube-ui/kube-ui-svc.yaml b/kubernetes/files/kube-addons/kube-ui/kube-ui-svc.yaml
new file mode 100644
index 0000000..876be68
--- /dev/null
+++ b/kubernetes/files/kube-addons/kube-ui/kube-ui-svc.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: kube-ui
+ namespace: kube-system
+ labels:
+ k8s-app: kube-ui
+ kubernetes.io/cluster-service: "true"
+ kubernetes.io/name: "KubeUI"
+spec:
+ ports:
+ - port: 80
+ targetPort: 8080
\ No newline at end of file
diff --git a/kubernetes/files/kube-addons/namespace.yml b/kubernetes/files/kube-addons/namespace.yml
new file mode 100644
index 0000000..4f03434
--- /dev/null
+++ b/kubernetes/files/kube-addons/namespace.yml
@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: kube-system
\ No newline at end of file
diff --git a/kubernetes/files/kube-gen-token.sh b/kubernetes/files/kube-gen-token.sh
new file mode 100644
index 0000000..fa6a5dd
--- /dev/null
+++ b/kubernetes/files/kube-gen-token.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+# Copyright 2015 The Kubernetes Authors All rights reserved.
+#
+# 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.
+
+token_dir=${TOKEN_DIR:-/var/srv/kubernetes}
+token_file="${token_dir}/known_tokens.csv"
+
+create_accounts=($@)
+
+touch "${token_file}"
+for account in "${create_accounts[@]}"; do
+ if grep ",${account}," "${token_file}" ; then
+ continue
+ fi
+ token=$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64 | tr -d "=+/" | dd bs=32 count=1 2>/dev/null)
+ echo "${token},${account},${account}" >> "${token_file}"
+ echo "${token}" > "${token_dir}/${account}.token"
+ echo "Added ${account}"
+done
diff --git a/kubernetes/files/kube-proxy/default b/kubernetes/files/kube-proxy/default
new file mode 100644
index 0000000..b7dddc1
--- /dev/null
+++ b/kubernetes/files/kube-proxy/default
@@ -0,0 +1,5 @@
+{%- from "kubernetes/map.jinja" import pool with context %}
+
+# test_args has to be kept at the end, so they'll overwrite any prior configuration
+DAEMON_ARGS="--logtostderr=true --v=2 --kubeconfig=/var/lib/kube-proxy/kubeconfig --master=https://{{ pool.master.host }}{% if pool.network.engine == 'calico' %} --proxy-mode=iptables{% endif %}"
+#--kubeconfig=/etc/kubernetes/proxy.kubeconfig"
\ No newline at end of file
diff --git a/kubernetes/files/kube-proxy/initd b/kubernetes/files/kube-proxy/initd
new file mode 100644
index 0000000..b530b32
--- /dev/null
+++ b/kubernetes/files/kube-proxy/initd
@@ -0,0 +1,130 @@
+#!/bin/bash
+#
+### BEGIN INIT INFO
+# Provides: kube-proxy
+# Required-Start: $local_fs $network $syslog
+# Required-Stop:
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: The Kubernetes network proxy
+# Description:
+# The Kubernetes network proxy enables network redirection and
+# loadbalancing for dynamically placed containers.
+### END INIT INFO
+
+
+# PATH should only include /usr/* if it runs after the mountnfs.sh script
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
+DESC="The Kubernetes network proxy"
+NAME=kube-proxy
+DAEMON=/usr/local/bin/kube-proxy
+DAEMON_ARGS=""
+DAEMON_LOG_FILE=/var/log/$NAME.log
+PIDFILE=/var/run/$NAME.pid
+SCRIPTNAME=/etc/init.d/$NAME
+DAEMON_USER=root
+
+# Exit if the package is not installed
+[ -x "$DAEMON" ] || exit 0
+
+# Read configuration variable file if it is present
+[ -r /etc/default/$NAME ] && . /etc/default/$NAME
+
+# Define LSB log_* functions.
+# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
+# and status_of_proc is working.
+. /lib/lsb/init-functions
+
+#
+# Function that starts the daemon/service
+#
+do_start()
+{
+ # Avoid a potential race at boot time when both monit and init.d start
+ # the same service
+ PIDS=$(pidof $DAEMON)
+ for PID in ${PIDS}; do
+ kill -9 $PID
+ done
+
+ # Raise the file descriptor limit - we expect to open a lot of sockets!
+ ulimit -n 65536
+
+ # Return
+ # 0 if daemon has been started
+ # 1 if daemon was already running
+ # 2 if daemon could not be started
+ start-stop-daemon --start --quiet --background --no-close \
+ --make-pidfile --pidfile $PIDFILE \
+ --exec $DAEMON -c $DAEMON_USER --test > /dev/null \
+ || return 1
+ start-stop-daemon --start --quiet --background --no-close \
+ --make-pidfile --pidfile $PIDFILE \
+ --exec $DAEMON -c $DAEMON_USER -- \
+ $DAEMON_ARGS >> $DAEMON_LOG_FILE 2>&1 \
+ || return 2
+}
+
+#
+# Function that stops the daemon/service
+#
+do_stop()
+{
+ # Return
+ # 0 if daemon has been stopped
+ # 1 if daemon was already stopped
+ # 2 if daemon could not be stopped
+ # other if a failure occurred
+ start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
+ RETVAL="$?"
+ [ "$RETVAL" = 2 ] && return 2
+ # Many daemons don't delete their pidfiles when they exit.
+ rm -f $PIDFILE
+ return "$RETVAL"
+}
+
+
+case "$1" in
+ start)
+ log_daemon_msg "Starting $DESC" "$NAME"
+ do_start
+ case "$?" in
+ 0|1) log_end_msg 0 || exit 0 ;;
+ 2) log_end_msg 1 || exit 1 ;;
+ esac
+ ;;
+ stop)
+ log_daemon_msg "Stopping $DESC" "$NAME"
+ do_stop
+ case "$?" in
+ 0|1) log_end_msg 0 ;;
+ 2) exit 1 ;;
+ esac
+ ;;
+ status)
+ status_of_proc -p $PIDFILE "$DAEMON" "$NAME" && exit 0 || exit $?
+ ;;
+
+ restart|force-reload)
+ log_daemon_msg "Restarting $DESC" "$NAME"
+ do_stop
+ case "$?" in
+ 0|1)
+ do_start
+ case "$?" in
+ 0) log_end_msg 0 ;;
+ 1) log_end_msg 1 ;; # Old process is still running
+ *) log_end_msg 1 ;; # Failed to start
+ esac
+ ;;
+ *)
+ # Failed to stop
+ log_end_msg 1
+ ;;
+ esac
+ ;;
+ *)
+ echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
+ exit 3
+ ;;
+esac
\ No newline at end of file
diff --git a/kubernetes/files/kube-proxy/kube-proxy.service b/kubernetes/files/kube-proxy/kube-proxy.service
new file mode 100644
index 0000000..ebd5729
--- /dev/null
+++ b/kubernetes/files/kube-proxy/kube-proxy.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Kubernetes Kube-Proxy Server
+Documentation=https://github.com/GoogleCloudPlatform/kubernetes
+
+[Service]
+EnvironmentFile=/etc/sysconfig/kube-proxy
+ExecStart=/usr/local/bin/kube-proxy "$DAEMON_ARGS"
+Restart=on-failure
+LimitNOFILE=65536
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/kubernetes/files/kube-proxy/proxy.kubeconfig b/kubernetes/files/kube-proxy/proxy.kubeconfig
new file mode 100644
index 0000000..ef37d71
--- /dev/null
+++ b/kubernetes/files/kube-proxy/proxy.kubeconfig
@@ -0,0 +1,20 @@
+{%- from "kubernetes/map.jinja" import pool with context %}
+
+apiVersion: v1
+kind: Config
+current-context: proxy-to-cluster.local
+preferences: {}
+contexts:
+- context:
+ cluster: cluster.local
+ user: kube_proxy
+ name: proxy-to-cluster.local
+clusters:
+- cluster:
+ certificate-authority: /etc/ssl/certs/ca-{{ pool.ca }}.crt
+# server: https://{{ pool.master.host }}:443
+ name: cluster.local
+users:
+- name: kube_proxy
+ user:
+ token: {{ pool.token.kube_proxy}}
\ No newline at end of file
diff --git a/kubernetes/files/kubelet/default.master b/kubernetes/files/kubelet/default.master
new file mode 100644
index 0000000..b53c35c
--- /dev/null
+++ b/kubernetes/files/kubelet/default.master
@@ -0,0 +1,4 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+
+# test_args has to be kept at the end, so they'll overwrite any prior configuration
+DAEMON_ARGS="--config=/etc/kubernetes/manifests --allow-privileged={{ master.kubelet.allow_privileged }} --cluster_dns={{ master.addons.dns.server }} --register-node=false --cluster_domain={{ master.addons.dns.domain }} --v=2"
\ No newline at end of file
diff --git a/kubernetes/files/kubelet/default.pool b/kubernetes/files/kubelet/default.pool
new file mode 100644
index 0000000..44020fd
--- /dev/null
+++ b/kubernetes/files/kubelet/default.pool
@@ -0,0 +1,4 @@
+{%- from "kubernetes/map.jinja" import pool with context %}
+
+# test_args has to be kept at the end, so they'll overwrite any prior configuration
+DAEMON_ARGS="--api-servers={% for member in pool.master.apiserver.members %}https://{{ member.host }}{% if not loop.last %},{% endif %}{% endfor %} --kubeconfig=/etc/kubernetes/kubelet.kubeconfig --config=/etc/kubernetes/manifests --allow-privileged={{ pool.kubelet.allow_privileged }} --cluster_dns={{ pool.cluster_dns }} --cluster_domain={{ pool.cluster_domain }} --v=2 {% if pool.network.engine == 'opencontrail' %}--network-plugin={{ pool.network.engine }}{% endif %} {% if pool.network.engine == 'calico' %}--network-plugin=cni --network-plugin-dir=/etc/cni/net.d{% endif %} --file-check-frequency={{ pool.kubelet.frequency }}"
\ No newline at end of file
diff --git a/kubernetes/files/kubelet/initd b/kubernetes/files/kubelet/initd
new file mode 100644
index 0000000..74f69a2
--- /dev/null
+++ b/kubernetes/files/kubelet/initd
@@ -0,0 +1,126 @@
+#!/bin/bash
+#
+### BEGIN INIT INFO
+# Provides: kubelet
+# Required-Start: $local_fs $network $syslog
+# Required-Stop:
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: The Kubernetes node container manager
+# Description:
+# The Kubernetes container manager maintains docker state against a state file.
+### END INIT INFO
+
+
+# PATH should only include /usr/* if it runs after the mountnfs.sh script
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
+DESC="The Kubernetes container manager"
+NAME=kubelet
+DAEMON=/usr/local/bin/kubelet
+DAEMON_ARGS=""
+DAEMON_LOG_FILE=/var/log/$NAME.log
+PIDFILE=/var/run/$NAME.pid
+SCRIPTNAME=/etc/init.d/$NAME
+DAEMON_USER=root
+
+# Exit if the package is not installed
+[ -x "$DAEMON" ] || exit 0
+
+# Read configuration variable file if it is present
+[ -r /etc/default/$NAME ] && . /etc/default/$NAME
+
+# Define LSB log_* functions.
+# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
+# and status_of_proc is working.
+. /lib/lsb/init-functions
+
+#
+# Function that starts the daemon/service
+#
+do_start()
+{
+ # Avoid a potential race at boot time when both monit and init.d start
+ # the same service
+ PIDS=$(pidof $DAEMON)
+ for PID in ${PIDS}; do
+ kill -9 $PID
+ done
+
+ # Return
+ # 0 if daemon has been started
+ # 1 if daemon was already running
+ # 2 if daemon could not be started
+ start-stop-daemon --start --quiet --background --no-close \
+ --make-pidfile --pidfile $PIDFILE \
+ --exec $DAEMON -c $DAEMON_USER --test > /dev/null \
+ || return 1
+ start-stop-daemon --start --quiet --background --no-close \
+ --make-pidfile --pidfile $PIDFILE \
+ --exec $DAEMON -c $DAEMON_USER -- \
+ $DAEMON_ARGS >> $DAEMON_LOG_FILE 2>&1 \
+ || return 2
+}
+
+#
+# Function that stops the daemon/service
+#
+do_stop()
+{
+ # Return
+ # 0 if daemon has been stopped
+ # 1 if daemon was already stopped
+ # 2 if daemon could not be stopped
+ # other if a failure occurred
+ start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
+ RETVAL="$?"
+ [ "$RETVAL" = 2 ] && return 2
+ # Many daemons don't delete their pidfiles when they exit.
+ rm -f $PIDFILE
+ return "$RETVAL"
+}
+
+
+case "$1" in
+ start)
+ log_daemon_msg "Starting $DESC" "$NAME"
+ do_start
+ case "$?" in
+ 0|1) log_end_msg 0 || exit 0 ;;
+ 2) log_end_msg 1 || exit 1 ;;
+ esac
+ ;;
+ stop)
+ log_daemon_msg "Stopping $DESC" "$NAME"
+ do_stop
+ case "$?" in
+ 0|1) log_end_msg 0 ;;
+ 2) exit 1 ;;
+ esac
+ ;;
+ status)
+ status_of_proc -p $PIDFILE "$DAEMON" "$NAME" && exit 0 || exit $?
+ ;;
+
+ restart|force-reload)
+ log_daemon_msg "Restarting $DESC" "$NAME"
+ do_stop
+ case "$?" in
+ 0|1)
+ do_start
+ case "$?" in
+ 0) log_end_msg 0 ;;
+ 1) log_end_msg 1 ;; # Old process is still running
+ *) log_end_msg 1 ;; # Failed to start
+ esac
+ ;;
+ *)
+ # Failed to stop
+ log_end_msg 1
+ ;;
+ esac
+ ;;
+ *)
+ echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
+ exit 3
+ ;;
+esac
\ No newline at end of file
diff --git a/kubernetes/files/kubelet/kubelet.kubeconfig b/kubernetes/files/kubelet/kubelet.kubeconfig
new file mode 100644
index 0000000..15a64dd
--- /dev/null
+++ b/kubernetes/files/kubelet/kubelet.kubeconfig
@@ -0,0 +1,20 @@
+{%- from "kubernetes/map.jinja" import pool with context %}
+
+apiVersion: v1
+kind: Config
+current-context: kubelet-to-cluster.local
+preferences: {}
+clusters:
+- cluster:
+ certificate-authority: /etc/ssl/certs/ca-{{ pool.ca }}.crt
+# server: https://{{ pool.master.host }}:443
+ name: cluster.local
+contexts:
+- context:
+ cluster: cluster.local
+ user: kubelet
+ name: kubelet-to-cluster.local
+users:
+- name: kubelet
+ user:
+ token: {{ pool.token.kubelet }}
\ No newline at end of file
diff --git a/kubernetes/files/kubelet/kubelet.service b/kubernetes/files/kubelet/kubelet.service
new file mode 100644
index 0000000..0c5b653
--- /dev/null
+++ b/kubernetes/files/kubelet/kubelet.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Kubernetes Kubelet Server
+Documentation=https://github.com/GoogleCloudPlatform/kubernetes
+
+[Service]
+EnvironmentFile=/etc/sysconfig/kubelet
+ExecStart=/usr/local/bin/kubelet "$DAEMON_ARGS"
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/kubernetes/files/manifest/cadvisor.manifest b/kubernetes/files/manifest/cadvisor.manifest
new file mode 100644
index 0000000..5c90e91
--- /dev/null
+++ b/kubernetes/files/manifest/cadvisor.manifest
@@ -0,0 +1,39 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: cadvisor
+ namespace: kube-system
+spec:
+ containers:
+ - name: cadvisor
+ image: google/cadvisor:latest
+ ports:
+ - name: http
+ containerPort: 8080
+ hostPort: 8080
+ volumeMounts:
+ - name: root
+ mountPath: /rootfs
+ readOnly: true
+ - name: varrun
+ mountPath: /var/run
+ readOnly: false
+ - name: varlibdocker
+ mountPath: /var/lib/docker
+ readOnly: true
+ - name: sys
+ mountPath: /sys
+ readOnly: true
+ volumes:
+ - name: root
+ hostPath:
+ path: /
+ - name: varrun
+ hostPath:
+ path: /var/run
+ - name: varlibdocker
+ hostPath:
+ path: /var/lib/docker
+ - name: sys
+ hostPath:
+ path: /sys
\ No newline at end of file
diff --git a/kubernetes/files/manifest/calico-etcd.manifest b/kubernetes/files/manifest/calico-etcd.manifest
new file mode 100644
index 0000000..a5a7b4c
--- /dev/null
+++ b/kubernetes/files/manifest/calico-etcd.manifest
@@ -0,0 +1,31 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: Pod
+metadata:
+ name: calico-etcd
+ namespace: calico-system
+spec:
+ hostNetwork: true
+ containers:
+ - name: calico-etcd-container
+ image: gcr.io/google_containers/etcd:2.2.1
+ command:
+ - "/usr/local/bin/etcd"
+ - "--name=calico-etcd"
+ - "--data-dir=/var/etcd/calico-data"
+ - "--advertise-client-urls=http://{{ master.apiserver.address }}:6666"
+ - "--listen-client-urls=http://0.0.0.0:6666"
+ - "--listen-peer-urls=http://0.0.0.0:6660"
+ securityContext:
+ privileged: true
+ ports:
+ - name: clientport
+ containerPort: 6666
+ hostPort: 6666
+ volumeMounts:
+ - mountPath: /var/etcd
+ name: varetcd
+ volumes:
+ - name: "varetcd"
+ hostPath:
+ path: "/mnt/master-pd/var/etcd"
\ No newline at end of file
diff --git a/kubernetes/files/manifest/contrail-vrouter-agent.manifest b/kubernetes/files/manifest/contrail-vrouter-agent.manifest
new file mode 100644
index 0000000..7ed6826
--- /dev/null
+++ b/kubernetes/files/manifest/contrail-vrouter-agent.manifest
@@ -0,0 +1,47 @@
+{
+"apiVersion": "v1",
+"kind": "Pod",
+"metadata": {
+ "name":"contrail-vrouter-agent",
+ "namespace": "kube-system"
+},
+"spec":{
+"hostNetwork": true,
+"containers":[
+ {
+ "name": "vrouter-agent",
+ "image": "opencontrail/vrouter-agent:2.20",
+ "securityContext": {
+ "Privileged": true
+ },
+ "resources": {
+ "limits": {
+ "cpu": "250m"
+ }
+ },
+ "command": [
+ "/usr/bin/contrail-vrouter-agent"
+ ],
+ "volumeMounts": [
+ {"name": "contrail-configs",
+ "mountPath": "/etc/contrail",
+ "readOnly": false
+ },
+ {"name": "contrail-logs",
+ "mountPath": "/var/log/contrail",
+ "readOnly": false
+ }
+ ]
+ }
+],
+"volumes":[
+ { "name": "contrail-configs",
+ "hostPath": {
+ "path": "/etc/contrail"}
+ },
+ { "name": "contrail-logs",
+ "hostPath": {
+ "path": "/var/log/contrail"}
+ }
+]
+}}
diff --git a/kubernetes/files/manifest/etcd-events.manifest b/kubernetes/files/manifest/etcd-events.manifest
new file mode 100644
index 0000000..84fa3fb
--- /dev/null
+++ b/kubernetes/files/manifest/etcd-events.manifest
@@ -0,0 +1,65 @@
+{
+"apiVersion": "v1",
+"kind": "Pod",
+"metadata": {
+ "name":"etcd-server-events",
+ "namespace": "kube-system"
+},
+"spec":{
+"hostNetwork": true,
+"containers":[
+ {
+ "name": "etcd-container",
+ "image": "gcr.io/google_containers/etcd:2.2.1",
+ "resources": {
+ "requests": {
+ "cpu": "100m"
+ }
+ },
+ "command": [
+ "/bin/sh",
+ "-c",
+ "/usr/local/bin/etcd --listen-peer-urls http://127.0.0.1:2381 --addr 127.0.0.1:4002 --bind-addr 127.0.0.1:4002 --data-dir /var/etcd/data-events 1>>/var/log/etcd-events.log 2>&1"
+ ],
+ "livenessProbe": {
+ "httpGet": {
+ "host": "127.0.0.1",
+ "port": 4002,
+ "path": "/health"
+ },
+ "initialDelaySeconds": 15,
+ "timeoutSeconds": 15
+ },
+ "ports":[
+ { "name": "serverport",
+ "containerPort": 2381,
+ "hostPort": 2381
+ },{
+ "name": "clientport",
+ "containerPort": 4002,
+ "hostPort": 4002
+ }
+ ],
+ "volumeMounts": [
+ {"name": "varetcd",
+ "mountPath": "/var/etcd",
+ "readOnly": false
+ },
+ {"name": "varlogetcd",
+ "mountPath": "/var/log/etcd-events.log",
+ "readOnly": false
+ }
+ ]
+ }
+],
+"volumes":[
+ { "name": "varetcd",
+ "hostPath": {
+ "path": "/mnt/master-pd/var/etcd"}
+ },
+ { "name": "varlogetcd",
+ "hostPath": {
+ "path": "/var/log/etcd-events.log"}
+ }
+]
+}}
diff --git a/kubernetes/files/manifest/etcd.manifest b/kubernetes/files/manifest/etcd.manifest
new file mode 100644
index 0000000..4a5e966
--- /dev/null
+++ b/kubernetes/files/manifest/etcd.manifest
@@ -0,0 +1,65 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{
+"apiVersion": "v1",
+"kind": "Pod",
+"metadata": {
+ "name":"etcd-server",
+ "namespace": "kube-system"
+},
+"spec":{
+"hostNetwork": true,
+"containers":[
+ {
+ "name": "etcd-container",
+ "image": "gcr.io/google_containers/etcd:2.2.1",
+ "resources": {
+ "requests": {
+ "cpu": "200m" }
+ },
+ "command": [
+ "/bin/sh",
+ "-c",
+ "/usr/local/bin/etcd --name {{ master.etcd.name }} --initial-cluster-state new --initial-advertise-peer-urls http://{{ master.etcd.host }}:2380 --listen-peer-urls http://{{ master.etcd.host }}:2380 --advertise-client-urls http://{{ master.etcd.host }}:4001 --listen-client-urls {%- if master.etcd.host == '127.0.0.1' %}{% for member in master.etcd.members %} http://{{ member.host }}:4001{% endfor %}{% else %} http://{{ master.etcd.host }}:4001{% endif %},http://127.0.0.1:4001 --initial-cluster {% for member in master.etcd.members %}{{ member.name }}={%- if master.etcd.host == '127.0.0.1' %}http://127.0.0.1:2380{% else %}http://{{ member.host }}:2380{% if not loop.last %},{% endif %}{% endif %}{% endfor %} --initial-cluster-token {{ master.etcd.token }} --data-dir /var/etcd/data 1>>/var/log/etcd.log 2>&1"
+ ],
+ "livenessProbe": {
+ "httpGet": {
+ "host": "127.0.0.1",
+ "port": 4001,
+ "path": "/health"
+ },
+ "initialDelaySeconds": 15,
+ "timeoutSeconds": 15
+ },
+ "ports":[
+ { "name": "serverport",
+ "containerPort": 2380,
+ "hostPort": 2380
+ },{
+ "name": "clientport",
+ "containerPort": 4001,
+ "hostPort": 4001
+ }
+ ],
+ "volumeMounts": [
+ {"name": "varetcd",
+ "mountPath": "/var/etcd",
+ "readOnly": false
+ },
+ {"name": "varlogetcd",
+ "mountPath": "/var/log/etcd.log",
+ "readOnly": false
+ }
+ ]
+ }
+],
+"volumes":[
+ { "name": "varetcd",
+ "hostPath": {
+ "path": "/mnt/master-pd/var/etcd"}
+ },
+ { "name": "varlogetcd",
+ "hostPath": {
+ "path": "/var/log/etcd.log"}
+ }
+]
+}}
diff --git a/kubernetes/files/manifest/flannel-server.manifest b/kubernetes/files/manifest/flannel-server.manifest
new file mode 100644
index 0000000..e8f6f9d
--- /dev/null
+++ b/kubernetes/files/manifest/flannel-server.manifest
@@ -0,0 +1,78 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{
+ "kind": "Pod",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "flannel-server",
+ "namespace": "kube-system",
+ "labels": {
+ "app": "flannel-server",
+ "version": "v0.1"
+ }
+ },
+ "spec": {
+ "volumes": [
+ {
+ "name": "varlog",
+ "hostPath": {
+ "path": "/var/log"
+ }
+ },
+ {
+ "name": "etcdstorage",
+ "emptyDir": {}
+ },
+ {
+ "name": "networkconfig",
+ "hostPath": {
+ "path": "/etc/kubernetes/network.json"
+ }
+ }
+ ],
+ "containers": [
+ {
+ "name": "flannel-server-helper",
+ "image": "gcr.io/google_containers/flannel-server-helper:0.1",
+ "args": [
+ "--network-config=/etc/kubernetes/network.json",
+ "--etcd-prefix=/kubernetes.io/network",
+ "--etcd-server=http://127.0.0.1:4001"
+ ],
+ "volumeMounts": [
+ {
+ "name": "networkconfig",
+ "mountPath": "/etc/kubernetes/network.json"
+ }
+ ],
+ "imagePullPolicy": "Always"
+ },
+ {
+ "name": "flannel-container",
+ "image": "quay.io/coreos/flannel:0.5.5",
+ "command": [
+ "/bin/sh",
+ "-c",
+ "/opt/bin/flanneld -listen 0.0.0.0:10253 -etcd-endpoints {% for member in master.etcd.members %}http://{{ member.host }}:4001{% if not loop.last %},{% endif %}{% endfor %} -etcd-prefix /kubernetes.io/network 2>&1 | tee -a /var/log/flannel_server.log"
+ ],
+ "ports": [
+ {
+ "hostPort": 10253,
+ "containerPort": 10253
+ }
+ ],
+ "resources": {
+ "requests": {
+ "cpu": "100m"
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "varlog",
+ "mountPath": "/var/log"
+ }
+ ]
+ }
+ ],
+ "hostNetwork": true
+ }
+}
\ No newline at end of file
diff --git a/kubernetes/files/manifest/glusterfs-endpoints.manifest b/kubernetes/files/manifest/glusterfs-endpoints.manifest
new file mode 100644
index 0000000..39ef763
--- /dev/null
+++ b/kubernetes/files/manifest/glusterfs-endpoints.manifest
@@ -0,0 +1,12 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: Endpoints
+metadata:
+ name: glusterfs-cluster
+subnets:
+ {%- for member in master.storage.members %}
+ addresses:
+ ip: {{ member.host }}
+ ports:
+ port: {{ member.port }}
+ {%- endfor %}
\ No newline at end of file
diff --git a/kubernetes/files/manifest/glusterfs-svc.manifest b/kubernetes/files/manifest/glusterfs-svc.manifest
new file mode 100644
index 0000000..5775a84
--- /dev/null
+++ b/kubernetes/files/manifest/glusterfs-svc.manifest
@@ -0,0 +1,8 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: Service
+metadata:
+ name: glusterfs-cluster
+spec:
+ ports:
+ port: {{ master.storage.port }}
\ No newline at end of file
diff --git a/kubernetes/files/manifest/kube-apiserver.manifest b/kubernetes/files/manifest/kube-apiserver.manifest
new file mode 100644
index 0000000..782b0b5
--- /dev/null
+++ b/kubernetes/files/manifest/kube-apiserver.manifest
@@ -0,0 +1,83 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: Pod
+metadata:
+ name: kube-apiserver
+ namespace: kube-system
+spec:
+ dnsPolicy: ClusterFirst
+ hostNetwork: true
+ restartPolicy: Always
+ terminationGracePeriodSeconds: 30
+ containers:
+ - name: kube-apiserver
+ image: {{ master.registry }}/kube-apiserver:{{ master.version }}
+ command:
+ - /bin/sh
+ - -c
+ - /usr/local/bin/kube-apiserver
+ --address=127.0.0.1
+ --etcd-servers={% for member in master.etcd.members %}http://{{ member.host }}:4001{% if not loop.last %},{% endif %}{% endfor %}
+ --admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota
+ --service-cluster-ip-range={{ master.service_addresses }}
+ --client-ca-file=/etc/ssl/certs/ca-{{ master.ca }}.crt
+ --basic-auth-file=/srv/kubernetes/basic_auth.csv
+ --tls-cert-file=/etc/ssl/certs/kubernetes-server.crt
+ --tls-private-key-file=/etc/ssl/private/kubernetes-server.key
+ --secure-port=443
+ --bind-address={{ master.apiserver.address }}
+ --token-auth-file=/srv/kubernetes/known_tokens.csv
+ --v=2
+ --allow-privileged=True
+ 1>>/var/log/kube-apiserver.log 2>&1
+ imagePullPolicy: IfNotPresent
+ livenessProbe:
+ httpGet:
+ host: 127.0.0.1
+ path: /healthz
+ port: 8080
+ scheme: HTTP
+ initialDelaySeconds: 15
+ timeoutSeconds: 15
+ ports:
+ - containerPort: 443
+ hostPort: 443
+ name: https
+ protocol: TCP
+ - containerPort: 8080
+ hostPort: 8080
+ name: local
+ protocol: TCP
+ resources:
+ requests:
+ cpu: 250m
+ volumeMounts:
+ - mountPath: /srv/kubernetes
+ name: srvkube
+ readOnly: true
+ - mountPath: /var/log/kube-apiserver.log
+ name: logfile
+ - mountPath: /etc/ssl
+ name: etcssl
+ readOnly: true
+ - mountPath: /usr/share/ca-certificates
+ name: usrsharecacerts
+ readOnly: true
+ - mountPath: /srv/sshproxy
+ name: srvsshproxy
+ volumes:
+ - hostPath:
+ path: /srv/kubernetes
+ name: srvkube
+ - hostPath:
+ path: /var/log/kube-apiserver.log
+ name: logfile
+ - hostPath:
+ path: /etc/ssl
+ name: etcssl
+ - hostPath:
+ path: /usr/share/ca-certificates
+ name: usrsharecacerts
+ - hostPath:
+ path: /srv/sshproxy
+ name: srvsshproxy
diff --git a/kubernetes/files/manifest/kube-controller-manager.manifest b/kubernetes/files/manifest/kube-controller-manager.manifest
new file mode 100644
index 0000000..25a71d8
--- /dev/null
+++ b/kubernetes/files/manifest/kube-controller-manager.manifest
@@ -0,0 +1,64 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: Pod
+metadata:
+ name: kube-controller-manager
+ namespace: kube-system
+spec:
+ dnsPolicy: ClusterFirst
+ hostNetwork: true
+ restartPolicy: Always
+ terminationGracePeriodSeconds: 30
+ containers:
+ - name: kube-controller-manager
+ image: {{ master.registry }}/kube-controller-manager:{{ master.version }}
+ command:
+ - /bin/sh
+ - -c
+ - /usr/local/bin/kube-controller-manager
+ --master=127.0.0.1:8080
+ --cluster-name=kubernetes
+ --service-account-private-key-file=/etc/ssl/private/kubernetes-server.key
+ --v=2
+ --root-ca-file=/etc/ssl/certs/ca-{{ master.ca }}.crt
+ --leader-elect=true
+ 1>>/var/log/kube-controller-manager.log 2>&1
+ imagePullPolicy: IfNotPresent
+ livenessProbe:
+ httpGet:
+ host: 127.0.0.1
+ path: /healthz
+ port: 10252
+ scheme: HTTP
+ initialDelaySeconds: 15
+ timeoutSeconds: 15
+ resources:
+ limits:
+ cpu: 200m
+ requests:
+ cpu: 200m
+ volumeMounts:
+ - mountPath: /srv/kubernetes
+ name: srvkube
+ readOnly: true
+ - mountPath: /var/log/kube-controller-manager.log
+ name: logfile
+ - mountPath: /etc/ssl
+ name: etcssl
+ readOnly: true
+ - mountPath: /usr/share/ca-certificates
+ name: usrsharecacerts
+ readOnly: true
+ volumes:
+ - hostPath:
+ path: /srv/kubernetes
+ name: srvkube
+ - hostPath:
+ path: /var/log/kube-controller-manager.log
+ name: logfile
+ - hostPath:
+ path: /etc/ssl
+ name: etcssl
+ - hostPath:
+ path: /usr/share/ca-certificates
+ name: usrsharecacerts
diff --git a/kubernetes/files/manifest/kube-network-manager.manifest b/kubernetes/files/manifest/kube-network-manager.manifest
new file mode 100644
index 0000000..1f1470a
--- /dev/null
+++ b/kubernetes/files/manifest/kube-network-manager.manifest
@@ -0,0 +1,24 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{
+ "apiVersion": "v1",
+ "kind": "Pod",
+ "metadata": {
+ "namespace": "opencontrail",
+ "name": "kube-network-manager"
+ },
+ "spec":{
+ "hostNetwork": true,
+ "containers":[{
+ "name": "kube-network-manager",
+ "image": "{{ master.network.network_manager.image }}:{{ master.network.network_manager.tag }}",
+ "volumeMounts": [{
+ "name": "config",
+ "mountPath": "/etc/kubernetes"
+ }]
+ }],
+ "volumes": [{
+ "name": "config",
+ "hostPath": {"path": "/etc/kubernetes"}
+ }]
+ }
+}
diff --git a/kubernetes/files/manifest/kube-proxy.manifest b/kubernetes/files/manifest/kube-proxy.manifest
new file mode 100644
index 0000000..23b46f4
--- /dev/null
+++ b/kubernetes/files/manifest/kube-proxy.manifest
@@ -0,0 +1,46 @@
+{%- from "kubernetes/map.jinja" import pool with context %}
+apiVersion: v1
+kind: Pod
+metadata:
+ name: kube-proxy
+ namespace: kube-system
+spec:
+ hostNetwork: true
+ containers:
+ - name: kube-proxy
+ image: {{ pool.registry }}/kube-proxy:{{ pool.version }}
+ resources:
+ requests:
+ cpu: 200m
+ command:
+ - /bin/sh
+ - -c
+ - kube-proxy
+ --logtostderr=true
+ --v=2
+ --kubeconfig=/etc/kubernetes/proxy.kubeconfig
+ --master=https://{{ pool.master.host }}
+ {% if pool.network.engine == 'calico' %}--proxy-mode=iptables{% endif %}
+ 1>>/var/log/kube-proxy.log 2>&1
+ securityContext:
+ privileged: true
+ volumeMounts:
+ - mountPath: /etc/ssl/certs
+ name: ssl-certs-host
+ readOnly: true
+ - mountPath: /var/log
+ name: varlog
+ readOnly: false
+ - mountPath: /var/lib/kube-proxy/kubeconfig
+ name: kubeconfig
+ readOnly: false
+ volumes:
+ - hostPath:
+ path: /usr/share/ca-certificates
+ name: ssl-certs-host
+ - hostPath:
+ path: /var/lib/kube-proxy/kubeconfig
+ name: kubeconfig
+ - hostPath:
+ path: /var/log
+ name: varlog
\ No newline at end of file
diff --git a/kubernetes/files/manifest/kube-scheduler.manifest b/kubernetes/files/manifest/kube-scheduler.manifest
new file mode 100644
index 0000000..5c7bc9f
--- /dev/null
+++ b/kubernetes/files/manifest/kube-scheduler.manifest
@@ -0,0 +1,42 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+apiVersion: v1
+kind: Pod
+metadata:
+ name: kube-scheduler
+ namespace: kube-system
+spec:
+ dnsPolicy: ClusterFirst
+ hostNetwork: true
+ nodeName: kubernetes-master
+ restartPolicy: Always
+ terminationGracePeriodSeconds: 30
+ containers:
+ - name: kube-scheduler
+ image: {{ master.registry }}/kube-scheduler:{{ master.version }}
+ imagePullPolicy: IfNotPresent
+ command:
+ - /bin/sh
+ - -c
+ - /usr/local/bin/kube-scheduler
+ --master=127.0.0.1:8080
+ --v=2
+ --leader-elect=true
+ 1>>/var/log/kube-scheduler.log 2>&1
+ livenessProbe:
+ httpGet:
+ host: 127.0.0.1
+ path: /healthz
+ port: 10251
+ scheme: HTTP
+ initialDelaySeconds: 15
+ timeoutSeconds: 15
+ resources:
+ requests:
+ cpu: 100m
+ volumeMounts:
+ - mountPath: /var/log/kube-scheduler.log
+ name: logfile
+ volumes:
+ - hostPath:
+ path: /var/log/kube-scheduler.log
+ name: logfile
\ No newline at end of file
diff --git a/kubernetes/files/nginx.conf b/kubernetes/files/nginx.conf
new file mode 100644
index 0000000..8443add
--- /dev/null
+++ b/kubernetes/files/nginx.conf
@@ -0,0 +1,37 @@
+server {
+ listen 443;
+ server_name localhost;
+
+ root html;
+ index index.html index.htm;
+
+ ssl on;
+ ssl_certificate /etc/pki/cert/{{ master.ca }}/{{ master.apiserver.address }}.crt;
+ ssl_certificate_key /etc/pki/cert/{{ master.ca }}/{{ master.apiserver.address }}.key;
+
+ ssl_session_timeout 5m;
+
+ # don't use SSLv3 because of POODLE
+ ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
+ ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
+ ssl_prefer_server_ciphers on;
+
+ location / {
+
+ # Proxy settings
+ # disable buffering so that watch works
+ proxy_buffering off;
+ proxy_pass http://127.0.0.1:8080/;
+ proxy_connect_timeout 159s;
+ proxy_send_timeout 600s;
+ proxy_read_timeout 600s;
+
+ # Disable retry
+ proxy_next_upstream off;
+
+ # Support web sockets
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ }
+}
\ No newline at end of file
diff --git a/kubernetes/files/opencontrail/namespace-opencontrail.yml b/kubernetes/files/opencontrail/namespace-opencontrail.yml
new file mode 100644
index 0000000..4e28c1f
--- /dev/null
+++ b/kubernetes/files/opencontrail/namespace-opencontrail.yml
@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: opencontrail
\ No newline at end of file
diff --git a/kubernetes/files/opencontrail/network.conf b/kubernetes/files/opencontrail/network.conf
new file mode 100644
index 0000000..a40cabd
--- /dev/null
+++ b/kubernetes/files/opencontrail/network.conf
@@ -0,0 +1,15 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+[DEFAULT]
+service-cluster-ip-range = {{ master.network.service_cluster_ip_range }}
+
+[opencontrail]
+default-domain = {{ master.network.default_domain }}
+public-ip-range = {{ master.network.public_ip_range }}
+cluster-service = {{ master.network.cluster_service }}
+api-server = {{ master.network.host }}
+api-port = {{ master.network.port }}
+default-project = {{ master.network.default_project }}
+public-network = {{ master.network.public_network }}
+private-ip-range = {{ master.network.private_ip_range }}
+network-label = {{ master.network.network_label }}
+service-label = {{ master.network.service_label }}
\ No newline at end of file
diff --git a/kubernetes/files/rc.yml b/kubernetes/files/rc.yml
new file mode 100644
index 0000000..7339fb4
--- /dev/null
+++ b/kubernetes/files/rc.yml
@@ -0,0 +1,117 @@
+{% from "kubernetes/map.jinja" import control with context %}
+apiVersion: {{ service.apiVersion }}
+kind: {{ service.kind }}
+metadata:
+ name: {{ service.service }}-{{ service.role }}
+ namespace: {{ service.namespace }}
+ labels:
+ app: {{ service.service }}-{{ service.role }}
+spec:
+ replicas: {{ service.replicas }}
+ template:
+ metadata:
+ labels:
+ app: {{ service.service }}-{{ service.role }}
+ spec:
+ {%- if service.hostNetwork is defined %}
+ hostNetwork: True
+ {%- endif %}
+ containers:
+ {%- for container_name, container in service.container.iteritems() %}
+ - name: {{ container_name }}
+ image: {% if container.registry is defined %}{{ container.registry }}/{%- endif %}{{ container.image }}{%- if container.tag is defined %}:{{ container.tag }}{%- endif %}
+ imagePullPolicy: IfNotPresent
+ {%- if container.privileged is defined %}
+ securityContext:
+ privileged: True
+ {%- endif %}
+ {%- if container.variables is defined %}
+ env:
+ {%- for variable in container.variables %}
+ - name: {{ variable.name }}
+ {%- if variable.fieldPath is defined %}
+ valueFrom:
+ fieldRef:
+ fieldPath: {{ variable.fieldPath }}
+ {%- else %}
+ value: {{ variable.value }}
+ {%- endif %}
+ {%- endfor %}
+ {%- endif %}
+ {%- if container.ports is defined %}
+ ports:
+ {%- for port in container.ports %}
+ - containerPort: {{ port.port }}
+ name: {{ port.name }}
+ {%- endfor %}
+ {%- endif %}
+ {%- if container.command is defined %}
+ command:
+ {%- for command in container.command %}
+ - {{ command }}
+ {%- endfor %}
+ {%- endif %}
+ {%- if container.volumes is defined %}
+ volumeMounts:
+ {%- for volume in container.volumes %}
+ - name: {{ volume.name }}
+ mountPath: {{ volume.mount }}
+ readOnly: {{ volume.read_only }}
+ {%- endfor %}
+ {%- endif %}
+ {%- if container.liveness_probe is defined %}
+ livenessProbe:
+ {%- if container.liveness_probe.type == 'http' %}
+ httpGet:
+ path: {{ container.liveness_probe.path }}
+ port: {{ container.liveness_probe.port }}
+ {%- elif container.liveness_probe.type == 'exec' %}
+ exec:
+ command:
+ {%- for command in container.liveness_probe.command %}
+ - {{ command }}
+ {%- endfor %}
+ {%- endif %}
+ initialDelaySeconds: {{ container.liveness_probe.initial_delay }}
+ timeoutSeconds: {{ container.liveness_probe.timeout }}
+ {%- endif %}
+ {%- if container.readiness_probe is defined %}
+ readinessProbe:
+ {%- if container.readiness_probe.type == 'http' %}
+ httpGet:
+ path: {{ container.readiness_probe.path }}
+ port: {{ container.readiness_probe.port }}
+ {%- elif container.readiness_probe.type == 'exec' %}
+ exec:
+ command:
+ {%- for command in container.liveness_probe.command %}
+ - {{ command }}
+ {%- endfor %}
+ {%- endif %}
+ initialDelaySeconds: {{ container.readiness_probe.initial_delay }}
+ timeoutSeconds: {{ container.readiness_probe.timeout }}
+ {%- endif %}
+ {%- endfor %}
+ {%- if service.volume is defined %}
+ volumes:
+ {%- for volume_name, volume in service.volume.iteritems() %}
+ - name: {{ volume_name }}
+ {%- if volume.type == 'emptyDir' %}
+ emptyDir: {}
+ {%- elif volume.type == 'hostPath' %}
+ hostPath:
+ path: {{ volume.path }}
+ {%- elif volume.type == 'glusterfs' %}
+ glusterfs:
+ endpoints: {{ volume.endpoints }}
+ path: {{ volume.path }}
+ readOnly: {{ volume.read_only }}
+ {%- endif %}
+ {%- endfor %}
+ {%- endif %}
+ {%- if service.nodeSelector is defined %}
+ nodeSelector:
+ {%- for selector in service.nodeSelector %}
+ {{ selector.key }}: {{ selector.value }}
+ {%- endfor %}
+ {%- endif %}
\ No newline at end of file
diff --git a/kubernetes/files/svc.yml b/kubernetes/files/svc.yml
new file mode 100644
index 0000000..c67a193
--- /dev/null
+++ b/kubernetes/files/svc.yml
@@ -0,0 +1,17 @@
+{% from "kubernetes/map.jinja" import control with context %}
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ name: {{ service.service }}-{{ service.role }}
+ app: {{ service.service }}-{{ service.role }}
+ name: {{ service.service }}-{{ service.role }}
+spec:
+ ports:
+ {%- for port in service.ports %}
+ - port: {{ port.port }}
+ name: {{ port.name }}
+ {%- endfor %}
+ type: {{ service.type }}
+ selector:
+ app: {{ service.service }}-{{ service.role }}
\ No newline at end of file
diff --git a/kubernetes/init.sls b/kubernetes/init.sls
new file mode 100644
index 0000000..22aad26
--- /dev/null
+++ b/kubernetes/init.sls
@@ -0,0 +1,13 @@
+
+{%- if pillar.kubernetes is defined %}
+include:
+{%- if pillar.kubernetes.master is defined %}
+- kubernetes.master
+{%- endif %}
+{%- if pillar.kubernetes.pool is defined %}
+- kubernetes.pool
+{%- endif %}
+{%- if pillar.kubernetes.control is defined %}
+- kubernetes.control
+{%- endif %}
+{%- endif %}
diff --git a/kubernetes/map.jinja b/kubernetes/map.jinja
new file mode 100644
index 0000000..9c9f82b
--- /dev/null
+++ b/kubernetes/map.jinja
@@ -0,0 +1,42 @@
+{% set common = salt['grains.filter_by']({
+ 'Debian': {
+ 'pkgs': ['curl', 'git', 'apt-transport-https', 'python-apt', 'nfs-common', 'socat', 'netcat-traditional', 'openssl'],
+ 'services': [],
+ },
+ 'RedHat': {
+ 'pkgs': ['curl', 'git', 'apt-transport-https', 'python-apt', 'nfs-common', 'socat', 'netcat-traditional', 'python'],
+ 'services': [],
+ },
+}, merge=salt['pillar.get']('kubernetes:common')) %}
+
+{% set master = salt['grains.filter_by']({
+ 'Debian': {
+ 'pkgs': [],
+ 'services': [],
+ },
+ 'RedHat': {
+ 'pkgs': [],
+ 'services': [],
+ },
+}, merge=salt['pillar.get']('kubernetes:master')) %}
+
+{% set pool = salt['grains.filter_by']({
+ 'Debian': {
+ 'pkgs': [],
+ 'services': [],
+ },
+ 'RedHat': {
+ 'pkgs': [],
+ 'services': [],
+ },
+}, merge=salt['pillar.get']('kubernetes:pool')) %}
+
+{% set control = salt['grains.filter_by']({
+ 'Debian': {
+ 'service': {},
+ },
+ 'RedHat': {
+ 'service': {},
+ },
+}, merge=salt['pillar.get']('kubernetes:control')) %}
+
diff --git a/kubernetes/master/api.sls b/kubernetes/master/api.sls
new file mode 100644
index 0000000..f153e75
--- /dev/null
+++ b/kubernetes/master/api.sls
@@ -0,0 +1,38 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{%- if master.enabled %}
+
+/srv/kubernetes/known_tokens.csv:
+ file.managed:
+ - source: salt://kubernetes/files/known_tokens.csv
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+
+/srv/kubernetes/basic_auth.csv:
+ file.managed:
+ - source: salt://kubernetes/files/basic_auth.csv
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+
+/var/log/kube-apiserver.log:
+ file.managed:
+ - user: root
+ - group: root
+ - mode: 644
+
+/etc/kubernetes/manifests/kube-apiserver.manifest:
+ file.managed:
+ - source: salt://kubernetes/files/manifest/kube-apiserver.manifest
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+ - dir_mode: 755
+
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/master/calico.sls b/kubernetes/master/calico.sls
new file mode 100644
index 0000000..665a4be
--- /dev/null
+++ b/kubernetes/master/calico.sls
@@ -0,0 +1,52 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{%- if master.enabled %}
+/etc/kubernetes/manifests/calico-etcd.manifest:
+ file.managed:
+ - source: salt://kubernetes/files/manifest/calico-etcd.manifest
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+ - dir_mode: 755
+ - template: jinja
+
+/usr/bin/calicoctl:
+ file.managed:
+ - source: https://github.com/projectcalico/calico-containers/releases/download/{{ master.network.version }}/calicoctl
+ - source_hash: md5={{ master.network.hash }}
+ - mode: 751
+ - user: root
+ - group: root
+
+{% if pillar.get('is_systemd') %}
+
+/etc/calico/network-environment:
+ file.managed:
+ - source: salt://kubernetes/files/calico/network-environment.master
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+ - dir_mode: 755
+ - template: jinja
+
+/etc/systemd/calico-node.service:
+ file.managed:
+ - source: salt://kubernetes/files/calico/calico-node.service
+ - user: root
+ - group: root
+
+{% endif %}
+
+calico_node:
+ service.running:
+ - enable: True
+ - watch:
+ - file: /usr/bin/calicoctl
+{% if pillar.get('is_systemd') %}
+ - file: /etc/systemd/calico-node.service
+{% else %}
+ - file: /etc/init/docker-calico-node.conf
+{% endif %}
+
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/master/controller-manager.sls b/kubernetes/master/controller-manager.sls
new file mode 100644
index 0000000..a0c93f6
--- /dev/null
+++ b/kubernetes/master/controller-manager.sls
@@ -0,0 +1,20 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{%- if master.enabled %}
+
+/etc/kubernetes/manifests/kube-controller-manager.manifest:
+ file.managed:
+ - source: salt://kubernetes/files/manifest/kube-controller-manager.manifest
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+ - dir_mode: 755
+
+/var/log/kube-controller-manager.log:
+ file.managed:
+ - user: root
+ - group: root
+ - mode: 644
+
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/master/etcd.sls b/kubernetes/master/etcd.sls
new file mode 100644
index 0000000..886483c
--- /dev/null
+++ b/kubernetes/master/etcd.sls
@@ -0,0 +1,46 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{%- if master.enabled %}
+
+/var/log/etcd-events.log:
+ file.managed:
+ - user: root
+ - group: root
+ - mode: 644
+
+/var/log/etcd.log:
+ file.managed:
+ - user: root
+ - group: root
+ - mode: 644
+
+/var/etcd:
+ file.directory:
+ - user: root
+ - group: root
+ - dir_mode: 700
+ - recurse:
+ - user
+ - group
+ - mode
+
+/etc/kubernetes/manifests/etcd.manifest:
+ file.managed:
+ - source: salt://kubernetes/files/manifest/etcd.manifest
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+ - dir_mode: 755
+
+/etc/kubernetes/manifests/etcd-events.manifest:
+ file.managed:
+ - source: salt://kubernetes/files/manifest/etcd-events.manifest
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+ - dir_mode: 755
+
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/master/flannel.sls b/kubernetes/master/flannel.sls
new file mode 100644
index 0000000..3f9c3b9
--- /dev/null
+++ b/kubernetes/master/flannel.sls
@@ -0,0 +1,76 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{%- if master.enabled %}
+flannel-tar:
+ archive:
+ - extracted
+ - user: root
+ - name: /usr/local/src
+ - source: https://storage.googleapis.com/kubernetes-release/flannel/flannel-0.5.5-linux-amd64.tar.gz
+ - tar_options: v
+ - source_hash: md5=972c717254775bef528f040af804f2cc
+ - archive_format: tar
+ - if_missing: /usr/local/src/flannel/flannel-0.5.5/
+
+flannel-symlink:
+ file.symlink:
+ - name: /usr/local/bin/flanneld
+ - target: /usr/local/src/flannel-0.5.5/flanneld
+ - force: true
+ - watch:
+ - archive: flannel-tar
+
+/var/log/etcd_flannel.log:
+ file.managed:
+ - user: root
+ - group: root
+ - mode: 755
+
+/var/log/flannel.log:
+ file.managed:
+ - user: root
+ - group: root
+ - mode: 755
+
+/etc/kubernetes/network.json:
+ file.managed:
+ - source: salt://kubernetes/files/flannel/network.json
+ - makedirs: True
+ - user: root
+ - group: root
+ - mode: 755
+ - template: jinja
+
+/etc/kubernetes/manifests/flannel-server.manifest:
+ file.managed:
+ - source: salt://kubernetes/files/manifest/flannel-server.manifest
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+ - dir_mode: 755
+ - template: jinja
+
+/etc/default/flannel:
+ file.managed:
+ - source: salt://kubernetes/files/flannel/default.master
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+
+/etc/init.d/flannel:
+ file.managed:
+ - source: salt://kubernetes/files/flannel/initd
+ - user: root
+ - group: root
+ - mode: 755
+
+flannel:
+ service.running:
+ - enable: True
+ - watch:
+ - file: /usr/local/bin/flanneld
+ - file: /etc/init.d/flannel
+ - file: /etc/default/flannel
+
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/master/glusterfs.sls b/kubernetes/master/glusterfs.sls
new file mode 100644
index 0000000..d4f7baa
--- /dev/null
+++ b/kubernetes/master/glusterfs.sls
@@ -0,0 +1,22 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{%- if master.enabled %}
+
+/etc/kubernetes/glusterfs/glusterfs-endpoints.manifest:
+ file.managed:
+ - source: salt://kubernetes/files/manifest/glusterfs-endpoints.manifest
+ - makedirs: True
+ - user: root
+ - group: root
+ - mode: 644
+ - template: jinja
+
+/etc/kubernetes/glusterfs/glusterfs-svc.manifest:
+ file.managed:
+ - source: salt://kubernetes/files/manifest/glusterfs-svc.manifest
+ - makedirs: True
+ - user: root
+ - group: root
+ - mode: 644
+ - template: jinja
+
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/master/init.sls b/kubernetes/master/init.sls
new file mode 100644
index 0000000..afbd5ea
--- /dev/null
+++ b/kubernetes/master/init.sls
@@ -0,0 +1,21 @@
+
+include:
+- kubernetes.master.service
+- kubernetes.master.etcd
+- kubernetes.master.api
+- kubernetes.master.controller-manager
+- kubernetes.master.scheduler
+- kubernetes.master.kube-addons
+{%- if master.network.engine == "opencontrail" %}
+- kubernetes.master.opencontrail-network-manager
+{%- endif %}
+{%- if master.network.engine == "flannel" %}
+- kubernetes.master.flannel
+{%- endif %}
+{%- if master.network.engine == "calico" %}
+- kubernetes.master.calico
+{%- endif %}
+{%- if master.storage.get('engine', 'none') == 'glusterfs' %}
+- kubernetes.master.glusterfs
+{%- endif %}
+- kubernetes.master.kubelet
diff --git a/kubernetes/master/kube-addons.sls b/kubernetes/master/kube-addons.sls
new file mode 100644
index 0000000..f4c31d0
--- /dev/null
+++ b/kubernetes/master/kube-addons.sls
@@ -0,0 +1,179 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{%- if master.enabled %}
+
+addon-dir-create:
+ file.directory:
+ - name: /etc/kubernetes/addons
+ - user: root
+ - group: root
+ - mode: 0755
+
+/etc/kubernetes/addons/namespace.yml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/namespace.yml
+ - user: root
+ - group: root
+ - file_mode: 644
+
+{%- if master.addons.dns.enabled %}
+
+/etc/kubernetes/addons/dns/skydns-svc.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/dns/skydns-svc.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+/etc/kubernetes/addons/dns/skydns-rc.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/dns/skydns-rc.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+{% endif %}
+
+{%- if master.addons.ui.enabled %}
+
+{%- if master.version == "v1.1.1" %}
+
+/etc/kubernetes/addons/kube-ui/kube-ui-svc.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/kube-ui/kube-ui-svc.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+/etc/kubernetes/addons/kube-ui/kube-ui-rc.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/kube-ui/kube-ui-rc.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+/etc/kubernetes/addons/kube-ui/kube-ui-address.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/kube-ui/kube-ui-address.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+/etc/kubernetes/addons/kube-ui/kube-ui-endpoint.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/kube-ui/kube-ui-endpoint.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+{% endif %}
+
+/etc/kubernetes/addons/dashboard/dashboard-service.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/dashboard/dashboard-service.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+/etc/kubernetes/addons/dashboard/dashboard-controller.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/dashboard/dashboard-controller.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+{%- if master.network.engine == "opencontrail" %}
+
+/etc/kubernetes/addons/dashboard/dashboard-address.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/dashboard/dashboard-address.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+/etc/kubernetes/addons/dashboard/dashboard-endpoint.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/dashboard/dashboard-endpoint.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+{% endif %}
+
+{% endif %}
+
+{%- if master.addons.heapster_influxdb.enabled %}
+
+/etc/kubernetes/addons/heapster-influxdb/heapster-address.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/heapster-influxdb/heapster-address.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+/etc/kubernetes/addons/heapster-influxdb/heapster-controller.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/heapster-influxdb/heapster-controller.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+/etc/kubernetes/addons/heapster-influxdb/heapster-endpoint.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/heapster-influxdb/heapster-endpoint.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+/etc/kubernetes/addons/heapster-influxdb/heapster-service.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/heapster-influxdb/heapster-service.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+/etc/kubernetes/addons/heapster-influxdb/influxdb-controller.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/heapster-influxdb/influxdb-controller.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+/etc/kubernetes/addons/heapster-influxdb/influxdb-service.yaml:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/heapster-influxdb/influxdb-service.yaml
+ - template: jinja
+ - group: root
+ - dir_mode: 755
+ - makedirs: True
+
+{% endif %}
+
+/etc/kubernetes/kube-addons.sh:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/kube-addons.sh
+ - user: root
+ - group: root
+ - mode: 755
+
+/etc/kubernetes/kube-addon-update.sh:
+ file.managed:
+ - source: salt://kubernetes/files/kube-addons/kube-addon-update.sh
+ - user: root
+ - group: root
+ - mode: 755
+
+{% endif %}
\ No newline at end of file
diff --git a/kubernetes/master/kubelet.sls b/kubernetes/master/kubelet.sls
new file mode 100644
index 0000000..78bf5a7
--- /dev/null
+++ b/kubernetes/master/kubelet.sls
@@ -0,0 +1,67 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{%- if master.enabled %}
+
+{% if pillar.get('is_systemd') %}
+{% set environment_file = '/etc/sysconfig/kubelet' %}
+{% else %}
+{% set environment_file = '/etc/default/kubelet' %}
+{% endif %}
+
+{{ environment_file }}:
+ file.managed:
+ - source: salt://kubernetes/files/kubelet/default.master
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+
+/usr/local/bin/kubelet:
+ file.managed:
+ - user: root
+ - group: root
+ - mode: 755
+
+{% if pillar.get('is_systemd') %}
+
+{{ pillar.get('systemd_system_path') }}/kubelet.service:
+ file.managed:
+ - source: salt://kubernetes/files/kubelet/kubelet.service
+ - user: root
+ - group: root
+
+fix-service-kubelet:
+ cmd.wait:
+ - name: /opt/kubernetes/helpers/services bounce kubelet
+ - watch:
+ - file: /usr/local/bin/kubelet
+ - file: {{ pillar.get('systemd_system_path') }}/kubelet.service
+ - file: {{ environment_file }}
+ - file: /var/lib/kubelet/kubeconfig
+
+{% else %}
+
+/etc/init.d/kubelet:
+ file.managed:
+ - source: salt://kubernetes/files/kubelet/initd
+ - user: root
+ - group: root
+ - mode: 755
+
+{% endif %}
+
+kubelet:
+ service.running:
+ - enable: True
+ - watch:
+ - file: /usr/local/bin/kubelet
+{% if pillar.get('is_systemd') %}
+ - file: {{ pillar.get('systemd_system_path') }}/kubelet.service
+{% else %}
+ - file: /etc/init.d/kubelet
+{% endif %}
+{% if grains['os_family'] == 'RedHat' %}
+ - file: /usr/lib/systemd/system/kubelet.service
+{% endif %}
+ - file: {{ environment_file }}
+
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/master/opencontrail-network-manager.sls b/kubernetes/master/opencontrail-network-manager.sls
new file mode 100644
index 0000000..803bd4d
--- /dev/null
+++ b/kubernetes/master/opencontrail-network-manager.sls
@@ -0,0 +1,30 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{%- if master.enabled %}
+
+/etc/kubernetes/manifests/kube-network-manager.manifest:
+ file.managed:
+ - source: salt://kubernetes/files/manifest/kube-network-manager.manifest
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+ - dir_mode: 755
+
+/etc/kubernetes/network.conf:
+ file.managed:
+ - source: salt://kubernetes/files/opencontrail/network.conf
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+
+/etc/kubernetes/namespace-opencontrail.yml:
+ file.managed:
+ - source: salt://kubernetes/files/opencontrail/namespace-opencontrail.yml
+ - user: root
+ - group: root
+ - file_mode: 644
+
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/master/scheduler.sls b/kubernetes/master/scheduler.sls
new file mode 100644
index 0000000..235d9b4
--- /dev/null
+++ b/kubernetes/master/scheduler.sls
@@ -0,0 +1,20 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{%- if master.enabled %}
+
+/etc/kubernetes/manifests/kube-scheduler.manifest:
+ file.managed:
+ - source: salt://kubernetes/files/manifest/kube-scheduler.manifest
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+ - dir_mode: 755
+
+/var/log/kube-scheduler.log:
+ file.managed:
+ - user: root
+ - group: root
+ - mode: 644
+
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/master/service.sls b/kubernetes/master/service.sls
new file mode 100644
index 0000000..1f6c562
--- /dev/null
+++ b/kubernetes/master/service.sls
@@ -0,0 +1,33 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{%- from "kubernetes/map.jinja" import common with context %}
+{%- from "linux/map.jinja" import system with context %}
+{%- if master.enabled %}
+
+include:
+- kubernetes._common
+
+kubernetes_master_binaries:
+ cmd.run:
+ - names:
+ - "cp /root/apt.tcpcloud.eu/kubernetes/bin/{{ common.binaries_version }}/kubectl /usr/bin/"
+ - "cp /root/apt.tcpcloud.eu/kubernetes/bin/{{ common.binaries_version }}/kubelet /usr/local/bin/"
+ - "cp /root/etcd-v2.2.1-linux-amd64/etcdctl /usr/bin/"
+ - unless: test -f /usr/local/bin/kubelet && test -f /usr/bin/kubectl && test -f /usr/bin/etcdctl
+ - require:
+ - cmd: kubernetes_binaries
+
+kubernetes_master_cert_group:
+ group.present:
+ - name: kube-cert
+ - system: True
+
+kubernetes_master_cert_dir:
+ file.directory:
+ - name: /srv/kubernetes/
+ - mode: 750
+ - group: kube-cert
+ - makedirs: True
+ - requires:
+ - group: kubernetes_master_cert_group
+
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/meta/sphinx.yml b/kubernetes/meta/sphinx.yml
new file mode 100644
index 0000000..9afcc4d
--- /dev/null
+++ b/kubernetes/meta/sphinx.yml
@@ -0,0 +1,15 @@
+doc:
+ name: Kubernetes
+ description: Manage a cluster of Linux containers as a single system to accelerate Dev and simplify Ops.
+ role:
+ {%- if pillar.kubernetes.pool is defined %}
+ {%- from "kubernetes/map.jinja" import client with context %}
+ pool:
+ name: pool
+ param: {}
+ {%- endif %}
+ {%- if pillar.kubernetes.master is defined %}
+ master:
+ name: master
+ param: {}
+ {%- endif %}
diff --git a/kubernetes/pool/calico.sls b/kubernetes/pool/calico.sls
new file mode 100644
index 0000000..366effb
--- /dev/null
+++ b/kubernetes/pool/calico.sls
@@ -0,0 +1,71 @@
+{%- from "kubernetes/map.jinja" import pool with context %}
+{%- if pool.enabled %}
+
+/usr/bin/calicoctl:
+ file.managed:
+ - source: https://github.com/projectcalico/calico-containers/releases/download/{{ pool.network.version }}/calicoctl
+ - source_hash: md5={{ pool.network.hash }}
+ - mode: 751
+ - user: root
+ - group: root
+
+/opt/cni/bin/calico:
+ file.managed:
+ - source: https://github.com/projectcalico/calico-cni/releases/download/v1.0.0/calico
+ - source_hash: md5=c829450f7e9d7abe81b3a8b37fc787a4
+ - mode: 751
+ - makedirs: true
+ - user: root
+ - group: root
+
+/opt/cni/bin/calico-ipam:
+ file.managed:
+ - source: https://github.com/projectcalico/calico-cni/releases/download/v1.0.0/calico-ipam
+ - source_hash: md5=a40d4db5b3acbb6dc93330b84d25d936
+ - mode: 751
+ - makedirs: true
+ - user: root
+ - group: root
+
+/etc/cni/net.d/10-calico.conf:
+ file.managed:
+ - source: salt://kubernetes/files/calico/calico.conf
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+ - dir_mode: 755
+ - template: jinja
+
+{% if pillar.get('is_systemd') %}
+
+/etc/calico/network-environment:
+ file.managed:
+ - source: salt://kubernetes/files/calico/network-environment.pool
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+ - dir_mode: 755
+ - template: jinja
+
+/etc/systemd/calico-node.service:
+ file.managed:
+ - source: salt://kubernetes/files/calico/calico-node.service
+ - user: root
+ - group: root
+
+{% endif %}
+
+calico_node:
+ service.running:
+ - enable: True
+ - watch:
+ - file: /usr/bin/calicoctl
+{% if pillar.get('is_systemd') %}
+ - file: /etc/systemd/calico-node.service
+{% else %}
+ - file: /etc/init/docker-calico-node.conf
+{% endif %}
+
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/pool/flannel.sls b/kubernetes/pool/flannel.sls
new file mode 100644
index 0000000..7d35da7
--- /dev/null
+++ b/kubernetes/pool/flannel.sls
@@ -0,0 +1,46 @@
+{%- from "kubernetes/map.jinja" import pool with context %}
+{%- if pool.enabled %}
+
+flannel-tar:
+ archive:
+ - extracted
+ - user: root
+ - name: /usr/local/src
+ - source: https://storage.googleapis.com/kubernetes-release/flannel/flannel-0.5.5-linux-amd64.tar.gz
+ - tar_options: v
+ - source_hash: md5=972c717254775bef528f040af804f2cc
+ - archive_format: tar
+ - if_missing: /usr/local/src/flannel/flannel-0.5.5/
+
+flannel-symlink:
+ file.symlink:
+ - name: /usr/local/bin/flanneld
+ - target: /usr/local/src/flannel-0.5.5/flanneld
+ - force: true
+ - watch:
+ - archive: flannel-tar
+
+/etc/default/flannel:
+ file.managed:
+ - source: salt://kubernetes/files/flannel/default.pool
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+
+/etc/init.d/flannel:
+ file.managed:
+ - source: salt://kubernetes/files/flannel/initd
+ - user: root
+ - group: root
+ - mode: 755
+
+flannel:
+ service.running:
+ - enable: True
+ - watch:
+ - file: /usr/local/bin/flanneld
+ - file: /etc/init.d/flannel
+ - file: /etc/default/flannel
+
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/pool/init.sls b/kubernetes/pool/init.sls
new file mode 100644
index 0000000..3ef881e
--- /dev/null
+++ b/kubernetes/pool/init.sls
@@ -0,0 +1,11 @@
+
+include:
+- kubernetes.pool.service
+{%- if pool.network.engine == "calico" %}
+- kubernetes.pool.calico
+{%- endif %}
+- kubernetes.pool.kubelet
+{%- if pool.network.engine == "flannel" %}
+- kubernetes.pool.flannel
+{%- endif %}
+- kubernetes.pool.kube-proxy
\ No newline at end of file
diff --git a/kubernetes/pool/kube-proxy.sls b/kubernetes/pool/kube-proxy.sls
new file mode 100644
index 0000000..6a406a2
--- /dev/null
+++ b/kubernetes/pool/kube-proxy.sls
@@ -0,0 +1,92 @@
+{%- from "kubernetes/map.jinja" import pool with context %}
+{%- if pool.enabled %}
+
+{% if pillar.get('is_systemd') %}
+{% set environment_file = '/etc/sysconfig/kube-proxy' %}
+{% else %}
+{% set environment_file = '/etc/default/kube-proxy' %}
+{% endif %}
+
+{{ environment_file }}:
+ file.managed:
+ - source: salt://kubernetes/files/kube-proxy/default
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+
+kube-proxy:
+ group.present:
+ - system: True
+ user.present:
+ - system: True
+ - gid_from_name: True
+ - shell: /sbin/nologin
+ - home: /var/kube-proxy
+ - require:
+ - group: kube-proxy
+
+{% if pillar.get('is_systemd') %}
+
+{{ pillar.get('systemd_system_path') }}/kube-proxy.service:
+ file.managed:
+ - source: salt://kubernetes/files/kube-proxy/kube-proxy.service
+ - user: root
+ - group: root
+ cmd.wait:
+ - name: /opt/kubernetes/helpers/services bounce kube-proxy
+ - watch:
+ - file: {{ environment_file }}
+ - file: {{ pillar.get('systemd_system_path') }}/kube-proxy.service
+ - file: /var/lib/kube-proxy/kubeconfig
+
+{% else %}
+
+/etc/init.d/kube-proxy:
+ file.managed:
+ - source: salt://kubernetes/files/kube-proxy/initd
+ - user: root
+ - group: root
+ - mode: 755
+
+{% endif %}
+
+kube-proxy-service:
+ service.running:
+ - name: kube-proxy
+ - enable: True
+ - watch:
+ - file: {{ environment_file }}
+{% if pillar.get('is_systemd') %}
+ - file: {{ pillar.get('systemd_system_path') }}/kube-proxy.service
+{% else %}
+ - file: /etc/init.d/kube-proxy
+{% endif %}
+ - file: /etc/kubernetes/proxy.kubeconfig
+
+/var/lib/kube-proxy/kubeconfig:
+ file.managed:
+ - source: salt://kubernetes/files/kube-proxy/proxy.kubeconfig
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+
+/etc/kubernetes/manifests/kube-proxy.manifest:
+ file.managed:
+ - source: salt://kubernetes/files/manifest/kube-proxy.manifest
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+ - dir_mode: 755
+
+/var/log/kube-controller-manager.log:
+ file.managed:
+ - user: root
+ - group: root
+ - mode: 644
+
+{% endif %}
\ No newline at end of file
diff --git a/kubernetes/pool/kubelet.sls b/kubernetes/pool/kubelet.sls
new file mode 100644
index 0000000..022efb3
--- /dev/null
+++ b/kubernetes/pool/kubelet.sls
@@ -0,0 +1,86 @@
+{%- from "kubernetes/map.jinja" import pool with context %}
+{%- if pool.enabled %}
+
+{% if pillar.get('is_systemd') %}
+{% set environment_file = '/etc/sysconfig/kubelet' %}
+{% else %}
+{% set environment_file = '/etc/default/kubelet' %}
+{% endif %}
+
+{{ environment_file }}:
+ file.managed:
+ - source: salt://kubernetes/files/kubelet/default.pool
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+
+/usr/local/bin/kubelet:
+ file.managed:
+ - user: root
+ - group: root
+ - mode: 755
+
+/etc/kubernetes/kubelet.kubeconfig:
+ file.managed:
+ - source: salt://kubernetes/files/kubelet/kubelet.kubeconfig
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+
+
+{% if pillar.get('is_systemd') %}
+
+{{ pillar.get('systemd_system_path') }}/kubelet.service:
+ file.managed:
+ - source: salt://kubernetes/files/kubelet/kubelet.service
+ - user: root
+ - group: root
+
+fix-service-kubelet:
+ cmd.wait:
+ - name: /opt/kubernetes/helpers/services bounce kubelet
+ - watch:
+ - file: /usr/local/bin/kubelet
+ - file: {{ pillar.get('systemd_system_path') }}/kubelet.service
+ - file: {{ environment_file }}
+ - file: /var/lib/kubelet/kubeconfig
+
+{% else %}
+
+/etc/init.d/kubelet:
+ file.managed:
+ - source: salt://kubernetes/files/kubelet/initd
+ - user: root
+ - group: root
+ - mode: 755
+
+{% endif %}
+
+/etc/kubernetes/manifests/cadvisor.manifest:
+ file.managed:
+ - source: salt://kubernetes/files/manifest/cadvisor.manifest
+ - user: root
+ - group: root
+ - mode: 644
+ - makedirs: true
+ - template: jinja
+
+kubelet:
+ service.running:
+ - enable: True
+ - watch:
+ - file: /usr/local/bin/kubelet
+{% if pillar.get('is_systemd') %}
+ - file: {{ pillar.get('systemd_system_path') }}/kubelet.service
+{% else %}
+ - file: /etc/init.d/kubelet
+{% endif %}
+{% if grains['os_family'] == 'RedHat' %}
+ - file: /usr/lib/systemd/system/kubelet.service
+{% endif %}
+ - file: {{ environment_file }}
+ - file: /etc/kubernetes/kubelet.kubeconfig
+{%- endif %}
\ No newline at end of file
diff --git a/kubernetes/pool/service.sls b/kubernetes/pool/service.sls
new file mode 100644
index 0000000..c104889
--- /dev/null
+++ b/kubernetes/pool/service.sls
@@ -0,0 +1,18 @@
+{%- from "kubernetes/map.jinja" import pool with context %}
+{%- from "kubernetes/map.jinja" import common with context %}
+{%- if pool.enabled %}
+
+include:
+- kubernetes._common
+
+kubernetes_pool_binaries:
+ cmd.run:
+ - names:
+ - "cp /root/apt.tcpcloud.eu/kubernetes/bin/{{ common.binaries_version }}/kube-proxy /usr/local/bin/"
+ - "cp /root/apt.tcpcloud.eu/kubernetes/bin/{{ common.binaries_version }}/kubectl /usr/bin/"
+ - "cp /root/apt.tcpcloud.eu/kubernetes/bin/{{ common.binaries_version }}/kubelet /usr/local/bin/"
+ - unless: test -f /usr/local/bin/kubelet && test -f /usr/local/bin/kube-proxy && test -f /usr/bin/kubectl
+ - require:
+ - cmd: kubernetes_binaries
+
+{%- endif %}
\ No newline at end of file
diff --git a/metadata/service/common.yml b/metadata/service/common.yml
new file mode 100644
index 0000000..47364d9
--- /dev/null
+++ b/metadata/service/common.yml
@@ -0,0 +1,6 @@
+parameters:
+ kubernetes:
+ common:
+ binaries_version: v1.1.1
+ network:
+ engine: none
\ No newline at end of file
diff --git a/metadata/service/control/cluster.yml b/metadata/service/control/cluster.yml
new file mode 100644
index 0000000..e411788
--- /dev/null
+++ b/metadata/service/control/cluster.yml
@@ -0,0 +1,6 @@
+applications:
+- kubernetes
+parameters:
+ kubernetes:
+ control:
+ enabled: true
\ No newline at end of file
diff --git a/metadata/service/master/cluster.yml b/metadata/service/master/cluster.yml
new file mode 100644
index 0000000..c528ed3
--- /dev/null
+++ b/metadata/service/master/cluster.yml
@@ -0,0 +1,65 @@
+applications:
+- kubernetes
+classes:
+- service.kubernetes.support
+- system.nginx.server.single
+- service.kubernetes.common
+parameters:
+ nginx:
+ server:
+ site:
+ kubernetes_master:
+ enabled: true
+ type: kubernetes
+ name: master
+ host:
+ name: ${_param:nginx_kubernetes_master_host}
+ kubernetes:
+ master:
+ enabled: true
+ version: v1.2.0
+ registry: tcpcloud
+ service_addresses: 10.254.0.0/16
+ admin:
+ username: admin
+ password: password
+ kubelet:
+ allow_privileged: True
+ apiserver:
+ address: ${_param:apiserver_address}
+ port: 8080
+ etcd:
+ host: 10.10.6.187
+ token: ca939ec9c2a17b0786f6d411fe019e9b
+ name: ${linux:system:name}
+ members:
+ - host: ${_param:cluster_node01_address}
+ name: ${_param:cluster_node01_hostname}
+ - host: ${_param:cluster_node02_address}
+ name: ${_param:cluster_node02_hostname}
+ - host: ${_param:cluster_node03_address}
+ name: ${_param:cluster_node03_hostname}
+ addons:
+ dns:
+ enabled: true
+ replicas: 1
+ domain: cluster.local
+ server: 10.254.0.10
+ ui:
+ enabled: true
+ public_ip: 185.22.97.131
+ heapster_influxdb:
+ enabled: true
+ public_ip: 185.22.97.132
+ token:
+ admin: DFvQ8GJ9JD4fKNfuyEddw3rjnFTkUKsv
+ kubelet: 7bN5hJ9JD4fKjnFTkUKsvVNfuyEddw3r
+ kube_proxy: DFvQ8GelB7afH3wClC9romaMPhquyyEe
+ scheduler: HY1UUxEPpmjW4a1dDLGIANYQp1nZkLDk
+ controller_manager: EreGh6AnWf8DxH8cYavB2zS029PUi7vx
+ logging: MJkXKdbgqRmTHSa2ykTaOaMykgO6KcEf
+ monitoring: hnsj0XqABgrSww7Nqo7UVTSZLJUt2XRd
+ dns: RAFeVSE4UvsCz4gk3KYReuOI5jsZ1Xt3
+ ca: kubernetes
+ storage:
+ engine: none
\ No newline at end of file
diff --git a/metadata/service/master/single.yml b/metadata/service/master/single.yml
new file mode 100644
index 0000000..779359f
--- /dev/null
+++ b/metadata/service/master/single.yml
@@ -0,0 +1,61 @@
+applications:
+- kubernetes
+classes:
+- service.kubernetes.support
+- system.nginx.server.single
+- service.kubernetes.common
+parameters:
+ nginx:
+ server:
+ site:
+ kubernetes_master:
+ enabled: true
+ type: kubernetes
+ name: master
+ host:
+ name: ${_param:nginx_kubernetes_master_host}
+ kubernetes:
+ master:
+ enabled: true
+ version: v1.2.0
+ registry: tcpcloud
+ service_addresses: 10.254.0.0/16
+ admin:
+ username: admin
+ password: password
+ kubelet:
+ allow_privileged: True
+ apiserver:
+ address: ${_param:apiserver_address}
+ port: 8080
+ etcd:
+ host: 127.0.0.1
+ token: ca939ec9c2a17b0786f6d411fe019e9b
+ name: ${linux:system:name}
+ members:
+ - host: ${_param:apiserver_address}
+ name: ${linux:system:name}
+ addons:
+ dns:
+ enabled: true
+ replicas: 1
+ domain: cluster.local
+ server: 10.254.0.10
+ ui:
+ enabled: true
+ public_ip: 185.22.97.131
+ heapster_influxdb:
+ enabled: true
+ public_ip: 185.22.97.132
+ token:
+ admin: DFvQ8GJ9JD4fKNfuyEddw3rjnFTkUKsv
+ kubelet: 7bN5hJ9JD4fKjnFTkUKsvVNfuyEddw3r
+ kube_proxy: DFvQ8GelB7afH3wClC9romaMPhquyyEe
+ scheduler: HY1UUxEPpmjW4a1dDLGIANYQp1nZkLDk
+ controller_manager: EreGh6AnWf8DxH8cYavB2zS029PUi7vx
+ logging: MJkXKdbgqRmTHSa2ykTaOaMykgO6KcEf
+ monitoring: hnsj0XqABgrSww7Nqo7UVTSZLJUt2XRd
+ dns: RAFeVSE4UvsCz4gk3KYReuOI5jsZ1Xt3
+ ca: kubernetes
+ storage:
+ engine: none
\ No newline at end of file
diff --git a/metadata/service/pool/cluster.yml b/metadata/service/pool/cluster.yml
new file mode 100644
index 0000000..cebe9fc
--- /dev/null
+++ b/metadata/service/pool/cluster.yml
@@ -0,0 +1,33 @@
+applications:
+- kubernetes
+classes:
+- service.kubernetes.support
+- service.kubernetes.common
+parameters:
+ kubernetes:
+ pool:
+ enabled: true
+ version: v1.2.0
+ master:
+ host: ${_param:cluster_vip_address}
+ apiserver:
+ members:
+ - host: ${_param:cluster_node01_address}
+ - host: ${_param:cluster_node02_address}
+ - host: ${_param:cluster_node03_address}
+ etcd:
+ members:
+ - host: ${_param:cluster_node01_address}
+ - host: ${_param:cluster_node02_address}
+ - host: ${_param:cluster_node03_address}
+ address: 0.0.0.0
+ cluster_dns: 10.254.0.10
+ cluster_domain: cluster.local
+ kubelet:
+ config: /etc/kubernetes/manifests
+ allow_privileged: True
+ frequency: 5s
+ token:
+ kubelet: 7bN5hJ9JD4fKjnFTkUKsvVNfuyEddw3r
+ kube_proxy: DFvQ8GelB7afH3wClC9romaMPhquyyEe
+ ca: kubernetes
\ No newline at end of file
diff --git a/metadata/service/pool/single.yml b/metadata/service/pool/single.yml
new file mode 100644
index 0000000..b219527
--- /dev/null
+++ b/metadata/service/pool/single.yml
@@ -0,0 +1,30 @@
+applications:
+- kubernetes
+classes:
+- service.kubernetes.support
+- service.kubernetes.common
+parameters:
+ kubernetes:
+ pool:
+ enabled: true
+ version: v1.2.0
+ master:
+ host: ${_param:master_address}
+ apiserver:
+ members:
+ - host: ${_param:master_address}
+ etcd:
+ members:
+ - host: ${_param:master_address}
+ address: 0.0.0.0
+ cluster_dns: 10.254.0.10
+ allow_privileged: True
+ cluster_domain: cluster.local
+ kubelet:
+ config: /etc/kubernetes/manifests
+ allow_privileged: True
+ frequency: 5s
+ token:
+ kubelet: 7bN5hJ9JD4fKjnFTkUKsvVNfuyEddw3r
+ kube_proxy: DFvQ8GelB7afH3wClC9romaMPhquyyEe
+ ca: kubernetes
\ No newline at end of file
diff --git a/metadata/service/support.yml b/metadata/service/support.yml
new file mode 100644
index 0000000..661b1cf
--- /dev/null
+++ b/metadata/service/support.yml
@@ -0,0 +1,11 @@
+parameters:
+ kubernetes:
+ _support:
+ collectd:
+ enabled: false
+ heka:
+ enabled: false
+ sensu:
+ enabled: false
+ sphinx:
+ enabled: true