├── .gitignore ├── LICENSE ├── README.md ├── README.md_template ├── configmap ├── README.md └── configmap.yaml ├── daemonset ├── README.md └── daemonset.yaml ├── deployment ├── README.md ├── deployment_nginx.yaml └── deployment_taint.yaml ├── ingress ├── README.md └── ingress.yaml ├── job ├── README.md ├── cronjob.yaml └── job.yaml ├── networkpolicy ├── README.md └── network_policy.yaml ├── other └── resource_quota.yaml ├── persistentvolume ├── README.md ├── persistentvolume.yaml └── persistentvolumeclaim.yaml ├── pod ├── README.md ├── pod_busybox.yaml ├── pod_configmap.yaml ├── pod_init_container.yaml ├── pod_labels.yaml ├── pod_namespace.yaml ├── pod_nginx.yaml ├── pod_node_selector.yaml ├── pod_persistentvolumeclaim.yaml ├── pod_redis.yaml ├── pod_resource_limit_request.yaml ├── pod_secret.yaml ├── pod_specific_node.yaml └── pod_volumes.yaml ├── rbac ├── README.md ├── clusterrole.yaml ├── clusterrole_aggregated.yaml ├── clusterrolebinding.yaml ├── role.yaml ├── rolebinding.yaml └── rolebinding_ref_clusterrole.yaml ├── secrets ├── README.md └── secret.yaml └── service ├── README.md ├── service_external_ip.yaml ├── service_load_balancer.yaml └── service_node_port.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | # IntelliJ project files 2 | .idea 3 | *.iml 4 | out 5 | gen 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Jakub Nowakowski 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes Admin Helper 2 | 3 | This project contains selection of resources helpful for Kubernetes Administrators. 4 | 5 | Manifests templates are created based on official Kubernetes [Documentation](https://kubernetes.io/docs/) 6 | and [API Reference v1.9](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/) 7 | 8 | Cheat sheet commands are based on official [kubectl Cheat Sheet](https://kubernetes.io/docs/reference/kubectl/cheatsheet/) 9 | 10 | --- 11 | 12 | ## Autocompletion 13 | ```bash 14 | source <(kubectl completion bash) 15 | ``` 16 | 17 | ## Configuration and Maintenance 18 | ```bash 19 | kubectl config view 20 | kubectl config current-context 21 | kubectl config use-context CONTEXT 22 | 23 | kubectl cluster-info 24 | kubectl get componentstatuses 25 | kubectl get events 26 | 27 | # Logs 28 | kubectl logs --namespace=NAMESPACE POD_NAME --container=CONTAINER_NAME 29 | kubectl logs --previous POD_NAME --container=CONTAINER_NAME 30 | 31 | # Namespaces 32 | kubectl get namespace 33 | kubectl create namespace NAMESPACE 34 | ``` 35 | 36 | ## Resource lifecycle operations 37 | 38 | ### Create 39 | ```bash 40 | kubectl create -f my-manifest.yaml # create from file 41 | kubectl create -f my1.yaml -f my2.yaml # create from multiple files 42 | kubectl create -f dir # create from files in dir 43 | ``` 44 | 45 | ### Read 46 | ```bash 47 | kubectl get pods # List all pods in the namespace 48 | kubectl get pods --all-namespaces # List all pods in all namespaces 49 | kubectl get pods -o wide # List all pods in the namespace, with more details 50 | kubectl get pods --include-uninitialized # List all pods in the namespace, including uninitialized ones 51 | kubectl get pods --watch # List all pods and watch changes 52 | kubectl get pod my-pod # List a particular deployment 53 | 54 | kubectl describe nodes my-node 55 | 56 | kubectl get services --sort-by=.metadata.name # List Services Sorted by Name 57 | 58 | # List pods Sorted by Restart Count 59 | kubectl get pods --sort-by='.status.containerStatuses[0].restartCount' 60 | 61 | # Get the version label of all pods with label app=cassandra 62 | kubectl get pods --selector=app=cassandra -o jsonpath='{.items[*].metadata.labels.version}' 63 | 64 | # Get all running pods in the namespace 65 | kubectl get pods --field-selector=status.phase=Running 66 | 67 | # Get ExternalIPs of all nodes 68 | kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}' 69 | 70 | # List Names of Pods that belong to Particular Deployment 71 | # "jq" command useful for transformations that are too complex for jsonpath, it can be found at https://stedolan.github.io/jq/ 72 | sel=$(kubectl get deployment nginx-deployment -o=json | jq -j '.spec.selector.matchLabels | to_entries | map([.key,.value] | join("=")) | join(",")') 73 | kubectl get pods -l=$sel -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}' 74 | ``` 75 | ### Update 76 | ```bash 77 | # Force replace, delete and then re-create the resource. Will cause a service outage. 78 | kubectl replace --force -f ./pod.json 79 | ``` 80 | 81 | ## Node 82 | ```bash 83 | kubectl label node NODE KEY=VALUE 84 | 85 | kubectl get nodes --show-labels 86 | 87 | kubectl get nodes -o jsonpath="{$.items[*].metadata.labels}" 88 | 89 | # Taint 90 | kubectl taint node NODE_NAME LABEL_KEY=LABEL_VALUE:NoSchedule 91 | 92 | 93 | # Drain and Uncordon 94 | kubectl drain NODE_NAME 95 | kubectl uncordon NODE_NAME 96 | ``` 97 | 98 | ## etcd 99 | * [Operating etcd clusters for Kubernetes](https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/) 100 | 101 | GitHub: 102 | * [etcd](https://github.com/coreos/etcd) 103 | * [etcdctl](https://github.com/coreos/etcd/tree/master/etcdctl#etcdctl) 104 | 105 | ### Global flags 106 | ```bash 107 | # API version 108 | export ETCDCTL_API=3 109 | 110 | # Certificates 111 | export ETCDCTL_CACERT=/tmp/ca.pem 112 | export ETCDCTL_CERT=/tmp/cert.pem 113 | export ETCDCTL_KEY=/tmp/key.pem 114 | ``` 115 | 116 | ### Commands 117 | ```bash 118 | # List etcd cluster members 119 | etcdctl member list 120 | 121 | # List resources 122 | etcdctl ls 123 | etcdctl ls /registry 124 | 125 | # Backup 126 | etcdctl --endpoints snapshot save snapshotdb 127 | etcdctl --write-out=table snapshot status snapshotdb 128 | ``` 129 | 130 | ## systemd 131 | ```bash 132 | systemctl list-units | grep kube 133 | 134 | systemctl status kube-apiserver 135 | 136 | journalctl -u kubelet 137 | ``` 138 | 139 | ## Minikube 140 | ```bash 141 | minikube start 142 | minikube ip 143 | minikube version 144 | minikube ssh 145 | ``` 146 | 147 | ## containerd 148 | ```bash 149 | sudo ctr -n k8s.io containers list 150 | ``` -------------------------------------------------------------------------------- /README.md_template: -------------------------------------------------------------------------------- 1 | # NAME 2 | 3 | 4 | 5 | ## Resources 6 | * [Documentation](https://kubernetes.io/docs/xxx) 7 | * [API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/xxx) 8 | 9 | ## Kubectl commands 10 | 11 | `kubectl get xxx` 12 | 13 | ## Manifests 14 | 15 | ```yaml 16 | xxx 17 | ``` -------------------------------------------------------------------------------- /configmap/README.md: -------------------------------------------------------------------------------- 1 | # NAME 2 | 3 | ConfigMaps allow to decouple configuration artifacts from image content to keep containerized applications portable. 4 | 5 | ## Resources 6 | * [Documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/) 7 | * [API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#configmap-v1-core) 8 | 9 | ## Kubectl commands 10 | 11 | `kubectl get configmap` 12 | 13 | `kubectl create configmap --from-file=` 14 | 15 | `kubectl create configmap --from-file=` 16 | 17 | `kubectl create configmap --from-file==` 18 | 19 | `kubectl create configmap --from-literal== --from-literal==` 20 | 21 | ## Manifests 22 | 23 | ```yaml 24 | apiVersion: v1 25 | kind: ConfigMap 26 | metadata: 27 | name: example-config 28 | namespace: default 29 | data: 30 | # example of a simple property defined using --from-literal 31 | example.property.1: hello 32 | example.property.2: world 33 | # example of a complex property defined using --from-file 34 | example.property.file: |- 35 | property.1=value-1 36 | property.2=value-2 37 | property.3=value-3 38 | ``` 39 | 40 | ConfigMap usage in Pod: [pod_configmap.yaml](../pod/pod_configmap.yaml) 41 | 42 | -------------------------------------------------------------------------------- /configmap/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: example-config 5 | namespace: default 6 | data: 7 | # example of a simple property defined using --from-literal 8 | example.property.1: hello 9 | example.property.2: world 10 | # example of a complex property defined using --from-file 11 | example.property.file: |- 12 | property.1=value-1 13 | property.2=value-2 14 | property.3=value-3 -------------------------------------------------------------------------------- /daemonset/README.md: -------------------------------------------------------------------------------- 1 | # DaemonSet 2 | 3 | A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. As nodes are added to the cluster, Pods are added to them. 4 | As nodes are removed from the cluster, those Pods are garbage collected. 5 | 6 | ## Resources 7 | * [Documentation](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) 8 | * [API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#daemonset-v1-apps) 9 | 10 | ## Manifests 11 | 12 | [daemonset.yaml](daemonset.yaml) -------------------------------------------------------------------------------- /daemonset/daemonset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: DaemonSet 3 | metadata: 4 | name: fluentd-elasticsearch 5 | namespace: kube-system 6 | labels: 7 | k8s-app: fluentd-logging 8 | spec: 9 | selector: 10 | matchLabels: 11 | name: fluentd-elasticsearch 12 | template: 13 | metadata: 14 | labels: 15 | name: fluentd-elasticsearch 16 | spec: 17 | # Tolerate taints on nodes 18 | tolerations: 19 | - key: node-role.kubernetes.io/master 20 | effect: NoSchedule 21 | # Select nodes 22 | nodeSelector: 23 | disktype: ssd 24 | containers: 25 | - name: fluentd-elasticsearch 26 | image: gcr.io/google-containers/fluentd-elasticsearch:1.20 27 | resources: 28 | limits: 29 | memory: 200Mi 30 | requests: 31 | cpu: 100m 32 | memory: 200Mi 33 | volumeMounts: 34 | - name: varlog 35 | mountPath: /var/log 36 | terminationGracePeriodSeconds: 30 37 | volumes: 38 | - name: varlog 39 | hostPath: 40 | path: /var/log 41 | -------------------------------------------------------------------------------- /deployment/README.md: -------------------------------------------------------------------------------- 1 | # Deployment 2 | 3 | A Deployment controller provides declarative updates for Pods and ReplicaSets. 4 | 5 | You describe a desired state in a Deployment object, and the Deployment controller changes the actual state to the desired state at a controlled rate. You can define Deployments to create new ReplicaSets, or to remove existing Deployments and adopt all their resources with new Deployments. 6 | 7 | ## Resources 8 | * [Documentation](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) 9 | * [API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#deployment-v1-apps) 10 | 11 | ## Kubectl commands 12 | 13 | `kubectl create --record -f ` 14 | 15 | Append --record to this command to record the current command in the annotations of the created or updated resource. 16 | 17 | ### Updating a Deployment 18 | 19 | ```bash 20 | kubectl rollout status deployment/ 21 | 22 | kubectl set image deployment/ =: 23 | 24 | kubectl edit deployment/ 25 | 26 | kubectl set resources deployment nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi 27 | ``` 28 | 29 | ### Rolling Back a Deployment 30 | 31 | ```bash 32 | kubectl rollout history deployment/ 33 | 34 | kubectl rollout history deployment/ --revision= 35 | 36 | kubectl rollout undo deployment/ 37 | 38 | kubectl rollout undo deployment/ --to-revision= 39 | ``` 40 | 41 | ### Scaling a Deployment 42 | 43 | `kubectl scale deployment --replicas=` 44 | 45 | `kubectl autoscale deployment --min= --max= --cpu-percent=` 46 | 47 | ### Pausing and Resuming a Deployment 48 | 49 | `kubectl rollout pause deployment/` 50 | 51 | `kubectl rollout resume deployment/` 52 | 53 | ## Manifests 54 | 55 | ```yaml 56 | xxx 57 | ``` -------------------------------------------------------------------------------- /deployment/deployment_nginx.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nginx-deployment 5 | labels: 6 | app: nginx 7 | spec: 8 | replicas: 5 9 | selector: 10 | matchLabels: 11 | app: nginx 12 | strategy: 13 | type: RollingUpdate 14 | rollingUpdate: 15 | maxUnavailable: 3 16 | maxSurge: 2 17 | template: 18 | metadata: 19 | labels: 20 | app: nginx 21 | spec: 22 | containers: 23 | - name: nginx 24 | image: nginx:1.7.9 25 | ports: 26 | - containerPort: 80 27 | 28 | -------------------------------------------------------------------------------- /deployment/deployment_taint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: taint-deployment 5 | spec: 6 | replicas: 8 7 | template: 8 | metadata: 9 | labels: 10 | app: nginx 11 | spec: 12 | containers: 13 | - name: nginx 14 | image: nginx:1.7.9 15 | ports: 16 | - containerPort: 80 17 | -------------------------------------------------------------------------------- /ingress/README.md: -------------------------------------------------------------------------------- 1 | # Ingress 2 | Manages external access to the services in a cluster, typically HTTP. 3 | 4 | ## Resources 5 | * [Documentation](https://kubernetes.io/docs/concepts/services-networking/ingress/) 6 | * [API Reference](https://kubernetes.io/docs/api-reference/v1.9/#ingress-v1beta1-extensions) 7 | 8 | ## Kubectl commands 9 | 10 | `kubectl get ingress` 11 | 12 | `kubectl edit ingress ingress-name` 13 | 14 | `kubectl replace -f ingress.yaml` 15 | 16 | ## Manifests 17 | 18 | [ingress.yaml](ingress.yaml) 19 | ```yaml 20 | apiVersion: extensions/v1beta1 21 | kind: Ingress 22 | metadata: 23 | name: ghost 24 | spec: 25 | rules: 26 | - host: ghost.192.168.99.100.nip.io 27 | http: 28 | paths: 29 | - backend: 30 | serviceName: ghost 31 | servicePort: 2368 32 | - host: nginx.192.168.99.100.nip.io 33 | http: 34 | paths: 35 | - backend: 36 | serviceName: nginx 37 | servicePort: 80 38 | ``` 39 | 40 | -------------------------------------------------------------------------------- /ingress/ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: ghost 5 | spec: 6 | rules: 7 | - host: ghost.192.168.99.100.nip.io 8 | http: 9 | paths: 10 | - backend: 11 | serviceName: ghost 12 | servicePort: 2368 13 | - host: nginx.192.168.99.100.nip.io 14 | http: 15 | paths: 16 | - backend: 17 | serviceName: nginx 18 | servicePort: 80 19 | -------------------------------------------------------------------------------- /job/README.md: -------------------------------------------------------------------------------- 1 | # NAME 2 | 3 | A job creates one or more pods and ensures that a specified number of them successfully terminate. 4 | 5 | ## Resources 6 | * [Documentation](https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/) 7 | * [API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#job-v1-batch) 8 | 9 | ## Kubectl commands 10 | 11 | `kubectl get xxx` 12 | 13 | ## Manifests 14 | 15 | ```yaml 16 | apiVersion: batch/v1 17 | kind: Job 18 | metadata: 19 | name: pi 20 | spec: 21 | template: 22 | spec: 23 | containers: 24 | - name: pi 25 | image: perl 26 | command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] 27 | restartPolicy: Never # Other possibility: OnFailure 28 | backoffLimit: 4 29 | # Parallel Jobs - Fixed Completion Count job 30 | # You can set "parallelism" if you want parallel execution of jobs 31 | completions: 5 32 | # Parallel Jobs - Work Queue Job job 33 | # Do not set "completions" 34 | parallelism: 2 35 | ``` -------------------------------------------------------------------------------- /job/cronjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1beta1 2 | kind: CronJob 3 | metadata: 4 | name: hello 5 | spec: 6 | schedule: "*/1 * * * *" 7 | jobTemplate: 8 | spec: 9 | template: 10 | spec: 11 | containers: 12 | - name: hello 13 | image: busybox 14 | args: 15 | - /bin/sh 16 | - -c 17 | - date; echo Hello from the Kubernetes cluster 18 | restartPolicy: OnFailure -------------------------------------------------------------------------------- /job/job.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: pi 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - name: pi 10 | image: perl 11 | command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] 12 | restartPolicy: Never # Other possibility: OnFailure 13 | backoffLimit: 4 14 | # Parallel Jobs - Fixed Completion Count job 15 | # You can set "parallelism" if you want parallel execution of jobs 16 | completions: 5 17 | # Parallel Jobs - Work Queue Job job 18 | # Do not set "completions" 19 | parallelism: 2 -------------------------------------------------------------------------------- /networkpolicy/README.md: -------------------------------------------------------------------------------- 1 | # Network Policy 2 | A network policy is a specification of how groups of pods are allowed to communicate with each other and other network endpoints. 3 | 4 | **NetworkPolicy** resources use labels to select pods and define rules which specify what traffic is allowed to the selected pods. 5 | 6 | By default, pods are non-isolated, they accept traffic from any source. 7 | Pods become isolated by having a NetworkPolicy that selects them. 8 | 9 | ## Resources 10 | * [Documentation: Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/) 11 | * [Documentation: Declare Network Policy](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy/) 12 | * [API Reference](https://kubernetes.io/docs/api-reference/v1.9/#networkpolicy-v1-networking) 13 | * [Blog: Securing Kubernetes Cluster Networking](https://ahmet.im/blog/kubernetes-network-policy/) 14 | 15 | ## Kubectl commands 16 | 17 | `kubectl get networkpolicies` 18 | 19 | ## Manifests 20 | 21 | ```yaml 22 | apiVersion: networking.k8s.io/v1 23 | kind: NetworkPolicy 24 | metadata: 25 | name: access-nginx 26 | namespace: default 27 | spec: 28 | podSelector: 29 | matchLabels: 30 | run: nginx 31 | ingress: 32 | - from: 33 | - podSelector: 34 | matchLabels: 35 | access: "true" 36 | - ipBlock: 37 | cidr: 172.17.0.0/16 38 | except: 39 | - 172.17.1.0/24 40 | - namespaceSelector: 41 | matchLabels: 42 | project: myproject 43 | ports: 44 | - protocol: TCP 45 | port: 6379 46 | egress: 47 | - to: 48 | - ipBlock: 49 | cidr: 10.0.0.0/24 50 | ports: 51 | - protocol: TCP 52 | port: 5978 53 | ``` 54 | 55 | 56 | -------------------------------------------------------------------------------- /networkpolicy/network_policy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: NetworkPolicy 3 | metadata: 4 | name: access-nginx 5 | namespace: default 6 | spec: 7 | podSelector: 8 | matchLabels: 9 | run: nginx 10 | ingress: 11 | - from: 12 | - podSelector: 13 | matchLabels: 14 | access: "true" 15 | - ipBlock: 16 | cidr: 172.17.0.0/16 17 | except: 18 | - 172.17.1.0/24 19 | - namespaceSelector: 20 | matchLabels: 21 | project: myproject 22 | ports: 23 | - protocol: TCP 24 | port: 6379 25 | egress: 26 | - to: 27 | - ipBlock: 28 | cidr: 10.0.0.0/24 29 | ports: 30 | - protocol: TCP 31 | port: 5978 -------------------------------------------------------------------------------- /other/resource_quota.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ResourceQuota 3 | metadata: 4 | name: mem-cpu-demo 5 | spec: 6 | hard: 7 | requests.cpu: "0.5" 8 | requests.memory: 512Mi 9 | limits.cpu: "2" 10 | limits.memory: 1Gi 11 | -------------------------------------------------------------------------------- /persistentvolume/README.md: -------------------------------------------------------------------------------- 1 | # NAME 2 | 3 | A **PersistentVolume** (PV) is a piece of storage in the cluster that has been provisioned by an administrator. 4 | PVs are volume plugins like Volumes, but have a lifecycle independent of any individual pod that uses the PV. 5 | 6 | A **PersistentVolumeClaim** (PVC) is a request for storage by a user. 7 | 8 | ## Resources 9 | * [Documentation](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) 10 | * [API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#persistentvolume-v1-core) 11 | 12 | ## Kubectl commands 13 | 14 | `kubectl get pv` 15 | 16 | `kubectl get pvc` 17 | 18 | ## Manifests 19 | 20 | Sample PersistentVolume manifest: [persistentvolume.yaml](persistentvolume.yaml)
21 | Sample PersistentVolumeClaim manifest: [persistentvolumeclaim.yaml](persistentvolumeclaim.yaml) 22 | 23 | Usage of PersistentVolumeClaim in Pod: [pod_persistentvolumeclaim.yaml](../pod/pod_persistentvolumeclaim.yaml) -------------------------------------------------------------------------------- /persistentvolume/persistentvolume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: pv0003 5 | spec: 6 | capacity: 7 | storage: 5Gi 8 | volumeMode: Filesystem 9 | accessModes: 10 | - ReadWriteOnce # other options: ReadOnlyMany, ReadWriteMany 11 | persistentVolumeReclaimPolicy: Recycle 12 | storageClassName: slow 13 | mountOptions: 14 | - hard 15 | - nfsvers=4.1 16 | nfs: 17 | path: /tmp 18 | server: 172.17.0.2 -------------------------------------------------------------------------------- /persistentvolume/persistentvolumeclaim.yaml: -------------------------------------------------------------------------------- 1 | kind: PersistentVolumeClaim 2 | apiVersion: v1 3 | metadata: 4 | name: myclaim 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | volumeMode: Filesystem 9 | resources: 10 | requests: 11 | storage: 8Gi 12 | storageClassName: slow 13 | selector: 14 | matchLabels: 15 | release: "stable" 16 | matchExpressions: 17 | - {key: environment, operator: In, values: [dev]} -------------------------------------------------------------------------------- /pod/README.md: -------------------------------------------------------------------------------- 1 | # Pods 2 | 3 | ## Resources 4 | * [Documentation](https://kubernetes.io/docs/concepts/workloads/pods/pod/) 5 | * [API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#pod-v1-core) 6 | 7 | ## Kubectl commands 8 | 9 | ```bash 10 | kubectl label pod my-pod new-label=awesome # Add a Label 11 | kubectl annotate pod my-pod icon-url=http://goo.gl/XXBTWq # Add an annotation 12 | 13 | kubectl get pods --show-labels 14 | kubectl get pods -LKEY 15 | 16 | kubectl port-forward POD_NAME LOCAL_PORT:POD_PORT 17 | 18 | kubectl exec -ti POD_NAME -- /bin/sh 19 | kubectl run -it --rm --restart=Never busybox --image=busybox sh 20 | ``` 21 | 22 | * Get all pods for node `` 23 | ```bash 24 | kubectl get pods -o jsonpath='{range .items[?(@.spec.nodeName=="")]}{.metadata.name}{"\n"}' --all-namespaces 25 | ``` 26 | 27 | * Get pods with _pod name_ and _node names_ sort by second column 28 | ```bash 29 | kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.nodeName}{"\n"}' --all-namespaces | sort -k 2 30 | ``` 31 | 32 | ## Manifests 33 | 34 | ```yaml 35 | apiVersion: v1 36 | kind: Pod 37 | metadata: 38 | name: busybox 39 | namespace: default 40 | spec: 41 | containers: 42 | - name: busybox 43 | image: busybox 44 | command: 45 | - sleep 46 | - "3600" 47 | ``` 48 | -------------------------------------------------------------------------------- /pod/pod_busybox.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: busybox 5 | namespace: default 6 | spec: 7 | containers: 8 | - name: busybox 9 | image: busybox 10 | command: 11 | - sleep 12 | - "3600" 13 | -------------------------------------------------------------------------------- /pod/pod_configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: configmapPod 5 | spec: 6 | containers: 7 | - name: test-container 8 | image: k8s.gcr.io/busybox 9 | # Use ConfigMap-defined environment variables in Pod commands 10 | command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] 11 | # Define a Pod environment variable with data from a single ConfigMap 12 | env: 13 | - name: SPECIAL_LEVEL_KEY 14 | valueFrom: 15 | configMapKeyRef: 16 | name: special-config 17 | key: special.how 18 | # Configure all key-value pairs in a ConfigMap as Pod environment variables 19 | envFrom: 20 | - configMapRef: 21 | name: special-config 22 | # Populate a Volume with data stored in a ConfigMap 23 | volumeMounts: 24 | - name: config-volume 25 | mountPath: /etc/config 26 | volumes: 27 | - name: config-volume 28 | configMap: 29 | # Provide the name of the ConfigMap containing the files you want to add to the container 30 | name: special-config 31 | # Add ConfigMap data to a specific path in the Volume 32 | items: 33 | - key: log_level 34 | path: log_level -------------------------------------------------------------------------------- /pod/pod_init_container.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: myapp-pod 5 | labels: 6 | app: myapp 7 | spec: 8 | containers: 9 | - name: myapp-container 10 | image: busybox 11 | command: ['sh', '-c', 'echo The app is running! && sleep 3600'] 12 | initContainers: 13 | - name: init-myservice 14 | image: busybox 15 | command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;'] 16 | - name: init-log 17 | image: busybox 18 | command: ['sh', '-c', 'touch myapp.log'] -------------------------------------------------------------------------------- /pod/pod_labels.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: vip 5 | labels: 6 | env: test 7 | spec: 8 | containers: 9 | - name: busybox 10 | image: busybox 11 | args: 12 | - sleep 13 | - "360" 14 | -------------------------------------------------------------------------------- /pod/pod_namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: busybox 5 | namespace: linuxcon 6 | spec: 7 | containers: 8 | - name: busybox 9 | image: busybox 10 | command: 11 | - sleep 12 | - "3600" 13 | -------------------------------------------------------------------------------- /pod/pod_nginx.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: nginx 5 | spec: 6 | containers: 7 | - name: nginx 8 | image: nginx 9 | -------------------------------------------------------------------------------- /pod/pod_node_selector.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: vip 5 | labels: 6 | env: test 7 | spec: 8 | containers: 9 | - name: vip1 10 | image: busybox 11 | args: 12 | - sleep 13 | - "1000000" 14 | - name: vip2 15 | image: busybox 16 | args: 17 | - sleep 18 | - "1000000" 19 | - name: vip3 20 | image: busybox 21 | args: 22 | - sleep 23 | - "1000000" 24 | - name: vip4 25 | image: busybox 26 | args: 27 | - sleep 28 | - "1000000" 29 | nodeSelector: 30 | status: other 31 | # kubernetes.io/hostname: node3 32 | -------------------------------------------------------------------------------- /pod/pod_persistentvolumeclaim.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: mypod 5 | spec: 6 | containers: 7 | - name: myfrontend 8 | image: dockerfile/nginx 9 | volumeMounts: 10 | - mountPath: "/var/www/html" 11 | name: mypd 12 | volumes: 13 | - name: mypd 14 | persistentVolumeClaim: 15 | claimName: myclaim -------------------------------------------------------------------------------- /pod/pod_redis.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: redis 5 | spec: 6 | containers: 7 | - name: redis 8 | image: redis 9 | -------------------------------------------------------------------------------- /pod/pod_resource_limit_request.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: busybox 5 | namespace: limited 6 | spec: 7 | containers: 8 | - name: busybox 9 | image: busybox 10 | command: 11 | - sleep 12 | - "3600" 13 | resources: 14 | requests: 15 | cpu: "0.3" 16 | memory: "300Mi" 17 | limits: 18 | cpu: "0.5" 19 | memory: "400Mi" 20 | -------------------------------------------------------------------------------- /pod/pod_secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: mysql 5 | spec: 6 | containers: 7 | - name: mysql 8 | image: mysql:5.5 9 | env: 10 | - name: MYSQL_ROOT_PASSWORD 11 | valueFrom: 12 | secretKeyRef: 13 | name: mysql 14 | key: password 15 | volumeMounts: 16 | - name: foo 17 | mountPath: "/etc/foo" 18 | readOnly: true 19 | volumes: 20 | - name: foo 21 | secret: 22 | secretName: mysecret 23 | -------------------------------------------------------------------------------- /pod/pod_specific_node.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: busybox 5 | spec: 6 | nodeName: node3 7 | containers: 8 | - name: busybox 9 | image: busybox 10 | args: 11 | - sleep 12 | - "360" 13 | -------------------------------------------------------------------------------- /pod/pod_volumes.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: test-pd 5 | spec: 6 | containers: 7 | - image: k8s.gcr.io/test-webserver 8 | name: test-container 9 | volumeMounts: 10 | - mountPath: /cache 11 | name: cache-volume 12 | subPath: mysql # sub-path inside the referenced volume instead of its root 13 | volumes: 14 | - name: cache-volume 15 | emptyDir: {} -------------------------------------------------------------------------------- /rbac/README.md: -------------------------------------------------------------------------------- 1 | # Role-Based Access Control 2 | 3 | Role-Based Access Control (“RBAC”) uses the “rbac.authorization.k8s.io” API group to drive authorization decisions, allowing admins to 4 | dynamically configure policies through the Kubernetes API. 5 | 6 | To enable RBAC, start the apiserver with `--authorization-mode=RBAC`. 7 | 8 | ## Resources 9 | * [Documentation](https://kubernetes.io/docs/admin/authorization/rbac/) 10 | * API References: 11 | * [Role](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#role-v1-rbac) 12 | * [ClusterRole](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#clusterrole-v1-rbac) 13 | * [RoleBinding](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#rolebinding-v1-rbac) 14 | * [ClusterRoleBinding](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#clusterrolebinding-v1-rbac) 15 | 16 | 17 | ## Kubectl commands 18 | 19 | `kubectl create rolebinding --clusterrole= --user= --namespace=` 20 | 21 | `kubectl create clusterrolebinding --clusterrole= --serviceaccount=` 22 | 23 | ## Role and ClusterRole 24 | [Documentation](https://kubernetes.io/docs/admin/authorization/rbac/#role-and-clusterrole) 25 | 26 | **Role** can only be used to grant access to resources within a single namespace. Sample manifest: [role.yaml](role.yaml) 27 | 28 | **ClusterRole** can be used to grant the same permissions as a Role, but because they are cluster-scoped, they can also be used to grant access to: 29 | * cluster-scoped resources (like nodes) 30 | * non-resource endpoints (like “/healthz”) 31 | * namespaced resources (like pods) across all namespaces (needed to run `kubectl get pods --all-namespaces`). 32 | Sample manifest: [cluster_role.yaml](clusterrole.yaml) 33 | 34 | ## RoleBinding and ClusterRoleBinding 35 | [Documentation](https://kubernetes.io/docs/admin/authorization/rbac/#rolebinding-and-clusterrolebinding) 36 | 37 | A role binding grants the permissions defined in a role to a user or set of users. 38 | 39 | Permissions can be granted within a namespace with a **RoleBinding**, or cluster-wide with a **ClusterRoleBinding**. 40 | 41 | * A **RoleBinding** may reference a **Role** in the same namespace. Sample manifest: [rolebinding.yaml](rolebinding.yaml) 42 | 43 | * A **RoleBinding** may reference a **ClusterRole** to grant the permissions within the *RoleBinding* namespace. Sample manifest: [rolebinding_ref_clusterrole.yaml](rolebinding_ref_clusterrole.yaml) 44 | 45 | * A **ClusterRoleBinding** may be used to grant permission at the cluster level and in all namespaces. Sample manifest: [clusterrolebinding.yaml](clusterrolebinding.yaml) 46 | 47 | ## Aggregated ClusterRoles 48 | [Documentation](https://kubernetes.io/docs/admin/authorization/rbac/#aggregated-clusterroles) 49 | 50 | ClusterRoles can be created by combining other ClusterRoles using an `aggregationRule` 51 | 52 | Sample manifest: [clusterrole_aggregated.yaml](clusterrole_aggregated.yaml) 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /rbac/clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: secret-reader 5 | # "namespace" omitted since ClusterRoles are not namespaced 6 | labels: 7 | rbac.example.com/aggregate-to-monitoring: "true" 8 | rules: 9 | - apiGroups: [""] 10 | resources: ["secrets"] 11 | verbs: ["get", "watch", "list"] 12 | - apiGroups: [""] 13 | resources: ["nodes"] 14 | verbs: ["get", "list", "watch"] 15 | - nonResourceURLs: ["/healthz", "/healthz/*"] # '*' in a nonResourceURL is a suffix glob match 16 | verbs: ["get", "post"] -------------------------------------------------------------------------------- /rbac/clusterrole_aggregated.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: monitoring 5 | aggregationRule: 6 | clusterRoleSelectors: 7 | - matchLabels: 8 | rbac.example.com/aggregate-to-monitoring: "true" 9 | rules: [] # Rules are automatically filled in by the controller manager. -------------------------------------------------------------------------------- /rbac/clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | # This cluster role binding allows anyone in the "manager" group to read secrets in any namespace. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRoleBinding 4 | metadata: 5 | name: read-secrets-global 6 | subjects: 7 | - kind: Group 8 | name: manager 9 | apiGroup: rbac.authorization.k8s.io 10 | roleRef: 11 | kind: ClusterRole 12 | name: secret-reader 13 | apiGroup: rbac.authorization.k8s.io -------------------------------------------------------------------------------- /rbac/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: dev-role 5 | namespace: developement 6 | rules: 7 | - apiGroups: [""] # "" indicates the core API group 8 | resources: ["pods", "pods/log"] 9 | verbs: ["*"] 10 | - apiGroups: [""] 11 | resources: ["configmaps"] 12 | resourceNames: ["my-configmap"] # restrict the role to specifically named resource 13 | verbs: ["update", "get"] 14 | - apiGroups: ["extensions", "apps"] 15 | resources: ["deployments"] 16 | verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] -------------------------------------------------------------------------------- /rbac/rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: read-pods 5 | namespace: developement 6 | subjects: 7 | # For a user named “jane” 8 | - kind: User 9 | name: "jane" 10 | apiGroup: rbac.authorization.k8s.io 11 | # For a group named “frontend-admins” 12 | - kind: Group 13 | name: "frontend-admins" 14 | apiGroup: rbac.authorization.k8s.io 15 | # For the default service account in the kube-system namespace 16 | - kind: ServiceAccount 17 | name: default 18 | namespace: kube-system 19 | # For all service accounts in the “qa” namespace 20 | - kind: Group 21 | name: system:serviceaccounts:qa 22 | apiGroup: rbac.authorization.k8s.io 23 | # For all service accounts everywhere 24 | - kind: Group 25 | name: system:serviceaccounts 26 | apiGroup: rbac.authorization.k8s.io 27 | # For all authenticated users 28 | - kind: Group 29 | name: system:authenticated # for unauthenticated users set to "system:unauthenticated" 30 | apiGroup: rbac.authorization.k8s.io 31 | roleRef: 32 | kind: Role 33 | name: dev-role 34 | apiGroup: rbac.authorization.k8s.io 35 | -------------------------------------------------------------------------------- /rbac/rolebinding_ref_clusterrole.yaml: -------------------------------------------------------------------------------- 1 | # This role binding allows "dave" to read secrets in the "development" namespace. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: RoleBinding 4 | metadata: 5 | name: read-secrets 6 | namespace: development # This only grants permissions within the "development" namespace. 7 | subjects: 8 | - kind: User 9 | name: dave 10 | apiGroup: rbac.authorization.k8s.io 11 | roleRef: 12 | kind: ClusterRole 13 | name: secret-reader 14 | apiGroup: rbac.authorization.k8s.io -------------------------------------------------------------------------------- /secrets/README.md: -------------------------------------------------------------------------------- 1 | # Secrets 2 | 3 | A Secret is an object that contains a small amount of sensitive data such as a password, a token, or a key. 4 | 5 | ## Resources 6 | * [Documentation](https://kubernetes.io/docs/concepts/configuration/secret/) 7 | * [API Reference](https://kubernetes.io/docs/api-reference/v1.9/#secret-v1-core) 8 | 9 | ## Kubectl commands 10 | 11 | `kubectl get secrets` 12 | 13 | `kubectl create secret generic --from-file=` 14 | 15 | `kubectl create secret generic --from-literal==` 16 | 17 | ## Creating a Secret Manually 18 | [Documentation](https://kubernetes.io/docs/concepts/configuration/secret/#creating-a-secret-manually) 19 | 20 | ### Encode a Secret 21 | Encode text with base64: 22 | ```bash 23 | $ echo -n "admin" | base64 24 | YWRtaW4= 25 | ``` 26 | 27 | Create manifest for the secret: 28 | ```yaml 29 | apiVersion: v1 30 | kind: Secret 31 | metadata: 32 | name: mysecret 33 | data: 34 | username: YWRtaW4= 35 | ``` 36 | 37 | ### Decode a Secret 38 | 39 | ```bash 40 | $ echo "YWRtaW4=" | base64 --decode 41 | admin 42 | ``` 43 | 44 | ## Manifests 45 | 46 | ```yaml 47 | apiVersion: v1 48 | kind: Secret 49 | metadata: 50 | name: manual-secret 51 | data: 52 | username: YWRtaW4= 53 | password: MWYyZDFlMmU2N2Rm 54 | ``` 55 | 56 | ## Use Secret in Pod 57 | Sample manifest: [pod_secret.yaml](../pod/pod_secret.yaml) -------------------------------------------------------------------------------- /secrets/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: manual-secret 5 | data: 6 | username: YWRtaW4= 7 | password: MWYyZDFlMmU2N2Rm 8 | -------------------------------------------------------------------------------- /service/README.md: -------------------------------------------------------------------------------- 1 | # Service 2 | 3 | A Kubernetes Service is an abstraction which defines a logical set of Pods and a policy by which to access them - 4 | sometimes called a micro-service. 5 | 6 | The set of Pods targeted by a Service is (usually) determined by a Label Selector. 7 | 8 | ## Resources 9 | * [Documentation](https://kubernetes.io/docs/concepts/services-networking/service/) 10 | * [API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#service-v1-core) 11 | 12 | ## Kubectl commands 13 | 14 | `kubectl get service` 15 | 16 | `kubectl expose deployment/` 17 | 18 | `kubectl​ ​expose​ ​deployment/ ​--port=​ ​--type=NodePort` 19 | 20 | ## Manifests 21 | 22 | ```yaml 23 | apiVersion: v1 24 | kind: Service 25 | metadata: 26 | name: nginx 27 | spec: 28 | selector: 29 | app: nginx 30 | type: NodePort 31 | ports: 32 | - port: 80 33 | 34 | nodePort: 8080 35 | ``` 36 | ## Service Types 37 | 38 | [Documentation](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services---service-types) 39 | 40 | * **ClusterIp** (default) - Exposes the service on cluster-internal IP. The service is only reachable from within the cluster. 41 | 42 | * **NodePort** - Exposes the service on each Node’s IP at a static port. You’ll be able to contact the NodePort service, 43 | from outside the cluster, by requesting `:`. 44 | Sample manifest: [service_node_port.yaml](service_node_port.yaml) 45 | 46 | * **LoadBalancer** - Exposes the service externally using a cloud provider’s load balancer. 47 | Sample manifest: [service_load_balancer.yaml](service_load_balancer.yaml) 48 | 49 | * **ExternalName** - Maps the service to the contents of the `externalName` field (e.g. _foo.bar.example.com_), by returning a _CNAME_ record with its value. 50 | [service_external_ip.yaml](service_external_ip.yaml) 51 | -------------------------------------------------------------------------------- /service/service_external_ip.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: my-service 5 | spec: 6 | selector: 7 | app: MyApp 8 | ports: 9 | - name: http 10 | protocol: TCP 11 | port: 80 12 | targetPort: 9376 13 | externalIPs: 14 | - 80.11.12.10 -------------------------------------------------------------------------------- /service/service_load_balancer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: my-service 5 | spec: 6 | selector: 7 | app: MyApp 8 | ports: 9 | - protocol: TCP 10 | port: 80 11 | targetPort: 9376 12 | clusterIP: 10.0.171.239 13 | loadBalancerIP: 78.11.24.19 14 | type: LoadBalancer 15 | -------------------------------------------------------------------------------- /service/service_node_port.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nginx 5 | spec: 6 | selector: 7 | app: nginx 8 | type: NodePort 9 | ports: 10 | - port: 80 11 | # nodePort is not required. If not provided Port will be assigned automatically. 12 | nodePort: 8080 13 | --------------------------------------------------------------------------------