{"id":2423,"date":"2019-07-02T17:49:00","date_gmt":"2019-07-02T17:49:00","guid":{"rendered":"https:\/\/owncloud.com\/?p=2423"},"modified":"2020-07-07T16:39:31","modified_gmt":"2020-07-07T16:39:31","slug":"running-owncloud-in-kubernetes-with-rook-ceph-storage","status":"publish","type":"post","link":"https:\/\/owncloud.com\/de\/blogs\/running-owncloud-in-kubernetes-with-rook-ceph-storage\/","title":{"rendered":"Running ownCloud in Kubernetes With Rook Ceph Storage"},"content":{"rendered":"<div class=\"headline-wrap\">\n<p class=\"excerpt bold\">The first part will be about the basics and requirements of the setup, so the <a href=\"https:\/\/owncloud.com\/running-owncloud-in-kubernetes-with-rook-ceph-storage-step-by-step\/\">second part<\/a> can cover the details step by step. In summary, we want to reach the following:<\/p>\n<\/div>\n<div class=\"content\">\n<ul>\n<li>Outages of the hardware should neither lead to data loss nor availability problems.<\/li>\n<li>Rising user numbers should not cause problems, or at least be easier to handle:\n<ul>\n<li>Depending on the type of storage the servers use, Ceph is very performant and shouldn\u2019t have problems with many users.<\/li>\n<li>Depending on which ownCloud features are used, the other possible bottleneck, the database.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2 id=\"kubernetes-was-ist-das-\">What is Kubernetes?<\/h2>\n<p>Kubernetes is an orchestrator for containers. This means that you can run Kubernetes containers across many different servers, and ships other useful features. Apart from running containers, Kubernetes can do a lot more, e.g. make HTTP applications reachable from the Internet through the\u00a0<a href=\"https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/ingress\/\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes Ingress Feature<\/a>.<\/p>\n<p>The rest of this series requires some basic Kubernetes knowledge. If Kubernetes is still a Pandora\u2019s Box for you, you can build up that knowledge through the amazing tutorials by the\u00a0<a href=\"https:\/\/kubernetes.io\/docs\/tutorials\/\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes Project<\/a>.<\/p>\n<p>Note:\u00a0the second article of the series assumes that you have a working Kubernetes cluster with at least one Node \/ Worker.<\/p>\n<h2 id=\"was-brauchen-wir-daf-r-\">What Do We Need?<\/h2>\n<p>Let\u2019s start with the components which you always need. We can then work ourselves up to the corresponding tools and projects which can help us to do meet those needs in the Kubernetes environment.<\/p>\n<h2 id=\"datenbank-postgresql\">Database \u2013 PostgreSQL<\/h2>\n<p>Let\u2019s start with the most important component, the database.<\/p>\n<p>In the case of a small ownCloud instance, often SQLite is used as a database. SQLite is not made for high availability. You should think about a change to either PostgreSQL, MySQL, or Oracle in any case.<\/p>\n<p><a class=\"fancybox image\" href=\"https:\/\/owncloud.org\/wp-content\/uploads\/2019\/05\/ownCloud-server-hosting-anonymous-tor-data-center.jpg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-17385\" src=\"https:\/\/owncloud.org\/wp-content\/uploads\/2019\/05\/ownCloud-server-hosting-anonymous-tor-data-center.jpg\" sizes=\"(max-width: 1920px) 100vw, 1920px\" srcset=\"https:\/\/owncloud.org\/wp-content\/uploads\/2019\/05\/ownCloud-server-hosting-anonymous-tor-data-center.jpg 1920w, https:\/\/owncloud.org\/wp-content\/uploads\/2019\/05\/ownCloud-server-hosting-anonymous-tor-data-center-300x168.jpg 300w, https:\/\/owncloud.org\/wp-content\/uploads\/2019\/05\/ownCloud-server-hosting-anonymous-tor-data-center-768x431.jpg 768w, https:\/\/owncloud.org\/wp-content\/uploads\/2019\/05\/ownCloud-server-hosting-anonymous-tor-data-center-1024x574.jpg 1024w, https:\/\/owncloud.org\/wp-content\/uploads\/2019\/05\/ownCloud-server-hosting-anonymous-tor-data-center-1800x1010.jpg 1800w, https:\/\/owncloud.org\/wp-content\/uploads\/2019\/05\/ownCloud-server-hosting-anonymous-tor-data-center-1320x740.jpg 1320w\" alt=\"\" width=\"550\" height=\"270\" \/><\/a><\/p>\n<p>Support for the Oracle Database Server is available in the ownCloud Enterprise Edition. For more information about SQLite, see\u00a0<a href=\"https:\/\/central.owncloud.org\/t\/when-to-and-not-to-use-sqlite\/853\" target=\"_blank\" rel=\"noopener noreferrer\">When to and not to use SQLITE \u2013 FAQ \u2013 ownCloud Central<\/a>.<\/p>\n<p>One of the\u00a0<a href=\"https:\/\/doc.owncloud.com\/server\/10.1\/admin_manual\/configuration\/database\/linux_database_configuration.html\" target=\"_blank\" rel=\"noopener noreferrer\">supported databases<\/a>\u00a0is PostgreSQL. As there are relatively small operators in Kubernetes which can run a PostgreSQL cluster, we will use those.<\/p>\n<p>But before we show the \u201cPostgreSQL Operator\u201d, what even is such an operator?<\/p>\n<p>Simply put, an operator in Kubernetes is an automation mechanism. The operator can react to the database and create certain custom objects in Kubernetes, so called\u00a0<a href=\"https:\/\/kubernetes.io\/docs\/tasks\/access-kubernetes-api\/custom-resources\/custom-resource-definitions\/\" target=\"_blank\" rel=\"noopener noreferrer\">CustomResourceDefinitions<\/a>.<\/p>\n<p>This means as an eample for a PostgreSQL operator: when a PostgreSQL object is created, the operator reacts to it and automatically creates other Kubernetes objects (e.g. Services, Deployments, StatefulSets) to create a PostgreSQL cluster.<\/p>\n<p>In this article we will use\u00a0<a href=\"https:\/\/github.com\/zalando\/postgres-operator\" target=\"_blank\" rel=\"noopener noreferrer\">Zalando\u2019s Postgres Operator<\/a>\u00a0to run a PostgreSQL cluster in Kubernetes.<\/p>\n<h2 id=\"storage\">Storage<\/h2>\n<p>ownCloud needs storage to save uploaded files. The database needs storage, too, e.g. for user logins, app data, and shares.<\/p>\n<p>For ownCloud a file system storage like NFS makes the most sense. The reason for using file system storage instead of block storage is that block storage was never intended for more than for a Writer.<\/p>\n<p>You could also integrate\u00a0<a href=\"https:\/\/owncloud.org\/news\/following-open-standards-new-open-source-s3-storage-implementation\/\" target=\"_blank\" rel=\"noopener\">Object Storage like AWS S3<\/a>\u00a0into ownCloud, but in this series we will limit ourselves to the usage of file system storage.<\/p>\n<p>For PostgreSQL you should definitely use block storage though, if you want the best performance. The background is that the database can write more directly with block storage; the Linux kernel can assist with caching.<\/p>\n<p>Now as we answered the question which type of storage is best for which part of the setup, let\u2019s talk about the storage software.<\/p>\n<div id=\"attachment_17952\" class=\"wp-caption aligncenter\" style=\"width: 549px;\">\n<p><a class=\"fancybox image\" href=\"https:\/\/owncloud.org\/wp-content\/uploads\/2019\/06\/ownCloud-kraken-ceph-jewel.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-17952 \" src=\"https:\/\/owncloud.org\/wp-content\/uploads\/2019\/06\/ownCloud-kraken-ceph-jewel.png\" sizes=\"(max-width: 768px) 100vw, 768px\" srcset=\"https:\/\/owncloud.org\/wp-content\/uploads\/2019\/06\/ownCloud-kraken-ceph-jewel.png 768w, https:\/\/owncloud.org\/wp-content\/uploads\/2019\/06\/ownCloud-kraken-ceph-jewel-300x210.png 300w\" alt=\"ownCloud kraken ceph jewel storage\" width=\"549\" height=\"413\" aria-describedby=\"caption-attachment-17952\" \/><\/a><\/p>\n<p id=\"caption-attachment-17952\" class=\"wp-caption-text\"><em>The kraken is the mascot of Ceph storage.<\/em><\/p>\n<\/div>\n<h3 id=\"ceph\">Ceph<\/h3>\n<p>The\u00a0<a href=\"https:\/\/ceph.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Ceph<\/a>\u00a0Project has been around circa since 2006. The highest priority for Ceph is data security. Perfect for us, as we do not want to lose any of our valuable data, whether vacation photos, musix, or important documents.<\/p>\n<p>You don\u2019t have to worry about Ceph being continuously developed \u2013 the Ceph foundation supports Ceph centrally, to push the already strong development even more. This shows again how good it is if companies which use Open Source come together and pull in the same direction.<\/p>\n<p>Ceph is very complex, but offers many features. Apart from filesystem storage, you can also use it for block storage and object storage in different protocols (e.g. S3 or OpenStack SWIFT).<\/p>\n<p>A fundamental recommendation is to read the\u00a0<a href=\"http:\/\/docs.ceph.com\/docs\/master\/start\/intro\/\" target=\"_blank\" rel=\"noopener noreferrer\">Intro to Ceph \u2013 Ceph Documentation<\/a>\u00a0to understand the basic concepts.\u00a0<a href=\"https:\/\/ceph.com\/users\/\" target=\"_blank\" rel=\"noopener noreferrer\">CERN, Deutsche Telekom, and many other organizations and companies<\/a>\u00a0use Ceph as a storage system for their applications.<\/p>\n<p>Most likely now the questions appears \u2013 where is Ceph supposed to run? The question is good and easily answered \u2013 in Kubernetes of course.\u00a0<a href=\"https:\/\/rook.io\/\" target=\"_blank\" rel=\"noopener noreferrer\">Rook.io<\/a>\u00a0is the way to go here.<\/p>\n<p>Rook enables Ceph to run in Kubernetes, just as other software which keeps persistent files, e.g. EdgeFS, Minio, CockroachDB and others.<\/p>\n<p>Above at\u00a0Database \u2013 PostgreSQ<strong>L<\/strong>\u00a0we talked about Kubernetes operators. Rook is such an operator, which reacts to Kubernetes custom objects. If it reacts on\u00a0<code>CephCluster<\/code>\u00a0objects, it can e.g. create a Ceph cluster in Kubernetes.<\/p>\n<p>Apart from creating the Ceph cluster, at the moment Rook also takes care of creating and deleting volumes in Ceph, while managing the\u00a0<code>PersistentVolume<\/code>\u00a0object in Kubernetes.<\/p>\n<p>For everyone who is interested in containers and Kubernetes I recommend to read about the topics\u00a0<a href=\"https:\/\/kubernetes.io\/blog\/2019\/01\/15\/container-storage-interface-ga\/\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes Blog \u2013 Container Storage Interface (CSI)<\/a>\u00a0and\u00a0<a href=\"https:\/\/kubernetes.io\/docs\/concepts\/storage\/persistent-volumes\/\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes \u2013 Persistent Volumes<\/a>.<\/p>\n<p>Now, as we have dealt with the storage topic, there is only one component missing: Redis.<\/p>\n<h2 id=\"redis\">Redis<\/h2>\n<p>By default, the database takes care of file locking. In the end we want to take this extra effort away from the database effort. That\u2019s why we are going to use Redis for it. For this topic there is\u00a0<a href=\"https:\/\/doc.owncloud.com\/server\/admin_manual\/configuration\/files\/files_locking_transactional.html\" target=\"_blank\" rel=\"noopener noreferrer\">Transactional File Locking<\/a>.<\/p>\n<p>Again we are going to use an operator to make our life a bit easier. The\u00a0<a href=\"https:\/\/kubedb.com\/docs\/0.12.0\/welcome\/\" target=\"_blank\" rel=\"noopener noreferrer\">kubedb Operator<\/a>\u00a0can run Redis as a Cluster in Kubernetes.<\/p>\n<p>For more information about the Redis part in kubed Operator, take a look at the\u00a0<a href=\"https:\/\/kubedb.com\/docs\/0.12.0\/concepts\/databases\/redis\/\" target=\"_blank\" rel=\"noopener noreferrer\">kubedb Documentation<\/a>.<\/p>\n<h1 id=\"der-plan\">The Plan<\/h1>\n<p>For a final overview how this will look in Kubernetes, here is a diagram with the components:<\/p>\n<div id=\"attachment_17492\" class=\"wp-caption aligncenter\">\n<p><a class=\"fancybox image\" href=\"https:\/\/owncloud.org\/wp-content\/uploads\/2019\/06\/owncloud-in-kubernetes-rook-ceph.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-17492\" src=\"https:\/\/owncloud.org\/wp-content\/uploads\/2019\/06\/owncloud-in-kubernetes-rook-ceph.png\" sizes=\"(max-width: 1750px) 100vw, 1750px\" srcset=\"https:\/\/owncloud.org\/wp-content\/uploads\/2019\/06\/owncloud-in-kubernetes-rook-ceph.png 1750w, https:\/\/owncloud.org\/wp-content\/uploads\/2019\/06\/owncloud-in-kubernetes-rook-ceph-300x205.png 300w, https:\/\/owncloud.org\/wp-content\/uploads\/2019\/06\/owncloud-in-kubernetes-rook-ceph-768x525.png 768w, https:\/\/owncloud.org\/wp-content\/uploads\/2019\/06\/owncloud-in-kubernetes-rook-ceph-1024x700.png 1024w, https:\/\/owncloud.org\/wp-content\/uploads\/2019\/06\/owncloud-in-kubernetes-rook-ceph-1320x903.png 1320w\" alt=\"owncloud in kubernetes rook ceph\" width=\"1750\" height=\"1197\" aria-describedby=\"caption-attachment-17492\" \/><\/a><\/p>\n<p id=\"caption-attachment-17492\" class=\"wp-caption-text\">All necessary components in our Kubernetes cluster.<\/p>\n<\/div>\n<p>To summarize it in bullet points:<\/p>\n<ul>\n<li>Kubernetes to run ownCloud and the other components as containers.\n<ul>\n<li>Ingress controller which depends on the Kubernetes installation, to make ownCloud accessible from the Internet.<\/li>\n<\/ul>\n<\/li>\n<li><a href=\"https:\/\/github.com\/zalando\/postgres-operator\" target=\"_blank\" rel=\"noopener noreferrer\">Zalando\u2019s Postgres operator<\/a>\u00a0for PostgreSQL clusters in Kubernetes.<\/li>\n<li><a href=\"https:\/\/kubedb.com\/docs\/0.12.0\/welcome\/\" target=\"_blank\" rel=\"noopener noreferrer\">kubed operator<\/a>\u00a0for Redis clusters in Kubernetes.<\/li>\n<li>Ceph Storage via a\u00a0<a href=\"https:\/\/rook.io\/\" target=\"_blank\" rel=\"noopener noreferrer\">Rook.io<\/a>\u00a0container in Kubernetes.<\/li>\n<\/ul>\n<p>We will execute this plan step by step in the second part of this article series, to run ownCloud in Kubernetes, redundant and highly available.<\/p>\n<p><a class=\"button-oc\" href=\"https:\/\/owncloud.com\/running-owncloud-in-kubernetes-with-rook-ceph-storage-step-by-step\/\" target=\"\" rel=\"noopener noreferrer\">Step by Step: Run ownCloud in Kubernetes with a Rook Ceph Cluster!<\/a><\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This is the first half of a series about running ownCloud in Kubernetes, with focus on high availability, scalability, and performance \u2013 what are the optimal database and storage choices?<\/p>\n","protected":false},"author":7,"featured_media":5055,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","inline_featured_image":false,"footnotes":""},"categories":[43],"tags":[],"class_list":["post-2423","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"_links":{"self":[{"href":"https:\/\/owncloud.com\/de\/wp-json\/wp\/v2\/posts\/2423","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/owncloud.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/owncloud.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/owncloud.com\/de\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/owncloud.com\/de\/wp-json\/wp\/v2\/comments?post=2423"}],"version-history":[{"count":0,"href":"https:\/\/owncloud.com\/de\/wp-json\/wp\/v2\/posts\/2423\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/owncloud.com\/de\/wp-json\/wp\/v2\/media\/5055"}],"wp:attachment":[{"href":"https:\/\/owncloud.com\/de\/wp-json\/wp\/v2\/media?parent=2423"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/owncloud.com\/de\/wp-json\/wp\/v2\/categories?post=2423"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/owncloud.com\/de\/wp-json\/wp\/v2\/tags?post=2423"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}