Giter VIP home page Giter VIP logo

kubeadm-workshop's Introduction

Workshop:

Building a multi-platform Kubernetes cluster on bare metal with kubeadm

Hi and welcome to this tutorial and demonstration of how to build a bare-metal Kubernetes cluster with kubeadm!

I'm one of the main kubeadm developers and very excited about bare metal as well, so I thought showing some of the things you can do with Kubernetes/kubeadm would be a great fit!

This workshop is a part of my talk at KubeCon Berlin: Autoscaling a Multi-Platform Kubernetes Cluster Built with kubeadm [I] - Lucas Käldström - YouTube

My slides for the presentation are here: http://slides.com/lucask/kubecon-berlin

Highligts

  • Showcases what you can do on bare-metal, even behind a firewall with no public IP address
  • Demonstrates usage of cutting-edge technologies like Persistent Storage running on-cluster, Autoscaling based on Custom Metrics and Aggregated API Servers

What's more, the Kubernetes yaml manifests included in this repository are multi-architecture and works on ARM, both 32- and 64-bit!

My own setup at home consists of this hardware:

  • 2x Up Board, 4 cores @ 1.44 GHz, 2 GB RAM, 1 GbE, 16 GB eMMc, amd64, Link
  • 2x Odroid C2, 4 cores @ 1.5 GHz, 2 GB RAM, 1 GbE, 16 GB eMMc, arm64, Link
  • 3x Raspberry Pi, 4 cores @ 1.2 GHz, 1 GB RAM, 100 MbE, 16 GB SD Card, arm/arm64, Link

Picture of the cluster

So, no more smalltalk then, let's dive right in!

Contents

This workshop is divided into these parts:

  • Installing kubeadm on all the machines you want in your cluster
  • Setting up your Kubernetes master
  • Setting up the worker nodes
  • Deploying the Pod networking layer
  • Deploying the Dashboard and Heapster
  • Deploying an Ingress Controller for exposing HTTP services
  • Deploying a persistent storage layer on top of Kubernetes with Rook
  • Deploying InfluxDB and Grafana for storing and visualizing CPU and memory metrics
  • Deploying a extension API Server for extending the Kubernetes API
  • Deploying the Prometheus Operator for monitoring Pods in the cluster
  • Deploying a sample custom metrics API Server
  • Deploying and autoscaling a sample node.js application based on custom metrics

Installing kubeadm on all the machines you want in your cluster

WARNING: This workshop uses alpha technologies in order to be on the edge and Kubernetes can't be upgraded. This means the features used and demonstrated here might work differently in v1.7 and backwards-compability isn't guaranteed in any way

Note: The first part that describes how to install kubeadm is just copied from the official kubeadm documentation

Note: It's expected that you have basic knowledge about how Kubernetes and kubeadm work, because quite advanced concepts are covered in this workshop.

Note: This guide has been tested on Ubuntu Xenial, Yakkety and Zesty

You can install kubeadm easily this way:

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF > /etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get update
apt-get install -y docker.io kubeadm

You should do this on all machines you're planning to include in your cluster, and these commands are exactly the same regardless on which architecture you are on.

Setting up your Kubernetes master

SSH into your master node, and switch to the root account of the machine or use sudo everywhere below.

As mentioned earlier, experimental features of different kinds will be used in this tutorial to show off the latest and greatest features in Kubernetes.

kubeadm for example, can take options from a configuration file in order to be customized easily. But the API exposed right now is not stable, and under heavy development. So this will definitely change (to the better) in time for v1.7.

The configuration file we'll use here looks like this in kubeadm.yaml:

kind: MasterConfiguration
apiVersion: kubeadm.k8s.io/v1alpha1
controllerManagerExtraArgs:
  horizontal-pod-autoscaler-use-rest-clients: "true"
  horizontal-pod-autoscaler-sync-period: "10s"
  node-monitor-grace-period: "10s"
apiServerExtraArgs:
  runtime-config: "api/all=true"
kubernetesVersion: "stable-1.8"

A brief walkthrough what the statements mean:

  • horizontal-pod-autoscaler-use-rest-clients: "true" tells the controller manager to look for the custom metrics API

You can now go ahead and initialize the master node with this command (assuming you're root, append sudo if not):

$ kubeadm init --config kubeadm.yaml

Make sure you got kubeadm v1.8.0-beta.1 or higher and docker 1.12.x. In order to control your cluster securely, you need to specify the KUBECONFIG variable to kubectl knows where to look for the admin credentials. Here is an example how to do it as a regular user.

sudo cp /etc/kubernetes/admin.conf $HOME/
sudo chown $(id -u):$(id -g) $HOME/admin.conf
export KUBECONFIG=$HOME/admin.conf

Make the kube-proxy DaemonSet multi-platform

Since kube-proxy runs in a DaemonSet, it will be scheduled on all nodes. By default, an image with the architecture that kubeadm init is run on is used in the DaemonSet, so if you ran kubeadm init on an arm64 image, the kube-proxy image with be gcr.io/google_containers/kube-proxy-arm64.

To make it possible to add nodes with other architectures we have to switch the image to a manifest list like this. First, make the DaemonSet, rolling-upgradeable and then change the image to a manifest list.

$ kubectl -n kube-system set image daemonset/kube-proxy kube-proxy=luxas/kube-proxy:v1.8.0-beta.1

With those two commands, kube-proxy will come up successfully on whatever node you bring to your cluster.

Deploying the Pod networking layer

The networking layer in Kubernetes is extensible, and you may pick the networking solution that fits you the best. I've tested this with Weave Net, but it should work with any other compliant provider.

Here's how to use Weave Net as the networking provider the really easy way:

$ kubectl apply -f https://git.io/weave-kube-1.6

OR you can run these two commands if you want to encrypt the communication between nodes:

$ kubectl create secret -n kube-system generic weave-passwd --from-literal=weave-passwd=$(hexdump -n 16 -e '4/4 "%08x" 1 "\n"' /dev/random)
$ kubectl apply -n kube-system -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')&password-secret=weave-passwd"

Setting up the worker nodes

kubeadm init above will print out a kubeadm join command for you to paste for joining the other nodes in your cluster to the master.

Note: Make sure you join all nodes before you arch-taint the nodes (if you do)!

$ kubeadm join --token <token> <master-ip>:<master-port>

Taints and tolerations

Taints and Tolerations is a concept of dedicated nodes. Simply put, if you taint a node with a key/value pair and the effect NoSchedule, it will reject all Pods that don't have the same key/value set in the Tolerations field of the PodSpec.

By default, the master is tainted with the node-role.kubernetes.io="" key/value pair which will make it only allow the kube-dns Deployment, the kube-proxy DaemonSet and most often the CNI network provider's DaemonSet, because they have the toleration.

In case you only have one node available for testing and want to run normal workloads on the master as well (allow all workloads on the master), run this command:

$ kubectl taint nodes --all node-role.kubernetes.io/master-

In order to make the default architecture amd64, and you know you might deploy workloads that aren't multi-platform, it's best to taint the "special" nodes of an other architecture and explicitely tolerate ARM (32- and 64-bit) on the workloads that support it.

You can taint your arm and arm64 nodes with these commands:

$ kubectl taint node <arm nodes> beta.kubernetes.io/arch=arm:NoSchedule
$ kubectl taint node <arm64 nodes> beta.kubernetes.io/arch=arm64:NoSchedule

Deploying the Dashboard and Heapster

I really like visualizing the cluster resources in the Kubernetes Dashboard (although I'm mostly a CLI guy).

You can install the dashboard with this command:

$ curl -sSL https://git.io/kube-dashboard | sed "s|image:.*|image: luxas/kubernetes-dashboard:v1.6.3|" | kubectl apply -f -
serviceaccount "dashboard" created
clusterrolebinding "dashboard-admin" created
deployment "kubernetes-dashboard" created
service "kubernetes-dashboard" created

You probably want some monitoring as well, if you install Heapster you can easily keep track of the CPU and memory usage in your cluster. Those stats will also be shown in the dashboard!

$ kubectl apply -f demos/monitoring/heapster.yaml
serviceaccount "heapster" created
clusterrolebinding "heapster" created
deployment "heapster" created
service "heapster" created

You should now see some Services in the kube-system namespace:

$ kubectl -n kube-system get svc
NAME                   CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
heapster               10.104.142.79   <none>        80/TCP          5s
kube-dns               10.96.0.10      <none>        53/UDP,53/TCP   42s
kubernetes-dashboard   10.97.73.205    <none>        80/TCP          11s

After heapster is up and running (check with kubectl -n kube-system get pods), you should be able to see the CPU and memory usage of the nodes in the cluster and for individual Pods:

$ kubectl top nodes
NAME        CPU(cores)   CPU%      MEMORY(bytes)   MEMORY%
test-node   131m         1%        9130Mi          30%

Deploying an Ingress Controller for exposing HTTP services

Now that you have created the dashboard and heapster Deployments and Services, how can you access them?

One solution might be making your Services of the NodePort type, but that's not a good long-term solution.

Instead, there is the Ingress object in Kubernetes that let's you create rules for how Services in your cluster should be exposed to the world. Before one can create Ingress rules, you need a Ingress Controller that watches for rules, applies them and forwards requests as specified.

One Ingress Controller provider is Traefik, and I'm using that one here.

In this demo I go a step further. Normally in order to expose your app you have locally to the internet requires that one of your machines has a public Internet address. We can workaround this very smoothly in a Kubernetes cluster by letting Ngrok forward requests from a public subdomain of ngrok.io to the Traefik Ingress Controller that's running in our cluster.

Using ngrok here is perfect for hybrid clusters where you have no control over the network you're connected to... you just have internet access. Also, this method is can be used in nearly any environment and will behave the same. But for production deployments (which we aren't dealing with here), you should of course expose a real loadbalancer node with a public IP.

$ kubectl apply -f demos/loadbalancing/traefik-common.yaml
clusterrole "traefik-ingress-controller" created
serviceaccount "traefik-ingress-controller" created
clusterrolebinding "traefik-ingress-controller" created
configmap "traefik-cfg" created

$ kubectl apply -f demos/loadbalancing/traefik-ngrok.yaml
deployment "traefik-ingress-controller" created
service "traefik-ingress-controller" created
service "traefik-web" created
configmap "ngrok-cfg" created
deployment "ngrok" created
service "ngrok" created

$ curl -sSL $(kubectl -n kube-system get svc ngrok -o template --template "{{.spec.clusterIP}}")/api/tunnels | jq  ".tunnels[].public_url" | sed 's/"//g;/http:/d'
https://foobarxyz.ngrok.io

You can now try to access the ngrok URL that got outputted by the above command. It first ask you for a password, then return 404 due to the absence of Ingress rules.

Authenticate to Traefik

404 with no Ingress rules

Let's change that by creating an Ingress rule!

Exposing the Dashboard via the Ingress Controller

We want to expose the dashboard to our newly-created public URL, under the /dashboard path.

That's easily achievable using this command:

$ kubectl apply -f demos/dashboard/ingress.yaml
ingress "kubernetes-dashboard" created

The Traefik Ingress Controller is set up to require basic auth before one can access the services.

I've set the username to kubernetes and the password to rocks!. You can obviously change this if you want by editing the traefik-common.yaml before deploying the Ingress Controller.

When you've signed in to https://{ngrok url}/dashboard/ (note the / in the end, it's required), you'll see a dashboard like this:

The Kubernetes Dashboard

Deploying a persistent storage layer on top of Kubernetes with Rook

Stateless services are cool, but deploying stateful applications on your Kubernetes cluster is even more fun.

For that you need somewhere to store persistent data, and that's not easy to achieve on bare metal. Rook is a promising project aiming to solve this by building a Kubernetes integration layer upon the battle-tested Ceph storage solution.

Rook is using ThirdPartyResources for knowing how to set up your storage solution, and has an operator that is listening for these TPRs.

Here is how to create a default Rook cluster by deploying the operator, a controller that will listen for PersistentVolumeClaims that need binding, a Rook Cluster ThirdPartyResource and finally a StorageClass.

$ kubectl apply -f https://raw.githubusercontent.com/rook/rook/release-0.5/cluster/examples/kubernetes/rook-operator.yaml
clusterrole "rook-operator" created
serviceaccount "rook-operator" created
clusterrolebinding "rook-operator" created
deployment "rook-operator" created

$ kubectl apply -f https://raw.githubusercontent.com/rook/rook/release-0.5/cluster/examples/kubernetes/rook-cluster.yaml
cluster "my-rook" created

$ kubectl apply -f https://raw.githubusercontent.com/rook/rook/release-0.5/cluster/examples/kubernetes/rook-storageclass.yaml
pool "replicapool" created
storageclass "rook-block" created

$ # Repeat this step for all namespaces you want to deploy PersistentVolumes with Rook in
$ kubectl get secret rook-rook-user -oyaml | sed "/resourceVer/d;/uid/d;/self/d;/creat/d;/namespace/d" | kubectl -n kube-system apply -f -
secret "rook-rook-user" created

$ # In order to make Rook the default Storage Provider by making the `rook-block` Storage Class the default, run this:
$ kubectl patch storageclass rook-block -p '{"metadata":{"annotations": {"storageclass.kubernetes.io/is-default-class": "true"}}}'
storageclass "rook-block" patched

$ apt-get update && apt-get install ceph-common -y

One limitation with v0.3.0 is that you can't control to which namespaces the rook authentication Secret should be deployed, so if you want to create PersistentVolumes in an other namespace than default, run the above kubectl command.

Deploying InfluxDB and Grafana for storing and visualizing CPU and memory metrics

Now that we have got persistent storage in our cluster, we can deploy some stateful services. For example, we can store monitoring data aggregated by Heapster in an InfluxDB database and visualize that data with a Grafana dashboard.

You must do this if you want to gather CPU/memory data from Heapster for a longer time, by default heapster just saves data from the latest couple of minutes.

$ kubectl apply -f demos/monitoring/influx-grafana.yaml
persistentvolumeclaim "grafana-pv-claim" created
persistentvolumeclaim "influxdb-pv-claim" created
deployment "monitoring-grafana" created
service "monitoring-grafana" created
deployment "monitoring-influxdb" created
service "monitoring-influxdb" created
ingress "monitoring-grafana" created

Note that an Ingress rule was created for Grafana automatically. You can access your Grafana instance at the https://{ngrok url}/grafana/ URL.

Grafana dashboard

Sample API Server

The core API Server is great, but what about if you want to write your own, extended API server that contains more high-level features that build on top of Kubernetes but still be able to control those high-level features from kubectl? This is now possible using the API Aggregation feature that will make it into beta in v1.7

First, let's check which API groups are available normally:

$ kubectl api-versions
apiregistration.k8s.io/v1beta1
apps/v1beta1
authentication.k8s.io/v1
authentication.k8s.io/v1beta1
authorization.k8s.io/v1
authorization.k8s.io/v1beta1
autoscaling/v1
autoscaling/v2alpha1
batch/v1
batch/v2alpha1
certificates.k8s.io/v1beta1
extensions/v1beta1
policy/v1beta1
rbac.authorization.k8s.io/v1alpha1
rbac.authorization.k8s.io/v1beta1
rook.io/v1beta1
settings.k8s.io/v1alpha1
storage.k8s.io/v1
storage.k8s.io/v1beta1
v1

It's pretty straightforward to write your own API server now with the break-out of k8s.io/apiserver. The sig-api-machinery team has also given us a sample implementation: k8s.io/sample-apiserver.

The sample API Server called wardle, contains one API group: wardle.k8s.io/v1alpha1 and one API resource in that group: Flunder This guide shows how easy it will be to extend the Kubernetes API in the future.

The sample API Server saves its data to a separate etcd instance running in-cluster. Notice the PersistentVolume that is created for etcd for that purpose. Note that in the future, the etcd Operator should probably be used for running etcd instead of running it manually like now.

$ kubectl apply -f demos/sample-apiserver/wardle.yaml
namespace "wardle" created
persistentvolumeclaim "etcd-pv-claim" created
serviceaccount "apiserver" created
clusterrolebinding "wardle:system:auth-delegator" created
rolebinding "wardle-auth-reader" created
deployment "wardle-apiserver" created
service "api" created
apiservice "v1alpha1.wardle.k8s.io" created

$ kubectl get secret rook-rook-user -oyaml | sed "/resourceVer/d;/uid/d;/self/d;/creat/d;/namespace/d" | kubectl -n wardle apply -f -
secret "rook-rook-user" created

After a few minutes, when the extended API server is up and running, kubectl will auto-discover that API group and it will be possible to create, list and delete Flunder objects just as any other API object.

$ kubectl api-versions
apiregistration.k8s.io/v1beta1
apps/v1beta1
authentication.k8s.io/v1
authentication.k8s.io/v1beta1
authorization.k8s.io/v1
authorization.k8s.io/v1beta1
autoscaling/v1
autoscaling/v2alpha1
batch/v1
batch/v2alpha1
certificates.k8s.io/v1beta1
extensions/v1beta1
policy/v1beta1
rbac.authorization.k8s.io/v1alpha1
rbac.authorization.k8s.io/v1beta1
rook.io/v1beta1
settings.k8s.io/v1alpha1
storage.k8s.io/v1
storage.k8s.io/v1beta1
v1
***wardle.k8s.io/v1alpha1***

$ # There is no foobarbaz resource, but the flunders resource does now exist
$ kubectl get foobarbaz
the server doesn't have a resource type "foobarbaz"

$ kubectl get flunders
No resources found.

$ kubectl apply -f demos/sample-apiserver/my-flunder.yaml
flunder "my-first-flunder" created

If you want to make sure this is real, you can check the etcd database running in-cluster with this command:

$ kubectl -n wardle exec -it $(kubectl -n wardle get po -l app=wardle-apiserver -otemplate --template "{{ (index .items 0).metadata.name}}") -c etcd /bin/sh -- -c "ETCDCTL_API=3 etcdctl get /registry/wardle.kubernetes.io/registry/wardle.kubernetes.io/wardle.k8s.io/flunders/my-first-flunder" | grep -v /registry/wardle | jq .
{
  "kind": "Flunder",
  "apiVersion": "wardle.k8s.io/v1alpha1",
  "metadata": {
    "name": "my-first-flunder",
    "uid": "bef75e16-2c5b-11e7-999c-1602732a5d02",
    "creationTimestamp": "2017-04-28T21:43:41Z",
    "labels": {
      "sample-label": "true"
    },
    "annotations": {
      "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"wardle.k8s.io/v1alpha1\",\"kind\":\"Flunder\",\"metadata\":{\"annotations\":{},\"labels\":{\"sample-label\":\"true\"},\"name\":\"my-first-flunder\",\"namespace\":\"default\"}}\n"
    }
  },
  "spec": {},
  "status": {}
}

Conclusion, the Flunder object we created was saved in the separate etcd instance!

Deploying the Prometheus Operator for monitoring Services in the cluster

Prometheus is a great monitoring solution, and combining it with Kubernetes makes it even more awesome.

These commands will first deploy the Prometheus operator as well as one Prometheus instance by creating a Prometheus ThirdPartyResource.

A lightweight nodejs application is deployed as well, which exports the http_requests_total metric at /metrics. A ServiceMonitor ThirdPartyResource is created that match the sample metrics app by the app=sample-metrics-app label.

The ServiceMonitor will make the Prometheus instance scrape metrics from the sample metrics web app.

You can access the Prometheus web UI via the NodePort or the internal Service.

$ kubectl apply -f demos/monitoring/prometheus-operator.yaml
clusterrole "prometheus-operator" created
serviceaccount "prometheus-operator" created
clusterrolebinding "prometheus-operator" created
deployment "prometheus-operator" created

$ kubectl apply -f demos/monitoring/sample-prometheus-instance.yaml
clusterrole "prometheus" created
serviceaccount "prometheus" created
clusterrolebinding "prometheus" created
prometheus "sample-metrics-prom" created
service "sample-metrics-prom" created

$ kubectl get svc
NAME                  CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes            10.96.0.1       <none>        443/TCP          30m
prometheus-operated   None            <none>        9090/TCP         4m
sample-metrics-prom   10.108.71.184   <nodes>       9090:30999/TCP   4m

Deploying a custom metrics API Server and a sample app

In v1.6, the Horizontal Pod Autoscaler controller can now consume custom metrics for autoscaling. For this to work, one needs to have enabled the autoscaling/v2alpha1 API group which makes it possible to create Horizontal Pod Autoscaler resources of the new version.

Also, one must have API aggregation enabled (which is the case in this demo) and a extension API Server that provides the custom-metrics.metrics.k8s.io/v1alpha1 API group/version.

There won't be an "official" one-size-fits all custom metrics API server, instead there will be a boilerplate people can use as the base for creating custom monitoring solutions.

I've built an example custom metrics server that queries a Prometheus instance for metrics data and exposing them in the custom metrics Kubernetes API. You can think of this custom metrics server as a shim/conversation layer between Prometheus data and the Horizontal Pod Autoscaling API for Kubernetes.

Here is a diagram over how this works on a high level:

Custom Metrics Architecture

You can also read the full custom metrics API proposal here

$ kubectl apply -f demos/monitoring/custom-metrics.yaml
namespace "custom-metrics" created
serviceaccount "custom-metrics-apiserver" created
clusterrolebinding "custom-metrics:system:auth-delegator" created
rolebinding "custom-metrics-auth-reader" created
clusterrole "custom-metrics-read" created
clusterrolebinding "custom-metrics-read" created
deployment "custom-metrics-apiserver" created
service "api" created
apiservice "v1alpha1.custom-metrics.metrics.k8s.io" created
clusterrole "custom-metrics-server-resources" created
clusterrolebinding "hpa-controller-custom-metrics" created

If you want to be able to curl the custom metrics API server easily (i.e. allow anyone to access the Custom Metrics API), you can run this kubectl command:

$ kubectl create clusterrolebinding allowall-cm --clusterrole custom-metrics-server-resources --user system:anonymous
clusterrolebinding "allowall-cm" created
$ kubectl apply -f demos/monitoring/sample-metrics-app.yaml
deployment "sample-metrics-app" created
service "sample-metrics-app" created
servicemonitor "sample-metrics-app" created
horizontalpodautoscaler "sample-metrics-app-hpa" created
ingress "sample-metrics-app" created

Now that we have our sample app, we should generate some load against it! If you don't have rakyll's excellent hey load generator already, you can install it this way:

$ # Install hey
$ docker run -it -v /usr/local/bin:/go/bin golang:1.8 go get github.com/rakyll/hey

$ export APP_ENDPOINT=$(kubectl get svc sample-metrics-app -o template --template {{.spec.clusterIP}}); echo ${APP_ENDPOINT}
$ hey -n 50000 -c 1000 http://${APP_ENDPOINT}

Then you can go and check out the Custom Metrics API, it should notice that a lot of requests have been served recently.

$ curl -sSLk https://10.96.0.1/apis/custom-metrics.metrics.k8s.io/v1alpha1/namespaces/default/services/sample-metrics-app/http_requests
{
  "kind": "MetricValueList",
  "apiVersion": "custom-metrics.metrics.k8s.io/v1alpha1",
  "metadata": {
    "selfLink": "/apis/custom-metrics.metrics.k8s.io/v1alpha1/namespaces/default/services/sample-metrics-app/http_requests"
  },
  "items": [
    {
      "describedObject": {
        "kind": "Service",
        "name": "sample-metrics-app",
        "apiVersion": "/__internal"
      },
      "metricName": "http_requests",
      "timestamp": "2017-06-30T20:56:34Z",
      "value": "501484m"
    }
  ]
}

You can query custom metrics for individual Pods as well:

$ kubectl get po
NAME                                  READY     STATUS    RESTARTS   AGE
prometheus-operator-815607840-zknhk   1/1       Running   0          38m
prometheus-sample-metrics-prom-0      2/2       Running   0          33m
rook-operator-3393217773-sglsv        1/1       Running   0          28m
sample-metrics-app-3083280453-3hbd8   1/1       Running   0          33m
sample-metrics-app-3083280453-fbds8   1/1       Running   0          1m


$ curl -sSLk https://10.96.0.1/apis/custom-metrics.metrics.k8s.io/v1alpha1/namespaces/default/pods/sample-metrics-app-3083280453-3hbd8/http_requests
{
  "kind": "MetricValueList",
  "apiVersion": "custom-metrics.metrics.k8s.io/v1alpha1",
  "metadata": {
    "selfLink": "/apis/custom-metrics.metrics.k8s.io/v1alpha1/namespaces/default/pods/sample-metrics-app-3083280453-3hbd8/http_requests"
  },
  "items": [
    {
      "describedObject": {
        "kind": "Pod",
        "name": "sample-metrics-app-3083280453-3hbd8",
        "apiVersion": "/__internal"
      },
      "metricName": "http_requests",
      "timestamp": "2017-06-30T21:00:46Z",
      "value": "433m"
    }
  ]
}

Install helm

Helm is a package manager for applications running on top of Kubernetes. You can read more about Helm in the official repository, for now we're just gonna install it.

Below you'll see the famous curl | bash pattern for installing an application, and yes, I know it's discouraged. But I'm doing it this way here to keep the tutorial short and concise, hardening the helm installation is left as an excercise to the user.

Then we're running helm init that will deploy its server side component and set up local cache at ~/.helm. Make sure the KUBECONFIG environment variable is set to point to the kubeconfig file for your kubeadm cluster.

$ curl -sSL https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash
$ helm init

tiller is the server-side component of the Helm ecosystem, and handles installation, upgrades and more. By default in version v2.3.x, helm init installs tiller without any RBAC privileges. This means tiller won't be able to install any apps unless we give it some RBAC permissions. However, knowing what tiller is gonna install for the user in beforehand is very hard, so the only way to make it work in all cases is to give it full privileges (root access) to the cluster. We're doing this by binding the tiller ServiceAccount here to the very powerful cluster-admin ClusterRole.

$ kubectl -n kube-system create serviceaccount tiller
$ kubectl -n kube-system patch deploy tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccountName":"tiller"}}}}'
$ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount kube-system:tiller
$ kubectl -n kube-system set image deploy/tiller-deploy tiller=luxas/tiller:v2.5.1

Deploying the Service Catalog

The Service Catalog Kubernetes project is super-interesting and promising.

If you're interested in the concept, watch these two KubeCon talks:

  • Steward, the Kubernetes-Native Service Broker [A] - Gabe Monroy, Deis: Youtube video
  • The Open Service Broker API and the Kubernetes Service Catalog [B] - Paul Morie & Chip Childers: Youtube video

Anyway, here's how to install the Service Catalog on your kubeadm cluster:

$ git clone https://github.com/luxas/service-catalog -b workshop
$ # First install the Service Catalog API Server and Controller Manager and then a sample Broker
$ helm install service-catalog/charts/catalog --name catalog --namespace catalog
$ helm install service-catalog/charts/ups-broker --name ups-broker --namespace ups-broker

I highly recommend this Service Catalog Walkthough.

TL;DR; Now that our Service Catalog API Server is there, we can kubectl get the resources:

$ kubectl get instances,bindings,serviceclasses,brokers
...

You can for example make an Instance and a Binding to the sample ups-broker you installed above like this:

$ kubectl apply -f demos/service-catalog/example.yaml
namespace "test-ns" created
instance "ups-instance" created
brinding "ups-binding" created

$ # Since the binding referenced a new Secret called "my-secret", the Service Catalog should now have created it for you:
$ kubectl -n test-ns get secret my-secret
TODO

Manifest list images

All the source for building the images used in this demo is available under images/.

You simply need to cd into the directory and run REGISTRY=foo make push, setting the REGISTRY variable to your Docker Hub account for example, where you have push rights.

All pushed images follow the pattern REGISTRY/IMAGE-ARCH:VERSION plus a manifest list of the form REGISTRY/IMAGE:VERSION that references to the architecture-specific images.

Currently, images are pushed for amd64, arm and arm64.

Acknowledgements / More reference

I'd like to thank some people that have been very helpful to me while putting together this workshop.

David Eads (@deads2k) has been very helpful to me and answered my questions about API aggregation, RBAC, etc..

Solly Ross (@DirectXMan12) has worked on the custom metrics API and helped me quickly understand the essential parts of it. He also uploaded a custom metrics API Server boilerplate which I've used as the base for my custom metrics implementation.

Also, these I want to thank the maintainers of the great projects below. Let's be grateful for all the really nice projects that are open sourced on Github.

Prometheus Operator by CoreOS: The Prometheus is an integral part of the custom metrics service in this workshop, it made it super-easy to create managed Prometheus instances with the TPR!

Prometheus by CNCF: Some projects are just rock-solid. The Prometheus core is such a project. Monitoring made available for everyone, simply.

Rook by Quantum: Rook is a very interesting and promising project and I'm excited to see how this project can be brought into something stable and reliable in the future.

Traefik by Containous: Traefik is a powerful loadbalancer, and I love the Kubernetes integration it has. Also, with the Prometheus exporter integration in v1.2, it got even cooler.

Weave by Weaveworks: Weave is a distributed networking system that plays very well with Kubernetes, it also is CNI-compliant, which is a good thing.

Future work / contributing

This workshop uses my own custom-built images under the luxas Docker Hub user. This is only a temporary solution while I carry patches I had to make in order to get it working, I will work to upstream these changes eventually though.

Feel free to contribute and help me improve things here and I'd be very thankful ;)

I use the Github tracker for tracking the improvements I want to make to this repository

License

MIT

kubeadm-workshop's People

Stargazers

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

Watchers

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

kubeadm-workshop's Issues

Add short explanation why special hyperkube image is required

From the workshop document:

KUBE_HYPERKUBE_IMAGE=luxas/hyperkube:v1.6.0-kubeadm-workshop-2 kubeadm init --config kubeadm.yaml

Just curious why a special hyperkube is required and how does it differ from the plain hyperkube. Would be awesome if one or two sentences could be added explaining the difference. (I'm asking because I'm currently on the way to update https://github.com/Project31/ansible-kubernetes-openshift-pi3 for the latest kubeadm awesomeness ;-)

Image pull backoff kube-proxy

Thanks for the detailed workshop writeup.

I get an error for the kube-proxy image after these steps:

kubectl -n kube-system set image daemonset/kube-proxy kube-proxy=luxas/kube-proxy:v1.7.0-beta.1

kube-system   etcd-shazdell                      1/1       Running            3          1h
kube-system   kube-apiserver-shazdell            1/1       Running            3          1h
kube-system   kube-controller-manager-shazdell   1/1       Running            3          1h
kube-system   kube-dns-3832805406-lnd0m          0/3       Pending            0          1h
kube-system   kube-proxy-p6551                   0/1       ImagePullBackOff   0          50m
kube-system   kube-scheduler-shazdell            1/1       Running            3          1h

timeout for kubectl top nodes

could you please help me to see why it is timeout to run top nodes?

thanks

ubuntu@kubernetes-1:~/kubeadm-workshop/demos/loadbalancing$ kubectl -n kube-system get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
elasticsearch 10.105.139.213 9200/TCP 13h
heapster 10.102.145.188 80/TCP 1h
kibana 10.107.223.233 5601:31601/TCP 13h
kube-dns 10.96.0.10 53/UDP,53/TCP 21h
kubernetes-dashboard 10.99.5.191 80:30006/TCP 7h
monitoring-influxdb 10.109.34.172 8086/TCP 1h
weave-scope-app 10.98.112.99 80:30005/TCP 7h

ubuntu@kubernetes-1:~/kubeadm-workshop/demos/loadbalancing$ kubectl -n kube-system get po
NAME READY STATUS RESTARTS AGE
elasticsearch-3501859570-tftrz 1/1 Running 0 13h
etcd-kubernetes-1 1/1 Running 1 21h
fluentd-gpnkj 1/1 Running 83 13h
fluentd-j6r9h 1/1 Running 1 13h
heapster-57121549-gq72j 1/1 Running 0 1h
kibana-3301510243-5zgd3 1/1 Running 0 13h
kube-apiserver-kubernetes-1 1/1 Running 0 21h
kube-controller-manager-kubernetes-1 1/1 Running 0 21h
kube-dns-692378583-tnz59 3/3 Running 0 21h
kube-flannel-ds-680qc 2/2 Running 2 13h
kube-flannel-ds-flm3p 2/2 Running 0 13h
kube-flannel-ds-v5j8d 2/2 Running 0 21h
kube-proxy-6tsn9 1/1 Running 0 13h
kube-proxy-f3g0b 1/1 Running 0 21h
kube-proxy-h018q 1/1 Running 0 13h
kube-scheduler-kubernetes-1 1/1 Running 0 21h
kubernetes-dashboard-2039414953-129cd 1/1 Running 0 7h
monitoring-influxdb-3480804314-9z3zz 1/1 Running 0 1h
weave-scope-agent-1d6w2 1/1 Running 0 7h
weave-scope-agent-1jwd7 1/1 Running 0 7h
weave-scope-agent-kq7zd 1/1 Running 0 7h
weave-scope-app-879505699-h03l6 1/1 Running 0 7h

ubuntu@kubernetes-1:~/kubeadm-workshop/demos/monitoring$ kubectl top nodes --heapster-port=80
Error from server (ServerTimeout): the server cannot complete the requested operation at this time, try again later (get services http:heapster:80)

I do not see custom-metrics-apiserver pod

Hi @luxas,
I am following the sample provided @ https://docs.bitnami.com/kubernetes/how-to/configure-autoscaling-custom-metrics/ to try horizontal scaling of pods. During the creation of custom API server when I do "kubectl create -f custom-metrics.yaml", I see that the custom service is deployed. But I do not see the pod corresponding to it. Is there a step I am missing?

kubectl create -f custom-metrics.yaml --show-all=true
namespace "custom-metrics" created
serviceaccount "custom-metrics-apiserver" created
clusterrolebinding "custom-metrics:system:auth-delegator" created
rolebinding "custom-metrics-auth-reader" created
clusterrole "custom-metrics-read" created
clusterrolebinding "custom-metrics-read" created
deployment "custom-metrics-apiserver" created
service "api" created
apiservice "v1alpha1.custom-metrics.metrics.k8s.io" created
clusterrole "custom-metrics-server-resources" created
clusterrolebinding "hpa-controller-custom-metrics" created

kubectl get pods -n custom-metrics
No resources found.

Location of custom metrics yaml https://github.com/kubeless/kubeless/blob/master/manifests/autoscaling/custom-metrics.yaml

Outdated guide in README.md

Current guide does not result in working cluster.

Dashboard install instructions not current (can fix by using "offical" arm installation of kubernetes-dashboard-arm).
No "heapster.yaml" in demos folder. Seems to be deprecated in current repo, but instructions still reference.

Readme links to 404 of custom metrics API.

The readme contains a link referencing to a 404, probably an old link:

A brief walkthrough what the statements mean:

horizontal-pod-autoscaler-use-rest-clients: "true" tells the controller manager to look for the custom metrics API

It's linking to https://github.com/kubernetes/community/blob/master/contributors/design-proposals/custom-metrics-api.md, which doesn't exist anymore.

I think the new link should be https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/custom-metrics-api.md, with the instrumentation folder added in the link.

Stuck in initializing part

Hi!I have read the "kubernetes-on-arm" I am stuck at initialize the master node . After I use the command "kubeadm init ". Every time the initialize process will stuck at "[apiclient] Created API client, waiting for the control plane to become ready" . Would anyone have solution or in a same condition and how could it be solved?

Add example usage of plain CNI usage with kubeadm on GCE

In combination with the cloud-controller-manager that handles the cloudy stuff, the networking should be a plain CNI bridge; set by a DaemonSet that drops the following file in /etc/cni/net.d on every node.

Since the kubenet->plain CNI stuff is proceeding, I want to test out how close we are using CNI-only (without the kubenet bells and whistles) on a cloud env like GCE.

I think the CNI spec will look something like this:

{
    "cniVersion": "0.2.0",
    "name": "gcenet",
    "type": "bridge",
    "mtu": 1460,
    "bridge": "cni0",
    "isGateway": true,
    "isDefaultGateway": true,
    "ipMasq": false,
    "hairpinMode": false,
    "ipam": {
        "type": "host-local",
        "subnet": "${bridge-cidr}"
    }
}

(shamelessly inspired from @jbeda's project here: https://github.com/jbeda/kubeadm-gce-tf/blob/master/tf-scripts/prereq.sh#L46 😄)

Can I get the source code of images:luxas/autoscale-demo:v0.1.2

In kubeadm-workshop/demos/monitoring/sample-metrics-app.yaml, the images for deployment sample-metrics-app deploying for.
I'm writing my own custom metrics API server. I had deployed the sample-metrics-app in my cluster and its custom metrics(http_requests) worked, so I want to figure out how to implement it. Can I get the source code of images:luxas/autoscale-demo:v0.1.2 ? Thanks!

Autoscale based on node metrics exposed to Prometheus by Node exporter

I am trying to access the values of node metrics (exposed by node exporter to Prometheus) in custom metrics API which appear e.g. jobs.batch/node_memory_MemTotal. But when I do kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/batch.jobs/node_memory_MemTotal" | jq . I get Error from server (NotFound): the server could not find the requested resource

custom autoscaler not working

✗ kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1/namespaces/default/services/sample-metrics-app/http_requests | jq
{
  "kind": "MetricValueList",
  "apiVersion": "custom.metrics.k8s.io/v1beta1",
  "metadata": {
    "selfLink": "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/services/sample-metrics-app/http_requests"
  },
  "items": [
    {
      "describedObject": {
        "kind": "Service",
        "name": "sample-metrics-app",
        "apiVersion": "/__internal"
      },
      "metricName": "http_requests",
      "timestamp": "2017-11-29T21:31:13Z",
      "value": "539m"
    }
  ]
}

Note that http_requests has value of "539m". It should be a number and not memory. In my case I was expecting 120 (that was my transaction per second i had set via my load test tool). Due to this issue hpa does not scale the replicaset appropriately. Prometheus metrics was verified to show right value.

I1129 21:27:07.806751       1 api.go:74] GET http://sample-metrics-prom.default.svc:9090/api/v1/query?query=sum%28rate%28http_requests_total%7Bservice%3D%22sample-metrics-app%22%2Cnamespace%3D%22default%22%7D%5B
1m%5D%29%29+by+%28service%29&time=1511990827.805 200 OK
I1129 21:27:07.806847       1 api.go:93] Response Body: {"status":"success","data":{"resultType":"vector","result":[{"metric":{"service":"sample-metrics-app"},"value":[1511990827.805,"30.54"]}]}}

This is what describing the hpa shows.

➜  kubectl describe hpa sample-metrics-app-hpa
Name:                                             sample-metrics-app-hpa
Namespace:                                        default
Labels:                                           <none>
Annotations:                                      kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"autoscaling/v2beta1","kind":"HorizontalPodAutoscaler","metadata":{"annotations":{},"name":"sample-metrics-app-hpa","namespace":"default"...
CreationTimestamp:                                Wed, 29 Nov 2017 21:29:58 +0000
Reference:                                        Deployment/sample-metrics-app
Metrics:                                          ( current / target )
  "http_requests" on Service/sample-metrics-app:  125300m / 100
Min replicas:                                     1
Max replicas:                                     10
Conditions:
  Type            Status  Reason            Message
  ----            ------  ------            -------
  AbleToScale     True    ReadyForNewScale  the last scale time was sufficiently old as to warrant a new scale
  ScalingActive   True    ValidMetricFound  the HPA was able to succesfully calculate a replica count from Service metric http_requests
  ScalingLimited  True    TooManyReplicas   the desired replica count was more than the maximum replica count
Events:
  Type     Reason                        Age              From                       Message
  ----     ------                        ----             ----                       -------
  Warning  FailedGetObjectMetric         8m (x9 over 2h)  horizontal-pod-autoscaler  unable to get metric http_requests: Service on default sample-metrics-app/unable to fetch metrics from API: the server could not find the requested resource (get services.custom.metrics.k8s.io sample-metrics-app)
  Warning  FailedComputeMetricsReplicas  8m (x9 over 2h)  horizontal-pod-autoscaler  failed to get object metric value: unable to get metric http_requests: Service on default sample-metrics-app/unable to fetch metrics from API: the server could not find the requested resource (get services.custom.metrics.k8s.io sample-metrics-app)

kubectl top nodes heapster

Hello

Deploy Heapster with : kubectl apply -f demos/monitoring/heapster.yaml

Heapster Pod comes online :

kube-system Pods
NAME                                   READY     STATUS             RESTARTS   AGE       IP              NODE
etcd-k8s-master                        1/1       Running            0          38m       192.168.0.160   k8s-master
heapster-3303827012-zd6c0              1/1       Running            0          16m       <none>          k8s-node-2
kube-apiserver-k8s-master              1/1       Running            4          42m       192.168.0.160   k8s-master
kube-controller-manager-k8s-master     1/1       Running            1          39m       192.168.0.160   k8s-master
kube-dns-2459497834-89f2f              3/3       Running            0          39m       10.32.0.2       k8s-master
kube-proxy-5mnzw                       1/1       Running            0          31m       192.168.0.163   k8s-node-3
kube-proxy-b0vqh                       1/1       Running            0          31m       192.168.0.164   k8s-node-4
kube-proxy-krgqg                       1/1       Running            0          39m       192.168.0.160   k8s-master
kube-proxy-s5h76                       1/1       Running            0          31m       192.168.0.161   k8s-node-1
kube-proxy-z9fcn                       1/1       Running            0          31m       192.168.0.162   k8s-node-2
kube-scheduler-k8s-master              1/1       Running            0          40m       192.168.0.160   k8s-master
kubernetes-dashboard-184298627-vl956   0/1       CrashLoopBackOff   6          17m       <none>          k8s-node-3
weave-net-7xxp6                        2/2       Running            0          31m       192.168.0.162   k8s-node-2
weave-net-cxzn2                        2/2       Running            0          31m       192.168.0.164   k8s-node-4
weave-net-l0bw5                        2/2       Running            0          31m       192.168.0.161   k8s-node-1
weave-net-r1bzn                        2/2       Running            0          35m       192.168.0.160   k8s-master
weave-net-wz9v4                        2/2       Running            1          31m       192.168.0.163   k8s-node-3

kube-system Services
NAME                   CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
heapster               10.96.242.72    <none>        80/TCP          16m
kube-dns               10.96.0.10      <none>        53/UDP,53/TCP   39m
kubernetes-dashboard   10.97.240.210   <none>        80/TCP          17m

Nodes
NAME         STATUS    AGE       VERSION   EXTERNAL-IP   OS-IMAGE                        KERNEL-VERSION
k8s-master   Ready     42m       v1.7.2    <none>        Raspbian GNU/Linux 8 (jessie)   4.4.50-hypriotos-v7+
k8s-node-1   Ready     31m       v1.7.2    <none>        Raspbian GNU/Linux 8 (jessie)   4.4.50-hypriotos-v7+
k8s-node-2   Ready     31m       v1.7.2    <none>        Raspbian GNU/Linux 8 (jessie)   4.4.50-hypriotos-v7+
k8s-node-3   Ready     31m       v1.7.2    <none>        Raspbian GNU/Linux 8 (jessie)   4.4.50-hypriotos-v7+
k8s-node-4   Ready     31m       v1.7.2    <none>        Raspbian GNU/Linux 8 (jessie)   4.4.50-hypriotos-v7+

kubectl top nodes gives :

Error from server (InternalError): an error on the server ("unknown") has prevented the request from succeeding (get services http:heapster:)

docker logs 66f3b69cb985 on the node gives :

E0729 11:16:36.622691       7 reflector.go:190] k8s.io/heapster/metrics/util/util.go:51: Failed to list *v1.Node: Get https://kubernetes.default/api/v1/nodes?resourceVersion=0: dial tcp: lookup kubernetes.default on 10.96.0.10:53: dial udp 10.96.0.10:53: connect: network is unreachable

Appreciate any help to resolve this.

kubernetes-dashboard CrashLoopBackOff

Hello.

Deploy Kubernetes Dashboard with : kubectl apply -f demos/dashboard/dashboard.yaml

Dashboard goes into CrashLoopBackOff state :

kube-system Pods
NAME                                   READY     STATUS             RESTARTS   AGE       IP              NODE
etcd-k8s-master                        1/1       Running            0          38m       192.168.0.160   k8s-master
heapster-3303827012-zd6c0              1/1       Running            0          16m       <none>          k8s-node-2
kube-apiserver-k8s-master              1/1       Running            4          42m       192.168.0.160   k8s-master
kube-controller-manager-k8s-master     1/1       Running            1          39m       192.168.0.160   k8s-master
kube-dns-2459497834-89f2f              3/3       Running            0          39m       10.32.0.2       k8s-master
kube-proxy-5mnzw                       1/1       Running            0          31m       192.168.0.163   k8s-node-3
kube-proxy-b0vqh                       1/1       Running            0          31m       192.168.0.164   k8s-node-4
kube-proxy-krgqg                       1/1       Running            0          39m       192.168.0.160   k8s-master
kube-proxy-s5h76                       1/1       Running            0          31m       192.168.0.161   k8s-node-1
kube-proxy-z9fcn                       1/1       Running            0          31m       192.168.0.162   k8s-node-2
kube-scheduler-k8s-master              1/1       Running            0          40m       192.168.0.160   k8s-master
kubernetes-dashboard-184298627-vl956   0/1       CrashLoopBackOff   6          17m       <none>          k8s-node-3
weave-net-7xxp6                        2/2       Running            0          31m       192.168.0.162   k8s-node-2
weave-net-cxzn2                        2/2       Running            0          31m       192.168.0.164   k8s-node-4
weave-net-l0bw5                        2/2       Running            0          31m       192.168.0.161   k8s-node-1
weave-net-r1bzn                        2/2       Running            0          35m       192.168.0.160   k8s-master
weave-net-wz9v4                        2/2       Running            1          31m       192.168.0.163   k8s-node-3

kube-system Services
NAME                   CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
heapster               10.96.242.72    <none>        80/TCP          16m
kube-dns               10.96.0.10      <none>        53/UDP,53/TCP   39m
kubernetes-dashboard   10.97.240.210   <none>        80/TCP          17m

Nodes
NAME         STATUS    AGE       VERSION   EXTERNAL-IP   OS-IMAGE                        KERNEL-VERSION
k8s-master   Ready     42m       v1.7.2    <none>        Raspbian GNU/Linux 8 (jessie)   4.4.50-hypriotos-v7+
k8s-node-1   Ready     31m       v1.7.2    <none>        Raspbian GNU/Linux 8 (jessie)   4.4.50-hypriotos-v7+
k8s-node-2   Ready     31m       v1.7.2    <none>        Raspbian GNU/Linux 8 (jessie)   4.4.50-hypriotos-v7+
k8s-node-3   Ready     31m       v1.7.2    <none>        Raspbian GNU/Linux 8 (jessie)   4.4.50-hypriotos-v7+
k8s-node-4   Ready     31m       v1.7.2    <none>        Raspbian GNU/Linux 8 (jessie)   4.4.50-hypriotos-v7+

kubectl describe po kubernetes-dashboard-184298627-vl956 -n kube-system gives :

  FirstSeen     LastSeen        Count   From                    SubObjectPath                           Type            Reason  Message
  ---------     --------        -----   ----                    -------------                           --------        ------  -------
  17m           17m             1       default-scheduler                                               Normal          ScheduledSuccessfully assigned kubernetes-dashboard-184298627-vl956 to k8s-node-3
  17m           17m             1       kubelet, k8s-node-3                                             Normal          SuccessfulMountVolume    MountVolume.SetUp succeeded for volume "dashboard-token-wchfv"
  13m           16s             8       kubelet, k8s-node-3     spec.containers{kubernetes-dashboard}   Normal          Pulling pulling image "luxas/kubernetes-dashboard:v1.6.1"
  12m           10s             8       kubelet, k8s-node-3     spec.containers{kubernetes-dashboard}   Normal          Pulled  Successfully pulled image "luxas/kubernetes-dashboard:v1.6.1"
  12m           10s             8       kubelet, k8s-node-3     spec.containers{kubernetes-dashboard}   Normal          Created Created container
  11m           9s              8       kubelet, k8s-node-3     spec.containers{kubernetes-dashboard}   Normal          Started Started container
  13m           6s              53      kubelet, k8s-node-3                                             Warning         FailedSync               Error syncing pod
  11m           6s              52      kubelet, k8s-node-3     spec.containers{kubernetes-dashboard}   Warning         BackOff Back-off restarting failed container

On the node docker logs bcc9c66addcd gives :

Using HTTP port: 8443
Creating API server client for https://10.96.0.1:443
Error while initializing connection to Kubernetes apiserver. This most likely means that the cluster is misconfigured (e.g., it has invalid apiserver certificates or service accounts configuration) or the --apiserver-host param points to a server that does not exist. Reason: Get https://10.96.0.1:443/version: dial tcp 10.96.0.1:443: connect: network is unreachable
Refer to the troubleshooting guide for more information: https://github.com/kubernetes/dashboard/blob/master/docs/user-guide/troubleshooting.md

Appreciate any help to resolve this.

Error syncing pod, skipping: timeout expired waiting for volumes to attach/mount for pod. using sample-prometheus-instance.yaml

Hi,

I'm getting the error Unable to mount volumes for pod error from the sample-prometheus-instance.yaml. No change was made in the yaml file.

Was wondering anyone encounters the same error?

https://github.com/luxas/kubeadm-workshop/blob/master/demos/monitoring/sample-prometheus-instance.yaml

   Unable to mount volumes for pod "prometheus-sample-metrics-prom-0_default(469b4880-0a9b-11e8-a29b-0800272637bb)": timeout expired waiting for volumes to attach/mount for pod "default"/"prometheus-sample-metrics-prom-0". list of unattached/unmounted volumes=[prometheus-sample-metrics-prom-db]

journalctl:

   Feb 05 20:05:53 minikube kubelet[3704]: E0205 20:05:53.570497    3704 nestedpendingoperations.go:263] Operation for "\"kubernetes.io/rbd/[10.97.152.94:6790 10.104.200.62:6790 10.111.171.163:6790]:k8s-dynamic-pvc-ea65c0b0-0a99-11e8-a29b-0800272637bb-ea742ba1-0a99-11e8-9a4d-0242ac110004\"" failed. No retries permitted until 2018-02-05 20:07:55.570463699 +0000 UTC m=+40710.307964873 (durationBeforeRetry 2m2s). Error: "MountVolume.WaitForAttach failed for volume \"pvc-ea65c0b0-0a99-11e8-a29b-0800272637bb\" (UniqueName: \"kubernetes.io/rbd/[10.97.152.94:6790 10.104.200.62:6790 10.111.171.163:6790]:k8s-dynamic-pvc-ea65c0b0-0a99-11e8-a29b-0800272637bb-ea742ba1-0a99-11e8-9a4d-0242ac110004\") pod \"prometheus-sample-metrics-prom-0\" (UID: \"38ed9d87-0aa9-11e8-a29b-0800272637bb\") : error: executable file not found in $PATH, rbd output: "
   Feb 05 20:05:53 minikube kubelet[3704]: I0205 20:05:53.368544    3704 operation_generator.go:446] MountVolume.WaitForAttach entering for volume "pvc-ea65c0b0-0a99-11e8-a29b-0800272637bb" (UniqueName: "kubernetes.io/rbd/[10.97.152.94:6790 10.104.200.62:6790 10.111.171.163:6790]:k8s-dynamic-pvc-ea65c0b0-0a99-11e8-a29b-0800272637bb-ea742ba1-0a99-11e8-9a4d-0242ac110004") pod "prometheus-sample-metrics-prom-0" (UID: "38ed9d87-0aa9-11e8-a29b-0800272637bb") DevicePath ""
   Feb 05 20:05:02 minikube kubelet[3704]: E0205 20:05:02.532512    3704 pod_workers.go:186] Error syncing pod 38ed9d87-0aa9-11e8-a29b-0800272637bb ("prometheus-sample-metrics-prom-0_default(38ed9d87-0aa9-11e8-a29b-0800272637bb)"), skipping: timeout expired waiting for volumes to attach/mount for pod "default"/"prometheus-sample-metrics-prom-0". list of unattached/unmounted volumes=[prometheus-sample-metrics-prom-db]

Env Info:
Minikube: v1.9.1
OS: Linux minikube 4.9.13 #1 SMP Thu Oct 19 17:14:00 UTC 2017 x86_64 GNU/Linux

Thanks in Advance.

sample-apiserver failed to start

$ kubectl -n wardle logs wardle-apiserver-2109496523-s604f wardle-server

...
panic: unknown flag: --etcd-servers

goroutine 1 [running]:
panic(0x13efce0, 0xc4204452c0)
/usr/local/go/src/runtime/panic.go:500 +0x1a1
main.main()
/go/src/k8s.io/custom-metrics-boilerplate/sample-main.go:40 +0x126

Custom metrics value not propagating to hpa

I am using the latest version (as of when this issue was reported. Commit 1e696ac..). There seems to be an issue with hpa getting the value of the custom-metric exposed by sample-metrics-app.
When I curl the custom-metrics api url https://${CM_API}/apis/custom-metrics.metrics.k8s.io/.....http_requests_total, the value field in the result result json is always 0. Even after I run the load generator. I checked kubectl logs custom-metrics-apiserver logs to find that the prometheus query issued by the metrics-apiserver is always getting an empty vector

validate%!(EXTRA string=http_requests_total, bool=true)sum(rate(http_requests_total{namespace="default",svc_name="sample-metrics-app"}[60s]))
http://sample-metrics-prom.default.svc:9090/api/v1/query?query=sum%28rate%28http_requests_total%7Bnamespace%3D%22default%22%2Csvc_name%3D%22sample-metrics-app%22%7D%5B60s%5D%29%29&time=2017-06-28T20%3A39%3A54.076714493Z
vector doesn't contain any elements
metricFor { services} default sample-metrics-app http_requests_total 0 60

The sample-metrics app is exposing the value correctly. When I curl sample-metrics-app-ip:9090/metrics, I can see

# HELP http_requests_total The amount of requests served by the server in total
# TYPE http_requests_total counter
http_requests_total 49642

When I curl the prometheus end-point, things get a little fishy. I see

# HELP http_requests_total Total number of HTTP requests made.
# TYPE http_requests_total counter
http_requests_total{code="200",handler="label_values",method="get"} 60
http_requests_total{code="200",handler="prometheus",method="get"} 8
http_requests_total{code="200",handler="query",method="get"} 161
http_requests_total{code="200",handler="status",method="get"} 797
http_requests_total{code="400",handler="query",method="get"} 1

These values doesn't seem to reflect the value exposed by sample-metrics-app. I am not sure if the link to Prometheus is broken from both sides (prom to app and prom to apiserver).

As a quick aside, with the upgrage to rc-1, custom metrics APIService needs two additional params:

The APIService "v1alpha1.custom-metrics.metrics.k8s.io" is invalid: 
* spec.groupPriorityMinimum: Invalid value: 0: must be positive and less than 20000
* spec.versionPriority: Invalid value: 0: must be positive and less than 1000

I don't believe this has any effect in what I am reporting, but for completeness sake, I set groupPriorityMinimum to 200 and versionPriority to 20.

[Update]: Just tried with the previous commit (before udpatating prom-operator version) and things seem fine 👍. Though in both versions, deleting the prometheus object (kubectl delete prometheus sample-metrics-prom) seem to slowdown all further queries to api-server.

Getting custom metrics on GKE

Hello, I've tried the custom-metrics-metrics-apiserver and the sample-metrics-app on a 1.8.6 GKE cluster and I think there is an error I'm making with regards to authentication or RBAC perhaps, but I'm not sure what it is, hopefully someone can point me in the right direction? I tried to run the server in the custom-metrics namespace and the kube-system namespace, both of which don't seem to work.

I've got the following in the logs from the custom-metrics-apiserver

I0128 12:37:20.988281       1 logs.go:41] http: TLS handshake error from 10.x.1.4:37000: tls: first record does not look like a TLS handshake
I0128 12:37:38.700217       1 request.go:836] Response Body: {"kind":"SubjectAccessReview","apiVersion":"authorization.k8s.io/v1beta1","metadata":{"creationTimestamp":null},"spec":{"nonResourceAttributes":{"path":"/apis/custom.metrics.k8s.io/v1beta1","verb":"get"},"user":"system:serviceaccount:kube-system:generic-garbage-collector","group":["system:serviceaccounts","system:serviceaccounts:kube-system","system:authenticated"]},"status":{"allowed":true}}
I0128 12:37:38.700654       1 handler.go:150] prometheus-custom-metrics-adapter: GET "/apis/custom.metrics.k8s.io/v1beta1" satisfied by gorestful with webservice /apis/custom.metrics.k8s.io/v1beta1
I0128 12:37:38.701803       1 wrap.go:42] GET /apis/custom.metrics.k8s.io/v1beta1: (26.724675ms) 200 [[kube-controller-manager/v1.8.6 (linux/amd64) kubernetes/ee9a976/system:serviceaccount:kube-system:generic-garbage-collector] 10.191.0.14:34362]
I0128 12:43:28.775871       1 request.go:836] Request Body: {"kind":"SubjectAccessReview","apiVersion":"authorization.k8s.io/v1beta1","metadata":{"creationTimestamp":null},"spec":{"nonResourceAttributes":{"path":"/swagger.json","verb":"get"},"user":"system:aggregator","group":["system:authenticated"]},"status":{"allowed":false}}

Error on rook-rook-user command

So far so good the workshop, however when i run the command
kubectl get secret rook-rook-user -oyaml | sed "/resourceVer/d;/uid/d;/self/d;/creat/d;/namespace/d" | kubectl -n kube-system apply -f -

I get as a response

-Error from server (NotFound): secrets "rook-rook-user" not found
error: no objects passed to apply

Is it something obvious i am missing since i am new to kubernetes?

Thanks in advance.

Question: Will this work with if EC2 machines are included ?

Given VPN connectivity exists and nodes can talk to each other like local network will this work with few machines being Raspberry Pi's and others including the master being EC2 machines ? Any changes that might be needed for that to work ?

kubeadm in self-hosted mode (1.6.1) fails to startup scheduler

I just did a super fresh install of everything but now hit the following issue with kubeadm 1.6.1

A

KUBE_HYPERKUBE_IMAGE=luxas/hyperkube:v1.6.0-and-PR-42911 kubeadm init --config /etc/kubernetes/kubeadm.yml

with /etc/kubernetes/kubeadm.yml (from the README except an extra predefined token)

kind: MasterConfiguration
apiVersion: kubeadm.k8s.io/v1alpha1
token: "3d63a1.d93b1c68af864b80"
networking:
  podSubnet: "10.1.0.0/16"
#  serviceSubnet: "10.200.100.0/24"
controllerManagerExtraArgs:
  controllers: "*,-persistentvolume-binder,bootstrapsigner,tokencleaner"
  horizontal-pod-autoscaler-use-rest-clients: "true"
  horizontal-pod-autoscaler-sync-period: "10s"
  node-monitor-grace-period: "10s"
apiServerExtraArgs:
  runtime-config: "api/all=true"
  feature-gates: "TaintBasedEvictions=true"
  proxy-client-cert-file: "/etc/kubernetes/pki/front-proxy-client.crt"
  proxy-client-key-file: "/etc/kubernetes/pki/front-proxy-client.key"
selfHosted: true

leads to

root@n0:/home/pi# KUBE_HYPERKUBE_IMAGE=luxas/hyperkube:v1.6.0-and-PR-42911 kubeadm init --config /etc/kubernetes/kubeadm.yml
[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.
[init] Using Kubernetes version: v1.6.0
[init] Using Authorization mode: RBAC
[preflight] Running pre-flight checks
[preflight] Starting the kubelet service
[certificates] Generated CA certificate and key.
[certificates] Generated API server certificate and key.
[certificates] API Server serving cert is signed for DNS names [n0 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.23.200]
[certificates] Generated API server kubelet client certificate and key.
[certificates] Generated service account token signing key and public key.
[certificates] Generated front-proxy CA certificate and key.
[certificates] Generated front-proxy client certificate and key.
[certificates] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"
[apiclient] Created API client, waiting for the control plane to become ready
[apiclient] All control plane components are healthy after 38.382559 seconds
[apiclient] Waiting for at least one node to register
[apiclient] First node has registered after 8.119716 seconds
[self-hosted] Creating self-hosted control plane...
[self-hosted] kube-apiserver DaemonSet current=0, desired=0
[self-hosted] Found 0 self-hosted-kube-apiserver pods
[self-hosted] Found 0 self-hosted-kube-apiserver pods
[self-hosted] Found 0 self-hosted-kube-apiserver pods
....
[self-hosted] Found 1 self-hosted-kube-apiserver pods
[self-hosted] Pod self-hosted-kube-apiserver-jx8s8 status: Pending
[self-hosted] Found 1 self-hosted-kube-apiserver pods
[self-hosted] Pod self-hosted-kube-apiserver-jx8s8 status: Pending
[self-hosted] Found 1 self-hosted-kube-apiserver pods
.....
[self-hosted] Pod self-hosted-kube-apiserver-jx8s8 status: Running
[apiclient] All control plane components are healthy after 19.398582 seconds
[self-hosted] self-hosted kube-apiserver ready after 41.020531 seconds
[self-hosted] Found 0 self-hosted-kube-scheduler pods
[self-hosted] Found 0 self-hosted-kube-scheduler pods
[self-hosted] Found 0 self-hosted-kube-scheduler pods
[self-hosted] Found 0 self-hosted-kube-scheduler pods
[self-hosted] Found 0 self-hosted-kube-scheduler pods
[self-hosted] Found 0 self-hosted-kube-scheduler pods
[self-hosted] Found 1 self-hosted-kube-scheduler pods
[self-hosted] Pod self-hosted-kube-scheduler-2660681130-r0php status: Pending
[self-hosted] Found 1 self-hosted-kube-scheduler pods
[self-hosted] Pod self-hosted-kube-scheduler-2660681130-r0php status: Pending
[self-hosted] Found 1 self-hosted-kube-scheduler pods
[self-hosted] Pod self-hosted-kube-scheduler-2660681130-r0php status: Pending
[self-hosted] Found 1 self-hosted-kube-scheduler pods
[self-hosted] Pod self-hosted-kube-scheduler-2660681130-r0php status: Pending
[self-hosted] Found 1 self-hosted-kube-scheduler pods
.....
(never ending)

which indicates that the scheduler pod doesn't come up. And indeed the problem is that the scheduler pod cannot be scheduled:

root@n0:/home/pi# kubectl get pods --all-namespaces
NAMESPACE     NAME                                          READY     STATUS    RESTARTS   AGE
kube-system   etcd-n0                                       1/1       Running   0          1m
kube-system   kube-controller-manager-n0                    1/1       Running   0          22s
kube-system   kube-scheduler-n0                             1/1       Running   1          1m
kube-system   self-hosted-kube-apiserver-jx8s8              1/1       Running   0          2m
kube-system   self-hosted-kube-scheduler-2660681130-r0php   0/1       Pending   0          1m

root@n0:/home/pi# kubectl describe pod self-hosted-kube-scheduler-2660681130-r0php --namespace=kube-system
Name:		self-hosted-kube-scheduler-2660681130-r0php
Namespace:	kube-system
Node:		/
Labels:		component=kube-scheduler
		k8s-app=self-hosted-kube-scheduler
		pod-template-hash=2660681130
		tier=control-plane
Annotations:	kubernetes.io/created-by={"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicaSet","namespace":"kube-system","name":"self-hosted-kube-scheduler-2660681130","uid":"449d6cb5-1917-...
Status:		Pending
IP:
Controllers:	ReplicaSet/self-hosted-kube-scheduler-2660681130
Containers:
  self-hosted-kube-scheduler:
    Image:	luxas/hyperkube:v1.6.0-and-PR-42911
    Port:
    Command:
      /hyperkube
      scheduler
      --address=127.0.0.1
      --leader-elect=true
      --kubeconfig=/etc/kubernetes/scheduler.conf
    Requests:
      cpu:		100m
    Liveness:		http-get http://127.0.0.1:10251/healthz delay=15s timeout=15s period=10s #success=1 #failure=8
    Environment:	<none>
    Mounts:
      /etc/kubernetes/ from k8s (ro)
      /etc/ssl/certs from certs (rw)
      /var/lock from var-lock (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-4szsp (ro)
Conditions:
  Type		Status
  PodScheduled 	False
Volumes:
  k8s:
    Type:	HostPath (bare host directory volume)
    Path:	/etc/kubernetes
  certs:
    Type:	HostPath (bare host directory volume)
    Path:	/etc/ssl/certs
  var-lock:
    Type:	HostPath (bare host directory volume)
    Path:	/var/lock
  default-token-4szsp:
    Type:	Secret (a volume populated by a Secret)
    SecretName:	default-token-4szsp
    Optional:	false
QoS Class:	Burstable
Node-Selectors:	node-role.kubernetes.io/master=
Tolerations:	node-role.kubernetes.io/master=:NoSchedule
		node.alpha.kubernetes.io/notReady=:Exists:NoExecute for 300s
		node.alpha.kubernetes.io/unreachable=:Exists:NoExecute for 300s
Events:
  FirstSeen	LastSeen	Count	From			SubObjectPath	Type		Reason		Message
  ---------	--------	-----	----			-------------	--------	------		-------
  1m		42s		8	default-scheduler			Warning		FailedScheduling	no nodes available to schedule pods

Looks like a catch-22 ;-)

Reboot support planned ?

Any thoughts how to solve the problem with rebooting a k8s cluster as stated in the "Known Issues section" (see #4) ? would be awesome if we could get this resolved as I expected that a pi cluster will be carried around a lot (e.g. to conferences ;-), so rebooting / restarting will happen quite often. Reinstalling the cluster afresh always before a demo is not really an option.

Deploying dependencies of Rook causes PersistentVolumeClaim is not bound errors

After I deploy dependencies of the Persistent Volumes, I get the following errors. The pods are in Pending state. This happens to Influx-Grafana and Prometheus:


[SchedulerPredicates failed due to PersistentVolumeClaim is not bound: "grafana-pv-claim", which is unexpected., SchedulerPredicates failed due to PersistentVolumeClaim is not bound: "grafana-pv-claim", which is unexpected., SchedulerPredicates failed due to PersistentVolumeClaim is not bound: "grafana-pv-claim", which is unexpected.]

---------

[SchedulerPredicates failed due to PersistentVolumeClaim is not bound: "influxdb-pv-claim", which is unexpected., SchedulerPredicates failed due to PersistentVolumeClaim is not bound: "influxdb-pv-claim", which is unexpected., SchedulerPredicates failed due to PersistentVolumeClaim is not bound: "influxdb-pv-claim", which is unexpected.]

---------

[SchedulerPredicates failed due to PersistentVolumeClaim is not bound: "prometheus-sample-metrics-prom-db-prometheus-sample-metrics-prom-0", which is unexpected., SchedulerPredicates failed due to PersistentVolumeClaim is not bound: "prometheus-sample-metrics-prom-db-prometheus-sample-metrics-prom-0", which is unexpected., SchedulerPredicates failed due to PersistentVolumeClaim is not bound: "prometheus-sample-metrics-prom-db-prometheus-sample-metrics-prom-0", which is unexpected.]

Outdated README: luxas/kube-proxy:v1.8.0-beta.1, which doesn't exist

Background

  • I am building a bare-metal k8s at home using a mix of rpi3s and old amd64 laptops
  • Ran into issue with multi-arch support when following official k8s docs (kube-proxy wouldn't start on the rpi3 nodes when controller was an amd64 node)
  • Found your helpful pointer in this GitHub issue
  • Proposed command didn't work, but fixing an outdated tag did fix the issue (thank you!)

Steps to reproduce

  1. Run the following command on an amd64 k8s controller node with arm64 worker nodes:
$ kubectl -n kube-system set image daemonset/kube-proxy kube-proxy=luxas/kube-proxy:v1.8.0-beta.1
  1. Behold image pull errors on amd64 nodes:
user@host:~$ kubectl get pods --all-namespaces
NAMESPACE     NAME                               READY     STATUS             RESTARTS   AGE
kube-system   etcd-latitude                      1/1       Running            0          44m
kube-system   kube-apiserver-latitude            1/1       Running            0          44m
kube-system   kube-controller-manager-latitude   1/1       Running            0          44m
kube-system   kube-dns-545bc4bfd4-8t77d          3/3       Running            0          45m
kube-system   kube-proxy-bmrjq                   1/1       Running            0          45m
kube-system   kube-proxy-cp6d9                   0/1       ImagePullBackOff   0          4s
kube-system   kube-proxy-dcr7r                   0/1       ImagePullBackOff   0          4s
kube-system   kube-proxy-g88rq                   0/1       ErrImagePull       0          4s
kube-system   kube-proxy-z5z4d                   0/1       ImagePullBackOff   0          4s

Proposed solution

  • Update documentation to remove the "-beta.1" suffix.
  • I'll submit a pull request

Dashboard install not working

Dashboard install not working:

$ curl -sSL https://git.io/kube-dashboard | sed "s|image:.*|image: luxas/kubernetes-dashboard:v1.6.3|" | kubectl apply -f -
error: error validating "STDIN": error validating data: apiVersion not set; if you choose to ignore these errors, turn validation off with --validate=false

when:

curl -sSL https://git.io/kube-dashboard
404: Not Found

DNS won't resolve

I'm running into an issue with DNS no matter which OS...

Everything create's fine:

root@mitchell-desktop:/etc/default# kubectl get po --all-namespaces
NAMESPACE     NAME                                       READY     STATUS    RESTARTS   AGE
default       nginx-416304662-rfjt3                      1/1       Running   0          18m
kube-system   etcd-mitchell-desktop                      1/1       Running   0          28m
kube-system   kube-apiserver-mitchell-desktop            1/1       Running   0          28m
kube-system   kube-controller-manager-mitchell-desktop   1/1       Running   0          29m
kube-system   kube-dns-2459497834-h88gc                  3/3       Running   0          29m
kube-system   kube-proxy-p88j4                           1/1       Running   0          27m
kube-system   kube-scheduler-mitchell-desktop            1/1       Running   0          28m
kube-system   weave-net-k6dlb                            2/2       Running   0          27m

But trying to resolve anything within a pod does not:

root@mitchell-desktop:/etc/default# kubectl exec -it nginx-416304662-rfjt3 sh
/ # curl google.com
curl: (6) Couldn't resolve host 'google.com'

I noticed dnsmasq is throwing an error:

root@mitchell-desktop:/etc/default# kubectl logs -n kube-system kube-dns-2459497834-h88gc dnsmasq | head -n 20
I0812 16:59:18.348899       1 main.go:76] opts: {{/usr/sbin/dnsmasq [-k --cache-size=1000 --log-facility=- --server=/
cluster.local/127.0.0.1#10053 --server=/in-addr.arpa/127.0.0.1#10053 --server=/ip6.arpa/127.0.0.1#10053] true} /etc/k
8s/dns/dnsmasq-nanny 10000000000}
I0812 16:59:18.349359       1 nanny.go:86] Starting dnsmasq [-k --cache-size=1000 --log-facility=- --server=/cluster.
local/127.0.0.1#10053 --server=/in-addr.arpa/127.0.0.1#10053 --server=/ip6.arpa/127.0.0.1#10053]
I0812 16:59:18.767589       1 nanny.go:111]
W0812 16:59:18.767658       1 nanny.go:112] Got EOF from stdout
I0812 16:59:18.767878       1 nanny.go:108] dnsmasq[13]: started, version 2.76 cachesize 1000
I0812 16:59:18.768167       1 nanny.go:108] dnsmasq[13]: compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN
 DHCP DHCPv6 no-Lua TFTP no-conntrack ipset auth no-DNSSEC loop-detect inotify
I0812 16:59:18.768291       1 nanny.go:108] dnsmasq[13]: using nameserver 127.0.0.1#10053 for domain ip6.arpa
I0812 16:59:18.768406       1 nanny.go:108] dnsmasq[13]: using nameserver 127.0.0.1#10053 for domain in-addr.arpa
I0812 16:59:18.768497       1 nanny.go:108] dnsmasq[13]: using nameserver 127.0.0.1#10053 for domain cluster.local
I0812 16:59:18.770129       1 nanny.go:108] dnsmasq[13]: reading /etc/resolv.conf
I0812 16:59:18.770341       1 nanny.go:108] dnsmasq[13]: using nameserver 127.0.0.1#10053 for domain ip6.arpa
I0812 16:59:18.770443       1 nanny.go:108] dnsmasq[13]: using nameserver 127.0.0.1#10053 for domain in-addr.arpa
I0812 16:59:18.770527       1 nanny.go:108] dnsmasq[13]: using nameserver 127.0.0.1#10053 for domain cluster.local
I0812 16:59:18.770647       1 nanny.go:108] dnsmasq[13]: using nameserver 127.0.1.1#53
I0812 16:59:18.770742       1 nanny.go:108] dnsmasq[13]: read /etc/hosts - 7 addresses
I0812 17:06:07.325776       1 nanny.go:108] dnsmasq[13]: Maximum number of concurrent DNS queries reached (max: 150)
I0812 17:06:16.195046       1 nanny.go:108] dnsmasq[13]: Maximum number of concurrent DNS queries reached (max: 150)
I0812 17:06:26.221765       1 nanny.go:108] dnsmasq[13]: Maximum number of concurrent DNS queries reached (max: 150)

I followed the workshop to a T on a clean install and no matter which OS (raspbian, hypriot, ubuntu) I get the same result.

Any idea what the issue might be?

What is `proxy-client-cert-file` good for?

Could you explain or point to some background information why these lines are needed? And what would be their default settings?

  proxy-client-cert-file: "/etc/kubernetes/pki/front-proxy-client.crt"
  proxy-client-key-file: "/etc/kubernetes/pki/front-proxy-client.key"

custom metrics prometheus adapter label name requirements

Hello. This is duplicate to kubernetes-sigs/prometheus-adapter#29, but I am not sure which repo is alive nowadays.

So forgive me if I ask in both.

Metrics must have the namespace label to be considered.

For each label on a metric, if that label name corresponds to a Kubernetes resource (like pod or service), the metric will be associated with that resource.

Is there any way to configure it? My labels are "kubernetes_namespace", "kubernetes_pod_name" and so forth. Therefore the metrics I need aren't captured by the adapter. I have an existing and long time running prometheus clusters all over the place, it would be potentially a breaking change to relabel everything.

What's the best way to go here?

Thank you!

Just wrote a script to install K8s + Docker on RPi (HypriotOS)

Following this tutorial, which is very useful btw, thanks for that.
I found the installation process a bit tedious, so I wrote a small script to automate the installation, though it's intended for RPi at the moment, it can be extended to any other platform as well. Feedback is always welcome.

Ps. didn't know if this was the best place to let you guys know

Here's the repo: untalpierre/k8s-arm

Lots of Info but it stalls after Rook is stared

Hi

I tried this with various version of Kubernetes (1.9.1, 1.8.1, 1.8.8, 1.7.11) and it runs until Rook cluster is started at which point it takes 5 minutes to respond to Kubectrl (the CPU is not busy). (all pods are running) but it is useless at that point. What would really help is to specify the version (that worked) of everything. Thanks I learned a lot but never got to the punch line where i could look at a dashboards.

NAMESPACE NAME READY STATUS RESTARTS AGE
default prometheus-operator-5cd8bbf869-wj9ct 1/1 Running 0 28m
default rook-operator-5b746cbd6d-q6t7x 1/1 Running 0 28m
kube-system etcd-kube1 1/1 Running 0 34m
kube-system heapster-797666785f-wqvj6 1/1 Running 0 30m
kube-system kube-apiserver-kube1 1/1 Running 0 34m
kube-system kube-controller-manager-kube1 1/1 Running 0 33m
kube-system kube-dns-545bc4bfd4-5vz68 3/3 Running 0 35m
kube-system kube-proxy-b9kp2 1/1 Running 0 33m
kube-system kube-proxy-mffdk 1/1 Running 0 33m
kube-system kube-proxy-ztkvd 1/1 Running 0 35m
kube-system kube-scheduler-kube1 1/1 Running 0 33m
kube-system kubernetes-dashboard-5569448c6d-lncfl 1/1 Running 0 32m
kube-system metrics-server-77b9cb679-q2khf 1/1 Running 0 31m
kube-system ngrok-bb6c478b-lpsgd 1/1 Running 0 28m
kube-system traefik-ingress-controller-6497984ff8-pqrtf 1/1 Running 0 28m
kube-system weave-net-5ljwz 2/2 Running 0 33m
kube-system weave-net-ffhvw 2/2 Running 0 33m
kube-system weave-net-fxd25 2/2 Running 0 33m
rook rook-api-c6d5669d7-2ggl4 1/1 Running 0 19m
rook rook-ceph-mgr0-578dbb9c4b-pjqjm 1/1 Running 0 19m
rook rook-ceph-mon0-hhn72 1/1 Running 0 19m
rook rook-ceph-mon1-hg58s 1/1 Running 0 19m
rook rook-ceph-mon2-h9kvj 1/1 Running 0 19m
rook rook-ceph-osd-2zr88 1/1 Running 0 19m
rook rook-ceph-osd-sg4j7 1/1 Running 0 19m
rook rook-ceph-osd-twn5l 1/1 Running 0 19m

Error when nodes try to join master

Was trying out the workshop and ran into some trouble when minion nodes try to join the master. Running on 16.04 (xenial).

ubuntu@k8-1:~/kubeadm-workshop$ kubeadm version
kubeadm version: version.Info{Major:"1", Minor:"6", GitVersion:"v1.6.4", GitCommit:"d6f433224538d4f9ca2f7ae19b252e6fcb66a3ae", GitTreeState:"clean", BuildDate:"2017-05-19T18:33:17Z", GoVersion:"go1.7.5", Compiler:"gc", Platform:"linux/amd64"}
ubuntu@k8-1:~/kubeadm-workshop$ kubectl version
Client Version: version.Info{Major:"1", Minor:"6", GitVersion:"v1.6.4", GitCommit:"d6f433224538d4f9ca2f7ae19b252e6fcb66a3ae", GitTreeState:"clean", BuildDate:"2017-05-19T18:44:27Z", GoVersion:"go1.7.5", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"8+", GitVersion:"v1.8.0-alpha.0", GitCommit:"b9e8d2aee6d59330306cb458c1241f5e2578c40b", GitTreeState:"clean", BuildDate:"2017-06-02T03:03:31Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}

kubeadm join --token token ip:port is getting stuck at

[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.
[preflight] Running pre-flight checks
[discovery] Trying to connect to API Server "192.168.0.11:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://192.168.0.11:6443"
[discovery] Cluster info signature and contents are valid, will use API Server "https://192.168.0.11:6443"
[discovery] Successfully established connection with API Server "192.168.0.11:6443"
[bootstrap] Detected server version: v1.8.0-alpha.0
[bootstrap] The server supports the Certificates API (certificates.k8s.io/v1beta1)
[csr] Created API client to obtain unique certificate for this node, generating keys and certificate signing request

I was wondering if it was because of version mismatch as per kubernetes/kubeadm#217 . Since it looked like kubeadm installed the v1.8.0-alpha version for the server, I tried changing the kubernetes-version in kubeadm.yaml to v1.6.4, but this is resulting in my kubeadm init getting stuck at

[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"
[apiclient] Created API client, waiting for the control plane to become ready

Retried init after a kubeadm reset, but no luck so far.

no matches for rook.io/, Kind=Cluster

Hello

kubectl apply -f https://raw.githubusercontent.com/rook/rook/release-0.4/demo/kubernetes/rook-cluster.yaml

Results in error

pirate@k8s-master:~/kubeadm-workshop$ kubectl apply -f https://raw.githubusercontent.com/rook/rook/release-0.4/demo/kubernetes/rook-cluster.yaml
error: unable to recognize "https://raw.githubusercontent.com/rook/rook/release-0.4/demo/kubernetes/rook-cluster.yaml": no matches for rook.io/, Kind=Cluster

Appreciate any help to resolve.

kubeadm High Availability cluster

Hello Luxas,
I'm struggling to make a HA cluster using kubeadm, I always had an issue about elected leader between my two masters, only one of theme has role master and the other one < none > as a role.

would you suggest me a way to make this work ?
by the way I'm using kubeadm 1.8.0

thank you

Weave does not work on Hypriot 1.4.0

When using the latest Hypriot base image (1.4.0) I can't get Weave running. As it seems, weaves uses the same UUID for calculating the virtual Mac address for all nodes:

k logs weave-net-x1z25 --namespace=kube-system weave
INFO: 2017/04/04 06:16:06.910766 Command line options: map[http-addr:127.0.0.1:6784 ipalloc-init:consensus=4 nickname:n3 status-addr:0.0.0.0:6782 docker-api: conn-limit:30 datapath:datapath ipalloc-range:10.32.0.0/12 no-dns:true port:6783]
INFO: 2017/04/04 06:16:06.911597 Communication between peers is unencrypted.
INFO: 2017/04/04 06:16:07.062159 Our name is 8e:0e:19:5d:4e:5e(n3)
INFO: 2017/04/04 06:16:07.062426 Launch detected - using supplied peer list: [192.168.23.200 192.168.23.201 192.168.23.202 192.168.23.203]
INFO: 2017/04/04 06:16:07.062669 Checking for pre-existing addresses on weave bridge
INFO: 2017/04/04 06:16:07.072861 [allocator 8e:0e:19:5d:4e:5e] No valid persisted data
INFO: 2017/04/04 06:16:07.158094 [allocator 8e:0e:19:5d:4e:5e] Initialising via deferred consensus
INFO: 2017/04/04 06:16:07.159120 Sniffing traffic on datapath (via ODP)
INFO: 2017/04/04 06:16:07.163257 ->[192.168.23.202:6783] attempting connection
INFO: 2017/04/04 06:16:07.163770 ->[192.168.23.201:6783] attempting connection
INFO: 2017/04/04 06:16:07.164761 ->[192.168.23.203:6783] attempting connection
INFO: 2017/04/04 06:16:07.165369 ->[192.168.23.200:6783] attempting connection
INFO: 2017/04/04 06:16:07.165999 ->[192.168.23.203:48229] connection accepted
INFO: 2017/04/04 06:16:07.173375 ->[192.168.23.203:6783|8e:0e:19:5d:4e:5e(n3)]: connection shutting down due to error: cannot connect to ourself
INFO: 2017/04/04 06:16:07.174156 ->[192.168.23.203:48229|8e:0e:19:5d:4e:5e(n3)]: connection shutting down due to error: cannot connect to ourself
INFO: 2017/04/04 06:16:07.185573 ->[192.168.23.202:6783|8e:0e:19:5d:4e:5e(n3)]: connection shutting down due to error: local "8e:0e:19:5d:4e:5e(n3)" and remote "8e:0e:19:5d:4e:5e(n2)" peer names collision
INFO: 2017/04/04 06:16:07.189360 Listening for HTTP control messages on 127.0.0.1:6784

This is related to kubernetes/kubeadm#31.

Is there are workaround to force a different UUID ? Or, how does Weave obtain / calculate the UUID ?

Error when joining nodes to the cluster

When following the instructions, I get the following when trying to join a node to the cluster:

discovery] Failed to connect to API Server "192.168.0.8:6443": there is no JWS signed token in the cluster-info ConfigMap. This token id "753691" is invalid for this cluster, can't connect

Problems with kubeadm init with 1.6.0

Because of kubernetes/kubeadm#212 the init of the master fails.

Seems like an hen-and-egg issue: kubeadm waits for an cni plugin to be installed until the first node is considered to be running, but the cni plugin (weave) is only installed after kubeadm init.

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.