├── Chapter1 ├── 1.3.2 mysql-rc.yaml ├── 1.3.2 mysql-svc.yaml ├── 1.3.3 myweb-rc.yaml ├── 1.3.3 myweb-svc.yaml ├── 1.4.12 pv-pvc.yaml ├── 1.4.13 namespace.yaml ├── 1.4.3 myweb-pod.yaml ├── 1.4.5 frontend-rc.yaml ├── 1.4.6 frontend-deployment.yaml ├── 1.4.7 hpa.yaml ├── 1.4.9 tomcat-service-multiple-ports.yaml ├── 1.4.9 tomcat-service-nodeport.yaml └── 1.4.9 tomcat-service.yaml ├── Chapter10 ├── 10.1.1 unschedule_node.yaml ├── 10.10 audit-policy.yaml ├── 10.11 dashboard.yaml ├── 10.3.1 namespace-development.yaml ├── 10.3.1 namespace-production.yaml ├── 10.4.1 pod-hugepages.yaml ├── 10.4.1 pod-resources-setting.yaml ├── 10.4.2 invalid-pod.yaml ├── 10.4.2 limit-test-nginx.yaml ├── 10.4.2 limitrange.yaml ├── 10.4.2 valid-pod.yaml ├── 10.4.4 resourcequota-compute-resources.yaml ├── 10.4.4 resourcequota-object-counts.yaml ├── 10.4.5 limitrange-resourcequota-practice.yaml ├── 10.6 poddisruptionbudget.yaml ├── 10.7 k8s-master-ha.yaml ├── 10.8.1 metrics-server.yaml ├── 10.8.2 prometheus-grafana.yaml └── 10.9 elasticsearch-fluentd-kibana.yml ├── Chapter12 ├── 12.1.1 windows-container.yaml ├── 12.2.1 gpu-amd-device-plugin.yaml ├── 12.2.1 gpu-nvidia-device-plugin.yaml ├── 12.2.2 pod-use-gpu.yaml └── 12.3.3 verticalpodautoscaler.yaml ├── Chapter2 ├── 2.2.2 clusterconfiguration.yaml ├── 2.3.1 kubernetes-config-files.txt ├── 2.3.1 systemd-service-unit-files.service └── 2.4.1 kubernetes-ssl-config-files.txt ├── Chapter3 ├── 3.10 init-containers.yaml ├── 3.11.1 deployment-update-rollback.yaml ├── 3.11.4 rc-rolling-update.yaml ├── 3.12.1 deployment-scale.yaml ├── 3.12.2 hpa-v1.yaml ├── 3.12.2 hpa-v2.yaml ├── 3.13 statefulset-mongodb-cluster.yaml ├── 3.2 frontend-localredis-pod.yaml ├── 3.3 static-web.yaml ├── 3.4 pod-volume-applogs.yaml ├── 3.5.2 cm-appconfigfiles.yaml ├── 3.5.2 cm-appvars.yaml ├── 3.5.3 cm-test-pod-envfrom.yaml ├── 3.5.3 cm-test-pod-use-envvar.yaml ├── 3.5.3 cm-test-pod-volume.yaml ├── 3.6.1 dapi-test-pod.yaml ├── 3.6.2 dapi-test-pod-container-vars.yaml ├── 3.6.3 dapi-test-pod-volume.yaml ├── 3.8 pod-livenessprobe.yaml ├── 3.9.1 nginx-deployment.yaml ├── 3.9.10 customized-scheduler.yaml ├── 3.9.2 redis-rc-nodeselector.yaml ├── 3.9.3 pod-nodeaffinity.yaml ├── 3.9.4 pod-podaffinity.yaml ├── 3.9.5 pod-taints-tolerations.yaml ├── 3.9.6 pod-priority.yaml ├── 3.9.7 daemonset.yaml ├── 3.9.8 job.yaml └── 3.9.9 cronjob.yaml ├── Chapter4 ├── 4.2 webapp-rc-service.yaml ├── 4.2.1 service-multiple-ports.yaml ├── 4.2.2 external-service.yaml ├── 4.3.2 headless-service-cassandra.yaml ├── 4.4.1 pod-hostnetwork.yaml ├── 4.4.1 pod-hostport.yaml ├── 4.4.2 service-nodeport.yaml ├── 4.5.2 coredns.yaml ├── 4.5.5 pod-dnsconfig.yaml ├── 4.6.1 ingress.yaml └── 4.6.5 ingress-tls.yaml ├── Chapter6 ├── 6.2.3 rbac.yaml ├── 6.5 imagepullsecret.yaml ├── 6.5 secret.yaml ├── 6.6.1 podsecuritypolicy.yaml ├── 6.6.2 podsecuritypolicy-examples.yaml └── 6.6.3 pod-securitycontext.yaml ├── Chapter7 ├── 7.5 pod-service-network.yaml ├── 7.6.2 cni-plugin-examples.json ├── 7.7.1 networkpolicy.yaml ├── 7.7.2 default-networkpolicy-in-namespace.yaml └── 7.8.4 cni-calico.yaml ├── Chapter8 ├── 8.2 pv-nfs.yaml ├── 8.2.1 pv-block-volume.yaml ├── 8.2.1 pv-mountoptions.yaml ├── 8.2.1 pv-nodeaffinity.yaml ├── 8.3 pvc.yaml ├── 8.5 storage-class.yaml ├── 8.5.1 storage-class-examples.yaml ├── 8.5.2 default-storageclass.yaml ├── 8.6 glusterfs-heketi.yaml ├── 8.7.3 csi-hostpath.yaml └── 8.7.4 volumesnapshot.yaml ├── Chapter9 ├── 9.4.1 customresourcedefinition.yaml └── 9.4.2 apiaggregation-apiservice.yaml └── README.md /Chapter1/1.3.2 mysql-rc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: mysql 5 | spec: 6 | replicas: 1 7 | selector: 8 | app: mysql 9 | template: 10 | metadata: 11 | labels: 12 | app: mysql 13 | spec: 14 | containers: 15 | - name: mysql 16 | image: mysql:5.7 17 | ports: 18 | - containerPort: 3306 19 | env: 20 | - name: MYSQL_ROOT_PASSWORD 21 | value: "123456" 22 | -------------------------------------------------------------------------------- /Chapter1/1.3.2 mysql-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | spec: 6 | ports: 7 | - port: 3306 8 | selector: 9 | app: mysql 10 | -------------------------------------------------------------------------------- /Chapter1/1.3.3 myweb-rc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: myweb 5 | spec: 6 | replicas: 5 7 | selector: 8 | app: myweb 9 | template: 10 | metadata: 11 | labels: 12 | app: myweb 13 | spec: 14 | containers: 15 | - name: myweb 16 | image: kubeguide/tomcat-app:v1 17 | ports: 18 | - containerPort: 8080 19 | env: 20 | - name: MYSQL_SERVICE_HOST 21 | value: 'mysql' 22 | - name: MYSQL_SERVICE_PORT 23 | value: '3306' 24 | -------------------------------------------------------------------------------- /Chapter1/1.3.3 myweb-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myweb 5 | spec: 6 | type: NodePort 7 | ports: 8 | - port: 8080 9 | nodePort: 30001 10 | selector: 11 | app: myweb 12 | 13 | -------------------------------------------------------------------------------- /Chapter1/1.4.12 pv-pvc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: PersistentVolume 4 | metadata: 5 | name: pv0003 6 | spec: 7 | capacity: 8 | storage: 5Gi 9 | accessModes: 10 | - ReadWriteOnce 11 | nfs: 12 | path: /somepath 13 | server: 172.17.0.2 14 | 15 | --- 16 | kind: PersistentVolumeClaim 17 | apiVersion: v1 18 | metadata: 19 | name: myclaim 20 | spec: 21 | accessModes: 22 | - ReadWriteOnce 23 | resources: 24 | requests: 25 | storage: 8Gi 26 | -------------------------------------------------------------------------------- /Chapter1/1.4.13 namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: development 6 | 7 | --- 8 | apiVersion: v1 9 | kind: Pod 10 | metadata: 11 | name: busybox 12 | namespace: development 13 | spec: 14 | containers: 15 | - image: busybox 16 | command: 17 | - sleep 18 | - "3600" 19 | name: busybox 20 | -------------------------------------------------------------------------------- /Chapter1/1.4.3 myweb-pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: myweb 5 | labels: 6 | app: myweb 7 | spec: 8 | containers: 9 | - name: myweb 10 | image: kubeguide/tomcat-app:v1 11 | ports: 12 | - containerPort: 8080 13 | env: 14 | - name: MYSQL_SERVICE_HOST 15 | value: 'mysql' 16 | - name: MYSQL_SERVICE_PORT 17 | value: '3306' 18 | -------------------------------------------------------------------------------- /Chapter1/1.4.5 frontend-rc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: frontend 5 | spec: 6 | replicas: 1 7 | selector: 8 | tier: frontend 9 | template: 10 | metadata: 11 | labels: 12 | app: app-demo 13 | tier: frontend 14 | spec: 15 | containers: 16 | - name: tomcat-demo 17 | image: tomcat 18 | imagePullPolicy: IfNotPresent 19 | env: 20 | - name: GET_HOSTS_FROM 21 | value: dns 22 | ports: 23 | - containerPort: 80 24 | -------------------------------------------------------------------------------- /Chapter1/1.4.6 frontend-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: frontend 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | tier: frontend 10 | matchExpressions: 11 | - {key: tier, operator: In, values: [frontend]} 12 | template: 13 | metadata: 14 | labels: 15 | app: app-demo 16 | tier: frontend 17 | spec: 18 | containers: 19 | - name: tomcat-demo 20 | image: tomcat 21 | imagePullPolicy: IfNotPresent 22 | ports: 23 | - containerPort: 8080 24 | -------------------------------------------------------------------------------- /Chapter1/1.4.7 hpa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v1 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: php-apache 5 | namespace: default 6 | spec: 7 | maxReplicas: 10 8 | minReplicas: 1 9 | scaleTargetRef: 10 | kind: Deployment 11 | name: php-apache 12 | targetCPUUtilizationPercentage: 90 13 | -------------------------------------------------------------------------------- /Chapter1/1.4.9 tomcat-service-multiple-ports.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: tomcat-service 5 | spec: 6 | ports: 7 | - port: 8080 8 | name: service-port 9 | - port: 8005 10 | name: shutdown-port 11 | selector: 12 | tier: frontend 13 | -------------------------------------------------------------------------------- /Chapter1/1.4.9 tomcat-service-nodeport.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: tomcat-service 5 | spec: 6 | type: NodePort 7 | ports: 8 | - port: 8080 9 | nodePort: 31002 10 | selector: 11 | tier: frontend 12 | -------------------------------------------------------------------------------- /Chapter1/1.4.9 tomcat-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: tomcat-service 5 | spec: 6 | ports: 7 | - port: 8080 8 | selector: 9 | tier: frontend 10 | -------------------------------------------------------------------------------- /Chapter10/10.1.1 unschedule_node.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Node 3 | metadata: 4 | name: k8s-node-1 5 | labels: 6 | kubernetes.io/hostname: k8s-node-1 7 | spec: 8 | unschedulable: true 9 | -------------------------------------------------------------------------------- /Chapter10/10.10 audit-policy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: audit.k8s.io/v1 2 | kind: Policy 3 | omitStages: 4 | - "RequestReceived" 5 | rules: 6 | - level: RequestResponse 7 | resources: 8 | - group: "" #core API group 9 | resources: ["pods"] 10 | - level: Metadata 11 | resources: 12 | - group: "" 13 | resources: ["pods/log", "pods/status"] 14 | - level: Request 15 | resources: 16 | - group: "" 17 | - group: "extensions" 18 | -------------------------------------------------------------------------------- /Chapter10/10.11 dashboard.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: Deployment 3 | apiVersion: extensions/v1beta1 4 | metadata: 5 | labels: 6 | app: kubernetes-dashboard 7 | name: kubernetes-dashboard 8 | namespace: kube-system 9 | spec: 10 | replicas: 1 11 | revisionHistoryLimit: 10 12 | selector: 13 | matchLabels: 14 | app: kubernetes-dashboard 15 | template: 16 | metadata: 17 | labels: 18 | app: kubernetes-dashboard 19 | annotations: 20 | scheduler.alpha.kubernetes.io/tolerations: | 21 | [ 22 | { 23 | "key": "dedicated", 24 | "operator": "Equal", 25 | "value": "master", 26 | "effect": "NoSchedule" 27 | } 28 | ] 29 | spec: 30 | containers: 31 | - name: kubernetes-dashboard 32 | image: gcr.io/google_containers/kubernetes-dashboard-amd64:v1.6.0 33 | imagePullPolicy: Always 34 | ports: 35 | - containerPort: 9090 36 | protocol: TCP 37 | args: 38 | livenessProbe: 39 | httpGet: 40 | path: / 41 | port: 9090 42 | initialDelaySeconds: 30 43 | timeoutSeconds: 30 44 | 45 | --- 46 | kind: Service 47 | apiVersion: v1 48 | metadata: 49 | labels: 50 | app: kubernetes-dashboard 51 | name: kubernetes-dashboard 52 | namespace: kube-system 53 | spec: 54 | type: NodePort 55 | ports: 56 | - port: 80 57 | targetPort: 9090 58 | nodePort: 9090 59 | selector: 60 | app: kubernetes-dashboard 61 | -------------------------------------------------------------------------------- /Chapter10/10.3.1 namespace-development.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: development 5 | -------------------------------------------------------------------------------- /Chapter10/10.3.1 namespace-production.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: production 5 | -------------------------------------------------------------------------------- /Chapter10/10.4.1 pod-hugepages.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | generateName: hugepages-volume- 5 | spec: 6 | containers: 7 | - image: fedora:latest 8 | command: 9 | - sleep 10 | - inf 11 | name: example 12 | volumeMounts: 13 | - mountPath: /hugepages 14 | name: hugepage 15 | resources: 16 | limits: 17 | hugepages-2Mi: 100Mi 18 | memory: 100Mi 19 | requests: 20 | memory: 100Mi 21 | volumes: 22 | - name: hugepage 23 | emptyDir: 24 | medium: HugePages 25 | -------------------------------------------------------------------------------- /Chapter10/10.4.1 pod-resources-setting.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: frontend 5 | spec: 6 | containers: 7 | - name: db 8 | image: mysql 9 | resources: 10 | requests: 11 | memory: "64Mi" 12 | cpu: "250m" 13 | limits: 14 | memory: "128Mi" 15 | cpu: "500m" 16 | - name: wp 17 | image: wordpress 18 | resources: 19 | requests: 20 | memory: "64Mi" 21 | cpu: "250m" 22 | limits: 23 | memory: "128Mi" 24 | cpu: "500m" 25 | -------------------------------------------------------------------------------- /Chapter10/10.4.2 invalid-pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: invalid-pod 5 | spec: 6 | containers: 7 | - name: kubernetes-serve-hostname 8 | image: gcr.io/google_containers/serve_hostname 9 | resources: 10 | limits: 11 | cpu: "3" 12 | memory: 100Mi 13 | -------------------------------------------------------------------------------- /Chapter10/10.4.2 limit-test-nginx.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: limit-test-nginx 5 | labels: 6 | name: limit-test-nginx 7 | spec: 8 | containers: 9 | - name: limit-test-nginx 10 | image: nginx 11 | resources: 12 | limits: 13 | cpu: "1" 14 | memory: 512Mi 15 | requests: 16 | cpu: "0.8" 17 | memory: 250Mi 18 | -------------------------------------------------------------------------------- /Chapter10/10.4.2 limitrange.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: LimitRange 3 | metadata: 4 | name: mylimits 5 | spec: 6 | limits: 7 | - max: 8 | cpu: "4" 9 | memory: 2Gi 10 | min: 11 | cpu: 200m 12 | memory: 6Mi 13 | maxLimitRequestRatio: 14 | cpu: 3 15 | memory: 2 16 | type: Pod 17 | - default: 18 | cpu: 300m 19 | memory: 200Mi 20 | defaultRequest: 21 | cpu: 200m 22 | memory: 100Mi 23 | max: 24 | cpu: "2" 25 | memory: 1Gi 26 | min: 27 | cpu: 100m 28 | memory: 3Mi 29 | maxLimitRequestRatio: 30 | cpu: 5 31 | memory: 4 32 | type: Container 33 | -------------------------------------------------------------------------------- /Chapter10/10.4.2 valid-pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: valid-pod 5 | labels: 6 | name: valid-pod 7 | spec: 8 | containers: 9 | - name: kubernetes-serve-hostname 10 | image: gcr.io/google_containers/serve_hostname 11 | resources: 12 | limits: 13 | cpu: "1" 14 | memory: 512Mi 15 | -------------------------------------------------------------------------------- /Chapter10/10.4.4 resourcequota-compute-resources.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ResourceQuota 3 | metadata: 4 | name: compute-resources 5 | spec: 6 | hard: 7 | pods: "4" 8 | requests.cpu: "1" 9 | requests.memory: 1Gi 10 | limits.cpu: "2" 11 | limits.memory: 2Gi 12 | -------------------------------------------------------------------------------- /Chapter10/10.4.4 resourcequota-object-counts.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ResourceQuota 3 | metadata: 4 | name: object-counts 5 | spec: 6 | hard: 7 | configmaps: "10" 8 | persistentvolumeclaims: "4" 9 | replicationcontrollers: "20" 10 | secrets: "10" 11 | services: "10" 12 | services.loadbalancers: "2" 13 | -------------------------------------------------------------------------------- /Chapter10/10.4.5 limitrange-resourcequota-practice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: quota-example 6 | 7 | --- 8 | apiVersion: v1 9 | kind: ResourceQuota 10 | metadata: 11 | name: object-counts 12 | spec: 13 | hard: 14 | persistentvolumeclaims: "2" 15 | services.loadbalancers: "2" 16 | services.nodeports: "0" 17 | 18 | --- 19 | apiVersion: v1 20 | kind: ResourceQuota 21 | metadata: 22 | name: compute-resources 23 | spec: 24 | hard: 25 | pods: "4" 26 | requests.cpu: "1" 27 | requests.memory: 1Gi 28 | limits.cpu: "2" 29 | limits.memory: 2Gi 30 | 31 | 32 | $ kubectl run nginx --image=nginx --replicas=1 --namespace=quota-example 33 | 34 | 35 | --- 36 | apiVersion: v1 37 | kind: LimitRange 38 | metadata: 39 | name: limits 40 | spec: 41 | limits: 42 | - default: 43 | cpu: 200m 44 | memory: 512Mi 45 | defaultRequest: 46 | cpu: 100m 47 | memory: 256Mi 48 | type: Container 49 | 50 | 51 | $ kubectl run nginx \ 52 | --image=nginx \ 53 | --replicas=1 \ 54 | --requests=cpu=100m,memory=256Mi \ 55 | --limits=cpu=200m,memory=512Mi \ 56 | --namespace=quota-example 57 | 58 | 59 | 60 | $ kubectl create namespace quota-scopes 61 | 62 | --- 63 | apiVersion: v1 64 | kind: ResourceQuota 65 | metadata: 66 | name: best-effort 67 | spec: 68 | hard: 69 | pods: "10" 70 | scopes: 71 | - BestEffort 72 | 73 | --- 74 | apiVersion: v1 75 | kind: ResourceQuota 76 | metadata: 77 | name: not-best-effort 78 | spec: 79 | hard: 80 | pods: "4" 81 | requests.cpu: "1" 82 | requests.memory: 1Gi 83 | limits.cpu: "2" 84 | limits.memory: 2Gi 85 | scopes: 86 | - NotBestEffort 87 | 88 | 89 | $ kubectl run best-effort-nginx --image=nginx --replicas=8 --namespace=quota-scopes 90 | 91 | 92 | $ kubectl run not-best-effort-nginx \ 93 | --image=nginx \ 94 | --replicas=2 \ 95 | --requests=cpu=100m,memory=256Mi \ 96 | --limits=cpu=200m,memory=512Mi \ 97 | --namespace=quota-scopes 98 | -------------------------------------------------------------------------------- /Chapter10/10.6 poddisruptionbudget.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: extensions/v1beta1 3 | kind: Deployment 4 | metadata: 5 | name: nginx 6 | labels: 7 | name: nginx 8 | spec: 9 | replicas: 3 10 | selector: 11 | matchLabels: 12 | name: nginx 13 | template: 14 | metadata: 15 | labels: 16 | name: nginx 17 | spec: 18 | containers: 19 | - name: nginx 20 | image: nginx 21 | ports: 22 | - containerPort: 80 23 | protocol: TCP 24 | 25 | --- 26 | apiVersion: policy/v1beta1 27 | kind: PodDisruptionBudget 28 | metadata: 29 | name: nginx 30 | spec: 31 | minAvailable: 3 32 | selector: 33 | matchLabels: 34 | name: nginx 35 | 36 | 37 | $ curl -v -H 'Content-type: application/json' http:///api/v1/namespaces/default/pods/nginx-1968750913-0k01k/eviction -d @eviction.json 38 | -------------------------------------------------------------------------------- /Chapter10/10.7 k8s-master-ha.yaml: -------------------------------------------------------------------------------- 1 | # kube-apiserver 2 | --- 3 | apiVersion: v1 4 | kind: Pod 5 | metadata: 6 | name: kube-apiserver 7 | spec: 8 | hostNetwork: true 9 | containers: 10 | - name: kube-apiserver 11 | image: gcr.io/google_containers/kube-apiserver:9680e782e08a1a1c94c656190011bd02 12 | command: 13 | - /bin/sh 14 | - -c 15 | - /usr/local/bin/kube-apiserver --etcd-servers=http://127.0.0.1:2379 16 | --admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota 17 | --service-cluster-ip-range=169.169.0.0/16 --v=2 18 | --allow-privileged=False 1>>/var/log/kube-apiserver.log 2>&1 19 | ports: 20 | - containerPort: 443 21 | hostPort: 443 22 | name: https 23 | - containerPort: 7080 24 | hostPort: 7080 25 | name: http 26 | - containerPort: 8080 27 | hostPort: 8080 28 | name: local 29 | volumeMounts: 30 | - mountPath: /srv/kubernetes 31 | name: srvkube 32 | readOnly: true 33 | - mountPath: /var/log/kube-apiserver.log 34 | name: logfile 35 | - mountPath: /etc/ssl 36 | name: etcssl 37 | readOnly: true 38 | - mountPath: /usr/share/ssl 39 | name: usrsharessl 40 | readOnly: true 41 | - mountPath: /var/ssl 42 | name: varssl 43 | readOnly: true 44 | - mountPath: /usr/ssl 45 | name: usrssl 46 | readOnly: true 47 | - mountPath: /usr/lib/ssl 48 | name: usrlibssl 49 | readOnly: true 50 | - mountPath: /usr/local/openssl 51 | name: usrlocalopenssl 52 | readOnly: true 53 | - mountPath: /etc/openssl 54 | name: etcopenssl 55 | readOnly: true 56 | - mountPath: /etc/pki/tls 57 | name: etcpkitls 58 | readOnly: true 59 | volumes: 60 | - hostPath: 61 | path: /srv/kubernetes 62 | name: srvkube 63 | - hostPath: 64 | path: /var/log/kube-apiserver.log 65 | name: logfile 66 | - hostPath: 67 | path: /etc/ssl 68 | name: etcssl 69 | - hostPath: 70 | path: /usr/share/ssl 71 | name: usrsharessl 72 | - hostPath: 73 | path: /var/ssl 74 | name: varssl 75 | - hostPath: 76 | path: /usr/ssl 77 | name: usrssl 78 | - hostPath: 79 | path: /usr/lib/ssl 80 | name: usrlibssl 81 | - hostPath: 82 | path: /usr/local/openssl 83 | name: usrlocalopenssl 84 | - hostPath: 85 | path: /etc/openssl 86 | name: etcopenssl 87 | - hostPath: 88 | path: /etc/pki/tls 89 | name: etcpkitls 90 | 91 | 92 | # kube-controller-manager 93 | --- 94 | apiVersion: v1 95 | kind: Pod 96 | metadata: 97 | name: kube-controller-manager 98 | spec: 99 | hostNetwork: true 100 | containers: 101 | - name: kube-controller-manager 102 | image: gcr.io/google_containers/kube-controller-manager:fda24638d51a48baa13c35337fcd4793 103 | command: 104 | - /bin/sh 105 | - -c 106 | - /usr/local/bin/kube-controller-manager --master=127.0.0.1:8080 107 | --v=2 --leader-elect=true 1>>/var/log/kube-controller-manager.log 2>&1 108 | livenessProbe: 109 | httpGet: 110 | path: /healthz 111 | port: 10252 112 | initialDelaySeconds: 15 113 | timeoutSeconds: 1 114 | volumeMounts: 115 | - mountPath: /srv/kubernetes 116 | name: srvkube 117 | readOnly: true 118 | - mountPath: /var/log/kube-controller-manager.log 119 | name: logfile 120 | - mountPath: /etc/ssl 121 | name: etcssl 122 | readOnly: true 123 | - mountPath: /usr/share/ssl 124 | name: usrsharessl 125 | readOnly: true 126 | - mountPath: /var/ssl 127 | name: varssl 128 | readOnly: true 129 | - mountPath: /usr/ssl 130 | name: usrssl 131 | readOnly: true 132 | - mountPath: /usr/lib/ssl 133 | name: usrlibssl 134 | readOnly: true 135 | - mountPath: /usr/local/openssl 136 | name: usrlocalopenssl 137 | readOnly: true 138 | - mountPath: /etc/openssl 139 | name: etcopenssl 140 | readOnly: true 141 | - mountPath: /etc/pki/tls 142 | name: etcpkitls 143 | readOnly: true 144 | volumes: 145 | - hostPath: 146 | path: /srv/kubernetes 147 | name: srvkube 148 | - hostPath: 149 | path: /var/log/kube-controller-manager.log 150 | name: logfile 151 | - hostPath: 152 | path: /etc/ssl 153 | name: etcssl 154 | - hostPath: 155 | path: /usr/share/ssl 156 | name: usrsharessl 157 | - hostPath: 158 | path: /var/ssl 159 | name: varssl 160 | - hostPath: 161 | path: /usr/ssl 162 | name: usrssl 163 | - hostPath: 164 | path: /usr/lib/ssl 165 | name: usrlibssl 166 | - hostPath: 167 | path: /usr/local/openssl 168 | name: usrlocalopenssl 169 | - hostPath: 170 | path: /etc/openssl 171 | name: etcopenssl 172 | - hostPath: 173 | path: /etc/pki/tls 174 | name: etcpkitls 175 | 176 | 177 | # kube-scheduler 178 | --- 179 | apiVersion: v1 180 | kind: Pod 181 | metadata: 182 | name: kube-scheduler 183 | spec: 184 | hostNetwork: true 185 | containers: 186 | - name: kube-scheduler 187 | image: gcr.io/google_containers/kube-scheduler:34d0b8f8b31e27937327961528739bc9 188 | command: 189 | - /bin/sh 190 | - -c 191 | - /usr/local/bin/kube-scheduler --master=127.0.0.1:8080 --v=2 --leader-elect=true 1>>/var/log/kube-scheduler.log 2>&1 192 | livenessProbe: 193 | httpGet: 194 | path: /healthz 195 | port: 10251 196 | initialDelaySeconds: 15 197 | timeoutSeconds: 1 198 | volumeMounts: 199 | - mountPath: /var/log/kube-scheduler.log 200 | name: logfile 201 | - mountPath: /var/run/secrets/kubernetes.io/serviceaccount 202 | name: default-token-s8ejd 203 | readOnly: true 204 | volumes: 205 | - hostPath: 206 | path: /var/log/kube-scheduler.log 207 | name: logfile 208 | -------------------------------------------------------------------------------- /Chapter10/10.8.1 metrics-server.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: metrics-server 6 | namespace: kube-system 7 | 8 | --- 9 | apiVersion: extensions/v1beta1 10 | kind: Deployment 11 | metadata: 12 | name: metrics-server 13 | namespace: kube-system 14 | labels: 15 | k8s-app: metrics-server 16 | spec: 17 | selector: 18 | matchLabels: 19 | k8s-app: metrics-server 20 | template: 21 | metadata: 22 | name: metrics-server 23 | labels: 24 | k8s-app: metrics-server 25 | spec: 26 | serviceAccountName: metrics-server 27 | containers: 28 | - name: metrics-server 29 | image: k8s.gcr.io/metrics-server-amd64:v0.3.1 30 | imagePullPolicy: IfNotPresent 31 | volumeMounts: 32 | - name: tmp-dir 33 | mountPath: /tmp 34 | volumes: 35 | - name: tmp-dir 36 | emptyDir: {} 37 | --- 38 | apiVersion: v1 39 | kind: Service 40 | metadata: 41 | name: metrics-server 42 | namespace: kube-system 43 | labels: 44 | kubernetes.io/name: "Metrics-server" 45 | spec: 46 | selector: 47 | k8s-app: metrics-server 48 | ports: 49 | - port: 443 50 | protocol: TCP 51 | targetPort: 443 52 | 53 | --- 54 | apiVersion: apiregistration.k8s.io/v1beta1 55 | kind: APIService 56 | metadata: 57 | name: v1beta1.metrics.k8s.io 58 | spec: 59 | service: 60 | name: metrics-server 61 | namespace: kube-system 62 | group: metrics.k8s.io 63 | version: v1beta1 64 | insecureSkipTLSVerify: true 65 | groupPriorityMinimum: 100 66 | versionPriority: 100 67 | -------------------------------------------------------------------------------- /Chapter10/10.8.2 prometheus-grafana.yaml: -------------------------------------------------------------------------------- 1 | # prometheus 2 | --- 3 | apiVersion: v1 4 | kind: ConfigMap 5 | metadata: 6 | name: prometheus-config 7 | namespace: kube-system 8 | labels: 9 | kubernetes.io/cluster-service: "true" 10 | addonmanager.kubernetes.io/mode: EnsureExists 11 | data: 12 | prometheus.rules.yml: | 13 | groups: 14 | - name: recording_rules 15 | rules: 16 | - record: service_myweb:container_memory_working_set_bytes:sum 17 | expr: sum by (namespace, label_service_myweb) (sum(container_memory_working_set_bytes{image!=""}) by (pod_name, namespace) * on (namespace, pod_name) group_left(service_myweb, label_service_myweb) label_replace(kube_pod_labels, "pod_name", "$1", "pod", "(.*)")) 18 | 19 | prometheus.yml: | 20 | global: 21 | scrape_interval: 30s 22 | rule_files: 23 | - 'prometheus.rules.yml' 24 | scrape_configs: 25 | - job_name: prometheus 26 | static_configs: 27 | - targets: 28 | - localhost:9090 29 | - job_name: kubernetes-apiservers 30 | kubernetes_sd_configs: 31 | - role: endpoints 32 | relabel_configs: 33 | - action: keep 34 | regex: default;kubernetes;https 35 | source_labels: 36 | - __meta_kubernetes_namespace 37 | - __meta_kubernetes_service_name 38 | - __meta_kubernetes_endpoint_port_name 39 | scheme: https 40 | tls_config: 41 | ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt 42 | insecure_skip_verify: true 43 | bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token 44 | 45 | - job_name: kubernetes-nodes-kubelet 46 | kubernetes_sd_configs: 47 | - role: node 48 | relabel_configs: 49 | - action: labelmap 50 | regex: __meta_kubernetes_node_label_(.+) 51 | scheme: https 52 | tls_config: 53 | ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt 54 | insecure_skip_verify: true 55 | bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token 56 | 57 | - job_name: kubernetes-nodes-cadvisor 58 | kubernetes_sd_configs: 59 | - role: node 60 | relabel_configs: 61 | - action: labelmap 62 | regex: __meta_kubernetes_node_label_(.+) 63 | - target_label: __metrics_path__ 64 | replacement: /metrics/cadvisor 65 | scheme: https 66 | tls_config: 67 | ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt 68 | insecure_skip_verify: true 69 | bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token 70 | 71 | - job_name: kubernetes-service-endpoints 72 | kubernetes_sd_configs: 73 | - role: endpoints 74 | relabel_configs: 75 | - action: keep 76 | regex: true 77 | source_labels: 78 | - __meta_kubernetes_service_annotation_prometheus_io_scrape 79 | - action: replace 80 | regex: (https?) 81 | source_labels: 82 | - __meta_kubernetes_service_annotation_prometheus_io_scheme 83 | target_label: __scheme__ 84 | - action: replace 85 | regex: (.+) 86 | source_labels: 87 | - __meta_kubernetes_service_annotation_prometheus_io_path 88 | target_label: __metrics_path__ 89 | - action: replace 90 | regex: ([^:]+)(?::\d+)?;(\d+) 91 | replacement: $1:$2 92 | source_labels: 93 | - __address__ 94 | - __meta_kubernetes_service_annotation_prometheus_io_port 95 | target_label: __address__ 96 | - action: labelmap 97 | regex: __meta_kubernetes_service_label_(.+) 98 | - action: replace 99 | source_labels: 100 | - __meta_kubernetes_namespace 101 | target_label: kubernetes_namespace 102 | - action: replace 103 | source_labels: 104 | - __meta_kubernetes_service_name 105 | target_label: kubernetes_name 106 | 107 | - job_name: kubernetes-services 108 | kubernetes_sd_configs: 109 | - role: service 110 | metrics_path: /probe 111 | params: 112 | module: 113 | - http_2xx 114 | relabel_configs: 115 | - action: keep 116 | regex: true 117 | source_labels: 118 | - __meta_kubernetes_service_annotation_prometheus_io_probe 119 | - source_labels: 120 | - __address__ 121 | target_label: __param_target 122 | - replacement: blackbox 123 | target_label: __address__ 124 | - source_labels: 125 | - __param_target 126 | target_label: instance 127 | - action: labelmap 128 | regex: __meta_kubernetes_service_label_(.+) 129 | - source_labels: 130 | - __meta_kubernetes_namespace 131 | target_label: kubernetes_namespace 132 | - source_labels: 133 | - __meta_kubernetes_service_name 134 | target_label: kubernetes_name 135 | 136 | - job_name: kubernetes-pods 137 | kubernetes_sd_configs: 138 | - role: pod 139 | relabel_configs: 140 | - action: keep 141 | regex: true 142 | source_labels: 143 | - __meta_kubernetes_pod_annotation_prometheus_io_scrape 144 | - action: replace 145 | regex: (.+) 146 | source_labels: 147 | - __meta_kubernetes_pod_annotation_prometheus_io_path 148 | target_label: __metrics_path__ 149 | - action: replace 150 | regex: ([^:]+)(?::\d+)?;(\d+) 151 | replacement: $1:$2 152 | source_labels: 153 | - __address__ 154 | - __meta_kubernetes_pod_annotation_prometheus_io_port 155 | target_label: __address__ 156 | - action: labelmap 157 | regex: __meta_kubernetes_pod_label_(.+) 158 | - action: replace 159 | source_labels: 160 | - __meta_kubernetes_namespace 161 | target_label: kubernetes_namespace 162 | - action: replace 163 | source_labels: 164 | - __meta_kubernetes_pod_name 165 | target_label: kubernetes_pod_name 166 | alerting: 167 | alertmanagers: 168 | - kubernetes_sd_configs: 169 | - role: pod 170 | tls_config: 171 | ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt 172 | bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token 173 | relabel_configs: 174 | - source_labels: [__meta_kubernetes_namespace] 175 | regex: kube-system 176 | action: keep 177 | - source_labels: [__meta_kubernetes_pod_label_k8s_app] 178 | regex: alertmanager 179 | action: keep 180 | - source_labels: [__meta_kubernetes_pod_container_port_number] 181 | regex: 182 | action: drop 183 | 184 | --- 185 | apiVersion: extensions/v1beta1 186 | kind: Deployment 187 | metadata: 188 | name: prometheus 189 | namespace: kube-system 190 | labels: 191 | k8s-app: prometheus 192 | kubernetes.io/cluster-service: "true" 193 | addonmanager.kubernetes.io/mode: Reconcile 194 | spec: 195 | replicas: 1 196 | selector: 197 | matchLabels: 198 | k8s-app: prometheus 199 | template: 200 | metadata: 201 | labels: 202 | k8s-app: prometheus 203 | annotations: 204 | scheduler.alpha.kubernetes.io/critical-pod: '' 205 | spec: 206 | priorityClassName: system-cluster-critical 207 | initContainers: 208 | - name: "init-chown-data" 209 | image: "busybox:latest" 210 | imagePullPolicy: "IfNotPresent" 211 | command: ["chown", "-R", "65534:65534", "/data"] 212 | volumeMounts: 213 | - name: storage-volume 214 | mountPath: /data 215 | subPath: "" 216 | containers: 217 | - name: prometheus-server-configmap-reload 218 | image: "jimmidyson/configmap-reload:v0.1" 219 | imagePullPolicy: "IfNotPresent" 220 | args: 221 | - --volume-dir=/etc/config 222 | - --webhook-url=http://localhost:9090/-/reload 223 | volumeMounts: 224 | - name: config-volume 225 | mountPath: /etc/config 226 | readOnly: true 227 | - name: prometheus-server 228 | image: "prom/prometheus:v2.8.0" 229 | imagePullPolicy: "IfNotPresent" 230 | args: 231 | - --config.file=/etc/config/prometheus.yml 232 | - --storage.tsdb.path=/data 233 | - --web.console.libraries=/etc/prometheus/console_libraries 234 | - --web.console.templates=/etc/prometheus/consoles 235 | - --web.enable-lifecycle 236 | ports: 237 | - containerPort: 9090 238 | readinessProbe: 239 | httpGet: 240 | path: /-/ready 241 | port: 9090 242 | initialDelaySeconds: 30 243 | timeoutSeconds: 30 244 | livenessProbe: 245 | httpGet: 246 | path: /-/healthy 247 | port: 9090 248 | initialDelaySeconds: 30 249 | timeoutSeconds: 30 250 | volumeMounts: 251 | - name: config-volume 252 | mountPath: /etc/config 253 | - name: storage-volume 254 | mountPath: /data 255 | subPath: "" 256 | terminationGracePeriodSeconds: 300 257 | volumes: 258 | - name: config-volume 259 | configMap: 260 | name: prometheus-config 261 | - name: storage-volume 262 | hostPath: 263 | path: /prometheus-data 264 | type: Directory 265 | 266 | --- 267 | kind: Service 268 | apiVersion: v1 269 | metadata: 270 | name: prometheus 271 | namespace: kube-system 272 | labels: 273 | kubernetes.io/name: "Prometheus" 274 | kubernetes.io/cluster-service: "true" 275 | addonmanager.kubernetes.io/mode: Reconcile 276 | spec: 277 | type: NodePort 278 | ports: 279 | - name: http 280 | port: 9090 281 | nodePort: 9090 282 | protocol: TCP 283 | targetPort: 9090 284 | selector: 285 | k8s-app: prometheus 286 | 287 | 288 | 289 | # node-exporter 290 | --- 291 | apiVersion: extensions/v1beta1 292 | kind: DaemonSet 293 | metadata: 294 | name: node-exporter 295 | namespace: kube-system 296 | labels: 297 | k8s-app: node-exporter 298 | kubernetes.io/cluster-service: "true" 299 | addonmanager.kubernetes.io/mode: Reconcile 300 | version: v0.17.0 301 | spec: 302 | updateStrategy: 303 | type: OnDelete 304 | template: 305 | metadata: 306 | labels: 307 | k8s-app: node-exporter 308 | version: v0.17.0 309 | annotations: 310 | scheduler.alpha.kubernetes.io/critical-pod: '' 311 | spec: 312 | priorityClassName: system-node-critical 313 | containers: 314 | - name: prometheus-node-exporter 315 | image: "prom/node-exporter:v0.17.0" 316 | imagePullPolicy: "IfNotPresent" 317 | args: 318 | - --path.procfs=/host/proc 319 | - --path.sysfs=/host/sys 320 | ports: 321 | - name: metrics 322 | containerPort: 9100 323 | hostPort: 9100 324 | volumeMounts: 325 | - name: proc 326 | mountPath: /host/proc 327 | readOnly: true 328 | - name: sys 329 | mountPath: /host/sys 330 | readOnly: true 331 | resources: 332 | limits: 333 | cpu: 1 334 | memory: 512Mi 335 | requests: 336 | cpu: 100m 337 | memory: 50Mi 338 | hostNetwork: true 339 | hostPID: true 340 | volumes: 341 | - name: proc 342 | hostPath: 343 | path: /proc 344 | - name: sys 345 | hostPath: 346 | path: /sys 347 | 348 | --- 349 | apiVersion: v1 350 | kind: Service 351 | metadata: 352 | name: node-exporter 353 | namespace: kube-system 354 | annotations: 355 | prometheus.io/scrape: "true" 356 | labels: 357 | kubernetes.io/cluster-service: "true" 358 | addonmanager.kubernetes.io/mode: Reconcile 359 | kubernetes.io/name: "NodeExporter" 360 | spec: 361 | clusterIP: None 362 | ports: 363 | - name: metrics 364 | port: 9100 365 | protocol: TCP 366 | targetPort: 9100 367 | selector: 368 | k8s-app: node-exporter 369 | 370 | 371 | 372 | # grafana 373 | --- 374 | kind: Deployment 375 | apiVersion: extensions/v1beta1 376 | metadata: 377 | name: grafana 378 | namespace: kube-system 379 | labels: 380 | k8s-app: grafana 381 | kubernetes.io/cluster-service: "true" 382 | addonmanager.kubernetes.io/mode: Reconcile 383 | spec: 384 | replicas: 1 385 | selector: 386 | matchLabels: 387 | k8s-app: grafana 388 | template: 389 | metadata: 390 | labels: 391 | k8s-app: grafana 392 | annotations: 393 | scheduler.alpha.kubernetes.io/critical-pod: '' 394 | spec: 395 | priorityClassName: system-cluster-critical 396 | tolerations: 397 | - key: node-role.kubernetes.io/master 398 | effect: NoSchedule 399 | - key: "CriticalAddonsOnly" 400 | operator: "Exists" 401 | containers: 402 | - name: grafana 403 | image: grafana/grafana:6.0.1 404 | imagePullPolicy: IfNotPresent 405 | resources: 406 | limits: 407 | cpu: 1 408 | memory: 1Gi 409 | requests: 410 | cpu: 100m 411 | memory: 100Mi 412 | env: 413 | - name: GF_AUTH_BASIC_ENABLED 414 | value: "false" 415 | - name: GF_AUTH_ANONYMOUS_ENABLED 416 | value: "true" 417 | - name: GF_AUTH_ANONYMOUS_ORG_ROLE 418 | value: Admin 419 | - name: GF_SERVER_ROOT_URL 420 | value: /api/v1/namespaces/kube-system/services/grafana/proxy/ 421 | ports: 422 | - name: ui 423 | containerPort: 3000 424 | 425 | --- 426 | apiVersion: v1 427 | kind: Service 428 | metadata: 429 | name: grafana 430 | namespace: kube-system 431 | labels: 432 | kubernetes.io/cluster-service: "true" 433 | addonmanager.kubernetes.io/mode: Reconcile 434 | kubernetes.io/name: "Grafana" 435 | spec: 436 | ports: 437 | - port: 80 438 | protocol: TCP 439 | targetPort: ui 440 | selector: 441 | k8s-app: grafana 442 | -------------------------------------------------------------------------------- /Chapter10/10.9 elasticsearch-fluentd-kibana.yml: -------------------------------------------------------------------------------- 1 | # elasticsearch 2 | --- 3 | apiVersion: v1 4 | kind: ReplicationController 5 | metadata: 6 | name: elasticsearch-logging-v1 7 | namespace: kube-system 8 | labels: 9 | k8s-app: elasticsearch-logging 10 | version: v1 11 | kubernetes.io/cluster-service: "true" 12 | spec: 13 | replicas: 2 14 | selector: 15 | k8s-app: elasticsearch-logging 16 | version: v1 17 | template: 18 | metadata: 19 | labels: 20 | k8s-app: elasticsearch-logging 21 | version: v1 22 | kubernetes.io/cluster-service: "true" 23 | spec: 24 | containers: 25 | - image: gcr.io/google_containers/elasticsearch:1.8 26 | name: elasticsearch-logging 27 | resources: 28 | # keep request = limit to keep this container in guaranteed class 29 | limits: 30 | cpu: 100m 31 | requests: 32 | cpu: 100m 33 | ports: 34 | - containerPort: 9200 35 | name: db 36 | protocol: TCP 37 | - containerPort: 9300 38 | name: transport 39 | protocol: TCP 40 | volumeMounts: 41 | - name: es-persistent-storage 42 | mountPath: /data 43 | volumes: 44 | - name: es-persistent-storage 45 | emptyDir: {} 46 | --- 47 | apiVersion: v1 48 | kind: Service 49 | metadata: 50 | name: elasticsearch-logging 51 | namespace: kube-system 52 | labels: 53 | k8s-app: elasticsearch-logging 54 | kubernetes.io/cluster-service: "true" 55 | kubernetes.io/name: "Elasticsearch" 56 | spec: 57 | ports: 58 | - port: 9200 59 | protocol: TCP 60 | targetPort: db 61 | selector: 62 | k8s-app: elasticsearch-logging 63 | 64 | 65 | 66 | # fluentd 67 | --- 68 | apiVersion: extensions/v1beta1 69 | kind: DaemonSet 70 | metadata: 71 | name: fluentd-cloud-logging 72 | namespace: kube-system 73 | labels: 74 | k8s-app: fluentd-cloud-logging 75 | spec: 76 | template: 77 | metadata: 78 | namespace: kube-system 79 | labels: 80 | k8s-app: fluentd-cloud-logging 81 | spec: 82 | containers: 83 | - name: fluentd-cloud-logging 84 | image: gcr.io/google_containers/fluentd-elasticsearch:1.17 85 | resources: 86 | limits: 87 | cpu: 100m 88 | memory: 200Mi 89 | env: 90 | - name: FLUENTD_ARGS 91 | value: -q 92 | volumeMounts: 93 | - name: varlog 94 | mountPath: /var/log 95 | readOnly: false 96 | - name: containers 97 | mountPath: /var/lib/docker/containers 98 | readOnly: false 99 | volumes: 100 | - name: containers 101 | hostPath: 102 | path: /var/lib/docker/containers 103 | - name: varlog 104 | hostPath: 105 | path: /var/log 106 | 107 | 108 | 109 | # kibana 110 | --- 111 | apiVersion: v1 112 | kind: ReplicationController 113 | metadata: 114 | name: kibana-logging-v1 115 | namespace: kube-system 116 | labels: 117 | k8s-app: kibana-logging 118 | version: v1 119 | kubernetes.io/cluster-service: "true" 120 | spec: 121 | replicas: 1 122 | selector: 123 | k8s-app: kibana-logging 124 | version: v1 125 | template: 126 | metadata: 127 | labels: 128 | k8s-app: kibana-logging 129 | version: v1 130 | kubernetes.io/cluster-service: "true" 131 | spec: 132 | containers: 133 | - name: kibana-logging 134 | image: gcr.io/google_containers/kibana:1.3 135 | resources: 136 | # keep request = limit to keep this container in guaranteed class 137 | limits: 138 | cpu: 100m 139 | requests: 140 | cpu: 100m 141 | env: 142 | - name: "ELASTICSEARCH_URL" 143 | value: "http://elasticsearch-logging:9200" 144 | ports: 145 | - containerPort: 5601 146 | name: ui 147 | protocol: TCP 148 | --- 149 | apiVersion: v1 150 | kind: Service 151 | metadata: 152 | name: kibana-logging 153 | namespace: kube-system 154 | labels: 155 | k8s-app: kibana-logging 156 | kubernetes.io/cluster-service: "true" 157 | kubernetes.io/name: "Kibana" 158 | spec: 159 | ports: 160 | - port: 5601 161 | protocol: TCP 162 | targetPort: ui 163 | selector: 164 | k8s-app: kibana-logging 165 | -------------------------------------------------------------------------------- /Chapter12/12.1.1 windows-container.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: win-webserver 6 | labels: 7 | app: win-webserver 8 | spec: 9 | ports: 10 | - port: 80 11 | targetPort: 80 12 | nodePort: 40001 13 | selector: 14 | app: win-webserver 15 | type: NodePort 16 | 17 | --- 18 | apiVersion: extensions/v1beta1 19 | kind: Deployment 20 | metadata: 21 | labels: 22 | app: win-webserver 23 | name: win-webserver 24 | spec: 25 | replicas: 1 26 | template: 27 | metadata: 28 | labels: 29 | app: win-webserver 30 | name: win-webserver 31 | spec: 32 | containers: 33 | - name: windowswebserver 34 | image: mcr.microsoft.com/windows/servercore:1809 35 | command: 36 | - powershell.exe 37 | - -command 38 | - "<#code used from https://gist.github.com/wagnerandrade/5424431#> ; $$listener = New-Object System.Net.HttpListener ; $$listener.Prefixes.Add('http://*:80/') ; $$listener.Start() ; $$callerCounts = @{} ; Write-Host('Listening at http://*:80/') ; while ($$listener.IsListening) { ;$$context = $$listener.GetContext() ;$$requestUrl = $$context.Request.Url ;$$clientIP = $$context.Request.RemoteEndPoint.Address ;$$response = $$context.Response ;Write-Host '' ;Write-Host('> {0}' -f $$requestUrl) ; ;$$count = 1 ;$$k=$$callerCounts.Get_Item($$clientIP) ;if ($$k -ne $$null) { $$count += $$k } ;$$callerCounts.Set_Item($$clientIP, $$count) ;$$ip=(Get-NetAdapter | Get-NetIpAddress); $$header='

Windows Container Web Server

' ;$$callerCountsString='' ;$$callerCounts.Keys | % { $$callerCountsString+='

IP {0} callerCount {1} ' -f $$ip[1].IPAddress,$$callerCounts.Item($$_) } ;$$footer='' ;$$content='{0}{1}{2}' -f $$header,$$callerCountsString,$$footer ;Write-Output $$content ;$$buffer = [System.Text.Encoding]::UTF8.GetBytes($$content) ;$$response.ContentLength64 = $$buffer.Length ;$$response.OutputStream.Write($$buffer, 0, $$buffer.Length) ;$$response.Close() ;$$responseStatus = $$response.StatusCode ;Write-Host('< {0}' -f $$responseStatus) } ; " 39 | nodeSelector: 40 | kubernetes.io/os: windows 41 | -------------------------------------------------------------------------------- /Chapter12/12.2.1 gpu-amd-device-plugin.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: extensions/v1beta1 3 | kind: DaemonSet 4 | metadata: 5 | name: amdgpu-device-plugin-daemonset 6 | namespace: kube-system 7 | spec: 8 | template: 9 | metadata: 10 | annotations: 11 | scheduler.alpha.kubernetes.io/critical-pod: "" 12 | labels: 13 | name: amdgpu-dp-ds 14 | spec: 15 | tolerations: 16 | - key: CriticalAddonsOnly 17 | operator: Exists 18 | containers: 19 | - image: rocm/k8s-device-plugin 20 | name: amdgpu-dp-cntr 21 | securityContext: 22 | allowPrivilegeEscalation: false 23 | capabilities: 24 | drop: ["ALL"] 25 | volumeMounts: 26 | - name: dp 27 | mountPath: /var/lib/kubelet/device-plugins 28 | - name: sys 29 | mountPath: /sys 30 | volumes: 31 | - name: dp 32 | hostPath: 33 | path: /var/lib/kubelet/device-plugins 34 | - name: sys 35 | hostPath: 36 | path: /sys 37 | -------------------------------------------------------------------------------- /Chapter12/12.2.1 gpu-nvidia-device-plugin.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: extensions/v1beta1 3 | kind: DaemonSet 4 | metadata: 5 | name: nvidia-device-plugin-daemonset 6 | namespace: kube-system 7 | spec: 8 | updateStrategy: 9 | type: RollingUpdate 10 | template: 11 | metadata: 12 | annotations: 13 | scheduler.alpha.kubernetes.io/critical-pod: "" 14 | labels: 15 | name: nvidia-device-plugin-ds 16 | spec: 17 | tolerations: 18 | - key: CriticalAddonsOnly 19 | operator: Exists 20 | - key: nvidia.com/gpu 21 | operator: Exists 22 | effect: NoSchedule 23 | containers: 24 | - image: nvidia/k8s-device-plugin:1.11 25 | name: nvidia-device-plugin-ctr 26 | securityContext: 27 | allowPrivilegeEscalation: false 28 | capabilities: 29 | drop: ["ALL"] 30 | volumeMounts: 31 | - name: device-plugin 32 | mountPath: /var/lib/kubelet/device-plugins 33 | volumes: 34 | - name: device-plugin 35 | hostPath: 36 | path: /var/lib/kubelet/device-plugins 37 | -------------------------------------------------------------------------------- /Chapter12/12.2.2 pod-use-gpu.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Pod 4 | metadata: 5 | name: cuda-vector-add 6 | spec: 7 | restartPolicy: OnFailure 8 | containers: 9 | - name: cuda-vector-add 10 | image: "k8s.gcr.io/cuda-vector-add:v0.1" 11 | resources: 12 | limits: 13 | nvidia.com/gpu: 1 # requesting 1 GPU 14 | 15 | 16 | --- 17 | apiVersion: v1 18 | kind: Pod 19 | metadata: 20 | name: cuda-vector-add 21 | spec: 22 | restartPolicy: OnFailure 23 | containers: 24 | - name: cuda-vector-add 25 | image: "k8s.gcr.io/cuda-vector-add:v0.1" 26 | resources: 27 | limits: 28 | nvidia.com/gpu: 1 29 | nodeSelector: 30 | accelerator: nvidia-tesla-p100 31 | -------------------------------------------------------------------------------- /Chapter12/12.3.3 verticalpodautoscaler.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: autoscaling.k8s.io/v1beta2 3 | kind: VerticalPodAutoscaler 4 | metadata: 5 | name: redis-vpa 6 | spec: 7 | targetRef: 8 | apiVersion: "extensions/v1beta1" 9 | kind: Deployment 10 | name: redis-master 11 | -------------------------------------------------------------------------------- /Chapter2/2.2.2 clusterconfiguration.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kubeadm.k8s.io/v1beta1 2 | kind: ClusterConfiguration 3 | imageRepository: docker.io/dustise 4 | kubernetesVersion: v1.14.0 5 | networking: 6 | podSubnet: "192.168.0.0/16" 7 | -------------------------------------------------------------------------------- /Chapter2/2.3.1 kubernetes-config-files.txt: -------------------------------------------------------------------------------- 1 | # /etc/kubernetes/apiserver 2 | KUBE_API_ARGS="--etcd-servers=http://127.0.0.1:2379 --insecure-bind-address=0.0.0.0 --insecure-port=8080 --service-cluster-ip-range=169.169.0.0/16 --service-node-port-range=1-65535 --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota --logtostderr=false --log-dir=/var/log/kubernetes --v=0" 3 | 4 | 5 | 6 | 7 | # /etc/kubernetes/kubeconfig 8 | apiVersion: v1 9 | kind: Config 10 | users: 11 | - name: client 12 | user: 13 | clusters: 14 | - name: default 15 | cluster: 16 | server: http://192.168.18.3:8080 17 | contexts: 18 | - context: 19 | cluster: default 20 | user: client 21 | name: default 22 | current-context: default 23 | 24 | 25 | 26 | 27 | # /etc/kubernetes/controller-manager 28 | KUBE_CONTROLLER_MANAGER_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig --logtostderr=false --log-dir=/var/log/kubernetes --v=0" 29 | 30 | 31 | 32 | 33 | # /etc/kubernetes/scheduler 34 | KUBE_SCHEDULER_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig --logtostderr=false --log-dir=/var/log/kubernetes --v=0" 35 | 36 | 37 | 38 | 39 | # /etc/kubernetes/kubelet 40 | KUBELET_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig --hostname-override=192.168.18.3 --logtostderr=false --log-dir=/var/log/kubernetes --v=0" 41 | 42 | 43 | 44 | 45 | # /etc/kubernetes/proxy 46 | KUBE_PROXY_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig --logtostderr=false --log-dir=/var/log/kubernetes --v=2" 47 | -------------------------------------------------------------------------------- /Chapter2/2.3.1 systemd-service-unit-files.service: -------------------------------------------------------------------------------- 1 | # etcd 2 | [Unit] 3 | Description=Etcd Server 4 | After=network.target 5 | 6 | [Service] 7 | Type=simple 8 | WorkingDirectory=/var/lib/etcd/ 9 | EnvironmentFile=-/etc/etcd/etcd.conf 10 | ExecStart=/usr/bin/etcd 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | 15 | 16 | 17 | 18 | # kube-apiserver 19 | [Unit] 20 | Description=Kubernetes API Server 21 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 22 | After=etcd.service 23 | Wants=etcd.service 24 | 25 | [Service] 26 | EnvironmentFile=/etc/kubernetes/apiserver 27 | ExecStart=/usr/bin/kube-apiserver $KUBE_API_ARGS 28 | Restart=on-failure 29 | Type=notify 30 | LimitNOFILE=65536 31 | 32 | [Install] 33 | WantedBy=multi-user.target 34 | 35 | 36 | 37 | 38 | # kube-controller-manager.service 39 | [Unit] 40 | Description=Kubernetes Controller Manager 41 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 42 | After=kube-apiserver.service 43 | Requires=kube-apiserver.service 44 | 45 | [Service] 46 | EnvironmentFile=/etc/kubernetes/controller-manager 47 | ExecStart=/usr/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_ARGS 48 | Restart=on-failure 49 | LimitNOFILE=65536 50 | 51 | [Install] 52 | WantedBy=multi-user.target 53 | 54 | 55 | 56 | 57 | # kube-scheduler.service 58 | [Unit] 59 | Description=Kubernetes Controller Manager 60 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 61 | After=kube-apiserver.service 62 | Requires=kube-apiserver.service 63 | 64 | [Service] 65 | EnvironmentFile=/etc/kubernetes/scheduler 66 | ExecStart=/usr/bin/kube-scheduler $KUBE_SCHEDULER_ARGS 67 | Restart=on-failure 68 | LimitNOFILE=65536 69 | 70 | [Install] 71 | WantedBy=multi-user.target 72 | 73 | 74 | 75 | 76 | # kubelet.service 77 | [Unit] 78 | Description=Kubernetes Kubelet Server 79 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 80 | After=docker.service 81 | Requires=docker.service 82 | 83 | [Service] 84 | WorkingDirectory=/var/lib/kubelet 85 | EnvironmentFile=/etc/kubernetes/kubelet 86 | ExecStart=/usr/bin/kubelet $KUBELET_ARGS 87 | Restart=on-failure 88 | 89 | [Install] 90 | WantedBy=multi-user.target 91 | 92 | 93 | 94 | 95 | # kube-proxy.service 96 | [Unit] 97 | Description=Kubernetes Kube-Proxy Server 98 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 99 | After=network.target 100 | Requires=network.service 101 | 102 | [Service] 103 | EnvironmentFile=/etc/kubernetes/proxy 104 | ExecStart=/usr/bin/kube-proxy $KUBE_PROXY_ARGS 105 | Restart=on-failure 106 | LimitNOFILE=65536 107 | 108 | [Install] 109 | WantedBy=multi-user.target 110 | -------------------------------------------------------------------------------- /Chapter2/2.4.1 kubernetes-ssl-config-files.txt: -------------------------------------------------------------------------------- 1 | #### master ssl config #### 2 | # openssl genrsa -out ca.key 2048 3 | 4 | # openssl req -x509 -new -nodes -key ca.key -subj "/CN=k8s-master" -days 5000 -out ca.crt 5 | 6 | # openssl genrsa -out server.key 2048 7 | 8 | 9 | # master_ssl.cnf 10 | [req] 11 | req_extensions = v3_req 12 | distinguished_name = req_distinguished_name 13 | [req_distinguished_name] 14 | [ v3_req ] 15 | basicConstraints = CA:FALSE 16 | keyUsage = nonRepudiation, digitalSignature, keyEncipherment 17 | subjectAltName = @alt_names 18 | [alt_names] 19 | DNS.1 = kubernetes 20 | DNS.2 = kubernetes.default 21 | DNS.3 = kubernetes.default.svc 22 | DNS.4 = kubernetes.default.svc.cluster.local 23 | DNS.5 = k8s-master 24 | IP.1 = 169.169.0.1 25 | IP.2 = 192.168.18.3 26 | 27 | 28 | # openssl req -new -key server.key -subj "/CN=k8s-master" -config master_ssl.cnf -out server.csr 29 | 30 | # openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 5000 -extensions v3_req -extfile master_ssl.cnf -out server.crt 31 | 32 | 33 | 34 | 35 | # /etc/kubernetes/apiserver 36 | KUBE_API_ARGS="--etcd-servers=http://127.0.0.1:2379 --client-ca-file=/var/run/kubernetes/ca.crt --tls-private-key-file=/var/run/kubernetes/server.key --tls-cert-file=/var/run/kubernetes/server.crt --insecure-port=0 --secure-port=6443 --service-cluster-ip-range=169.169.0.0/16 --service-node-port-range=1-65535 --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota --logtostderr=false --log-dir=/var/log/kubernetes --v=0" 37 | 38 | 39 | 40 | 41 | # /etc/kubernetes/kubeconfig 42 | apiVersion: v1 43 | kind: Config 44 | users: 45 | - name: controllermanager 46 | user: 47 | client-certificate: /var/run/kubernetes/cs_client.crt 48 | client-key: /var/run/kubernetes/cs_client.key 49 | clusters: 50 | - name: local 51 | cluster: 52 | certificate-authority: /var/run/kubernetes/ca.crt 53 | server: https://192.168.18.3:6443 54 | contexts: 55 | - context: 56 | cluster: local 57 | user: controllermanager 58 | name: my-context 59 | current-context: my-context 60 | 61 | 62 | 63 | 64 | # /etc/kubernetes/controller-manager 65 | KUBE_CONTROLLER_MANAGER_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig --service-account-key-file=/var/run/kubernetes/server.key --root-ca-file=/var/run/kubernetes/ca.crt --logtostderr=false --log-dir=/var/log/kubernetes --v=0" 66 | 67 | 68 | 69 | 70 | # /etc/kubernetes/scheduler 71 | KUBE_SCHEDULER_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig --logtostderr=false --log-dir=/var/log/kubernetes --v=0" 72 | 73 | 74 | 75 | 76 | 77 | #### node ssl config #### 78 | 79 | $ openssl genrsa -out kubelet_client.key 2048 80 | $ openssl req -new -key kubelet_client.key -subj "/CN=192.168.18.4" -out kubelet_client.csr 81 | $ openssl x509 -req -in kubelet_client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out kubelet_client.crt -days 5000 82 | 83 | 84 | # /etc/kubernetes/kubeconfig 85 | apiVersion: v1 86 | kind: Config 87 | users: 88 | - name: kubelet 89 | user: 90 | client-certificate: /etc/kubernetes/ssl_keys/kubelet_client.crt 91 | client-key: /etc/kubernetes/ssl_keys/kubelet_client.key 92 | clusters: 93 | - name: local 94 | cluster: 95 | certificate-authority: /etc/kubernetes/ssl_keys/ca.crt 96 | server: https://192.168.18.3:6443 97 | contexts: 98 | - context: 99 | cluster: local 100 | user: kubelet 101 | name: my-context 102 | current-context: my-context 103 | 104 | 105 | 106 | 107 | # /etc/kubernetes/kubelet 108 | KUBELET_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig --hostname-override=192.168.18.3 --logtostderr=false --log-dir=/var/log/kubernetes --v=0" 109 | 110 | 111 | 112 | 113 | # /etc/kubernetes/proxy 114 | KUBE_PROXY_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig --logtostderr=false --log-dir=/var/log/kubernetes --v=2" 115 | 116 | 117 | 118 | 119 | 120 | #### kubectl cli #### 121 | # kubectl --server=https://192.168.18.3:6443 --certificate-authority=/etc/kubernetes/ssl_keys/ca.crt --client-certificate=/etc/kubernetes/ssl_keys/cs_client.crt --client-key=/etc/kubernetes/ssl_keys/cs_client.key get nodes 122 | -------------------------------------------------------------------------------- /Chapter3/3.10 init-containers.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: nginx 5 | annotations: 6 | spec: 7 | # These containers are run during pod initialization 8 | initContainers: 9 | - name: install 10 | image: busybox 11 | command: 12 | - wget 13 | - "-O" 14 | - "/work-dir/index.html" 15 | - http://kubernetes.io 16 | volumeMounts: 17 | - name: workdir 18 | mountPath: "/work-dir" 19 | containers: 20 | - name: nginx 21 | image: nginx 22 | ports: 23 | - containerPort: 80 24 | volumeMounts: 25 | - name: workdir 26 | mountPath: /usr/share/nginx/html 27 | dnsPolicy: Default 28 | volumes: 29 | - name: workdir 30 | emptyDir: {} -------------------------------------------------------------------------------- /Chapter3/3.11.1 deployment-update-rollback.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1beta1 3 | kind: Deployment 4 | metadata: 5 | name: nginx-deployment 6 | spec: 7 | replicas: 3 8 | template: 9 | metadata: 10 | labels: 11 | app: nginx 12 | spec: 13 | containers: 14 | - name: nginx 15 | image: nginx:1.7.9 16 | ports: 17 | - containerPort: 80 18 | 19 | 20 | 21 | # update 22 | $ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 23 | $ kubectl rollout status deployment/nginx-deployment 24 | 25 | 26 | # rollback 27 | $ kubectl rollout history deployment/nginx-deployment --revision=3 28 | $ kubectl rollout undo deployment/nginx-deployment 29 | $ kubectl rollout undo deployment/nginx-deployment --to-revision=2 30 | 31 | 32 | # pause and resume 33 | $ kubectl rollout pause deployment/nginx-deployment 34 | $ kubectl set image deploy/nginx-deployment nginx=nginx:1.9.1 35 | $ kubectl rollout history deploy/nginx-deployment 36 | $ kubectl set resources deployment nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi 37 | $ kubectl rollout resume deploy nginx-deployment 38 | -------------------------------------------------------------------------------- /Chapter3/3.11.4 rc-rolling-update.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ReplicationController 4 | metadata: 5 | name: redis-master-v2 6 | labels: 7 | name: redis-master 8 | version: v2 9 | spec: 10 | replicas: 1 11 | selector: 12 | name: redis-master 13 | version: v2 14 | template: 15 | metadata: 16 | labels: 17 | name: redis-master 18 | version: v2 19 | spec: 20 | containers: 21 | - name: master 22 | image: kubeguide/redis-master:2.0 23 | ports: 24 | - containerPort: 6379 25 | 26 | 27 | 28 | # kubectl rolling-update redis-master -f redis-master-controller-v2.yaml 29 | 30 | # kubectl rolling-update redis-master --image=redis-master:2.0 31 | 32 | # kubectl rolling-update redis-master --image=kubeguide/redis-master:2.0 --rollback 33 | -------------------------------------------------------------------------------- /Chapter3/3.12.1 deployment-scale.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1beta1 3 | kind: Deployment 4 | metadata: 5 | name: nginx-deployment 6 | spec: 7 | replicas: 3 8 | template: 9 | metadata: 10 | labels: 11 | app: nginx 12 | spec: 13 | containers: 14 | - name: nginx 15 | image: nginx:1.7.9 16 | ports: 17 | - containerPort: 80 18 | 19 | 20 | 21 | $ kubectl scale deployment nginx-deployment --replicas 5 22 | 23 | $ kubectl scale deployment nginx-deployment --replicas=1 24 | -------------------------------------------------------------------------------- /Chapter3/3.12.2 hpa-v1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v1 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: php-apache 5 | spec: 6 | scaleTargetRef: 7 | apiVersion: apps/v1beta1 8 | kind: Deployment 9 | name: php-apache 10 | minReplicas: 1 11 | maxReplicas: 10 12 | targetCPUUtilizationPercentage: 50 -------------------------------------------------------------------------------- /Chapter3/3.12.2 hpa-v2.yaml: -------------------------------------------------------------------------------- 1 | # 1. prometheus-operator 2 | --- 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | labels: 7 | k8s-app: prometheus-operator 8 | name: prometheus-operator 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | k8s-app: prometheus-operator 14 | template: 15 | metadata: 16 | labels: 17 | k8s-app: prometheus-operator 18 | spec: 19 | containers: 20 | - image: quay.io/coreos/prometheus-operator:v0.17.0 21 | imagePullPolicy: IfNotPresent 22 | name: prometheus-operator 23 | ports: 24 | - containerPort: 8080 25 | name: http 26 | resources: 27 | limits: 28 | cpu: 200m 29 | memory: 100Mi 30 | requests: 31 | cpu: 100m 32 | memory: 50Mi 33 | 34 | 35 | 36 | # 2. Prometheus 37 | --- 38 | apiVersion: monitoring.coreos.com/v1 39 | kind: Prometheus 40 | metadata: 41 | name: prometheus 42 | labels: 43 | app: prometheus 44 | prometheus: prometheus 45 | spec: 46 | replicas: 1 47 | baseImage: prom/prometheus 48 | version: v2.8.0 49 | serviceMonitorSelector: 50 | matchLabels: 51 | service-monitor: function 52 | resources: 53 | requests: 54 | memory: 300Mi 55 | 56 | --- 57 | apiVersion: v1 58 | kind: Service 59 | metadata: 60 | name: prometheus 61 | labels: 62 | app: prometheus 63 | prometheus: prometheus 64 | spec: 65 | selector: 66 | prometheus: prometheus 67 | ports: 68 | - name: http 69 | port: 9090 70 | 71 | 72 | 73 | # 3. custom-metrics-server 74 | --- 75 | kind: Namespace 76 | apiVersion: v1 77 | metadata: 78 | name: custom-metrics 79 | 80 | --- 81 | apiVersion: v1 82 | kind: ConfigMap 83 | metadata: 84 | name: adapter-config 85 | namespace: custom-metrics 86 | data: 87 | config.yaml: | 88 | rules: 89 | - seriesQuery: '{__name__=~"^container_.*",container_name!="POD",namespace!="",pod_name!=""}' 90 | seriesFilters: [] 91 | resources: 92 | overrides: 93 | namespace: 94 | resource: namespace 95 | pod_name: 96 | resource: pod 97 | name: 98 | matches: ^container_(.*)_seconds_total$ 99 | as: "" 100 | metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container_name!="POD"}[1m])) by (<<.GroupBy>>) 101 | - seriesQuery: '{__name__=~"^container_.*",container_name!="POD",namespace!="",pod_name!=""}' 102 | seriesFilters: 103 | - isNot: ^container_.*_seconds_total$ 104 | resources: 105 | overrides: 106 | namespace: 107 | resource: namespace 108 | pod_name: 109 | resource: pod 110 | name: 111 | matches: ^container_(.*)_total$ 112 | as: "" 113 | metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container_name!="POD"}[1m])) by (<<.GroupBy>>) 114 | - seriesQuery: '{__name__=~"^container_.*",container_name!="POD",namespace!="",pod_name!=""}' 115 | seriesFilters: 116 | - isNot: ^container_.*_total$ 117 | resources: 118 | overrides: 119 | namespace: 120 | resource: namespace 121 | pod_name: 122 | resource: pod 123 | name: 124 | matches: ^container_(.*)$ 125 | as: "" 126 | metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>,container_name!="POD"}) by (<<.GroupBy>>) 127 | - seriesQuery: '{namespace!="",__name__!~"^container_.*"}' 128 | seriesFilters: 129 | - isNot: .*_total$ 130 | resources: 131 | template: <<.Resource>> 132 | name: 133 | matches: "" 134 | as: "" 135 | metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>) 136 | - seriesQuery: '{namespace!="",__name__!~"^container_.*"}' 137 | seriesFilters: 138 | - isNot: .*_seconds_total 139 | resources: 140 | template: <<.Resource>> 141 | name: 142 | matches: ^(.*)_total$ 143 | as: "" 144 | metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>) 145 | - seriesQuery: '{namespace!="",__name__!~"^container_.*"}' 146 | seriesFilters: [] 147 | resources: 148 | template: <<.Resource>> 149 | name: 150 | matches: ^(.*)_seconds_total$ 151 | as: "" 152 | metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>) 153 | resourceRules: 154 | cpu: 155 | containerQuery: sum(rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>) 156 | nodeQuery: sum(rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>, id='/'}[1m])) by (<<.GroupBy>>) 157 | resources: 158 | overrides: 159 | instance: 160 | resource: node 161 | namespace: 162 | resource: namespace 163 | pod_name: 164 | resource: pod 165 | containerLabel: container_name 166 | memory: 167 | containerQuery: sum(container_memory_working_set_bytes{<<.LabelMatchers>>}) by (<<.GroupBy>>) 168 | nodeQuery: sum(container_memory_working_set_bytes{<<.LabelMatchers>>,id='/'}) by (<<.GroupBy>>) 169 | resources: 170 | overrides: 171 | instance: 172 | resource: node 173 | namespace: 174 | resource: namespace 175 | pod_name: 176 | resource: pod 177 | containerLabel: container_name 178 | window: 1m 179 | 180 | --- 181 | apiVersion: apps/v1 182 | kind: Deployment 183 | metadata: 184 | name: custom-metrics-server 185 | namespace: custom-metrics 186 | labels: 187 | app: custom-metrics-server 188 | spec: 189 | replicas: 1 190 | selector: 191 | matchLabels: 192 | app: custom-metrics-server 193 | template: 194 | metadata: 195 | name: custom-metrics-server 196 | labels: 197 | app: custom-metrics-server 198 | spec: 199 | containers: 200 | - name: custom-metrics-server 201 | image: directxman12/k8s-prometheus-adapter-amd64 202 | imagePullPolicy: IfNotPresent 203 | args: 204 | - --prometheus-url=http://prometheus.default.svc:9090/ 205 | - --metrics-relist-interval=30s 206 | - --v=10 207 | - --config=/etc/adapter/config.yaml 208 | - --logtostderr=true 209 | ports: 210 | - containerPort: 443 211 | securityContext: 212 | runAsUser: 0 213 | volumeMounts: 214 | - mountPath: /etc/adapter/ 215 | name: config 216 | readOnly: true 217 | volumes: 218 | - name: config 219 | configMap: 220 | name: adapter-config 221 | 222 | --- 223 | apiVersion: v1 224 | kind: Service 225 | metadata: 226 | name: custom-metrics-server 227 | namespace: custom-metrics 228 | spec: 229 | ports: 230 | - port: 443 231 | targetPort: 443 232 | selector: 233 | app: custom-metrics-server 234 | 235 | --- 236 | apiVersion: apiregistration.k8s.io/v1beta1 237 | kind: APIService 238 | metadata: 239 | name: v1beta1.custom.metrics.k8s.io 240 | spec: 241 | service: 242 | name: custom-metrics-server 243 | namespace: custom-metrics 244 | group: custom.metrics.k8s.io 245 | version: v1beta1 246 | insecureSkipTLSVerify: true 247 | groupPriorityMinimum: 100 248 | versionPriority: 100 249 | 250 | 251 | 252 | # 4. app 253 | --- 254 | apiVersion: apps/v1 255 | kind: Deployment 256 | metadata: 257 | name: sample-app 258 | labels: 259 | app: sample-app 260 | spec: 261 | replicas: 1 262 | selector: 263 | matchLabels: 264 | app: sample-app 265 | template: 266 | metadata: 267 | labels: 268 | app: sample-app 269 | spec: 270 | containers: 271 | - image: luxas/autoscale-demo:v0.1.2 272 | imagePullPolicy: IfNotPresent 273 | name: metrics-provider 274 | ports: 275 | - name: http 276 | containerPort: 8080 277 | 278 | --- 279 | apiVersion: v1 280 | kind: Service 281 | metadata: 282 | name: sample-app 283 | labels: 284 | app: sample-app 285 | spec: 286 | ports: 287 | - name: http 288 | port: 80 289 | targetPort: 8080 290 | selector: 291 | app: sample-app 292 | 293 | 294 | 295 | # 5. Prometheus ServiceMonitor 296 | apiVersion: monitoring.coreos.com/v1 297 | kind: ServiceMonitor 298 | metadata: 299 | name: sample-app 300 | labels: 301 | service-monitor: function 302 | spec: 303 | selector: 304 | matchLabels: 305 | app: sample-app 306 | endpoints: 307 | - port: http 308 | 309 | 310 | 311 | # 6. HPA 312 | --- 313 | apiVersion: autoscaling/v2beta2 314 | kind: HorizontalPodAutoscaler 315 | metadata: 316 | name: sample-app 317 | spec: 318 | scaleTargetRef: 319 | apiVersion: apps/v1 320 | kind: Deployment 321 | name: sample-app 322 | minReplicas: 1 323 | maxReplicas: 10 324 | metrics: 325 | - type: Pods 326 | pods: 327 | metric: 328 | name: http_requests 329 | target: 330 | type: AverageValue 331 | averageValue: 500m 332 | 333 | 334 | 335 | # 7. send http requests to app 336 | # for i in {1..100000}; do wget -q -O- 169.169.43.252 > /dev/null; done 337 | -------------------------------------------------------------------------------- /Chapter3/3.13 statefulset-mongodb-cluster.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: storage.k8s.io/v1 3 | kind: StorageClass 4 | metadata: 5 | name: fast 6 | provisioner: kubernetes.io/glusterfs 7 | parameters: 8 | resturl: "http://" 9 | 10 | 11 | --- 12 | apiVersion: v1 13 | kind: Service 14 | metadata: 15 | name: mongo 16 | labels: 17 | name: mongo 18 | spec: 19 | ports: 20 | - port: 27017 21 | targetPort: 27017 22 | clusterIP: None 23 | selector: 24 | role: mongo 25 | 26 | 27 | --- 28 | apiVersion: apps/v1beta1 29 | kind: StatefulSet 30 | metadata: 31 | name: mongo 32 | spec: 33 | serviceName: "mongo" 34 | replicas: 3 35 | template: 36 | metadata: 37 | labels: 38 | role: mongo 39 | environment: test 40 | spec: 41 | terminationGracePeriodSeconds: 10 42 | containers: 43 | - name: mongo 44 | image: mongo 45 | command: 46 | - mongod 47 | - "--replSet" 48 | - rs0 49 | - "--smallfiles" 50 | - "--noprealloc" 51 | ports: 52 | - containerPort: 27017 53 | volumeMounts: 54 | - name: mongo-persistent-storage 55 | mountPath: /data/db 56 | - name: mongo-sidecar 57 | image: cvallance/mongo-k8s-sidecar 58 | env: 59 | - name: MONGO_SIDECAR_POD_LABELS 60 | value: "role=mongo,environment=test" 61 | - name: KUBERNETES_MONGO_SERVICE_NAME 62 | value: "mongo" 63 | volumeClaimTemplates: 64 | - metadata: 65 | name: mongo-persistent-storage 66 | annotations: 67 | volume.beta.kubernetes.io/storage-class: "fast" 68 | spec: 69 | accessModes: [ "ReadWriteOnce" ] 70 | resources: 71 | requests: 72 | storage: 100Gi 73 | -------------------------------------------------------------------------------- /Chapter3/3.2 frontend-localredis-pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: redis-php 5 | labels: 6 | name: redis-php 7 | spec: 8 | containers: 9 | - name: frontend 10 | image: kubeguide/guestbook-php-frontend:localredis 11 | ports: 12 | - containerPort: 80 13 | - name: redis 14 | image: kubeguide/redis-master 15 | ports: 16 | - containerPort: 6379 17 | -------------------------------------------------------------------------------- /Chapter3/3.3 static-web.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: static-web 5 | labels: 6 | name: static-web 7 | spec: 8 | containers: 9 | - name: static-web 10 | image: nginx 11 | ports: 12 | - name: web 13 | containerPort: 80 14 | 15 | -------------------------------------------------------------------------------- /Chapter3/3.4 pod-volume-applogs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: volume-pod 5 | spec: 6 | containers: 7 | - name: tomcat 8 | image: tomcat 9 | ports: 10 | - containerPort: 8080 11 | volumeMounts: 12 | - name: app-logs 13 | mountPath: /usr/local/tomcat/logs 14 | - name: busybox 15 | image: busybox 16 | command: ["sh", "-c", "tail -f /logs/catalina*.log"] 17 | volumeMounts: 18 | - name: app-logs 19 | mountPath: /logs 20 | volumes: 21 | - name: app-logs 22 | emptyDir: {} 23 | -------------------------------------------------------------------------------- /Chapter3/3.5.2 cm-appconfigfiles.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: cm-appconfigfiles 5 | data: 6 | key-serverxml: | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 31 | 32 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | key-loggingproperties: "handlers 43 | = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler, 44 | 3manager.org.apache.juli.FileHandler, 4host-manager.org.apache.juli.FileHandler, 45 | java.util.logging.ConsoleHandler\r\n\r\n.handlers = 1catalina.org.apache.juli.FileHandler, 46 | java.util.logging.ConsoleHandler\r\n\r\n1catalina.org.apache.juli.FileHandler.level 47 | = FINE\r\n1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs\r\n1catalina.org.apache.juli.FileHandler.prefix 48 | = catalina.\r\n\r\n2localhost.org.apache.juli.FileHandler.level = FINE\r\n2localhost.org.apache.juli.FileHandler.directory 49 | = ${catalina.base}/logs\r\n2localhost.org.apache.juli.FileHandler.prefix = localhost.\r\n\r\n3manager.org.apache.juli.FileHandler.level 50 | = FINE\r\n3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs\r\n3manager.org.apache.juli.FileHandler.prefix 51 | = manager.\r\n\r\n4host-manager.org.apache.juli.FileHandler.level = FINE\r\n4host-manager.org.apache.juli.FileHandler.directory 52 | = ${catalina.base}/logs\r\n4host-manager.org.apache.juli.FileHandler.prefix = 53 | host-manager.\r\n\r\njava.util.logging.ConsoleHandler.level = FINE\r\njava.util.logging.ConsoleHandler.formatter 54 | = java.util.logging.SimpleFormatter\r\n\r\n\r\norg.apache.catalina.core.ContainerBase.[Catalina].[localhost].level 55 | = INFO\r\norg.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers 56 | = 2localhost.org.apache.juli.FileHandler\r\n\r\norg.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level 57 | = INFO\r\norg.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers 58 | = 3manager.org.apache.juli.FileHandler\r\n\r\norg.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level 59 | = INFO\r\norg.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers 60 | = 4host-manager.org.apache.juli.FileHandler\r\n\r\n" 61 | 62 | -------------------------------------------------------------------------------- /Chapter3/3.5.2 cm-appvars.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: cm-appvars 5 | data: 6 | apploglevel: info 7 | appdatadir: /var/data 8 | 9 | -------------------------------------------------------------------------------- /Chapter3/3.5.3 cm-test-pod-envfrom.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: cm-test-pod 5 | spec: 6 | containers: 7 | - name: cm-test 8 | image: busybox 9 | command: [ "/bin/sh", "-c", "env" ] 10 | envFrom: 11 | - configMapRef 12 | name: cm-appvars 13 | restartPolicy: Never 14 | -------------------------------------------------------------------------------- /Chapter3/3.5.3 cm-test-pod-use-envvar.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: cm-test-pod 5 | spec: 6 | containers: 7 | - name: cm-test 8 | image: busybox 9 | command: [ "/bin/sh", "-c", "env | grep APP" ] 10 | env: 11 | - name: APPLOGLEVEL 12 | valueFrom: 13 | configMapKeyRef: 14 | name: cm-appvars 15 | key: apploglevel 16 | - name: APPDATADIR 17 | valueFrom: 18 | configMapKeyRef: 19 | name: cm-appvars 20 | key: appdatadir 21 | restartPolicy: Never 22 | -------------------------------------------------------------------------------- /Chapter3/3.5.3 cm-test-pod-volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: cm-test-app 5 | spec: 6 | containers: 7 | - name: cm-test-app 8 | image: kubeguide/tomcat-app:v1 9 | ports: 10 | - containerPort: 8080 11 | volumeMounts: 12 | - name: serverxml 13 | mountPath: /configfiles 14 | volumes: 15 | - name: serverxml 16 | configMap: 17 | name: cm-appconfigfiles 18 | items: 19 | - key: key-serverxml 20 | path: server.xml 21 | - key: key-loggingproperties 22 | path: logging.properties 23 | -------------------------------------------------------------------------------- /Chapter3/3.6.1 dapi-test-pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: dapi-test-pod 5 | spec: 6 | containers: 7 | - name: test-container 8 | image: busybox 9 | command: [ "/bin/sh", "-c", "env" ] 10 | env: 11 | - name: MY_POD_NAME 12 | valueFrom: 13 | fieldRef: 14 | fieldPath: metadata.name 15 | - name: MY_POD_NAMESPACE 16 | valueFrom: 17 | fieldRef: 18 | fieldPath: metadata.namespace 19 | - name: MY_POD_IP 20 | valueFrom: 21 | fieldRef: 22 | fieldPath: status.podIP 23 | restartPolicy: Never 24 | -------------------------------------------------------------------------------- /Chapter3/3.6.2 dapi-test-pod-container-vars.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: dapi-test-pod-container-vars 5 | spec: 6 | containers: 7 | - name: test-container 8 | image: busybox 9 | imagePullPolicy: Never 10 | command: [ "sh", "-c"] 11 | args: 12 | - while true; do 13 | echo -en '\n'; 14 | printenv MY_CPU_REQUEST MY_CPU_LIMIT; 15 | printenv MY_MEM_REQUEST MY_MEM_LIMIT; 16 | sleep 3600; 17 | done; 18 | resources: 19 | requests: 20 | memory: "32Mi" 21 | cpu: "125m" 22 | limits: 23 | memory: "64Mi" 24 | cpu: "250m" 25 | env: 26 | - name: MY_CPU_REQUEST 27 | valueFrom: 28 | resourceFieldRef: 29 | containerName: test-container 30 | resource: requests.cpu 31 | - name: MY_CPU_LIMIT 32 | valueFrom: 33 | resourceFieldRef: 34 | containerName: test-container 35 | resource: limits.cpu 36 | - name: MY_MEM_REQUEST 37 | valueFrom: 38 | resourceFieldRef: 39 | containerName: test-container 40 | resource: requests.memory 41 | - name: MY_MEM_LIMIT 42 | valueFrom: 43 | resourceFieldRef: 44 | containerName: test-container 45 | resource: limits.memory 46 | restartPolicy: Never -------------------------------------------------------------------------------- /Chapter3/3.6.3 dapi-test-pod-volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: dapi-test-pod-volume 5 | labels: 6 | zone: us-east-coast 7 | cluster: test-cluster1 8 | rack: rack-22 9 | annotations: 10 | build: two 11 | builder: john-doe 12 | spec: 13 | containers: 14 | - name: test-container 15 | image: busybox 16 | imagePullPolicy: Never 17 | command: ["sh", "-c"] 18 | args: 19 | - while true; do 20 | if [[ -e /etc/podinfo/labels ]]; then 21 | echo -en '\n\n'; cat /etc/podinfo/labels; fi; 22 | if [[ -e /etc/podinfo/annotations ]]; then 23 | echo -en '\n\n'; cat /etc/podinfo/annotations; fi; 24 | sleep 3600; 25 | done; 26 | volumeMounts: 27 | - name: podinfo 28 | mountPath: /etc/podinfo 29 | readOnly: false 30 | volumes: 31 | - name: podinfo 32 | downwardAPI: 33 | items: 34 | - path: "labels" 35 | fieldRef: 36 | fieldPath: metadata.labels 37 | - path: "annotations" 38 | fieldRef: 39 | fieldPath: metadata.annotations 40 | -------------------------------------------------------------------------------- /Chapter3/3.8 pod-livenessprobe.yaml: -------------------------------------------------------------------------------- 1 | # exec 2 | --- 3 | apiVersion: v1 4 | kind: Pod 5 | metadata: 6 | labels: 7 | test: liveness 8 | name: liveness-exec 9 | spec: 10 | containers: 11 | - name: liveness 12 | image: gcr.io/google_containers/busybox 13 | args: 14 | - /bin/sh 15 | - -c 16 | - echo ok > /tmp/health; sleep 10; rm -rf /tmp/health; sleep 600 17 | livenessProbe: 18 | exec: 19 | command: 20 | - cat 21 | - /tmp/health 22 | initialDelaySeconds: 15 23 | timeoutSeconds: 1 24 | 25 | 26 | # tcpsocket 27 | --- 28 | apiVersion: v1 29 | kind: Pod 30 | metadata: 31 | name: pod-with-healthcheck 32 | spec: 33 | containers: 34 | - name: nginx 35 | image: nginx 36 | ports: 37 | - containerPort: 80 38 | livenessProbe: 39 | tcpSocket: 40 | port: 80 41 | initialDelaySeconds: 30 42 | timeoutSeconds: 1 43 | 44 | 45 | # http 46 | --- 47 | apiVersion: v1 48 | kind: Pod 49 | metadata: 50 | name: pod-with-healthcheck 51 | spec: 52 | containers: 53 | - name: nginx 54 | image: nginx 55 | ports: 56 | - containerPort: 80 57 | livenessProbe: 58 | httpGet: 59 | path: /_status/healthz 60 | port: 80 61 | initialDelaySeconds: 30 62 | timeoutSeconds: 1 63 | -------------------------------------------------------------------------------- /Chapter3/3.9.1 nginx-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: nginx-deployment 5 | spec: 6 | replicas: 3 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 -------------------------------------------------------------------------------- /Chapter3/3.9.10 customized-scheduler.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Pod 4 | metadata: 5 | name: nginx 6 | labels: 7 | app: nginx 8 | spec: 9 | schedulerName: my-scheduler 10 | containers: 11 | - name: nginx 12 | image: nginx 13 | 14 | 15 | 16 | # customized scheduler, need to run through kubectl proxy 17 | #!/bin/bash 18 | SERVER='localhost:8001' 19 | while true; 20 | do 21 | for PODNAME in $(kubectl --server $SERVER get pods -o json | jq '.items[] | select(.spec.schedulerName == "my-scheduler") | select(.spec.nodeName == null) | .metadata.name' | tr -d '"'); 22 | do 23 | NODES=($(kubectl --server $SERVER get nodes -o json | jq '.items[].metadata.name' | tr -d '"')) 24 | NUMNODES=${#NODES[@]} 25 | CHOSEN=${NODES[$[ $RANDOM % $NUMNODES ]]} 26 | curl --header "Content-Type:application/json" --request POST --data '{"apiVersion":"v1", "kind": "Binding", "metadata": {"name": "'$PODNAME'"}, "target": {"apiVersion": "v1", "kind": "Node", "name":"'$CHOSEN'"}}' http://$SERVER/api/v1/namespaces/default/pods/$PODNAME/binding/ 27 | echo "Assigned $PODNAME to $CHOSEN" 28 | done 29 | sleep 1 30 | done 31 | -------------------------------------------------------------------------------- /Chapter3/3.9.2 redis-rc-nodeselector.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: redis-master 5 | labels: 6 | name: redis-master 7 | spec: 8 | replicas: 1 9 | selector: 10 | name: redis-master 11 | template: 12 | metadata: 13 | labels: 14 | name: redis-master 15 | spec: 16 | containers: 17 | - name: master 18 | image: kubeguide/redis-master 19 | ports: 20 | - containerPort: 6379 21 | nodeSelector: 22 | zone: north -------------------------------------------------------------------------------- /Chapter3/3.9.3 pod-nodeaffinity.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: with-node-affinity 5 | spec: 6 | affinity: 7 | nodeAffinity: 8 | requiredDuringSchedulingIgnoredDuringExecution: 9 | nodeSelectorTerms: 10 | - matchExpressions: 11 | - key: beta.kubernetes.io/arch 12 | operator: In 13 | values: 14 | - amd64 15 | preferredDuringSchedulingIgnoredDuringExecution: 16 | - weight: 1 17 | preference: 18 | matchExpressions: 19 | - key: disk-type 20 | operator: In 21 | values: 22 | - ssd 23 | containers: 24 | - name: with-node-affinity 25 | image: gcr.io/google_containers/pause:2.0 26 | -------------------------------------------------------------------------------- /Chapter3/3.9.4 pod-podaffinity.yaml: -------------------------------------------------------------------------------- 1 | # affinity 2 | --- 3 | apiVersion: v1 4 | kind: Pod 5 | metadata: 6 | name: pod-flag 7 | labels: 8 | security: "S1" 9 | app: "nginx" 10 | spec: 11 | containers: 12 | - name: nginx 13 | image: nginx 14 | 15 | --- 16 | apiVersion: v1 17 | kind: Pod 18 | metadata: 19 | name: pod-affinity 20 | spec: 21 | affinity: 22 | podAffinity: 23 | requiredDuringSchedulingIgnoredDuringExecution: 24 | - labelSelector: 25 | matchExpressions: 26 | - key: security 27 | operator: In 28 | values: 29 | - S1 30 | topologyKey: kubernetes.io/hostname 31 | containers: 32 | - name: with-pod-affinity 33 | image: gcr.io/google_containers/pause:2.0 34 | 35 | 36 | 37 | # anti-affinity 38 | --- 39 | apiVersion: v1 40 | kind: Pod 41 | metadata: 42 | name: anti-affinity 43 | spec: 44 | affinity: 45 | podAffinity: 46 | requiredDuringSchedulingIgnoredDuringExecution: 47 | - labelSelector: 48 | matchExpressions: 49 | - key: security 50 | operator: In 51 | values: 52 | - S1 53 | topologyKey: failure-domain.beta.kubernetes.io/zone 54 | podAntiAffinity: 55 | requiredDuringSchedulingIgnoredDuringExecution: 56 | - labelSelector: 57 | matchExpressions: 58 | - key: app 59 | operator: In 60 | values: 61 | - nginx 62 | topologyKey: kubernetes.io/hostname 63 | containers: 64 | - name: anti-affinity 65 | image: gcr.io/google_containers/pause:2.0 66 | -------------------------------------------------------------------------------- /Chapter3/3.9.5 pod-taints-tolerations.yaml: -------------------------------------------------------------------------------- 1 | # can be schedued to node1 2 | 3 | $ kubectl taint nodes node1 key=value:NoSchedule 4 | 5 | --- 6 | apiVersion: v1 7 | kind: Pod 8 | metadata: 9 | name: pod-toleration 10 | spec: 11 | tolerations: 12 | - key: "key" 13 | operator: "Equal" 14 | value: "value" 15 | effect: "NoSchedule" 16 | containers: 17 | - name: pod-toleration 18 | image: gcr.io/google_containers/pause:2.0 19 | 20 | --- 21 | tolerations: 22 | - key: "key" 23 | operator: "Exists" 24 | effect: "NoSchedule" 25 | 26 | 27 | 28 | 29 | # can't be scheduled to node1 30 | 31 | $ kubectl taint nodes node1 key1=value1:NoSchedule 32 | $ kubectl taint nodes node1 key1=value1:NoExecute 33 | $ kubectl taint nodes node1 key2=value2:NoSchedule 34 | 35 | 36 | --- 37 | tolerations: 38 | - key: "key1" 39 | operator: "Equal" 40 | value: "value1" 41 | effect: "NoSchedule" 42 | - key: "key1" 43 | operator: "Equal" 44 | value: "value1" 45 | effect: "NoExecute" 46 | 47 | -------------------------------------------------------------------------------- /Chapter3/3.9.6 pod-priority.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: scheduling.k8s.io/v1beta1 3 | kind: PriorityClass 4 | metadata: 5 | name: high-priority 6 | value: 1000000 7 | globalDefault: false 8 | description: "This priority class should be used for XYZ service pods only." 9 | 10 | 11 | --- 12 | apiVersion: v1 13 | kind: Pod 14 | metadata: 15 | name: nginx 16 | labels: 17 | env: test 18 | spec: 19 | containers: 20 | - name: nginx 21 | image: nginx 22 | imagePullPolicy: IfNotPresent 23 | priorityClassName: high-priority 24 | -------------------------------------------------------------------------------- /Chapter3/3.9.7 daemonset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: DaemonSet 3 | metadata: 4 | name: fluentd-cloud-logging 5 | namespace: kube-system 6 | labels: 7 | k8s-app: fluentd-cloud-logging 8 | spec: 9 | template: 10 | metadata: 11 | namespace: kube-system 12 | labels: 13 | k8s-app: fluentd-cloud-logging 14 | spec: 15 | containers: 16 | - name: fluentd-cloud-logging 17 | image: gcr.io/google_containers/fluentd-elasticsearch:1.17 18 | resources: 19 | limits: 20 | cpu: 100m 21 | memory: 200Mi 22 | env: 23 | - name: FLUENTD_ARGS 24 | value: -q 25 | volumeMounts: 26 | - name: varlog 27 | mountPath: /var/log 28 | readOnly: false 29 | - name: containers 30 | mountPath: /var/lib/docker/containers 31 | readOnly: false 32 | volumes: 33 | - name: containers 34 | hostPath: 35 | path: /var/lib/docker/containers 36 | - name: varlog 37 | hostPath: 38 | path: /var/log -------------------------------------------------------------------------------- /Chapter3/3.9.8 job.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: process-item-$ITEM 5 | labels: 6 | jobgroup: jobexample 7 | spec: 8 | template: 9 | metadata: 10 | name: jobexample 11 | labels: 12 | jobgroup: jobexample 13 | spec: 14 | containers: 15 | - name: c 16 | image: busybox 17 | command: ["sh", "-c", "echo Processing item $ITEM && sleep 5"] 18 | restartPolicy: Never 19 | -------------------------------------------------------------------------------- /Chapter3/3.9.9 cronjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v2alpha1 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 -------------------------------------------------------------------------------- /Chapter4/4.2 webapp-rc-service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ReplicationController 4 | metadata: 5 | name: webapp 6 | spec: 7 | replicas: 2 8 | template: 9 | metadata: 10 | name: webapp 11 | labels: 12 | app: webapp 13 | spec: 14 | containers: 15 | - name: webapp 16 | image: tomcat 17 | ports: 18 | - containerPort: 8080 19 | 20 | --- 21 | apiVersion: v1 22 | kind: Service 23 | metadata: 24 | name: webapp 25 | spec: 26 | ports: 27 | - port: 8081 28 | targetPort: 8080 29 | selector: 30 | app: webapp 31 | -------------------------------------------------------------------------------- /Chapter4/4.2.1 service-multiple-ports.yaml: -------------------------------------------------------------------------------- 1 | # multiple ports 2 | --- 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | name: webapp 7 | spec: 8 | ports: 9 | - port: 8080 10 | targetPort: 8080 11 | name: web 12 | - port: 8005 13 | targetPort: 8005 14 | name: management 15 | selector: 16 | app: webapp 17 | 18 | --- 19 | apiVersion: v1 20 | kind: Service 21 | metadata: 22 | name: kube-dns 23 | namespace: kube-system 24 | labels: 25 | k8s-app: kube-dns 26 | kubernetes.io/cluster-service: "true" 27 | kubernetes.io/name: "KubeDNS" 28 | spec: 29 | selector: 30 | k8s-app: kube-dns 31 | clusterIP: 169.169.0.100 32 | ports: 33 | - name: dns 34 | port: 53 35 | protocol: UDP 36 | - name: dns-tcp 37 | port: 53 38 | protocol: TCP 39 | -------------------------------------------------------------------------------- /Chapter4/4.2.2 external-service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: Service 3 | apiVersion: v1 4 | metadata: 5 | name: my-service 6 | spec: 7 | ports: 8 | - protocol: TCP 9 | port: 80 10 | targetPort: 80 11 | 12 | --- 13 | kind: Endpoints 14 | apiVersion: v1 15 | metadata: 16 | name: my-service 17 | subsets: 18 | - addresses: 19 | - IP: 1.2.3.4 20 | ports: 21 | - port: 80 22 | -------------------------------------------------------------------------------- /Chapter4/4.3.2 headless-service-cassandra.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | labels: 6 | name: cassandra 7 | name: cassandra 8 | spec: 9 | ports: 10 | - port: 9042 11 | selector: 12 | name: cassandra 13 | 14 | --- 15 | apiVersion: v1 16 | kind: ReplicationController 17 | metadata: 18 | labels: 19 | name: cassandra 20 | name: cassandra 21 | spec: 22 | replicas: 1 23 | selector: 24 | name: cassandra 25 | template: 26 | metadata: 27 | labels: 28 | name: cassandra 29 | spec: 30 | containers: 31 | - command: 32 | - /run.sh 33 | resources: 34 | limits: 35 | cpu: 0.5 36 | env: 37 | - name: MAX_HEAP_SIZE 38 | value: 512M 39 | - name: HEAP_NEWSIZE 40 | value: 100M 41 | - name: POD_NAMESPACE 42 | valueFrom: 43 | fieldRef: 44 | fieldPath: metadata.namespace 45 | image: gcr.io/google_containers/cassandra:v5 46 | name: cassandra 47 | ports: 48 | - containerPort: 9042 49 | name: cql 50 | - containerPort: 9160 51 | name: thrift 52 | volumeMounts: 53 | - mountPath: /cassandra_data 54 | name: data 55 | volumes: 56 | - name: data 57 | emptyDir: {} 58 | 59 | -------------------------------------------------------------------------------- /Chapter4/4.4.1 pod-hostnetwork.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: webapp 5 | labels: 6 | app: webapp 7 | spec: 8 | hostNetwork: true 9 | containers: 10 | - name: webapp 11 | image: tomcat 12 | imagePullPolicy: Never 13 | ports: 14 | - containerPort: 8080 -------------------------------------------------------------------------------- /Chapter4/4.4.1 pod-hostport.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: webapp 5 | labels: 6 | app: webapp 7 | spec: 8 | containers: 9 | - name: webapp 10 | image: tomcat 11 | ports: 12 | - containerPort: 8080 13 | hostPort: 8081 -------------------------------------------------------------------------------- /Chapter4/4.4.2 service-nodeport.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: webapp 5 | spec: 6 | type: NodePort 7 | ports: 8 | - port: 8080 9 | targetPort: 8080 10 | nodePort: 8081 11 | selector: 12 | app: webapp 13 | -------------------------------------------------------------------------------- /Chapter4/4.5.2 coredns.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: coredns 6 | namespace: kube-system 7 | labels: 8 | addonmanager.kubernetes.io/mode: EnsureExists 9 | data: 10 | Corefile: | 11 | cluster.local { 12 | errors 13 | health 14 | kubernetes cluster.local in-addr.arpa ip6.arpa { 15 | pods insecure 16 | upstream 17 | fallthrough in-addr.arpa ip6.arpa 18 | } 19 | prometheus :9153 20 | forward . /etc/resolv.conf 21 | cache 30 22 | loop 23 | reload 24 | loadbalance 25 | } 26 | . { 27 | cache 30 28 | loadbalance 29 | forward . /etc/resolv.conf 30 | } 31 | 32 | --- 33 | apiVersion: apps/v1 34 | kind: Deployment 35 | metadata: 36 | name: coredns 37 | namespace: kube-system 38 | labels: 39 | k8s-app: kube-dns 40 | kubernetes.io/cluster-service: "true" 41 | addonmanager.kubernetes.io/mode: Reconcile 42 | kubernetes.io/name: "CoreDNS" 43 | spec: 44 | replicas: 1 45 | strategy: 46 | type: RollingUpdate 47 | rollingUpdate: 48 | maxUnavailable: 1 49 | selector: 50 | matchLabels: 51 | k8s-app: kube-dns 52 | template: 53 | metadata: 54 | labels: 55 | k8s-app: kube-dns 56 | annotations: 57 | seccomp.security.alpha.kubernetes.io/pod: 'docker/default' 58 | spec: 59 | priorityClassName: system-cluster-critical 60 | tolerations: 61 | - key: "CriticalAddonsOnly" 62 | operator: "Exists" 63 | nodeSelector: 64 | beta.kubernetes.io/os: linux 65 | containers: 66 | - name: coredns 67 | image: coredns/coredns:1.3.1 68 | imagePullPolicy: IfNotPresent 69 | resources: 70 | limits: 71 | memory: 170Mi 72 | requests: 73 | cpu: 100m 74 | memory: 70Mi 75 | args: [ "-conf", "/etc/coredns/Corefile" ] 76 | volumeMounts: 77 | - name: config-volume 78 | mountPath: /etc/coredns 79 | readOnly: true 80 | ports: 81 | - containerPort: 53 82 | name: dns 83 | protocol: UDP 84 | - containerPort: 53 85 | name: dns-tcp 86 | protocol: TCP 87 | - containerPort: 9153 88 | name: metrics 89 | protocol: TCP 90 | livenessProbe: 91 | httpGet: 92 | path: /health 93 | port: 8080 94 | scheme: HTTP 95 | initialDelaySeconds: 60 96 | timeoutSeconds: 5 97 | successThreshold: 1 98 | failureThreshold: 5 99 | securityContext: 100 | allowPrivilegeEscalation: false 101 | capabilities: 102 | add: 103 | - NET_BIND_SERVICE 104 | drop: 105 | - all 106 | readOnlyRootFilesystem: true 107 | dnsPolicy: Default 108 | volumes: 109 | - name: config-volume 110 | configMap: 111 | name: coredns 112 | items: 113 | - key: Corefile 114 | path: Corefile 115 | 116 | --- 117 | apiVersion: v1 118 | kind: Service 119 | metadata: 120 | name: kube-dns 121 | namespace: kube-system 122 | annotations: 123 | prometheus.io/port: "9153" 124 | prometheus.io/scrape: "true" 125 | labels: 126 | k8s-app: kube-dns 127 | kubernetes.io/cluster-service: "true" 128 | addonmanager.kubernetes.io/mode: Reconcile 129 | kubernetes.io/name: "CoreDNS" 130 | spec: 131 | selector: 132 | k8s-app: kube-dns 133 | clusterIP: 169.169.0.100 134 | ports: 135 | - name: dns 136 | port: 53 137 | protocol: UDP 138 | - name: dns-tcp 139 | port: 53 140 | protocol: TCP 141 | - name: metrics 142 | port: 9153 143 | protocol: TCP 144 | 145 | # app to test servicename 146 | --- 147 | apiVersion: v1 148 | kind: Pod 149 | metadata: 150 | name: busybox 151 | namespace: default 152 | spec: 153 | containers: 154 | - name: busybox 155 | image: gcr.io/google_containers/busybox 156 | command: 157 | - sleep 158 | - "3600" 159 | 160 | # kubectl exec busybox -- nslookup redis-master 161 | -------------------------------------------------------------------------------- /Chapter4/4.5.5 pod-dnsconfig.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | namespace: default 5 | name: dns-example 6 | spec: 7 | containers: 8 | - name: test 9 | image: nginx 10 | dnsPolicy: "None" 11 | dnsConfig: 12 | nameservers: 13 | - 1.2.3.4 14 | searches: 15 | - ns1.svc.cluster.local 16 | - my.dns.search.suffix 17 | options: 18 | - name: ndots 19 | value: "2" 20 | - name: edns0 21 | -------------------------------------------------------------------------------- /Chapter4/4.6.1 ingress.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: extensions/v1beta1 3 | kind: Deployment 4 | metadata: 5 | name: default-http-backend 6 | labels: 7 | k8s-app: default-http-backend 8 | namespace: kube-system 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | labels: 14 | k8s-app: default-http-backend 15 | spec: 16 | terminationGracePeriodSeconds: 60 17 | containers: 18 | - name: default-http-backend 19 | image: gcr.io/google_containers/defaultbackend:1.0 20 | livenessProbe: 21 | httpGet: 22 | path: /healthz 23 | port: 8080 24 | scheme: HTTP 25 | initialDelaySeconds: 30 26 | timeoutSeconds: 5 27 | ports: 28 | - containerPort: 8080 29 | resources: 30 | limits: 31 | cpu: 10m 32 | memory: 20Mi 33 | requests: 34 | cpu: 10m 35 | memory: 20Mi 36 | --- 37 | apiVersion: v1 38 | kind: Service 39 | metadata: 40 | name: default-http-backend 41 | namespace: kube-system 42 | labels: 43 | k8s-app: default-http-backend 44 | spec: 45 | ports: 46 | - port: 80 47 | targetPort: 8080 48 | selector: 49 | k8s-app: default-http-backend 50 | 51 | --- 52 | apiVersion: extensions/v1beta1 53 | kind: DaemonSet 54 | metadata: 55 | name: nginx-ingress-lb 56 | labels: 57 | name: nginx-ingress-lb 58 | namespace: kube-system 59 | spec: 60 | template: 61 | metadata: 62 | labels: 63 | name: nginx-ingress-lb 64 | spec: 65 | terminationGracePeriodSeconds: 60 66 | containers: 67 | - image: gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.2 68 | name: nginx-ingress-lb 69 | readinessProbe: 70 | httpGet: 71 | path: /healthz 72 | port: 10254 73 | scheme: HTTP 74 | livenessProbe: 75 | httpGet: 76 | path: /healthz 77 | port: 10254 78 | scheme: HTTP 79 | initialDelaySeconds: 10 80 | timeoutSeconds: 1 81 | ports: 82 | - containerPort: 80 83 | hostPort: 80 84 | - containerPort: 443 85 | hostPort: 443 86 | env: 87 | - name: POD_NAME 88 | valueFrom: 89 | fieldRef: 90 | fieldPath: metadata.name 91 | - name: POD_NAMESPACE 92 | valueFrom: 93 | fieldRef: 94 | fieldPath: metadata.namespace 95 | args: 96 | - /nginx-ingress-controller 97 | - --default-backend-service=$(POD_NAMESPACE)/default-http-backend 98 | 99 | --- 100 | apiVersion: extensions/v1beta1 101 | kind: Ingress 102 | metadata: 103 | name: mywebsite-ingress 104 | spec: 105 | rules: 106 | - host: mywebsite.com 107 | http: 108 | paths: 109 | - path: /demo 110 | backend: 111 | serviceName: webapp 112 | servicePort: 8080 113 | -------------------------------------------------------------------------------- /Chapter4/4.6.5 ingress-tls.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: mywebsite-ingress-secret 6 | type: kubernetes.io/tls 7 | data: 8 | tls.crt: 9 | MIIDAzCCAeugAwIBAgIJALrTg9VLmFgdMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNVBAMMDW15d2Vic2l0ZS5jb20wHhcNMTcwNDIzMTMwMjA1WhcNMzAxMjMxMTMwMjA1WjAYMRYwFAYDVQQDDA1teXdlYnNpdGUu Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApL1y1rq1I3EQ5E0PjzW8Lc3heW4WYTyk POisDT9Zgyc+TLPGj/YF4QnAuoIUAUNtXPlmINKuD9Fxzmh6q0oSBVb42BU0RzOTtvaCVOU+uoJ9MgJp d7Bao5higTZMyvj5a1M9iwb7k4xRAsuGCh/jDO8fj6tgJW4WfzawO5w1pDd2fFDxYn34Ma1pg0xFebVa iqBu9FL0JbiEimsV9y7V+g6jjfGffu2xl06X3svqAdfGhvS+uCTArAXiZgS279se1Xp834CG0MJeP7ta mD44IfA2wkkmD+uCVjSEcNFsveY5cJevjf0PSE9g5wohSXphd1sIGyjEy2APeIJBP8bQ+wIDAQABo1Aw TjAdBgNVHQ4EFgQUjmpxpmdFPKWkr+A2XLF7oqro2GkwHwYDVR0jBBgwFoAUjmpxpmdFPKWkr+A2XLF7 oqro2GkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAAVXPyfagP1AIov3kXRhI3WfyCOIN /sgNSqKM3FuykboSBN6c1w4UhrpF71Hd4nt0myeyX/o69o2Oc9a9dIS2FEGKvfxZQ4sa99iI3qjoMAuu f/Q9fDYIZ+k0YvY4pbcCqqOyICFBCMLlAct/aB0K1GBvC5k06vD4Rn2fOdVMkloW+Zf41cxVIRZe/tQG nZoEhtM6FQADrv1+jM5gjIKRX3s2/Jcxy5g2XLPqtSpzYA0F7FJyuFJXEG+P9X466xPi9ialUri66vkb UVT6uLXGhhunsu6bZ/qwsm2HzdPo4WRQ3z2VhgFzHEzHVVX+CEyZ8fJGoSi7njapHb08lRiztQ== 10 | tls.key: 11 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCkvXLWurUjcRDkTQ+PNbwtzeF5bhZhPKQ86KwNP1mDJz5Ms8aP9gXhCcC6ghQBQ21c+WYg0q4P0XHOaHqrShIFVvjYFTRHM5O29oJU5T66gn0y Aml3sFqjmGKBNkzK+PlrUz2LBvuTjFECy4YKH+MM7x+Pq2AlbhZ/NrA7nDWkN3Z8UPFiffgxrWmDTEV5 tVqKoG70UvQluISKaxX3LtX6DqON8Z9+7bGXTpfey+oB18aG9L64JMCsBeJmBLbv2x7VenzfgIbQwl4/ u1qYPjgh8DbCSSYP64JWNIRw0Wy95jlwl6+N/Q9IT2DnCiFJemF3WwgbKMTLYA94gkE/xtD7AgMBAAEC ggEAUftNePq1RgvwYgzPX29YVFsOiAV28bDh8sW/SWBrRU90O2uDtwSx7EmUNbyiA/bwJ8KdRlxR7uFG B3gLA876pNmhQLdcqspKClUmiuUCkIJ7lzWIEt4aXStqae8BzEiWpwhnqhYxgD3l2sQ50jQII9mkFTUt xbLBU1F95kxYjX2XmFTrrvwroDLZEHCPcbY9hNUFhZaCdBBYKADmWo9eV/xZJ97ZAFpbpWyONrFjNwMj jqCmxMx3HwOI/tLbhpvob6RT1UG1QUPlbB8aXR1FeSgt0NYhYwWKF7JSXcYBiyQubtd3T6RBtNjFk4b/ zuEUhdFN1lKJLcsVDVQZgMsO4QKBgQDajXAq4hMKPH3CKdieAialj4rVAPyrAFYDMokW+7buZZAgZO1a rRtqFWLTtp6hwHqwTySHFyiRsK2Ikfct1H16hRn6FXbiPrFDP8gpYveu31Cd1qqYUYI7xaodWUiLldrt eun9sLr3YYR7kaXYRenWZFjZbbUkq3KJfoh+uArPwwKBgQDA95Y4xhcL0F5pE/TLEdj33WjRXMkXMCHX Gl3fTnBImoRf7jF9e5fRK/v4YIHaMCOn+6drwMv9KHFL0nvxPbgbECW1F2OfzmNgm6l7jkpcsCQOVtuu1+4gK+B2geQYRA2LhBk+9MtGQFmwSPgwSg+VHUrm28qhzUmTCN1etdpeaQKBgGAFqHSO44Kp1S8Lp6q0 kzpGeN7hEiIngaLh/y1j5pmTceFptocSa2sOfl86azPyF3WDMC9SU3a/Q18vkoRGSeMcu68O4y7AEK3V RiI4402nvAm9GTLXDPsp+3XtllwNuSSBznCxx1ONOuH3uf/tp7GUYR0WgHHeCfKy71GNluJ1AoGAKhHQ XnBRdfHno2EGbX9mniNXRs3DyZpkxlCpRpYDRNDrKz7y6ziW0LOWK4BezwLPwz/KMGPIFVlL2gv5mY6r JLtQfTqsLZsBb36AZL+Q1sRQGBA3tNa+w6TNOwj2gZPUoCYcmu0jpB1DcHt4II8E9q18NviUJNJsx/GW 0Z80DIECgYEAxzQBh/ckRvRaprN0v8w9GRq3wTYYD9y15U+3ecEIZrr1g9bLOi/rktXy3vqL6kj6CFlp wwRVLj8R3u1QPy3MpJNXYR1Bua+/FVn2xKwyYDuXaqs0vW3xLONVO7z44gAKmEQyDq2sir+vpayuY4ps fXXK06uifz6ELfVyY6XZvRA= 12 | 13 | --- 14 | apiVersion: extensions/v1beta1 15 | kind: Ingress 16 | metadata: 17 | name: mywebsite-ingress-tls 18 | spec: 19 | tls: 20 | - hosts: 21 | - mywebsite.com 22 | secretName: mywebsite-ingress-secret 23 | rules: 24 | - host: mywebsite.com 25 | http: 26 | paths: 27 | - path: /demo 28 | backend: 29 | serviceName: myweb 30 | servicePort: 8080 31 | -------------------------------------------------------------------------------- /Chapter6/6.2.3 rbac.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: Role 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | metadata: 5 | namespace: default 6 | name: pod-reader 7 | rules: 8 | - apiGroups: [""] 9 | resources: ["pods"] 10 | verbs: ["get", "watch", "list"] 11 | 12 | --- 13 | kind: ClusterRole 14 | apiVersion: rbac.authorization.k8s.io/v1 15 | metadata: 16 | rules: 17 | - apiGroups: [""] 18 | resources: ["secrets"] 19 | verbs: ["get", "watch", "list"] 20 | 21 | --- 22 | kind: RoleBinding 23 | apiVersion: rbac.authorization.k8s.io/v1 24 | metadata: 25 | name: read-pods 26 | namespace: default 27 | subjects: 28 | - kind: User 29 | name: jane 30 | apiGroup: rbac.authorization.k8s.io 31 | roleRef: 32 | kind: Role 33 | name: pod-reader 34 | apiGroup: rbac.authorization.k8s.io 35 | 36 | --- 37 | kind: RoleBinding 38 | apiVersion: rbac.authorization.k8s.io/v1 39 | metadata: 40 | name: read-secrets 41 | namespace: development 42 | subjects: 43 | - kind: User 44 | name: dave 45 | apiGroup: rbac.authorization.k8s.io 46 | roleRef: 47 | kind: ClusterRole 48 | name: secret-reader 49 | apiGroup: rbac.authorization.k8s.io 50 | 51 | --- 52 | kind: ClusterRoleBinding 53 | apiVersion: rbac.authorization.k8s.io/v1 54 | metadata: 55 | name: read-secrets-global 56 | subjects: 57 | - kind: Group 58 | name: manager 59 | apiGroup: rbac.authorization.k8s.io 60 | roleRef: 61 | kind: ClusterRole 62 | name: secret-reader 63 | apiGroup: rbac.authorization.k8s.io 64 | 65 | 66 | 67 | # resources reference 68 | --- 69 | kind: Role 70 | apiVersion: rbac.authorization.k8s.io/v1 71 | metadata: 72 | namespace: default 73 | name: pod-and-pod-logs-reader 74 | rules: 75 | - apiGroups: [""] 76 | resources: ["pods", "pods/log"] 77 | verbs: ["get", "list"] 78 | 79 | --- 80 | kind: Role 81 | apiVersion: rbac.authorization.k8s.io/v1 82 | metadata: 83 | namespace: default 84 | name: configmap-updater 85 | rules: 86 | - apiGroups: [""] 87 | resources: ["configmap"] 88 | resourceNames: ["my-configmap"] 89 | verbs: ["update", "get"] 90 | -------------------------------------------------------------------------------- /Chapter6/6.5 imagepullsecret.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: myregistrykey 6 | data: 7 | .dockercfg: eyAiaHR0cHM6Ly9pbmRleC5kb2NrZXIuaW8vdjEvIjogeyAiYXV0aCI6ICJab UZyWlhCaGMzTjNiM0prTVRJSyIsICJlbWFpbCI6ICJqZG9lQGV4YW1wbGUuY29tIiB9IH0K 8 | type: kubernetes.io/dockercfg 9 | 10 | --- 11 | apiVersion: v1 12 | kind: Pod 13 | metadata: 14 | name: mypod2 15 | spec: 16 | containers: 17 | - name: foo 18 | image: janedoe/awesomeapp:v1 19 | imagePullSecrets: 20 | - name: myregistrykey 21 | -------------------------------------------------------------------------------- /Chapter6/6.5 secret.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: mysecret 6 | type: Opaque 7 | data: 8 | password: dmFsdWUtMg0K 9 | username: dmFsdWUtMQ0K 10 | 11 | --- 12 | apiVersion: v1 13 | kind: Pod 14 | metadata: 15 | name: mypod 16 | namespace: myns 17 | spec: 18 | containers: 19 | - name: mycontainer 20 | image: redis 21 | volumeMounts: 22 | - name: foo 23 | mountPath: "/etc/foo" 24 | readOnly: true 25 | volumes: 26 | - name: foo 27 | secret: 28 | secretName: mysecret 29 | -------------------------------------------------------------------------------- /Chapter6/6.6.1 podsecuritypolicy.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: policy/v1beta1 3 | kind: PodSecurityPolicy 4 | metadata: 5 | name: psp-non-privileged 6 | spec: 7 | privileged: false 8 | seLinux: 9 | rule: RunAsAny 10 | supplementalGroups: 11 | rule: RunAsAny 12 | runAsUser: 13 | rule: RunAsAny 14 | fsGroup: 15 | rule: RunAsAny 16 | volumes: 17 | - '*' 18 | 19 | 20 | # ok to create 21 | --- 22 | apiVersion: v1 23 | kind: Pod 24 | metadata: 25 | name: nginx 26 | spec: 27 | containers: 28 | - name: nginx 29 | image: nginx 30 | 31 | 32 | # forbidden to create 33 | --- 34 | apiVersion: v1 35 | kind: Pod 36 | metadata: 37 | name: nginx 38 | spec: 39 | containers: 40 | - name: nginx 41 | image: nginx 42 | securityContext: 43 | privileged: true 44 | -------------------------------------------------------------------------------- /Chapter6/6.6.2 podsecuritypolicy-examples.yaml: -------------------------------------------------------------------------------- 1 | #### PodSecurityPolicy examples #### 2 | 3 | # AllowedHostPaths 4 | --- 5 | apiVersion: policy/v1beta1 6 | kind: PodSecurityPolicy 7 | metadata: 8 | name: allow-hostpath-volumes 9 | spec: 10 | volumes: 11 | - hostPath 12 | allowedHostPaths: 13 | - pathPrefix: "/foo" 14 | readOnly: true 15 | 16 | 17 | # allowedFlexVolumes 18 | --- 19 | apiVersion: policy/v1beta1 20 | kind: PodSecurityPolicy 21 | metadata: 22 | name: allow-flex-volumes 23 | spec: 24 | volumes: 25 | - flexVolume 26 | allowedFlexVolumes: 27 | - driver: example/lvm 28 | - driver: example/cifs 29 | 30 | 31 | # privileged 32 | --- 33 | apiVersion: policy/v1beta1 34 | kind: PodSecurityPolicy 35 | metadata: 36 | name: privileged 37 | annotations: 38 | seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' 39 | spec: 40 | privileged: true 41 | allowPrivilegeEscalation: true 42 | allowedCapabilities: 43 | - '*' 44 | volumes: 45 | - '*' 46 | hostNetwork: true 47 | hostPorts: 48 | - min: 0 49 | max: 65535 50 | hostIPC: true 51 | hostPID: true 52 | runAsUser: 53 | rule: 'RunAsAny' 54 | seLinux: 55 | rule: 'RunAsAny' 56 | supplementalGroups: 57 | rule: 'RunAsAny' 58 | fsGroup: 59 | rule: 'RunAsAny' 60 | 61 | 62 | # restricted 63 | --- 64 | apiVersion: policy/v1beta1 65 | kind: PodSecurityPolicy 66 | metadata: 67 | name: restricted 68 | annotations: 69 | seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default' 70 | apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' 71 | seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' 72 | apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' 73 | spec: 74 | privileged: false 75 | allowPrivilegeEscalation: false 76 | requiredDropCapabilities: 77 | - ALL 78 | volumes: 79 | - 'configMap' 80 | - 'emptyDir' 81 | - 'projected' 82 | - 'secret' 83 | - 'downwardAPI' 84 | - 'persistentVolumeClaim' 85 | hostNetwork: false 86 | hostIPC: false 87 | hostPID: false 88 | runAsUser: 89 | rule: 'MustRunAsNonRoot' 90 | seLinux: 91 | rule: 'RunAsAny' 92 | supplementalGroups: 93 | rule: 'MustRunAs' 94 | ranges: 95 | - min: 1 96 | max: 65535 97 | fsGroup: 98 | rule: 'MustRunAs' 99 | ranges: 100 | - min: 1 101 | max: 65535 102 | readOnlyRootFilesystem: false 103 | 104 | 105 | 106 | 107 | # authorizing via rbac 108 | --- 109 | kind: ClusterRole 110 | apiVersion: rbac.authorization.k8s.io/v1 111 | metadata: 112 | name: 113 | rules: 114 | - apiGroups: ['policy'] 115 | resources: ['podsecuritypolicies'] 116 | verbs: ['use'] 117 | resourceNames: 118 | - 119 | 120 | --- 121 | kind: ClusterRoleBinding 122 | apiVersion: rbac.authorization.k8s.io/v1 123 | metadata: 124 | name: 125 | roleRef: 126 | kind: ClusterRole 127 | name: 128 | apiGroup: rbac.authorization.k8s.io 129 | subjects: 130 | - kind: ServiceAccount 131 | name: 132 | namespace: 133 | - kind: User 134 | apiGroup: rbac.authorization.k8s.io 135 | name: 136 | 137 | --- 138 | kind: RoleBinding 139 | apiVersion: rbac.authorization.k8s.io/v1 140 | metadata: 141 | name: 142 | namespace: 143 | roleRef: 144 | kind: Role 145 | name: 146 | apiGroup: rbac.authorization.k8s.io 147 | subjects: 148 | - kind: Group 149 | apiGroup: rbac.authorization.k8s.io 150 | name: system:serviceaccounts 151 | - kind: Group 152 | apiGroup: rbac.authorization.k8s.io 153 | name: system:authenticated 154 | -------------------------------------------------------------------------------- /Chapter6/6.6.3 pod-securitycontext.yaml: -------------------------------------------------------------------------------- 1 | # pod level 2 | --- 3 | apiVersion: v1 4 | kind: Pod 5 | metadata: 6 | name: security-context-demo 7 | spec: 8 | securityContext: 9 | runAsUser: 1000 10 | runAsGroup: 3000 11 | fsGroup: 2000 12 | volumes: 13 | - name: sec-ctx-vol 14 | emptyDir: {} 15 | containers: 16 | - name: sec-ctx-demo 17 | image: gcr.io/google-samples/node-hello:1.0 18 | volumeMounts: 19 | - name: sec-ctx-vol 20 | mountPath: /data/demo 21 | securityContext: 22 | allowPrivilegeEscalation: false 23 | 24 | 25 | # container level 26 | --- 27 | apiVersion: v1 28 | kind: Pod 29 | metadata: 30 | name: security-context-demo-2 31 | spec: 32 | securityContext: 33 | runAsUser: 1000 34 | containers: 35 | - name: sec-ctx-demo-2 36 | image: gcr.io/google-samples/node-hello:1.0 37 | securityContext: 38 | runAsUser: 2000 39 | allowPrivilegeEscalation: false 40 | 41 | 42 | # capabilities 43 | --- 44 | apiVersion: v1 45 | kind: Pod 46 | metadata: 47 | name: security-context-demo-4 48 | spec: 49 | containers: 50 | - name: sec-ctx-4 51 | image: gcr.io/google-samples/node-hello:1.0 52 | securityContext: 53 | capabilities: 54 | add: ["NET_ADMIN", "SYS_TIME"] 55 | -------------------------------------------------------------------------------- /Chapter7/7.5 pod-service-network.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ReplicationController 4 | metadata: 5 | name: frontend 6 | labels: 7 | name: frontend 8 | spec: 9 | replicas: 1 10 | selector: 11 | name: frontend 12 | template: 13 | metadata: 14 | labels: 15 | name: frontend 16 | spec: 17 | containers: 18 | - name: php-redis 19 | image: kubeguide/guestbook-php-frontend 20 | env: 21 | - name: GET_HOSTS_FROM 22 | value: env 23 | ports: 24 | - containerPort: 80 25 | hostPort: 80 26 | 27 | --- 28 | apiVersion: v1 29 | kind: Service 30 | metadata: 31 | name: frontend 32 | labels: 33 | name: frontend 34 | spec: 35 | ports: 36 | - port: 80 37 | selector: 38 | name: frontend 39 | -------------------------------------------------------------------------------- /Chapter7/7.6.2 cni-plugin-examples.json: -------------------------------------------------------------------------------- 1 | # dbnet 2 | { 3 | "cniVersion": "0.4.0", 4 | "name": "dbnet", 5 | "type": "bridge", 6 | "bridge": "cni0", 7 | "ipam": { 8 | "type": "host-local", 9 | "subnet": "10.1.0.0/16", 10 | "gateway": "10.1.0.1" 11 | }, 12 | "dns": { 13 | "nameservers": [ "10.1.0.1" ] 14 | } 15 | } 16 | 17 | 18 | 19 | # ipam plugin 20 | { 21 | "cniVersion": "0.4.0", 22 | "ips": [ 23 | { 24 | "version": "<4-or-6>", 25 | "address": "", 26 | "gateway": "" (optional) 27 | }, 28 | ...... 29 | ], 30 | "routes": [ (optional) 31 | { 32 | "dst": "", 33 | "gw": "" (optional) 34 | }, 35 | ...... 36 | ] 37 | "dns": { 38 | "nameservers": (optional) 39 | "domain": (optional) 40 | "search": (optional) 41 | "options": (optional) 42 | } 43 | } 44 | 45 | 46 | 47 | # multiple plugin 48 | { 49 | "cniVersion": "0.4.0", 50 | "name": "dbnet", 51 | "plugins": [ 52 | { 53 | "type": "bridge", 54 | // type (plugin) specific 55 | "bridge": "cni0", 56 | // args may be ignored by plugins 57 | "args": { 58 | "labels" : { 59 | "appVersion" : "1.0" 60 | } 61 | }, 62 | "ipam": { 63 | "type": "host-local", 64 | // ipam specific 65 | "subnet": "10.1.0.0/16", 66 | "gateway": "10.1.0.1" 67 | }, 68 | "dns": { 69 | "nameservers": [ "10.1.0.1" ] 70 | } 71 | }, 72 | { 73 | "type": "tuning", 74 | "sysctl": { 75 | "net.core.somaxconn": "500" 76 | } 77 | } 78 | ] 79 | } 80 | 81 | -------------------------------------------------------------------------------- /Chapter7/7.7.1 networkpolicy.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: networking.k8s.io/v1 3 | kind: NetworkPolicy 4 | metadata: 5 | name: test-network-policy 6 | namespace: default 7 | spec: 8 | podSelector: 9 | matchLabels: 10 | role: db 11 | policyTypes: 12 | - Ingress 13 | - Egress 14 | ingress: 15 | - from: 16 | - ipBlock: 17 | cidr: 172.17.0.0/16 18 | except: 19 | - 172.17.1.0/24 20 | - namespaceSelector: 21 | matchLabels: 22 | project: myproject 23 | - podSelector: 24 | matchLabels: 25 | role: frontend 26 | ports: 27 | - protocol: TCP 28 | port: 6379 29 | egress: 30 | - to: 31 | - ipBlock: 32 | cidr: 10.0.0.0/24 33 | ports: 34 | - protocol: TCP 35 | port: 5978 36 | -------------------------------------------------------------------------------- /Chapter7/7.7.2 default-networkpolicy-in-namespace.yaml: -------------------------------------------------------------------------------- 1 | # default deny ingress 2 | --- 3 | apiVersion: networking.k8s.io/v1 4 | kind: NetworkPolicy 5 | metadata: 6 | name: default-deny 7 | spec: 8 | podSelector: {} 9 | policyTypes: 10 | - Ingress 11 | 12 | 13 | # default allow ingress 14 | --- 15 | apiVersion: networking.k8s.io/v1 16 | kind: NetworkPolicy 17 | metadata: 18 | name: allow-all 19 | spec: 20 | podSelector: {} 21 | ingress: 22 | - {} 23 | policyTypes: 24 | - Ingress 25 | 26 | 27 | # default deny egress 28 | --- 29 | apiVersion: networking.k8s.io/v1 30 | kind: NetworkPolicy 31 | metadata: 32 | name: default-deny 33 | spec: 34 | podSelector: {} 35 | policyTypes: 36 | - Egress 37 | 38 | 39 | # default allow egress 40 | --- 41 | apiVersion: networking.k8s.io/v1 42 | kind: NetworkPolicy 43 | metadata: 44 | name: allow-all 45 | spec: 46 | podSelector: {} 47 | egress: 48 | - {} 49 | policyTypes: 50 | - Egress 51 | 52 | 53 | # default deny ingress and egress 54 | --- 55 | apiVersion: networking.k8s.io/v1 56 | kind: NetworkPolicy 57 | metadata: 58 | name: default-deny 59 | spec: 60 | podSelector: {} 61 | policyTypes: 62 | - Ingress 63 | - Egress 64 | -------------------------------------------------------------------------------- /Chapter7/7.8.4 cni-calico.yaml: -------------------------------------------------------------------------------- 1 | # calico 2 | --- 3 | kind: ConfigMap 4 | apiVersion: v1 5 | metadata: 6 | name: calico-config 7 | namespace: kube-system 8 | data: 9 | etcd_endpoints: "http://192.168.18.3:2379" 10 | 11 | etcd_ca: "" # "/calico-secrets/etcd-ca" 12 | etcd_cert: "" # "/calico-secrets/etcd-cert" 13 | etcd_key: "" # "/calico-secrets/etcd-key" 14 | 15 | typha_service_name: "none" 16 | 17 | calico_backend: "bird" 18 | 19 | veth_mtu: "1440" 20 | 21 | cni_network_config: |- 22 | { 23 | "name": "k8s-pod-network", 24 | "cniVersion": "0.3.0", 25 | "plugins": [ 26 | { 27 | "type": "calico", 28 | "log_level": "info", 29 | "etcd_endpoints": "__ETCD_ENDPOINTS__", 30 | "etcd_key_file": "__ETCD_KEY_FILE__", 31 | "etcd_cert_file": "__ETCD_CERT_FILE__", 32 | "etcd_ca_cert_file": "__ETCD_CA_CERT_FILE__", 33 | "mtu": __CNI_MTU__, 34 | "ipam": { 35 | "type": "calico-ipam" 36 | }, 37 | "policy": { 38 | "type": "k8s" 39 | }, 40 | "kubernetes": { 41 | "kubeconfig": "__KUBECONFIG_FILEPATH__" 42 | } 43 | }, 44 | { 45 | "type": "portmap", 46 | "snat": true, 47 | "capabilities": {"portMappings": true} 48 | } 49 | ] 50 | } 51 | 52 | 53 | --- 54 | apiVersion: v1 55 | kind: Secret 56 | type: Opaque 57 | metadata: 58 | name: calico-etcd-secrets 59 | namespace: kube-system 60 | data: 61 | # etcd-key: null 62 | # etcd-cert: null 63 | # etcd-ca: null 64 | 65 | --- 66 | kind: DaemonSet 67 | apiVersion: extensions/v1beta1 68 | metadata: 69 | name: calico-node 70 | namespace: kube-system 71 | labels: 72 | k8s-app: calico-node 73 | spec: 74 | selector: 75 | matchLabels: 76 | k8s-app: calico-node 77 | updateStrategy: 78 | type: RollingUpdate 79 | rollingUpdate: 80 | maxUnavailable: 1 81 | template: 82 | metadata: 83 | labels: 84 | k8s-app: calico-node 85 | annotations: 86 | scheduler.alpha.kubernetes.io/critical-pod: '' 87 | spec: 88 | nodeSelector: 89 | beta.kubernetes.io/os: linux 90 | hostNetwork: true 91 | tolerations: 92 | - effect: NoSchedule 93 | operator: Exists 94 | - key: CriticalAddonsOnly 95 | operator: Exists 96 | - effect: NoExecute 97 | operator: Exists 98 | serviceAccountName: calico-node 99 | terminationGracePeriodSeconds: 0 100 | initContainers: 101 | # This container installs the Calico CNI binaries 102 | # and CNI network config file on each node. 103 | - name: install-cni 104 | image: calico/cni:v3.5.2 105 | command: ["/install-cni.sh"] 106 | env: 107 | - name: CNI_CONF_NAME 108 | value: "10-calico.conflist" 109 | - name: CNI_NETWORK_CONFIG 110 | valueFrom: 111 | configMapKeyRef: 112 | name: calico-config 113 | key: cni_network_config 114 | - name: ETCD_ENDPOINTS 115 | valueFrom: 116 | configMapKeyRef: 117 | name: calico-config 118 | key: etcd_endpoints 119 | - name: CNI_MTU 120 | valueFrom: 121 | configMapKeyRef: 122 | name: calico-config 123 | key: veth_mtu 124 | # Prevents the container from sleeping forever. 125 | - name: SLEEP 126 | value: "false" 127 | volumeMounts: 128 | - mountPath: /host/opt/cni/bin 129 | name: cni-bin-dir 130 | - mountPath: /host/etc/cni/net.d 131 | name: cni-net-dir 132 | - mountPath: /calico-secrets 133 | name: etcd-certs 134 | containers: 135 | - name: calico-node 136 | image: calico/node:v3.5.2 137 | env: 138 | - name: ETCD_ENDPOINTS 139 | valueFrom: 140 | configMapKeyRef: 141 | name: calico-config 142 | key: etcd_endpoints 143 | - name: ETCD_CA_CERT_FILE 144 | valueFrom: 145 | configMapKeyRef: 146 | name: calico-config 147 | key: etcd_ca 148 | # Location of the client key for etcd. 149 | - name: ETCD_KEY_FILE 150 | valueFrom: 151 | configMapKeyRef: 152 | name: calico-config 153 | key: etcd_key 154 | - name: ETCD_CERT_FILE 155 | valueFrom: 156 | configMapKeyRef: 157 | name: calico-config 158 | key: etcd_cert 159 | - name: CALICO_K8S_NODE_REF 160 | valueFrom: 161 | fieldRef: 162 | fieldPath: spec.nodeName 163 | # Choose the backend to use. 164 | - name: CALICO_NETWORKING_BACKEND 165 | valueFrom: 166 | configMapKeyRef: 167 | name: calico-config 168 | key: calico_backend 169 | - name: CLUSTER_TYPE 170 | value: "k8s,bgp" 171 | - name: IP 172 | value: "autodetect" 173 | - name: CALICO_IPV4POOL_IPIP 174 | value: "Always" 175 | - name: FELIX_IPINIPMTU 176 | valueFrom: 177 | configMapKeyRef: 178 | name: calico-config 179 | key: veth_mtu 180 | - name: CALICO_IPV4POOL_CIDR 181 | value: "10.1.0.0/16" 182 | - name: CALICO_IPV4POOL_IPIP 183 | value: "always" 184 | - name: IP_AUTODETECTION_METHOD 185 | value: "interface=ens.*" 186 | - name: IP6_AUTODETECTION_METHOD 187 | value: "interface=ens.*" 188 | - name: CALICO_DISABLE_FILE_LOGGING 189 | value: "true" 190 | - name: FELIX_DEFAULTENDPOINTTOHOSTACTION 191 | value: "ACCEPT" 192 | - name: FELIX_IPV6SUPPORT 193 | value: "false" 194 | - name: FELIX_LOGSEVERITYSCREEN 195 | value: "info" 196 | - name: FELIX_HEALTHENABLED 197 | value: "true" 198 | securityContext: 199 | privileged: true 200 | resources: 201 | requests: 202 | cpu: 250m 203 | livenessProbe: 204 | httpGet: 205 | path: /liveness 206 | port: 9099 207 | host: localhost 208 | periodSeconds: 10 209 | initialDelaySeconds: 10 210 | failureThreshold: 6 211 | readinessProbe: 212 | exec: 213 | command: 214 | - /bin/calico-node 215 | - -bird-ready 216 | - -felix-ready 217 | periodSeconds: 10 218 | volumeMounts: 219 | - mountPath: /lib/modules 220 | name: lib-modules 221 | readOnly: true 222 | - mountPath: /run/xtables.lock 223 | name: xtables-lock 224 | readOnly: false 225 | - mountPath: /var/run/calico 226 | name: var-run-calico 227 | readOnly: false 228 | - mountPath: /var/lib/calico 229 | name: var-lib-calico 230 | readOnly: false 231 | - mountPath: /calico-secrets 232 | name: etcd-certs 233 | volumes: 234 | # Used by calico/node. 235 | - name: lib-modules 236 | hostPath: 237 | path: /lib/modules 238 | - name: var-run-calico 239 | hostPath: 240 | path: /var/run/calico 241 | - name: var-lib-calico 242 | hostPath: 243 | path: /var/lib/calico 244 | - name: xtables-lock 245 | hostPath: 246 | path: /run/xtables.lock 247 | type: FileOrCreate 248 | - name: cni-bin-dir 249 | hostPath: 250 | path: /opt/cni/bin 251 | - name: cni-net-dir 252 | hostPath: 253 | path: /etc/cni/net.d 254 | - name: etcd-certs 255 | secret: 256 | secretName: calico-etcd-secrets 257 | defaultMode: 0400 258 | 259 | 260 | --- 261 | apiVersion: extensions/v1beta1 262 | kind: Deployment 263 | metadata: 264 | name: calico-kube-controllers 265 | namespace: kube-system 266 | labels: 267 | k8s-app: calico-kube-controllers 268 | annotations: 269 | scheduler.alpha.kubernetes.io/critical-pod: '' 270 | spec: 271 | replicas: 1 272 | strategy: 273 | type: Recreate 274 | template: 275 | metadata: 276 | name: calico-kube-controllers 277 | namespace: kube-system 278 | labels: 279 | k8s-app: calico-kube-controllers 280 | spec: 281 | nodeSelector: 282 | beta.kubernetes.io/os: linux 283 | hostNetwork: true 284 | tolerations: 285 | - key: CriticalAddonsOnly 286 | operator: Exists 287 | - key: node-role.kubernetes.io/master 288 | effect: NoSchedule 289 | serviceAccountName: calico-kube-controllers 290 | containers: 291 | - name: calico-kube-controllers 292 | image: calico/kube-controllers:v3.5.2 293 | env: 294 | - name: ETCD_ENDPOINTS 295 | valueFrom: 296 | configMapKeyRef: 297 | name: calico-config 298 | key: etcd_endpoints 299 | - name: ETCD_CA_CERT_FILE 300 | valueFrom: 301 | configMapKeyRef: 302 | name: calico-config 303 | key: etcd_ca 304 | - name: ETCD_KEY_FILE 305 | valueFrom: 306 | configMapKeyRef: 307 | name: calico-config 308 | key: etcd_key 309 | - name: ETCD_CERT_FILE 310 | valueFrom: 311 | configMapKeyRef: 312 | name: calico-config 313 | key: etcd_cert 314 | - name: ENABLED_CONTROLLERS 315 | value: policy,namespace,serviceaccount,workloadendpoint,node 316 | volumeMounts: 317 | - mountPath: /calico-secrets 318 | name: etcd-certs 319 | readinessProbe: 320 | exec: 321 | command: 322 | - /usr/bin/check-status 323 | - -r 324 | volumes: 325 | - name: etcd-certs 326 | secret: 327 | secretName: calico-etcd-secrets 328 | defaultMode: 0400 329 | 330 | 331 | # sample app 332 | --- 333 | apiVersion: v1 334 | kind: ReplicationController 335 | metadata: 336 | name: mysql 337 | spec: 338 | replicas: 1 339 | selector: 340 | app: mysql 341 | template: 342 | metadata: 343 | labels: 344 | app: mysql 345 | spec: 346 | containers: 347 | - name: mysql 348 | image: mysql 349 | ports: 350 | - containerPort: 3306 351 | env: 352 | - name: MYSQL_ROOT_PASSWORD 353 | value: "123456" 354 | 355 | --- 356 | apiVersion: v1 357 | kind: ReplicationController 358 | metadata: 359 | name: myweb 360 | spec: 361 | replicas: 2 362 | selector: 363 | app: myweb 364 | template: 365 | metadata: 366 | labels: 367 | app: myweb 368 | spec: 369 | containers: 370 | - name: myweb 371 | image: kubeguide/tomcat-app:v1 372 | ports: 373 | - containerPort: 8080 374 | env: 375 | - name: MYSQL_SERVICE_HOST 376 | value: 'mysql' 377 | - name: MYSQL_SERVICE_PORT 378 | value: '3306' 379 | 380 | 381 | 382 | # networkpolicy example 383 | --- 384 | apiVersion: v1 385 | kind: Pod 386 | metadata: 387 | name: nginx 388 | labels: 389 | app: nginx 390 | spec: 391 | containers: 392 | - name: nginx 393 | image: nginx 394 | 395 | --- 396 | kind: NetworkPolicy 397 | apiVersion: networking.k8s.io/v1 398 | metadata: 399 | name: allow-nginxclient 400 | spec: 401 | podSelector: 402 | matchLabels: 403 | app: nginx 404 | ingress: 405 | - from: 406 | - podSelector: 407 | matchLabels: 408 | role: nginxclient 409 | ports: 410 | - protocol: TCP 411 | port: 80 412 | 413 | # allow 414 | --- 415 | apiVersion: v1 416 | kind: Pod 417 | metadata: 418 | name: client1 419 | labels: 420 | role: nginxclient 421 | spec: 422 | containers: 423 | - name: client1 424 | image: busybox 425 | command: [ "sleep", "3600" ] 426 | 427 | # deny 428 | --- 429 | apiVersion: v1 430 | kind: Pod 431 | metadata: 432 | name: client2 433 | spec: 434 | containers: 435 | - name: client2 436 | image: busybox 437 | command: [ "sleep", "3600" ] 438 | -------------------------------------------------------------------------------- /Chapter8/8.2 pv-nfs.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: PersistentVolume 4 | metadata: 5 | name: pv1 6 | spec: 7 | capacity: 8 | storage: 5Gi 9 | accessModes: 10 | - ReadWriteOnce 11 | persistentVolumeReclaimPolicy: Recycle 12 | storageClassName: slow 13 | nfs: 14 | path: /tmp 15 | server: 172.17.0.2 16 | -------------------------------------------------------------------------------- /Chapter8/8.2.1 pv-block-volume.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: PersistentVolume 4 | metadata: 5 | name: block-pv 6 | spec: 7 | capacity: 8 | storage: 10Gi 9 | accessModes: 10 | - ReadWriteOnce 11 | persistentVolumeReclaimPolicy: Retain 12 | volumeMode: Block 13 | fc: 14 | targetWWNs: ["50060e801049cfd1"] 15 | lun: 0 16 | readOnly: false 17 | -------------------------------------------------------------------------------- /Chapter8/8.2.1 pv-mountoptions.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: "v1" 3 | kind: "PersistentVolume" 4 | metadata: 5 | name: gce-disk-1 6 | spec: 7 | capacity: 8 | storage: "10Gi" 9 | accessModes: 10 | - "ReadWriteOnce" 11 | mountOptions: 12 | - hard 13 | - nolock 14 | - nfsvers=3 15 | gcePersistentDisk: 16 | fsType: "ext4" 17 | pdName: "gce-disk-1 18 | -------------------------------------------------------------------------------- /Chapter8/8.2.1 pv-nodeaffinity.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: PersistentVolume 4 | metadata: 5 | name: example-local-pv 6 | spec: 7 | capacity: 8 | storage: 5Gi 9 | accessModes: 10 | - ReadWriteOnce 11 | persistentVolumeReclaimPolicy: Delete 12 | storageClassName: local-storage 13 | local: 14 | path: /mnt/disks/ssd1 15 | nodeAffinity: 16 | required: 17 | nodeSelectorTerms: 18 | - matchExpressions: 19 | - key: kubernetes.io/hostname 20 | operator: In 21 | values: 22 | - my-node 23 | -------------------------------------------------------------------------------- /Chapter8/8.3 pvc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: PersistentVolumeClaim 3 | apiVersion: v1 4 | metadata: 5 | name: myclaim 6 | spec: 7 | accessModes: 8 | - ReadWriteOnce 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]} 18 | -------------------------------------------------------------------------------- /Chapter8/8.5 storage-class.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: StorageClass 3 | apiVersion: storage.k8s.io/v1 4 | metadata: 5 | name: standard 6 | provisioner: kubernetes.io/aws-ebs 7 | parameters: 8 | type: gp2 9 | -------------------------------------------------------------------------------- /Chapter8/8.5.1 storage-class-examples.yaml: -------------------------------------------------------------------------------- 1 | # AWS EBS 2 | --- 3 | kind: StorageClass 4 | apiVersion: storage.k8s.io/v1 5 | metadata: 6 | name: slow 7 | provisioner: kubernetes.io/aws-ebs 8 | parameters: 9 | type: io1 10 | zone: us-east-1d 11 | iopsPerGB: "10" 12 | 13 | 14 | # GCE PD 15 | --- 16 | kind: StorageClass 17 | apiVersion: storage.k8s.io/v1 18 | metadata: 19 | name: slow 20 | provisioner: kubernetes.io/gce-pd 21 | parameters: 22 | type: pd-standard 23 | zone: us-central1-a 24 | 25 | 26 | # glusterfs 27 | --- 28 | apiVersion: storage.k8s.io/v1 29 | kind: StorageClass 30 | metadata: 31 | name: slow 32 | provisioner: kubernetes.io/glusterfs 33 | parameters: 34 | resturl: "http://127.0.0.1:8081" 35 | clusterid: "630372ccdc720a92c681fb928f27b53f" 36 | restauthenabled: "true" 37 | restuser: "admin" 38 | secretNamespace: "default" 39 | secretName: "heketi-secret" 40 | gidMin: "40000" 41 | gidMax: "50000" 42 | volumetype: "replicate:3" 43 | 44 | 45 | # openstack cinder 46 | --- 47 | kind: StorageClass 48 | apiVersion: storage.k8s.io/v1 49 | metadata: 50 | name: gold 51 | provisioner: kubernetes.io/cinder 52 | parameters: 53 | type: fast 54 | availability: nova 55 | -------------------------------------------------------------------------------- /Chapter8/8.5.2 default-storageclass.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: StorageClass 3 | apiVersion: storage.k8s.io/v1 4 | metadata: 5 | name: gold 6 | annotations: 7 | storageclass.beta.kubernetes.io/is-default-class="true" 8 | provisioner: kubernetes.io/gce-pd 9 | parameters: 10 | type: pd-ssd 11 | -------------------------------------------------------------------------------- /Chapter8/8.6 glusterfs-heketi.yaml: -------------------------------------------------------------------------------- 1 | # glusterfs 2 | --- 3 | kind: DaemonSet 4 | apiVersion: extensions/v1beta1 5 | metadata: 6 | name: glusterfs 7 | labels: 8 | glusterfs: daemonset 9 | annotations: 10 | description: GlusterFS DaemonSet 11 | tags: glusterfs 12 | spec: 13 | template: 14 | metadata: 15 | name: glusterfs 16 | labels: 17 | glusterfs-node: pod 18 | spec: 19 | nodeSelector: 20 | storagenode: glusterfs 21 | hostNetwork: true 22 | containers: 23 | - image: gluster/gluster-centos:latest 24 | name: glusterfs 25 | volumeMounts: 26 | - name: glusterfs-heketi 27 | mountPath: "/var/lib/heketi" 28 | - name: glusterfs-run 29 | mountPath: "/run" 30 | - name: glusterfs-lvm 31 | mountPath: "/run/lvm" 32 | - name: glusterfs-etc 33 | mountPath: "/etc/glusterfs" 34 | - name: glusterfs-logs 35 | mountPath: "/var/log/glusterfs" 36 | - name: glusterfs-config 37 | mountPath: "/var/lib/glusterd" 38 | - name: glusterfs-dev 39 | mountPath: "/dev" 40 | - name: glusterfs-misc 41 | mountPath: "/var/lib/misc/glusterfsd" 42 | - name: glusterfs-cgroup 43 | mountPath: "/sys/fs/cgroup" 44 | readOnly: true 45 | - name: glusterfs-ssl 46 | mountPath: "/etc/ssl" 47 | readOnly: true 48 | securityContext: 49 | capabilities: {} 50 | privileged: true 51 | readinessProbe: 52 | timeoutSeconds: 3 53 | initialDelaySeconds: 60 54 | exec: 55 | command: 56 | - "/bin/bash" 57 | - "-c" 58 | - systemctl status glusterd.service 59 | livenessProbe: 60 | timeoutSeconds: 3 61 | initialDelaySeconds: 60 62 | exec: 63 | command: 64 | - "/bin/bash" 65 | - "-c" 66 | - systemctl status glusterd.service 67 | volumes: 68 | - name: glusterfs-heketi 69 | hostPath: 70 | path: "/var/lib/heketi" 71 | - name: glusterfs-run 72 | - name: glusterfs-lvm 73 | hostPath: 74 | path: "/run/lvm" 75 | - name: glusterfs-etc 76 | hostPath: 77 | path: "/etc/glusterfs" 78 | - name: glusterfs-logs 79 | hostPath: 80 | path: "/var/log/glusterfs" 81 | - name: glusterfs-config 82 | hostPath: 83 | path: "/var/lib/glusterd" 84 | - name: glusterfs-dev 85 | hostPath: 86 | path: "/dev" 87 | - name: glusterfs-misc 88 | hostPath: 89 | path: "/var/lib/misc/glusterfsd" 90 | - name: glusterfs-cgroup 91 | hostPath: 92 | path: "/sys/fs/cgroup" 93 | - name: glusterfs-ssl 94 | hostPath: 95 | path: "/etc/ssl" 96 | 97 | 98 | # heketi 99 | --- 100 | apiVersion: v1 101 | kind: ServiceAccount 102 | metadata: 103 | name: heketi-service-account 104 | 105 | --- 106 | kind: Deployment 107 | apiVersion: extensions/v1beta1 108 | metadata: 109 | name: deploy-heketi 110 | labels: 111 | glusterfs: heketi-deployment 112 | deploy-heketi: heketi-deployment 113 | annotations: 114 | description: Defines how to deploy Heketi 115 | spec: 116 | replicas: 1 117 | template: 118 | metadata: 119 | name: deploy-heketi 120 | labels: 121 | name: deploy-heketi 122 | glusterfs: heketi-pod 123 | spec: 124 | serviceAccountName: heketi-service-account 125 | containers: 126 | - image: heketi/heketi 127 | name: deploy-heketi 128 | env: 129 | - name: HEKETI_EXECUTOR 130 | value: kubernetes 131 | - name: HEKETI_FSTAB 132 | value: "/var/lib/heketi/fstab" 133 | - name: HEKETI_SNAPSHOT_LIMIT 134 | value: '14' 135 | - name: HEKETI_KUBE_GLUSTER_DAEMONSET 136 | value: "y" 137 | ports: 138 | - containerPort: 8080 139 | volumeMounts: 140 | - name: db 141 | mountPath: "/var/lib/heketi" 142 | readinessProbe: 143 | timeoutSeconds: 3 144 | initialDelaySeconds: 3 145 | httpGet: 146 | path: "/hello" 147 | port: 8080 148 | livenessProbe: 149 | timeoutSeconds: 3 150 | initialDelaySeconds: 30 151 | httpGet: 152 | path: "/hello" 153 | port: 8080 154 | volumes: 155 | - name: db 156 | hostPath: 157 | path: "/heketi-data" 158 | 159 | --- 160 | kind: Service 161 | apiVersion: v1 162 | metadata: 163 | name: deploy-heketi 164 | labels: 165 | glusterfs: heketi-service 166 | deploy-heketi: support 167 | annotations: 168 | description: Exposes Heketi Service 169 | spec: 170 | selector: 171 | name: deploy-heketi 172 | ports: 173 | - name: deploy-heketi 174 | port: 8080 175 | targetPort: 8080 176 | 177 | 178 | 179 | 180 | # topology.json 181 | { 182 | "clusters": [ 183 | { 184 | "nodes": [ 185 | { 186 | "node": { 187 | "hostnames": { 188 | "manage": [ 189 | "k8s-node-1" 190 | ], 191 | "storage": [ 192 | "192.168.18.3" 193 | ] 194 | }, 195 | "zone": 1 196 | }, 197 | "devices": [ 198 | "/dev/sdb" 199 | ] 200 | }, 201 | { 202 | "node": { 203 | "hostnames": { 204 | "manage": [ 205 | "k8s-node-2" 206 | ], 207 | "storage": [ 208 | "192.168.18.4" 209 | ] 210 | }, 211 | "zone": 1 212 | }, 213 | "devices": [ 214 | "/dev/sdb" 215 | ] 216 | }, 217 | { 218 | "node": { 219 | "hostnames": { 220 | "manage": [ 221 | "k8s-node-3" 222 | ], 223 | "storage": [ 224 | "192.168.18.5" 225 | ] 226 | }, 227 | "zone": 1 228 | }, 229 | "devices": [ 230 | "/dev/sdb" 231 | ] 232 | } 233 | ] 234 | } 235 | ] 236 | } 237 | 238 | 239 | # in heketi container 240 | # heketi-cli topology load --json=topology.json 241 | 242 | 243 | 244 | 245 | # storageclass 246 | --- 247 | apiVersion: storage.k8s.io/v1 248 | kind: StorageClass 249 | metadata: 250 | name: gluster-heketi 251 | provisioner: kubernetes.io/glusterfs 252 | parameters: 253 | resturl: "http://172.17.2.2:8080" 254 | restauthenabled: "false" 255 | 256 | 257 | 258 | # pvc 259 | --- 260 | kind: PersistentVolumeClaim 261 | apiVersion: v1 262 | metadata: 263 | name: pvc-gluster-heketi 264 | spec: 265 | storageClassName: gluster-heketi 266 | accessModes: 267 | - ReadWriteOnce 268 | resources: 269 | requests: 270 | storage: 1Gi 271 | 272 | 273 | # pod use pvc 274 | --- 275 | apiVersion: v1 276 | kind: Pod 277 | metadata: 278 | name: pod-use-pvc 279 | spec: 280 | containers: 281 | - name: pod-use-pvc 282 | image: busybox 283 | command: 284 | - sleep 285 | - "3600" 286 | volumeMounts: 287 | - name: gluster-volume 288 | mountPath: "/pv-data" 289 | readOnly: false 290 | volumes: 291 | - name: gluster-volume 292 | persistentVolumeClaim: 293 | claimName: pvc-gluster-heketi 294 | -------------------------------------------------------------------------------- /Chapter8/8.7.3 csi-hostpath.yaml: -------------------------------------------------------------------------------- 1 | # csidrivers 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | name: csidrivers.csi.storage.k8s.io 7 | labels: 8 | addonmanager.kubernetes.io/mode: Reconcile 9 | spec: 10 | group: csi.storage.k8s.io 11 | names: 12 | kind: CSIDriver 13 | plural: csidrivers 14 | scope: Cluster 15 | validation: 16 | openAPIV3Schema: 17 | properties: 18 | spec: 19 | description: Specification of the CSI Driver. 20 | properties: 21 | attachRequired: 22 | description: Indicates this CSI volume driver requires an attach operation,and that Kubernetes should call attach and wait for any attach operationto complete before proceeding to mount. 23 | type: boolean 24 | podInfoOnMountVersion: 25 | description: Indicates this CSI volume driver requires additional pod 26 | information (like podName, podUID, etc.) during mount operations. 27 | type: string 28 | version: v1alpha1 29 | 30 | 31 | # csinodeinfo 32 | --- 33 | apiVersion: apiextensions.k8s.io/v1beta1 34 | kind: CustomResourceDefinition 35 | metadata: 36 | name: csinodeinfos.csi.storage.k8s.io 37 | labels: 38 | addonmanager.kubernetes.io/mode: Reconcile 39 | spec: 40 | group: csi.storage.k8s.io 41 | names: 42 | kind: CSINodeInfo 43 | plural: csinodeinfos 44 | scope: Cluster 45 | validation: 46 | openAPIV3Schema: 47 | properties: 48 | spec: 49 | description: Specification of CSINodeInfo 50 | properties: 51 | drivers: 52 | description: List of CSI drivers running on the node and their specs. 53 | type: array 54 | items: 55 | properties: 56 | name: 57 | description: The CSI driver that this object refers to. 58 | type: string 59 | nodeID: 60 | description: The node from the driver point of view. 61 | type: string 62 | topologyKeys: 63 | description: List of keys supported by the driver. 64 | items: 65 | type: string 66 | type: array 67 | status: 68 | description: Status of CSINodeInfo 69 | properties: 70 | drivers: 71 | description: List of CSI drivers running on the node and their statuses. 72 | type: array 73 | items: 74 | properties: 75 | name: 76 | description: The CSI driver that this object refers to. 77 | type: string 78 | available: 79 | description: Whether the CSI driver is installed. 80 | type: boolean 81 | volumePluginMechanism: 82 | description: Indicates to external components the required mechanism 83 | to use for any in-tree plugins replaced by this driver. 84 | pattern: in-tree|csi 85 | type: string 86 | version: v1alpha1 87 | 88 | 89 | # csi-hostpath-attacher 90 | --- 91 | apiVersion: v1 92 | kind: ServiceAccount 93 | metadata: 94 | name: csi-attacher 95 | # replace with non-default namespace name 96 | namespace: default 97 | --- 98 | kind: ClusterRole 99 | apiVersion: rbac.authorization.k8s.io/v1 100 | metadata: 101 | name: external-attacher-runner 102 | rules: 103 | - apiGroups: [""] 104 | resources: ["persistentvolumes"] 105 | verbs: ["get", "list", "watch", "update"] 106 | - apiGroups: [""] 107 | resources: ["nodes"] 108 | verbs: ["get", "list", "watch"] 109 | - apiGroups: ["csi.storage.k8s.io"] 110 | resources: ["csinodeinfos"] 111 | verbs: ["get", "list", "watch"] 112 | - apiGroups: ["storage.k8s.io"] 113 | resources: ["volumeattachments"] 114 | verbs: ["get", "list", "watch", "update"] 115 | --- 116 | kind: ClusterRoleBinding 117 | apiVersion: rbac.authorization.k8s.io/v1 118 | metadata: 119 | name: csi-attacher-role 120 | subjects: 121 | - kind: ServiceAccount 122 | name: csi-attacher 123 | # replace with non-default namespace name 124 | namespace: default 125 | roleRef: 126 | kind: ClusterRole 127 | name: external-attacher-runner 128 | apiGroup: rbac.authorization.k8s.io 129 | --- 130 | kind: Role 131 | apiVersion: rbac.authorization.k8s.io/v1 132 | metadata: 133 | # replace with non-default namespace name 134 | namespace: default 135 | name: external-attacher-cfg 136 | rules: 137 | - apiGroups: [""] 138 | resources: ["configmaps"] 139 | verbs: ["get", "watch", "list", "delete", "update", "create"] 140 | --- 141 | kind: RoleBinding 142 | apiVersion: rbac.authorization.k8s.io/v1 143 | metadata: 144 | name: csi-attacher-role-cfg 145 | # replace with non-default namespace name 146 | namespace: default 147 | subjects: 148 | - kind: ServiceAccount 149 | name: csi-attacher 150 | # replace with non-default namespace name 151 | namespace: default 152 | roleRef: 153 | kind: Role 154 | name: external-attacher-cfg 155 | apiGroup: rbac.authorization.k8s.io 156 | 157 | --- 158 | kind: Service 159 | apiVersion: v1 160 | metadata: 161 | name: csi-hostpath-attacher 162 | labels: 163 | app: csi-hostpath-attacher 164 | spec: 165 | selector: 166 | app: csi-hostpath-attacher 167 | ports: 168 | - name: dummy 169 | port: 12345 170 | --- 171 | kind: StatefulSet 172 | apiVersion: apps/v1 173 | metadata: 174 | name: csi-hostpath-attacher 175 | spec: 176 | serviceName: "csi-hostpath-attacher" 177 | replicas: 1 178 | selector: 179 | matchLabels: 180 | app: csi-hostpath-attacher 181 | template: 182 | metadata: 183 | labels: 184 | app: csi-hostpath-attacher 185 | spec: 186 | serviceAccountName: csi-attacher 187 | containers: 188 | - name: csi-attacher 189 | image: quay.io/k8scsi/csi-attacher:v1.0.1 190 | imagePullPolicy: IfNotPresent 191 | args: 192 | - --v=5 193 | - --csi-address=$(ADDRESS) 194 | env: 195 | - name: ADDRESS 196 | value: /csi/csi.sock 197 | volumeMounts: 198 | - mountPath: /csi 199 | name: socket-dir 200 | volumes: 201 | - hostPath: 202 | path: /var/lib/kubelet/plugins/csi-hostpath 203 | type: DirectoryOrCreate 204 | name: socket-dir 205 | 206 | 207 | # csi-hostpath-provisioner 208 | --- 209 | apiVersion: v1 210 | kind: ServiceAccount 211 | metadata: 212 | name: csi-provisioner 213 | # replace with non-default namespace name 214 | namespace: default 215 | --- 216 | kind: ClusterRole 217 | apiVersion: rbac.authorization.k8s.io/v1 218 | metadata: 219 | name: external-provisioner-runner 220 | rules: 221 | - apiGroups: [""] 222 | resources: ["secrets"] 223 | verbs: ["get", "list"] 224 | - apiGroups: [""] 225 | resources: ["persistentvolumes"] 226 | verbs: ["get", "list", "watch", "create", "delete"] 227 | - apiGroups: [""] 228 | resources: ["persistentvolumeclaims"] 229 | verbs: ["get", "list", "watch", "update"] 230 | - apiGroups: ["storage.k8s.io"] 231 | resources: ["storageclasses"] 232 | verbs: ["get", "list", "watch"] 233 | - apiGroups: [""] 234 | resources: ["events"] 235 | verbs: ["list", "watch", "create", "update", "patch"] 236 | - apiGroups: ["snapshot.storage.k8s.io"] 237 | resources: ["volumesnapshots"] 238 | verbs: ["get", "list"] 239 | - apiGroups: ["snapshot.storage.k8s.io"] 240 | resources: ["volumesnapshotcontents"] 241 | verbs: ["get", "list"] 242 | - apiGroups: ["csi.storage.k8s.io"] 243 | resources: ["csinodeinfos"] 244 | verbs: ["get", "list", "watch"] 245 | - apiGroups: [""] 246 | resources: ["nodes"] 247 | verbs: ["get", "list", "watch"] 248 | --- 249 | kind: ClusterRoleBinding 250 | apiVersion: rbac.authorization.k8s.io/v1 251 | metadata: 252 | name: csi-provisioner-role 253 | subjects: 254 | - kind: ServiceAccount 255 | name: csi-provisioner 256 | # replace with non-default namespace name 257 | namespace: default 258 | roleRef: 259 | kind: ClusterRole 260 | name: external-provisioner-runner 261 | apiGroup: rbac.authorization.k8s.io 262 | --- 263 | kind: Role 264 | apiVersion: rbac.authorization.k8s.io/v1 265 | metadata: 266 | # replace with non-default namespace name 267 | namespace: default 268 | name: external-provisioner-cfg 269 | rules: 270 | - apiGroups: [""] 271 | resources: ["endpoints"] 272 | verbs: ["get", "watch", "list", "delete", "update", "create"] 273 | --- 274 | kind: RoleBinding 275 | apiVersion: rbac.authorization.k8s.io/v1 276 | metadata: 277 | name: csi-provisioner-role-cfg 278 | # replace with non-default namespace name 279 | namespace: default 280 | subjects: 281 | - kind: ServiceAccount 282 | name: csi-provisioner 283 | # replace with non-default namespace name 284 | namespace: default 285 | roleRef: 286 | kind: Role 287 | name: external-provisioner-cfg 288 | apiGroup: rbac.authorization.k8s.io 289 | 290 | --- 291 | kind: Service 292 | apiVersion: v1 293 | metadata: 294 | name: csi-hostpath-provisioner 295 | labels: 296 | app: csi-hostpath-provisioner 297 | spec: 298 | selector: 299 | app: csi-hostpath-provisioner 300 | ports: 301 | - name: dummy 302 | port: 12345 303 | --- 304 | kind: StatefulSet 305 | apiVersion: apps/v1 306 | metadata: 307 | name: csi-hostpath-provisioner 308 | spec: 309 | serviceName: "csi-hostpath-provisioner" 310 | replicas: 1 311 | selector: 312 | matchLabels: 313 | app: csi-hostpath-provisioner 314 | template: 315 | metadata: 316 | labels: 317 | app: csi-hostpath-provisioner 318 | spec: 319 | serviceAccountName: csi-provisioner 320 | containers: 321 | - name: csi-provisioner 322 | image: quay.io/k8scsi/csi-provisioner:v1.0.1 323 | imagePullPolicy: IfNotPresent 324 | args: 325 | - "--provisioner=csi-hostpath" 326 | - "--csi-address=$(ADDRESS)" 327 | - "--connection-timeout=15s" 328 | env: 329 | - name: ADDRESS 330 | value: /csi/csi.sock 331 | volumeMounts: 332 | - mountPath: /csi 333 | name: socket-dir 334 | volumes: 335 | - hostPath: 336 | path: /var/lib/kubelet/plugins/csi-hostpath 337 | type: DirectoryOrCreate 338 | name: socket-dir 339 | 340 | 341 | # csi-hostpathplugin 342 | --- 343 | apiVersion: v1 344 | kind: ServiceAccount 345 | metadata: 346 | name: csi-node-sa 347 | # replace with non-default namespace name 348 | namespace: default 349 | --- 350 | kind: ClusterRole 351 | apiVersion: rbac.authorization.k8s.io/v1 352 | metadata: 353 | name: driver-registrar-runner 354 | rules: 355 | - apiGroups: [""] 356 | resources: ["events"] 357 | verbs: ["get", "list", "watch", "create", "update", "patch"] 358 | # The following permissions are only needed when running 359 | # driver-registrar without the --kubelet-registration-path 360 | # parameter, i.e. when using driver-registrar instead of 361 | # kubelet to update the csi.volume.kubernetes.io/nodeid 362 | # annotation. That mode of operation is going to be deprecated 363 | # and should not be used anymore, but is needed on older 364 | # Kubernetes versions. 365 | # - apiGroups: [""] 366 | # resources: ["nodes"] 367 | # verbs: ["get", "update", "patch"] 368 | --- 369 | kind: ClusterRoleBinding 370 | apiVersion: rbac.authorization.k8s.io/v1 371 | metadata: 372 | name: csi-driver-registrar-role 373 | subjects: 374 | - kind: ServiceAccount 375 | name: csi-node-sa 376 | # replace with non-default namespace name 377 | namespace: default 378 | roleRef: 379 | kind: ClusterRole 380 | name: driver-registrar-runner 381 | apiGroup: rbac.authorization.k8s.io 382 | 383 | --- 384 | kind: DaemonSet 385 | apiVersion: apps/v1 386 | metadata: 387 | name: csi-hostpathplugin 388 | spec: 389 | selector: 390 | matchLabels: 391 | app: csi-hostpathplugin 392 | template: 393 | metadata: 394 | labels: 395 | app: csi-hostpathplugin 396 | spec: 397 | serviceAccountName: csi-node-sa 398 | hostNetwork: true 399 | containers: 400 | - name: driver-registrar 401 | image: quay.io/k8scsi/csi-node-driver-registrar:v1.0.1 402 | imagePullPolicy: IfNotPresent 403 | args: 404 | - --v=5 405 | - --csi-address=/csi/csi.sock 406 | - --kubelet-registration-path=/var/lib/kubelet/plugins/csi-hostpath/csi.sock 407 | env: 408 | - name: KUBE_NODE_NAME 409 | valueFrom: 410 | fieldRef: 411 | apiVersion: v1 412 | fieldPath: spec.nodeName 413 | volumeMounts: 414 | - mountPath: /csi 415 | name: socket-dir 416 | - mountPath: /registration 417 | name: registration-dir 418 | - name: hostpath 419 | image: quay.io/k8scsi/hostpathplugin:v1.0.1 420 | imagePullPolicy: IfNotPresent 421 | args: 422 | - "--v=5" 423 | - "--endpoint=$(CSI_ENDPOINT)" 424 | - "--nodeid=$(KUBE_NODE_NAME)" 425 | env: 426 | - name: CSI_ENDPOINT 427 | value: unix:///csi/csi.sock 428 | - name: KUBE_NODE_NAME 429 | valueFrom: 430 | fieldRef: 431 | apiVersion: v1 432 | fieldPath: spec.nodeName 433 | securityContext: 434 | privileged: true 435 | volumeMounts: 436 | - mountPath: /csi 437 | name: socket-dir 438 | - mountPath: /var/lib/kubelet/pods 439 | mountPropagation: Bidirectional 440 | name: mountpoint-dir 441 | volumes: 442 | - hostPath: 443 | path: /var/lib/kubelet/plugins/csi-hostpath 444 | type: DirectoryOrCreate 445 | name: socket-dir 446 | - hostPath: 447 | path: /var/lib/kubelet/pods 448 | type: DirectoryOrCreate 449 | name: mountpoint-dir 450 | - hostPath: 451 | path: /var/lib/kubelet/plugins_registry 452 | type: Directory 453 | name: registration-dir 454 | 455 | 456 | 457 | 458 | # app to use csi storage 459 | # csi-storageclass 460 | --- 461 | apiVersion: storage.k8s.io/v1 462 | kind: StorageClass 463 | metadata: 464 | name: csi-hostpath-sc 465 | provisioner: csi-hostpath 466 | reclaimPolicy: Delete 467 | volumeBindingMode: Immediate 468 | 469 | # csi-pvc 470 | --- 471 | apiVersion: v1 472 | kind: PersistentVolumeClaim 473 | metadata: 474 | name: csi-pvc 475 | spec: 476 | accessModes: 477 | - ReadWriteOnce 478 | resources: 479 | requests: 480 | storage: 1Gi 481 | storageClassName: csi-hostpath-sc 482 | 483 | # pod 484 | --- 485 | kind: Pod 486 | apiVersion: v1 487 | metadata: 488 | name: my-csi-app 489 | spec: 490 | containers: 491 | - name: my-csi-app 492 | image: busybox 493 | imagePullPolicy: IfNotPresent 494 | command: [ "sleep", "1000000" ] 495 | volumeMounts: 496 | - mountPath: "/data" 497 | name: my-csi-volume 498 | volumes: 499 | - name: my-csi-volume 500 | persistentVolumeClaim: 501 | claimName: csi-pvc 502 | -------------------------------------------------------------------------------- /Chapter8/8.7.4 volumesnapshot.yaml: -------------------------------------------------------------------------------- 1 | # csi VolumeSnapshotContent 2 | --- 3 | apiVersion: snapshot.storage.k8s.io/v1alpha1 4 | kind: VolumeSnapshotContent 5 | metadata: 6 | name: new-snapshot-content-test 7 | spec: 8 | snapshotClassName: csi-hostpath-snapclass 9 | source: 10 | name: pvc-test 11 | kind: PersistentVolumeClaim 12 | volumeSnapshotSource: 13 | csiVolumeSnapshotSource: 14 | creationTime: 1535478900692119403 15 | driver: csi-hostpath 16 | restoreSize: 10Gi 17 | snapshotHandle: 7bdd0de3-aaeb-11e8-9aae-0242ac110002 18 | 19 | 20 | # csi VolumeSnapshot 21 | --- 22 | apiVersion: snapshot.storage.k8s.io/v1alpha1 23 | kind: VolumeSnapshot 24 | metadata: 25 | name: new-snapshot-test 26 | spec: 27 | snapshotClassName: csi-hostpath-snapclass 28 | source: 29 | name: pvc-test 30 | kind: PersistentVolumeClaim 31 | -------------------------------------------------------------------------------- /Chapter9/9.4.1 customresourcedefinition.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1beta1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: virtualservices.networking.istio.io 6 | annotations: 7 | "helm.sh/hook": crd-install 8 | labels: 9 | app: istio-pilot 10 | spec: 11 | group: networking.istio.io 12 | scope: Namespaced 13 | versions: 14 | - name: v1alpha3 15 | served: true 16 | storage: true 17 | names: 18 | kind: VirtualService 19 | listKind: VirtualServiceList 20 | singular: virtualservice 21 | plural: virtualservices 22 | categories: 23 | - istio-io 24 | - networking-istio-io 25 | 26 | 27 | --- 28 | apiVersion: networking.istio.io/v1alpha3 29 | kind: VirtualService 30 | metadata: 31 | name: helloworld 32 | spec: 33 | hosts: 34 | - "*" 35 | gateways: 36 | - helloworld-gateway 37 | http: 38 | - match: 39 | - uri: 40 | exact: /hello 41 | route: 42 | - destination: 43 | host: helloworld 44 | port: 45 | number: 5000 46 | 47 | 48 | 49 | 50 | # crd subresources 51 | --- 52 | apiVersion: apiextensions.k8s.io/v1beta1 53 | kind: CustomResourceDefinition 54 | metadata: 55 | name: crontabs.stable.example.com 56 | spec: 57 | group: stable.example.com 58 | versions: 59 | - name: v1 60 | served: true 61 | storage: true 62 | scope: Namespaced 63 | names: 64 | plural: crontabs 65 | singular: crontab 66 | kind: CronTab 67 | shortNames: 68 | - ct 69 | subresources: 70 | status: {} 71 | scale: 72 | specReplicasPath: .spec.replicas 73 | statusReplicasPath: .status.replicas 74 | labelSelectorPath: .status.labelSelector 75 | 76 | --- 77 | apiVersion: "stable.example.com/v1" 78 | kind: CronTab 79 | metadata: 80 | name: my-new-cron-object 81 | spec: 82 | cronSpec: "* * * * */5" 83 | image: my-awesome-cron-image 84 | replicas: 3 85 | 86 | 87 | 88 | 89 | # crd validation 90 | --- 91 | apiVersion: apiextensions.k8s.io/v1beta1 92 | kind: CustomResourceDefinition 93 | metadata: 94 | name: crontabs.stable.example.com 95 | spec: 96 | group: stable.example.com 97 | versions: 98 | - name: v1 99 | served: true 100 | storage: true 101 | version: v1 102 | scope: Namespaced 103 | names: 104 | plural: crontabs 105 | singular: crontab 106 | kind: CronTab 107 | shortNames: 108 | - ct 109 | validation: 110 | openAPIV3Schema: 111 | properties: 112 | spec: 113 | properties: 114 | cronSpec: 115 | type: string 116 | pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$' 117 | replicas: 118 | type: integer 119 | minimum: 1 120 | maximum: 10 121 | 122 | # validation fail 123 | --- 124 | apiVersion: "stable.example.com/v1" 125 | kind: CronTab 126 | metadata: 127 | name: my-new-cron-object 128 | spec: 129 | cronSpec: "* * * *" 130 | image: my-awesome-cron-image 131 | replicas: 15 132 | 133 | 134 | 135 | 136 | # custom crd display column 137 | --- 138 | apiVersion: apiextensions.k8s.io/v1beta1 139 | kind: CustomResourceDefinition 140 | metadata: 141 | name: crontabs.stable.example.com 142 | spec: 143 | group: stable.example.com 144 | version: v1 145 | scope: Namespaced 146 | names: 147 | plural: crontabs 148 | singular: crontab 149 | kind: CronTab 150 | shortNames: 151 | - ct 152 | additionalPrinterColumns: 153 | - name: Spec 154 | type: string 155 | description: The cron spec defining the interval a CronJob is run 156 | JSONPath: .spec.cronSpec 157 | - name: Replicas 158 | type: integer 159 | description: The number of jobs launched by the CronJob 160 | JSONPath: .spec.replicas 161 | - name: Age 162 | type: date 163 | JSONPath: .metadata.creationTimestamp 164 | 165 | 166 | 167 | # finalizer 168 | --- 169 | apiVersion: "stable.example.com/v1" 170 | kind: CronTab 171 | metadata: 172 | finalizers: 173 | - finalizer.stable.example.com 174 | -------------------------------------------------------------------------------- /Chapter9/9.4.2 apiaggregation-apiservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiregistration.k8s.io/v1beta1 3 | kind: APIService 4 | metadata: 5 | name: v1beta1.custom.metrics.k8s.io 6 | spec: 7 | service: 8 | name: custom-metrics-server 9 | namespace: custom-metrics 10 | group: custom.metrics.k8s.io 11 | version: v1beta1 12 | insecureSkipTLSVerify: true 13 | groupPriorityMinimum: 100 14 | versionPriority: 100 15 | 16 | 17 | 18 | # metrics server example 19 | --- 20 | apiVersion: v1 21 | kind: ServiceAccount 22 | metadata: 23 | name: metrics-server 24 | namespace: kube-system 25 | --- 26 | apiVersion: extensions/v1beta1 27 | kind: Deployment 28 | metadata: 29 | name: metrics-server 30 | namespace: kube-system 31 | labels: 32 | k8s-app: metrics-server 33 | spec: 34 | selector: 35 | matchLabels: 36 | k8s-app: metrics-server 37 | template: 38 | metadata: 39 | name: metrics-server 40 | labels: 41 | k8s-app: metrics-server 42 | spec: 43 | serviceAccountName: metrics-server 44 | containers: 45 | - name: metrics-server 46 | image: k8s.gcr.io/metrics-server-amd64:v0.3.1 47 | imagePullPolicy: IfNotPresent 48 | volumeMounts: 49 | - name: tmp-dir 50 | mountPath: /tmp 51 | volumes: 52 | - name: tmp-dir 53 | emptyDir: {} 54 | --- 55 | apiVersion: v1 56 | kind: Service 57 | metadata: 58 | name: metrics-server 59 | namespace: kube-system 60 | labels: 61 | kubernetes.io/name: "Metrics-server" 62 | spec: 63 | selector: 64 | k8s-app: metrics-server 65 | ports: 66 | - port: 443 67 | protocol: TCP 68 | targetPort: 443 69 | 70 | 71 | --- 72 | kind: ClusterRole 73 | apiVersion: rbac.authorization.k8s.io/v1 74 | metadata: 75 | name: system:aggregated-metrics-reader 76 | labels: 77 | rbac.authorization.k8s.io/aggregate-to-view: "true" 78 | rbac.authorization.k8s.io/aggregate-to-edit: "true" 79 | rbac.authorization.k8s.io/aggregate-to-admin: "true" 80 | rules: 81 | - apiGroups: ["metrics.k8s.io"] 82 | resources: ["pods"] 83 | verbs: ["get", "list", "watch"] 84 | --- 85 | apiVersion: rbac.authorization.k8s.io/v1 86 | kind: ClusterRole 87 | metadata: 88 | name: system:metrics-server 89 | rules: 90 | - apiGroups: 91 | - "" 92 | resources: 93 | - pods 94 | - nodes 95 | - nodes/stats 96 | verbs: 97 | - get 98 | - list 99 | - watch 100 | --- 101 | apiVersion: rbac.authorization.k8s.io/v1 102 | kind: ClusterRoleBinding 103 | metadata: 104 | name: system:metrics-server 105 | roleRef: 106 | apiGroup: rbac.authorization.k8s.io 107 | kind: ClusterRole 108 | name: system:metrics-server 109 | subjects: 110 | - kind: ServiceAccount 111 | name: metrics-server 112 | namespace: kube-system 113 | --- 114 | apiVersion: rbac.authorization.k8s.io/v1beta1 115 | kind: ClusterRoleBinding 116 | metadata: 117 | name: metrics-server:system:auth-delegator 118 | roleRef: 119 | apiGroup: rbac.authorization.k8s.io 120 | kind: ClusterRole 121 | name: system:auth-delegator 122 | subjects: 123 | - kind: ServiceAccount 124 | name: metrics-server 125 | namespace: kube-system 126 | --- 127 | apiVersion: rbac.authorization.k8s.io/v1beta1 128 | kind: RoleBinding 129 | metadata: 130 | name: metrics-server-auth-reader 131 | namespace: kube-system 132 | roleRef: 133 | apiGroup: rbac.authorization.k8s.io 134 | kind: Role 135 | name: extension-apiserver-authentication-reader 136 | subjects: 137 | - kind: ServiceAccount 138 | name: metrics-server 139 | namespace: kube-system 140 | 141 | --- 142 | apiVersion: apiregistration.k8s.io/v1beta1 143 | kind: APIService 144 | metadata: 145 | name: v1beta1.metrics.k8s.io 146 | spec: 147 | service: 148 | name: metrics-server 149 | namespace: kube-system 150 | group: metrics.k8s.io 151 | version: v1beta1 152 | insecureSkipTLSVerify: true 153 | groupPriorityMinimum: 100 154 | versionPriority: 100 155 | 156 | 157 | 158 | # curl http://192.168.18.3:8080/apis/metrics.k8s.io/v1beta1/nodes 159 | 160 | # curl http://192.168.18.3:8080/apis/metrics.k8s.io/v1beta1/pods 161 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 《Kubernetes权威指南》第4版书中示例 2 | --------------------------------------------------------------------------------