Kubernetes unter PhotonOS

2016/11/15

Kubernetes unter Photon scheint kaum einer zu machen. Also, genau richtig damit ich mich damit mal Beschäftige. :-) Für unseren Test, möchte ich eine Umgebung in VirtualBox aufbauen. Als ersten erstelle ich einen einzigen Server und benenne diesen docker1. Nach der Grundkonfiguriation, werde ich den Server auf docker2 und docker3 clonen. So habe ich einen Master und zwei Node.

Nach der bereits erfolgten Photon Installation, konfigurieren wir das OS erst einmal nach unseren Vorstellungen. Ich nenne den Server docker1

Docker Master: docker1

tdnf update

hostname docker1
vim /etc/hostname
docker1

tdnf install kubernetes
tdnf install docker
tdnf install dhcp-client

useradd -m docker
passwd docker <PASSWD>

vim /etc/ssh/sshd_config
PubkeyAcceptedKeyTypes=+ssh-dss
PermitRootLogin without-password
systemctl restart sshd

vim /etc/hosts

192.168.56.102  docker1
192.168.56.104  docker2
192.168.56.105  docker3

mkdir /var/run/kubernetes
chown kube: /var/run/kubernetes

Zu dieser Konfiguration habe ich Root wie auch dem User Docker mein ssh pub key freigegeben. Wie oben zu sehen ist, verwende ich in meiner Test Umgebung noch eine veraltete SSH Key verschlüsselung, weswegen ich dies im SSH Server freigeben muss. Das heißt nicht, dass Ihr es auch tun müsst. Nimmt also nicht alles blind entgegen, sondern denkt über das was ich hier aufschreibe nach. Vielleicht habt Ihr ja sogar bessere Ideen oder ich mache Grobe Fehler. Dann schreibt es mir! :-)

Wenn Docker hinter einem Transparenten Proxy steht, welcher das SSL Zertifikat aufbricht, muss die entsprechende PKI in die Datei /etc/pki/tls/certs/ca-bundle.crt eingetragen werden.

Also… Als nächstes Konfigurieren wir Kubernetes.

vim /etc/kubernetes/config

KUBE_LOGTOSTDERR="--logtostderr=true"

KUBE_LOG_LEVEL="--v=0"

KUBE_ALLOW_PRIV="--allow_privileged=false"

KUBE_MASTER="--master=http://docker1:8080"


vim /etc/kubernetes/apiserver

KUBE_API_ADDRESS="--address=0.0.0.0"

KUBE_API_PORT="--port=8080"

KUBELET_PORT="--kubelet_port=10250"

KUBE_ETCD_SERVERS="--etcd_servers=http://127.0.0.1:4001"

KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"

KUBE_ADMISSION_CONTROL="--admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"

WICHTIG: Die Variable KUBE_ADMISSION_CONTROL muss genau so aussehen wie hier angegeben. Weicht diese ab, kommt das Dashboard nicht hoch.

Als nächstes müssen wir noch Secrets erstellen


mkdir /var/run/kubernetes
chown -R kube: /var/run/kubernetes

kubectl create secret tls tls-secret --cert=/var/run/kubernetes/apiserver.crt --key=/var/run/kubernetes/apiserver.key --dry-run

Nun ist es an der Zeit, Kubernetes zu starten. Der Übersicht halber, schreibe ich dies hier als Bash Schleife auf! Ich würde Euch aber den Tipp geben, jeden Service einzeln zu starten um ggfs. Fehlermeldungen zu sehen!

for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler kube-proxy; do
    systemctl restart $SERVICES
    systemctl enable $SERVICES
    systemctl status $SERVICES
done

Ist alles korrekt, prüfen wir ob alle Ports offen sind.


root@docker1 [ ~ ]# netstat -tulpen
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode       PID/Program name
tcp        0      0 127.0.0.1:4001          0.0.0.0:*               LISTEN      0          135586      1236/etcd       
tcp        0      0 127.0.0.1:2379          0.0.0.0:*               LISTEN      0          135583      1236/etcd       
tcp        0      0 127.0.0.1:2380          0.0.0.0:*               LISTEN      0          135577      1236/etcd       
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      0          11092       443/sshd        
tcp        0      0 127.0.0.1:7001          0.0.0.0:*               LISTEN      0          135580      1236/etcd       
tcp6       0      0 :::10251                :::*                    LISTEN      999        136115      1276/kube-scheduler
tcp6       0      0 :::10252                :::*                    LISTEN      999        136057      1264/kube-controlle
tcp6       0      0 :::8080                 :::*                    LISTEN      999        135822      1249/kube-apiserver
tcp6       0      0 :::22                   :::*                    LISTEN      0          11099       443/sshd        
udp        0      0 192.168.56.102:68       0.0.0.0:*                           76         134607      323/systemd-network
udp        0      0 10.0.2.15:68            0.0.0.0:*                           76         104975      323/systemd-network
udp        0      0 0.0.0.0:5355            0.0.0.0:*                           77         10424       347/systemd-resolve
udp6       0      0 fe80::a00:27ff:fe93:546 :::*                                76         11689       323/systemd-network
udp6       0      0 fe80::a00:27ff:fe0b:546 :::*                                76         11675       323/systemd-network

Schauen wir uns mal den Status des Clusters an.

root@docker1 [ ~ ]# kubectl cluster-info
Kubernetes master is running at http://localhost:8080

Sieht also alles gut aus.

Nun ist der Master Server soweit Konfiguriert und wir können diesen nach docker2 clonen um dann die restliche Konfiguration für den ersten Node vorzunehmen. WICHTIG Ihr müsst unter dem Klon die Datei /etc/mashine-id löschen und den Netzwerkkarten neue IP Adressen vergeben. Sonnst bekommt Ihr Netzwerk Konflikte.

rm /etc/mashine-id
systemd-machine-id-setup

Docker Node: docker2

Wir haben ja nun den Clon von docker1. Durch das Klonen haben wir uns zwar einiges an Arbeit erspart, aber dafür nun auch zwei Server die glauben Master zu sein. :-) Dies wollen wir doch mal kurz ändern.

for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do
    systemctl stop $SERVICES
    systemctl disable $SERVICES
    systemctl status $SERVICES
done

Einmal schauen ob das auch funktioniert hat.

root@docker2 [ ~ ]# kubectl cluster-info
The connection to the server localhost:8080 was refused - did you specify the right host or port?

Auf dem Node wird ein Kubernetes Proxy laufen. Dieser benötigt IP-Tables! Auf dem Master haben wir das entsprechende Packet deinstalliert da es für unseren Test nur zu viele Baustellen aufmacht. Auf den Nodes müssen wir das Packet wieder installieren.

tdnf install iptables

Sehr schön! Kommen wir nun dazu docker2 als Node zu konfigurieren.

vim /etc/kubernetes/kubelet

KUBELET_ADDRESS="--bind-address=0.0.0.0"

KUBELET_PORT="--port=10250"

#KUBELET_HOSTNAME="--hostname_override=127.0.0.1"

KUBELET_API_SERVER="--api_servers=http://docker1:8080"



Anschließend starten wir die entsprechenden Services. Wie auch bei docker1, verwende ich Übersichtshalber eine Schleife. Macht dies aber beim ersten mal einzeln um ggfs. Fehlermeldungen besser sehen zu können.

for SERVICES in kube-proxy kubelet docker; do
    systemctl restart $SERVICES
    systemctl enable $SERVICES
    systemctl status $SERVICES
done

Wenn es beim starten keine Fehlermeldungen gab, können wir davon ausgehen, dass der Node soweit ok ist. Melden wir uns nun auf docker1 an um uns den Status des Cluster anzuschauen.

root@docker1 [ ~ ]# kubectl get nodes
NAME      STATUS    AGE
docker2   Ready     2m

Sieht gut aus. :-) Wir könnten als nun unser docker2 Klonen und anschließend ohne viel dazu tun weitere Docker Nodes aufzubauen. An dieser Stelle möchte ich jedoch zunächst das Docker Dashboard installieren und wieder eine bessere Übersicht zu erlangen.

Docker Dashboard

Das Docker Dashboard installieren wir auf dem Master.

curl http://rawgit.com/kubernetes/dashboard/master/src/deploy/kubernetes-dashboard.yaml > kubernetes-dashboard.yaml

root@docker1 [ ~ ]# kubectl create namespace kube-system          
namespace "kube-system" created

root@docker1 [ ~ ]# kubectl create -f kubernetes-dashboard.yaml
deployment "kubernetes-dashboard" created
You have exposed your service on an external port on all nodes in your
cluster.  If you want to expose this service to the external internet, you may
need to set up firewall rules for the service port(s) (tcp:31227) to serve traffic.

See http://releases.k8s.io/release-1.2/docs/user-guide/services-firewalls.md for more details.
service "kubernetes-dashboard" created

Kontrollieren ob es Fehlermeldungen gibt.

kubectl get events --namespace=kube-system

Wenn nein, dann sollte nun alles wie folgt aussehen.

root@docker1 [ ~ ]# kubectl describe service kubernetes-dashboard --namespace=kube-system
Name:			kubernetes-dashboard
Namespace:		kube-system
Labels:			app=kubernetes-dashboard
Selector:		app=kubernetes-dashboard
Type:			NodePort
IP:			10.254.167.208
Port:			<unset>	80/TCP
NodePort:		<unset>	30978/TCP
Endpoints:		<none>
Session Affinity:	None
No events.


root@docker1 [ ~ ]# kubectl describe endpoints --namespace=kube-system
Name:		kubernetes-dashboard
Namespace:	kube-system
Labels:		app=kubernetes-dashboard
Subsets:
  Addresses:		<none>
  NotReadyAddresses:	172.17.0.2
  Ports:
    Name	Port	Protocol
    ----	----	--------
    <unset>	9090	TCP

No events.


root@docker1 [ ~ ]#  kubectl get pods --namespace=kube-system
NAME                                    READY     STATUS              RESTARTS   AGE
kubernetes-dashboard-2091788654-ko2vk   0/1       ContainerCreating   0          2m
root@docker1 [ ~ ]#

Update

Leider bekomme ich das Dashboard von Kubernetes nicht zum laufen. Und bislang weiß ich nicht wo das Problem liegt.