Projects:Kubernetes: verschil tussen versies

Naar navigatie springen Naar zoeken springen
6.830 bytes toegevoegd ,  5 feb 2020
k
Minnozz heeft pagina HSNWiki:Kubernetes hernoemd naar Projects:Kubernetes over een doorverwijzing
k (Minnozz heeft pagina HSNWiki:Kubernetes hernoemd naar Projects:Kubernetes over een doorverwijzing)
 
(14 tussenliggende versies door 3 gebruikers niet weergegeven)
Regel 947: Regel 947:
But, if we want to run our own Docker images inside Kubernetes, it will need to be able to pull them as well. This can be done by uploading our images to Docker Hub, but for our own experimentation, let's set up our own registry and plug Kubernetes into it.
But, if we want to run our own Docker images inside Kubernetes, it will need to be able to pull them as well. This can be done by uploading our images to Docker Hub, but for our own experimentation, let's set up our own registry and plug Kubernetes into it.


To begin with, the registry will need storage for its images. True to our earlier experiments, we start by creating a persistent volume claim.
To begin with, the registry will need storage for its images. True to our earlier experiments, we start by creating a persistent volume claim. (I'll assume there's a persistent volume to fulfill it; if not, check above how to create one yourself.)


To do: Set up Docker Registry. Push images to it. Start them in a pod.
<pre>
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: registry-files
spec:
  storageClassName: default
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
</pre>
 
The registry deployment:
 
<pre>
apiVersion: apps/v1
kind: Deployment
metadata:
  name: registry
spec:
  selector:
    matchLabels:
      app: registry
  replicas: 1
  template:
    metadata:
      labels:
        app: registry
    spec:
      volumes:
      - name: registrystorage
        persistentVolumeClaim:
          claimName: registry-files
      containers:
      - name: registry
        image: registry:2
        ports:
        - containerPort: 5000
        volumeMounts:
        - mountPath: /var/lib/registry
          name: registrystorage
</pre>
 
And a Service + Ingress to make it accessible on a new hostname. I found that Docker doesn't support accessing a registry with a path prefix, so we have to give it its own hostname. Luckily, with Traefik, it's easy to route; you'll only have to add a record in DNS.
 
<pre>
apiVersion: v1
kind: Service
metadata:
  name: registry-service
spec:
  selector:
    app: registry
  ports:
    - name: registry
      port: 5000
      protocol: TCP
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: registry-ingress
spec:
  rules:
  - host: kuberegistry.sjorsgielen.nl
    http:
      paths:
      - path: /
        backend:
          serviceName: registry-service
          servicePort: 5000
</pre>
 
After a minute, as before, https://kuberegistry.sjorsgielen.nl/v2/ (replace with your own hostname) should return 200 OK with a page content of "{}".
 
To test whether it's working, let's take the Ubuntu Docker image and push it onto our registry, as per [https://docs.docker.com/registry/ more or less these instructions]. Here, it's important that the registry is well-reachable over HTTPS, as Docker will only allow non-SSL HTTP communication over localhost! (Although you could get around this with a <code>kubectl port-forward</code>.)
 
<pre>
$ docker pull ubuntu
$ docker image tag ubuntu kuberegistry.sjorsgielen.nl/myubuntu
$ docker push kuberegistry.sjorsgielen.nl/myubuntu
[...] Retrying in 10 seconds
</pre>
 
That seems to fail. As before, we can figure out the root cause by getting the logs of the Registry pod:
 
<pre>
$ kubectl logs registry-6bf4dbcfb-9csf5
[...]
time="2019-03-28T21:44:04.465658668Z" level=error msg="response completed with error" err.code=unknown err.detail="filesystem: mkdir /var/lib/registry/docker: permission denied" err.message="unknown error" go.version=go1.11.2 http.request.host=kuberegistry.sjorsgielen.nl http.request.id=c00f2785-30b0-469d-bcff-70a12c0f604b http.request.method=POST http.request.remoteaddr=10.107.160.0 http.request.uri="/v2/myubuntu/blobs/uploads/" http.request.useragent="docker/18.06.1-ce go/go1.10.4 git-commit/e68fc7a kernel/4.4.0-112-generic os/linux arch/amd64 UpstreamClient(Docker-Client/18.06.1-ce \(linux\))" http.response.contenttype="application/json; charset=utf-8" http.response.duration=125.482304ms http.response.status=500 http.response.written=164 vars.name=myubuntu
</pre>
 
A "permission denied" error in "mkdir /var/lib/registry/docker". Now, we may not know the PersistentVolume behind whatever is mounted in the registry, but we can quickly find out by checking <code>kubectl describe deployment registry</code>, <code>kubectl get pvc</code> and <code>kubectl describe pv registry-storage</code>. In my case, it's because root squashing is enabled on my NFS mount and the directory is being accessed by root, therefore by an anonymous uid/gid, which doesn't have rights in the directory. It's easily fixed and now the push works:
 
<pre>
$ docker push kuberegistry.sjorsgielen.nl/myubuntu
The push refers to repository [kuberegistry.sjorsgielen.nl/myubuntu]
b57c79f4a9f3: Pushed
d60e01b37e74: Pushed
e45cfbc98a50: Pushed
762d8e1a6054: Pushed
latest: digest: sha256:f2557f94cac1cc4509d0483cb6e302da841ecd6f82eb2e91dc7ba6cfd0c580ab size: 1150
</pre>
 
Now, let's make our own Docker image, push it, and start it in a Pod!
 
Here's an example Dockerfile that runs a tiny Perl-based webserver that always responds with its own hostname:
 
<pre>
$ cat Dockerfile
FROM ubuntu:bionic
 
RUN apt-get update \
&& apt-get install -y libmojolicious-perl \
&& rm -rf /var/lib/apt/lists/*
 
# Normally, you'd use COPY here, but I wanted to keep this in one file
RUN echo "#!/usr/bin/env perl"                      >>/app.pl \
&& echo "use Mojolicious::Lite;"                    >>/app.pl \
&& echo "get '/' => sub {"                          >>/app.pl \
&& echo "  shift->render(text => 'Hello World!'); " >>/app.pl \
&& echo "};"                                        >>/app.pl \
&& echo "app->start;"                              >>/app.pl \
&& chmod +x /app.pl
 
EXPOSE 3000
CMD ["/app.pl", "daemon", "-l"]
$ docker build -t kuberegistry.sjorsgielen.nl/helloworld:latest .
$ docker push kuberegistry.sjorsgielen.nl/helloworld:latest
</pre>
 
At this point, you should be able to write a Deployment, Service and Ingress for this application, using the examples above. <code>kubectl apply</code> should then start the Pod, Traefik should route the service and whatever host/path you configured should quickly be reachable and respond with "Hello World". We've created our own image and ran it on your cluster!


= To do =
= To do =
Regel 956: Regel 1.089:
* Kubernetes Dashboard
* Kubernetes Dashboard
* Attempt Kubernetes upgrade from 1.13 to 1.14
* Attempt Kubernetes upgrade from 1.13 to 1.14
** https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-14/
** First, do a normal apt upgrade (the kubernetes packages are held and will not be modified)
** Then, unhold the kubeadm package on the master, upgrade it to the right version, then re-hold it
*** This only worked for me after unholding the kubelet and upgrading it as well.
** On the master, "kubeadm upgrade plan", then "kubeadm upgrade apply v1.14.x"
** Upgrade CNI controller by re-running the same <code>kubectl apply</code> as earlier
** Unhold the kubelet and kubectl packages on the master, upgrade them and re-hold them, then restart the kubelet
** For each worker, unhold the kubeadm package, upgrade it, rehold it; cordon (drain) the node; upgrade the node config; install the new kubelet version and restart it; uncordon the node.
*** Here too, this only worked for me after unholding the kubelet and upgrading it as well.
* Try getting information on a pod from inside it using the Kubernetes API
* Try getting information on a pod from inside it using the Kubernetes API
** https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/#accessing-the-api-from-a-pod
** <code>wget --ca-certificate=/run/secrets/kubernetes.io/serviceaccount/ca.crt -qO- https://kubernetes.default.svc.cluster.local/api/</code>
** Doesn't need using the Kubernetes API, can be done using env vars: https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/
* Play with native cronjobs
* Play with native cronjobs
* Play with Statefulset / Daemonset
* Play with Statefulset / Daemonset
Regel 964: Regel 1.109:
** Allow K8s API communication from a pod, but only to receive information about itself
** Allow K8s API communication from a pod, but only to receive information about itself
** Basically: Make it impossible to root a node even with "broad" privileges on the Kubernetes API server
** Basically: Make it impossible to root a node even with "broad" privileges on the Kubernetes API server
** https://kubernetes.io/docs/concepts/policy/pod-security-policy/
* Limiting pods in memory, CPU, I/O
* Limiting pods in memory, CPU, I/O
* Limiting pods in network communication
* Limiting pods in network communication
[[Categorie:Projects]]

Navigatiemenu