Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
k8s_basic_storage [2020/05/22 15:35] – andonovj | k8s_basic_storage [2020/05/25 12:49] (current) – [Dynamic Provisioning] andonovj | ||
---|---|---|---|
Line 138: | Line 138: | ||
< | < | ||
+ | apiVersion: v1 | ||
kind: Pod | kind: Pod | ||
metadata: | metadata: | ||
Line 232: | Line 233: | ||
root@node-1:/ | root@node-1:/ | ||
</ | </ | ||
- | Lo and behold, the simple text file is on persistent storage and won't be affected | + | Lo and behold, the simple text file is on persistent storage and won't be affected |
- | As we mentioned, that kind of persistent storage allocation DOESN' | + | As we mentioned, that kind of persistent storage allocation DOESN' |
+ | |||
+ | {{ : | ||
+ | |||
+ | You see that, mapping and mapping and mapping | ||
=====Dynamic Provisioning===== | =====Dynamic Provisioning===== | ||
- | Let's configure Dynamic storage. | + | Let's configure Dynamic storage. |
+ | |||
+ | Now, for Dynamic provisioning with NFS I had to re-configure the cluster. In a nutshell make sure that teh API IP which you give when you initiate the cluster has the same subnet of the pod network. | ||
+ | |||
+ | For example: | ||
+ | |||
+ | < | ||
+ | kubeadm init --ignore-preflight-errors=NumCPU --apiserver-advertise-address=192.168.50.10 --pod-network-cidr=192.168.50.0/ | ||
+ | </ | ||
+ | |||
+ | Calico by default is using: 192.168.0.0/ | ||
+ | |||
+ | So let's get going. In the begining, I had something like that: | ||
+ | |||
+ | < | ||
+ | NAMESPACE | ||
+ | kube-system | ||
+ | kube-system | ||
+ | kube-system | ||
+ | kube-system | ||
+ | kube-system | ||
+ | kube-system | ||
+ | kube-system | ||
+ | kube-system | ||
+ | kube-system | ||
+ | kube-system | ||
+ | kube-system | ||
+ | kube-system | ||
+ | kube-system | ||
+ | ubuntu@k8s-master: | ||
+ | </ | ||
+ | |||
+ | So we have to create the following: | ||
+ | |||
+ | * Deployment | ||
+ | * Service Account | ||
+ | * Service | ||
+ | * RBAC | ||
+ | * Storage Class | ||
+ | * Claim | ||
+ | |||
+ | ====Create the Deployment, | ||
+ | You can see the deployment, | ||
+ | |||
+ | < | ||
+ | apiVersion: v1 | ||
+ | kind: ServiceAccount | ||
+ | metadata: | ||
+ | name: nfs-provisioner | ||
+ | --- | ||
+ | kind: Service | ||
+ | apiVersion: v1 | ||
+ | metadata: | ||
+ | name: nfs-provisioner | ||
+ | labels: | ||
+ | app: nfs-provisioner | ||
+ | spec: | ||
+ | ports: | ||
+ | - name: nfs | ||
+ | port: 2049 | ||
+ | - name: nfs-udp | ||
+ | port: 2049 | ||
+ | protocol: UDP | ||
+ | - name: nlockmgr | ||
+ | port: 32803 | ||
+ | - name: nlockmgr-udp | ||
+ | port: 32803 | ||
+ | protocol: UDP | ||
+ | - name: mountd | ||
+ | port: 20048 | ||
+ | - name: mountd-udp | ||
+ | port: 20048 | ||
+ | protocol: UDP | ||
+ | - name: rquotad | ||
+ | port: 875 | ||
+ | - name: rquotad-udp | ||
+ | port: 875 | ||
+ | protocol: UDP | ||
+ | - name: rpcbind | ||
+ | port: 111 | ||
+ | - name: rpcbind-udp | ||
+ | port: 111 | ||
+ | protocol: UDP | ||
+ | - name: statd | ||
+ | port: 662 | ||
+ | - name: statd-udp | ||
+ | port: 662 | ||
+ | protocol: UDP | ||
+ | selector: | ||
+ | app: nfs-provisioner | ||
+ | --- | ||
+ | kind: Deployment | ||
+ | apiVersion: apps/v1 | ||
+ | metadata: | ||
+ | name: nfs-provisioner | ||
+ | spec: | ||
+ | selector: | ||
+ | matchLabels: | ||
+ | app: nfs-provisioner | ||
+ | replicas: 1 | ||
+ | strategy: | ||
+ | type: Recreate | ||
+ | template: | ||
+ | metadata: | ||
+ | labels: | ||
+ | app: nfs-provisioner | ||
+ | spec: | ||
+ | serviceAccount: | ||
+ | containers: | ||
+ | - name: nfs-provisioner | ||
+ | image: quay.io/ | ||
+ | ports: | ||
+ | - name: nfs | ||
+ | containerPort: | ||
+ | - name: nfs-udp | ||
+ | containerPort: | ||
+ | protocol: UDP | ||
+ | - name: nlockmgr | ||
+ | containerPort: | ||
+ | - name: nlockmgr-udp | ||
+ | containerPort: | ||
+ | protocol: UDP | ||
+ | - name: mountd | ||
+ | containerPort: | ||
+ | - name: mountd-udp | ||
+ | containerPort: | ||
+ | protocol: UDP | ||
+ | - name: rquotad | ||
+ | containerPort: | ||
+ | - name: rquotad-udp | ||
+ | containerPort: | ||
+ | protocol: UDP | ||
+ | - name: rpcbind | ||
+ | containerPort: | ||
+ | - name: rpcbind-udp | ||
+ | containerPort: | ||
+ | protocol: UDP | ||
+ | - name: statd | ||
+ | containerPort: | ||
+ | - name: statd-udp | ||
+ | containerPort: | ||
+ | protocol: UDP | ||
+ | securityContext: | ||
+ | capabilities: | ||
+ | add: | ||
+ | - DAC_READ_SEARCH | ||
+ | - SYS_RESOURCE | ||
+ | args: | ||
+ | - " | ||
+ | env: | ||
+ | - name: POD_IP | ||
+ | valueFrom: | ||
+ | fieldRef: | ||
+ | fieldPath: status.podIP | ||
+ | - name: SERVICE_NAME | ||
+ | value: nfs-provisioner | ||
+ | - name: POD_NAMESPACE | ||
+ | valueFrom: | ||
+ | fieldRef: | ||
+ | fieldPath: metadata.namespace | ||
+ | imagePullPolicy: | ||
+ | volumeMounts: | ||
+ | - name: export-volume | ||
+ | mountPath: /export | ||
+ | volumes: | ||
+ | - name: export-volume | ||
+ | hostPath: | ||
+ | path: /srv | ||
+ | ubuntu@k8s-master: | ||
+ | serviceaccount/ | ||
+ | service/ | ||
+ | deployment.apps/ | ||
+ | </ | ||
+ | |||
+ | Then let's create the RBAC, which created the Cluster roles and maps them and of course the storage class | ||
+ | |||
+ | ===Create RBAC and Storage Class=== | ||
+ | < | ||
+ | kind: ClusterRole | ||
+ | apiVersion: rbac.authorization.k8s.io/ | ||
+ | metadata: | ||
+ | name: nfs-provisioner-runner | ||
+ | rules: | ||
+ | - apiGroups: ["" | ||
+ | resources: [" | ||
+ | verbs: [" | ||
+ | - apiGroups: ["" | ||
+ | resources: [" | ||
+ | verbs: [" | ||
+ | - apiGroups: [" | ||
+ | resources: [" | ||
+ | verbs: [" | ||
+ | - apiGroups: ["" | ||
+ | resources: [" | ||
+ | verbs: [" | ||
+ | - apiGroups: ["" | ||
+ | resources: [" | ||
+ | verbs: [" | ||
+ | - apiGroups: [" | ||
+ | resources: [" | ||
+ | resourceNames: | ||
+ | verbs: [" | ||
+ | --- | ||
+ | kind: ClusterRoleBinding | ||
+ | apiVersion: rbac.authorization.k8s.io/ | ||
+ | metadata: | ||
+ | name: run-nfs-provisioner | ||
+ | subjects: | ||
+ | - kind: ServiceAccount | ||
+ | name: nfs-provisioner | ||
+ | # replace with namespace where provisioner is deployed | ||
+ | namespace: default | ||
+ | roleRef: | ||
+ | kind: ClusterRole | ||
+ | name: nfs-provisioner-runner | ||
+ | apiGroup: rbac.authorization.k8s.io | ||
+ | --- | ||
+ | kind: Role | ||
+ | apiVersion: rbac.authorization.k8s.io/ | ||
+ | metadata: | ||
+ | name: leader-locking-nfs-provisioner | ||
+ | rules: | ||
+ | - apiGroups: ["" | ||
+ | resources: [" | ||
+ | verbs: [" | ||
+ | --- | ||
+ | kind: RoleBinding | ||
+ | apiVersion: rbac.authorization.k8s.io/ | ||
+ | metadata: | ||
+ | name: leader-locking-nfs-provisioner | ||
+ | subjects: | ||
+ | - kind: ServiceAccount | ||
+ | name: nfs-provisioner | ||
+ | # replace with namespace where provisioner is deployed | ||
+ | namespace: default | ||
+ | roleRef: | ||
+ | kind: Role | ||
+ | name: leader-locking-nfs-provisioner | ||
+ | apiGroup: rbac.authorization.k8s.io | ||
+ | ubuntu@k8s-master: | ||
+ | kind: StorageClass | ||
+ | apiVersion: storage.k8s.io/ | ||
+ | metadata: | ||
+ | name: example-nfs | ||
+ | provisioner: | ||
+ | mountOptions: | ||
+ | - vers=4.1 | ||
+ | ubuntu@k8s-master: | ||
+ | clusterrole.rbac.authorization.k8s.io/ | ||
+ | clusterrolebinding.rbac.authorization.k8s.io/ | ||
+ | role.rbac.authorization.k8s.io/ | ||
+ | rolebinding.rbac.authorization.k8s.io/ | ||
+ | ubuntu@k8s-master: | ||
+ | storageclass.storage.k8s.io/ | ||
+ | </ | ||
+ | |||
+ | ====Create Storage Claim==== | ||
+ | With Dynamic provisioning, | ||
+ | |||
+ | < | ||
+ | ubuntu@k8s-master: | ||
+ | kind: PersistentVolumeClaim | ||
+ | apiVersion: v1 | ||
+ | metadata: | ||
+ | name: nfs | ||
+ | annotations: | ||
+ | volume.beta.kubernetes.io/ | ||
+ | spec: | ||
+ | accessModes: | ||
+ | - ReadWriteMany | ||
+ | resources: | ||
+ | requests: | ||
+ | storage: 10Mi | ||
+ | ubuntu@k8s-master: | ||
+ | </ | ||
+ | |||
+ | ====Verify==== | ||
+ | We can verify the configuration as follows: | ||
+ | |||
+ | |||
+ | < | ||
+ | ubuntu@k8s-master: | ||
+ | NAME CAPACITY | ||
+ | persistentvolume/ | ||
+ | |||
+ | NAME STATUS | ||
+ | persistentvolumeclaim/ | ||
+ | ubuntu@k8s-master: | ||
+ | </ | ||
+ | |||
+ | Finally, we have a bounded PVC using Dynamic Provision. There is one very good git with all this files: | ||
+ | |||
+ | < | ||
+ | ubuntu@k8s-master: | ||
+ | ubuntu@k8s-master: | ||
+ | ubuntu@k8s-master: | ||
+ | total 32 | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | drwxr-xr-x | ||
+ | drwx------ | ||
+ | -rw-r--r-- | ||
+ | drwxrwxr-x | ||
+ | drwxr-xr-x | ||
+ | drwxrwxr-x 17 ubuntu ubuntu 4096 May 25 11:27 external-storage | ||
+ | </ | ||
+ | |||
+ | ====Create a Pod with Dynamic Provisioning==== | ||
+ | We can of course create a pod which will be using the NFS, let's create NGINX pod for example: | ||
+ | |||
+ | < | ||
+ | apiVersion: apps/v1 | ||
+ | kind: Deployment | ||
+ | metadata: | ||
+ | labels: | ||
+ | app: nginx | ||
+ | name: nfs-nginx | ||
+ | spec: | ||
+ | replicas: 1 | ||
+ | selector: | ||
+ | matchLabels: | ||
+ | app: nginx | ||
+ | template: | ||
+ | metadata: | ||
+ | labels: | ||
+ | app: nginx | ||
+ | spec: | ||
+ | volumes: | ||
+ | - name: nfs # | ||
+ | persistentVolumeClaim: | ||
+ | claimName: nfs # same name of pvc that was created | ||
+ | containers: | ||
+ | - image: nginx | ||
+ | name: nginx | ||
+ | volumeMounts: | ||
+ | - name: nfs # name of volume should match claimName volume | ||
+ | mountPath: mydata2 # mount inside of contianer | ||
+ | ubuntu@k8s-master: | ||
+ | deployment.apps/ | ||
+ | ubuntu@k8s-master: | ||
+ | NAME READY | ||
+ | nfs-nginx-6b4db6f57-4mczr | ||
+ | nfs-provisioner-7795cf6f4-d7m2l | ||
+ | ubuntu@k8s-master: | ||
+ | </ | ||
+ | |||
+ | Even an ubuntu pod: | ||
+ | < | ||
+ | ubuntu@k8s-master: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: first-pod | ||
+ | spec: | ||
+ | volumes: | ||
+ | - name: fast10m | ||
+ | persistentVolumeClaim: | ||
+ | claimName: nfs | ||
+ | containers: | ||
+ | - name: ctr1 | ||
+ | image: ubuntu: | ||
+ | command: | ||
+ | - /bin/bash | ||
+ | - " | ||
+ | - "sleep 60m" | ||
+ | volumeMounts: | ||
+ | - mountPath: "/ | ||
+ | name: fast10m | ||
+ | ubuntu@k8s-master: | ||
+ | NAME READY | ||
+ | first-pod | ||
+ | nfs-nginx-6b4db6f57-4mczr | ||
+ | nfs-provisioner-7795cf6f4-d7m2l | ||
+ | ubuntu@k8s-master: | ||
+ | </ | ||
+ | |||
+ | Eurika, finally we are done with both types of privisioning |